From 144f2690598c46ed8074e25c840b68f24f989bad Mon Sep 17 00:00:00 2001 From: Moxie Marlinspike Date: Fri, 11 Jul 2014 14:20:01 -0700 Subject: [PATCH] Upgrade curve25519-donna to latest. --- libaxolotl/jni/curve25519-donna.c | 295 ++++++++++++++----- libaxolotl/libs/armeabi-v7a/libcurve25519.so | Bin 90172 -> 90172 bytes libaxolotl/libs/armeabi/libcurve25519.so | Bin 90168 -> 90168 bytes libaxolotl/libs/x86/libcurve25519.so | Bin 114752 -> 114752 bytes 4 files changed, 217 insertions(+), 78 deletions(-) diff --git a/libaxolotl/jni/curve25519-donna.c b/libaxolotl/jni/curve25519-donna.c index b84c9e0ff1..f2c2ac58e6 100644 --- a/libaxolotl/jni/curve25519-donna.c +++ b/libaxolotl/jni/curve25519-donna.c @@ -43,8 +43,7 @@ * * This is, almost, a clean room reimplementation from the curve25519 paper. It * uses many of the tricks described therein. Only the crecip function is taken - * from the sample implementation. - */ + * from the sample implementation. */ #include #include @@ -63,25 +62,23 @@ typedef int64_t limb; * significant first. The value of the field element is: * x[0] + 2^26·x[1] + x^51·x[2] + 2^102·x[3] + ... * - * i.e. the limbs are 26, 25, 26, 25, ... bits wide. - */ + * i.e. the limbs are 26, 25, 26, 25, ... bits wide. */ /* Sum two numbers: output += in */ static void fsum(limb *output, const limb *in) { unsigned i; for (i = 0; i < 10; i += 2) { - output[0+i] = (output[0+i] + in[0+i]); - output[1+i] = (output[1+i] + in[1+i]); + output[0+i] = output[0+i] + in[0+i]; + output[1+i] = output[1+i] + in[1+i]; } } /* Find the difference of two numbers: output = in - output - * (note the order of the arguments!) - */ + * (note the order of the arguments!). */ static void fdifference(limb *output, const limb *in) { unsigned i; for (i = 0; i < 10; ++i) { - output[i] = (in[i] - output[i]); + output[i] = in[i] - output[i]; } } @@ -97,7 +94,8 @@ static void fscalar_product(limb *output, const limb *in, const limb scalar) { * * output must be distinct to both inputs. The inputs are reduced coefficient * form, the output is not. - */ + * + * output[x] <= 14 * the largest product of the input limbs. */ static void fproduct(limb *output, const limb *in2, const limb *in) { output[0] = ((limb) ((s32) in2[0])) * ((s32) in[0]); output[1] = ((limb) ((s32) in2[0])) * ((s32) in[1]) + @@ -201,9 +199,15 @@ static void fproduct(limb *output, const limb *in2, const limb *in) { output[18] = 2 * ((limb) ((s32) in2[9])) * ((s32) in[9]); } -/* Reduce a long form to a short form by taking the input mod 2^255 - 19. */ +/* Reduce a long form to a short form by taking the input mod 2^255 - 19. + * + * On entry: |output[i]| < 14*2^54 + * On exit: |output[0..8]| < 280*2^54 */ static void freduce_degree(limb *output) { - /* Each of these shifts and adds ends up multiplying the value by 19. */ + /* Each of these shifts and adds ends up multiplying the value by 19. + * + * For output[0..8], the absolute entry value is < 14*2^54 and we add, at + * most, 19*14*2^54 thus, on exit, |output[0..8]| < 280*2^54. */ output[8] += output[18] << 4; output[8] += output[18] << 1; output[8] += output[18]; @@ -237,11 +241,13 @@ static void freduce_degree(limb *output) { #error "This code only works on a two's complement system" #endif -/* return v / 2^26, using only shifts and adds. */ +/* return v / 2^26, using only shifts and adds. + * + * On entry: v can take any value. */ static inline limb div_by_2_26(const limb v) { - /* High word of v; no shift needed*/ + /* High word of v; no shift needed. */ const uint32_t highword = (uint32_t) (((uint64_t) v) >> 32); /* Set to all 1s if v was negative; else set to 0s. */ const int32_t sign = ((int32_t) highword) >> 31; @@ -251,7 +257,9 @@ div_by_2_26(const limb v) return (v + roundoff) >> 26; } -/* return v / (2^25), using only shifts and adds. */ +/* return v / (2^25), using only shifts and adds. + * + * On entry: v can take any value. */ static inline limb div_by_2_25(const limb v) { @@ -265,6 +273,9 @@ div_by_2_25(const limb v) return (v + roundoff) >> 25; } +/* return v / (2^25), using only shifts and adds. + * + * On entry: v can take any value. */ static inline s32 div_s32_by_2_25(const s32 v) { @@ -274,8 +285,7 @@ div_s32_by_2_25(const s32 v) /* Reduce all coefficients of the short form input so that |x| < 2^26. * - * On entry: |output[i]| < 2^62 - */ + * On entry: |output[i]| < 280*2^54 */ static void freduce_coefficients(limb *output) { unsigned i; @@ -283,56 +293,65 @@ static void freduce_coefficients(limb *output) { for (i = 0; i < 10; i += 2) { limb over = div_by_2_26(output[i]); + /* The entry condition (that |output[i]| < 280*2^54) means that over is, at + * most, 280*2^28 in the first iteration of this loop. This is added to the + * next limb and we can approximate the resulting bound of that limb by + * 281*2^54. */ output[i] -= over << 26; output[i+1] += over; + /* For the first iteration, |output[i+1]| < 281*2^54, thus |over| < + * 281*2^29. When this is added to the next limb, the resulting bound can + * be approximated as 281*2^54. + * + * For subsequent iterations of the loop, 281*2^54 remains a conservative + * bound and no overflow occurs. */ over = div_by_2_25(output[i+1]); output[i+1] -= over << 25; output[i+2] += over; } - /* Now |output[10]| < 2 ^ 38 and all other coefficients are reduced. */ + /* Now |output[10]| < 281*2^29 and all other coefficients are reduced. */ output[0] += output[10] << 4; output[0] += output[10] << 1; output[0] += output[10]; output[10] = 0; - /* Now output[1..9] are reduced, and |output[0]| < 2^26 + 19 * 2^38 - * So |over| will be no more than 77825 */ + /* Now output[1..9] are reduced, and |output[0]| < 2^26 + 19*281*2^29 + * So |over| will be no more than 2^16. */ { limb over = div_by_2_26(output[0]); output[0] -= over << 26; output[1] += over; } - /* Now output[0,2..9] are reduced, and |output[1]| < 2^25 + 77825 - * So |over| will be no more than 1. */ - { - /* output[1] fits in 32 bits, so we can use div_s32_by_2_25 here. */ - s32 over32 = div_s32_by_2_25((s32) output[1]); - output[1] -= over32 << 25; - output[2] += over32; - } - - /* Finally, output[0,1,3..9] are reduced, and output[2] is "nearly reduced": - * we have |output[2]| <= 2^26. This is good enough for all of our math, - * but it will require an extra freduce_coefficients before fcontract. */ + /* Now output[0,2..9] are reduced, and |output[1]| < 2^25 + 2^16 < 2^26. The + * bound on |output[1]| is sufficient to meet our needs. */ } /* A helpful wrapper around fproduct: output = in * in2. * - * output must be distinct to both inputs. The output is reduced degree and - * reduced coefficient. - */ + * On entry: |in[i]| < 2^27 and |in2[i]| < 2^27. + * + * output must be distinct to both inputs. The output is reduced degree + * (indeed, one need only provide storage for 10 limbs) and |output[i]| < 2^26. */ static void fmul(limb *output, const limb *in, const limb *in2) { limb t[19]; fproduct(t, in, in2); + /* |t[i]| < 14*2^54 */ freduce_degree(t); freduce_coefficients(t); + /* |t[i]| < 2^26 */ memcpy(output, t, sizeof(limb) * 10); } +/* Square a number: output = in**2 + * + * output must be distinct from the input. The inputs are reduced coefficient + * form, the output is not. + * + * output[x] <= 14 * the largest product of the input limbs. */ static void fsquare_inner(limb *output, const limb *in) { output[0] = ((limb) ((s32) in[0])) * ((s32) in[0]); output[1] = 2 * ((limb) ((s32) in[0])) * ((s32) in[1]); @@ -391,12 +410,23 @@ static void fsquare_inner(limb *output, const limb *in) { output[18] = 2 * ((limb) ((s32) in[9])) * ((s32) in[9]); } +/* fsquare sets output = in^2. + * + * On entry: The |in| argument is in reduced coefficients form and |in[i]| < + * 2^27. + * + * On exit: The |output| argument is in reduced coefficients form (indeed, one + * need only provide storage for 10 limbs) and |out[i]| < 2^26. */ static void fsquare(limb *output, const limb *in) { limb t[19]; fsquare_inner(t, in); + /* |t[i]| < 14*2^54 because the largest product of two limbs will be < + * 2^(27+27) and fsquare_inner adds together, at most, 14 of those + * products. */ freduce_degree(t); freduce_coefficients(t); + /* |t[i]| < 2^26 */ memcpy(output, t, sizeof(limb) * 10); } @@ -417,7 +447,7 @@ fexpand(limb *output, const u8 *input) { F(6, 19, 1, 0x3ffffff); F(7, 22, 3, 0x1ffffff); F(8, 25, 4, 0x3ffffff); - F(9, 28, 6, 0x3ffffff); + F(9, 28, 6, 0x1ffffff); #undef F } @@ -425,60 +455,143 @@ fexpand(limb *output, const u8 *input) { #error "This code only works when >> does sign-extension on negative numbers" #endif +/* s32_eq returns 0xffffffff iff a == b and zero otherwise. */ +static s32 s32_eq(s32 a, s32 b) { + a = ~(a ^ b); + a &= a << 16; + a &= a << 8; + a &= a << 4; + a &= a << 2; + a &= a << 1; + return a >> 31; +} + +/* s32_gte returns 0xffffffff if a >= b and zero otherwise, where a and b are + * both non-negative. */ +static s32 s32_gte(s32 a, s32 b) { + a -= b; + /* a >= 0 iff a >= b. */ + return ~(a >> 31); +} + /* Take a fully reduced polynomial form number and contract it into a - * little-endian, 32-byte array - */ + * little-endian, 32-byte array. + * + * On entry: |input_limbs[i]| < 2^26 */ static void -fcontract(u8 *output, limb *input) { +fcontract(u8 *output, limb *input_limbs) { int i; int j; + s32 input[10]; + s32 mask; + + /* |input_limbs[i]| < 2^26, so it's valid to convert to an s32. */ + for (i = 0; i < 10; i++) { + input[i] = input_limbs[i]; + } for (j = 0; j < 2; ++j) { for (i = 0; i < 9; ++i) { if ((i & 1) == 1) { - /* This calculation is a time-invariant way to make input[i] positive - by borrowing from the next-larger limb. - */ - const s32 mask = (s32)(input[i]) >> 31; - const s32 carry = -(((s32)(input[i]) & mask) >> 25); - input[i] = (s32)(input[i]) + (carry << 25); - input[i+1] = (s32)(input[i+1]) - carry; + /* This calculation is a time-invariant way to make input[i] + * non-negative by borrowing from the next-larger limb. */ + const s32 mask = input[i] >> 31; + const s32 carry = -((input[i] & mask) >> 25); + input[i] = input[i] + (carry << 25); + input[i+1] = input[i+1] - carry; } else { - const s32 mask = (s32)(input[i]) >> 31; - const s32 carry = -(((s32)(input[i]) & mask) >> 26); - input[i] = (s32)(input[i]) + (carry << 26); - input[i+1] = (s32)(input[i+1]) - carry; + const s32 mask = input[i] >> 31; + const s32 carry = -((input[i] & mask) >> 26); + input[i] = input[i] + (carry << 26); + input[i+1] = input[i+1] - carry; } } + + /* There's no greater limb for input[9] to borrow from, but we can multiply + * by 19 and borrow from input[0], which is valid mod 2^255-19. */ { - const s32 mask = (s32)(input[9]) >> 31; - const s32 carry = -(((s32)(input[9]) & mask) >> 25); - input[9] = (s32)(input[9]) + (carry << 25); - input[0] = (s32)(input[0]) - (carry * 19); + const s32 mask = input[9] >> 31; + const s32 carry = -((input[9] & mask) >> 25); + input[9] = input[9] + (carry << 25); + input[0] = input[0] - (carry * 19); } + + /* After the first iteration, input[1..9] are non-negative and fit within + * 25 or 26 bits, depending on position. However, input[0] may be + * negative. */ } /* The first borrow-propagation pass above ended with every limb except (possibly) input[0] non-negative. - Since each input limb except input[0] is decreased by at most 1 - by a borrow-propagation pass, the second borrow-propagation pass - could only have wrapped around to decrease input[0] again if the - first pass left input[0] negative *and* input[1] through input[9] - were all zero. In that case, input[1] is now 2^25 - 1, and this - last borrow-propagation step will leave input[1] non-negative. - */ + If input[0] was negative after the first pass, then it was because of a + carry from input[9]. On entry, input[9] < 2^26 so the carry was, at most, + one, since (2**26-1) >> 25 = 1. Thus input[0] >= -19. + + In the second pass, each limb is decreased by at most one. Thus the second + borrow-propagation pass could only have wrapped around to decrease + input[0] again if the first pass left input[0] negative *and* input[1] + through input[9] were all zero. In that case, input[1] is now 2^25 - 1, + and this last borrow-propagation step will leave input[1] non-negative. */ { - const s32 mask = (s32)(input[0]) >> 31; - const s32 carry = -(((s32)(input[0]) & mask) >> 26); - input[0] = (s32)(input[0]) + (carry << 26); - input[1] = (s32)(input[1]) - carry; + const s32 mask = input[0] >> 31; + const s32 carry = -((input[0] & mask) >> 26); + input[0] = input[0] + (carry << 26); + input[1] = input[1] - carry; } - /* Both passes through the above loop, plus the last 0-to-1 step, are - necessary: if input[9] is -1 and input[0] through input[8] are 0, - negative values will remain in the array until the end. - */ + /* All input[i] are now non-negative. However, there might be values between + * 2^25 and 2^26 in a limb which is, nominally, 25 bits wide. */ + for (j = 0; j < 2; j++) { + for (i = 0; i < 9; i++) { + if ((i & 1) == 1) { + const s32 carry = input[i] >> 25; + input[i] &= 0x1ffffff; + input[i+1] += carry; + } else { + const s32 carry = input[i] >> 26; + input[i] &= 0x3ffffff; + input[i+1] += carry; + } + } + + { + const s32 carry = input[9] >> 25; + input[9] &= 0x1ffffff; + input[0] += 19*carry; + } + } + + /* If the first carry-chain pass, just above, ended up with a carry from + * input[9], and that caused input[0] to be out-of-bounds, then input[0] was + * < 2^26 + 2*19, because the carry was, at most, two. + * + * If the second pass carried from input[9] again then input[0] is < 2*19 and + * the input[9] -> input[0] carry didn't push input[0] out of bounds. */ + + /* It still remains the case that input might be between 2^255-19 and 2^255. + * In this case, input[1..9] must take their maximum value and input[0] must + * be >= (2^255-19) & 0x3ffffff, which is 0x3ffffed. */ + mask = s32_gte(input[0], 0x3ffffed); + for (i = 1; i < 10; i++) { + if ((i & 1) == 1) { + mask &= s32_eq(input[i], 0x1ffffff); + } else { + mask &= s32_eq(input[i], 0x3ffffff); + } + } + + /* mask is either 0xffffffff (if input >= 2^255-19) and zero otherwise. Thus + * this conditionally subtracts 2^255-19. */ + input[0] -= mask & 0x3ffffed; + + for (i = 1; i < 10; i++) { + if ((i & 1) == 1) { + input[i] -= mask & 0x1ffffff; + } else { + input[i] -= mask & 0x3ffffff; + } + } input[1] <<= 2; input[2] <<= 3; @@ -516,7 +629,9 @@ fcontract(u8 *output, limb *input) { * x z: short form, destroyed * xprime zprime: short form, destroyed * qmqp: short form, preserved - */ + * + * On entry and exit, the absolute value of the limbs of all inputs and outputs + * are < 2^26. */ static void fmonty(limb *x2, limb *z2, /* output 2Q */ limb *x3, limb *z3, /* output Q + Q' */ limb *x, limb *z, /* input Q */ @@ -527,43 +642,69 @@ static void fmonty(limb *x2, limb *z2, /* output 2Q */ memcpy(origx, x, 10 * sizeof(limb)); fsum(x, z); - fdifference(z, origx); // does x - z + /* |x[i]| < 2^27 */ + fdifference(z, origx); /* does x - z */ + /* |z[i]| < 2^27 */ memcpy(origxprime, xprime, sizeof(limb) * 10); fsum(xprime, zprime); + /* |xprime[i]| < 2^27 */ fdifference(zprime, origxprime); + /* |zprime[i]| < 2^27 */ fproduct(xxprime, xprime, z); + /* |xxprime[i]| < 14*2^54: the largest product of two limbs will be < + * 2^(27+27) and fproduct adds together, at most, 14 of those products. + * (Approximating that to 2^58 doesn't work out.) */ fproduct(zzprime, x, zprime); + /* |zzprime[i]| < 14*2^54 */ freduce_degree(xxprime); freduce_coefficients(xxprime); + /* |xxprime[i]| < 2^26 */ freduce_degree(zzprime); freduce_coefficients(zzprime); + /* |zzprime[i]| < 2^26 */ memcpy(origxprime, xxprime, sizeof(limb) * 10); fsum(xxprime, zzprime); + /* |xxprime[i]| < 2^27 */ fdifference(zzprime, origxprime); + /* |zzprime[i]| < 2^27 */ fsquare(xxxprime, xxprime); + /* |xxxprime[i]| < 2^26 */ fsquare(zzzprime, zzprime); + /* |zzzprime[i]| < 2^26 */ fproduct(zzprime, zzzprime, qmqp); + /* |zzprime[i]| < 14*2^52 */ freduce_degree(zzprime); freduce_coefficients(zzprime); + /* |zzprime[i]| < 2^26 */ memcpy(x3, xxxprime, sizeof(limb) * 10); memcpy(z3, zzprime, sizeof(limb) * 10); fsquare(xx, x); + /* |xx[i]| < 2^26 */ fsquare(zz, z); + /* |zz[i]| < 2^26 */ fproduct(x2, xx, zz); + /* |x2[i]| < 14*2^52 */ freduce_degree(x2); freduce_coefficients(x2); + /* |x2[i]| < 2^26 */ fdifference(zz, xx); // does zz = xx - zz + /* |zz[i]| < 2^27 */ memset(zzz + 10, 0, sizeof(limb) * 9); fscalar_product(zzz, zz, 121665); + /* |zzz[i]| < 2^(27+17) */ /* No need to call freduce_degree here: fscalar_product doesn't increase the degree of its input. */ freduce_coefficients(zzz); + /* |zzz[i]| < 2^26 */ fsum(zzz, xx); + /* |zzz[i]| < 2^27 */ fproduct(z2, zz, zzz); + /* |z2[i]| < 14*2^(26+27) */ freduce_degree(z2); freduce_coefficients(z2); + /* |z2|i| < 2^26 */ } /* Conditionally swap two reduced-form limb arrays if 'iswap' is 1, but leave @@ -574,8 +715,7 @@ static void fmonty(limb *x2, limb *z2, /* output 2Q */ * wrong results. Also, the two limb arrays must be in reduced-coefficient, * reduced-degree form: the values in a[10..19] or b[10..19] aren't swapped, * and all all values in a[0..9],b[0..9] must have magnitude less than - * INT32_MAX. - */ + * INT32_MAX. */ static void swap_conditional(limb a[19], limb b[19], limb iswap) { unsigned i; @@ -592,8 +732,7 @@ swap_conditional(limb a[19], limb b[19], limb iswap) { * * resultx/resultz: the x coordinate of the resulting curve point (short form) * n: a little endian, 32-byte number - * q: a point of the curve (short form) - */ + * q: a point of the curve (short form) */ static void cmult(limb *resultx, limb *resultz, const u8 *n, const limb *q) { limb a[19] = {0}, b[19] = {1}, c[19] = {1}, d[19] = {0}; @@ -711,8 +850,6 @@ crecip(limb *out, const limb *z) { /* 2^255 - 21 */ fmul(out,t1,z11); } -int curve25519_donna(u8 *, const u8 *, const u8 *); - int curve25519_donna(u8 *mypublic, const u8 *secret, const u8 *basepoint) { limb bp[10], x[10], z[11], zmone[10]; @@ -720,12 +857,14 @@ curve25519_donna(u8 *mypublic, const u8 *secret, const u8 *basepoint) { int i; for (i = 0; i < 32; ++i) e[i] = secret[i]; +// e[0] &= 248; +// e[31] &= 127; +// e[31] |= 64; fexpand(bp, basepoint); cmult(x, z, e, bp); crecip(zmone, z); fmul(z, x, zmone); - freduce_coefficients(z); fcontract(mypublic, z); return 0; } diff --git a/libaxolotl/libs/armeabi-v7a/libcurve25519.so b/libaxolotl/libs/armeabi-v7a/libcurve25519.so index 90a3df310bb145aefee9f82628314abd6a860186..fdde5d0672a67d11a04bdde1a9473057108b8c2d 100755 GIT binary patch delta 5029 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 Yq5s0x&7X;la-w?Z`w!lliMQkb0;=A|R{#J2 diff --git a/libaxolotl/libs/armeabi/libcurve25519.so b/libaxolotl/libs/armeabi/libcurve25519.so index 3cee9ff8494372f3e5d061017b33a10cdc653691..7cecff027c30aa287129c065c0acc53d94b86959 100755 GIT binary patch delta 7007 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 delta 6828 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 diff --git a/libaxolotl/libs/x86/libcurve25519.so b/libaxolotl/libs/x86/libcurve25519.so index 2d6361b25a45ba9f3778b5bf55ea6c3551d02cb7..55b968a35de823066522b2711a5ab5c746c3dd19 100755 GIT binary patch delta 6250 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 p?~eUEEy{_%b~