/** * 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); } }
void ed_mul_basic(ed_t r, const ed_t p, const bn_t k) { ed_t t; ed_null(t); if (bn_is_zero(k) || ed_is_infty(p)) { ed_set_infty(r); return; } TRY { ed_new(t); ed_copy(t, p); for (int i = bn_bits(k) - 2; i >= 0; i--) { ed_dbl(t, t); if (bn_get_bit(k, i)) { ed_add(t, t, p); } } ed_norm(r, t); if (bn_sign(k) == RLC_NEG) { ed_neg(r, r); } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { ed_free(t); } }
void ed_mul_lwreg(ed_t r, const ed_t p, const bn_t k) { if (bn_is_zero(k) || ed_is_infty(p)) { ed_set_infty(r); return; } ed_mul_reg_imp(r, p, k); }
/*============================================================================*/ int ed_size_bin(const ed_t a, int pack) { int size = 0; if (ed_is_infty(a)) { return 1; } size = 1 + FP_BYTES; if (!pack) { size += FP_BYTES; } return size; }
void ed_mul_monty(ed_t r, const ed_t p, const bn_t k) { ed_t t[2]; ed_null(t[0]); ed_null(t[1]); if (bn_is_zero(k) || ed_is_infty(p)) { ed_set_infty(r); return; } TRY { ed_new(t[0]); ed_new(t[1]); ed_set_infty(t[0]); ed_copy(t[1], p); for (int i = bn_bits(k) - 1; i >= 0; i--) { int j = bn_get_bit(k, i); dv_swap_cond(t[0]->x, t[1]->x, RLC_FP_DIGS, j ^ 1); dv_swap_cond(t[0]->y, t[1]->y, RLC_FP_DIGS, j ^ 1); dv_swap_cond(t[0]->z, t[1]->z, RLC_FP_DIGS, j ^ 1); #if ED_ADD == EXTND dv_swap_cond(t[0]->t, t[1]->t, RLC_FP_DIGS, j ^ 1); #endif ed_add(t[0], t[0], t[1]); ed_dbl(t[1], t[1]); dv_swap_cond(t[0]->x, t[1]->x, RLC_FP_DIGS, j ^ 1); dv_swap_cond(t[0]->y, t[1]->y, RLC_FP_DIGS, j ^ 1); dv_swap_cond(t[0]->z, t[1]->z, RLC_FP_DIGS, j ^ 1); #if ED_ADD == EXTND dv_swap_cond(t[0]->t, t[1]->t, RLC_FP_DIGS, j ^ 1); #endif } ed_norm(r, t[0]); if (bn_sign(k) == RLC_NEG) { ed_neg(r, r); } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { ed_free(t[1]); ed_free(t[0]); } }
void ed_write_bin(uint8_t *bin, int len, const ed_t a, int pack) { ed_t t; ed_null(t); if (ed_is_infty(a)) { if (len != 1) { THROW(ERR_NO_BUFFER); } else { bin[0] = 0; return; } } TRY { ed_new(t); ed_norm(t, a); if (pack) { if (len != FP_BYTES + 1) { THROW(ERR_NO_BUFFER); } else { ed_pck(t, t); bin[0] = 2 | fp_get_bit(t->x, 0); fp_write_bin(bin + 1, FP_BYTES, t->y); } } else { if (len != 2 * FP_BYTES + 1) { THROW(ERR_NO_BUFFER); } else { bin[0] = 4; fp_write_bin(bin + 1, FP_BYTES, t->y); fp_write_bin(bin + FP_BYTES + 1, FP_BYTES, t->x); } } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { ed_free(t); } }
void ed_mul_slide(ed_t r, const ed_t p, const bn_t k) { ed_t t[1 << (EP_WIDTH - 1)], q; int i, j, l; uint8_t win[RLC_FP_BITS + 1]; ed_null(q); if (bn_is_zero(k) || ed_is_infty(p)) { ed_set_infty(r); return; } TRY { for (i = 0; i < (1 << (EP_WIDTH - 1)); i ++) { ed_null(t[i]); ed_new(t[i]); } ed_new(q); ed_copy(t[0], p); ed_dbl(q, p); #if defined(EP_MIXED) ed_norm(q, q); #endif /* Create table. */ for (i = 1; i < (1 << (EP_WIDTH - 1)); i++) { ed_add(t[i], t[i - 1], q); } #if defined(EP_MIXED) ed_norm_sim(t + 1, (const ed_t *)t + 1, (1 << (EP_WIDTH - 1)) - 1); #endif ed_set_infty(q); l = RLC_FP_BITS + 1; bn_rec_slw(win, &l, k, EP_WIDTH); for (i = 0; i < l; i++) { if (win[i] == 0) { ed_dbl(q, q); } else { for (j = 0; j < util_bits_dig(win[i]); j++) { ed_dbl(q, q); } ed_add(q, q, t[win[i] >> 1]); } } ed_norm(r, q); if (bn_sign(k) == RLC_NEG) { ed_neg(r, r); } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { for (i = 0; i < (1 << (EP_WIDTH - 1)); i++) { ed_free(t[i]); } ed_free(q); } }