Пример #1
0
/**
 * Multiply the generator g of the elliptic curve by @a val
 * to obtain the point on the curve representing @a val.
 * Afterwards, point addition will correspond to integer
 * addition.  #GNUNET_CRYPTO_ecc_dlog() can be used to
 * convert a point back to an integer (as long as the
 * integer is smaller than the MAX of the @a edc context).
 *
 * @param edc calculation context for ECC operations
 * @param val value to encode into a point
 * @return representation of the value as an ECC point,
 *         must be freed using #GNUNET_CRYPTO_ecc_free()
 */
gcry_mpi_point_t
GNUNET_CRYPTO_ecc_dexp (struct GNUNET_CRYPTO_EccDlogContext *edc,
			int val)
{
  gcry_mpi_t fact;
  gcry_mpi_t n;
  gcry_mpi_point_t g;
  gcry_mpi_point_t r;

  g = gcry_mpi_ec_get_point ("g", edc->ctx, 0);
  GNUNET_assert (NULL != g);
  fact = gcry_mpi_new (0);
  if (val < 0)
  {
    n = gcry_mpi_ec_get_mpi ("n", edc->ctx, 1);
    gcry_mpi_set_ui (fact, - val);
    gcry_mpi_sub (fact, n, fact);
    gcry_mpi_release (n);
  }
  else
  {
    gcry_mpi_set_ui (fact, val);
  }
  r = gcry_mpi_point_new (0);
  gcry_mpi_ec_mul (r, fact, g, edc->ctx);
  gcry_mpi_release (fact);
  gcry_mpi_point_release (g);
  return r;
}
Пример #2
0
int point_decompress(struct affine_point *p, const gcry_mpi_t x, int yflag, 
		     const struct domain_params *dp)
{
  gcry_mpi_t h, y;
  int res;
  h = gcry_mpi_snew(0);
  y = gcry_mpi_snew(0);
  gcry_mpi_mulm(h, x, x, dp->m);
  gcry_mpi_addm(h, h, dp->a, dp->m);
  gcry_mpi_mulm(h, h, x, dp->m);
  gcry_mpi_addm(h, h, dp->b, dp->m);
  if ((res = mod_root(y, h, dp->m)))
    if ((res = (gcry_mpi_cmp_ui(y, 0) || ! yflag))) {
      p->x = gcry_mpi_snew(0);
      p->y = gcry_mpi_snew(0);
      gcry_mpi_set(p->x, x);
      if (gcry_mpi_test_bit(y, 0) == yflag)
	gcry_mpi_set(p->y, y);
      else
	gcry_mpi_sub(p->y, dp->m, y);
      assert(point_on_curve(p, dp));
    }
  gcry_mpi_release(h);
  gcry_mpi_release(y);
  return res;
}
Пример #3
0
/* compute 2^m (mod phi(p)), for a prime p */
static gcry_mpi_t twopowmodphi(uint64_t m, const gcry_mpi_t p) {
        gcry_mpi_t phi, r;
        int n;

        phi = gcry_mpi_new(0);
        gcry_mpi_sub_ui(phi, p, 1);

        /* count number of used bits in m */
        for (n = 0; (1ULL << n) <= m; n++)
                ;

        r = gcry_mpi_new(0);
        gcry_mpi_set_ui(r, 1);
        while (n) { /* square and multiply algorithm for fast exponentiation */
                n--;
                gcry_mpi_mulm(r, r, r, phi);
                if (m & ((uint64_t)1 << n)) {
                        gcry_mpi_add(r, r, r);
                        if (gcry_mpi_cmp(r, phi) >= 0)
                                gcry_mpi_sub(r, r, phi);
                }
        }

        gcry_mpi_release(phi);
        return r;
}
Пример #4
0
/**
 * Obtain a random point on the curve and its
 * additive inverse. Both returned values
 * must be freed using #GNUNET_CRYPTO_ecc_free().
 *
 * @param edc calculation context for ECC operations
 * @param[out] r set to a random point on the curve
 * @param[out] r_inv set to the additive inverse of @a r
 */
void
GNUNET_CRYPTO_ecc_rnd (struct GNUNET_CRYPTO_EccDlogContext *edc,
		       gcry_mpi_point_t *r,
		       gcry_mpi_point_t *r_inv)
{
  gcry_mpi_t fact;
  gcry_mpi_t n;
  gcry_mpi_point_t g;

  fact = GNUNET_CRYPTO_ecc_random_mod_n (edc);

  /* calculate 'r' */
  g = gcry_mpi_ec_get_point ("g", edc->ctx, 0);
  GNUNET_assert (NULL != g);
  *r = gcry_mpi_point_new (0);
  gcry_mpi_ec_mul (*r, fact, g, edc->ctx);

  /* calculate 'r_inv' */
  n = gcry_mpi_ec_get_mpi ("n", edc->ctx, 1);
  gcry_mpi_sub (fact, n, fact); /* fact = n - fact = - fact */
  *r_inv = gcry_mpi_point_new (0);
  gcry_mpi_ec_mul (*r_inv, fact, g, edc->ctx);

  gcry_mpi_release (n);
  gcry_mpi_release (fact);
  gcry_mpi_point_release (g);
}
Пример #5
0
/**
 * Do pre-calculation for ECC discrete logarithm for small factors.
 *
 * @param max maximum value the factor can be
 * @param mem memory to use (should be smaller than @a max), must not be zero.
 * @return @a max if dlog failed, otherwise the factor
 */
struct GNUNET_CRYPTO_EccDlogContext *
GNUNET_CRYPTO_ecc_dlog_prepare (unsigned int max,
				unsigned int mem)
{
  struct GNUNET_CRYPTO_EccDlogContext *edc;
  unsigned int K = ((max + (mem-1)) / mem);
  gcry_mpi_point_t g;
  struct GNUNET_PeerIdentity key;
  gcry_mpi_point_t gKi;
  gcry_mpi_t fact;
  gcry_mpi_t n;
  unsigned int i;

  GNUNET_assert (max < INT32_MAX);
  edc = GNUNET_new (struct GNUNET_CRYPTO_EccDlogContext);
  edc->max = max;
  edc->mem = mem;

  edc->map = GNUNET_CONTAINER_multipeermap_create (mem * 2,
						   GNUNET_NO);

  GNUNET_assert (0 == gcry_mpi_ec_new (&edc->ctx,
				       NULL,
				       CURVE));
  g = gcry_mpi_ec_get_point ("g", edc->ctx, 0);
  GNUNET_assert (NULL != g);
  fact = gcry_mpi_new (0);
  gKi = gcry_mpi_point_new (0);
  for (i=0;i<=mem;i++)
  {
    gcry_mpi_set_ui (fact, i * K);
    gcry_mpi_ec_mul (gKi, fact, g, edc->ctx);
    extract_pk (gKi, edc->ctx, &key);
    GNUNET_assert (GNUNET_OK ==
		   GNUNET_CONTAINER_multipeermap_put (edc->map,
						      &key,
						      (void*) (long) i + max,
						      GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
  }
  /* negative values */
  n = gcry_mpi_ec_get_mpi ("n", edc->ctx, 1);
  for (i=1;i<mem;i++)
  {
    gcry_mpi_set_ui (fact, i * K);
    gcry_mpi_sub (fact, n, fact);
    gcry_mpi_ec_mul (gKi, fact, g, edc->ctx);
    extract_pk (gKi, edc->ctx, &key);
    GNUNET_assert (GNUNET_OK ==
		   GNUNET_CONTAINER_multipeermap_put (edc->map,
						      &key,
						      (void*) (long) max - i,
						      GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
  }
  gcry_mpi_release (fact);
  gcry_mpi_release (n);
  gcry_mpi_point_release (gKi);
  gcry_mpi_point_release (g);
  return edc;
}
Пример #6
0
/**
 * Do some DLOG operations for testing.
 *
 * @param edc context for ECC operations
 * @param do_dlog #GNUNET_YES if we want to actually do the bencharked operation
 */
static void
test_dlog (struct GNUNET_CRYPTO_EccDlogContext *edc, 
           int do_dlog)
{
  gcry_mpi_t fact;
  gcry_mpi_t n;
  gcry_ctx_t ctx;
  gcry_mpi_point_t q;
  gcry_mpi_point_t g;
  unsigned int i;
  int x;
  int iret;

  GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, NULL, CURVE));
  g = gcry_mpi_ec_get_point ("g", ctx, 0);
  GNUNET_assert (NULL != g);
  n = gcry_mpi_ec_get_mpi ("n", ctx, 0);
  q = gcry_mpi_point_new (0);
  fact = gcry_mpi_new (0);
  for (i=0;i<TEST_ITER;i++)
  {
    fprintf (stderr, ".");
    x = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
				  MAX_FACT);
    if (0 == GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
				       2))
    {
      gcry_mpi_set_ui (fact, x);
      gcry_mpi_sub (fact, n, fact);
      x = - x;
    }
    else 
    {
      gcry_mpi_set_ui (fact, x);
    }
    gcry_mpi_ec_mul (q, fact, g, ctx);
    if ( (GNUNET_YES == do_dlog) &&
	 (x !=
	  (iret = GNUNET_CRYPTO_ecc_dlog (edc,
					  q))) )
    {
      fprintf (stderr, 
	       "DLOG failed for value %d (%d)\n", 
	       x,
	       iret);
      GNUNET_assert (0);
    }
  }
  gcry_mpi_release (fact);
  gcry_mpi_release (n);
  gcry_mpi_point_release (g);
  gcry_mpi_point_release (q);
  gcry_ctx_release (ctx);
  fprintf (stderr, "\n");
}
Пример #7
0
unsigned char* sub(unsigned char* x, unsigned char* y){
	size_t scanned;
	unsigned char *result;
	gcry_mpi_t a = gcry_mpi_new(0);
	gcry_mpi_t b = gcry_mpi_new(0);
	gcry_mpi_scan(&a, GCRYMPI_FMT_HEX, x, 0, &scanned);
	gcry_mpi_scan(&b, GCRYMPI_FMT_HEX, y, 0, &scanned);
	gcry_mpi_sub(a, a, b);
	gcry_mpi_aprint(GCRYMPI_FMT_HEX, &result, NULL, a);
	return result;
}
Пример #8
0
int mixin_key_and_curve(struct affine_point *P, gcry_mpi_t pubkey, 
	const struct curve_params *cp)
{
	int yflag, res;

	if ((yflag = (gcry_mpi_cmp(pubkey, cp->dp.m) >= 0)))
		gcry_mpi_sub(pubkey, pubkey, cp->dp.m);
	res = gcry_mpi_cmp_ui(pubkey, 0) >= 0 && gcry_mpi_cmp(pubkey, cp->dp.m) < 0 &&
			point_decompress(P, pubkey, yflag, &cp->dp);
	return res;
}
Пример #9
0
/**
 * Obtain a random scalar for point multiplication on the curve and
 * its multiplicative inverse.
 *
 * @param edc calculation context for ECC operations
 * @param[out] r set to a random scalar on the curve
 * @param[out] r_inv set to the multiplicative inverse of @a r
 */
void
GNUNET_CRYPTO_ecc_rnd_mpi (struct GNUNET_CRYPTO_EccDlogContext *edc,
                           gcry_mpi_t *r,
                           gcry_mpi_t *r_inv)
{
  gcry_mpi_t n;

  *r = GNUNET_CRYPTO_ecc_random_mod_n (edc);
  /* r_inv = n - r = - r */
  *r_inv = gcry_mpi_new (0);
  n = gcry_mpi_ec_get_mpi ("n", edc->ctx, 1);
  gcry_mpi_sub (*r_inv, n, *r);
}
Пример #10
0
static bigint_t
wrap_gcry_mpi_sub (bigint_t w, const bigint_t a, const bigint_t b)
{
  if (w == NULL)
    w = _gnutls_mpi_alloc_like (b);

  if (w == NULL)
    return NULL;

  gcry_mpi_sub (w, a, b);

  return w;
}
Пример #11
0
static int 
test_sub (void)
{
  gcry_mpi_t one;
  gcry_mpi_t two;
  gcry_mpi_t result;
  unsigned char* pc;
  
  gcry_mpi_scan(&one, GCRYMPI_FMT_USG, ones, sizeof(ones), NULL);
  gcry_mpi_scan(&two, GCRYMPI_FMT_USG, twos, sizeof(twos), NULL);
  result = gcry_mpi_new(0);
  gcry_mpi_sub(result, two, one);
  
  gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result);
  if (verbose)
    printf("Result of two minus one:\n%s\n", pc);
  gcry_free(pc);
  
  gcry_mpi_release(one);
  gcry_mpi_release(two);
  gcry_mpi_release(result);
  return 1;
}
Пример #12
0
void
gcry_mpi_subm( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m)
{
    gcry_mpi_sub(w, u, v);
    _gcry_mpi_fdiv_r( w, w, m );
}