From 6ecfbb5ac85cd4d784ff347fb04bffb3d11df013 Mon Sep 17 00:00:00 2001 From: CPerezz Date: Tue, 20 Jun 2023 09:09:23 +0200 Subject: [PATCH 1/2] Fix secp256r1 consts to pass tests --- src/secp256r1/fq.rs | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/src/secp256r1/fq.rs b/src/secp256r1/fq.rs index c23ae262..d628a96e 100644 --- a/src/secp256r1/fq.rs +++ b/src/secp256r1/fq.rs @@ -82,21 +82,21 @@ const R3: Fq = Fq([ const GENERATOR: Fq = Fq::from_raw([0x07, 0x00, 0x00, 0x00]); /// GENERATOR^t where t * 2^s + 1 = r with t odd. In other words, this is a 2^s root of unity. -/// `ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550` +/// `ffc97f062a770992ba807ace842a3dfc1546cad004378daf0592d7fbb41e6602` const ROOT_OF_UNITY: Fq = Fq::from_raw([ - 0xf3b9cac2fc632550, - 0xbce6faada7179e84, - 0xffffffffffffffff, - 0xffffffff00000000, + 0x0592d7fbb41e6602, + 0x1546cad004378daf, + 0xba807ace842a3dfc, + 0xffc97f062a770992, ]); /// 1 / ROOT_OF_UNITY mod q -/// `ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550` +/// `a0a66a5562d46f2ac645fa0458131caee3ac117c794c4137379c7f0657c73764` const ROOT_OF_UNITY_INV: Fq = Fq::from_raw([ - 0xf3b9cac2fc632550, - 0xbce6faada7179e84, - 0xffffffffffffffff, - 0xffffffff00000000, + 0x379c7f0657c73764, + 0xe3ac117c794c4137, + 0xc645fa0458131cae, + 0xa0a66a5562d46f2a, ]); /// 1 / 2 mod q @@ -116,7 +116,7 @@ const ZETA: Fq = Fq::from_raw([ /// Generator of the t-order multiplicative subgroup. /// Computed by exponentiating Self::MULTIPLICATIVE_GENERATOR by 2^s, where s is Self::S. -const DELTA: Fq = Fq::from_raw([0x31, 0, 0, 0]); +const DELTA: Fq = Fq::from_raw([0x1e39a5057d81, 0, 0, 0]); use crate::{ field_arithmetic, field_common, field_specific, impl_add_binop_specify_output, @@ -206,11 +206,12 @@ impl ff::Field for Fq { } fn sqrt(&self) -> CtOption { + // 7fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a let tm1d2 = [ - 0x18541eb9ddbdf752, - 0xd6105cac886ec313, - 0x9fffffffffffffff, - 0x9fffffff60000000, + 0x279dce5617e3192a, + 0xfde737d56d38bcf4, + 0x07ffffffffffffff, + 0x7fffffff8000000, ]; ff::helpers::sqrt_tonelli_shanks(self, &tm1d2) @@ -232,7 +233,7 @@ impl ff::PrimeField for Fq { const ROOT_OF_UNITY_INV: Self = ROOT_OF_UNITY_INV; const TWO_INV: Self = TWO_INV; const DELTA: Self = DELTA; - const S: u32 = 1; + const S: u32 = 4; fn from_repr(repr: Self::Repr) -> CtOption { let mut tmp = Fq([0, 0, 0, 0]); From 5a6256c00815bfc9b3c2d087ce8a161350bba45d Mon Sep 17 00:00:00 2001 From: CPerezz Date: Tue, 20 Jun 2023 15:01:02 +0200 Subject: [PATCH 2/2] fix: Handle no reduction case needed in montgomery asm As said by @han0110: > It's because the montgomery_reduction hardcoded in from_raw is only for sparse field (higest carry will always be 0), but we shuold just hartdcode dense field version to cover all cases. And it should be fine since from_raw is usually used for constly initialize some constants. Co-authored-by: Han --- src/derive/field.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/derive/field.rs b/src/derive/field.rs index 5e7dd78b..e6f87ff4 100644 --- a/src/derive/field.rs +++ b/src/derive/field.rs @@ -82,7 +82,7 @@ macro_rules! field_common { let (r5, carry) = mac(r5, val[3], $r2.0[2], carry); let (r6, r7) = mac(r6, val[3], $r2.0[3], carry); - // Montgomery reduction (first part) + // Montgomery reduction let k = r0.wrapping_mul($inv); let (_, carry) = mac(r0, k, $modulus.0[0], 0); let (r1, carry) = mac(r1, k, $modulus.0[1], carry); @@ -109,14 +109,14 @@ macro_rules! field_common { let (r4, carry) = mac(r4, k, $modulus.0[1], carry); let (r5, carry) = mac(r5, k, $modulus.0[2], carry); let (r6, carry) = mac(r6, k, $modulus.0[3], carry); - let (r7, _) = adc(r7, carry2, carry); + let (r7, carry2) = adc(r7, carry2, carry); - // Montgomery reduction (sub part) + // Result may be within MODULUS of the correct value let (d0, borrow) = sbb(r4, $modulus.0[0], 0); let (d1, borrow) = sbb(r5, $modulus.0[1], borrow); let (d2, borrow) = sbb(r6, $modulus.0[2], borrow); let (d3, borrow) = sbb(r7, $modulus.0[3], borrow); - + let (_, borrow) = sbb(carry2, 0, borrow); let (d0, carry) = adc(d0, $modulus.0[0] & borrow, 0); let (d1, carry) = adc(d1, $modulus.0[1] & borrow, carry); let (d2, carry) = adc(d2, $modulus.0[2] & borrow, carry);