From 90e87f7ab1dd087cf11fc11222040358418c5666 Mon Sep 17 00:00:00 2001 From: Paul Miller Date: Sat, 6 May 2023 12:38:53 +0000 Subject: [PATCH] weierstrass: adjust SWUFpSqrtRatio to not use exp operator --- src/abstract/weierstrass.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/abstract/weierstrass.ts b/src/abstract/weierstrass.ts index f70c07a..5981ca4 100644 --- a/src/abstract/weierstrass.ts +++ b/src/abstract/weierstrass.ts @@ -1107,10 +1107,14 @@ export function SWUFpSqrtRatio(Fp: mod.IField, Z: T) { let l = _0n; for (let o = q - _1n; o % _2n === _0n; o /= _2n) l += _1n; const c1 = l; // 1. c1, the largest integer such that 2^c1 divides q - 1. - const c2 = (q - _1n) / _2n ** c1; // 2. c2 = (q - 1) / (2^c1) # Integer arithmetic + // We need 2n ** c1 and 2n ** (c1-1). We can't use **; but we can use <<. + // 2n ** c1 == 2n << (c1-1) + const _2n_pow_c1_1 = _2n << (c1 - _1n - _1n); + const _2n_pow_c1 = _2n_pow_c1_1 * _2n; + const c2 = (q - _1n) / _2n_pow_c1; // 2. c2 = (q - 1) / (2^c1) # Integer arithmetic const c3 = (c2 - _1n) / _2n; // 3. c3 = (c2 - 1) / 2 # Integer arithmetic - const c4 = _2n ** c1 - _1n; // 4. c4 = 2^c1 - 1 # Integer arithmetic - const c5 = _2n ** (c1 - _1n); // 5. c5 = 2^(c1 - 1) # Integer arithmetic + const c4 = _2n_pow_c1 - _1n; // 4. c4 = 2^c1 - 1 # Integer arithmetic + const c5 = _2n_pow_c1_1; // 5. c5 = 2^(c1 - 1) # Integer arithmetic const c6 = Fp.pow(Z, c2); // 6. c6 = Z^c2 const c7 = Fp.pow(Z, (c2 + _1n) / _2n); // 7. c7 = Z^((c2 + 1) / 2) let sqrtRatio = (u: T, v: T): { isValid: boolean; value: T } => { @@ -1132,7 +1136,8 @@ export function SWUFpSqrtRatio(Fp: mod.IField, Z: T) { tv4 = Fp.cmov(tv5, tv4, isQR); // 16. tv4 = CMOV(tv5, tv4, isQR) // 17. for i in (c1, c1 - 1, ..., 2): for (let i = c1; i > _1n; i--) { - let tv5 = _2n ** (i - _2n); // 18. tv5 = i - 2; 19. tv5 = 2^tv5 + let tv5 = i - _2n; // 18. tv5 = i - 2 + tv5 = _2n << (tv5 - _1n); // 19. tv5 = 2^tv5 let tvv5 = Fp.pow(tv4, tv5); // 20. tv5 = tv4^tv5 const e1 = Fp.eql(tvv5, Fp.ONE); // 21. e1 = tv5 == 1 tv2 = Fp.mul(tv3, tv1); // 22. tv2 = tv3 * tv1