11package ecgfp5
22
33import (
4+ "math/big"
45 "testing"
56
67 g "github.com/elliottech/poseidon_crypto/field/goldilocks"
@@ -24,6 +25,40 @@ func TestSerdes(t *testing.T) {
2425 }
2526}
2627
28+ func TestScalarElementFromLittleEndianBytesReduces (t * testing.T ) {
29+ // Create a byte array that represents a scalar larger than the order
30+ bigScalar := new (big.Int ).Add (ORDER , big .NewInt (1234567890 ))
31+ leBytes := bigScalar .Bytes ()
32+ s := ScalarElementFromLittleEndianBytes (leBytes )
33+
34+ if ToNonCanonicalBigInt (s ).Cmp (ORDER ) != - 1 {
35+ t .Fatalf ("Expected scalar to be reduced modulo order, but got %v" , ToNonCanonicalBigInt (s ))
36+ }
37+ }
38+
39+ func FuzzSerdes (f * testing.F ) {
40+ f .Add ([]byte {1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25 , 26 , 27 , 28 , 29 , 30 , 31 , 32 , 33 , 34 , 35 , 36 , 37 , 38 , 39 , 40 })
41+ f .Add (ORDER .Bytes ())
42+
43+ f .Fuzz (func (t * testing.T , a []byte ) {
44+ // take 40 bytes only
45+ if len (a ) > 40 {
46+ a = a [:40 ]
47+ } else if len (a ) < 40 {
48+ // pad with zeros
49+ a = append (a , make ([]byte , 40 - len (a ))... )
50+ }
51+ s := ScalarElementFromLittleEndianBytes (a )
52+
53+ b := s .ToLittleEndianBytes ()
54+ ss := ScalarElementFromLittleEndianBytes (b )
55+
56+ if ! s .Equals (ss ) {
57+ t .Fatalf ("Serdes mismatch: %v != %v" , s , ss )
58+ }
59+ })
60+ }
61+
2762func TestSplitTo4LimbBits (t * testing.T ) {
2863 scalar := ECgFp5Scalar {
2964 6950590877883398434 ,
@@ -120,12 +155,31 @@ func TestAddScalar(t *testing.T) {
120155 }
121156}
122157
158+ func FuzzAddScalar (f * testing.F ) {
159+ f .Add ([]byte {1 , 2 , 3 , 4 }, []byte {5 , 6 , 7 , 8 })
160+ f .Add (ORDER .Bytes (), ORDER .Bytes ())
161+
162+ f .Fuzz (func (t * testing.T , a []byte , b []byte ) {
163+ aBig := new (big.Int ).SetBytes (a )
164+ scalar1 := FromNonCanonicalBigInt (aBig )
165+ bBig := new (big.Int ).SetBytes (b )
166+ scalar2 := FromNonCanonicalBigInt (bBig )
167+
168+ result := scalar1 .Add (scalar2 )
169+ resultBig := FromNonCanonicalBigInt (new (big.Int ).Add (aBig , bBig ))
170+
171+ if ! result .Equals (resultBig ) {
172+ t .Fatalf ("Addition mismatch: %v + %v != %v" , scalar1 , scalar2 , result )
173+ }
174+ })
175+ }
176+
123177func TestSub (t * testing.T ) {
124178 scalar1 := ECgFp5Scalar {1 , 2 , 0 , 0 , 0 }
125- scalar2 := ECgFp5Scalar {0xFFFFFFFFFFFFFFFF , 0xFFFFFFFFFFFFFFFF , 0xFFFFFFFFFFFFFFFF , 0xFFFFFFFFFFFFFFFF , 0xFFFFFFFFFFFFFFFF }
179+ scalar2 := ECgFp5Scalar {0xFFFFFFFFFFFFFFFF , 0xFFFFFFFFFFFFFFFF , 0xFFFFFFFFFFFFFFFF , 0xFFFFFFFFFFFFFFFF , 0x0FFFFFFFFFFFFFFF }
126180
127181 result := scalar1 .Sub (scalar2 )
128- expectedValues := ECgFp5Scalar {0xe80fd996948bffe3 , 0xe8885c39d724a09e , 0x7fffffe6cfb80639 , 0x7ffffff100000016 , 0x7ffffffd80000007 }
182+ expectedValues := ECgFp5Scalar {0xe80fd996948bffe3 , 0xe8885c39d724a09e , 0x7fffffe6cfb80639 , 0x7ffffff100000016 , 8070450521510510599 }
129183
130184 for i := 0 ; i < 5 ; i ++ {
131185 if result [i ] != expectedValues [i ] {
@@ -134,6 +188,25 @@ func TestSub(t *testing.T) {
134188 }
135189}
136190
191+ func FuzzSubScalar (f * testing.F ) {
192+ f .Add ([]byte {1 , 2 , 3 , 4 }, []byte {5 , 6 , 7 , 8 })
193+ f .Add (ORDER .Bytes (), ORDER .Bytes ())
194+
195+ f .Fuzz (func (t * testing.T , a []byte , b []byte ) {
196+ aBig := new (big.Int ).SetBytes (a )
197+ scalar1 := FromNonCanonicalBigInt (aBig )
198+ bBig := new (big.Int ).SetBytes (b )
199+ scalar2 := FromNonCanonicalBigInt (bBig )
200+
201+ result := scalar1 .Sub (scalar2 )
202+ resultBig := FromNonCanonicalBigInt (new (big.Int ).Sub (aBig , bBig ))
203+
204+ if ! result .Equals (resultBig ) {
205+ t .Fatalf ("Subtraction mismatch: %v - %v != %v" , scalar1 , scalar2 , result )
206+ }
207+ })
208+ }
209+
137210func TestSelect (t * testing.T ) {
138211 a0 := ECgFp5Scalar {1 , 2 , 3 , 4 , 5 }
139212 a1 := ECgFp5Scalar {0xFFFFFFFFFFFFFFFF , 0xFFFFFFFFFFFFFFFE , 0xFFFFFFFFFFFFFFFD , 0xFFFFFFFFFFFFFFFC , 0xFFFFFFFFFFFFFFFB }
@@ -155,7 +228,7 @@ func TestSelect(t *testing.T) {
155228
156229func TestMontyMul (t * testing.T ) {
157230 scalar1 := ECgFp5Scalar {1 , 2 , 3 , 4 , 5 }
158- scalar2 := ECgFp5Scalar {0xFFFFFFFFFFFFFFFF , 0xFFFFFFFFFFFFFFFF , 0xFFFFFFFFFFFFFFFF , 0xFFFFFFFFFFFFFFFF , 0xFFFFFFFFFFFFFFFF }
231+ scalar2 := ECgFp5Scalar {0xFFFFFFFFFFFFFFFF , 0xFFFFFFFFFFFFFFFF , 0xFFFFFFFFFFFFFFFF , 0xFFFFFFFFFFFFFFFF , 0xFFFFFFFFFFFFFFFF } // montymul can work with non-canonical inputs
159232
160233 result := scalar1 .MontyMul (scalar2 )
161234 expectedValues := ECgFp5Scalar {10974894505036100890 , 7458803775930281466 , 744239893213209819 , 3396127080529349464 , 5979369289905897562 }
@@ -192,6 +265,25 @@ func TestMul(t *testing.T) {
192265 }
193266}
194267
268+ func FuzzMulScalar (f * testing.F ) {
269+ f .Add ([]byte {1 , 2 , 3 , 4 }, []byte {5 , 6 , 7 , 8 })
270+ f .Add (ORDER .Bytes (), ORDER .Bytes ())
271+
272+ f .Fuzz (func (t * testing.T , a []byte , b []byte ) {
273+ aBig := new (big.Int ).SetBytes (a )
274+ scalar1 := FromNonCanonicalBigInt (aBig )
275+ bBig := new (big.Int ).SetBytes (b )
276+ scalar2 := FromNonCanonicalBigInt (bBig )
277+
278+ result := scalar1 .Mul (scalar2 )
279+ resultBig := FromNonCanonicalBigInt (new (big.Int ).Mul (aBig , bBig ))
280+
281+ if ! result .Equals (resultBig ) {
282+ t .Fatalf ("Multiplication mismatch: %v * %v != %v" , scalar1 , scalar2 , result )
283+ }
284+ })
285+ }
286+
195287func TestRecodeSigned (t * testing.T ) {
196288 var ss [50 ]int32
197289 scalar := ECgFp5Scalar {
0 commit comments