@@@ testing
[secnet] / dh.c
diff --git a/dh.c b/dh.c
index 0b5e4d2..7a25ee1 100644 (file)
--- a/dh.c
+++ b/dh.c
@@ -42,10 +42,10 @@ struct dh {
     MP_INT p,g; /* prime modulus and generator */
 };
 
-static string_t dh_makepublic(void *sst, uint8_t *secret, int32_t secretlen)
+static int32_t dh_makepublic(void *sst, void *public, int32_t publiclen,
+                            uint8_t *secret, int32_t secretlen)
 {
     struct dh *st=sst;
-    string_t r;
     MP_INT a, b; /* a is secret key, b is public key */
 
     mpz_init(&a);
@@ -55,17 +55,19 @@ static string_t dh_makepublic(void *sst, uint8_t *secret, int32_t secretlen)
 
     mpz_powm_sec(&b, &st->g, &a, &st->p);
 
-    r=write_mpstring(&b);
+    assert(mpz_sizeinbase(&b, 16) + 2 <= (size_t)publiclen);
+    mpz_get_str(public, 16, &b);
 
     mpz_clear(&a);
     mpz_clear(&b);
-    return r;
+
+    return strlen(public);
 }
 
 static dh_makeshared_fn dh_makeshared;
 static bool_t dh_makeshared(void *sst, uint8_t *secret, int32_t secretlen,
-                           cstring_t rempublic, uint8_t *sharedsecret,
-                           int32_t buflen)
+                           const void *public, int32_t publiclen,
+                           uint8_t *sharedsecret, int32_t buflen)
 {
     struct dh *st=sst;
     MP_INT a, b, c;
@@ -75,7 +77,7 @@ static bool_t dh_makeshared(void *sst, uint8_t *secret, int32_t secretlen,
     mpz_init(&c);
 
     read_mpbin(&a, secret, secretlen);
-    mpz_set_str(&b, rempublic, 16);
+    mpz_set_str(&b, public, 16);
 
     mpz_powm_sec(&c, &b, &a, &st->p);
 
@@ -170,6 +172,8 @@ static list_t *dh_apply(closure_t *self, struct cloc loc, dict_t *context,
     /* According to the docs, mpz_sizeinbase(,256) is allowed to return
      * an answer which is 1 too large.  But mpz_sizeinbase(,2) isn't. */
 
+    st->ops.public_len=(mpz_sizeinbase(&st->p,16)+2);
+
     if (!dict)
        st->ops.capab_bit = CAPAB_BIT_TRADZP;
     else