void gotr_ecbd_gen_flake_key(gcry_mpi_point_t *ret, gcry_mpi_point_t y0, gcry_mpi_t r1, gcry_mpi_point_t R1, gcry_mpi_point_t R0, gcry_mpi_point_t V1) { gcry_mpi_point_t tmp = gcry_mpi_point_new(0); gcry_mpi_t n = gcry_mpi_new(0); gcry_mpi_point_release(*ret); *ret = gcry_mpi_point_new(0); gcry_mpi_mul_ui(n, r1, 4); gcry_mpi_ec_mul(*ret, n, y0, edctx); gcry_mpi_set_ui(n, 3); gcry_mpi_ec_mul(tmp, n, R1, edctx); gcry_mpi_ec_add(*ret, *ret, tmp, edctx); gcry_mpi_ec_dup(tmp, R0, edctx); gcry_mpi_ec_add(*ret, *ret, tmp, edctx); gcry_mpi_ec_add(*ret, *ret, V1, edctx); gcry_mpi_point_release(tmp); gcry_mpi_release(n); }
/** * Calculate ECC discrete logarithm for small factors. * * @param edc precalculated values, determine range of factors * @param input point on the curve to factor * @return `edc->max` if dlog failed, otherwise the factor */ int GNUNET_CRYPTO_ecc_dlog (struct GNUNET_CRYPTO_EccDlogContext *edc, gcry_mpi_point_t input) { unsigned int K = ((edc->max + (edc->mem-1)) / edc->mem); gcry_mpi_point_t g; struct GNUNET_PeerIdentity key; gcry_mpi_point_t q; unsigned int i; int res; void *retp; g = gcry_mpi_ec_get_point ("g", edc->ctx, 0); GNUNET_assert (NULL != g); q = gcry_mpi_point_new (0); res = edc->max; for (i=0;i<=edc->max/edc->mem;i++) { if (0 == i) extract_pk (input, edc->ctx, &key); else extract_pk (q, edc->ctx, &key); retp = GNUNET_CONTAINER_multipeermap_get (edc->map, &key); if (NULL != retp) { res = (((long) retp) - edc->max) * K - i; /* we continue the loop here to make the implementation "constant-time". If we do not care about this, we could just 'break' here and do fewer operations... */ } if (i == edc->max/edc->mem) break; /* q = q + g */ if (0 == i) gcry_mpi_ec_add (q, input, g, edc->ctx); else gcry_mpi_ec_add (q, q, g, edc->ctx); } gcry_mpi_point_release (g); gcry_mpi_point_release (q); return res; }
/** * Add two points on the elliptic curve. * * @param edc calculation context for ECC operations * @param a some value * @param b some value * @return @a a + @a b, must be freed using #GNUNET_CRYPTO_ecc_free() */ gcry_mpi_point_t GNUNET_CRYPTO_ecc_add (struct GNUNET_CRYPTO_EccDlogContext *edc, gcry_mpi_point_t a, gcry_mpi_point_t b) { gcry_mpi_point_t r; r = gcry_mpi_point_new (0); gcry_mpi_ec_add (r, a, b, edc->ctx); return r; }
void gotr_ecbd_gen_circle_key(gcry_mpi_point_t *ret, gcry_mpi_point_t *X, gcry_mpi_point_t Z, gcry_mpi_t r) { gcry_mpi_point_t tmp = gcry_mpi_point_new(0); gcry_mpi_t n = gcry_mpi_new(0); unsigned int i; gcry_mpi_point_release(*ret); *ret = gcry_mpi_point_set(NULL, NULL, GCRYMPI_CONST_ONE, GCRYMPI_CONST_ONE); for (i = 0; X[i]; i++) { gcry_mpi_set_ui(n, i+1); gcry_mpi_ec_mul(tmp, n, X[i], edctx); gcry_mpi_ec_add(*ret, *ret, tmp, edctx); } gcry_mpi_mul_ui(n, r, i+1); gcry_mpi_ec_mul(tmp, n, Z, edctx); gcry_mpi_ec_add(*ret, *ret, tmp, edctx); gcry_mpi_release(n); gcry_mpi_point_release(tmp); }
void gotr_ecbd_gen_X_value(gcry_mpi_point_t* ret, const gcry_mpi_point_t succ, const gcry_mpi_point_t pred, const gcry_mpi_t priv) { gcry_mpi_t x = gcry_mpi_new(0); gcry_mpi_t y = gcry_mpi_new(0); gcry_mpi_t z = gcry_mpi_new(0); gcry_mpi_point_t tmpoint = gcry_mpi_point_new(0); gotr_assert(succ && pred && priv); gcry_mpi_point_release(*ret); *ret = gcry_mpi_point_new(0); ///@todo use gcry_mpi_ec_sub after it is released gcry_mpi_point_get(x, y, z, pred); gcry_mpi_neg(x, x); gcry_mpi_point_set(tmpoint, x, y, z); gcry_mpi_ec_add(tmpoint, succ, tmpoint, edctx); gcry_mpi_ec_mul(*ret, priv, tmpoint, edctx); gcry_mpi_point_release(tmpoint); gcry_mpi_release(x); gcry_mpi_release(y); gcry_mpi_release(z); }