Beispiel #1
0
static void
test_routerkeys_cross_certify_ntor(void *args)
{
  (void) args;

  tor_cert_t *cert = NULL;
  curve25519_keypair_t onion_keys;
  ed25519_public_key_t master_key;
  ed25519_public_key_t onion_check_key;
  time_t now = time(NULL);
  int sign;

  tt_int_op(0, OP_EQ, ed25519_public_from_base64(&master_key,
                               "IamwritingthesetestsOnARainyAfternoonin2014"));
  tt_int_op(0, OP_EQ, curve25519_keypair_generate(&onion_keys, 0));
  cert = make_ntor_onion_key_crosscert(&onion_keys,
                                       &master_key,
                                       now, 10000,
                                       &sign);
  tt_assert(cert);
  tt_assert(sign == 0 || sign == 1);
  tt_int_op(cert->cert_type, OP_EQ, CERT_TYPE_ONION_ID);
  tt_int_op(1, OP_EQ, ed25519_pubkey_eq(&cert->signed_key, &master_key));
  tt_int_op(0, OP_EQ, ed25519_public_key_from_curve25519_public_key(
                               &onion_check_key, &onion_keys.pubkey, sign));
  tt_int_op(0, OP_EQ, tor_cert_checksig(cert, &onion_check_key, now));

 done:
  tor_cert_free(cert);
}
Beispiel #2
0
/**
 * Given a curve25519 keypair in <b>inp</b>, generate a corresponding
 * ed25519 keypair in <b>out</b>, and set <b>signbit_out</b> to the
 * sign bit of the X coordinate of the ed25519 key.
 *
 * NOTE THAT IT IS PROBABLY NOT SAFE TO USE THE GENERATED KEY FOR ANYTHING
 * OUTSIDE OF WHAT'S PRESENTED IN PROPOSAL 228.  In particular, it's probably
 * not a great idea to use it to sign attacker-supplied anything.
 */
int
ed25519_keypair_from_curve25519_keypair(ed25519_keypair_t *out,
                                        int *signbit_out,
                                        const curve25519_keypair_t *inp)
{
  const char string[] = "Derive high part of ed25519 key from curve25519 key";
  ed25519_public_key_t pubkey_check;
  SHA512_CTX ctx;
  uint8_t sha512_output[64];

  memcpy(out->seckey.seckey, inp->seckey.secret_key, 32);
  SHA512_Init(&ctx);
  SHA512_Update(&ctx, out->seckey.seckey, 32);
  SHA512_Update(&ctx, string, sizeof(string));
  SHA512_Final(sha512_output, &ctx);
  memcpy(out->seckey.seckey + 32, sha512_output, 32);

  ed25519_public_key_generate(&out->pubkey, &out->seckey);

  *signbit_out = out->pubkey.pubkey[31] >> 7;

  ed25519_public_key_from_curve25519_public_key(&pubkey_check, &inp->pubkey,
                                                *signbit_out);

  tor_assert(fast_memeq(pubkey_check.pubkey, out->pubkey.pubkey, 32));

  memwipe(&pubkey_check, 0, sizeof(pubkey_check));
  memwipe(&ctx, 0, sizeof(ctx));
  memwipe(sha512_output, 0, sizeof(sha512_output));

  return 0;
}
Beispiel #3
0
static void
bench_ed25519_impl(void)
{
  uint64_t start, end;
  const int iters = 1<<12;
  int i;
  const uint8_t msg[] = "but leaving, could not tell what they had heard";
  ed25519_signature_t sig;
  ed25519_keypair_t kp;
  curve25519_keypair_t curve_kp;
  ed25519_public_key_t pubkey_tmp;

  ed25519_secret_key_generate(&kp.seckey, 0);
  start = perftime();
  for (i = 0; i < iters; ++i) {
    ed25519_public_key_generate(&kp.pubkey, &kp.seckey);
  }
  end = perftime();
  printf("Generate public key: %.2f usec\n",
         MICROCOUNT(start, end, iters));

  start = perftime();
  for (i = 0; i < iters; ++i) {
    ed25519_sign(&sig, msg, sizeof(msg), &kp);
  }
  end = perftime();
  printf("Sign a short message: %.2f usec\n",
         MICROCOUNT(start, end, iters));

  start = perftime();
  for (i = 0; i < iters; ++i) {
    ed25519_checksig(&sig, msg, sizeof(msg), &kp.pubkey);
  }
  end = perftime();
  printf("Verify signature: %.2f usec\n",
         MICROCOUNT(start, end, iters));

  curve25519_keypair_generate(&curve_kp, 0);
  start = perftime();
  for (i = 0; i < iters; ++i) {
    ed25519_public_key_from_curve25519_public_key(&pubkey_tmp,
                                                  &curve_kp.pubkey, 1);
  }
  end = perftime();
  printf("Convert public point from curve25519: %.2f usec\n",
         MICROCOUNT(start, end, iters));

  curve25519_keypair_generate(&curve_kp, 0);
  start = perftime();
  for (i = 0; i < iters; ++i) {
    ed25519_public_blind(&pubkey_tmp, &kp.pubkey, msg);
  }
  end = perftime();
  printf("Blind a public key: %.2f usec\n",
         MICROCOUNT(start, end, iters));
}
Beispiel #4
0
static void
test_crypto_ed25519_fuzz_donna(void *arg)
{
  const unsigned iters = 1024;
  uint8_t msg[1024];
  unsigned i;
  (void)arg;

  tt_uint_op(iters, OP_EQ, sizeof(msg));
  crypto_rand((char*) msg, sizeof(msg));

  /* Fuzz Ed25519-donna vs ref10, alternating the implementation used to
   * generate keys/sign per iteration.
   */
  for (i = 0; i < iters; ++i) {
    const int use_donna = i & 1;
    uint8_t blinding[32];
    curve25519_keypair_t ckp;
    ed25519_keypair_t kp, kp_blind, kp_curve25519;
    ed25519_public_key_t pk, pk_blind, pk_curve25519;
    ed25519_signature_t sig, sig_blind;
    int bit = 0;

    crypto_rand((char*) blinding, sizeof(blinding));

    /* Impl. A:
     *  1. Generate a keypair.
     *  2. Blinded the keypair.
     *  3. Sign a message (unblinded).
     *  4. Sign a message (blinded).
     *  5. Generate a curve25519 keypair, and convert it to Ed25519.
     */
    ed25519_set_impl_params(use_donna);
    tt_int_op(0, OP_EQ, ed25519_keypair_generate(&kp, i&1));
    tt_int_op(0, OP_EQ, ed25519_keypair_blind(&kp_blind, &kp, blinding));
    tt_int_op(0, OP_EQ, ed25519_sign(&sig, msg, i, &kp));
    tt_int_op(0, OP_EQ, ed25519_sign(&sig_blind, msg, i, &kp_blind));

    tt_int_op(0, OP_EQ, curve25519_keypair_generate(&ckp, i&1));
    tt_int_op(0, OP_EQ, ed25519_keypair_from_curve25519_keypair(
            &kp_curve25519, &bit, &ckp));

    /* Impl. B:
     *  1. Validate the public key by rederiving it.
     *  2. Validate the blinded public key by rederiving it.
     *  3. Validate the unblinded signature (and test a invalid signature).
     *  4. Validate the blinded signature.
     *  5. Validate the public key (from Curve25519) by rederiving it.
     */
    ed25519_set_impl_params(!use_donna);
    tt_int_op(0, OP_EQ, ed25519_public_key_generate(&pk, &kp.seckey));
    tt_mem_op(pk.pubkey, OP_EQ, kp.pubkey.pubkey, 32);

    tt_int_op(0, OP_EQ, ed25519_public_blind(&pk_blind, &kp.pubkey, blinding));
    tt_mem_op(pk_blind.pubkey, OP_EQ, kp_blind.pubkey.pubkey, 32);

    tt_int_op(0, OP_EQ, ed25519_checksig(&sig, msg, i, &pk));
    sig.sig[0] ^= 15;
    tt_int_op(-1, OP_EQ, ed25519_checksig(&sig, msg, sizeof(msg), &pk));

    tt_int_op(0, OP_EQ, ed25519_checksig(&sig_blind, msg, i, &pk_blind));

    tt_int_op(0, OP_EQ, ed25519_public_key_from_curve25519_public_key(
            &pk_curve25519, &ckp.pubkey, bit));
    tt_mem_op(pk_curve25519.pubkey, OP_EQ, kp_curve25519.pubkey.pubkey, 32);
  }

 done:
  ;
}