diff --git a/src/abstract/weierstrass.ts b/src/abstract/weierstrass.ts index bcedd98..b7192e4 100644 --- a/src/abstract/weierstrass.ts +++ b/src/abstract/weierstrass.ts @@ -943,16 +943,10 @@ export function weierstrass(curveDef: CurveType): CurveFn { const q = Point.BASE.multiply(k).toAffine(); // q = Gk const r = modN(q.x); // r = q.x mod n if (r === _0n) return; - // X blinding according to https://tches.iacr.org/index.php/TCHES/article/view/7337/6509 - // b * m + b * r * d ∈ [0,q−1] exposed via side-channel, but d (private scalar) is not. - // NOTE: there is still probable some leak in multiplication, since it is not constant-time - const b = ut.bytesToNumberBE(utils.randomPrivateKey()); // random scalar, b ∈ [1,q−1] - const bi = invN(b); // b^-1 - const bdr = modN(b * d * r); // b * d * r - const bm = modN(b * m); // b * m - const mrx = modN(bi * modN(bdr + bm)); // b^-1(bm + bdr) -> m + rd - - const s = modN(ik * mrx); // s = k^-1(m + rd) mod n + // Can use scalar blinding b^-1(bm + bdr) where b ∈ [1,q−1] according to + // https://tches.iacr.org/index.php/TCHES/article/view/7337/6509. We've decided against it: + // a) dependency on CSPRNG b) 15% slowdown c) doesn't really help since bigints are not CT + const s = modN(ik * modN(m + r * d)); // Not using blinding here if (s === _0n) return; let recovery = (q.x === r ? 0 : 2) | Number(q.y & _1n); // recovery bit (2 or 3, when q.x > n) let normS = s;