Beispiel #1
0
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;
}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
}