[PATCH] mpi:ec: Least leak with k^(-1) for ECDSA.
NIIBE Yutaka via Gcrypt-devel <[email protected]> Wed, 14 May 2025 13:35:43 +0900
| Newsgroups | gmane.comp.encryption.gpg.libgcrypt.devel |
|---|---|
| Message-ID | <0bd4c77be6e04f5c8734926234742c3a2bb8fb18.1747197335.git.gniibe@fsij.org> |
* src/mpi.h (_gcry_mpi_assign_limb_space): Add. (_gcry_mpih_mod_lli, _gcry_mpih_mul_lli): Add. * cipher/ecc-ecdsa.c (_gcry_ecc_ecdsa_sign): Take care about least leak with k^(-1). -- GnuPG-bug-id: 7519 Signed-off-by: NIIBE Yutaka <[email protected]> --- cipher/ecc-ecdsa.c | 20 +++++++++++++++++++- src/mpi.h | 7 +++++++ 2 files changed, 26 insertions(+), 1 deletion(-) _______________________________________________ Gcrypt-devel mailing list [email protected] https://lists.gnupg.org/mailman/listinfo/gcrypt-devel
0001-mpi-ec-Least-leak-with-k-1-for-ECDSA.patch
(text/x-patch, 2.5 KB)
diff --git a/cipher/ecc-ecdsa.c b/cipher/ecc-ecdsa.c
index 9da8e6dc..6231ae0b 100644
--- a/cipher/ecc-ecdsa.c
+++ b/cipher/ecc-ecdsa.c
@@ -170,7 +170,25 @@ _gcry_ecc_ecdsa_sign (gcry_mpi_t input, gcry_mpi_t k_supplied, mpi_ec_t ec,
mpi_mulm (dr, dr, r, ec->n); /* dr = d*r mod n */
mpi_mulm (sum, b, hash, ec->n);
mpi_addm (sum, sum, dr, ec->n); /* sum = hash + (d*r) mod n */
- mpi_mulm (s, k_1, sum, ec->n); /* s = k^(-1)*(hash+(d*r)) mod n */
+ /* Then, s = k^(-1)*(hash+(d*r)) mod n */
+ { /* s = k_1 * sum */
+ mpi_ptr_t sp;
+ mpi_limb_t cy;
+
+ mpi_resize (sum, ec->n->nlimbs);
+ mpi_resize (s, ec->n->nlimbs * 2);
+ sp = s->d;
+ s->nlimbs = ec->n->nlimbs * 2;
+ cy = _gcry_mpih_mul_lli (sp, k_1->d, ec->n->nlimbs, sum->d,
+ ec->n->nlimbs);
+ sp[s->nlimbs - 1] = cy;
+ }
+ { /* s = s mod n */
+ mpi_ptr_t sp = _gcry_mpih_mod_lli (s->d, s->nlimbs, ec->n->d,
+ ec->n->nlimbs);
+ _gcry_mpi_assign_limb_space (s, sp, ec->n->nlimbs);
+ s->nlimbs = ec->n->nlimbs;
+ }
/* Undo blinding by b^-1 */
mpi_mulm (s, bi, s, ec->n);
if (mpi_cmp_ui (s, 0))
diff --git a/src/mpi.h b/src/mpi.h
index 74944b07..1c29c206 100644
--- a/src/mpi.h
+++ b/src/mpi.h
@@ -157,6 +157,8 @@ enum gcry_mpi_constants
gcry_mpi_t _gcry_mpi_const (enum gcry_mpi_constants no);
+void _gcry_mpi_assign_limb_space( gcry_mpi_t a, mpi_ptr_t ap,
+ unsigned int nlimbs );
/*-- mpicoder.c --*/
@@ -332,6 +334,8 @@ mpi_limb_t _gcry_mpih_add_n_cond (mpi_ptr_t wp, mpi_ptr_t up, mpi_ptr_t vp,
mpi_size_t usize, unsigned long op_enable);
int _gcry_mpih_cmp_ui (mpi_ptr_t up, mpi_size_t usize, unsigned long v);
int _gcry_mpih_cmp_lli (mpi_ptr_t op1_ptr, mpi_ptr_t op2_ptr, mpi_size_t size);
+mpi_ptr_t _gcry_mpih_mod_lli (mpi_ptr_t vp, mpi_size_t vsize,
+ mpi_ptr_t up, mpi_size_t usize);
/*-- mpih-add.c --*/
mpi_limb_t _gcry_mpih_add_n (mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
@@ -341,5 +345,8 @@ mpi_limb_t _gcry_mpih_add_n (mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
of RES_PTR == S1_PTR and the size is same), Least Leak Intended. */
#define _gcry_mpih_add_lli _gcry_mpih_add_n
+/*-- mpih-mul.c --*/
+mpi_limb_t _gcry_mpih_mul_lli( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t usize,
+ mpi_ptr_t vp, mpi_size_t vsize );
#endif /*G10_MPI_H*/