void ep2_rand(ep2_t p) { bn_t n, k; ep2_t gen; bn_null(k); bn_null(n); ep2_null(gen); TRY { bn_new(k); bn_new(n); ep2_new(gen); ep2_curve_get_ord(n); bn_rand_mod(k, n); ep2_curve_get_gen(gen); ep2_mul(p, gen, k); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(k); bn_free(n); ep2_free(gen); } }
void ep2_mul_pre_nafwi(ep2_t *t, ep2_t p) { int l; bn_t n; bn_null(n); TRY { bn_new(n); ep2_curve_get_ord(n); l = bn_bits(n) + 1; l = ((l % EP_DEPTH) == 0 ? (l / EP_DEPTH) : (l / EP_DEPTH) + 1); ep2_copy(t[0], p); for (int i = 1; i < l; i++) { ep2_dbl(t[i], t[i - 1]); for (int j = 1; j < EP_DEPTH; j++) { ep2_dbl(t[i], t[i]); } } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(n); } }
void ep2_mul_fix_combd(ep2_t r, ep2_t *t, bn_t k) { int i, j, d, e, w0, w1, n0, p0, p1; bn_t n; if (bn_is_zero(k)) { ep2_set_infty(r); return; } bn_null(n); TRY { bn_new(n); ep2_curve_get_ord(n); d = bn_bits(n); d = ((d % EP_DEPTH) == 0 ? (d / EP_DEPTH) : (d / EP_DEPTH) + 1); e = (d % 2 == 0 ? (d / 2) : (d / 2) + 1); ep2_set_infty(r); n0 = bn_bits(k); p1 = (e - 1) + (EP_DEPTH - 1) * d; for (i = e - 1; i >= 0; i--) { ep2_dbl(r, r); w0 = 0; p0 = p1; for (j = EP_DEPTH - 1; j >= 0; j--, p0 -= d) { w0 = w0 << 1; if (p0 < n0 && bn_get_bit(k, p0)) { w0 = w0 | 1; } } w1 = 0; p0 = p1-- + e; for (j = EP_DEPTH - 1; j >= 0; j--, p0 -= d) { w1 = w1 << 1; if (i + e < d && p0 < n0 && bn_get_bit(k, p0)) { w1 = w1 | 1; } } ep2_add(r, r, t[w0]); ep2_add(r, r, t[(1 << EP_DEPTH) + w1]); } ep2_norm(r, r); if (bn_sign(k) == RLC_NEG) { ep2_neg(r, r); } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(n); } }
void ep2_mul_fix_combs(ep2_t r, ep2_t *t, bn_t k) { int i, j, l, w, n0, p0, p1; bn_t n; if (bn_is_zero(k)) { ep2_set_infty(r); return; } bn_null(n); TRY { bn_new(n); ep2_curve_get_ord(n); l = bn_bits(n); l = ((l % EP_DEPTH) == 0 ? (l / EP_DEPTH) : (l / EP_DEPTH) + 1); n0 = bn_bits(k); p0 = (EP_DEPTH) * l - 1; w = 0; p1 = p0--; for (j = EP_DEPTH - 1; j >= 0; j--, p1 -= l) { w = w << 1; if (p1 < n0 && bn_get_bit(k, p1)) { w = w | 1; } } ep2_copy(r, t[w]); for (i = l - 2; i >= 0; i--) { ep2_dbl(r, r); w = 0; p1 = p0--; for (j = EP_DEPTH - 1; j >= 0; j--, p1 -= l) { w = w << 1; if (p1 < n0 && bn_get_bit(k, p1)) { w = w | 1; } } if (w > 0) { ep2_add(r, r, t[w]); } } ep2_norm(r, r); if (bn_sign(k) == RLC_NEG) { ep2_neg(r, r); } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(n); } }
void ep2_mul_pre_combd(ep2_t *t, ep2_t p) { int i, j, d, e; bn_t n; bn_null(n); TRY { bn_new(n); ep2_curve_get_ord(n); d = bn_bits(n); d = ((d % EP_DEPTH) == 0 ? (d / EP_DEPTH) : (d / EP_DEPTH) + 1); e = (d % 2 == 0 ? (d / 2) : (d / 2) + 1); ep2_set_infty(t[0]); ep2_copy(t[1], p); for (j = 1; j < EP_DEPTH; j++) { ep2_dbl(t[1 << j], t[1 << (j - 1)]); for (i = 1; i < d; i++) { ep2_dbl(t[1 << j], t[1 << j]); } #if defined(EP_MIXED) ep2_norm(t[1 << j], t[1 << j]); #endif for (i = 1; i < (1 << j); i++) { ep2_add(t[(1 << j) + i], t[i], t[1 << j]); } } ep2_set_infty(t[1 << EP_DEPTH]); for (j = 1; j < (1 << EP_DEPTH); j++) { ep2_dbl(t[(1 << EP_DEPTH) + j], t[j]); for (i = 1; i < e; i++) { ep2_dbl(t[(1 << EP_DEPTH) + j], t[(1 << EP_DEPTH) + j]); } } #if defined(EP_MIXED) for (i = 1; i < RELIC_EP_TABLE_COMBD; i++) { ep2_norm(t[i], t[i]); } #endif } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(n); } }
void ep2_mul_pre_combs(ep2_t *t, ep2_t p) { int i, j, l; bn_t n; bn_null(n); TRY { bn_new(n); ep2_curve_get_ord(n); l = bn_bits(n); l = ((l % EP_DEPTH) == 0 ? (l / EP_DEPTH) : (l / EP_DEPTH) + 1); ep2_set_infty(t[0]); ep2_copy(t[1], p); for (j = 1; j < EP_DEPTH; j++) { ep2_dbl(t[1 << j], t[1 << (j - 1)]); for (i = 1; i < l; i++) { ep2_dbl(t[1 << j], t[1 << j]); } #if defined(EP_MIXED) ep2_norm(t[1 << j], t[1 << j]); #endif for (i = 1; i < (1 << j); i++) { ep2_add(t[(1 << j) + i], t[i], t[1 << j]); } } #if defined(EP_MIXED) for (i = 1; i < RLC_EP_TABLE_COMBS; i++) { ep2_norm(t[i], t[i]); } #endif } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(n); } }
void ep2_mul_pre_basic(ep2_t *t, ep2_t p) { bn_t n; bn_null(n); TRY { bn_new(n); ep2_curve_get_ord(n); ep2_copy(t[0], p); for (int i = 1; i < bn_bits(n); i++) { ep2_dbl(t[i], t[i - 1]); } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(n); } }
void ep2_mul_sim_trick(ep2_t r, ep2_t p, bn_t k, ep2_t q, bn_t l) { ep2_t t0[1 << (EP_WIDTH / 2)]; ep2_t t1[1 << (EP_WIDTH / 2)]; ep2_t t[1 << EP_WIDTH]; bn_t n; int l0, l1, w = EP_WIDTH / 2; uint8_t w0[CEIL(2 * FP_BITS, w)], w1[CEIL(2 * FP_BITS, w)]; bn_null(n); for (int i = 0; i < 1 << EP_WIDTH; i++) { ep2_null(t[i]); } for (int i = 0; i < 1 << (EP_WIDTH / 2); i++) { ep2_null(t0[i]); ep2_null(t1[i]); } TRY { bn_new(n); ep2_curve_get_ord(n); for (int i = 0; i < (1 << w); i++) { ep2_new(t0[i]); ep2_new(t1[i]); } for (int i = 0; i < (1 << EP_WIDTH); i++) { ep2_new(t[i]); } ep2_set_infty(t0[0]); for (int i = 1; i < (1 << w); i++) { ep2_add(t0[i], t0[i - 1], p); } ep2_set_infty(t1[0]); for (int i = 1; i < (1 << w); i++) { ep2_add(t1[i], t1[i - 1], q); } for (int i = 0; i < (1 << w); i++) { for (int j = 0; j < (1 << w); j++) { ep2_add(t[(i << w) + j], t0[i], t1[j]); } } l0 = l1 = CEIL(2 * FP_BITS, w); bn_rec_win(w0, &l0, k, w); bn_rec_win(w1, &l1, l, w); for (int i = l0; i < l1; i++) { w0[i] = 0; } for (int i = l1; i < l0; i++) { w1[i] = 0; } ep2_set_infty(r); for (int i = MAX(l0, l1) - 1; i >= 0; i--) { for (int j = 0; j < w; j++) { ep2_dbl(r, r); } ep2_add(r, r, t[(w0[i] << w) + w1[i]]); } ep2_norm(r, r); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(n); for (int i = 0; i < (1 << w); i++) { ep2_free(t0[i]); ep2_free(t1[i]); } for (int i = 0; i < (1 << EP_WIDTH); i++) { ep2_free(t[i]); } } }