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; }
int _dsa_validate_dss_g(struct dsa_params *pub, unsigned domain_seed_size, const uint8_t *domain_seed, unsigned index) { int ret; unsigned p_bits, q_bits; struct dsa_params pub2; mpz_t r; p_bits = mpz_sizeinbase(pub->p, 2); q_bits = mpz_sizeinbase(pub->q, 2); ret = _dsa_check_qp_sizes(q_bits, p_bits, 0); if (ret == 0) { return 0; } mpz_init(r); dsa_params_init(&pub2); mpz_set(pub2.p, pub->p); mpz_set(pub2.q, pub->q); /* verify g */ if (index > 255) { goto fail; } /* 2<= g <= p-1 */ mpz_set(r, pub->p); mpz_sub_ui(r, r, 1); if (mpz_cmp_ui(pub->g, 2) < 0 || mpz_cmp(pub->g, r) >= 0) { goto fail; } /* g^q == 1 mod p */ mpz_powm(r, pub->g, pub->q, pub->p); if (mpz_cmp_ui(r, 1) != 0) { goto fail; } /* repeat g generation */ ret = _dsa_generate_dss_g(&pub2, domain_seed_size, domain_seed, NULL, NULL, index); if (ret == 0) { goto fail; } if (mpz_cmp(pub->g, pub2.g) != 0) { goto fail; } /* everything looks ok */ ret = 1; goto finish; fail: ret = 0; finish: dsa_params_clear(&pub2); mpz_clear(r); return ret; }
int _dsa_validate_dss_pq(struct dsa_params *pub, struct dss_params_validation_seeds *cert) { int ret; unsigned p_bits, q_bits; struct dsa_params pub2; struct dss_params_validation_seeds cert2; mpz_t r, s; p_bits = mpz_sizeinbase(pub->p, 2); q_bits = mpz_sizeinbase(pub->q, 2); ret = _dsa_check_qp_sizes(q_bits, p_bits, 0); if (ret == 0) { return 0; } mpz_init(r); mpz_init(s); dsa_params_init(&pub2); nettle_mpz_set_str_256_u(s, cert->seed_length, cert->seed); /* firstseed < 2^(N-1) */ mpz_set_ui(r, 1); mpz_mul_2exp(r, r, q_bits - 1); if (mpz_cmp(s, r) < 0) { goto fail; } /* 2^N <= q */ mpz_set_ui(r, 1); mpz_mul_2exp(r, r, q_bits); if (mpz_cmp(r, pub->q) <= 0) { goto fail; } /* 2^L <= p */ mpz_set_ui(r, 1); mpz_mul_2exp(r, r, p_bits); if (mpz_cmp(r, pub->p) <= 0) { goto fail; } /* p-1 mod q != 0 */ mpz_set(r, pub->p); mpz_sub_ui(r, r, 1); mpz_mod(r, r, pub->q); if (mpz_cmp_ui(r, 0) != 0) { goto fail; } /* replay the construction */ ret = _dsa_generate_dss_pq(&pub2, &cert2, cert->seed_length, cert->seed, NULL, NULL, p_bits, q_bits); if (ret == 0) { goto fail; } if ((cert->pseed_length > 0 && cert->pseed_length != cert2.pseed_length) || (cert->qseed_length > 0 && cert->qseed_length != cert2.qseed_length) || (cert->pgen_counter > 0 && cert->pgen_counter != cert2.pgen_counter) || (cert->qgen_counter > 0 && cert->qgen_counter != cert2.qgen_counter) || (cert->qseed_length > 0 && memcmp(cert->qseed, cert2.qseed, cert2.qseed_length) != 0) || (cert->pseed_length > 0 && memcmp(cert->pseed, cert2.pseed, cert2.pseed_length) != 0)) { goto fail; } if (mpz_cmp(pub->q, pub2.q) != 0) { goto fail; } if (mpz_cmp(pub->p, pub2.p) != 0) { goto fail; } if (mpz_sizeinbase(s, 2) < q_bits - 1) { goto fail; } ret = 1; goto finish; fail: ret = 0; finish: dsa_params_clear(&pub2); mpz_clear(r); mpz_clear(s); return ret; }