@@ -60,7 +60,7 @@ func (c *ecrecoverCircuit) Define(api frontend.API) error {
6060 return nil
6161}
6262
63- func testRoutineECRecover (t * testing.T , wantStrict bool ) (circ , wit * ecrecoverCircuit , largeS bool ) {
63+ func testRoutineECRecover (t * testing.T , forceLargeS bool ) (circ , wit * ecrecoverCircuit ) {
6464 halfFr := new (big.Int ).Sub (fr .Modulus (), big .NewInt (1 ))
6565 halfFr .Div (halfFr , big .NewInt (2 ))
6666
@@ -72,18 +72,22 @@ func testRoutineECRecover(t *testing.T, wantStrict bool) (circ, wit *ecrecoverCi
7272 msg := []byte ("test" )
7373 var r , s * big.Int
7474 var v uint
75- for {
76- v , r , s , err = sk .SignForRecover (msg , nil )
77- if err != nil {
78- t .Fatal ("sign" , err )
79- }
80- if ! wantStrict || halfFr .Cmp (s ) > 0 {
81- break
82- }
75+ v , r , s , err = sk .SignForRecover (msg , nil )
76+ if err != nil {
77+ t .Fatal ("sign" , err )
8378 }
84- strict := 0
85- if wantStrict {
86- strict = 1
79+ // SignForRecover always returns s < r_mod/2. But in the tests we want
80+ // to check that the circuit fails when s > r_mod/2 in strict mode.
81+ if forceLargeS {
82+ // first we make s large
83+ s .Sub (fr .Modulus (), s )
84+ // but we also have to swap the sign of the recovered public key
85+ v ^= 1
86+ }
87+
88+ strict := 1
89+ if forceLargeS {
90+ strict = 0
8791 }
8892 circuit := ecrecoverCircuit {}
8993 witness := ecrecoverCircuit {
@@ -98,19 +102,19 @@ func testRoutineECRecover(t *testing.T, wantStrict bool) (circ, wit *ecrecoverCi
98102 Y : emulated.ValueOf [emulated.Secp256k1Fp ](pk .A .Y ),
99103 },
100104 }
101- return & circuit , & witness , halfFr . Cmp ( s ) <= 0
105+ return & circuit , & witness
102106}
103107
104108func TestECRecoverCircuitShortStrict (t * testing.T ) {
105109 assert := test .NewAssert (t )
106- circuit , witness , _ := testRoutineECRecover (t , true )
110+ circuit , witness := testRoutineECRecover (t , false )
107111 err := test .IsSolved (circuit , witness , ecc .BN254 .ScalarField ())
108112 assert .NoError (err )
109113}
110114
111115func TestECRecoverCircuitShortLax (t * testing.T ) {
112116 assert := test .NewAssert (t )
113- circuit , witness , _ := testRoutineECRecover (t , false )
117+ circuit , witness := testRoutineECRecover (t , true )
114118 err := test .IsSolved (circuit , witness , ecc .BN254 .ScalarField ())
115119 assert .NoError (err )
116120}
@@ -120,25 +124,21 @@ func TestECRecoverCircuitShortMismatch(t *testing.T) {
120124 halfFr := new (big.Int ).Sub (fr .Modulus (), big .NewInt (1 ))
121125 halfFr .Div (halfFr , big .NewInt (2 ))
122126 var circuit , witness * ecrecoverCircuit
123- var largeS bool
124- for {
125- circuit , witness , largeS = testRoutineECRecover (t , false )
126- if largeS {
127- witness .Strict = 1
128- break
129- }
130- }
127+ circuit , witness = testRoutineECRecover (t , true )
128+ witness .Strict = 1
131129 err := test .IsSolved (circuit , witness , ecc .BN254 .ScalarField ())
132130 assert .Error (err )
133131}
134132
135133func TestECRecoverCircuitFull (t * testing.T ) {
136134 assert := test .NewAssert (t )
137- circuit , witness , _ := testRoutineECRecover (t , false )
135+ circuit , witness := testRoutineECRecover (t , false )
136+ _ , witness2 := testRoutineECRecover (t , true )
138137
139138 assert .CheckCircuit (
140139 circuit ,
141140 test .WithValidAssignment (witness ),
141+ test .WithValidAssignment (witness2 ),
142142 test .WithCurves (ecc .BN254 , ecc .BLS12_377 ),
143143 test .NoProverChecks (),
144144 )
@@ -256,10 +256,14 @@ func TestECRecoverInfinityWoFailure(t *testing.T) {
256256
257257func TestInvalidFailureTag (t * testing.T ) {
258258 assert := test .NewAssert (t )
259- circuit , witness , _ := testRoutineECRecover (t , false )
259+ circuit , witness := testRoutineECRecover (t , false )
260260 witness .IsFailure = 1
261261 err := test .IsSolved (circuit , witness , ecc .BN254 .ScalarField ())
262262 assert .Error (err )
263+ _ , witness2 := testRoutineECRecover (t , true )
264+ witness2 .IsFailure = 1
265+ err = test .IsSolved (circuit , witness2 , ecc .BN254 .ScalarField ())
266+ assert .Error (err )
263267}
264268
265269func TestLargeV (t * testing.T ) {
0 commit comments