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); }
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; }
void point_add(struct affine_point *p1, const struct affine_point *p2, const struct domain_params *dp) { if (! point_is_zero(p2)) { if (! point_is_zero(p1)) { if (! gcry_mpi_cmp(p1->x, p2->x)) { if (! gcry_mpi_cmp(p1->y, p2->y)) point_double(p1, dp); else point_load_zero(p1); } else { gcry_mpi_t t; t = gcry_mpi_snew(0); gcry_mpi_subm(t, p1->y, p2->y, dp->m); gcry_mpi_subm(p1->y, p1->x, p2->x, dp->m); gcry_mpi_invm(p1->y, p1->y, dp->m); gcry_mpi_mulm(p1->y, t, p1->y, dp->m); gcry_mpi_mulm(t, p1->y, p1->y, dp->m); gcry_mpi_addm(p1->x, p1->x, p2->x, dp->m); gcry_mpi_subm(p1->x, t, p1->x, dp->m); gcry_mpi_subm(t, p2->x, p1->x, dp->m); gcry_mpi_mulm(p1->y, p1->y, t, dp->m); gcry_mpi_subm(p1->y, p1->y, p2->y, dp->m); gcry_mpi_release(t); } } else point_set(p1, p2); } }
int point_on_curve(const struct affine_point *p, const struct domain_params *dp) { int res; if (! (res = point_is_zero(p))) { gcry_mpi_t h1, h2; h1 = gcry_mpi_snew(0); h2 = gcry_mpi_snew(0); gcry_mpi_mulm(h1, p->x, p->x, dp->m); gcry_mpi_addm(h1, h1, dp->a, dp->m); gcry_mpi_mulm(h1, h1, p->x, dp->m); gcry_mpi_addm(h1, h1, dp->b, dp->m); gcry_mpi_mulm(h2, p->y, p->y, dp->m); res = ! gcry_mpi_cmp(h1, h2); gcry_mpi_release(h1); gcry_mpi_release(h2); } return res; }
static bigint_t wrap_gcry_mpi_addm (bigint_t w, const bigint_t a, const bigint_t b, const bigint_t m) { if (w == NULL) w = _gnutls_mpi_alloc_like (m); if (w == NULL) return NULL; gcry_mpi_addm (w, a, b, m); return w; }
/* 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; }