@@ -173,7 +173,7 @@ func requireEq(t *testing.T, exp *big.Int, got *Int, txt string) bool {
173173 return true
174174}
175175
176- func testRandomOp (t * testing.T , nativeFunc func (a , b , c * Int ), bigintFunc func (a , b , c * big.Int )) {
176+ func testRandomOp (t * testing.T , nativeFunc func (a , b , c * Int ) * Int , bigintFunc func (a , b , c * big.Int ) * big. Int ) {
177177 for i := 0 ; i < 10000 ; i ++ {
178178 b1 , f1 , err := randNums ()
179179 if err != nil {
@@ -251,38 +251,14 @@ func TestRandomSubOverflow(t *testing.T) {
251251 }
252252}
253253
254- func TestRandomSub (t * testing.T ) {
255- testRandomOp (t ,
256- func (f1 , f2 , f3 * Int ) {
257- f1 .Sub (f2 , f3 )
258- },
259- func (b1 , b2 , b3 * big.Int ) {
260- b1 .Sub (b2 , b3 )
261- },
262- )
263- }
264-
265- func TestRandomAdd (t * testing.T ) {
266- testRandomOp (t ,
267- func (f1 , f2 , f3 * Int ) {
268- f1 .Add (f2 , f3 )
269- },
270- func (b1 , b2 , b3 * big.Int ) {
271- b1 .Add (b2 , b3 )
272- },
273- )
274- }
275-
276- func TestRandomMul (t * testing.T ) {
277-
278- testRandomOp (t ,
279- func (f1 , f2 , f3 * Int ) {
280- f1 .Mul (f2 , f3 )
281- },
282- func (b1 , b2 , b3 * big.Int ) {
283- b1 .Mul (b2 , b3 )
284- },
285- )
254+ func TestRandomBinOp (t * testing.T ) {
255+ t .Run ("Add" , func (t * testing.T ) { testRandomOp (t , (* Int ).Add , (* big .Int ).Add ) })
256+ t .Run ("Sub" , func (t * testing.T ) { testRandomOp (t , (* Int ).Sub , (* big .Int ).Sub ) })
257+ t .Run ("Mul" , func (t * testing.T ) { testRandomOp (t , (* Int ).Mul , (* big .Int ).Mul ) })
258+ t .Run ("Div" , func (t * testing.T ) { testRandomOp (t , (* Int ).Div , bigDiv ) })
259+ t .Run ("Mod" , func (t * testing.T ) { testRandomOp (t , (* Int ).Mod , bigMod ) })
260+ t .Run ("SDiv" , func (t * testing.T ) { testRandomOp (t , (* Int ).SDiv , bigSDiv ) })
261+ t .Run ("SMod" , func (t * testing.T ) { testRandomOp (t , (* Int ).SMod , bigSMod ) })
286262}
287263
288264func TestRandomMulOverflow (t * testing.T ) {
@@ -309,63 +285,23 @@ func TestRandomMulOverflow(t *testing.T) {
309285
310286func TestRandomSquare (t * testing.T ) {
311287 testRandomOp (t ,
312- func (f1 , f2 , f3 * Int ) {
288+ func (f1 , f2 , f3 * Int ) * Int {
313289 f1 .squared ()
290+ return f1
314291 },
315- func (b1 , b2 , b3 * big.Int ) {
316- b1 .Mul (b1 , b1 )
317- },
318- )
319- }
320-
321- func TestRandomDiv (t * testing.T ) {
322- testRandomOp (t ,
323- func (f1 , f2 , f3 * Int ) {
324- f1 .Div (f2 , f3 )
325- },
326- func (b1 , b2 , b3 * big.Int ) {
327- if b3 .Sign () == 0 {
328- b1 .SetUint64 (0 )
329- } else {
330- b1 .Div (b2 , b3 )
331- }
332- },
333- )
334- }
335-
336- func TestRandomMod (t * testing.T ) {
337- testRandomOp (t ,
338- func (f1 , f2 , f3 * Int ) {
339- f1 .Mod (f2 , f3 )
340- },
341- func (b1 , b2 , b3 * big.Int ) {
342- if b3 .Sign () == 0 {
343- b1 .SetUint64 (0 )
344- } else {
345- b1 .Mod (b2 , b3 )
346- }
347- },
348- )
349- }
350-
351- func TestRandomSMod (t * testing.T ) {
352- testRandomOp (t ,
353- func (f1 , f2 , f3 * Int ) {
354- f1 .SMod (f2 , f3 )
355- },
356- func (b1 , b2 , b3 * big.Int ) {
357- SMod (b1 , b2 , b3 )
292+ func (b1 , b2 , b3 * big.Int ) * big.Int {
293+ return b1 .Mul (b1 , b1 )
358294 },
359295 )
360296}
361297
362298func TestRandomSqrt (t * testing.T ) {
363299 testRandomOp (t ,
364- func (f1 , f2 , f3 * Int ) {
365- f1 .Sqrt (f2 )
300+ func (f1 , f2 , f3 * Int ) * Int {
301+ return f1 .Sqrt (f2 )
366302 },
367- func (b1 , b2 , b3 * big.Int ) {
368- b1 .Sqrt (b2 )
303+ func (b1 , b2 , b3 * big.Int ) * big. Int {
304+ return b1 .Sqrt (b2 )
369305 },
370306 )
371307}
@@ -742,7 +678,7 @@ func TestRandomAbs(t *testing.T) {
742678 if err != nil {
743679 t .Fatal (err )
744680 }
745- U256 (b )
681+ u256 (b )
746682 b2 := S256 (big .NewInt (0 ).Set (b ))
747683 b2 .Abs (b2 )
748684 f1a := new (Int ).Abs (f1 )
@@ -764,20 +700,15 @@ func TestRandomSDiv(t *testing.T) {
764700 if err != nil {
765701 t .Fatal (err )
766702 }
767- U256 (b )
768- U256 (b2 )
703+ u256 (b )
704+ u256 (b2 )
769705
770706 f1a , f2a := f1 .Clone (), f2 .Clone ()
771707
772708 f1aAbs , f2aAbs := new (Int ).Abs (f1 ), new (Int ).Abs (f2 )
773709
774710 f1 .SDiv (f1 , f2 )
775- if b2 .BitLen () == 0 {
776- // zero
777- b = big .NewInt (0 )
778- } else {
779- b = SDiv (b , b , b2 )
780- }
711+ b = bigSDiv (b , b , b2 )
781712 if eq := checkEq (b , f1 ); ! eq {
782713 bf , _ := FromBig (b )
783714 t .Fatalf ("Expected equality:\n f1 = %x\n f2 = %x\n \n \n abs1= %x\n abs2= %x\n [sdiv]==\n f = %x\n bf = %x\n b = %x\n " ,
@@ -967,7 +898,7 @@ func TestAddSubUint64(t *testing.T) {
967898 bigArg , _ := new (big.Int ).SetString (tc .arg , 0 )
968899 arg , _ := FromBig (bigArg )
969900 { // SubUint64
970- want , _ := FromBig (U256 (new (big.Int ).Sub (bigArg , new (big.Int ).SetUint64 (tc .n ))))
901+ want , _ := FromBig (u256 (new (big.Int ).Sub (bigArg , new (big.Int ).SetUint64 (tc .n ))))
971902 have := new (Int ).SetAllOne ().SubUint64 (arg , tc .n )
972903 if ! have .Eq (want ) {
973904 t .Logf ("args: %s, %d\n " , tc .arg , tc .n )
@@ -977,7 +908,7 @@ func TestAddSubUint64(t *testing.T) {
977908 }
978909 }
979910 { // AddUint64
980- want , _ := FromBig (U256 (new (big.Int ).Add (bigArg , new (big.Int ).SetUint64 (tc .n ))))
911+ want , _ := FromBig (u256 (new (big.Int ).Add (bigArg , new (big.Int ).SetUint64 (tc .n ))))
981912 have := new (Int ).AddUint64 (arg , tc .n )
982913 if ! have .Eq (want ) {
983914 t .Logf ("args: %s, %d\n " , tc .arg , tc .n )
@@ -1015,29 +946,46 @@ var (
1015946 tt256m1 = new (big.Int ).Sub (bigtt256 , big .NewInt (1 ))
1016947)
1017948
1018- // U256 encodes as a 256 bit two's complement number. This operation is destructive.
1019- func U256 (x * big.Int ) * big.Int {
949+ // u256 encodes as a 256 bit two's complement number. This operation is destructive.
950+ func u256 (x * big.Int ) * big.Int {
1020951 return x .And (x , tt256m1 )
1021952}
1022953
1023- // Exp implements exponentiation by squaring.
954+ // bigExp implements exponentiation by squaring.
1024955// The result is truncated to 256 bits.
1025- func Exp (result , base , exponent * big.Int ) * big.Int {
956+ func bigExp (result , base , exponent * big.Int ) * big.Int {
1026957 result .SetUint64 (1 )
1027958
1028959 for _ , word := range exponent .Bits () {
1029960 for i := 0 ; i < wordBits ; i ++ {
1030961 if word & 1 == 1 {
1031- U256 (result .Mul (result , base ))
962+ u256 (result .Mul (result , base ))
1032963 }
1033- U256 (base .Mul (base , base ))
964+ u256 (base .Mul (base , base ))
1034965 word >>= 1
1035966 }
1036967 }
1037968 return result
1038969}
1039970
1040- func SDiv (result , x , y * big.Int ) * big.Int {
971+ // bigDiv implements uint256/EVM compatible division for big.Int: returns 0 when dividing by 0
972+ func bigDiv (z , x , y * big.Int ) * big.Int {
973+ if y .Sign () == 0 {
974+ return z .SetUint64 (0 )
975+ }
976+ return z .Div (x , y )
977+ }
978+
979+ // bigMod implements uint256/EVM compatible mod for big.Int: returns 0 when dividing by 0
980+ func bigMod (z , x , y * big.Int ) * big.Int {
981+ if y .Sign () == 0 {
982+ return z .SetUint64 (0 )
983+ }
984+ return z .Mod (x , y )
985+ }
986+
987+ // bigSDiv implements EVM-compatible SDIV operation on big.Int
988+ func bigSDiv (result , x , y * big.Int ) * big.Int {
1041989 if y .Sign () == 0 {
1042990 return result .SetUint64 (0 )
1043991 }
@@ -1055,7 +1003,8 @@ func SDiv(result, x, y *big.Int) *big.Int {
10551003 return result
10561004}
10571005
1058- func SMod (result , x , y * big.Int ) * big.Int {
1006+ // bigSMod implements EVM-compatible SMOD operation on big.Int
1007+ func bigSMod (result , x , y * big.Int ) * big.Int {
10591008 if y .Sign () == 0 {
10601009 return result .SetUint64 (0 )
10611010 }
@@ -1068,14 +1017,20 @@ func SMod(result, x, y *big.Int) *big.Int {
10681017 if neg {
10691018 result .Neg (result )
10701019 }
1071- return U256 (result )
1020+ return u256 (result )
10721021}
10731022
1074- func addMod (result , x , y , mod * big.Int ) * big.Int {
1023+ func bigAddMod (result , x , y , mod * big.Int ) * big.Int {
1024+ if mod .Sign () == 0 {
1025+ return result .SetUint64 (0 )
1026+ }
10751027 return result .Mod (result .Add (x , y ), mod )
10761028}
10771029
1078- func mulMod (result , x , y , mod * big.Int ) * big.Int {
1030+ func bigMulMod (result , x , y , mod * big.Int ) * big.Int {
1031+ if mod .Sign () == 0 {
1032+ return result .SetUint64 (0 )
1033+ }
10791034 return result .Mod (result .Mul (x , y ), mod )
10801035}
10811036
@@ -1107,7 +1062,7 @@ func TestRandomExp(t *testing.T) {
11071062 t .Fatal ("FromBig(exp) overflow" )
11081063 }
11091064
1110- b_res := Exp (new (big.Int ), b_base , b_exp )
1065+ b_res := bigExp (new (big.Int ), b_base , b_exp )
11111066 if eq := checkEq (b_res , f_res ); ! eq {
11121067 bf , _ := FromBig (b_res )
11131068 t .Fatalf ("Expected equality:\n base= %x\n exp = %x\n [ ^ ]==\n f = %x\n bf= %x\n b = %x\n " , basecopy , expcopy , f_res , bf , b_res )
@@ -1217,25 +1172,11 @@ func TestBinOp(t *testing.T) {
12171172 t .Run ("Add" , func (t * testing.T ) { proc (t , (* Int ).Add , (* big .Int ).Add ) })
12181173 t .Run ("Sub" , func (t * testing.T ) { proc (t , (* Int ).Sub , (* big .Int ).Sub ) })
12191174 t .Run ("Mul" , func (t * testing.T ) { proc (t , (* Int ).Mul , (* big .Int ).Mul ) })
1220- t .Run ("Div" , func (t * testing.T ) {
1221- proc (t , (* Int ).Div , func (z , x , y * big.Int ) * big.Int {
1222- if y .Sign () == 0 {
1223- return z .SetUint64 (0 )
1224- }
1225- return z .Div (x , y )
1226- })
1227- })
1228- t .Run ("Mod" , func (t * testing.T ) {
1229- proc (t , (* Int ).Mod , func (z , x , y * big.Int ) * big.Int {
1230- if y .Sign () == 0 {
1231- return z .SetUint64 (0 )
1232- }
1233- return z .Mod (x , y )
1234- })
1235- })
1236- t .Run ("SDiv" , func (t * testing.T ) { proc (t , (* Int ).SDiv , SDiv ) })
1237- t .Run ("SMod" , func (t * testing.T ) { proc (t , (* Int ).SMod , SMod ) })
1238- t .Run ("Exp" , func (t * testing.T ) { proc (t , (* Int ).Exp , Exp ) })
1175+ t .Run ("Div" , func (t * testing.T ) { proc (t , (* Int ).Div , bigDiv ) })
1176+ t .Run ("Mod" , func (t * testing.T ) { proc (t , (* Int ).Mod , bigMod ) })
1177+ t .Run ("SDiv" , func (t * testing.T ) { proc (t , (* Int ).SDiv , bigSDiv ) })
1178+ t .Run ("SMod" , func (t * testing.T ) { proc (t , (* Int ).SMod , bigSMod ) })
1179+ t .Run ("Exp" , func (t * testing.T ) { proc (t , (* Int ).Exp , bigExp ) })
12391180
12401181 t .Run ("And" , func (t * testing.T ) { proc (t , (* Int ).And , (* big .Int ).And ) })
12411182 t .Run ("Or" , func (t * testing.T ) { proc (t , (* Int ).Or , (* big .Int ).Or ) })
@@ -1330,30 +1271,9 @@ func TestTernOp(t *testing.T) {
13301271 }
13311272 }
13321273 }
1333- t .Run ("AddMod" , func (t * testing.T ) {
1334- proc (t , (* Int ).AddMod , func (z , x , y , m * big.Int ) * big.Int {
1335- if m .Sign () == 0 {
1336- return z .SetUint64 (0 )
1337- }
1338- return addMod (z , x , y , m )
1339- })
1340- })
1341- t .Run ("MulMod" , func (t * testing.T ) {
1342- proc (t , (* Int ).MulMod , func (z , x , y , m * big.Int ) * big.Int {
1343- if m .Sign () == 0 {
1344- return z .SetUint64 (0 )
1345- }
1346- return mulMod (z , x , y , m )
1347- })
1348- })
1349- t .Run ("MulModWithReciprocal" , func (t * testing.T ) {
1350- proc (t , (* Int ).mulModWithReciprocalWrapper , func (z , x , y , m * big.Int ) * big.Int {
1351- if m .Sign () == 0 {
1352- return z .SetUint64 (0 )
1353- }
1354- return mulMod (z , x , y , m )
1355- })
1356- })
1274+ t .Run ("AddMod" , func (t * testing.T ) { proc (t , (* Int ).AddMod , bigAddMod ) })
1275+ t .Run ("MulMod" , func (t * testing.T ) { proc (t , (* Int ).MulMod , bigMulMod ) })
1276+ t .Run ("MulModWithReciprocal" , func (t * testing.T ) { proc (t , (* Int ).mulModWithReciprocalWrapper , bigMulMod ) })
13571277}
13581278
13591279func TestCmpOp (t * testing.T ) {
0 commit comments