[tor-commits] [tor/master] Merge branch 'ed25519_ref10_squashed'

nickm at torproject.org nickm at torproject.org
Thu Sep 25 19:12:41 UTC 2014


commit 1c5d680b3d6734e989a92deedbcf2bb46f31f7f9
Merge: 50d15e0 46cda48
Author: Nick Mathewson <nickm at torproject.org>
Date:   Thu Sep 25 15:11:34 2014 -0400

    Merge branch 'ed25519_ref10_squashed'
    
    Conflicts:
    	src/common/include.am
    	src/ext/README

 .gitignore                                   |    4 +
 src/common/crypto_curve25519.c               |  174 +++-
 src/common/crypto_curve25519.h               |   14 +
 src/common/crypto_ed25519.c                  |  353 +++++++
 src/common/crypto_ed25519.h                  |  116 +++
 src/common/crypto_format.c                   |   22 +
 src/common/include.am                        |    7 +-
 src/ext/README                               |    7 +
 src/ext/ed25519/ref10/Makefile               |   41 +
 src/ext/ed25519/ref10/README.tor             |   23 +
 src/ext/ed25519/ref10/api.h                  |    4 +
 src/ext/ed25519/ref10/base.h                 | 1344 ++++++++++++++++++++++++++
 src/ext/ed25519/ref10/base.py                |   65 ++
 src/ext/ed25519/ref10/base2.h                |   40 +
 src/ext/ed25519/ref10/base2.py               |   60 ++
 src/ext/ed25519/ref10/blinding.c             |   76 ++
 src/ext/ed25519/ref10/crypto_hash_sha512.h   |   30 +
 src/ext/ed25519/ref10/crypto_int32.h         |    3 +
 src/ext/ed25519/ref10/crypto_int64.h         |    3 +
 src/ext/ed25519/ref10/crypto_sign.h          |    9 +
 src/ext/ed25519/ref10/crypto_uint32.h        |    3 +
 src/ext/ed25519/ref10/crypto_uint64.h        |    3 +
 src/ext/ed25519/ref10/crypto_verify_32.h     |    5 +
 src/ext/ed25519/ref10/d.h                    |    1 +
 src/ext/ed25519/ref10/d.py                   |   28 +
 src/ext/ed25519/ref10/d2.h                   |    1 +
 src/ext/ed25519/ref10/d2.py                  |   28 +
 src/ext/ed25519/ref10/ed25519_ref10.h        |   30 +
 src/ext/ed25519/ref10/fe.h                   |   56 ++
 src/ext/ed25519/ref10/fe_0.c                 |   19 +
 src/ext/ed25519/ref10/fe_1.c                 |   19 +
 src/ext/ed25519/ref10/fe_add.c               |   57 ++
 src/ext/ed25519/ref10/fe_cmov.c              |   63 ++
 src/ext/ed25519/ref10/fe_copy.c              |   29 +
 src/ext/ed25519/ref10/fe_frombytes.c         |   73 ++
 src/ext/ed25519/ref10/fe_invert.c            |   14 +
 src/ext/ed25519/ref10/fe_isnegative.c        |   16 +
 src/ext/ed25519/ref10/fe_isnonzero.c         |   19 +
 src/ext/ed25519/ref10/fe_mul.c               |  253 +++++
 src/ext/ed25519/ref10/fe_neg.c               |   45 +
 src/ext/ed25519/ref10/fe_pow22523.c          |   13 +
 src/ext/ed25519/ref10/fe_sq.c                |  149 +++
 src/ext/ed25519/ref10/fe_sq2.c               |  160 +++
 src/ext/ed25519/ref10/fe_sub.c               |   57 ++
 src/ext/ed25519/ref10/fe_tobytes.c           |  119 +++
 src/ext/ed25519/ref10/ge.h                   |   95 ++
 src/ext/ed25519/ref10/ge_add.c               |   11 +
 src/ext/ed25519/ref10/ge_add.h               |   97 ++
 src/ext/ed25519/ref10/ge_add.q               |   49 +
 src/ext/ed25519/ref10/ge_double_scalarmult.c |   96 ++
 src/ext/ed25519/ref10/ge_frombytes.c         |   50 +
 src/ext/ed25519/ref10/ge_madd.c              |   11 +
 src/ext/ed25519/ref10/ge_madd.h              |   88 ++
 src/ext/ed25519/ref10/ge_madd.q              |   46 +
 src/ext/ed25519/ref10/ge_msub.c              |   11 +
 src/ext/ed25519/ref10/ge_msub.h              |   88 ++
 src/ext/ed25519/ref10/ge_msub.q              |   46 +
 src/ext/ed25519/ref10/ge_p1p1_to_p2.c        |   12 +
 src/ext/ed25519/ref10/ge_p1p1_to_p3.c        |   13 +
 src/ext/ed25519/ref10/ge_p2_0.c              |    8 +
 src/ext/ed25519/ref10/ge_p2_dbl.c            |   11 +
 src/ext/ed25519/ref10/ge_p2_dbl.h            |   73 ++
 src/ext/ed25519/ref10/ge_p2_dbl.q            |   41 +
 src/ext/ed25519/ref10/ge_p3_0.c              |    9 +
 src/ext/ed25519/ref10/ge_p3_dbl.c            |   12 +
 src/ext/ed25519/ref10/ge_p3_to_cached.c      |   17 +
 src/ext/ed25519/ref10/ge_p3_to_p2.c          |   12 +
 src/ext/ed25519/ref10/ge_p3_tobytes.c        |   14 +
 src/ext/ed25519/ref10/ge_precomp_0.c         |    8 +
 src/ext/ed25519/ref10/ge_scalarmult_base.c   |  109 +++
 src/ext/ed25519/ref10/ge_sub.c               |   11 +
 src/ext/ed25519/ref10/ge_sub.h               |   97 ++
 src/ext/ed25519/ref10/ge_sub.q               |   49 +
 src/ext/ed25519/ref10/ge_tobytes.c           |   14 +
 src/ext/ed25519/ref10/keyconv.c              |   37 +
 src/ext/ed25519/ref10/keypair.c              |   51 +
 src/ext/ed25519/ref10/open.c                 |   42 +
 src/ext/ed25519/ref10/pow22523.h             |  160 +++
 src/ext/ed25519/ref10/pow22523.q             |   61 ++
 src/ext/ed25519/ref10/pow225521.h            |  160 +++
 src/ext/ed25519/ref10/pow225521.q            |   61 ++
 src/ext/ed25519/ref10/q2h.sh                 |    4 +
 src/ext/ed25519/ref10/randombytes.h          |    4 +
 src/ext/ed25519/ref10/sc.h                   |   15 +
 src/ext/ed25519/ref10/sc_muladd.c            |  368 +++++++
 src/ext/ed25519/ref10/sc_reduce.c            |  275 ++++++
 src/ext/ed25519/ref10/sign.c                 |   29 +
 src/ext/ed25519/ref10/sqrtm1.h               |    1 +
 src/ext/ed25519/ref10/sqrtm1.py              |   28 +
 src/ext/include.am                           |   67 ++
 src/test/bench.c                             |   62 ++
 src/test/ed25519_exts_ref.py                 |  234 +++++
 src/test/ed25519_vectors.inc                 |  150 +++
 src/test/include.am                          |    3 +-
 src/test/slow_ed25519.py                     |  115 +++
 src/test/test_crypto.c                       |  364 +++++++
 96 files changed, 7101 insertions(+), 43 deletions(-)

diff --cc .gitignore
index 744c2b8,df94237..9ddd0c5
--- a/.gitignore
+++ b/.gitignore
@@@ -136,8 -133,11 +136,12 @@@ cscope.
  /src/config/sample-server-torrc
  /src/config/torrc
  /src/config/torrc.sample
 +/src/config/torrc.minimal
  
+ # /src/ext/
+ /src/ext/ed25519/ref10/libed25519_ref10.a
+ /src/ext/ed25519/ref10/libed25519_ref10.lib
+ 
  # /src/or/
  /src/or/Makefile
  /src/or/Makefile.in
diff --cc src/common/include.am
index d669cf4,8fc1ff9..5c000e8
--- a/src/common/include.am
+++ b/src/common/include.am
@@@ -114,8 -114,7 +118,9 @@@ COMMONHEADERS = 
    src/common/container.h			\
    src/common/crypto.h				\
    src/common/crypto_curve25519.h		\
+   src/common/crypto_ed25519.h			\
 +  src/common/crypto_pwbox.h			\
 +  src/common/crypto_s2k.h			\
    src/common/di_ops.h				\
    src/common/memarea.h				\
    src/common/linux_syscalls.inc			\
diff --cc src/ext/README
index a263dd7,b759fc2..616716e
--- a/src/ext/README
+++ b/src/ext/README
@@@ -50,7 -50,8 +50,14 @@@ siphash.
      hash algorithm to avoid collision-based DoS attacks against hash
      tables.
  
 +trunnel/*.[ch]
 +
 +    Headers and runtime code for Trunnel, a system for generating
 +    code to encode and decode binary formats.
++
+ ed25519/ref10/*
+ 
+     Daniel Bernsten's portable ref10 implementation of ed25519.
+     Public domain.
+ 
++
diff --cc src/test/test_crypto.c
index 36af725,6c2258e..0c87c88
--- a/src/test/test_crypto.c
+++ b/src/test/test_crypto.c
@@@ -13,9 -12,9 +13,11 @@@
  #include "siphash.h"
  #ifdef CURVE25519_ENABLED
  #include "crypto_curve25519.h"
+ #include "crypto_ed25519.h"
+ #include "ed25519_vectors.inc"
  #endif
 +#include "crypto_s2k.h"
 +#include "crypto_pwbox.h"
  
  extern const char AUTHORITY_SIGNKEY_3[];
  extern const char AUTHORITY_SIGNKEY_A_DIGEST[];
@@@ -1516,9 -1163,365 +1518,365 @@@ test_crypto_curve25519_persist(void *ar
    tor_free(tag);
  }
  
+ static void
+ test_crypto_ed25519_simple(void *arg)
+ {
+   ed25519_keypair_t kp1, kp2;
+   ed25519_public_key_t pub1, pub2;
+   ed25519_secret_key_t sec1, sec2;
+   ed25519_signature_t sig1, sig2;
+   const uint8_t msg[] =
+     "GNU will be able to run Unix programs, "
+     "but will not be identical to Unix.";
+   const uint8_t msg2[] =
+     "Microsoft Windows extends the features of the DOS operating system, "
+     "yet is compatible with most existing applications that run under DOS.";
+   size_t msg_len = strlen((const char*)msg);
+   size_t msg2_len = strlen((const char*)msg2);
+ 
+   (void)arg;
+ 
+   tt_int_op(0, ==, ed25519_secret_key_generate(&sec1, 0));
+   tt_int_op(0, ==, ed25519_secret_key_generate(&sec2, 1));
+ 
+   tt_int_op(0, ==, ed25519_public_key_generate(&pub1, &sec1));
+   tt_int_op(0, ==, ed25519_public_key_generate(&pub2, &sec1));
+ 
 -  test_memeq(pub1.pubkey, pub2.pubkey, sizeof(pub1.pubkey));
++  tt_mem_op(pub1.pubkey, ==, pub2.pubkey, sizeof(pub1.pubkey));
+ 
+   memcpy(&kp1.pubkey, &pub1, sizeof(pub1));
+   memcpy(&kp1.seckey, &sec1, sizeof(sec1));
+   tt_int_op(0, ==, ed25519_sign(&sig1, msg, msg_len, &kp1));
+   tt_int_op(0, ==, ed25519_sign(&sig2, msg, msg_len, &kp1));
+ 
+   /* Ed25519 signatures are deterministic */
 -  test_memeq(sig1.sig, sig2.sig, sizeof(sig1.sig));
++  tt_mem_op(sig1.sig, ==, sig2.sig, sizeof(sig1.sig));
+ 
+   /* Basic signature is valid. */
+   tt_int_op(0, ==, ed25519_checksig(&sig1, msg, msg_len, &pub1));
+ 
+   /* Altered signature doesn't work. */
+   sig1.sig[0] ^= 3;
+   tt_int_op(-1, ==, ed25519_checksig(&sig1, msg, msg_len, &pub1));
+ 
+   /* Wrong public key doesn't work. */
+   tt_int_op(0, ==, ed25519_public_key_generate(&pub2, &sec2));
+   tt_int_op(-1, ==, ed25519_checksig(&sig2, msg, msg_len, &pub2));
+ 
+   /* Wrong message doesn't work. */
+   tt_int_op(0, ==, ed25519_checksig(&sig2, msg, msg_len, &pub1));
+   tt_int_op(-1, ==, ed25519_checksig(&sig2, msg, msg_len-1, &pub1));
+   tt_int_op(-1, ==, ed25519_checksig(&sig2, msg2, msg2_len, &pub1));
+ 
+   /* Batch signature checking works with some bad. */
+   tt_int_op(0, ==, ed25519_keypair_generate(&kp2, 0));
+   tt_int_op(0, ==, ed25519_sign(&sig1, msg, msg_len, &kp2));
+   {
+     ed25519_checkable_t ch[] = {
+       { &pub1, sig2, msg, msg_len }, /*ok*/
+       { &pub1, sig2, msg, msg_len-1 }, /*bad*/
+       { &kp2.pubkey, sig2, msg2, msg2_len }, /*bad*/
+       { &kp2.pubkey, sig1, msg, msg_len }, /*ok*/
+     };
+     int okay[4];
+     tt_int_op(-2, ==, ed25519_checksig_batch(okay, ch, 4));
+     tt_int_op(okay[0], ==, 1);
+     tt_int_op(okay[1], ==, 0);
+     tt_int_op(okay[2], ==, 0);
+     tt_int_op(okay[3], ==, 1);
+     tt_int_op(-2, ==, ed25519_checksig_batch(NULL, ch, 4));
+   }
+ 
+   /* Batch signature checking works with all good. */
+   {
+     ed25519_checkable_t ch[] = {
+       { &pub1, sig2, msg, msg_len }, /*ok*/
+       { &kp2.pubkey, sig1, msg, msg_len }, /*ok*/
+     };
+     int okay[2];
+     tt_int_op(0, ==, ed25519_checksig_batch(okay, ch, 2));
+     tt_int_op(okay[0], ==, 1);
+     tt_int_op(okay[1], ==, 1);
+     tt_int_op(0, ==, ed25519_checksig_batch(NULL, ch, 2));
+   }
+ 
+  done:
+   ;
+ }
+ 
+ static void
+ test_crypto_ed25519_test_vectors(void *arg)
+ {
+   char *mem_op_hex_tmp=NULL;
+   int i;
+   struct {
+     const char *sk;
+     const char *pk;
+     const char *sig;
+     const char *msg;
+   } items[] = {
+     /* These test vectors were generated with the "ref" implementation of
+      * ed25519 from SUPERCOP-20130419 */
+     { "4c6574277320686f706520746865726520617265206e6f206275677320696e20",
+       "f3e0e493b30f56e501aeb868fc912fe0c8b76621efca47a78f6d75875193dd87",
+       "b5d7fd6fd3adf643647ce1fe87a2931dedd1a4e38e6c662bedd35cdd80bfac51"
+         "1b2c7d1ee6bd929ac213014e1a8dc5373854c7b25dbe15ec96bf6c94196fae06",
+       "506c6561736520657863757365206d7920667269656e642e2048652069736e2774"
+       "204e554c2d7465726d696e617465642e"
+     },
+ 
+     { "74686520696d706c656d656e746174696f6e20776869636820617265206e6f74",
+       "407f0025a1e1351a4cb68e92f5c0ebaf66e7aaf93a4006a4d1a66e3ede1cfeac",
+       "02884fde1c3c5944d0ecf2d133726fc820c303aae695adceabf3a1e01e95bf28"
+         "da88c0966f5265e9c6f8edc77b3b96b5c91baec3ca993ccd21a3f64203600601",
+       "506c6561736520657863757365206d7920667269656e642e2048652069736e2774"
+       "204e554c2d7465726d696e617465642e"
+     },
+     { "6578706f73656420627920456e676c697368207465787420617320696e707574",
+       "61681cb5fbd69f9bc5a462a21a7ab319011237b940bc781cdc47fcbe327e7706",
+       "6a127d0414de7510125d4bc214994ffb9b8857a46330832d05d1355e882344ad"
+         "f4137e3ca1f13eb9cc75c887ef2309b98c57528b4acd9f6376c6898889603209",
+       "506c6561736520657863757365206d7920667269656e642e2048652069736e2774"
+       "204e554c2d7465726d696e617465642e"
+     },
+ 
+     /* These come from "sign.input" in ed25519's page */
+     { "5b5a619f8ce1c66d7ce26e5a2ae7b0c04febcd346d286c929e19d0d5973bfef9",
+       "6fe83693d011d111131c4f3fbaaa40a9d3d76b30012ff73bb0e39ec27ab18257",
+       "0f9ad9793033a2fa06614b277d37381e6d94f65ac2a5a94558d09ed6ce922258"
+         "c1a567952e863ac94297aec3c0d0c8ddf71084e504860bb6ba27449b55adc40e",
+       "5a8d9d0a22357e6655f9c785"
+     },
+     { "940c89fe40a81dafbdb2416d14ae469119869744410c3303bfaa0241dac57800",
+       "a2eb8c0501e30bae0cf842d2bde8dec7386f6b7fc3981b8c57c9792bb94cf2dd",
+       "d8bb64aad8c9955a115a793addd24f7f2b077648714f49c4694ec995b330d09d"
+         "640df310f447fd7b6cb5c14f9fe9f490bcf8cfadbfd2169c8ac20d3b8af49a0c",
+       "b87d3813e03f58cf19fd0b6395"
+     },
+     { "9acad959d216212d789a119252ebfe0c96512a23c73bd9f3b202292d6916a738",
+       "cf3af898467a5b7a52d33d53bc037e2642a8da996903fc252217e9c033e2f291",
+       "6ee3fe81e23c60eb2312b2006b3b25e6838e02106623f844c44edb8dafd66ab0"
+         "671087fd195df5b8f58a1d6e52af42908053d55c7321010092748795ef94cf06",
+       "55c7fa434f5ed8cdec2b7aeac173",
+     },
+     { "d5aeee41eeb0e9d1bf8337f939587ebe296161e6bf5209f591ec939e1440c300",
+       "fd2a565723163e29f53c9de3d5e8fbe36a7ab66e1439ec4eae9c0a604af291a5",
+       "f68d04847e5b249737899c014d31c805c5007a62c0a10d50bb1538c5f3550395"
+         "1fbc1e08682f2cc0c92efe8f4985dec61dcbd54d4b94a22547d24451271c8b00",
+       "0a688e79be24f866286d4646b5d81c"
+     },
+ 
+     { NULL, NULL, NULL, NULL}
+   };
+ 
+   (void)arg;
+ 
+   for (i = 0; items[i].pk; ++i) {
+     ed25519_keypair_t kp;
+     ed25519_signature_t sig;
+     uint8_t sk_seed[32];
+     uint8_t *msg;
+     size_t msg_len;
+     base16_decode((char*)sk_seed, sizeof(sk_seed),
+                   items[i].sk, 64);
+     ed25519_secret_key_from_seed(&kp.seckey, sk_seed);
+     tt_int_op(0, ==, ed25519_public_key_generate(&kp.pubkey, &kp.seckey));
+     test_memeq_hex(kp.pubkey.pubkey, items[i].pk);
+ 
+     msg_len = strlen(items[i].msg) / 2;
+     msg = tor_malloc(msg_len);
+     base16_decode((char*)msg, msg_len, items[i].msg, strlen(items[i].msg));
+ 
+     tt_int_op(0, ==, ed25519_sign(&sig, msg, msg_len, &kp));
+     test_memeq_hex(sig.sig, items[i].sig);
+ 
+     tor_free(msg);
+   }
+ 
+  done:
+   tor_free(mem_op_hex_tmp);
+ }
+ 
  #endif
  
  static void
+ test_crypto_ed25519_encode(void *arg)
+ {
+   char buf[ED25519_BASE64_LEN+1];
+   ed25519_keypair_t kp;
+   ed25519_public_key_t pk;
+   char *mem_op_hex_tmp = NULL;
+   (void) arg;
+ 
+   /* Test roundtrip. */
+   tt_int_op(0, ==, ed25519_keypair_generate(&kp, 0));
+   tt_int_op(0, ==, ed25519_public_to_base64(buf, &kp.pubkey));
+   tt_int_op(ED25519_BASE64_LEN, ==, strlen(buf));
+   tt_int_op(0, ==, ed25519_public_from_base64(&pk, buf));
 -  test_memeq(kp.pubkey.pubkey, pk.pubkey, ED25519_PUBKEY_LEN);
++  tt_mem_op(kp.pubkey.pubkey, ==, pk.pubkey, ED25519_PUBKEY_LEN);
+ 
+   /* Test known value. */
+   tt_int_op(0, ==, ed25519_public_from_base64(&pk,
+                              "lVIuIctLjbGZGU5wKMNXxXlSE3cW4kaqkqm04u6pxvM"));
+   test_memeq_hex(pk.pubkey,
+          "95522e21cb4b8db199194e7028c357c57952137716e246aa92a9b4e2eea9c6f3");
+ 
+  done:
+   tor_free(mem_op_hex_tmp);
+ }
+ 
+ static void
+ test_crypto_ed25519_convert(void *arg)
+ {
+   const uint8_t msg[] =
+     "The eyes are not here / There are no eyes here.";
+   const int N = 30;
+   int i;
+   (void)arg;
+ 
+   for (i = 0; i < N; ++i) {
+     curve25519_keypair_t curve25519_keypair;
+     ed25519_keypair_t ed25519_keypair;
+     ed25519_public_key_t ed25519_pubkey;
+ 
+     int bit=0;
+     ed25519_signature_t sig;
+ 
+     tt_int_op(0,==,curve25519_keypair_generate(&curve25519_keypair, i&1));
+     tt_int_op(0,==,ed25519_keypair_from_curve25519_keypair(
+                               &ed25519_keypair, &bit, &curve25519_keypair));
+     tt_int_op(0,==,ed25519_public_key_from_curve25519_public_key(
+                         &ed25519_pubkey, &curve25519_keypair.pubkey, bit));
+     tt_mem_op(ed25519_pubkey.pubkey, ==, ed25519_keypair.pubkey.pubkey, 32);
+ 
+     tt_int_op(0,==,ed25519_sign(&sig, msg, sizeof(msg), &ed25519_keypair));
+     tt_int_op(0,==,ed25519_checksig(&sig, msg, sizeof(msg),
+                                     &ed25519_pubkey));
+ 
+     tt_int_op(-1,==,ed25519_checksig(&sig, msg, sizeof(msg)-1,
+                                      &ed25519_pubkey));
+     sig.sig[0] ^= 15;
+     tt_int_op(-1,==,ed25519_checksig(&sig, msg, sizeof(msg),
+                                      &ed25519_pubkey));
+   }
+ 
+  done:
+   ;
+ }
+ 
+ static void
+ test_crypto_ed25519_blinding(void *arg)
+ {
+   const uint8_t msg[] =
+     "Eyes I dare not meet in dreams / In death's dream kingdom";
+ 
+   const int N = 30;
+   int i;
+   (void)arg;
+ 
+   for (i = 0; i < N; ++i) {
+     uint8_t blinding[32];
+     ed25519_keypair_t ed25519_keypair;
+     ed25519_keypair_t ed25519_keypair_blinded;
+     ed25519_public_key_t ed25519_pubkey_blinded;
+ 
+     ed25519_signature_t sig;
+ 
+     crypto_rand((char*) blinding, sizeof(blinding));
+ 
+     tt_int_op(0,==,ed25519_keypair_generate(&ed25519_keypair, 0));
+     tt_int_op(0,==,ed25519_keypair_blind(&ed25519_keypair_blinded,
+                                          &ed25519_keypair, blinding));
+ 
+     tt_int_op(0,==,ed25519_public_blind(&ed25519_pubkey_blinded,
+                                         &ed25519_keypair.pubkey, blinding));
+ 
+     tt_mem_op(ed25519_pubkey_blinded.pubkey, ==,
+               ed25519_keypair_blinded.pubkey.pubkey, 32);
+ 
+     tt_int_op(0,==,ed25519_sign(&sig, msg, sizeof(msg),
+                                 &ed25519_keypair_blinded));
+ 
+     tt_int_op(0,==,ed25519_checksig(&sig, msg, sizeof(msg),
+                                     &ed25519_pubkey_blinded));
+ 
+     tt_int_op(-1,==,ed25519_checksig(&sig, msg, sizeof(msg)-1,
+                                      &ed25519_pubkey_blinded));
+     sig.sig[0] ^= 15;
+     tt_int_op(-1,==,ed25519_checksig(&sig, msg, sizeof(msg),
+                                      &ed25519_pubkey_blinded));
+   }
+ 
+  done:
+   ;
+ }
+ 
+ static void
+ test_crypto_ed25519_testvectors(void *arg)
+ {
+   unsigned i;
+   char *mem_op_hex_tmp = NULL;
+   (void)arg;
+ 
+   for (i = 0; i < ARRAY_LENGTH(ED25519_SECRET_KEYS); ++i) {
+     uint8_t sk[32];
+     ed25519_secret_key_t esk;
+     ed25519_public_key_t pk, blind_pk, pkfromcurve;
+     ed25519_keypair_t keypair, blind_keypair;
+     curve25519_keypair_t curvekp;
+     uint8_t blinding_param[32];
+     ed25519_signature_t sig;
+     int sign;
+ 
+ #define DECODE(p,s) base16_decode((char*)(p),sizeof(p),(s),strlen(s))
+ #define EQ(a,h) test_memeq_hex((const char*)(a), (h))
+ 
+     tt_int_op(0, ==, DECODE(sk, ED25519_SECRET_KEYS[i]));
+     tt_int_op(0, ==, DECODE(blinding_param, ED25519_BLINDING_PARAMS[i]));
+ 
+     tt_int_op(0, ==, ed25519_secret_key_from_seed(&esk, sk));
+     EQ(esk.seckey, ED25519_EXPANDED_SECRET_KEYS[i]);
+ 
+     tt_int_op(0, ==, ed25519_public_key_generate(&pk, &esk));
+     EQ(pk.pubkey, ED25519_PUBLIC_KEYS[i]);
+ 
+     memcpy(&curvekp.seckey.secret_key, esk.seckey, 32);
+     curve25519_public_key_generate(&curvekp.pubkey, &curvekp.seckey);
+ 
+     tt_int_op(0, ==,
+           ed25519_keypair_from_curve25519_keypair(&keypair, &sign, &curvekp));
+     tt_int_op(0, ==, ed25519_public_key_from_curve25519_public_key(
+                                         &pkfromcurve, &curvekp.pubkey, sign));
+     tt_mem_op(keypair.pubkey.pubkey, ==, pkfromcurve.pubkey, 32);
+     EQ(curvekp.pubkey.public_key, ED25519_CURVE25519_PUBLIC_KEYS[i]);
+ 
+     /* Self-signing */
+     memcpy(&keypair.seckey, &esk, sizeof(esk));
+     memcpy(&keypair.pubkey, &pk, sizeof(pk));
+ 
+     tt_int_op(0, ==, ed25519_sign(&sig, pk.pubkey, 32, &keypair));
+ 
+     EQ(sig.sig, ED25519_SELF_SIGNATURES[i]);
+ 
+     /* Blinding */
+     tt_int_op(0, ==,
+             ed25519_keypair_blind(&blind_keypair, &keypair, blinding_param));
+     tt_int_op(0, ==,
+             ed25519_public_blind(&blind_pk, &pk, blinding_param));
+ 
+     EQ(blind_keypair.seckey.seckey, ED25519_BLINDED_SECRET_KEYS[i]);
+     EQ(blind_pk.pubkey, ED25519_BLINDED_PUBLIC_KEYS[i]);
+ 
+     tt_mem_op(blind_pk.pubkey, ==, blind_keypair.pubkey.pubkey, 32);
+ 
+ #undef DECODE
+ #undef EQ
+   }
+  done:
+   tor_free(mem_op_hex_tmp);
+ }
+ 
+ static void
  test_crypto_siphash(void *arg)
  {
    /* From the reference implementation, taking



More information about the tor-commits mailing list