Exemple #1
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;
}
Exemple #2
0
void jacobian_load_affine(struct jacobian_point *p1,
			  const struct affine_point *p2)
{
  if (! point_is_zero(p2)) {
    gcry_mpi_set(p1->x, p2->x);
    gcry_mpi_set(p1->y, p2->y);
    gcry_mpi_set_ui(p1->z, 1);
  }
  else
    gcry_mpi_set_ui(p1->z, 0);
}
Exemple #3
0
void point_double(struct affine_point *p, const struct domain_params *dp)
{
  if (gcry_mpi_cmp_ui(p->y, 0)) {
    gcry_mpi_t t1, t2;
    t1 = gcry_mpi_snew(0);
    t2 = gcry_mpi_snew(0);
    gcry_mpi_mulm(t2, p->x, p->x, dp->m);
    gcry_mpi_addm(t1, t2, t2, dp->m);
    gcry_mpi_addm(t1, t1, t2, dp->m);
    gcry_mpi_addm(t1, t1, dp->a, dp->m);
    gcry_mpi_addm(t2, p->y, p->y, dp->m);
    gcry_mpi_invm(t2, t2, dp->m);
    gcry_mpi_mulm(t1, t1, t2, dp->m);
    gcry_mpi_mulm(t2, t1, t1, dp->m);
    gcry_mpi_subm(t2, t2, p->x, dp->m);
    gcry_mpi_subm(t2, t2, p->x, dp->m);
    gcry_mpi_subm(p->x, p->x, t2, dp->m);
    gcry_mpi_mulm(t1, t1, p->x, dp->m);
    gcry_mpi_subm(p->y, t1, p->y, dp->m);
    gcry_mpi_set(p->x, t2);
    gcry_mpi_release(t1);
    gcry_mpi_release(t2);
  }
  else
    gcry_mpi_set_ui(p->x, 0);
}
Exemple #4
0
nuts_mpi_t nuts_mpi_copy(const nuts_mpi_t mpi) {
  if (mpi != NULL) {
    gcry_check();

    gcry_mpi_t mpi2 = gcry_mpi_set(NULL, mpi->mpi);
    return nuts_mpi_alloc(mpi2);
  } else {
    return NULL;
  }
}
Exemple #5
0
/**
 * Return true if n is probably a prime
 */
static int
is_prime (gcry_mpi_t n, int steps, struct GNUNET_HashCode * hc)
{
  gcry_mpi_t x;
  gcry_mpi_t y;
  gcry_mpi_t z;
  gcry_mpi_t nminus1;
  gcry_mpi_t a2;
  gcry_mpi_t q;
  unsigned int i, j, k;
  int rc = 0;
  unsigned int nbits;

  x = gcry_mpi_new (0);
  y = gcry_mpi_new (0);
  z = gcry_mpi_new (0);
  nminus1 = gcry_mpi_new (0);
  a2 = gcry_mpi_set_ui (NULL, 2);

  nbits = gcry_mpi_get_nbits (n);
  gcry_mpi_sub_ui (nminus1, n, 1);

  /* Find q and k, so that n = 1 + 2^k * q . */
  q = gcry_mpi_set (NULL, nminus1);
  k = mpz_trailing_zeroes (q);
  mpz_tdiv_q_2exp (q, q, k);

  for (i = 0; i < steps; i++)
  {
    if (!i)
    {
      gcry_mpi_set_ui (x, 2);
    }
    else
    {
      mpz_randomize (x, nbits - 1, hc);
      GNUNET_assert (gcry_mpi_cmp (x, nminus1) < 0);
      GNUNET_assert (gcry_mpi_cmp_ui (x, 1) > 0);
    }
    gcry_mpi_powm (y, x, q, n);
    if (gcry_mpi_cmp_ui (y, 1) && gcry_mpi_cmp (y, nminus1))
    {
      for (j = 1; j < k && gcry_mpi_cmp (y, nminus1); j++)
      {
        gcry_mpi_powm (y, y, a2, n);
        if (!gcry_mpi_cmp_ui (y, 1))
          goto leave;           /* Not a prime. */
      }
      if (gcry_mpi_cmp (y, nminus1))
        goto leave;             /* Not a prime. */
    }
  }
  rc = 1;                       /* May be a prime. */

leave:
  gcry_mpi_release (x);
  gcry_mpi_release (y);
  gcry_mpi_release (z);
  gcry_mpi_release (nminus1);
  gcry_mpi_release (q);
  gcry_mpi_release (a2);

  return rc;
}
Exemple #6
0
static int
test_const_and_immutable (void)
{
  gcry_mpi_t one, second_one;

  one = gcry_mpi_set_ui (NULL, 1);
  if (gcry_mpi_get_flag (one, GCRYMPI_FLAG_IMMUTABLE)
      || gcry_mpi_get_flag (one, GCRYMPI_FLAG_CONST))
    die ("immutable or const flag initially set\n");

  second_one = gcry_mpi_copy (one);
  if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_IMMUTABLE))
    die ("immutable flag set after copy\n");
  if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_CONST))
    die ("const flag set after copy\n");
  gcry_mpi_release (second_one);

  gcry_mpi_set_flag (one, GCRYMPI_FLAG_IMMUTABLE);
  if (!gcry_mpi_get_flag (one, GCRYMPI_FLAG_IMMUTABLE))
    die ("failed to set immutable flag\n");
  if (gcry_mpi_get_flag (one, GCRYMPI_FLAG_CONST))
    die ("const flag unexpectly set\n");

  second_one = gcry_mpi_copy (one);
  if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_IMMUTABLE))
    die ("immutable flag not cleared after copy\n");
  if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_CONST))
    die ("const flag unexpectly set after copy\n");
  gcry_mpi_release (second_one);

  gcry_mpi_clear_flag (one, GCRYMPI_FLAG_IMMUTABLE);
  if (gcry_mpi_get_flag (one, GCRYMPI_FLAG_IMMUTABLE))
    die ("failed to clear immutable flag\n");
  if (gcry_mpi_get_flag (one, GCRYMPI_FLAG_CONST))
    die ("const flag unexpectly set\n");

  gcry_mpi_set_flag (one, GCRYMPI_FLAG_CONST);
  if (!gcry_mpi_get_flag (one, GCRYMPI_FLAG_CONST))
    die ("failed to set const flag\n");
  if (!gcry_mpi_get_flag (one, GCRYMPI_FLAG_IMMUTABLE))
    die ("failed to set immutable flag with const flag\n");

  second_one = gcry_mpi_copy (one);
  if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_IMMUTABLE))
    die ("immutable flag not cleared after copy\n");
  if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_CONST))
    die ("const flag not cleared after copy\n");
  gcry_mpi_release (second_one);

  gcry_mpi_clear_flag (one, GCRYMPI_FLAG_IMMUTABLE);
  if (!gcry_mpi_get_flag (one, GCRYMPI_FLAG_IMMUTABLE))
    die ("clearing immutable flag not ignored for a constant MPI\n");
  if (!gcry_mpi_get_flag (one, GCRYMPI_FLAG_CONST))
    die ("const flag unexpectly cleared\n");


  second_one = gcry_mpi_set (NULL, GCRYMPI_CONST_ONE);
  if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_IMMUTABLE))
    die ("immutable flag not cleared by mpi_set (NULL,x)\n");
  if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_CONST))
    die ("const flag not cleared by mpi_set (NULL,x)\n");
  gcry_mpi_release (second_one);

  second_one = gcry_mpi_set_ui (NULL, 42);
  gcry_mpi_set (second_one, GCRYMPI_CONST_ONE);
  if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_IMMUTABLE))
    die ("immutable flag not cleared after mpi_set (a,x)\n");
  if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_CONST))
    die ("const flag not cleared mpi_set (a,x)\n");
  gcry_mpi_release (second_one);


  /* Due to the the constant flag the release below should be a NOP
     and will leak memory.  */
  gcry_mpi_release (one);
  return 1;
}
Exemple #7
0
void point_set(struct affine_point *p1, const struct affine_point *p2)
{
  gcry_mpi_set(p1->x, p2->x);
  gcry_mpi_set(p1->y, p2->y);
}
Exemple #8
0
/* Check that the RSA secret key SKEY is valid.  Swap parameters to
   the libgcrypt standard.  */
static gpg_error_t
rsa_key_check (struct rsa_secret_key_s *skey)
{
  int err = 0;
  gcry_mpi_t t = gcry_mpi_snew (0);
  gcry_mpi_t t1 = gcry_mpi_snew (0);
  gcry_mpi_t t2 = gcry_mpi_snew (0);
  gcry_mpi_t phi = gcry_mpi_snew (0);

  /* Check that n == p * q.  */
  gcry_mpi_mul (t, skey->p, skey->q);
  if (gcry_mpi_cmp( t, skey->n) )
    {
      log_error ("RSA oops: n != p * q\n");
      err++;
    }

  /* Check that p is less than q.  */
  if (gcry_mpi_cmp (skey->p, skey->q) > 0)
    {
      gcry_mpi_t tmp;

      log_info ("swapping secret primes\n");
      tmp = gcry_mpi_copy (skey->p);
      gcry_mpi_set (skey->p, skey->q);
      gcry_mpi_set (skey->q, tmp);
      gcry_mpi_release (tmp);
      /* Recompute u.  */
      gcry_mpi_invm (skey->u, skey->p, skey->q);
    }

  /* Check that e divides neither p-1 nor q-1.  */
  gcry_mpi_sub_ui (t, skey->p, 1 );
  gcry_mpi_div (NULL, t, t, skey->e, 0);
  if (!gcry_mpi_cmp_ui( t, 0) )
    {
      log_error ("RSA oops: e divides p-1\n");
      err++;
    }
  gcry_mpi_sub_ui (t, skey->q, 1);
  gcry_mpi_div (NULL, t, t, skey->e, 0);
  if (!gcry_mpi_cmp_ui( t, 0))
    {
      log_info ("RSA oops: e divides q-1\n" );
      err++;
    }

  /* Check that d is correct.  */
  gcry_mpi_sub_ui (t1, skey->p, 1);
  gcry_mpi_sub_ui (t2, skey->q, 1);
  gcry_mpi_mul (phi, t1, t2);
  gcry_mpi_invm (t, skey->e, phi);
  if (gcry_mpi_cmp (t, skey->d))
    {
      /* No: try universal exponent. */
      gcry_mpi_gcd (t, t1, t2);
      gcry_mpi_div (t, NULL, phi, t, 0);
      gcry_mpi_invm (t, skey->e, t);
      if (gcry_mpi_cmp (t, skey->d))
        {
          log_error ("RSA oops: bad secret exponent\n");
          err++;
        }
    }

  /* Check for correctness of u.  */
  gcry_mpi_invm (t, skey->p, skey->q);
  if (gcry_mpi_cmp (t, skey->u))
    {
      log_info ("RSA oops: bad u parameter\n");
      err++;
    }

  if (err)
    log_info ("RSA secret key check failed\n");

  gcry_mpi_release (t);
  gcry_mpi_release (t1);
  gcry_mpi_release (t2);
  gcry_mpi_release (phi);

  return err? gpg_error (GPG_ERR_BAD_SECKEY):0;
}
Exemple #9
0
static bigint_t
wrap_gcry_mpi_set (bigint_t w, const bigint_t u)
{
  return gcry_mpi_set (w, u);
}
Exemple #10
0
/*
 * Test iterative X25519 computation through lower layer MPI routines.
 *
 * Input: K (as hex string), ITER, R (as hex string)
 *
 * where R is expected result of iterating X25519 by ITER times.
 *
 */
static void
test_it (int testno, const char *k_str, int iter, const char *result_str)
{
  gcry_ctx_t ctx;
  gpg_error_t err;
  void *buffer = NULL;
  size_t buflen;
  gcry_mpi_t mpi_k = NULL;
  gcry_mpi_t mpi_x = NULL;
  gcry_mpi_point_t P = NULL;
  gcry_mpi_point_t Q;
  int i;
  gcry_mpi_t mpi_kk = NULL;

  if (verbose > 1)
    info ("Running test %d: iteration=%d\n", testno, iter);

  gcry_mpi_ec_new (&ctx, NULL, "Curve25519");
  Q = gcry_mpi_point_new (0);

  if (!(buffer = hex2buffer (k_str, &buflen)) || buflen != 32)
    {
      fail ("error scanning MPI for test %d, %s: %s",
            testno, "k", "invalid hex string");
      goto leave;
    }
  reverse_buffer (buffer, buflen);
  if ((err = gcry_mpi_scan (&mpi_x, GCRYMPI_FMT_USG, buffer, buflen, NULL)))
    {
      fail ("error scanning MPI for test %d, %s: %s",
            testno, "x", gpg_strerror (err));
      goto leave;
    }

  xfree (buffer);
  buffer = NULL;

  P = gcry_mpi_point_set (NULL, mpi_x, NULL, GCRYMPI_CONST_ONE);

  mpi_k = gcry_mpi_copy (mpi_x);
  if (debug)
    print_mpi ("k", mpi_k);

  for (i = 0; i < iter; i++)
    {
      /*
       * Another variant of decodeScalar25519 thing.
       */
      mpi_kk = gcry_mpi_set (mpi_kk, mpi_k);
      gcry_mpi_set_bit (mpi_kk, 254);
      gcry_mpi_clear_bit (mpi_kk, 255);
      gcry_mpi_clear_bit (mpi_kk, 0);
      gcry_mpi_clear_bit (mpi_kk, 1);
      gcry_mpi_clear_bit (mpi_kk, 2);

      gcry_mpi_ec_mul (Q, mpi_kk, P, ctx);

      P = gcry_mpi_point_set (P, mpi_k, NULL, GCRYMPI_CONST_ONE);
      gcry_mpi_ec_get_affine (mpi_k, NULL, Q, ctx);

      if (debug)
        print_mpi ("k", mpi_k);
    }

  {
    unsigned char res[32];
    char *r, *r0;

    gcry_mpi_print (GCRYMPI_FMT_USG, res, 32, NULL, mpi_k);
    reverse_buffer (res, 32);

    r0 = r = xmalloc (65);
    if (!r0)
      {
        fail ("memory allocation for test %d", testno);
        goto leave;
      }

    for (i=0; i < 32; i++, r += 2)
      snprintf (r, 3, "%02x", res[i]);

    if (strcmp (result_str, r0))
      {
        fail ("curv25519 failed for test %d: %s",
              testno, "wrong value returned");
        info ("  expected: '%s'", result_str);
        info ("       got: '%s'", r0);
      }
    xfree (r0);
  }

 leave:
  gcry_mpi_release (mpi_kk);
  gcry_mpi_release (mpi_k);
  gcry_mpi_point_release (P);
  gcry_mpi_release (mpi_x);
  xfree (buffer);
  gcry_mpi_point_release (Q);
  gcry_ctx_release (ctx);
}