diff options
Diffstat (limited to 'src/libcryptobox')
-rw-r--r-- | src/libcryptobox/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/libcryptobox/curve25519/LICENSE.md | 3 | ||||
-rw-r--r-- | src/libcryptobox/curve25519/avx.c | 8 | ||||
-rw-r--r-- | src/libcryptobox/curve25519/curve25519-donna-c64.c | 10 | ||||
-rw-r--r-- | src/libcryptobox/curve25519/curve25519-donna.c | 9 | ||||
-rw-r--r-- | src/libcryptobox/curve25519/curve25519.c | 48 | ||||
-rw-r--r-- | src/libcryptobox/curve25519/ref.c | 201 |
7 files changed, 184 insertions, 96 deletions
diff --git a/src/libcryptobox/CMakeLists.txt b/src/libcryptobox/CMakeLists.txt index 224a9deb9..80e922fb5 100644 --- a/src/libcryptobox/CMakeLists.txt +++ b/src/libcryptobox/CMakeLists.txt @@ -51,6 +51,7 @@ ENDIF() SET(CURVESRC ${CMAKE_CURRENT_SOURCE_DIR}/curve25519/curve25519-donna-c64.c ${CMAKE_CURRENT_SOURCE_DIR}/curve25519/curve25519-donna.c + ${CMAKE_CURRENT_SOURCE_DIR}/curve25519/ref.c ${CMAKE_CURRENT_SOURCE_DIR}/curve25519/curve25519.c) IF(HAVE_AVX2) diff --git a/src/libcryptobox/curve25519/LICENSE.md b/src/libcryptobox/curve25519/LICENSE.md index 33a3240ae..44705d0bf 100644 --- a/src/libcryptobox/curve25519/LICENSE.md +++ b/src/libcryptobox/curve25519/LICENSE.md @@ -44,3 +44,6 @@ language called qhasm and uses the floating point registers. 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. + +avx code: +public domain implementation by Tung Chou
\ No newline at end of file diff --git a/src/libcryptobox/curve25519/avx.c b/src/libcryptobox/curve25519/avx.c index 615b48111..b06b7223a 100644 --- a/src/libcryptobox/curve25519/avx.c +++ b/src/libcryptobox/curve25519/avx.c @@ -184,10 +184,16 @@ scalarmult_avx (unsigned char *q, fe var[3]; fe51 x_51; fe51 z_51; + unsigned char e[32]; + + memcpy (e, n, 32); + e[0] &= 248; + e[31] &= 127; + e[31] |= 64; fe_frombytes (x1, p); - ladder_avx (var, n); + ladder_avx (var, e); z_51.v[0] = (z2[1] << 26) + z2[0]; z_51.v[1] = (z2[3] << 26) + z2[2]; diff --git a/src/libcryptobox/curve25519/curve25519-donna-c64.c b/src/libcryptobox/curve25519/curve25519-donna-c64.c index d98c385c2..a3a78fcdb 100644 --- a/src/libcryptobox/curve25519/curve25519-donna-c64.c +++ b/src/libcryptobox/curve25519/curve25519-donna-c64.c @@ -480,12 +480,18 @@ static void crecip (felem out, const felem z) int scalarmult_donna64 (u8 *mypublic, const u8 *secret, const u8 *basepoint) { limb bp[5], x[5], z[5], zmone[5]; - int i; + unsigned char e[32]; + + memcpy (e, secret, 32); + e[0] &= 248; + e[31] &= 127; + e[31] |= 64; fexpand (bp, basepoint); - cmult (x, z, secret, bp); + cmult (x, z, e, bp); crecip (zmone, z); fmul (z, x, zmone); fcontract (mypublic, z); + return 0; } diff --git a/src/libcryptobox/curve25519/curve25519-donna.c b/src/libcryptobox/curve25519/curve25519-donna.c index b3b59d860..55d1d1730 100644 --- a/src/libcryptobox/curve25519/curve25519-donna.c +++ b/src/libcryptobox/curve25519/curve25519-donna.c @@ -894,11 +894,18 @@ static void crecip (limb *out, const limb *z) int scalarmult_donna32 (u8 *mypublic, const u8 *secret, const u8 *basepoint) { limb bp[10], x[10], z[11], zmone[10]; + unsigned char e[32]; + + memcpy (e, secret, 32); + e[0] &= 248; + e[31] &= 127; + e[31] |= 64; fexpand (bp, basepoint); - cmult (x, z, secret, bp); + cmult (x, z, e, bp); crecip (zmone, z); fmul (z, x, zmone); fcontract (mypublic, z); + return 0; } diff --git a/src/libcryptobox/curve25519/curve25519.c b/src/libcryptobox/curve25519/curve25519.c index 1870d4987..df795a855 100644 --- a/src/libcryptobox/curve25519/curve25519.c +++ b/src/libcryptobox/curve25519/curve25519.c @@ -53,6 +53,9 @@ CURVE25519_DECLARE(avx); #endif +CURVE25519_DECLARE(ref); +#define CURVE25519_REF CURVE25519_IMPL(0, "ref", ref) + #if !defined(__LP64__) CURVE25519_DECLARE(donna32); #define CURVE25519_GENERIC CURVE25519_IMPL(0, "donna32", donna32) @@ -68,8 +71,52 @@ static const curve25519_impl_t curve25519_list[] = { #endif }; +const guchar secA[] = {0x5A, 0xC9, 0x9F, 0x33, 0x63, 0x2E, 0x5A, 0x76, 0x8D, + 0xE7, 0xE8, 0x1B, 0xF8, 0x54, 0xC2, 0x7C, 0x46, 0xE3, + 0xFB, 0xF2, 0xAB, 0xBA, 0xCD, 0x29, 0xEC, 0x4A, 0xFF, + 0x51, 0x73, 0x69, 0xC6, 0x60}; +const guchar secB[] = {0x47, 0xDC, 0x3D, 0x21, 0x41, 0x74, 0x82, 0x0E, 0x11, + 0x54, 0xB4, 0x9B, 0xC6, 0xCD, 0xB2, 0xAB, 0xD4, 0x5E, + 0xE9, 0x58, 0x17, 0x05, 0x5D, 0x25, 0x5A, 0xA3, 0x58, + 0x31, 0xB7, 0x0D, 0x32, 0x60}; + static const curve25519_impl_t *curve25519_opt = &curve25519_list[0]; +static gboolean +curve25519_test_impl (const curve25519_impl_t *impl) +{ + guchar sec_local[32], sec_ref[32], + pubA[32], pubB[32]; + + curve25519_impl_t ref_impl = CURVE25519_REF; + + ref_impl.scalarmult (pubA, secA, curve25519_basepoint); + ref_impl.scalarmult (pubB, secB, curve25519_basepoint); + + impl->scalarmult (sec_local, secA, pubB); + ref_impl.scalarmult (sec_ref, secA, pubB); + + if (memcmp (sec_local, sec_ref, sizeof (sec_ref)) != 0) { + return FALSE; + } + + impl->scalarmult (sec_local, secB, pubA); + ref_impl.scalarmult (sec_ref, secB, pubA); + + if (memcmp (sec_local, sec_ref, sizeof (sec_ref)) != 0) { + return FALSE; + } + + impl->scalarmult (sec_local, secB, pubA); + impl->scalarmult (sec_ref, secA, pubB); + + if (memcmp (sec_local, sec_ref, sizeof (sec_ref)) != 0) { + return FALSE; + } + + return TRUE; +} + void curve25519_load (void) { @@ -83,6 +130,7 @@ curve25519_load (void) } } } + g_assert (curve25519_test_impl (curve25519_opt)); } int diff --git a/src/libcryptobox/curve25519/ref.c b/src/libcryptobox/curve25519/ref.c index 7e4820906..e8e3459f6 100644 --- a/src/libcryptobox/curve25519/ref.c +++ b/src/libcryptobox/curve25519/ref.c @@ -6,7 +6,10 @@ Derived from public domain code by D. J. Bernstein. 20140216 tweak: Mask top bit of point input. */ -static void add (unsigned int out[32], const unsigned int a[32], +#include "config.h" + +static void add (unsigned int out[32], + const unsigned int a[32], const unsigned int b[32]) { unsigned int j; @@ -21,7 +24,8 @@ static void add (unsigned int out[32], const unsigned int a[32], out[31] = u; } -static void sub (unsigned int out[32], const unsigned int a[32], +static void curve25519_ref_sub (unsigned int out[32], + const unsigned int a[32], const unsigned int b[32]) { unsigned int j; @@ -36,7 +40,7 @@ static void sub (unsigned int out[32], const unsigned int a[32], out[31] = u; } -static void squeeze (unsigned int a[32]) +static void curve25519_ref_squeeze (unsigned int a[32]) { unsigned int j; unsigned int u; @@ -58,10 +62,12 @@ static void squeeze (unsigned int a[32]) a[31] = u; } -static const unsigned int 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 }; +static const unsigned int 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 +}; -static void freeze (unsigned int a[32]) +static void curve25519_ref_freeze (unsigned int a[32]) { unsigned int aorig[32]; unsigned int j; @@ -75,7 +81,8 @@ static void freeze (unsigned int a[32]) a[j] ^= negative & (aorig[j] ^ a[j]); } -static void mult (unsigned int out[32], const unsigned int a[32], +static void curve25519_ref_mult (unsigned int out[32], + const unsigned int a[32], const unsigned int b[32]) { unsigned int i; @@ -90,10 +97,10 @@ static void mult (unsigned int out[32], const unsigned int a[32], u += 38 * a[j] * b[i + 32 - j]; out[i] = u; } - squeeze (out); + curve25519_ref_squeeze (out); } -static void mult121665 (unsigned int out[32], const unsigned int a[32]) +static void curve25519_ref_mult121665 (unsigned int out[32], const unsigned int a[32]) { unsigned int j; unsigned int u; @@ -116,7 +123,7 @@ static void mult121665 (unsigned int out[32], const unsigned int a[32]) out[j] = u; } -static void square (unsigned int out[32], const unsigned int a[32]) +static void curve25519_ref_square (unsigned int out[32], const unsigned int a[32]) { unsigned int i; unsigned int j; @@ -135,11 +142,14 @@ static void square (unsigned int out[32], const unsigned int a[32]) } out[i] = u; } - squeeze (out); + curve25519_ref_squeeze (out); } -static void select (unsigned int p[64], unsigned int q[64], - const unsigned int r[64], const unsigned int s[64], unsigned int b) +static void curve25519_ref_select (unsigned int p[64], + unsigned int q[64], + const unsigned int r[64], + const unsigned int s[64], + unsigned int b) { unsigned int j; unsigned int t; @@ -188,26 +198,26 @@ static void mainloop (unsigned int work[64], const unsigned char e[32]) for (pos = 254; pos >= 0; --pos) { b = e[pos / 8] >> (pos & 7); b &= 1; - select (xzmb, xzm1b, xzm, xzm1, b); + curve25519_ref_select (xzmb, xzm1b, xzm, xzm1, b); add (a0, xzmb, xzmb + 32); - sub (a0 + 32, xzmb, xzmb + 32); + curve25519_ref_sub (a0 + 32, xzmb, xzmb + 32); add (a1, xzm1b, xzm1b + 32); - sub (a1 + 32, xzm1b, xzm1b + 32); - square (b0, a0); - square (b0 + 32, a0 + 32); - mult (b1, a1, a0 + 32); - mult (b1 + 32, a1 + 32, a0); + curve25519_ref_sub (a1 + 32, xzm1b, xzm1b + 32); + curve25519_ref_square (b0, a0); + curve25519_ref_square (b0 + 32, a0 + 32); + curve25519_ref_mult (b1, a1, a0 + 32); + curve25519_ref_mult (b1 + 32, a1 + 32, a0); add (c1, b1, b1 + 32); - sub (c1 + 32, b1, b1 + 32); - square (r, c1 + 32); - sub (s, b0, b0 + 32); - mult121665 (t, s); + curve25519_ref_sub (c1 + 32, b1, b1 + 32); + curve25519_ref_square (r, c1 + 32); + curve25519_ref_sub (s, b0, b0 + 32); + curve25519_ref_mult121665 (t, s); add (u, t, b0); - mult (xznb, b0, b0 + 32); - mult (xznb + 32, s, u); - square (xzn1b, c1); - mult (xzn1b + 32, r, work); - select (xzm, xzm1, xznb, xzn1b, b); + curve25519_ref_mult (xznb, b0, b0 + 32); + curve25519_ref_mult (xznb + 32, s, u); + curve25519_ref_square (xzn1b, c1); + curve25519_ref_mult (xzn1b + 32, r, work); + curve25519_ref_select (xzm, xzm1, xznb, xzn1b, b); } for (j = 0; j < 64; ++j) @@ -228,91 +238,98 @@ static void recip (unsigned int out[32], const unsigned int z[32]) unsigned int t1[32]; int i; - /* 2 */square (z2, z); - /* 4 */square (t1, z2); - /* 8 */square (t0, t1); - /* 9 */mult (z9, t0, z); - /* 11 */mult (z11, z9, z2); - /* 22 */square (t0, z11); - /* 2^5 - 2^0 = 31 */mult (z2_5_0, t0, z9); - - /* 2^6 - 2^1 */square (t0, z2_5_0); - /* 2^7 - 2^2 */square (t1, t0); - /* 2^8 - 2^3 */square (t0, t1); - /* 2^9 - 2^4 */square (t1, t0); - /* 2^10 - 2^5 */square (t0, t1); - /* 2^10 - 2^0 */mult (z2_10_0, t0, z2_5_0); - - /* 2^11 - 2^1 */square (t0, z2_10_0); - /* 2^12 - 2^2 */square (t1, t0); - /* 2^20 - 2^10 */for (i = 2; i < 10; i += 2) { - square (t0, t1); - square (t1, t0); + /* 2 */ curve25519_ref_square (z2, z); + /* 4 */ curve25519_ref_square (t1, z2); + /* 8 */ curve25519_ref_square (t0, t1); + /* 9 */ curve25519_ref_mult (z9, t0, z); + /* 11 */ curve25519_ref_mult (z11, z9, z2); + /* 22 */ curve25519_ref_square (t0, z11); + /* 2^5 - 2^0 = 31 */ curve25519_ref_mult (z2_5_0, t0, z9); + + /* 2^6 - 2^1 */ curve25519_ref_square (t0, z2_5_0); + /* 2^7 - 2^2 */ curve25519_ref_square (t1, t0); + /* 2^8 - 2^3 */ curve25519_ref_square (t0, t1); + /* 2^9 - 2^4 */ curve25519_ref_square (t1, t0); + /* 2^10 - 2^5 */ curve25519_ref_square (t0, t1); + /* 2^10 - 2^0 */ curve25519_ref_mult (z2_10_0, t0, z2_5_0); + + /* 2^11 - 2^1 */ curve25519_ref_square (t0, z2_10_0); + /* 2^12 - 2^2 */ curve25519_ref_square (t1, t0); + /* 2^20 - 2^10 */ for (i = 2; i < 10; i += 2) { + curve25519_ref_square (t0, t1); + curve25519_ref_square (t1, t0); } - /* 2^20 - 2^0 */mult (z2_20_0, t1, z2_10_0); + /* 2^20 - 2^0 */ curve25519_ref_mult (z2_20_0, t1, z2_10_0); - /* 2^21 - 2^1 */square (t0, z2_20_0); - /* 2^22 - 2^2 */square (t1, t0); - /* 2^40 - 2^20 */for (i = 2; i < 20; i += 2) { - square (t0, t1); - square (t1, t0); + /* 2^21 - 2^1 */ curve25519_ref_square (t0, z2_20_0); + /* 2^22 - 2^2 */ curve25519_ref_square (t1, t0); + /* 2^40 - 2^20 */ for (i = 2; i < 20; i += 2) { + curve25519_ref_square (t0, t1); + curve25519_ref_square (t1, t0); } - /* 2^40 - 2^0 */mult (t0, t1, z2_20_0); + /* 2^40 - 2^0 */ curve25519_ref_mult (t0, t1, z2_20_0); - /* 2^41 - 2^1 */square (t1, t0); - /* 2^42 - 2^2 */square (t0, t1); - /* 2^50 - 2^10 */for (i = 2; i < 10; i += 2) { - square (t1, t0); - square (t0, t1); + /* 2^41 - 2^1 */ curve25519_ref_square (t1, t0); + /* 2^42 - 2^2 */ curve25519_ref_square (t0, t1); + /* 2^50 - 2^10 */ for (i = 2; i < 10; i += 2) { + curve25519_ref_square (t1, t0); + curve25519_ref_square (t0, t1); } - /* 2^50 - 2^0 */mult (z2_50_0, t0, z2_10_0); + /* 2^50 - 2^0 */ curve25519_ref_mult (z2_50_0, t0, z2_10_0); - /* 2^51 - 2^1 */square (t0, z2_50_0); - /* 2^52 - 2^2 */square (t1, t0); - /* 2^100 - 2^50 */for (i = 2; i < 50; i += 2) { - square (t0, t1); - square (t1, t0); + /* 2^51 - 2^1 */ curve25519_ref_square (t0, z2_50_0); + /* 2^52 - 2^2 */ curve25519_ref_square (t1, t0); + /* 2^100 - 2^50 */ for (i = 2; i < 50; i += 2) { + curve25519_ref_square (t0, t1); + curve25519_ref_square (t1, t0); } - /* 2^100 - 2^0 */mult (z2_100_0, t1, z2_50_0); + /* 2^100 - 2^0 */ curve25519_ref_mult (z2_100_0, t1, z2_50_0); - /* 2^101 - 2^1 */square (t1, z2_100_0); - /* 2^102 - 2^2 */square (t0, t1); - /* 2^200 - 2^100 */for (i = 2; i < 100; i += 2) { - square (t1, t0); - square (t0, t1); + /* 2^101 - 2^1 */ curve25519_ref_square (t1, z2_100_0); + /* 2^102 - 2^2 */ curve25519_ref_square (t0, t1); + /* 2^200 - 2^100 */ for (i = 2; i < 100; i += 2) { + curve25519_ref_square (t1, t0); + curve25519_ref_square (t0, t1); } - /* 2^200 - 2^0 */mult (t1, t0, z2_100_0); + /* 2^200 - 2^0 */ curve25519_ref_mult (t1, t0, z2_100_0); - /* 2^201 - 2^1 */square (t0, t1); - /* 2^202 - 2^2 */square (t1, t0); - /* 2^250 - 2^50 */for (i = 2; i < 50; i += 2) { - square (t0, t1); - square (t1, t0); + /* 2^201 - 2^1 */ curve25519_ref_square (t0, t1); + /* 2^202 - 2^2 */ curve25519_ref_square (t1, t0); + /* 2^250 - 2^50 */ for (i = 2; i < 50; i += 2) { + curve25519_ref_square (t0, t1); + curve25519_ref_square (t1, t0); } - /* 2^250 - 2^0 */mult (t0, t1, z2_50_0); - - /* 2^251 - 2^1 */square (t1, t0); - /* 2^252 - 2^2 */square (t0, t1); - /* 2^253 - 2^3 */square (t1, t0); - /* 2^254 - 2^4 */square (t0, t1); - /* 2^255 - 2^5 */square (t1, t0); - /* 2^255 - 21 */mult (out, t1, z11); + /* 2^250 - 2^0 */ curve25519_ref_mult (t0, t1, z2_50_0); + + /* 2^251 - 2^1 */ curve25519_ref_square (t1, t0); + /* 2^252 - 2^2 */ curve25519_ref_square (t0, t1); + /* 2^253 - 2^3 */ curve25519_ref_square (t1, t0); + /* 2^254 - 2^4 */ curve25519_ref_square (t0, t1); + /* 2^255 - 2^5 */ curve25519_ref_square (t1, t0); + /* 2^255 - 21 */ curve25519_ref_mult (out, t1, z11); } -int curve25519 (unsigned char *q, const unsigned char *n, +int scalarmult_ref (unsigned char *q, + const unsigned char *n, const unsigned char *p) { unsigned int work[96]; + unsigned char e[32]; unsigned int i; - + for (i = 0; i < 32; ++i) + e[i] = n[i]; + e[0] &= 248; + e[31] &= 127; + e[31] |= 64; for (i = 0; i < 32; ++i) work[i] = p[i]; work[31] &= 127; - mainloop (work, n); + mainloop (work, e); recip (work + 32, work + 32); - mult (work + 64, work, work + 32); - freeze (work + 64); + curve25519_ref_mult (work + 64, work, work + 32); + curve25519_ref_freeze (work + 64); for (i = 0; i < 32; ++i) q[i] = work[64 + i]; return 0; } + |