int fp3_srt(fp3_t c, fp3_t a) { int r = 0; fp3_t t0, t1, t2, t3; bn_t e; fp3_null(t0); fp3_null(t1); fp3_null(t2); fp3_null(t3); bn_null(e); TRY { fp3_new(t0); fp3_new(t1); fp3_new(t2); fp3_new(t3); bn_new(e); fp3_dbl(t3, a); fp3_frb(t0, t3, 1); fp3_sqr(t1, t0); fp3_mul(t2, t1, t0); fp3_mul(t1, t1, t2); fp3_frb(t0, t0, 1); fp3_mul(t3, t3, t1); fp3_mul(t0, t0, t3); e->used = FP_DIGS; dv_copy(e->dp, fp_prime_get(), FP_DIGS); bn_sub_dig(e, e, 5); bn_div_dig(e, e, 8); fp3_exp(t0, t0, e); fp3_mul(t0, t0, t2); fp3_sqr(t1, t0); fp3_mul(t1, t1, a); fp3_dbl(t1, t1); fp3_mul(t0, t0, a); fp_sub_dig(t1[0], t1[0], 1); fp3_mul(c, t0, t1); fp3_sqr(t0, c); if (fp3_cmp(t0, a) == CMP_EQ) { r = 1; } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { fp3_free(t0); fp3_free(t1); fp3_free(t2); fp3_free(t3); bn_free(e); } return r; }
int fp2_upk(fp2_t c, fp2_t a) { int result, b = fp_get_bit(a[1], 0); fp_t t; fp_null(t); TRY { fp_new(t); /* a_0^2 + a_1^2 = 1, thus a_1^2 = 1 - a_0^2. */ fp_sqr(t, a[0]); fp_sub_dig(t, t, 1); fp_neg(t, t); /* a1 = sqrt(a_0^2). */ result = fp_srt(t, t); if (result) { /* Verify if least significant bit of the result matches the * compressed second coordinate. */ if (fp_get_bit(t, 0) != b) { fp_neg(t, t); } fp_copy(c[0], a[0]); fp_copy(c[1], t); } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { fp_free(t); } return result; }
void fp8_sqr_uni(fp8_t c, fp8_t a) { fp4_t t0, t1, t2; fp4_null(t0); fp4_null(t1); fp4_null(t2); TRY { fp4_new(t0); fp4_new(t1); fp4_new(t2); fp4_sqr(t0, a[1]); fp4_add(t1, a[0], a[1]); fp4_sqr(t2, t1); fp4_sub(t2, t2, t0); fp4_mul_art(c[0], t0); fp4_sub(c[1], t2, c[0]); fp4_dbl(c[0], c[0]); fp_add_dig(c[0][0][0], c[0][0][0], 1); fp_sub_dig(c[1][0][0], c[1][0][0], 1); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { fp4_free(t0); fp4_free(t1); fp4_free(t2); } }
int ed_affine_is_valid(const fp_t x, const fp_t y) { fp_t tmpFP0; fp_t tmpFP1; fp_t tmpFP2; fp_null(tmpFP0); fp_null(tmpFP1); fp_null(tmpFP2); int r = 0; TRY { fp_new(tmpFP0); fp_new(tmpFP1); fp_new(tmpFP2); // a * X^2 + Y^2 - 1 - d * X^2 * Y^2 =?= 0 fp_sqr(tmpFP0, x); fp_mul(tmpFP0, core_get()->ed_a, tmpFP0); fp_sqr(tmpFP1, y); fp_add(tmpFP1, tmpFP0, tmpFP1); fp_sub_dig(tmpFP1, tmpFP1, 1); fp_sqr(tmpFP0, x); fp_mul(tmpFP0, core_get()->ed_d, tmpFP0); fp_sqr(tmpFP2, y); fp_mul(tmpFP2, tmpFP0, tmpFP2); fp_sub(tmpFP0, tmpFP1, tmpFP2); r = fp_is_zero(tmpFP0); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { fp_free(tmpFP0); fp_free(tmpFP1); fp_free(tmpFP2); } return r; }