summaryrefslogtreecommitdiff
path: root/mpi
diff options
context:
space:
mode:
authorNIIBE Yutaka <gniibe@fsij.org>2019-10-25 10:06:26 +0900
committerNIIBE Yutaka <gniibe@fsij.org>2019-10-25 10:06:26 +0900
commit2dfedafe08ac57a87e6892d1af4d72cbb398fe40 (patch)
tree60e15eca5f7f2d993b2a865f01597b1d50278725 /mpi
parent050e0b4accfae6a49dda6b1bac52749edec5ce22 (diff)
downloadlibgcrypt-2dfedafe08ac57a87e6892d1af4d72cbb398fe40.tar.gz
ecc: Make _gcry_mpi_ec_mul_point friendly to X25519 computation.
* mpi/ec.c (_gcry_mpi_ec_mul_point): Support scalar input as an opaque MPI in little-endian native format. * cipher/ecc-ecdh.c (_gcry_ecc_mul_point): Use an opaque scalar. Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
Diffstat (limited to 'mpi')
-rw-r--r--mpi/ec.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/mpi/ec.c b/mpi/ec.c
index 387ac7e1..548473c2 100644
--- a/mpi/ec.c
+++ b/mpi/ec.c
@@ -30,6 +30,7 @@
#include "ec-context.h"
#include "ec-internal.h"
+extern void reverse_buffer (unsigned char *buffer, unsigned int length);
#define point_init(a) _gcry_mpi_point_init ((a))
#define point_free(a) _gcry_mpi_point_free_parts ((a))
@@ -1569,6 +1570,7 @@ _gcry_mpi_ec_mul_point (mpi_point_t result,
mpi_point_t q1, q2, prd, sum;
unsigned long sw;
mpi_size_t rsize;
+ int scalar_copied = 0;
/* Compute scalar point multiplication with Montgomery Ladder.
Note that we don't use Y-coordinate in the points at all.
@@ -1584,6 +1586,32 @@ _gcry_mpi_ec_mul_point (mpi_point_t result,
p2.x = mpi_copy (point->x);
mpi_set_ui (p2.z, 1);
+ if (mpi_is_opaque (scalar))
+ {
+ const unsigned int pbits = ctx->nbits;
+ gcry_mpi_t a;
+ unsigned int n;
+ unsigned char *raw;
+
+ scalar_copied = 1;
+
+ raw = _gcry_mpi_get_opaque_copy (scalar, &n);
+ if ((n+7)/8 != (pbits+7)/8)
+ log_fatal ("scalar size (%d) != prime size (%d)\n",
+ (n+7)/8, (pbits+7)/8);
+
+ reverse_buffer (raw, (n+7)/8);
+ if ((pbits % 8))
+ raw[0] &= (1 << (pbits % 8)) - 1;
+ raw[0] |= (1 << ((pbits + 7) % 8));
+ raw[(pbits+7)/8 - 1] &= (256 - ctx->h);
+ a = mpi_is_secure (scalar) ? mpi_snew (pbits): mpi_new (pbits);
+ _gcry_mpi_set_buffer (a, raw, (n+7)/8, 0);
+ xfree (raw);
+
+ scalar = a;
+ }
+
point_resize (&p1, ctx);
point_resize (&p2, ctx);
point_resize (&p1_, ctx);
@@ -1633,6 +1661,8 @@ _gcry_mpi_ec_mul_point (mpi_point_t result,
point_free (&p2);
point_free (&p1_);
point_free (&p2_);
+ if (scalar_copied)
+ _gcry_mpi_release (scalar);
return;
}