Loading curve25519-donna.c +43 −0 Original line number Diff line number Diff line Loading @@ -420,6 +420,17 @@ fexpand(limb *output, const u8 *input) { #error "This code only works when >> does sign-extension on negative numbers" #endif /* Return 1 if input1 >= input2; return 0 otherwise. input1 and input2 must have absolute value less than 2**29. */ static s32 sub_s32_geq(s32 input1, s32 input2) { s32 a = input1 - input2; /* a >= 0 iff input1 >= input2 */ s32 b = a >> 31; /* b == 0 if input1 >= input2; b == -1 otherwise */ s32 c = b + 1; return c; } /* Take a fully reduced polynomial form number and contract it into a * little-endian, 32-byte array */ Loading Loading @@ -471,6 +482,38 @@ fcontract(u8 *output, limb *input) { negative values will remain in the array until the end. */ /* Now ensure that input is not greater than 2**255 - 20. */ { limb tmp[10]; /* sub_s32_geq uses considerably fewer operations than sub_s32_equal did. */ s32 out_of_bounds_p = sub_s32_geq(input[9], 0x1ffffff); out_of_bounds_p &= sub_s32_geq(input[8], 0x3ffffff); out_of_bounds_p &= sub_s32_geq(input[7], 0x1ffffff); out_of_bounds_p &= sub_s32_geq(input[6], 0x3ffffff); out_of_bounds_p &= sub_s32_geq(input[5], 0x1ffffff); out_of_bounds_p &= sub_s32_geq(input[4], 0x3ffffff); out_of_bounds_p &= sub_s32_geq(input[3], 0x1ffffff); out_of_bounds_p &= sub_s32_geq(input[2], 0x3ffffff); out_of_bounds_p &= sub_s32_geq(input[1], 0x1ffffff); out_of_bounds_p &= sub_s32_geq(input[0], 0x3ffffff - 18); tmp[9] = (-out_of_bounds_p) & 0x1ffffff; tmp[8] = (-out_of_bounds_p) & 0x3ffffff; tmp[7] = (-out_of_bounds_p) & 0x1ffffff; tmp[6] = (-out_of_bounds_p) & 0x3ffffff; tmp[5] = (-out_of_bounds_p) & 0x1ffffff; tmp[4] = (-out_of_bounds_p) & 0x3ffffff; tmp[3] = (-out_of_bounds_p) & 0x1ffffff; tmp[2] = (-out_of_bounds_p) & 0x3ffffff; tmp[1] = (-out_of_bounds_p) & 0x1ffffff; tmp[0] = (-out_of_bounds_p) & (0x3ffffff - 18); fdifference(tmp, input); /* XXXX could use s32 arithmetic here instead */ memcpy(input, tmp, sizeof(tmp)); } input[1] <<= 2; input[2] <<= 3; input[3] <<= 5; Loading Loading
curve25519-donna.c +43 −0 Original line number Diff line number Diff line Loading @@ -420,6 +420,17 @@ fexpand(limb *output, const u8 *input) { #error "This code only works when >> does sign-extension on negative numbers" #endif /* Return 1 if input1 >= input2; return 0 otherwise. input1 and input2 must have absolute value less than 2**29. */ static s32 sub_s32_geq(s32 input1, s32 input2) { s32 a = input1 - input2; /* a >= 0 iff input1 >= input2 */ s32 b = a >> 31; /* b == 0 if input1 >= input2; b == -1 otherwise */ s32 c = b + 1; return c; } /* Take a fully reduced polynomial form number and contract it into a * little-endian, 32-byte array */ Loading Loading @@ -471,6 +482,38 @@ fcontract(u8 *output, limb *input) { negative values will remain in the array until the end. */ /* Now ensure that input is not greater than 2**255 - 20. */ { limb tmp[10]; /* sub_s32_geq uses considerably fewer operations than sub_s32_equal did. */ s32 out_of_bounds_p = sub_s32_geq(input[9], 0x1ffffff); out_of_bounds_p &= sub_s32_geq(input[8], 0x3ffffff); out_of_bounds_p &= sub_s32_geq(input[7], 0x1ffffff); out_of_bounds_p &= sub_s32_geq(input[6], 0x3ffffff); out_of_bounds_p &= sub_s32_geq(input[5], 0x1ffffff); out_of_bounds_p &= sub_s32_geq(input[4], 0x3ffffff); out_of_bounds_p &= sub_s32_geq(input[3], 0x1ffffff); out_of_bounds_p &= sub_s32_geq(input[2], 0x3ffffff); out_of_bounds_p &= sub_s32_geq(input[1], 0x1ffffff); out_of_bounds_p &= sub_s32_geq(input[0], 0x3ffffff - 18); tmp[9] = (-out_of_bounds_p) & 0x1ffffff; tmp[8] = (-out_of_bounds_p) & 0x3ffffff; tmp[7] = (-out_of_bounds_p) & 0x1ffffff; tmp[6] = (-out_of_bounds_p) & 0x3ffffff; tmp[5] = (-out_of_bounds_p) & 0x1ffffff; tmp[4] = (-out_of_bounds_p) & 0x3ffffff; tmp[3] = (-out_of_bounds_p) & 0x1ffffff; tmp[2] = (-out_of_bounds_p) & 0x3ffffff; tmp[1] = (-out_of_bounds_p) & 0x1ffffff; tmp[0] = (-out_of_bounds_p) & (0x3ffffff - 18); fdifference(tmp, input); /* XXXX could use s32 arithmetic here instead */ memcpy(input, tmp, sizeof(tmp)); } input[1] <<= 2; input[2] <<= 3; input[3] <<= 5; Loading