BIGNUM* Commit(const_ProductStatement st, const BIGNUM* m1, const BIGNUM* m2) { unsigned char digest[SHA_DIGEST_LENGTH]; SHA_CTX sha; CHECK_CALL(SHA1_Init(&sha)); AddBignumToHash(&sha, IntegerGroup_GetP(st->group)); AddBignumToHash(&sha, IntegerGroup_GetQ(st->group)); AddBignumToHash(&sha, IntegerGroup_GetG(st->group)); AddBignumToHash(&sha, IntegerGroup_GetH(st->group)); AddBignumToHash(&sha, st->commit_a); AddBignumToHash(&sha, st->commit_b); AddBignumToHash(&sha, st->commit_c); AddBignumToHash(&sha, m1); AddBignumToHash(&sha, m2); CHECK_CALL(SHA1_Final(digest, &sha)); BIGNUM* result = BN_bin2bn(digest, SHA_DIGEST_LENGTH, NULL); CHECK_CALL(result); CHECK_CALL(BN_mod(result, result, IntegerGroup_GetQ(st->group), IntegerGroup_GetCtx(st->group))); return result; }
bool RsaDevice_GenEaSigningRequest(RsaDevice d, X509_REQ* req, BIGNUM* delta_x, BIGNUM* delta_y, BIGNUM* rand_n, ProductEvidence* ev) { BN_zero(delta_x); BN_zero(delta_y); PrintTime("Calculating x+x' and y+y'"); // p = x + x' CHECK_CALL(d->p = BN_dup(d->x)); CHECK_CALL(BN_add(d->p, d->p, d->x_prime)); // q = y + y' CHECK_CALL(d->q = BN_dup(d->y)); CHECK_CALL(BN_add(d->q, d->q, d->y_prime)); PrintTime("...done"); PrintTime("Making finding deltas to make p and q prime"); if(!MakePrime(d->params, d->p, &delta_x, RsaParams_GetCtx(d->params))) return false; if(!MakePrime(d->params, d->q, &delta_y, RsaParams_GetCtx(d->params))) return false; PrintTime("...done"); PrintTime("Adding deltas to p and q"); // p = x + x' + delta_x CHECK_CALL(BN_add(d->p, d->p, delta_x)); // q = y + y' + delta_y CHECK_CALL(BN_add(d->q, d->q, delta_y)); PrintTime("...done"); PrintTime("Calculating n"); // n = p*q CHECK_CALL(d->n = BN_new()); CHECK_CALL(BN_mul(d->n, d->p, d->q, RsaParams_GetCtx(d->params))); ASSERT(BN_cmp(d->n, IntegerGroup_GetQ(RsaParams_GetGroup(d->params))) == -1); PrintTime("...done"); const_IntegerGroup group = RsaParams_GetGroup(d->params); // Get randomness for commitment to n PrintTime("Picking r_n"); BIGNUM* r_n = IntegerGroup_RandomExponent(group); CHECK_CALL(r_n); CHECK_CALL(BN_copy(rand_n, r_n)); BN_clear_free(r_n); PrintTime("...done"); PrintTime("Generating commits to p,q,n"); // Commit to p BIGNUM* commit_p = IntegerGroup_Commit(group, d->p, d->rand_p); CHECK_CALL(commit_p); // Commit to q BIGNUM* commit_q = IntegerGroup_Commit(group, d->q, d->rand_q); // Commit to n BIGNUM* commit_n = IntegerGroup_Commit(group, d->n, rand_n); PrintTime("...done"); /* printf("C(p) = "); BN_print_fp(stdout, commit_p); puts(""); printf("C(q) = "); BN_print_fp(stdout, commit_q); puts(""); printf("C(n) = "); BN_print_fp(stdout, commit_n); puts(""); */ PrintTime("Generating prodproof"); ProductStatement st = ProductStatement_New(RsaParams_GetGroup(d->params), commit_p, commit_q, commit_n); PrintTime("...done"); // Generate proof that n = p*q PrintTime("Generating prodevidence"); *ev = ProductEvidence_New(st, d->p, d->rand_p, d->rand_q, rand_n); PrintTime("...done"); ProductStatement_Free(st); BN_clear_free(commit_p); BN_clear_free(commit_q); BN_clear_free(commit_n); CHECK_CALL(req); PrintTime("Generating certificate"); CHECK_CALL(GenerateCertRequest(d, req)); PrintTime("...done"); return true; }
ProductEvidence ProductEvidence_New(ProductStatement st, const BIGNUM *a, const BIGNUM *r_a, const BIGNUM *r_b, const BIGNUM *r_c) { ProductEvidence ev = safe_malloc(sizeof(*ev)); const BIGNUM* g = IntegerGroup_GetG(st->group); const BIGNUM* h = IntegerGroup_GetH(st->group); const BIGNUM* q = IntegerGroup_GetQ(st->group); BN_CTX* ctx = IntegerGroup_GetCtx(st->group); // A = g^a h^{r_a} // B = g^b h^{r_b} // C = g^{ab} h^{r_c} // r_prod = r_c - a*r_b BIGNUM* r_prod; CHECK_CALL(r_prod = BN_dup(a)); CHECK_CALL(BN_mod_mul(r_prod, r_prod, r_b, q, ctx)); CHECK_CALL(BN_mod_sub(r_prod, r_c, r_prod, q, ctx)); // == Commitment == // x, s1, s2 in [0, q) BIGNUM *x = IntegerGroup_RandomExponent(st->group); BIGNUM *s1 = IntegerGroup_RandomExponent(st->group); BIGNUM *s2 = IntegerGroup_RandomExponent(st->group); CHECK_CALL(x); CHECK_CALL(s1); CHECK_CALL(s2); // m1 = g^x h^s1 BIGNUM* m1 = IntegerGroup_CascadeExponentiate(st->group, g, x, h, s1); CHECK_CALL(m1); // m2 = B^x h^s2 BIGNUM* m2 = IntegerGroup_CascadeExponentiate(st->group, st->commit_b, x, h, s2); CHECK_CALL(m2); // == Challenge == // c = H(g, h, q, p, A, B, C, m1, m2) ev->c = Commit(st, m1, m2); // == Response == // z = x + ca mod q ev->z = BN_dup(ev->c); CHECK_CALL(ev->z); CHECK_CALL(BN_mod_mul(ev->z, ev->z, a, q, ctx)); CHECK_CALL(BN_mod_add(ev->z, ev->z, x, q, ctx)); // w1 = s1 + (c r_a) mod q ev->w1 = BN_dup(r_a); CHECK_CALL(ev->w1); CHECK_CALL(BN_mod_mul(ev->w1, ev->w1, ev->c, q, ctx)); CHECK_CALL(BN_mod_add(ev->w1, ev->w1, s1, q, ctx)); // w2 = s2 + (c r_prod) mod q ev->w2 = BN_dup(r_prod); CHECK_CALL(ev->w2); CHECK_CALL(BN_mod_mul(ev->w2, ev->w2, ev->c, q, ctx)); CHECK_CALL(BN_mod_add(ev->w2, ev->w2, s2, q, ctx)); // proof is (c, z, w1, w2) BN_free(m1); BN_free(m2); BN_clear_free(x); BN_clear_free(s1); BN_clear_free(s2); BN_clear_free(r_prod); return ev; }