static void bench_dsa_sign (void *p) { struct dsa_ctx *ctx = p; struct dsa_signature s; dsa_signature_init (&s); dsa_sign (&ctx->params, ctx->key, &ctx->lfib, (nettle_random_func *)knuth_lfib_random, SHA1_DIGEST_SIZE, ctx->digest, &s); dsa_signature_clear (&s); }
static void bench_ecdsa_sign (void *p) { struct ecdsa_ctx *ctx = p; struct dsa_signature s; dsa_signature_init (&s); ecdsa_sign (&ctx->key, &ctx->rctx, (nettle_random_func *) knuth_lfib_random, ctx->digest_size, ctx->digest, &s); dsa_signature_clear (&s); }
void test_dsa160(const struct dsa_public_key *pub, const struct dsa_private_key *key, const struct dsa_signature *expected) { struct sha1_ctx sha1; struct dsa_signature signature; struct knuth_lfib_ctx lfib; sha1_init(&sha1); dsa_signature_init(&signature); knuth_lfib_init(&lfib, 1111); sha1_update(&sha1, LDATA("The magic words are squeamish ossifrage")); ASSERT (dsa_sha1_sign(pub, key, &lfib, (nettle_random_func *) knuth_lfib_random, &sha1, &signature)); if (verbose) { fprintf(stderr, "dsa160 signature: "); mpz_out_str(stderr, 16, signature.r); fprintf(stderr, ", "); mpz_out_str(stderr, 16, signature.s); fprintf(stderr, "\n"); } if (expected) ASSERT (mpz_cmp (signature.r, expected->r) == 0 && mpz_cmp (signature.s, expected->s) == 0); /* Try bad data */ ASSERT (!DSA_VERIFY(pub, sha1, "The magick words are squeamish ossifrage", &signature)); /* Try correct data */ ASSERT (DSA_VERIFY(pub, sha1, "The magic words are squeamish ossifrage", &signature)); /* Try bad signature */ mpz_togglebit(signature.r, 17); ASSERT (!DSA_VERIFY(pub, sha1, "The magic words are squeamish ossifrage", &signature)); dsa_signature_clear(&signature); }
static void test_ecdsa (const struct ecc_curve *ecc, /* Private key */ const char *sz, /* Random nonce */ const char *sk, /* Hash */ const struct tstring *h, /* Expected signature */ const char *r, const char *s) { struct dsa_signature ref; mpz_t z; mpz_t k; mp_limb_t *rp = xalloc_limbs (ecc->size); mp_limb_t *sp = xalloc_limbs (ecc->size); mp_limb_t *scratch = xalloc_limbs (ecc_ecdsa_sign_itch (ecc)); dsa_signature_init (&ref); mpz_init_set_str (z, sz, 16); mpz_init_set_str (k, sk, 16); ecc_ecdsa_sign (ecc, mpz_limbs_read_n (z, ecc->size), mpz_limbs_read_n (k, ecc->size), h->length, h->data, rp, sp, scratch); mpz_set_str (ref.r, r, 16); mpz_set_str (ref.s, s, 16); if (mpz_limbs_cmp (ref.r, rp, ecc->size) != 0 || mpz_limbs_cmp (ref.s, sp, ecc->size) != 0) { fprintf (stderr, "_ecdsa_sign failed, bit_size = %u\n", ecc->bit_size); gmp_fprintf (stderr, "r = %Nx\n", rp, ecc->size); gmp_fprintf (stderr, "s = %Nx\n", sp, ecc->size); gmp_fprintf (stderr, "ref.r = %Zx\n", ref.r); gmp_fprintf (stderr, "ref.s = %Zx\n", ref.s); abort(); } free (rp); free (sp); free (scratch); dsa_signature_clear (&ref); mpz_clear (k); mpz_clear (z); }
static void * bench_dsa_init (unsigned size) { struct dsa_ctx *ctx; struct sexp_iterator i; unsigned char dsa1024[] = "{KDExOnByaXZhdGUta2V5KDM6ZHNhKDE6cDEyOToA2q4hOXEClLMXXMOl9xaPcGC/GeGmCMv" " VCaaW0uWc50DvvmJDPQPdCehyfZr/1dv2UDbx06TC7ls/IFd+BsDzGBRxqIQ44J20cn+0gt" " NMIXAocE1QhCCFaT5gXrk8zMlqBEGaP3RdpgxNanEXkTj2Wma8r1GtrLX3HPafio62jicpK" " DE6cTIxOgDN9pcW3exdVAesC9WsxwCGoJK24ykoMTpnMTI5OgCJr9DmKdiE0WJZB7HACESv" " Tpg1qZgc8E15byQ+OsHUyOTRrJRTcrgKZJW7dFRJ9cXmyi7XYCd3bJtu/2HRHLY1vd4qMvU" " 7Y8x08ooCoABGV7nGqcmdQfEho1OY6TZh2NikmPKZLeur3PZFpcZ8Dl+KVWtwC55plNC7Om" " iAQy8MaCkoMTp5MTI5OgDakk0LOUQwzOKt9FHOBmBKrWsvTm7549eScTUqH4OMm3btjUsXz" " MmlqEe+imwQCOW/AE3Xw9pXZeETWK0jlLe8k5vnKcNskerFwZ1eQKtOPPQty8IqQ9PEfF6B" " 0oVQiJg2maHUDWFnDkIBd7ZR1z8FnZMUxH9mH4kEUo6YQgtCdykoMTp4MjA6cOl3ijiiMjI" " pesFD8jxESWb2mn8pKSk=}"; ctx = xalloc(sizeof(*ctx)); dsa_params_init (&ctx->params); mpz_init (ctx->pub); mpz_init (ctx->key); dsa_signature_init (&ctx->s); knuth_lfib_init (&ctx->lfib, 1); if (size != 1024) die ("Internal error.\n"); if (! (sexp_transport_iterator_first (&i, sizeof(dsa1024) - 1, dsa1024) && sexp_iterator_check_type (&i, "private-key") && sexp_iterator_check_type (&i, "dsa") && dsa_keypair_from_sexp_alist (&ctx->params, ctx->pub, ctx->key, 0, DSA_SHA1_Q_BITS, &i)) ) die ("Internal error.\n"); ctx->digest = hash_string (&nettle_sha1, "foo"); dsa_sign (&ctx->params, ctx->key, &ctx->lfib, (nettle_random_func *)knuth_lfib_random, SHA1_DIGEST_SIZE, ctx->digest, &ctx->s); return ctx; }
static void * bench_ecdsa_init (unsigned size) { struct ecdsa_ctx *ctx; const struct ecc_curve *ecc; const char *xs; const char *ys; const char *zs; mpz_t x, y, z; ctx = xalloc (sizeof(*ctx)); dsa_signature_init (&ctx->s); knuth_lfib_init (&ctx->rctx, 17); switch (size) { case 192: ecc = &_nettle_secp_192r1; xs = "8e8e07360350fb6b7ad8370cfd32fa8c6bba785e6e200599"; ys = "7f82ddb58a43d59ff8dc66053002b918b99bd01bd68d6736"; zs = "f2e620e086d658b4b507996988480917640e4dc107808bdd"; ctx->digest = hash_string (&nettle_sha1, "abc"); ctx->digest_size = 20; break; case 224: ecc = &_nettle_secp_224r1; xs = "993bf363f4f2bc0f255f22563980449164e9c894d9efd088d7b77334"; ys = "b75fff9849997d02d135140e4d0030944589586e22df1fc4b629082a"; zs = "cdfd01838247f5de3cc70b688418046f10a2bfaca6de9ec836d48c27"; ctx->digest = hash_string (&nettle_sha224, "abc"); ctx->digest_size = 28; break; /* From RFC 4754 */ case 256: ecc = &_nettle_secp_256r1; xs = "2442A5CC 0ECD015F A3CA31DC 8E2BBC70 BF42D60C BCA20085 E0822CB0 4235E970"; ys = "6FC98BD7 E50211A4 A27102FA 3549DF79 EBCB4BF2 46B80945 CDDFE7D5 09BBFD7D"; zs = "DC51D386 6A15BACD E33D96F9 92FCA99D A7E6EF09 34E70975 59C27F16 14C88A7F"; ctx->digest = hash_string (&nettle_sha256, "abc"); ctx->digest_size = 32; break; case 384: ecc = &_nettle_secp_384r1; xs = "96281BF8 DD5E0525 CA049C04 8D345D30 82968D10 FEDF5C5A CA0C64E6 465A97EA" "5CE10C9D FEC21797 41571072 1F437922"; ys = "447688BA 94708EB6 E2E4D59F 6AB6D7ED FF9301D2 49FE49C3 3096655F 5D502FAD" "3D383B91 C5E7EDAA 2B714CC9 9D5743CA"; zs = "0BEB6466 34BA8773 5D77AE48 09A0EBEA 865535DE 4C1E1DCB 692E8470 8E81A5AF" "62E528C3 8B2A81B3 5309668D 73524D9F"; ctx->digest = hash_string (&nettle_sha384, "abc"); ctx->digest_size = 48; break; case 521: ecc = &_nettle_secp_521r1; xs = "0151518F 1AF0F563 517EDD54 85190DF9 5A4BF57B 5CBA4CF2 A9A3F647 4725A35F" "7AFE0A6D DEB8BEDB CD6A197E 592D4018 8901CECD 650699C9 B5E456AE A5ADD190" "52A8"; ys = "006F3B14 2EA1BFFF 7E2837AD 44C9E4FF 6D2D34C7 3184BBAD 90026DD5 E6E85317" "D9DF45CA D7803C6C 20035B2F 3FF63AFF 4E1BA64D 1C077577 DA3F4286 C58F0AEA" "E643"; zs = "0065FDA3 409451DC AB0A0EAD 45495112 A3D813C1 7BFD34BD F8C1209D 7DF58491" "20597779 060A7FF9 D704ADF7 8B570FFA D6F062E9 5C7E0C5D 5481C5B1 53B48B37" "5FA1"; ctx->digest = hash_string (&nettle_sha512, "abc"); ctx->digest_size = 64; break; default: die ("Internal error.\n"); } ecc_point_init (&ctx->pub, ecc); ecc_scalar_init (&ctx->key, ecc); mpz_init_set_str (x, xs, 16); mpz_init_set_str (y, ys, 16); mpz_init_set_str (z, zs, 16); ecc_point_set (&ctx->pub, x, y); ecc_scalar_set (&ctx->key, z); mpz_clear (x); mpz_clear (y); mpz_clear (z); ecdsa_sign (&ctx->key, &ctx->rctx, (nettle_random_func *) knuth_lfib_random, ctx->digest_size, ctx->digest, &ctx->s); return ctx; }
void test_main (void) { unsigned i; struct knuth_lfib_ctx rctx; struct dsa_signature signature; struct tstring *digest; knuth_lfib_init (&rctx, 4711); dsa_signature_init (&signature); digest = SHEX (/* sha256("abc") */ "BA7816BF 8F01CFEA 414140DE 5DAE2223" "B00361A3 96177A9C B410FF61 F20015AD"); for (i = 0; ecc_curves[i]; i++) { const struct ecc_curve *ecc = ecc_curves[i]; struct ecc_point pub; struct ecc_scalar key; if (verbose) fprintf (stderr, "Curve %d\n", ecc->bit_size); ecc_point_init (&pub, ecc); ecc_scalar_init (&key, ecc); ecdsa_generate_keypair (&pub, &key, &rctx, (nettle_random_func *) knuth_lfib_random); if (verbose) { gmp_fprintf (stderr, "Public key:\nx = %Nx\ny = %Nx\n", pub.p, ecc->size, pub.p + ecc->size, ecc->size); gmp_fprintf (stderr, "Private key: %Nx\n", key.p, ecc->size); } if (!ecc_valid_p (&pub)) die ("ecdsa_generate_keypair produced an invalid point.\n"); ecdsa_sign (&key, &rctx, (nettle_random_func *) knuth_lfib_random, digest->length, digest->data, &signature); if (!ecdsa_verify (&pub, digest->length, digest->data, &signature)) die ("ecdsa_verify failed.\n"); digest->data[3] ^= 17; if (ecdsa_verify (&pub, digest->length, digest->data, &signature)) die ("ecdsa_verify returned success with invalid digest.\n"); digest->data[3] ^= 17; mpz_combit (signature.r, 117); if (ecdsa_verify (&pub, digest->length, digest->data, &signature)) die ("ecdsa_verify returned success with invalid signature.r.\n"); mpz_combit (signature.r, 117); mpz_combit (signature.s, 93); if (ecdsa_verify (&pub, digest->length, digest->data, &signature)) die ("ecdsa_verify returned success with invalid signature.s.\n"); ecc_point_clear (&pub); ecc_scalar_clear (&key); } dsa_signature_clear (&signature); }
/* in case of DSA puts into data, r,s */ static int _wrap_nettle_pk_sign (gnutls_pk_algorithm_t algo, gnutls_datum_t * signature, const gnutls_datum_t * vdata, const gnutls_pk_params_st * pk_params) { int ret; unsigned int hash; unsigned int hash_len; switch (algo) { case GNUTLS_PK_EC: /* we do ECDSA */ { ecc_key priv; struct dsa_signature sig; int curve_id = pk_params->flags; if (is_supported_curve(curve_id) == 0) return gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE); _ecc_params_to_privkey(pk_params, &priv); dsa_signature_init (&sig); hash = _gnutls_dsa_q_to_hash (algo, pk_params, &hash_len); if (hash_len > vdata->size) { gnutls_assert (); _gnutls_debug_log("Security level of algorithm requires hash %s(%d) or better\n", gnutls_mac_get_name(hash), hash_len); hash_len = vdata->size; } ret = ecc_sign_hash(vdata->data, hash_len, &sig, NULL, rnd_func, &priv, curve_id); if (ret != 0) { gnutls_assert (); ret = GNUTLS_E_PK_SIGN_FAILED; goto ecdsa_fail; } ret = _gnutls_encode_ber_rs (signature, &sig.r, &sig.s); ecdsa_fail: dsa_signature_clear (&sig); _ecc_params_clear( &priv); if (ret < 0) { gnutls_assert (); goto cleanup; } break; } case GNUTLS_PK_DSA: { struct dsa_public_key pub; struct dsa_private_key priv; struct dsa_signature sig; memset(&priv, 0, sizeof(priv)); memset(&pub, 0, sizeof(pub)); _dsa_params_to_pubkey (pk_params, &pub); _dsa_params_to_privkey (pk_params, &priv); dsa_signature_init (&sig); hash = _gnutls_dsa_q_to_hash (algo, pk_params, &hash_len); if (hash_len > vdata->size) { gnutls_assert (); _gnutls_debug_log("Security level of algorithm requires hash %s(%d) or better\n", gnutls_mac_get_name(hash), hash_len); hash_len = vdata->size; } ret = _dsa_sign (&pub, &priv, NULL, rnd_func, hash_len, vdata->data, &sig); if (ret == 0) { gnutls_assert (); ret = GNUTLS_E_PK_SIGN_FAILED; goto dsa_fail; } ret = _gnutls_encode_ber_rs (signature, &sig.r, &sig.s); dsa_fail: dsa_signature_clear (&sig); if (ret < 0) { gnutls_assert (); goto cleanup; } break; } case GNUTLS_PK_RSA: { struct rsa_private_key priv; struct rsa_public_key pub; mpz_t s; _rsa_params_to_privkey (pk_params, &priv); _rsa_params_to_pubkey (pk_params, &pub); mpz_init(s); ret = rsa_pkcs1_sign_tr(&pub, &priv, NULL, rnd_func, vdata->size, vdata->data, s); if (ret == 0) { gnutls_assert(); ret = GNUTLS_E_PK_SIGN_FAILED; goto rsa_fail; } ret = _gnutls_mpi_dprint (s, signature); rsa_fail: mpz_clear(s); if (ret < 0) { gnutls_assert (); goto cleanup; } break; } default: gnutls_assert (); ret = GNUTLS_E_INTERNAL_ERROR; goto cleanup; } ret = 0; cleanup: return ret; }
/* in case of DSA puts into data, r,s */ static int _wrap_nettle_pk_sign (gnutls_pk_algorithm_t algo, gnutls_datum_t * signature, const gnutls_datum_t * vdata, const gnutls_pk_params_st * pk_params) { int ret; unsigned int hash; unsigned int hash_len; switch (algo) { case GNUTLS_PK_EC: /* we do ECDSA */ { ecc_key priv; struct dsa_signature sig; _ecc_params_to_privkey(pk_params, &priv); dsa_signature_init (&sig); hash = _gnutls_dsa_q_to_hash (algo, pk_params, &hash_len); if (hash_len > vdata->size) { gnutls_assert (); _gnutls_debug_log("Security level of algorithm requires hash %s(%d) or better\n", gnutls_mac_get_name(hash), hash_len); hash_len = vdata->size; } ret = ecc_sign_hash(vdata->data, hash_len, &sig, NULL, rnd_func, &priv); if (ret != 0) { gnutls_assert (); ret = GNUTLS_E_PK_SIGN_FAILED; goto ecdsa_fail; } ret = _gnutls_encode_ber_rs (signature, &sig.r, &sig.s); ecdsa_fail: dsa_signature_clear (&sig); _ecc_params_clear( &priv); if (ret < 0) { gnutls_assert (); goto cleanup; } break; } case GNUTLS_PK_DSA: { struct dsa_public_key pub; struct dsa_private_key priv; struct dsa_signature sig; memset(&priv, 0, sizeof(priv)); memset(&pub, 0, sizeof(pub)); _dsa_params_to_pubkey (pk_params, &pub); _dsa_params_to_privkey (pk_params, &priv); dsa_signature_init (&sig); hash = _gnutls_dsa_q_to_hash (algo, pk_params, &hash_len); if (hash_len > vdata->size) { gnutls_assert (); _gnutls_debug_log("Security level of algorithm requires hash %s(%d) or better\n", gnutls_mac_get_name(hash), hash_len); hash_len = vdata->size; } ret = _dsa_sign (&pub, &priv, NULL, rnd_func, hash_len, vdata->data, &sig); if (ret == 0) { gnutls_assert (); ret = GNUTLS_E_PK_SIGN_FAILED; goto dsa_fail; } ret = _gnutls_encode_ber_rs (signature, &sig.r, &sig.s); dsa_fail: dsa_signature_clear (&sig); if (ret < 0) { gnutls_assert (); goto cleanup; } break; } case GNUTLS_PK_RSA: { struct rsa_private_key priv; bigint_t hash, nc, ri; if (_gnutls_mpi_scan_nz (&hash, vdata->data, vdata->size) != 0) { gnutls_assert (); return GNUTLS_E_MPI_SCAN_FAILED; } memset(&priv, 0, sizeof(priv)); _rsa_params_to_privkey (pk_params, &priv); nc = rsa_blind (hash, pk_params->params[1] /*e */ , pk_params->params[0] /*m */ , &ri); _gnutls_mpi_release (&hash); if (nc == NULL) { gnutls_assert (); ret = GNUTLS_E_MEMORY_ERROR; goto rsa_fail; } rsa_compute_root (&priv, TOMPZ (nc), TOMPZ (nc)); rsa_unblind (nc, ri, pk_params->params[0] /*m */ ); ret = _gnutls_mpi_dprint (nc, signature); rsa_fail: _gnutls_mpi_release (&nc); _gnutls_mpi_release (&ri); if (ret < 0) { gnutls_assert (); goto cleanup; } break; } default: gnutls_assert (); ret = GNUTLS_E_INTERNAL_ERROR; goto cleanup; } ret = 0; cleanup: return ret; }