/* * Uncompress twisted Edwards curve point. */ int ed_upk(ed_t r, const ed_t p) { int result = 1; fp_t t; TRY { fp_new(t); fp_copy(r->y, p->y); ed_recover_x(t, p->y, core_get()->ed_d, core_get()->ed_a); if (fp_get_bit(t, 0) != fp_get_bit(p->x, 0)) { fp_neg(t, t); } fp_copy(r->x, t); #if ED_ADD == EXTND fp_mul(r->t, r->x, r->y); #endif fp_set_dig(r->z, 1); r->norm = 1; } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { fp_free(t); } return result; }
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; }
int ep_upk(ep_t r, const ep_t p) { fp_t t; int result = 0; fp_null(t); TRY { fp_new(t); ep_rhs(t, p); /* t0 = sqrt(x1^3 + a * x1 + b). */ result = fp_srt(t, t); if (result) { /* Verify if least significant bit of the result matches the * compressed y-coordinate. */ if (fp_get_bit(t, 0) != fp_get_bit(p->y, 0)) { fp_neg(t, t); } fp_copy(r->x, p->x); fp_copy(r->y, t); fp_set_dig(r->z, 1); r->norm = 1; } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { fp_free(t); } return result; }
void fp2_write_bin(uint8_t *bin, int len, fp2_t a, int pack) { fp2_t t; fp2_null(t); TRY { fp2_new(t); if (pack && fp2_test_uni(a)) { if (len != FP_BYTES + 1) { THROW(ERR_NO_BUFFER); } else { fp2_pck(t, t); fp_write_bin(bin, FP_BYTES, a[0]); bin[FP_BYTES] = fp_get_bit(a[1], 0); } } else { if (len != 2 * FP_BYTES) { THROW(ERR_NO_BUFFER); } else { fp_write_bin(bin, FP_BYTES, a[0]); fp_write_bin(bin + FP_BYTES, FP_BYTES, a[1]); } } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { fp2_free(t); } }
/* * Compress twisted Edwards curve point by compressing the x-coordinate to its sign. */ void ed_pck(ed_t r, const ed_t p) { fp_copy(r->y, p->y); int b = fp_get_bit(p->x, 0); fp_zero(r->x); fp_set_bit(r->x, 0, b); fp_set_dig(r->z, 1); r->norm = 1; }
void fp2_pck(fp2_t c, fp2_t a) { int b = fp_get_bit(a[1], 0); if (fp2_test_uni(c)) { fp_copy(c[0], a[0]); fp_zero(c[1]); fp_set_bit(c[1], 0, b); } else { fp2_copy(c, a); } }
void ep_write_bin(uint8_t *bin, int len, const ep_t a, int pack) { ep_t t; ep_null(t); if (ep_is_infty(a)) { if (len != 1) { THROW(ERR_NO_BUFFER); } else { bin[0] = 0; return; } } TRY { ep_new(t); ep_norm(t, a); if (pack) { if (len != FP_BYTES + 1) { THROW(ERR_NO_BUFFER); } else { ep_pck(t, t); bin[0] = 2 | fp_get_bit(t->y, 0); fp_write_bin(bin + 1, FP_BYTES, t->x); } } else { if (len != 2 * FP_BYTES + 1) { THROW(ERR_NO_BUFFER); } else { bin[0] = 4; fp_write_bin(bin + 1, FP_BYTES, t->x); fp_write_bin(bin + FP_BYTES + 1, FP_BYTES, t->y); } } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { ep_free(t); } }