示例#1
0
文件: protocol.c 项目: asciimoo/PyECC
int ECDSA_verify(const char *msg, const struct affine_point *Q,
		 const gcry_mpi_t sig, const struct curve_params *cp)
{
  gcry_mpi_t e, r, s;
  struct affine_point X1, X2;
  int res = 0;
  r = gcry_mpi_new(0);
  s = gcry_mpi_new(0);
  gcry_mpi_div(s, r, sig, cp->dp.order, 0);
  if (gcry_mpi_cmp_ui(s, 0) <= 0 || gcry_mpi_cmp(s, cp->dp.order) >= 0 ||
      gcry_mpi_cmp_ui(r, 0) <= 0 || gcry_mpi_cmp(r, cp->dp.order) >= 0) 
    goto end;
  gcry_mpi_scan(&e, GCRYMPI_FMT_USG, msg, 64, NULL);
  gcry_mpi_mod(e, e, cp->dp.order);
  gcry_mpi_invm(s, s, cp->dp.order);
  gcry_mpi_mulm(e, e, s, cp->dp.order);
  X1 = pointmul(&cp->dp.base, e, &cp->dp);
  gcry_mpi_mulm(e, r, s, cp->dp.order);
  X2 = pointmul(Q, e, &cp->dp);
  point_add(&X1, &X2, &cp->dp);
  gcry_mpi_release(e);
  if (! point_is_zero(&X1)) {
    gcry_mpi_mod(s, X1.x, cp->dp.order);
    res = ! gcry_mpi_cmp(s, r);
  }
  point_release(&X1);
  point_release(&X2);
 end:
  gcry_mpi_release(r);
  gcry_mpi_release(s);
  return res;
}
示例#2
0
文件: protocol.c 项目: asciimoo/PyECC
/* Algorithms 4.29 and 4.30 in the "Guide to Elliptic Curve Cryptography"     */
gcry_mpi_t ECDSA_sign(const char *msg, const gcry_mpi_t d,
		      const struct curve_params *cp)
{
  struct affine_point p1;
  gcry_mpi_t e, k, r, s;

#if ECDSA_DETERMINISTIC
  struct aes256cprng *cprng;
  cprng = ecdsa_cprng_init(msg, d, cp);
#endif
  r = gcry_mpi_snew(0);
  s = gcry_mpi_snew(0);
 Step1:
#if ECDSA_DETERMINISTIC
  k = ecdsa_cprng_get_exponent(cprng, cp);
#else
  k = get_random_exponent(cp);
#endif
  p1 = pointmul(&cp->dp.base, k, &cp->dp);
  gcry_mpi_mod(r, p1.x, cp->dp.order);
  point_release(&p1);
  if (! gcry_mpi_cmp_ui(r, 0)) {
    gcry_mpi_release(k);
    goto Step1;
  }
  gcry_mpi_scan(&e, GCRYMPI_FMT_USG, msg, 64, NULL);
  gcry_mpi_set_flag(e, GCRYMPI_FLAG_SECURE);
  gcry_mpi_mod(e, e, cp->dp.order);
  gcry_mpi_mulm(s, d, r, cp->dp.order);
  gcry_mpi_addm(s, s, e, cp->dp.order);
  gcry_mpi_invm(e, k, cp->dp.order);
  gcry_mpi_mulm(s, s, e, cp->dp.order);
  gcry_mpi_release(e);
  gcry_mpi_release(k);
  if (! gcry_mpi_cmp_ui(s, 0))
    goto Step1;
  gcry_mpi_mul(s, s, cp->dp.order);
  gcry_mpi_add(s, s, r);
  gcry_mpi_release(r);
#if ECDSA_DETERMINISTIC
  ecdsa_cprng_done(cprng);
#endif
  return s;
}
示例#3
0
static bigint_t
wrap_gcry_mpi_mod (const bigint_t a, const bigint_t b)
{
  bigint_t r = _gnutls_mpi_alloc_like (b);

  if (r == NULL)
    return NULL;

  gcry_mpi_mod (r, a, b);

  return r;
}
示例#4
0
文件: protocol.c 项目: asciimoo/PyECC
gcry_mpi_t buf_to_exponent(const char *buf, int buflen,
			   const struct curve_params *cp)
{
  gcry_mpi_t a, b;
  gcry_mpi_scan(&a, GCRYMPI_FMT_USG, buf, buflen, NULL);
  gcry_mpi_set_flag(a, GCRYMPI_FLAG_SECURE);
  b = gcry_mpi_new(0);
  gcry_mpi_sub_ui(b, cp->dp.order, 1);
  gcry_mpi_mod(a, a, b);
  gcry_mpi_add_ui(a, a, 1);
  gcry_mpi_release(b);
  return a;
}
示例#5
0
/** @brief generates a random integer between 0 and max
 * @returns 1 in case of success, 0 otherwise
 */
int ssh_gcry_rand_range(bignum dest, bignum max)
{
    size_t bits;
    bignum rnd;
    int rc;

    bits = bignum_num_bits(max) + 64;
    rnd = bignum_new();
    if (rnd == NULL) {
        return 0;
    }
    rc = bignum_rand(rnd, bits);
    if (rc != 1) {
        return rc;
    }
    gcry_mpi_mod(dest, rnd, max);
    bignum_safe_free(rnd);
    return 1;
}
示例#6
0
/* Compute and print missing RSA parameters.  */
static void
compute_missing (gcry_mpi_t rsa_p, gcry_mpi_t rsa_q, gcry_mpi_t rsa_e)
{
  gcry_mpi_t rsa_n, rsa_d, rsa_pm1, rsa_qm1, rsa_u;
  gcry_mpi_t phi, tmp_g, tmp_f;

  rsa_n = gcry_mpi_new (0);
  rsa_d = gcry_mpi_new (0);
  rsa_pm1 = gcry_mpi_new (0);
  rsa_qm1 = gcry_mpi_new (0);
  rsa_u = gcry_mpi_new (0);

  phi = gcry_mpi_new (0);
  tmp_f = gcry_mpi_new (0);
  tmp_g = gcry_mpi_new (0);

  /* Check that p < q; if not swap p and q.  */
  if (openpgp_mode && gcry_mpi_cmp (rsa_p, rsa_q) > 0)
    {
      fprintf (stderr, PGM ": swapping p and q\n");
      gcry_mpi_swap (rsa_p, rsa_q);
    }

  gcry_mpi_mul (rsa_n, rsa_p, rsa_q);


  /* Compute the Euler totient:  phi = (p-1)(q-1)  */
  gcry_mpi_sub_ui (rsa_pm1, rsa_p, 1);
  gcry_mpi_sub_ui (rsa_qm1, rsa_q, 1);
  gcry_mpi_mul (phi, rsa_pm1, rsa_qm1);

  if (!gcry_mpi_gcd (tmp_g, rsa_e, phi))
    die ("parameter 'e' does match 'p' and 'q'\n");

  /* Compute: f = lcm(p-1,q-1) = phi / gcd(p-1,q-1) */
  gcry_mpi_gcd (tmp_g, rsa_pm1, rsa_qm1);
  gcry_mpi_div (tmp_f, NULL, phi, tmp_g, -1);

  /* Compute the secret key:  d = e^{-1} mod lcm(p-1,q-1) */
  gcry_mpi_invm (rsa_d, rsa_e, tmp_f);

  /* Compute the CRT helpers: d mod (p-1), d mod (q-1)   */
  gcry_mpi_mod (rsa_pm1, rsa_d, rsa_pm1);
  gcry_mpi_mod (rsa_qm1, rsa_d, rsa_qm1);

  /* Compute the CRT value:   OpenPGP:    u = p^{-1} mod q
                             Standard: iqmp = q^{-1} mod p */
  if (openpgp_mode)
    gcry_mpi_invm (rsa_u, rsa_p, rsa_q);
  else
    gcry_mpi_invm (rsa_u, rsa_q, rsa_p);

  gcry_mpi_release (phi);
  gcry_mpi_release (tmp_f);
  gcry_mpi_release (tmp_g);

  /* Print everything.  */
  print_mpi_line ("n", rsa_n);
  print_mpi_line ("e", rsa_e);
  if (openpgp_mode)
    print_mpi_line ("d", rsa_d);
  print_mpi_line ("p", rsa_p);
  print_mpi_line ("q", rsa_q);
  if (openpgp_mode)
    print_mpi_line ("u", rsa_u);
  else
    {
      print_mpi_line ("dmp1", rsa_pm1);
      print_mpi_line ("dmq1", rsa_qm1);
      print_mpi_line ("iqmp", rsa_u);
    }

  gcry_mpi_release (rsa_n);
  gcry_mpi_release (rsa_d);
  gcry_mpi_release (rsa_pm1);
  gcry_mpi_release (rsa_qm1);
  gcry_mpi_release (rsa_u);
}
示例#7
0
/* Check the math used with Twisted Edwards curves.  */
static void
twistededwards_math (void)
{
  gpg_error_t err;
  gcry_ctx_t ctx;
  gcry_mpi_point_t G, Q;
  gcry_mpi_t k;
  gcry_mpi_t w, a, x, y, z, p, n, b, I;

  wherestr = "twistededwards_math";
  show ("checking basic Twisted Edwards math\n");

  err = gcry_mpi_ec_new (&ctx, NULL, "Ed25519");
  if (err)
    die ("gcry_mpi_ec_new failed: %s\n", gpg_strerror (err));

  k = hex2mpi
    ("2D3501E723239632802454EE5DDC406EFB0BDF18486A5BDE9C0390A9C2984004"
     "F47252B628C953625B8DEB5DBCB8DA97AA43A1892D11FA83596F42E0D89CB1B6");
  G = gcry_mpi_ec_get_point ("g", ctx, 1);
  if (!G)
    die ("gcry_mpi_ec_get_point(G) failed\n");
  Q = gcry_mpi_point_new (0);


  w = gcry_mpi_new (0);
  a = gcry_mpi_new (0);
  x = gcry_mpi_new (0);
  y = gcry_mpi_new (0);
  z = gcry_mpi_new (0);
  I = gcry_mpi_new (0);
  p = gcry_mpi_ec_get_mpi ("p", ctx, 1);
  n = gcry_mpi_ec_get_mpi ("n", ctx, 1);
  b = gcry_mpi_ec_get_mpi ("b", ctx, 1);

  /* Check: 2^{p-1} mod p == 1 */
  gcry_mpi_sub_ui (a, p, 1);
  gcry_mpi_powm (w, GCRYMPI_CONST_TWO, a, p);
  if (gcry_mpi_cmp_ui (w, 1))
    fail ("failed assertion: 2^{p-1} mod p == 1\n");

  /* Check: p % 4 == 1 */
  gcry_mpi_mod (w, p, GCRYMPI_CONST_FOUR);
  if (gcry_mpi_cmp_ui (w, 1))
    fail ("failed assertion: p % 4 == 1\n");

  /* Check: 2^{n-1} mod n == 1 */
  gcry_mpi_sub_ui (a, n, 1);
  gcry_mpi_powm (w, GCRYMPI_CONST_TWO, a, n);
  if (gcry_mpi_cmp_ui (w, 1))
    fail ("failed assertion: 2^{n-1} mod n == 1\n");

  /* Check: b^{(p-1)/2} mod p == p-1 */
  gcry_mpi_sub_ui (a, p, 1);
  gcry_mpi_div (x, NULL, a, GCRYMPI_CONST_TWO, -1);
  gcry_mpi_powm (w, b, x, p);
  gcry_mpi_abs (w);
  if (gcry_mpi_cmp (w, a))
    fail ("failed assertion: b^{(p-1)/2} mod p == p-1\n");

  /* I := 2^{(p-1)/4} mod p */
  gcry_mpi_sub_ui (a, p, 1);
  gcry_mpi_div (x, NULL, a, GCRYMPI_CONST_FOUR, -1);
  gcry_mpi_powm (I, GCRYMPI_CONST_TWO, x, p);

  /* Check: I^2 mod p == p-1 */
  gcry_mpi_powm (w, I, GCRYMPI_CONST_TWO, p);
  if (gcry_mpi_cmp (w, a))
    fail ("failed assertion: I^2 mod p == p-1\n");

  /* Check: G is on the curve */
  if (!gcry_mpi_ec_curve_point (G, ctx))
    fail ("failed assertion: G is on the curve\n");

  /* Check: nG == (0,1) */
  gcry_mpi_ec_mul (Q, n, G, ctx);
  if (gcry_mpi_ec_get_affine (x, y, Q, ctx))
    fail ("failed to get affine coordinates\n");
  if (gcry_mpi_cmp_ui (x, 0) || gcry_mpi_cmp_ui (y, 1))
    fail ("failed assertion: nG == (0,1)\n");

  /* Now two arbitrary point operations taken from the ed25519.py
     sample data.  */
  gcry_mpi_release (a);
  a = hex2mpi
    ("4f71d012df3c371af3ea4dc38385ca5bb7272f90cb1b008b3ed601c76de1d496"
     "e30cbf625f0a756a678d8f256d5325595cccc83466f36db18f0178eb9925edd3");
  gcry_mpi_ec_mul (Q, a, G, ctx);
  if (gcry_mpi_ec_get_affine (x, y, Q, ctx))
    fail ("failed to get affine coordinates\n");
  if (cmp_mpihex (x, ("157f7361c577aad36f67ed33e38dc7be"
                      "00014fecc2165ca5cee9eee19fe4d2c1"))
      || cmp_mpihex (y, ("5a69dbeb232276b38f3f5016547bb2a2"
                         "4025645f0b820e72b8cad4f0a909a092")))
    {
      fail ("sample point multiply failed:\n");
      print_mpi ("r", a);
      print_mpi ("Rx", x);
      print_mpi ("Ry", y);
    }

  gcry_mpi_release (a);
  a = hex2mpi
    ("2d3501e723239632802454ee5ddc406efb0bdf18486a5bde9c0390a9c2984004"
     "f47252b628c953625b8deb5dbcb8da97aa43a1892d11fa83596f42e0d89cb1b6");
  gcry_mpi_ec_mul (Q, a, G, ctx);
  if (gcry_mpi_ec_get_affine (x, y, Q, ctx))
    fail ("failed to get affine coordinates\n");
  if (cmp_mpihex (x, ("6218e309d40065fcc338b3127f468371"
                      "82324bd01ce6f3cf81ab44e62959c82a"))
      || cmp_mpihex (y, ("5501492265e073d874d9e5b81e7f8784"
                         "8a826e80cce2869072ac60c3004356e5")))
    {
      fail ("sample point multiply failed:\n");
      print_mpi ("r", a);
      print_mpi ("Rx", x);
      print_mpi ("Ry", y);
    }


  gcry_mpi_release (I);
  gcry_mpi_release (b);
  gcry_mpi_release (n);
  gcry_mpi_release (p);
  gcry_mpi_release (w);
  gcry_mpi_release (a);
  gcry_mpi_release (x);
  gcry_mpi_release (y);
  gcry_mpi_release (z);
  gcry_mpi_point_release (Q);
  gcry_mpi_point_release (G);
  gcry_mpi_release (k);
  gcry_ctx_release (ctx);
}
示例#8
0
文件: fsprg.c 项目: poettering/fsprg
/* Decompose $x \in Z_n$ into $(xp,xq) \in Z_p \times Z_q$ using Chinese Remainder Theorem */
static void CRT_decompose(gcry_mpi_t *xp, gcry_mpi_t *xq, const gcry_mpi_t x, const gcry_mpi_t p, const gcry_mpi_t q) {
        *xp = gcry_mpi_new(0);
        *xq = gcry_mpi_new(0);
        gcry_mpi_mod(*xp, x, p);
        gcry_mpi_mod(*xq, x, q);
}
示例#9
0
guchar*
gkm_data_der_write_private_key_rsa (gcry_sexp_t s_key, gsize *n_key)
{
	GNode *asn = NULL;
	gcry_mpi_t n, e, d, p, q, u, e1, e2, tmp;
	guchar *result = NULL;

	n = e = d = p = q = u = e1 = e2 = tmp = NULL;

	asn = egg_asn1x_create (pk_asn1_tab, "RSAPrivateKey");
	g_return_val_if_fail (asn, NULL);

	if (!gkm_sexp_extract_mpi (s_key, &n, "rsa", "n", NULL) ||
	    !gkm_sexp_extract_mpi (s_key, &e, "rsa", "e", NULL) ||
	    !gkm_sexp_extract_mpi (s_key, &d, "rsa", "d", NULL) ||
	    !gkm_sexp_extract_mpi (s_key, &p, "rsa", "p", NULL) ||
	    !gkm_sexp_extract_mpi (s_key, &q, "rsa", "q", NULL) ||
	    !gkm_sexp_extract_mpi (s_key, &u, "rsa", "u", NULL))
		goto done;

	if (!gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "modulus", NULL), n) ||
	    !gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "publicExponent", NULL), e) ||
	    !gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "privateExponent", NULL), d) ||
	    !gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "prime1", NULL), p) ||
	    !gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "prime2", NULL), q) ||
	    !gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "coefficient", NULL), u))
		goto done;

	/* Calculate e1 and e2 */
	tmp = gcry_mpi_snew (1024);
	gcry_mpi_sub_ui (tmp, p, 1);
	e1 = gcry_mpi_snew (1024);
	gcry_mpi_mod (e1, d, tmp);
	gcry_mpi_sub_ui (tmp, q, 1);
	e2 = gcry_mpi_snew (1024);
	gcry_mpi_mod (e2, d, tmp);

	/* Write out calculated */
	if (!gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "exponent1", NULL), e1) ||
	    !gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "exponent2", NULL), e2))
		goto done;

	/* Write out the version */
	if (!egg_asn1x_set_integer_as_ulong (egg_asn1x_node (asn, "version", NULL), 0))
		goto done;

	result = egg_asn1x_encode (asn, egg_secure_realloc, n_key);
	if (result == NULL)
		g_warning ("couldn't encode private rsa key: %s", egg_asn1x_message (asn));

done:
	egg_asn1x_destroy (asn);
	gcry_mpi_release (n);
	gcry_mpi_release (e);
	gcry_mpi_release (d);
	gcry_mpi_release (p);
	gcry_mpi_release (q);
	gcry_mpi_release (u);

	gcry_mpi_release (tmp);
	gcry_mpi_release (e1);
	gcry_mpi_release (e2);

	return result;
}
示例#10
0
文件: export.c 项目: FMayzek/gnupg
/* Parse a private key S-expression and retutn a malloced array with
   the RSA paramaters in pkcs#12 order.  The caller needs to
   deep-release this array.  */
static gcry_mpi_t *
sexp_to_kparms (gcry_sexp_t sexp)
{
  gcry_sexp_t list, l2;
  const char *name;
  const char *s;
  size_t n;
  int idx;
  const char *elems;
  gcry_mpi_t *array;

  list = gcry_sexp_find_token (sexp, "private-key", 0 );
  if(!list)
    return NULL;
  l2 = gcry_sexp_cadr (list);
  gcry_sexp_release (list);
  list = l2;
  name = gcry_sexp_nth_data (list, 0, &n);
  if(!name || n != 3 || memcmp (name, "rsa", 3))
    {
      gcry_sexp_release (list);
      return NULL;
    }

  /* Parameter names used with RSA in the pkcs#12 order. */
  elems = "nedqp--u";
  array = xtrycalloc (strlen(elems) + 1, sizeof *array);
  if (!array)
    {
      gcry_sexp_release (list);
      return NULL;
    }
  for (idx=0, s=elems; *s; s++, idx++ )
    {
      if (*s == '-')
        continue; /* Computed below  */
      l2 = gcry_sexp_find_token (list, s, 1);
      if (l2)
        {
          array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
          gcry_sexp_release (l2);
        }
      if (!array[idx]) /* Required parameter not found or invalid.  */
        {
          for (idx=0; array[idx]; idx++)
            gcry_mpi_release (array[idx]);
          xfree (array);
          gcry_sexp_release (list);
          return NULL;
        }
    }
  gcry_sexp_release (list);

  array[5] = gcry_mpi_snew (0);  /* compute d mod (q-1) */
  gcry_mpi_sub_ui (array[5], array[3], 1);
  gcry_mpi_mod (array[5], array[2], array[5]);

  array[6] = gcry_mpi_snew (0);  /* compute d mod (p-1) */
  gcry_mpi_sub_ui (array[6], array[4], 1);
  gcry_mpi_mod (array[6], array[3], array[6]);

  return array;
}