/** * Normalizes a point represented in projective coordinates. * * @param r - the result. * @param p - the point to normalize. */ void ed_norm(ed_t r, const ed_t p) { if (ed_is_infty(p)) { ed_set_infty(r); return; } if (fp_cmp_dig(p->z, 1) == CMP_EQ) { /* If the point is represented in affine coordinates, we just copy it. */ ed_copy(r, p); } else { fp_t z_inv; fp_null(z_inv); fp_new(z_inv); fp_inv(z_inv, p->z); fp_mul(r->x, p->x, z_inv); fp_mul(r->y, p->y, z_inv); #if ED_ADD == EXTND fp_mul(r->t, p->t, z_inv); #endif fp_set_dig(r->z, 1); fp_free(z_inv); } }
/** * Detects an optimization based on the curve coefficients. * * @param[out] opt - the resulting optimization. * @param[in] a - the curve coefficient. */ static void detect_opt(int *opt, fp_t a) { fp_t t; fp_null(t); TRY { fp_new(t); fp_prime_conv_dig(t, 3); fp_neg(t, t); if (fp_cmp(a, t) == CMP_EQ) { *opt = OPT_MINUS3; } else { if (fp_is_zero(a)) { *opt = OPT_ZERO; } else { fp_set_dig(t, 1); if (fp_cmp_dig(a, 1) == CMP_EQ) { *opt = OPT_ONE; } else { if (fp_cmp_dig(a, 2) == CMP_EQ) { *opt = OPT_TWO; } else { if (fp_bits(a) <= FP_DIGIT) { *opt = OPT_DIGIT; } else { *opt = RELIC_OPT_NONE; } } } } } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { fp_free(t); } }
int ed_is_infty(const ed_t p) { assert(!fp_is_zero(p->z)); int ret = 0; fp_t norm_y; fp_null(norm_y); fp_new(norm_y); fp_inv(norm_y, p->z); fp_mul(norm_y, p->y, norm_y); if (fp_cmp_dig(norm_y, 1) == CMP_EQ && fp_is_zero(p->x)) { ret = 1; } fp_free(norm_y); return ret; }
int fp3_cmp_dig(fp3_t a, dig_t b) { return (fp_cmp_dig(a[0], b) == CMP_EQ) && fp_is_zero(a[1]) && fp_is_zero(a[2]) ? CMP_EQ : CMP_NE; }
int fp_srt(fp_t c, const fp_t a) { bn_t e; fp_t t0; fp_t t1; int r = 0; bn_null(e); fp_null(t0); fp_null(t1); TRY { bn_new(e); fp_new(t0); fp_new(t1); /* Make e = p. */ e->used = FP_DIGS; dv_copy(e->dp, fp_prime_get(), FP_DIGS); if (fp_prime_get_mod8() == 3 || fp_prime_get_mod8() == 7) { /* Easy case, compute a^((p + 1)/4). */ bn_add_dig(e, e, 1); bn_rsh(e, e, 2); fp_exp(t0, a, e); fp_sqr(t1, t0); r = (fp_cmp(t1, a) == CMP_EQ); fp_copy(c, t0); } else { int f = 0, m = 0; /* First, check if there is a root. Compute t1 = a^((p - 1)/2). */ bn_rsh(e, e, 1); fp_exp(t0, a, e); if (fp_cmp_dig(t0, 1) != CMP_EQ) { /* Nope, there is no square root. */ r = 0; } else { r = 1; /* Find a quadratic non-residue modulo p, that is a number t2 * such that (t2 | p) = t2^((p - 1)/2)!= 1. */ do { fp_rand(t1); fp_exp(t0, t1, e); } while (fp_cmp_dig(t0, 1) == CMP_EQ); /* Write p - 1 as (e * 2^f), odd e. */ bn_lsh(e, e, 1); while (bn_is_even(e)) { bn_rsh(e, e, 1); f++; } /* Compute t2 = t2^e. */ fp_exp(t1, t1, e); /* Compute t1 = a^e, c = a^((e + 1)/2) = a^(e/2 + 1), odd e. */ bn_rsh(e, e, 1); fp_exp(t0, a, e); fp_mul(e->dp, t0, a); fp_sqr(t0, t0); fp_mul(t0, t0, a); fp_copy(c, e->dp); while (1) { if (fp_cmp_dig(t0, 1) == CMP_EQ) { break; } fp_copy(e->dp, t0); for (m = 0; (m < f) && (fp_cmp_dig(t0, 1) != CMP_EQ); m++) { fp_sqr(t0, t0); } fp_copy(t0, e->dp); for (int i = 0; i < f - m - 1; i++) { fp_sqr(t1, t1); } fp_mul(c, c, t1); fp_sqr(t1, t1); fp_mul(t0, t0, t1); f = m; } } } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(e); fp_free(t0); fp_free(t1); } return r; }