aboutsummaryrefslogtreecommitdiff
path: root/crypto.c
diff options
context:
space:
mode:
authorMarkus Teich <markus.teich@stusta.mhn.de>2016-06-16 00:09:29 +0200
committerMarkus Teich <markus.teich@stusta.mhn.de>2016-06-17 10:29:49 +0200
commit761dd37e1f905719df2cd8f4420e4b46da80bffb (patch)
treeb93ec567a19e2407274fc3350ea51186aac8f091 /crypto.c
parent6f3fb463176c04c9a258fce820ec66724a4d13f4 (diff)
refactor smc and ec crypto functions and ad 0og zkp
Diffstat (limited to 'crypto.c')
-rw-r--r--crypto.c263
1 files changed, 49 insertions, 214 deletions
diff --git a/crypto.c b/crypto.c
index 55ab26a..b4f71e4 100644
--- a/crypto.c
+++ b/crypto.c
@@ -34,8 +34,10 @@ struct brandt_ec_pkey {
unsigned char q_y[256 / 8];
};
-gcry_mpi_point_t ec_gen;
gcry_ctx_t ec_ctx;
+gcry_mpi_point_t ec_gen;
+gcry_mpi_point_t ec_zero;
+gcry_mpi_t ec_n;
/**
* brandt_crypto_init
@@ -49,10 +51,19 @@ brandt_crypto_init ()
rc = gcry_mpi_ec_new (&ec_ctx, NULL, CURVE);
brandt_assert_gpgerr (rc);
+
ec_gen = gcry_mpi_ec_get_point ("g", ec_ctx, 0);
brandt_assert (NULL != ec_gen);
+
+ ec_zero = gcry_mpi_point_new (0);
+ brandt_assert (NULL != ec_zero);
+ gcry_mpi_ec_sub (ec_zero, ec_gen, ec_gen, ec_ctx);
+
+ ec_n = gcry_mpi_ec_get_mpi ("n", ec_ctx, 1);
+ brandt_assert (NULL != ec_n);
}
+
/* --- RANDOM --- */
void
@@ -64,6 +75,7 @@ brandt_rand_poll ()
gcry_fast_random_poll ();
}
+
/* --- HASHING --- */
/**
@@ -79,6 +91,7 @@ brandt_hash (const void *block, size_t size, struct brandt_hash_code *ret)
gcry_md_hash_buffer (GCRY_MD_SHA512, ret, block, size);
}
+
/* --- MPI --- */
/**
@@ -101,6 +114,7 @@ adjust (void *buf, size_t size, size_t target)
}
}
+
/**
* Output the given MPI value to the given buffer in
* network byte order.
@@ -141,6 +155,7 @@ brandt_mpi_print_unsigned (void *buf, size_t size, gcry_mpi_t val)
}
}
+
/**
* Convert data buffer into MPI value.
* The buffer is interpreted as network
@@ -159,6 +174,7 @@ brandt_mpi_scan_unsigned (gcry_mpi_t *result, const void *data, size_t size)
brandt_assert_gpgerr (rc);
}
+
//gcry_mpi_point_t
//deserialize_point(const struct brandt_point* data, const int len)
//{
@@ -185,73 +201,18 @@ brandt_mpi_scan_unsigned (gcry_mpi_t *result, const void *data, size_t size)
/* --- EC --- */
/**
- * Extract values from an S-expression.
- *
- * @param array where to store the result(s)
- * @param sexp S-expression to parse
- * @param topname top-level name in the S-expression that is of interest
- * @param elems names of the elements to extract
- * @return 0 on success
- */
-static int
-key_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp, const char *topname,
- const char *elems)
-{
- gcry_sexp_t list;
- gcry_sexp_t l2;
- const char *s;
- unsigned int i;
- unsigned int idx;
-
- list = gcry_sexp_find_token (sexp, topname, 0);
- if (!list)
- return 1;
- l2 = gcry_sexp_cadr (list);
- gcry_sexp_release (list);
- list = l2;
- if (!list)
- return 2;
- idx = 0;
- for (s = elems; *s; s++, idx++)
- {
- l2 = gcry_sexp_find_token (list, s, 1);
- if (!l2)
- {
- for (i = 0; i < idx; i++)
- {
- gcry_free (array[i]);
- array[i] = NULL;
- }
- gcry_sexp_release (list);
- return 3; /* required parameter not found */
- }
- array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
- gcry_sexp_release (l2);
- if (!array[idx])
- {
- for (i = 0; i < idx; i++)
- {
- gcry_free (array[i]);
- array[i] = NULL;
- }
- gcry_sexp_release (list);
- return 4; /* required parameter is invalid */
- }
- }
- gcry_sexp_release (list);
- return 0;
-}
-
-/**
* brandt_ec_skey_create
*
* @param[out] skey where to store the generated secret key
*/
void
-brandt_ec_skey_create (gcry_mpi_t *skey)
+brandt_ec_skey_create (gcry_mpi_t skey)
{
+ gcry_mpi_t ret;
gcry_sexp_t s_keyparam;
gcry_sexp_t priv_sexp;
+ gcry_sexp_t priv_key;
+ gcry_sexp_t priv_key2;
gcry_error_t rc;
rc = gcry_sexp_build (&s_keyparam, NULL, "(genkey(ecc(curve \"" CURVE "\")"
@@ -262,24 +223,22 @@ brandt_ec_skey_create (gcry_mpi_t *skey)
brandt_assert_gpgerr (rc);
gcry_sexp_release (s_keyparam);
- rc = key_from_sexp (skey, priv_sexp, "private-key", "d");
- brandt_assert_gpgerr (rc);
-
+ priv_key = gcry_sexp_find_token (priv_sexp, "private-key", 11);
+ brandt_assert (NULL != priv_key);
gcry_sexp_release (priv_sexp);
-}
-/**
- * brandt_ec_pkey_compute
- *
- * @param pkey TODO
- * @param skey TODO
- */
-void
-brandt_ec_pkey_compute (gcry_mpi_point_t *pkey, const gcry_mpi_t skey)
-{
+ priv_key2 = gcry_sexp_find_token (priv_key, "d", 1);
+ brandt_assert (NULL != priv_key2);
+ gcry_sexp_release (priv_key);
+ ret = gcry_sexp_nth_mpi (priv_key2, 1, GCRYMPI_FMT_USG);
+ brandt_assert (NULL != ret);
+ gcry_sexp_release (priv_key2);
+
+ gcry_mpi_snatch (skey, ret);
}
+
/**
* brandt_ec_keypair_create
*
@@ -287,33 +246,16 @@ brandt_ec_pkey_compute (gcry_mpi_point_t *pkey, const gcry_mpi_t skey)
* @param[out] skey where to store the generated secret key
*/
void
-brandt_ec_keypair_create (gcry_mpi_point_t *pkey, gcry_mpi_t *skey)
+brandt_ec_keypair_create (gcry_mpi_point_t pkey, gcry_mpi_t skey)
{
- gcry_ctx_t ctx;
- gcry_sexp_t s_keyparam;
- gcry_sexp_t priv_sexp;
- gcry_error_t rc;
-
- rc = gcry_sexp_build (&s_keyparam, NULL, "(genkey(ecc(curve \"" CURVE "\")"
- "(flags)))");
- brandt_assert_gpgerr (rc);
-
- rc = gcry_pk_genkey (&priv_sexp, s_keyparam);
- brandt_assert_gpgerr (rc);
- gcry_sexp_release (s_keyparam);
-
- rc = key_from_sexp (skey, priv_sexp, "private-key", "d");
- brandt_assert_gpgerr (rc);
-
- rc = gcry_mpi_ec_new (&ctx, priv_sexp, NULL);
- brandt_assert_gpgerr (rc);
- gcry_sexp_release (priv_sexp);
+ brandt_assert (NULL != pkey);
+ brandt_assert (NULL != skey);
- *pkey = gcry_mpi_ec_get_point ("q", ctx, 0);
- brandt_assert (NULL != *pkey);
- gcry_ctx_release (ctx);
+ brandt_ec_skey_create (skey);
+ gcry_mpi_ec_mul (pkey, skey, ec_gen, ec_ctx);
}
+
/**
* brandt_ec_keypair_create_base
*
@@ -322,16 +264,19 @@ brandt_ec_keypair_create (gcry_mpi_point_t *pkey, gcry_mpi_t *skey)
* @param[in] base which base point should be used to calculate the public key
*/
void
-brandt_ec_keypair_create_base (gcry_mpi_point_t *pkey, gcry_mpi_t *skey,
+brandt_ec_keypair_create_base (gcry_mpi_point_t pkey,
+ gcry_mpi_t skey,
const gcry_mpi_point_t base)
{
+ brandt_assert (NULL != pkey);
+ brandt_assert (NULL != skey);
+ brandt_assert (NULL != base);
+
brandt_ec_skey_create (skey);
- brandt_assert (*skey);
- *pkey = gcry_mpi_point_new (0);
- brandt_assert (*pkey);
- gcry_mpi_ec_mul (*pkey, *skey, base, ec_ctx);
+ gcry_mpi_ec_mul (pkey, skey, base, ec_ctx);
}
+
/**
* brandt_ec_point_cmp compares two curve points
*
@@ -356,8 +301,8 @@ brandt_ec_point_cmp (const gcry_mpi_point_t a, const gcry_mpi_point_t b)
return 1;
}
- if (!gcry_mpi_ec_get_affine (ax, ay, a, ec_ctx)
- && !gcry_mpi_ec_get_affine (bx, by, b, ec_ctx))
+ if (!gcry_mpi_ec_get_affine (ax, ay, a, ec_ctx) &&
+ !gcry_mpi_ec_get_affine (bx, by, b, ec_ctx))
{
ret = gcry_mpi_cmp (ax, bx) || gcry_mpi_cmp (ay, by);
}
@@ -369,117 +314,6 @@ brandt_ec_point_cmp (const gcry_mpi_point_t a, const gcry_mpi_point_t b)
return ret;
}
-/**
- * Convert the given private key from the network format to the
- * S-expression that can be used by libgcrypt.
- *
- * @param priv private key to decode
- * @return NULL on error
- */
-static gcry_sexp_t
-decode_private_ecdhe_key (const struct brandt_ec_skey *priv)
-{
- gcry_sexp_t result;
- gcry_error_t rc;
-
- rc = gcry_sexp_build (&result, NULL,
- "(private-key(ecc(curve \"" CURVE "\")"
- "(d %b)))",
- (int)sizeof (priv->d), priv->d);
- brandt_assert_gpgerr (rc);
- return result;
-}
-
-/**
- * Extract the public key for the given private key.
- *
- * @param priv the private key
- * @param pub where to write the public key
- */
-void
-brandt_ecdhe_key_get_public (const struct brandt_ec_skey *priv,
- struct brandt_ec_pkey *pub)
-{
- gcry_sexp_t sexp;
- gcry_ctx_t ctx;
- gcry_mpi_t q;
- gcry_error_t rc;
-
- sexp = decode_private_ecdhe_key (priv);
- brandt_assert (NULL != sexp);
- rc = gcry_mpi_ec_new (&ctx, sexp, NULL);
- brandt_assert_gpgerr (rc);
- gcry_sexp_release (sexp);
- q = gcry_mpi_ec_get_mpi ("q@eddsa", ctx, 0);
- brandt_assert (NULL != q);
- brandt_mpi_print_unsigned (pub->q_y, sizeof (pub->q_y), q);
- gcry_mpi_release (q);
- gcry_ctx_release (ctx);
-}
-
-/**
- * Derive key material from a public and a private ECDHE key.
- *
- * @param priv private key to use for the ECDH (x)
- * @param pub public key to use for the ECDH (yG)
- * @param key_material where to write the key material (xyG)
- * @return 0 on error, 1 on success
- */
-int
-brandt_ecdhe (const struct brandt_ec_skey *priv,
- const struct brandt_ec_pkey *pub,
- struct brandt_hash_code *key_material)
-{
- gcry_error_t rc;
- int rc2;
- gcry_mpi_point_t result;
- gcry_mpi_point_t q;
- gcry_mpi_t d;
- gcry_ctx_t ctx;
- gcry_sexp_t pub_sexpr;
- gcry_mpi_t result_x;
- unsigned char xbuf[256 / 8];
- size_t rsize;
-
- /* first, extract the q = dP value from the public key */
- if (0 != gcry_sexp_build (&pub_sexpr, NULL,
- "(public-key(ecc(curve " CURVE ")(q %b)))",
- (int)sizeof (pub->q_y), pub->q_y))
- return 0;
- rc = gcry_mpi_ec_new (&ctx, pub_sexpr, NULL);
- brandt_assert_gpgerr (rc);
- gcry_sexp_release (pub_sexpr);
- q = gcry_mpi_ec_get_point ("q", ctx, 0);
-
- /* second, extract the d value from our private key */
- brandt_mpi_scan_unsigned (&d, priv->d, sizeof (priv->d));
-
- /* then call the 'multiply' function, to compute the product */
- result = gcry_mpi_point_new (0);
- gcry_mpi_ec_mul (result, d, q, ctx);
- gcry_mpi_point_release (q);
- gcry_mpi_release (d);
-
- /* finally, convert point to string for hashing */
- result_x = gcry_mpi_new (256);
- rc = gcry_mpi_ec_get_affine (result_x, NULL, result, ctx);
- brandt_assert (0 == rc);
- gcry_mpi_point_release (result);
- gcry_ctx_release (ctx);
-
- rsize = sizeof (xbuf);
- rc2 = gcry_mpi_get_flag (result_x, GCRYMPI_FLAG_OPAQUE);
- brandt_assert (0 == rc2);
- /* result_x can be negative here, so we do not use 'brandt_mpi_print_unsigned'
- * as that does not include the sign bit; x should be a 255-bit
- * value, so with the sign it should fit snugly into the 256-bit
- * xbuf */
- rc = gcry_mpi_print (GCRYMPI_FMT_STD, xbuf, rsize, &rsize, result_x);
- brandt_assert_gpgerr (rc);
- brandt_hash (xbuf, rsize, key_material);
- gcry_mpi_release (result_x);
- return 1;
-}
/**
* Clear memory that was used to store a private key.
@@ -492,6 +326,7 @@ brandt_ec_key_clear (struct brandt_ec_skey *skey)
memset (skey, 0, sizeof (struct brandt_ec_skey));
}
+
/**
* Generate a random value mod n.
*