#include <gcrypt.h>
#include "gnunet_util_lib.h"
-#define EXTRA_CHECKS ALLOW_EXTRA_CHECKS
+#define EXTRA_CHECKS 0
/**
* Name of the curve we are using. Note that we have hard-coded
}
-/**
- * If target != size, move @a target bytes to the end of the size-sized
- * buffer and zero out the first @a target - @a size bytes.
- *
- * @param buf original buffer
- * @param size number of bytes in @a buf
- * @param target target size of the buffer
- */
-static void
-adjust (unsigned char *buf,
- size_t size,
- size_t target)
-{
- if (size < target)
- {
- memmove (&buf[target - size], buf, size);
- memset (buf, 0, target - size);
- }
-}
-
-
-/**
- * Output the given MPI value to the given buffer.
- *
- * @param buf where to output to
- * @param size number of bytes in @a buf
- * @param val value to write to @a buf
- */
-static void
-mpi_print (unsigned char *buf,
- size_t size,
- gcry_mpi_t val)
-{
- size_t rsize;
-
- if (gcry_mpi_get_flag (val, GCRYMPI_FLAG_OPAQUE))
- {
- /* Store opaque MPIs left aligned into the buffer. */
- unsigned int nbits;
- const void *p;
-
- p = gcry_mpi_get_opaque (val, &nbits);
- GNUNET_assert (p);
- rsize = (nbits+7)/8;
- if (rsize > size)
- rsize = size;
- memcpy (buf, p, rsize);
- if (rsize < size)
- memset (buf+rsize, 0, size - rsize);
- }
- else
- {
- /* Store regular MPIs as unsigned integers right aligned into
- the buffer. */
- rsize = size;
- GNUNET_assert (0 ==
- gcry_mpi_print (GCRYMPI_FMT_USG, buf, rsize, &rsize,
- val));
- adjust (buf, rsize, size);
- }
-}
-
-
-/**
- * Convert data buffer into MPI value.
- *
- * @param result where to store MPI value (allocated)
- * @param data raw data (GCRYMPI_FMT_USG)
- * @param size number of bytes in data
- */
-static void
-mpi_scan (gcry_mpi_t *result,
- const unsigned char *data,
- size_t size)
-{
- int rc;
-
- if (0 != (rc = gcry_mpi_scan (result,
- GCRYMPI_FMT_USG,
- data, size, &size)))
- {
- LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
- GNUNET_assert (0);
- }
-}
-
-
/**
* Convert the given private key from the network format to the
* S-expression that can be used by libgcrypt.
gcry_sexp_release (sexp);
q = gcry_mpi_ec_get_mpi ("q@eddsa", ctx, 0);
GNUNET_assert (q);
- mpi_print (pub->q_y, sizeof (pub->q_y), q);
+ GNUNET_CRYPTO_mpi_print_unsigned (pub->q_y, sizeof (pub->q_y), q);
gcry_mpi_release (q);
gcry_ctx_release (ctx);
}
gcry_sexp_release (sexp);
q = gcry_mpi_ec_get_mpi ("q@eddsa", ctx, 0);
GNUNET_assert (q);
- mpi_print (pub->q_y, sizeof (pub->q_y), q);
+ GNUNET_CRYPTO_mpi_print_unsigned (pub->q_y, sizeof (pub->q_y), q);
gcry_mpi_release (q);
gcry_ctx_release (ctx);
}
gcry_sexp_release (sexp);
q = gcry_mpi_ec_get_mpi ("q@eddsa", ctx, 0);
GNUNET_assert (q);
- mpi_print (pub->q_y, sizeof (pub->q_y), q);
+ GNUNET_CRYPTO_mpi_print_unsigned (pub->q_y, sizeof (pub->q_y), q);
gcry_mpi_release (q);
gcry_ctx_release (ctx);
}
if (0 != (rc = gcry_sexp_build (&s_keyparam, NULL,
"(genkey(ecc(curve \"" CURVE "\")"
- "(flags noparam)))")))
+ "(flags)))")))
{
LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
return NULL;
}
gcry_sexp_release (priv_sexp);
priv = GNUNET_new (struct GNUNET_CRYPTO_EcdhePrivateKey);
- mpi_print (priv->d, sizeof (priv->d), d);
+ GNUNET_CRYPTO_mpi_print_unsigned (priv->d, sizeof (priv->d), d);
gcry_mpi_release (d);
return priv;
}
if (0 != (rc = gcry_sexp_build (&s_keyparam, NULL,
"(genkey(ecc(curve \"" CURVE "\")"
- "(flags noparam)))")))
+ "(flags)))")))
{
LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
return NULL;
}
gcry_sexp_release (priv_sexp);
priv = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPrivateKey);
- mpi_print (priv->d, sizeof (priv->d), d);
+ GNUNET_CRYPTO_mpi_print_unsigned (priv->d, sizeof (priv->d), d);
gcry_mpi_release (d);
return priv;
}
if (0 != (rc = gcry_sexp_build (&s_keyparam, NULL,
"(genkey(ecc(curve \"" CURVE "\")"
- "(flags noparam eddsa)))")))
+ "(flags eddsa)))")))
{
LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
return NULL;
}
gcry_sexp_release (priv_sexp);
priv = GNUNET_new (struct GNUNET_CRYPTO_EddsaPrivateKey);
- mpi_print (priv->d, sizeof (priv->d), d);
+ GNUNET_CRYPTO_mpi_print_unsigned (priv->d, sizeof (priv->d), d);
gcry_mpi_release (d);
return priv;
}
if (once)
return &anonymous;
- mpi_print (anonymous.d,
+ GNUNET_CRYPTO_mpi_print_unsigned (anonymous.d,
sizeof (anonymous.d),
GCRYMPI_CONST_ONE);
once = 1;
}
+/**
+ * Compare two Peer Identities.
+ *
+ * @param first first peer identity
+ * @param second second peer identity
+ * @return bigger than 0 if first > second,
+ * 0 if they are the same
+ * smaller than 0 if second > first
+ */
+int
+GNUNET_CRYPTO_cmp_peer_identity (const struct GNUNET_PeerIdentity *first,
+ const struct GNUNET_PeerIdentity *second)
+{
+ return memcmp (first, second, sizeof (struct GNUNET_PeerIdentity));
+}
+
+
/**
* Convert the data specified in the given purpose argument to an
* S-expression suitable for signature operations.
return GNUNET_SYSERR;
}
gcry_sexp_release (sig_sexp);
- mpi_print (sig->r, sizeof (sig->r), rs[0]);
- mpi_print (sig->s, sizeof (sig->s), rs[1]);
+ GNUNET_CRYPTO_mpi_print_unsigned (sig->r, sizeof (sig->r), rs[0]);
+ GNUNET_CRYPTO_mpi_print_unsigned (sig->s, sizeof (sig->s), rs[1]);
gcry_mpi_release (rs[0]);
gcry_mpi_release (rs[1]);
return GNUNET_OK;
return GNUNET_SYSERR;
}
gcry_sexp_release (sig_sexp);
- mpi_print (sig->r, sizeof (sig->r), rs[0]);
- mpi_print (sig->s, sizeof (sig->s), rs[1]);
+ GNUNET_CRYPTO_mpi_print_unsigned (sig->r, sizeof (sig->r), rs[0]);
+ GNUNET_CRYPTO_mpi_print_unsigned (sig->s, sizeof (sig->s), rs[1]);
gcry_mpi_release (rs[0]);
gcry_mpi_release (rs[1]);
return GNUNET_OK;
q = gcry_mpi_ec_get_point ("q", ctx, 0);
/* second, extract the d value from our private key */
- mpi_scan (&d, priv->d, sizeof (priv->d));
+ GNUNET_CRYPTO_mpi_scan_unsigned (&d, priv->d, sizeof (priv->d));
/* then call the 'multiply' function, to compute the product */
result = gcry_mpi_point_new (0);
rsize = sizeof (xbuf);
GNUNET_assert (! gcry_mpi_get_flag (result_x, GCRYMPI_FLAG_OPAQUE));
- /* result_x can be negative here, so we do not use 'mpi_print'
+ /* result_x can be negative here, so we do not use 'GNUNET_CRYPTO_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 */
label, strlen (label),
context, strlen (context),
NULL, 0);
- mpi_scan (&h, (unsigned char *) &hc, sizeof (hc));
+ GNUNET_CRYPTO_mpi_scan_unsigned (&h, (unsigned char *) &hc, sizeof (hc));
return h;
}
GNUNET_CRYPTO_ecdsa_key_get_public (priv, &pub);
h = derive_h (&pub, label, context);
- mpi_scan (&x, priv->d, sizeof (priv->d));
+ GNUNET_CRYPTO_mpi_scan_unsigned (&x, priv->d, sizeof (priv->d));
d = gcry_mpi_new (256);
gcry_mpi_mulm (d, h, x, n);
gcry_mpi_release (h);
gcry_mpi_release (n);
gcry_ctx_release (ctx);
ret = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPrivateKey);
- mpi_print (ret->d, sizeof (ret->d), d);
+ GNUNET_CRYPTO_mpi_print_unsigned (ret->d, sizeof (ret->d), d);
gcry_mpi_release (d);
return ret;
}
+/**
+ * Computes a new PeerIdentity using the Chord formula.
+ * new_peer_identity = ((my_identity + pow(2,i)) mod (pow(2,m)
+ * where m, size of struct GNUNET_PeerIdentity in bits.
+ * i, 0 <= i <= m
+ * @param my_identity original PeerIdentity
+ * @param value of i.
+ * @return finger_identity
+ */
+struct GNUNET_PeerIdentity *
+GNUNET_CRYPTO_compute_finger_identity(struct GNUNET_PeerIdentity *my_identity, unsigned int index)
+{
+ gcry_mpi_t my_identity_mpi;
+ gcry_mpi_t finger_identity_mpi;
+ gcry_mpi_t add;
+ gcry_mpi_t mod;
+ gcry_error_t rc;
+ struct GNUNET_PeerIdentity *finger_identity;
+ size_t read = 0;
+ size_t write = 0;
+
+ finger_identity = GNUNET_malloc(sizeof(struct GNUNET_PeerIdentity));
+
+ /* Initialize my_identity_mpi. */
+ my_identity_mpi = gcry_mpi_new(8*sizeof(struct GNUNET_PeerIdentity));
+
+ /* Copy my_identity into my_id */
+ if(0 != (rc = gcry_mpi_scan(&my_identity_mpi, GCRYMPI_FMT_USG, my_identity->public_key.q_y,
+ sizeof(struct GNUNET_PeerIdentity), &read)))
+ {
+ LOG_GCRY (GNUNET_ERROR_TYPE_DEBUG, "gcry_mpi_scan", rc);
+ GNUNET_free(finger_identity);
+ return NULL;
+ }
+
+ /* Initialize finger_identity_mpi */
+ finger_identity_mpi = gcry_mpi_new(8*sizeof(struct GNUNET_PeerIdentity));
+
+ /* Initialize add */
+ add = gcry_mpi_new(8*sizeof(struct GNUNET_PeerIdentity));
+
+ /* Set the index bit in add.*/
+ gcry_mpi_set_bit(add,index);
+
+ /* Initialize mod */
+ mod = gcry_mpi_new(8*sizeof(struct GNUNET_PeerIdentity) + 1);
+ gcry_mpi_set_bit(mod,257);
+ gcry_mpi_sub_ui(mod,mod,(unsigned long)1);
+
+
+ /* finger_identity_mpi = (my_identity_mpi + add) % mod */
+ gcry_mpi_addm(finger_identity_mpi,my_identity_mpi,add,mod);
+
+
+ /* Copy finger_identity_mpi to finger_identity */
+ if(0 != (rc = gcry_mpi_print(GCRYMPI_FMT_USG,finger_identity->public_key.q_y,
+ 32,&write,finger_identity_mpi)))
+ {
+ LOG_GCRY (GNUNET_ERROR_TYPE_DEBUG, "gcry_mpi_print", rc);
+ GNUNET_free(finger_identity);
+ return NULL;
+ }
+
+ return finger_identity;
+}
+
+
/**
* Derive a public key from a given public key and a label.
* Essentially calculates a public key 'V = H(l,P) * P'.
*
* @param pub original public key
- * @param label label to use for key deriviation
+ * @param label label to use for key derivation
* @param context additional context to use for HKDF of 'h';
* typically the name of the subsystem/application
* @param result where to write the derived public key
q = gcry_mpi_ec_get_point ("q", ctx, 0);
GNUNET_assert (q);
- /* calulcate h_mod_n = h % n */
+ /* calculate h_mod_n = h % n */
h = derive_h (pub, label, context);
n = gcry_mpi_ec_get_mpi ("n", ctx, 1);
h_mod_n = gcry_mpi_new (256);
gcry_mpi_point_release (v);
q_y = gcry_mpi_ec_get_mpi ("q@eddsa", ctx, 0);
GNUNET_assert (q_y);
- mpi_print (result->q_y, sizeof result->q_y, q_y);
+ GNUNET_CRYPTO_mpi_print_unsigned (result->q_y, sizeof result->q_y, q_y);
gcry_mpi_release (q_y);
gcry_ctx_release (ctx);
}