use proof structs. fix bug in mpi_serialize
This commit is contained in:
parent
5844231993
commit
8d717c4b3d
334
crypto.c
334
crypto.c
@ -157,19 +157,26 @@ ec_skey_create (gcry_mpi_t skey)
|
||||
|
||||
|
||||
/**
|
||||
* ec_keypair_create
|
||||
* ec_keypair_create creates a new keypair by creating a random secret key first
|
||||
* and multipyling the base point with it to get the public key.
|
||||
*
|
||||
* @param[out] pkey where to store the generated public key
|
||||
* @param[out] skey where to store the generated secret key
|
||||
* @param[out] skey where to store the generated secret key. May be NULL if
|
||||
* you're not interested in the secret key and just need a random point.
|
||||
*/
|
||||
void
|
||||
ec_keypair_create (gcry_mpi_point_t pkey, gcry_mpi_t skey)
|
||||
{
|
||||
brandt_assert (NULL != pkey);
|
||||
brandt_assert (NULL != skey);
|
||||
gcry_mpi_t sk;
|
||||
|
||||
ec_skey_create (skey);
|
||||
gcry_mpi_ec_mul (pkey, skey, ec_gen, ec_ctx);
|
||||
brandt_assert (NULL != pkey);
|
||||
sk = (NULL == skey) ? gcry_mpi_new (0) : skey;
|
||||
|
||||
ec_skey_create (sk);
|
||||
gcry_mpi_ec_mul (pkey, sk, ec_gen, ec_ctx);
|
||||
|
||||
if (NULL == skey)
|
||||
gcry_mpi_release (sk);
|
||||
}
|
||||
|
||||
|
||||
@ -244,19 +251,21 @@ mpi_serialize (struct ec_mpi *dst, gcry_mpi_t src)
|
||||
{
|
||||
size_t rsize = 0;
|
||||
unsigned int nbits;
|
||||
const void *p;
|
||||
const void *vp;
|
||||
char *cp = (char *)dst;
|
||||
gcry_error_t rc;
|
||||
|
||||
|
||||
if (gcry_mpi_get_flag (src, GCRYMPI_FLAG_OPAQUE))
|
||||
{
|
||||
/* Store opaque MPIs left aligned into the buffer. Used by Ed25519 point
|
||||
* compression */
|
||||
p = gcry_mpi_get_opaque (src, &nbits);
|
||||
brandt_assert (p);
|
||||
vp = gcry_mpi_get_opaque (src, &nbits);
|
||||
brandt_assert (vp);
|
||||
rsize = (nbits + 7) / 8;
|
||||
if (rsize > sizeof (struct ec_mpi))
|
||||
rsize = sizeof (struct ec_mpi);
|
||||
memcpy (dst, p, rsize);
|
||||
memcpy (dst, vp, rsize);
|
||||
if (rsize < sizeof (struct ec_mpi))
|
||||
memset (((char *)dst) + rsize, 0, sizeof (struct ec_mpi) - rsize);
|
||||
}
|
||||
@ -270,7 +279,7 @@ mpi_serialize (struct ec_mpi *dst, gcry_mpi_t src)
|
||||
/* Shift the output to the right, if shorter than available space */
|
||||
if (rsize && rsize < sizeof (struct ec_mpi))
|
||||
{
|
||||
memmove (&dst[sizeof (struct ec_mpi) - rsize], dst, rsize);
|
||||
memmove (&cp[sizeof (struct ec_mpi) - rsize], dst, rsize);
|
||||
memset (dst, 0, sizeof (struct ec_mpi) - rsize);
|
||||
}
|
||||
}
|
||||
@ -577,8 +586,8 @@ smc_encrypt_bid (struct AuctionData *ad,
|
||||
gcry_mpi_t r1,
|
||||
gcry_mpi_t r2)
|
||||
{
|
||||
smc_zkp_0og (ad->alpha[ad->i][j], (j == ad->b ? ec_gen : ec_zero), ad->Y,
|
||||
ad->beta[ad->i][j], a1, a2, b1, b2, d1, d2, r1, r2);
|
||||
// smc_zkp_0og (ad->alpha[ad->i][j], j == ad->b, ad->Y,
|
||||
// ad->beta[ad->i][j], a1, a2, b1, b2, d1, d2, r1, r2);
|
||||
}
|
||||
|
||||
|
||||
@ -604,27 +613,28 @@ smc_compute_outcome (struct AuctionData *ad)
|
||||
|
||||
|
||||
/**
|
||||
* smc_zkp_dl
|
||||
* smc_zkp_dl creates a proof of knowledge of @a x with \f$v = xg\f$ where
|
||||
* \f$g\f$ is the base point on Ed25519.
|
||||
*
|
||||
* @param v \todo
|
||||
* @param g \todo
|
||||
* @param x \todo
|
||||
* @param a \todo
|
||||
* @param r \todo
|
||||
* @param[in] v input point. Must be known to the verifier.
|
||||
* @param[in] x private key. Knowledge of this number is certified in the proof
|
||||
* @param[out] proof pointer where to save the output proof structure. Must be
|
||||
* shared with the verifier.
|
||||
*/
|
||||
void
|
||||
smc_zkp_dl (const gcry_mpi_point_t v,
|
||||
const gcry_mpi_point_t g,
|
||||
const gcry_mpi_t x,
|
||||
const gcry_mpi_point_t a,
|
||||
gcry_mpi_t r)
|
||||
struct proof_dl *proof)
|
||||
{
|
||||
struct zkp_challenge_dl challenge;
|
||||
struct brandt_hash_code challhash;
|
||||
gcry_mpi_point_t a = gcry_mpi_point_new (0);
|
||||
gcry_mpi_t r = gcry_mpi_new (0);
|
||||
gcry_mpi_t c = gcry_mpi_new (0);
|
||||
gcry_mpi_t z = gcry_mpi_new (0);
|
||||
|
||||
ec_keypair_create_base (a, z, g);
|
||||
/* a = zg */
|
||||
ec_keypair_create (a, z);
|
||||
|
||||
/* compute challenge c */
|
||||
ec_point_serialize (&challenge.g, ec_gen);
|
||||
@ -634,36 +644,44 @@ smc_zkp_dl (const gcry_mpi_point_t v,
|
||||
mpi_parse (c, (struct ec_mpi *)&challhash);
|
||||
gcry_mpi_mod (c, c, ec_n);
|
||||
|
||||
/* r = z + cx */
|
||||
gcry_mpi_mulm (r, c, x, ec_n);
|
||||
gcry_mpi_addm (r, r, z, ec_n);
|
||||
|
||||
ec_point_serialize (&proof->a, a);
|
||||
mpi_serialize (&proof->r, r);
|
||||
|
||||
gcry_mpi_point_release (a);
|
||||
gcry_mpi_release (r);
|
||||
gcry_mpi_release (c);
|
||||
gcry_mpi_release (z);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* smc_zkp_dl_check
|
||||
* smc_zkp_dl_check verifies a proof of knowledge of \f$x = ECDL_g(v)\f$ where
|
||||
* \f$g\f$ is the base point on Ed25519.
|
||||
*
|
||||
* @param v \todo
|
||||
* @param g \todo
|
||||
* @param a \todo
|
||||
* @param r \todo
|
||||
* @param[in] v input point. Received from the prover.
|
||||
* @param[in] proof pointer to the proof structure. Received from the prover.
|
||||
* @return 0 if the proof is correct, something else otherwise
|
||||
*/
|
||||
int
|
||||
smc_zkp_dl_check (const gcry_mpi_point_t v,
|
||||
const gcry_mpi_point_t g,
|
||||
const gcry_mpi_point_t a,
|
||||
const gcry_mpi_t r)
|
||||
const struct proof_dl *proof)
|
||||
{
|
||||
int ret;
|
||||
struct zkp_challenge_dl challenge;
|
||||
struct brandt_hash_code challhash;
|
||||
gcry_mpi_point_t a = gcry_mpi_point_new (0);
|
||||
gcry_mpi_t r = gcry_mpi_new (0);
|
||||
gcry_mpi_t c = gcry_mpi_new (0);
|
||||
gcry_mpi_point_t left = gcry_mpi_point_new (0);
|
||||
gcry_mpi_point_t right = gcry_mpi_point_new (0);
|
||||
|
||||
ec_point_parse (a, &proof->a);
|
||||
mpi_parse (r, &proof->r);
|
||||
|
||||
/* compute challenge c */
|
||||
ec_point_serialize (&challenge.g, ec_gen);
|
||||
ec_point_serialize (&challenge.v, v);
|
||||
@ -672,11 +690,14 @@ smc_zkp_dl_check (const gcry_mpi_point_t v,
|
||||
mpi_parse (c, (struct ec_mpi *)&challhash);
|
||||
gcry_mpi_mod (c, c, ec_n);
|
||||
|
||||
gcry_mpi_ec_mul (left, r, g, ec_ctx);
|
||||
/* rg =? a + cv */
|
||||
gcry_mpi_ec_mul (left, r, ec_gen, ec_ctx);
|
||||
gcry_mpi_ec_mul (right, c, v, ec_ctx);
|
||||
gcry_mpi_ec_add (right, a, right, ec_ctx);
|
||||
|
||||
ret = ec_point_cmp (left, right);
|
||||
|
||||
gcry_mpi_point_release (a);
|
||||
gcry_mpi_release (r);
|
||||
gcry_mpi_release (c);
|
||||
gcry_mpi_point_release (left);
|
||||
gcry_mpi_point_release (right);
|
||||
@ -686,82 +707,116 @@ smc_zkp_dl_check (const gcry_mpi_point_t v,
|
||||
|
||||
|
||||
/**
|
||||
* smc_zkp_2dle \todo
|
||||
* smc_zkp_2dle creates a proof that two ECDLs are equal without revealing the
|
||||
* ECDL. \f$v=xg_1, w=xg_2\f$ are calculated as well and can be returned to the
|
||||
* caller if needed.
|
||||
*
|
||||
* @param v TODO
|
||||
* @param w TODO
|
||||
* @param g1 TODO
|
||||
* @param g2 TODO
|
||||
* @param x TODO
|
||||
* @param a TODO
|
||||
* @param b TODO
|
||||
* @param r TODO
|
||||
* @param[out] v first output point. May be NULL if not needed by the caller.
|
||||
* Must be known to the verifier.
|
||||
* @param[out] w second output point. May be NULL if not needed by the caller.
|
||||
* Must be known to the verifier.
|
||||
* @param[in] g1 first base point. Must be known to the verifier.
|
||||
* @param[in] g2 second base point. Must be known to the verifier.
|
||||
* @param[in] x private number to prove knowledge of.
|
||||
* @param[out] proof pointer where to save the output proof structure. Must be
|
||||
* shared with the verifier.
|
||||
*/
|
||||
void
|
||||
smc_zkp_2dle (const gcry_mpi_point_t v,
|
||||
const gcry_mpi_point_t w,
|
||||
smc_zkp_2dle (gcry_mpi_point_t v,
|
||||
gcry_mpi_point_t w,
|
||||
const gcry_mpi_point_t g1,
|
||||
const gcry_mpi_point_t g2,
|
||||
const gcry_mpi_t x,
|
||||
gcry_mpi_point_t a,
|
||||
gcry_mpi_point_t b,
|
||||
gcry_mpi_t r)
|
||||
struct proof_2dle *proof)
|
||||
{
|
||||
struct zkp_challenge_2dle challenge;
|
||||
struct brandt_hash_code challhash;
|
||||
gcry_mpi_point_t rv;
|
||||
gcry_mpi_point_t rw;
|
||||
gcry_mpi_point_t a = gcry_mpi_point_new (0);
|
||||
gcry_mpi_point_t b = gcry_mpi_point_new (0);
|
||||
gcry_mpi_t r = gcry_mpi_new (0);
|
||||
gcry_mpi_t c = gcry_mpi_new (0);
|
||||
gcry_mpi_t z = gcry_mpi_new (0);
|
||||
|
||||
rv = (NULL == v) ? rv = gcry_mpi_point_new (0) : v;
|
||||
rw = (NULL == w) ? rw = gcry_mpi_point_new (0) : w;
|
||||
|
||||
/* v = x*g1 */
|
||||
gcry_mpi_ec_mul (rv, x, g1, ec_ctx);
|
||||
|
||||
/* w = x*g2 */
|
||||
gcry_mpi_ec_mul (rw, x, g2, ec_ctx);
|
||||
|
||||
/* a = z*g1 */
|
||||
ec_keypair_create_base (a, z, g1);
|
||||
|
||||
/* b = z*g2 */
|
||||
gcry_mpi_ec_mul (b, z, g2, ec_ctx);
|
||||
|
||||
/* compute challenge c */
|
||||
ec_point_serialize (&challenge.g1, g1);
|
||||
ec_point_serialize (&challenge.g2, g2);
|
||||
ec_point_serialize (&challenge.v, v);
|
||||
ec_point_serialize (&challenge.w, w);
|
||||
ec_point_serialize (&challenge.v, rv);
|
||||
ec_point_serialize (&challenge.w, rw);
|
||||
ec_point_serialize (&challenge.a, a);
|
||||
ec_point_serialize (&challenge.b, b);
|
||||
brandt_hash (&challenge, sizeof (struct zkp_challenge_dl), &challhash);
|
||||
mpi_parse (c, (struct ec_mpi *)&challhash);
|
||||
gcry_mpi_mod (c, c, ec_n);
|
||||
|
||||
/* r = z + cx */
|
||||
gcry_mpi_mulm (r, c, x, ec_n);
|
||||
gcry_mpi_addm (r, r, z, ec_n);
|
||||
|
||||
mpi_serialize (&proof->r, r);
|
||||
ec_point_serialize (&proof->a, a);
|
||||
ec_point_serialize (&proof->b, b);
|
||||
|
||||
if (NULL == v)
|
||||
gcry_mpi_point_release (rv);
|
||||
if (NULL == w)
|
||||
gcry_mpi_point_release (rw);
|
||||
gcry_mpi_point_release (a);
|
||||
gcry_mpi_point_release (b);
|
||||
gcry_mpi_release (r);
|
||||
gcry_mpi_release (c);
|
||||
gcry_mpi_release (z);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* smc_zkp_2dle_check \todo
|
||||
* smc_zkp_2dle_check verifies a proof of knowledge of \f$x\f$ with \f$v=xg_1\f$
|
||||
* and \f$w=xg_2\f$.
|
||||
*
|
||||
* @param v TODO
|
||||
* @param w TODO
|
||||
* @param g1 TODO
|
||||
* @param g2 TODO
|
||||
* @param a TODO
|
||||
* @param b TODO
|
||||
* @param r TODO
|
||||
* @return TODO
|
||||
* @param[in] v first input point.
|
||||
* @param[in] w second input point.
|
||||
* @param[in] g1 first base point.
|
||||
* @param[in] g2 second base point.
|
||||
* @param[in] proof pointer to the proof structure. Received from the prover.
|
||||
* @return 0 if the proof is correct, something else otherwise
|
||||
*/
|
||||
int
|
||||
smc_zkp_2dle_check (const gcry_mpi_point_t v,
|
||||
const gcry_mpi_point_t w,
|
||||
const gcry_mpi_point_t g1,
|
||||
const gcry_mpi_point_t g2,
|
||||
const gcry_mpi_point_t a,
|
||||
const gcry_mpi_point_t b,
|
||||
const gcry_mpi_t r)
|
||||
const struct proof_2dle *proof)
|
||||
{
|
||||
int ret;
|
||||
struct zkp_challenge_2dle challenge;
|
||||
struct brandt_hash_code challhash;
|
||||
gcry_mpi_point_t a = gcry_mpi_point_new (0);
|
||||
gcry_mpi_point_t b = gcry_mpi_point_new (0);
|
||||
gcry_mpi_t r = gcry_mpi_new (0);
|
||||
gcry_mpi_t c = gcry_mpi_new (0);
|
||||
gcry_mpi_point_t left = gcry_mpi_point_new (0);
|
||||
gcry_mpi_point_t right = gcry_mpi_point_new (0);
|
||||
|
||||
mpi_parse (r, &proof->r);
|
||||
ec_point_parse (a, &proof->a);
|
||||
ec_point_parse (b, &proof->b);
|
||||
|
||||
/* compute challenge c */
|
||||
ec_point_serialize (&challenge.g1, g1);
|
||||
ec_point_serialize (&challenge.g2, g2);
|
||||
@ -773,16 +828,21 @@ smc_zkp_2dle_check (const gcry_mpi_point_t v,
|
||||
mpi_parse (c, (struct ec_mpi *)&challhash);
|
||||
gcry_mpi_mod (c, c, ec_n);
|
||||
|
||||
/* r*g1 =? a + cv */
|
||||
gcry_mpi_ec_mul (left, r, g1, ec_ctx);
|
||||
gcry_mpi_ec_mul (right, c, v, ec_ctx);
|
||||
gcry_mpi_ec_add (right, a, right, ec_ctx);
|
||||
ret = ec_point_cmp (left, right);
|
||||
|
||||
/* r*g2 =? b + cw */
|
||||
gcry_mpi_ec_mul (left, r, g2, ec_ctx);
|
||||
gcry_mpi_ec_mul (right, c, w, ec_ctx);
|
||||
gcry_mpi_ec_add (right, b, right, ec_ctx);
|
||||
ret |= ec_point_cmp (left, right);
|
||||
|
||||
gcry_mpi_point_release (a);
|
||||
gcry_mpi_point_release (b);
|
||||
gcry_mpi_release (r);
|
||||
gcry_mpi_release (c);
|
||||
gcry_mpi_point_release (left);
|
||||
gcry_mpi_point_release (right);
|
||||
@ -792,55 +852,57 @@ smc_zkp_2dle_check (const gcry_mpi_point_t v,
|
||||
|
||||
|
||||
/**
|
||||
* smc_zkp_0og \todo
|
||||
* smc_zkp_0og encrypts one of two values and creates a proof that the
|
||||
* ciphertext decrypts to either one of those two values without revealing which
|
||||
* one was encrypted. The two values are the zero point or the base point of the
|
||||
* Ed25519 curve. Encryption is done via ElGamal: \f$(\alpha,\beta)=(m+ry,rg)\f$
|
||||
* where \f$m\f$ is the value to encrypt, \f$y\f$ is the public key and \f$g\f$
|
||||
* is the base point. The nonce \f$r\f$ is generated as well and can be returned
|
||||
* to the caller if he needs it (e.g. for another proof).
|
||||
*
|
||||
* @param alpha TODO
|
||||
* @param m TODO
|
||||
* @param y TODO
|
||||
* @param beta TODO
|
||||
* @param a1 TODO
|
||||
* @param a2 TODO
|
||||
* @param b1 TODO
|
||||
* @param b2 TODO
|
||||
* @param d1 TODO
|
||||
* @param d2 TODO
|
||||
* @param r1 TODO
|
||||
* @param r2 TODO
|
||||
* @param[in] m_is_gen if true, the base point is encrypted, else the zero point
|
||||
* is encrypted.
|
||||
* @param[in] y public key to use for encryption.
|
||||
* @param[out] r random number used for encryption. May be NULL if caller
|
||||
* doesn't need it.
|
||||
* @param[out] alpha first part of the ciphertext output
|
||||
* @param[out] beta second part of the ciphertext output
|
||||
* @param[out] proof pointer where to save the output proof structure. Must be
|
||||
* shared with the verifier.
|
||||
*/
|
||||
void
|
||||
smc_zkp_0og (gcry_mpi_point_t alpha,
|
||||
const gcry_mpi_point_t m,
|
||||
smc_zkp_0og (int m_is_gen,
|
||||
const gcry_mpi_point_t y,
|
||||
gcry_mpi_t r,
|
||||
gcry_mpi_point_t alpha,
|
||||
gcry_mpi_point_t beta,
|
||||
gcry_mpi_point_t a1,
|
||||
gcry_mpi_point_t a2,
|
||||
gcry_mpi_point_t b1,
|
||||
gcry_mpi_point_t b2,
|
||||
gcry_mpi_t d1,
|
||||
gcry_mpi_t d2,
|
||||
gcry_mpi_t r1,
|
||||
gcry_mpi_t r2)
|
||||
struct proof_0og *proof)
|
||||
{
|
||||
struct zkp_challenge_0og challenge;
|
||||
struct brandt_hash_code challhash;
|
||||
gcry_mpi_point_t a1 = gcry_mpi_point_new (0);
|
||||
gcry_mpi_point_t a2 = gcry_mpi_point_new (0);
|
||||
gcry_mpi_point_t b1 = gcry_mpi_point_new (0);
|
||||
gcry_mpi_point_t b2 = gcry_mpi_point_new (0);
|
||||
gcry_mpi_t d1 = gcry_mpi_new (0);
|
||||
gcry_mpi_t d2 = gcry_mpi_new (0);
|
||||
gcry_mpi_t r1 = gcry_mpi_new (0);
|
||||
gcry_mpi_t r2 = gcry_mpi_new (0);
|
||||
gcry_mpi_t c = gcry_mpi_new (0);
|
||||
gcry_mpi_t r = gcry_mpi_new (0);
|
||||
gcry_mpi_t rr;
|
||||
gcry_mpi_t w = gcry_mpi_new (0);
|
||||
int eq0 = !ec_point_cmp (m, ec_zero);
|
||||
int eqg = !ec_point_cmp (m, ec_gen);
|
||||
|
||||
if (!(eq0 ^ eqg))
|
||||
eprintf ("zero knowledge proof: m is neither 0 nor g");
|
||||
rr = (NULL == r) ? gcry_mpi_new (0) : r;
|
||||
|
||||
/* beta = r*g */
|
||||
ec_keypair_create (beta, r);
|
||||
gcry_mpi_mod (r, r, ec_n);
|
||||
ec_keypair_create (beta, rr);
|
||||
gcry_mpi_mod (rr, rr, ec_n);
|
||||
|
||||
/* alpha = m + r*y */
|
||||
gcry_mpi_ec_mul (alpha, r, y, ec_ctx);
|
||||
gcry_mpi_ec_add (alpha, m, alpha, ec_ctx);
|
||||
gcry_mpi_ec_mul (alpha, rr, y, ec_ctx);
|
||||
gcry_mpi_ec_add (alpha, m_is_gen ? ec_gen : ec_zero, alpha, ec_ctx);
|
||||
|
||||
if (eq0)
|
||||
if (!m_is_gen)
|
||||
{ /* m == 0 */
|
||||
ec_keypair_create_base (a1, d1, beta);
|
||||
gcry_mpi_mod (d1, d1, ec_n);
|
||||
@ -900,13 +962,13 @@ smc_zkp_0og (gcry_mpi_point_t alpha,
|
||||
mpi_parse (c, (struct ec_mpi *)&challhash);
|
||||
gcry_mpi_mod (c, c, ec_n);
|
||||
|
||||
if (eq0)
|
||||
if (!m_is_gen)
|
||||
{ /* m == 0 */
|
||||
/* d2 = c - d1 */
|
||||
gcry_mpi_subm (d2, c, d1, ec_n);
|
||||
|
||||
/* r2 = w - r*d2 */
|
||||
gcry_mpi_mulm (r2, r, d2, ec_n);
|
||||
gcry_mpi_mulm (r2, rr, d2, ec_n);
|
||||
gcry_mpi_subm (r2, w, r2, ec_n);
|
||||
}
|
||||
else
|
||||
@ -915,53 +977,75 @@ smc_zkp_0og (gcry_mpi_point_t alpha,
|
||||
gcry_mpi_subm (d1, c, d2, ec_n);
|
||||
|
||||
/* r1 = w - r*d1 */
|
||||
gcry_mpi_mulm (r1, r, d1, ec_n);
|
||||
gcry_mpi_mulm (r1, rr, d1, ec_n);
|
||||
gcry_mpi_subm (r1, w, r1, ec_n);
|
||||
}
|
||||
|
||||
ec_point_serialize (&proof->a1, a1);
|
||||
ec_point_serialize (&proof->a2, a2);
|
||||
ec_point_serialize (&proof->b1, b1);
|
||||
ec_point_serialize (&proof->b2, b2);
|
||||
mpi_serialize (&proof->d1, d1);
|
||||
mpi_serialize (&proof->d2, d2);
|
||||
mpi_serialize (&proof->r1, r1);
|
||||
mpi_serialize (&proof->r2, r2);
|
||||
|
||||
gcry_mpi_point_release (a1);
|
||||
gcry_mpi_point_release (a2);
|
||||
gcry_mpi_point_release (b1);
|
||||
gcry_mpi_point_release (b2);
|
||||
gcry_mpi_release (d1);
|
||||
gcry_mpi_release (d2);
|
||||
gcry_mpi_release (r1);
|
||||
gcry_mpi_release (r2);
|
||||
gcry_mpi_release (c);
|
||||
gcry_mpi_release (r);
|
||||
if (NULL == r)
|
||||
gcry_mpi_release (rr);
|
||||
gcry_mpi_release (w);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* smc_zkp_0og_check \todo
|
||||
* smc_zkp_0og_check verifies a proof that \f$(\alpha,\beta\f$ decrypts either
|
||||
* to the base point \f$g\f$ or the zero point.
|
||||
*
|
||||
* @param alpha TODO
|
||||
* @param y TODO
|
||||
* @param beta TODO
|
||||
* @param a1 TODO
|
||||
* @param a2 TODO
|
||||
* @param b1 TODO
|
||||
* @param b2 TODO
|
||||
* @param d1 TODO
|
||||
* @param d2 TODO
|
||||
* @param r1 TODO
|
||||
* @param r2 TODO
|
||||
* @return TODO
|
||||
* @param[in] y the public key used for encryption
|
||||
* @param[in] alpha first part of the ciphertext
|
||||
* @param[in] beta second part of the ciphertext
|
||||
* @param[in] proof pointer to the proof structure. Received from the prover.
|
||||
* @return 0 if the proof is correct, something else otherwise
|
||||
*/
|
||||
int
|
||||
smc_zkp_0og_check (const gcry_mpi_point_t alpha,
|
||||
const gcry_mpi_point_t y,
|
||||
smc_zkp_0og_check (const gcry_mpi_point_t y,
|
||||
const gcry_mpi_point_t alpha,
|
||||
const gcry_mpi_point_t beta,
|
||||
const gcry_mpi_point_t a1,
|
||||
const gcry_mpi_point_t a2,
|
||||
const gcry_mpi_point_t b1,
|
||||
const gcry_mpi_point_t b2,
|
||||
const gcry_mpi_t d1,
|
||||
const gcry_mpi_t d2,
|
||||
const gcry_mpi_t r1,
|
||||
const gcry_mpi_t r2)
|
||||
const struct proof_0og *proof)
|
||||
{
|
||||
int ret;
|
||||
struct zkp_challenge_0og challenge;
|
||||
struct brandt_hash_code challhash;
|
||||
gcry_mpi_point_t a1 = gcry_mpi_point_new (0);
|
||||
gcry_mpi_point_t a2 = gcry_mpi_point_new (0);
|
||||
gcry_mpi_point_t b1 = gcry_mpi_point_new (0);
|
||||
gcry_mpi_point_t b2 = gcry_mpi_point_new (0);
|
||||
gcry_mpi_t d1 = gcry_mpi_new (0);
|
||||
gcry_mpi_t d2 = gcry_mpi_new (0);
|
||||
gcry_mpi_t r1 = gcry_mpi_new (0);
|
||||
gcry_mpi_t r2 = gcry_mpi_new (0);
|
||||
gcry_mpi_t c = gcry_mpi_new (0);
|
||||
gcry_mpi_t sum = gcry_mpi_new (0);
|
||||
gcry_mpi_point_t right = gcry_mpi_point_new (0);
|
||||
gcry_mpi_point_t tmp = gcry_mpi_point_new (0);
|
||||
|
||||
ec_point_parse (a1, &proof->a1);
|
||||
ec_point_parse (a2, &proof->a2);
|
||||
ec_point_parse (b1, &proof->b1);
|
||||
ec_point_parse (b2, &proof->b2);
|
||||
mpi_parse (d1, &proof->d1);
|
||||
mpi_parse (d2, &proof->d2);
|
||||
mpi_parse (r1, &proof->r1);
|
||||
mpi_parse (r2, &proof->r2);
|
||||
|
||||
/* compute challenge c */
|
||||
ec_point_serialize (&challenge.g, ec_gen);
|
||||
ec_point_serialize (&challenge.alpha, alpha);
|
||||
@ -1003,6 +1087,14 @@ smc_zkp_0og_check (const gcry_mpi_point_t alpha,
|
||||
gcry_mpi_ec_add (right, right, tmp, ec_ctx);
|
||||
ret |= ec_point_cmp (b2, right) << 4;
|
||||
|
||||
gcry_mpi_point_release (a1);
|
||||
gcry_mpi_point_release (a2);
|
||||
gcry_mpi_point_release (b1);
|
||||
gcry_mpi_point_release (b2);
|
||||
gcry_mpi_release (d1);
|
||||
gcry_mpi_release (d2);
|
||||
gcry_mpi_release (r1);
|
||||
gcry_mpi_release (r2);
|
||||
gcry_mpi_release (c);
|
||||
gcry_mpi_release (sum);
|
||||
gcry_mpi_point_release (right);
|
||||
|
54
crypto.h
54
crypto.h
@ -73,55 +73,45 @@ struct proof_2dle {
|
||||
struct ec_mpi b;
|
||||
};
|
||||
|
||||
struct proof_0og {
|
||||
struct ec_mpi a1;
|
||||
struct ec_mpi a2;
|
||||
struct ec_mpi b1;
|
||||
struct ec_mpi b2;
|
||||
struct ec_mpi d1;
|
||||
struct ec_mpi d2;
|
||||
struct ec_mpi r1;
|
||||
struct ec_mpi r2;
|
||||
};
|
||||
|
||||
void smc_zkp_dl (const gcry_mpi_point_t v,
|
||||
const gcry_mpi_point_t g,
|
||||
const gcry_mpi_t x,
|
||||
const gcry_mpi_point_t a,
|
||||
gcry_mpi_t r);
|
||||
struct proof_dl *proof);
|
||||
int smc_zkp_dl_check (const gcry_mpi_point_t v,
|
||||
const gcry_mpi_point_t g,
|
||||
const gcry_mpi_point_t a,
|
||||
const gcry_mpi_t r);
|
||||
const struct proof_dl *proof);
|
||||
|
||||
void smc_zkp_2dle (const gcry_mpi_point_t v,
|
||||
const gcry_mpi_point_t w,
|
||||
const gcry_mpi_point_t g1,
|
||||
const gcry_mpi_point_t g2,
|
||||
const gcry_mpi_t x,
|
||||
gcry_mpi_point_t a,
|
||||
gcry_mpi_point_t b,
|
||||
gcry_mpi_t r);
|
||||
struct proof_2dle *proof);
|
||||
int smc_zkp_2dle_check (const gcry_mpi_point_t v,
|
||||
const gcry_mpi_point_t w,
|
||||
const gcry_mpi_point_t g1,
|
||||
const gcry_mpi_point_t g2,
|
||||
const gcry_mpi_point_t a,
|
||||
const gcry_mpi_point_t b,
|
||||
const gcry_mpi_t r);
|
||||
const struct proof_2dle *proof);
|
||||
|
||||
void smc_zkp_0og (gcry_mpi_point_t alpha,
|
||||
const gcry_mpi_point_t m,
|
||||
void smc_zkp_0og (int m_is_gen,
|
||||
const gcry_mpi_point_t y,
|
||||
gcry_mpi_t r,
|
||||
gcry_mpi_point_t alpha,
|
||||
gcry_mpi_point_t beta,
|
||||
gcry_mpi_point_t a1,
|
||||
gcry_mpi_point_t a2,
|
||||
gcry_mpi_point_t b1,
|
||||
gcry_mpi_point_t b2,
|
||||
gcry_mpi_t d1,
|
||||
gcry_mpi_t d2,
|
||||
gcry_mpi_t r1,
|
||||
gcry_mpi_t r2);
|
||||
int smc_zkp_0og_check (const gcry_mpi_point_t alpha,
|
||||
const gcry_mpi_point_t y,
|
||||
struct proof_0og *proof);
|
||||
int smc_zkp_0og_check (const gcry_mpi_point_t y,
|
||||
const gcry_mpi_point_t alpha,
|
||||
const gcry_mpi_point_t beta,
|
||||
const gcry_mpi_point_t a1,
|
||||
const gcry_mpi_point_t a2,
|
||||
const gcry_mpi_point_t b1,
|
||||
const gcry_mpi_point_t b2,
|
||||
const gcry_mpi_t d1,
|
||||
const gcry_mpi_t d2,
|
||||
const gcry_mpi_t r1,
|
||||
const gcry_mpi_t r2);
|
||||
const struct proof_0og *proof);
|
||||
|
||||
/* --- Protocol implementation --- */
|
||||
|
||||
|
@ -88,6 +88,10 @@ test_serialization ()
|
||||
check (!ec_point_cmp (oldp, newp), "serialization changed point");
|
||||
check (!gcry_mpi_cmp (oldi, newi), "serialization changed mpi");
|
||||
|
||||
mpi_serialize (&seri, GCRYMPI_CONST_ONE);
|
||||
mpi_parse (newi, &seri);
|
||||
check (!gcry_mpi_cmp (GCRYMPI_CONST_ONE, newi), "serializing mpi 1 fail");
|
||||
|
||||
gcry_mpi_point_release (oldp);
|
||||
gcry_mpi_point_release (newp);
|
||||
gcry_mpi_release (oldi);
|
||||
@ -98,33 +102,18 @@ test_serialization ()
|
||||
int
|
||||
test_smc_zkp_dl ()
|
||||
{
|
||||
gcry_mpi_t r = gcry_mpi_new (0);
|
||||
struct proof_dl proof;
|
||||
gcry_mpi_t x = gcry_mpi_new (0);
|
||||
gcry_mpi_point_t a = gcry_mpi_point_new (0);
|
||||
gcry_mpi_point_t g = gcry_mpi_point_new (0);
|
||||
gcry_mpi_point_t v = gcry_mpi_point_new (0);
|
||||
|
||||
ec_keypair_create (g, r);
|
||||
/* v = xg */
|
||||
ec_keypair_create (v, x);
|
||||
|
||||
if (0 == tests_run)
|
||||
{
|
||||
/* \todo: there has to be a better way to copy a point */
|
||||
gcry_mpi_ec_mul (g, GCRYMPI_CONST_ONE, ec_gen, ec_ctx);
|
||||
}
|
||||
|
||||
ec_keypair_create_base (v, x, g);
|
||||
|
||||
smc_zkp_dl (v, g, x, a, r);
|
||||
check (!smc_zkp_dl_check (v, g, a, r), "zkp dl wrong");
|
||||
|
||||
check (gcry_mpi_ec_curve_point (a, ec_ctx), "not on curve");
|
||||
check (gcry_mpi_ec_curve_point (g, ec_ctx), "not on curve");
|
||||
smc_zkp_dl (v, x, &proof);
|
||||
check (gcry_mpi_ec_curve_point (v, ec_ctx), "not on curve");
|
||||
check (!smc_zkp_dl_check (v, &proof), "zkp dl wrong");
|
||||
|
||||
gcry_mpi_release (r);
|
||||
gcry_mpi_release (x);
|
||||
gcry_mpi_point_release (a);
|
||||
gcry_mpi_point_release (g);
|
||||
gcry_mpi_point_release (v);
|
||||
}
|
||||
|
||||
@ -132,42 +121,24 @@ test_smc_zkp_dl ()
|
||||
int
|
||||
test_smc_zkp_2dle ()
|
||||
{
|
||||
gcry_mpi_t r = gcry_mpi_new (0);
|
||||
struct proof_2dle proof;
|
||||
gcry_mpi_t x = gcry_mpi_new (0);
|
||||
gcry_mpi_point_t a = gcry_mpi_point_new (0);
|
||||
gcry_mpi_point_t b = gcry_mpi_point_new (0);
|
||||
gcry_mpi_point_t g1 = gcry_mpi_point_new (0);
|
||||
gcry_mpi_point_t g2 = gcry_mpi_point_new (0);
|
||||
gcry_mpi_point_t v = gcry_mpi_point_new (0);
|
||||
gcry_mpi_point_t w = gcry_mpi_point_new (0);
|
||||
|
||||
ec_keypair_create (g1, r);
|
||||
ec_keypair_create (g2, r);
|
||||
ec_keypair_create (g1, x);
|
||||
ec_keypair_create (g2, x);
|
||||
|
||||
if (0 == tests_run)
|
||||
{
|
||||
/* \todo: there has to be a better way to copy a point */
|
||||
gcry_mpi_ec_mul (g1, GCRYMPI_CONST_ONE, ec_gen, ec_ctx);
|
||||
gcry_mpi_ec_mul (g2, GCRYMPI_CONST_ONE, ec_gen, ec_ctx);
|
||||
}
|
||||
|
||||
ec_keypair_create_base (v, x, g1);
|
||||
gcry_mpi_ec_mul (w, x, g2, ec_ctx);
|
||||
|
||||
smc_zkp_2dle (v, w, g1, g2, x, a, b, r);
|
||||
check (!smc_zkp_2dle_check (v, w, g1, g2, a, b, r), "zkp 2dle wrong");
|
||||
|
||||
check (gcry_mpi_ec_curve_point (a, ec_ctx), "not on curve");
|
||||
check (gcry_mpi_ec_curve_point (b, ec_ctx), "not on curve");
|
||||
smc_zkp_2dle (v, w, g1, g2, x, &proof);
|
||||
check (gcry_mpi_ec_curve_point (g1, ec_ctx), "not on curve");
|
||||
check (gcry_mpi_ec_curve_point (g2, ec_ctx), "not on curve");
|
||||
check (gcry_mpi_ec_curve_point (v, ec_ctx), "not on curve");
|
||||
check (gcry_mpi_ec_curve_point (w, ec_ctx), "not on curve");
|
||||
check (!smc_zkp_2dle_check (v, w, g1, g2, &proof), "zkp 2dle wrong");
|
||||
|
||||
gcry_mpi_release (r);
|
||||
gcry_mpi_release (x);
|
||||
gcry_mpi_point_release (a);
|
||||
gcry_mpi_point_release (b);
|
||||
gcry_mpi_point_release (g1);
|
||||
gcry_mpi_point_release (g2);
|
||||
gcry_mpi_point_release (v);
|
||||
@ -178,51 +149,30 @@ test_smc_zkp_2dle ()
|
||||
int
|
||||
test_smc_zkp_0og ()
|
||||
{
|
||||
gcry_mpi_t d1 = gcry_mpi_new (0);
|
||||
gcry_mpi_t d2 = gcry_mpi_new (0);
|
||||
gcry_mpi_t r1 = gcry_mpi_new (0);
|
||||
gcry_mpi_t r2 = gcry_mpi_new (0);
|
||||
struct proof_0og proof;
|
||||
gcry_mpi_point_t y = gcry_mpi_point_new (0);
|
||||
gcry_mpi_point_t alpha = gcry_mpi_point_new (0);
|
||||
gcry_mpi_point_t beta = gcry_mpi_point_new (0);
|
||||
gcry_mpi_point_t a1 = gcry_mpi_point_new (0);
|
||||
gcry_mpi_point_t a2 = gcry_mpi_point_new (0);
|
||||
gcry_mpi_point_t b1 = gcry_mpi_point_new (0);
|
||||
gcry_mpi_point_t b2 = gcry_mpi_point_new (0);
|
||||
|
||||
ec_keypair_create (y, r1);
|
||||
/* get random public key point. We don't need the secret key to check the
|
||||
* proof here */
|
||||
ec_keypair_create (y, NULL);
|
||||
|
||||
smc_zkp_0og (alpha, (tests_run % 2 ? ec_zero : ec_gen), y, beta, a1, a2, b1,
|
||||
b2, d1, d2, r1, r2);
|
||||
check (!smc_zkp_0og_check (alpha, y, beta, a1, a2, b1, b2, d1, d2, r1,
|
||||
r2), "zkp 0og is wrong");
|
||||
|
||||
check (gcry_mpi_ec_curve_point (y, ec_ctx), "not on curve");
|
||||
smc_zkp_0og (tests_run % 2, y, NULL, alpha, beta, &proof);
|
||||
check (gcry_mpi_ec_curve_point (alpha, ec_ctx), "not on curve");
|
||||
check (gcry_mpi_ec_curve_point (beta, ec_ctx), "not on curve");
|
||||
check (gcry_mpi_ec_curve_point (a1, ec_ctx), "not on curve");
|
||||
check (gcry_mpi_ec_curve_point (a2, ec_ctx), "not on curve");
|
||||
check (gcry_mpi_ec_curve_point (b1, ec_ctx), "not on curve");
|
||||
check (gcry_mpi_ec_curve_point (b2, ec_ctx), "not on curve");
|
||||
check (!smc_zkp_0og_check (y, alpha, beta, &proof), "zkp 0og is wrong");
|
||||
|
||||
gcry_mpi_release (d1);
|
||||
gcry_mpi_release (d2);
|
||||
gcry_mpi_release (r1);
|
||||
gcry_mpi_release (r2);
|
||||
gcry_mpi_point_release (y);
|
||||
gcry_mpi_point_release (alpha);
|
||||
gcry_mpi_point_release (beta);
|
||||
gcry_mpi_point_release (a1);
|
||||
gcry_mpi_point_release (a2);
|
||||
gcry_mpi_point_release (b1);
|
||||
gcry_mpi_point_release (b2);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
int repeat = 8;
|
||||
int repeat = 16;
|
||||
|
||||
BRANDT_init ();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user