diff options
-rw-r--r-- | src/ec25519.c | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/src/ec25519.c b/src/ec25519.c index d9a8528..f2bc288 100644 --- a/src/ec25519.c +++ b/src/ec25519.c @@ -138,19 +138,20 @@ static void squeeze(uint32_t a[32]) { a[31] = u; } + +static const uint32_t minusp[32] = { + 19, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 128 +}; + /** * Ensures that the output of a previous \ref squeeze is fully reduced * * After a \ref freeze, only the lower byte of each integer part holds a meaningful value. */ static void freeze(uint32_t a[32]) { - static const uint32_t minusp[32] = { - 19, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 128 - }; - uint32_t aorig[32]; unsigned int j; uint32_t negative; @@ -165,6 +166,18 @@ static void freeze(uint32_t a[32]) { } /** + * Returns the parity (lowest bit of the fully reduced value) of a + * + * The input must be \em squeezed. + */ +static int parity(uint32_t a[32]) { + uint32_t b[32]; + + add(b, a, minusp); + return (a[0] ^ (b[31] >> 7) ^ 1) & 1; +} + +/** * Multiplies two unpacked integers (modulo p) * * The result will be \em squeezed. @@ -554,7 +567,7 @@ int ecc_25519_load_packed(ecc_25519_work_t *out, const ecc_int256_t *in) { /* No squeeze is necessary after subtractions from zero if the subtrahend is squeezed */ sub(Yt, zero, Y); - select(out->Y, Y, Yt, (in->p[31] >> 7) ^ (Y[0] & 1)); + select(out->Y, Y, Yt, (in->p[31] >> 7) ^ parity(Y)); mult(out->T, out->X, out->Y); |