diff --git a/bench/bench_fp.c b/bench/bench_fp.c index ab96188ab..ea3f576c2 100644 --- a/bench/bench_fp.c +++ b/bench/bench_fp.c @@ -571,15 +571,6 @@ static void arith(void) { BENCH_END; #endif -#if FP_SMB == BINAR || !defined(STRIP) - BENCH_RUN("fp_smb_binar") { - fp_rand(a); - fp_sqr(a, a); - BENCH_ADD(fp_smb_binar(a)); - } - BENCH_END; -#endif - #if FP_SMB == DIVST || !defined(STRIP) BENCH_RUN("fp_smb_divst") { fp_rand(a); diff --git a/cmake/fp.cmake b/cmake/fp.cmake index 4636a948a..44648fb2c 100644 --- a/cmake/fp.cmake +++ b/cmake/fp.cmake @@ -39,7 +39,6 @@ message(" FP_METHD=LOWER Pass inversion to the lower level.\n") message(" Legendre symbol:") message(" FP_METHD=BASIC Computation by Fermat's Little Theorem.") -message(" FP_METHD=BINAR Binary algorithm.") message(" FP_METHD=DIVST Constant-time method by division steps.") message(" FP_METHD=JMPDS Constant-time method by jump division steps.") message(" FP_METHD=LOWER Pass call to the lower level.\n") diff --git a/include/relic_conf.h.in b/include/relic_conf.h.in index f9bb79a25..e11eb7a44 100644 --- a/include/relic_conf.h.in +++ b/include/relic_conf.h.in @@ -266,8 +266,6 @@ /** Legendre by Fermat's Little Theorem. */ #define BASIC 1 -/** Binary method. */ -#define BINAR 2 /** Constant-time inversion by Bernstein-Yang division steps. */ #define DIVST 5 /** Constant-time inversion by Bernstein-Yang jump division steps. */ diff --git a/include/relic_fp.h b/include/relic_fp.h index 57241a15c..e5bf72632 100644 --- a/include/relic_fp.h +++ b/include/relic_fp.h @@ -400,8 +400,6 @@ typedef rlc_align dig_t fp_st[RLC_FP_DIGS + RLC_PAD(RLC_FP_BYTES)/(RLC_DIG / 8)] */ #if FP_SMB == BASIC #define fp_smb(A) fp_smb_basic(A) -#elif FP_SMB == BINAR -#define fp_smb(A) fp_smb_binar(A) #elif FP_SMB == DIVST #define fp_smb(A) fp_smb_divst(A) #elif FP_SMB == JMPDS @@ -1142,14 +1140,6 @@ void fp_inv_sim(fp_t *c, const fp_t *a, int n); */ int fp_smb_basic(const fp_t a); -/** - * Computes Legendre symbol of a prime field element using the binary method. - * - * @param[in] a - the prime field element to compute. - * @return the result. - */ -int fp_smb_binar(const fp_t a); - /** * Computes Legendre symbol of a prime field element using the constant-time * division step approach by Bernstein and Bo-Yin Yang. diff --git a/include/relic_label.h b/include/relic_label.h index 3342828d6..6abb25b5e 100644 --- a/include/relic_label.h +++ b/include/relic_label.h @@ -542,7 +542,6 @@ #undef fp_inv_lower #undef fp_inv_sim #undef fp_smb_basic -#undef fp_smb_binar #undef fp_smb_divst #undef fp_smb_jmpds #undef fp_smb_lower @@ -639,7 +638,6 @@ #define fp_inv_lower RLC_PREFIX(fp_inv_lower) #define fp_inv_sim RLC_PREFIX(fp_inv_sim) #define fp_smb_basic RLC_PREFIX(fp_smb_basic) -#define fp_smb_binar RLC_PREFIX(fp_smb_binar) #define fp_smb_divst RLC_PREFIX(fp_smb_divst) #define fp_smb_jmpds RLC_PREFIX(fp_smb_jmpds) #define fp_smb_lower RLC_PREFIX(fp_smb_lower) diff --git a/src/fp/relic_fp_smb.c b/src/fp/relic_fp_smb.c index 4c01b5567..2ea43ca72 100644 --- a/src/fp/relic_fp_smb.c +++ b/src/fp/relic_fp_smb.c @@ -163,204 +163,6 @@ int fp_smb_basic(const fp_t a) { #endif -#if FP_SMB == BINAR || !defined(STRIP) - -static inline dig_t is_zero(dig_t l) { - l = ~l & (l - 1); - return (l >> (RLC_DIG - 1)); -} - -static dig_t lshift_2(dig_t hi, dig_t lo, size_t l) { - size_t r = RLC_DIG - l; - dig_t mask = 0 - (is_zero(l) ^ 1); - return (hi << (l & (RLC_DIG - 1))) | ((lo & mask) >> (r & (RLC_DIG - 1))); -} - -static void ab_approximation_n(dig_t a_[2], const dig_t a[], - dig_t b_[2], const dig_t b[]) { - dig_t a_hi, a_lo, b_hi, b_lo, mask; - size_t i; - - i = RLC_FP_DIGS - 1; - a_hi = a[i], a_lo = a[i - 1]; - b_hi = b[i], b_lo = b[i - 1]; - for (int j = i - 1; j >= 0; j--) { - mask = 0 - is_zero(a_hi | b_hi); - a_hi = ((a_lo ^ a_hi) & mask) ^ a_hi; - b_hi = ((b_lo ^ b_hi) & mask) ^ b_hi; - a_lo = ((a[j] ^ a_lo) & mask) ^ a_lo; - b_lo = ((b[j] ^ b_lo) & mask) ^ b_lo; - } - i = RLC_DIG - util_bits_dig(a_hi | b_hi); - /* |i| can be RLC_DIG if all a[2..]|b[2..] were zeros */ - - a_[0] = a[0], a_[1] = lshift_2(a_hi, a_lo, i); - b_[0] = b[0], b_[1] = lshift_2(b_hi, b_lo, i); -} - -static dig_t smul_n_shift_n(dig_t ret[], const dig_t a[], dig_t *f_, - const dig_t b[], dig_t *g_) { - dig_t a_[RLC_FP_DIGS + 1], b_[RLC_FP_DIGS + 1], f, g, neg, carry, hi; - size_t i; - - /* |a|*|f_| */ - f = *f_; - neg = 0 - RLC_SIGN(f); - f = (f ^ neg) - neg; /* ensure |f| is positive */ - bn_negs_low(a_, a, -neg, RLC_FP_DIGS); - hi = fp_mul1_low(a_, a_, f); - a_[RLC_FP_DIGS] = hi - (f & neg); - - /* |b|*|g_| */ - g = *g_; - neg = 0 - RLC_SIGN(g); - g = (g ^ neg) - neg; /* ensure |g| is positive */ - bn_negs_low(b_, b, -neg, RLC_FP_DIGS); - hi = fp_mul1_low(b_, b_, g); - b_[RLC_FP_DIGS] = hi - (g & neg); - - /* |a|*|f_| + |b|*|g_| */ - (void)bn_addn_low(a_, a_, b_, RLC_FP_DIGS + 1); - - /* (|a|*|f_| + |b|*|g_|) >> k */ - for (carry = a_[0], i = 0; i < RLC_FP_DIGS; i++) { - hi = carry >> (RLC_DIG - 2); - carry = a_[i + 1]; - ret[i] = hi | (carry << 2); - } - - /* ensure result is non-negative, fix up |f_| and |g_| accordingly */ - neg = 0 - RLC_SIGN(carry); - *f_ = (*f_ ^ neg) - neg; - *g_ = (*g_ ^ neg) - neg; - bn_negs_low(ret, ret, -neg, RLC_FP_DIGS); - - return neg; -} - -/* - * Copy of inner_loop_n above, but with |L| updates. - */ -static dig_t legendre_loop_n(dig_t l, dig_t m[4], const dig_t a_[2], - const dig_t b_[2], size_t n) { - dig_t limbx, f0 = 1, g0 = 0, f1 = 0, g1 = 1; - dig_t a_lo, a_hi, b_lo, b_hi, t_lo, t_hi, odd, borrow, xorm; - - a_lo = a_[0], a_hi = a_[1]; - b_lo = b_[0], b_hi = b_[1]; - - while (n--) { - odd = 0 - (a_lo & 1); - - /* a_ -= b_ if a_ is odd */ - t_lo = a_lo, t_hi = a_hi; - - borrow = 0; - limbx = a_lo - (b_lo & odd); - borrow = (a_lo < limbx); - a_lo = limbx; - - limbx = a_hi - (b_hi & odd); - xorm = limbx - borrow; - borrow = -((a_hi < limbx) || (borrow && !limbx)); - a_hi = xorm; - - l += ((t_lo & b_lo) >> 1) & borrow; - - /* negate a_-b_ if it borrowed */ - a_lo ^= borrow; - a_hi ^= borrow; - limbx = a_lo + (borrow & 1); - a_hi += (a_lo < limbx); - a_lo = limbx; - - /* b_=a_ if a_-b_ borrowed */ - b_lo = ((t_lo ^ b_lo) & borrow) ^ b_lo; - b_hi = ((t_hi ^ b_hi) & borrow) ^ b_hi; - - /* exchange f0 and f1 if a_-b_ borrowed */ - xorm = (f0 ^ f1) & borrow; - f0 ^= xorm; - f1 ^= xorm; - - /* exchange g0 and g1 if a_-b_ borrowed */ - xorm = (g0 ^ g1) & borrow; - g0 ^= xorm; - g1 ^= xorm; - - /* subtract if a_ was odd */ - f0 -= f1 & odd; - g0 -= g1 & odd; - - f1 <<= 1; - g1 <<= 1; - a_lo >>= 1; - a_lo |= a_hi << (RLC_DIG - 1); - a_hi >>= 1; - - l += (b_lo + 2) >> 2; - } - - m[0] = f0; - m[1] = g0; - m[2] = f1; - m[3] = g1; - - return l; -} - -int fp_smb_binar(const fp_t a) { - const size_t s = RLC_DIG - 2; - dv_t x, y, t; - dig_t a_[2], b_[2], neg, l = 0, m[4]; - bn_t _t; - int iterations = 2 * RLC_FP_DIGS * RLC_DIG; - - if (fp_is_zero(a)) { - return 0; - } - - bn_null(_t); - dv_null(x); - dv_null(y); - dv_null(t); - - RLC_TRY { - bn_new(_t); - dv_new(x); - dv_new(y); - dv_new(t); - - fp_prime_back(_t, a); - dv_zero(x, RLC_FP_DIGS); - dv_copy(x, _t->dp, _t->used); - dv_copy(y, fp_prime_get(), RLC_FP_DIGS); - - for (size_t i = 0; i < iterations / s; i++) { - ab_approximation_n(a_, x, b_, y); - l = legendre_loop_n(l, m, a_, b_, s); - neg = smul_n_shift_n(t, x, &m[0], y, &m[1]); - (void)smul_n_shift_n(y, x, &m[2], y, &m[3]); - fp_copy(x, t); - l += (y[0] >> 1) & neg; - } - - l = legendre_loop_n(l, m, x, y, iterations % s); - - } RLC_CATCH_ANY { - RLC_THROW(ERR_CAUGHT) - } RLC_FINALLY { - bn_free(_t); - dv_free(x); - dv_free(y); - dv_free(t); - } - - return (l & 1 ? -1 : 1); -} - -#endif - #if FP_SMB == DIVST || !defined(STRIP) int fp_smb_divst(const fp_t a) { diff --git a/test/test_fp.c b/test/test_fp.c index 08400cb30..0a44bbd3f 100644 --- a/test/test_fp.c +++ b/test/test_fp.c @@ -936,13 +936,6 @@ static int symbol(void) { } TEST_END; #endif -#if FP_SMB == BINAR || !defined(STRIP) - TEST_CASE("binary symbol computation is correct") { - fp_rand(a); - TEST_ASSERT(fp_smb(a) == fp_smb_binar(a), end); - } TEST_END; -#endif - #if FP_SMB == DIVST || !defined(STRIP) TEST_CASE("division step symbol computation is correct") { fp_rand(a);