curve25519-donna-helpers.h (2836B)
1 /* 2 Public domain by Andrew M. <liquidsun@gmail.com> 3 See: https://github.com/floodyberry/curve25519-donna 4 5 Curve25519 implementation agnostic helpers 6 */ 7 8 #ifdef __GNUC__ 9 #define ED_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) 10 #endif 11 12 #if __GNUC__ && ED_GCC_VERSION >= 401 13 #if ED_GCC_VERSION >= 406 14 #pragma GCC diagnostic push 15 #endif 16 /* Some versions of GCC (particularly on arm) give us bogus warnings here. 17 * Suppress the GCC warning so we can build Tor with -Wstack-protector. */ 18 #pragma GCC diagnostic ignored "-Wstack-protector" 19 #endif 20 21 /* 22 * In: b = 2^5 - 2^0 23 * Out: b = 2^250 - 2^0 24 */ 25 static void 26 curve25519_pow_two5mtwo0_two250mtwo0(bignum25519 b) { 27 bignum25519 ALIGN(16) t0,c; 28 29 /* 2^5 - 2^0 */ /* b */ 30 /* 2^10 - 2^5 */ curve25519_square_times(t0, b, 5); 31 /* 2^10 - 2^0 */ curve25519_mul_noinline(b, t0, b); 32 /* 2^20 - 2^10 */ curve25519_square_times(t0, b, 10); 33 /* 2^20 - 2^0 */ curve25519_mul_noinline(c, t0, b); 34 /* 2^40 - 2^20 */ curve25519_square_times(t0, c, 20); 35 /* 2^40 - 2^0 */ curve25519_mul_noinline(t0, t0, c); 36 /* 2^50 - 2^10 */ curve25519_square_times(t0, t0, 10); 37 /* 2^50 - 2^0 */ curve25519_mul_noinline(b, t0, b); 38 /* 2^100 - 2^50 */ curve25519_square_times(t0, b, 50); 39 /* 2^100 - 2^0 */ curve25519_mul_noinline(c, t0, b); 40 /* 2^200 - 2^100 */ curve25519_square_times(t0, c, 100); 41 /* 2^200 - 2^0 */ curve25519_mul_noinline(t0, t0, c); 42 /* 2^250 - 2^50 */ curve25519_square_times(t0, t0, 50); 43 /* 2^250 - 2^0 */ curve25519_mul_noinline(b, t0, b); 44 } 45 46 /* 47 * z^(p - 2) = z(2^255 - 21) 48 */ 49 static void 50 curve25519_recip(bignum25519 out, const bignum25519 z) { 51 bignum25519 ALIGN(16) a,t0,b; 52 53 /* 2 */ curve25519_square_times(a, z, 1); /* a = 2 */ 54 /* 8 */ curve25519_square_times(t0, a, 2); 55 /* 9 */ curve25519_mul_noinline(b, t0, z); /* b = 9 */ 56 /* 11 */ curve25519_mul_noinline(a, b, a); /* a = 11 */ 57 /* 22 */ curve25519_square_times(t0, a, 1); 58 /* 2^5 - 2^0 = 31 */ curve25519_mul_noinline(b, t0, b); 59 /* 2^250 - 2^0 */ curve25519_pow_two5mtwo0_two250mtwo0(b); 60 /* 2^255 - 2^5 */ curve25519_square_times(b, b, 5); 61 /* 2^255 - 21 */ curve25519_mul_noinline(out, b, a); 62 } 63 64 /* 65 * z^((p-5)/8) = z^(2^252 - 3) 66 */ 67 static void 68 curve25519_pow_two252m3(bignum25519 two252m3, const bignum25519 z) { 69 bignum25519 ALIGN(16) b,c,t0; 70 71 /* 2 */ curve25519_square_times(c, z, 1); /* c = 2 */ 72 /* 8 */ curve25519_square_times(t0, c, 2); /* t0 = 8 */ 73 /* 9 */ curve25519_mul_noinline(b, t0, z); /* b = 9 */ 74 /* 11 */ curve25519_mul_noinline(c, b, c); /* c = 11 */ 75 /* 22 */ curve25519_square_times(t0, c, 1); 76 /* 2^5 - 2^0 = 31 */ curve25519_mul_noinline(b, t0, b); 77 /* 2^250 - 2^0 */ curve25519_pow_two5mtwo0_two250mtwo0(b); 78 /* 2^252 - 2^2 */ curve25519_square_times(b, b, 2); 79 /* 2^252 - 3 */ curve25519_mul_noinline(two252m3, b, z); 80 } 81 82 #if __GNUC__ && ED_GCC_VERSION >= 406 83 #pragma GCC diagnostic pop 84 #endif