]> source.dussan.org Git - rspamd.git/commitdiff
Add testing for curve25519 ECDH.
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Mon, 12 Oct 2015 15:18:22 +0000 (16:18 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Mon, 12 Oct 2015 15:18:22 +0000 (16:18 +0100)
src/libcryptobox/CMakeLists.txt
src/libcryptobox/curve25519/LICENSE.md
src/libcryptobox/curve25519/avx.c
src/libcryptobox/curve25519/curve25519-donna-c64.c
src/libcryptobox/curve25519/curve25519-donna.c
src/libcryptobox/curve25519/curve25519.c
src/libcryptobox/curve25519/ref.c

index 224a9deb9201c6ea86ec30e98fff6ea4c70c0643..80e922fb559922ec360da871377b51b22c2d7312 100644 (file)
@@ -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)
index 33a3240ae0f69043bb343219669db18e6c4ae8f9..44705d0bf6725a0bc5ebc5516876b048b5eddc16 100644 (file)
@@ -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
index 615b48111ea33e4c806de4b26b841589687403ba..b06b7223a70f5ca9afed957d9a21882529783330 100644 (file)
@@ -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];
index d98c385c2addaf69c8c527038fe0c43ae1f82ba2..a3a78fcdbfae5311e24dfb03d34a13830535a495 100644 (file)
@@ -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;
 }
index b3b59d860eb97a32a48018e94500f1afebd8b47c..55d1d1730d30033ce2d6543e4e0da22d55fea333 100644 (file)
@@ -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;
 }
index 1870d49878d5abaada3fe72aed791d5a8a41c61a..df795a855c7a362c21e4b68f1e74044480aa9798 100644 (file)
@@ -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
index 7e48209062a2cb5daa432e9952f3328b4482b617..e8e3459f6d9f796679699507586172651056e2cc 100644 (file)
@@ -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;
 }
+