bool RsaDevice_GenEntropyRequest(RsaDevice d, BIGNUM* commit_x, BIGNUM* commit_y) { if(d->x || d->y) return false; PrintTime("Getting x, y, r_p, r_q"); CHECK_CALL(d->x = RsaParams_RandomLargeValue(d->params)); CHECK_CALL(d->y = RsaParams_RandomLargeValue(d->params)); CHECK_CALL(d->rand_p = IntegerGroup_RandomExponent(RsaParams_GetGroup(d->params))); CHECK_CALL(d->rand_q = IntegerGroup_RandomExponent(RsaParams_GetGroup(d->params))); PrintTime("...done"); bool retval = (d->x && d->y && d->rand_p && d->rand_q); PrintTime("Generating C(x), C(y)"); BIGNUM* cx = IntegerGroup_Commit(RsaParams_GetGroup(d->params), d->x, d->rand_p); BIGNUM* cy = IntegerGroup_Commit(RsaParams_GetGroup(d->params), d->y, d->rand_q); PrintTime("...done"); CHECK_CALL(cx); CHECK_CALL(cy); CHECK_CALL(BN_copy(commit_x, cx)); CHECK_CALL(BN_copy(commit_y, cy)); BN_clear_free(cx); BN_clear_free(cy); return retval; }
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; }