github.com/neatlab/neatio@v1.7.3-0.20220425043230-d903e92fcc75/utilities/common/math/big_test.go (about) 1 package math 2 3 import ( 4 "bytes" 5 "encoding/hex" 6 "math/big" 7 "testing" 8 9 "github.com/neatlab/neatio/utilities/common" 10 ) 11 12 func TestHexOrDecimal256(t *testing.T) { 13 tests := []struct { 14 input string 15 num *big.Int 16 ok bool 17 }{ 18 {"", big.NewInt(0), true}, 19 {"0", big.NewInt(0), true}, 20 {"0x0", big.NewInt(0), true}, 21 {"12345678", big.NewInt(12345678), true}, 22 {"0x12345678", big.NewInt(0x12345678), true}, 23 {"0X12345678", big.NewInt(0x12345678), true}, 24 25 {"0123456789", big.NewInt(123456789), true}, 26 {"00", big.NewInt(0), true}, 27 {"0x00", big.NewInt(0), true}, 28 {"0x012345678abc", big.NewInt(0x12345678abc), true}, 29 30 {"abcdef", nil, false}, 31 {"0xgg", nil, false}, 32 33 {"115792089237316195423570985008687907853269984665640564039457584007913129639936", nil, false}, 34 } 35 for _, test := range tests { 36 var num HexOrDecimal256 37 err := num.UnmarshalText([]byte(test.input)) 38 if (err == nil) != test.ok { 39 t.Errorf("ParseBig(%q) -> (err == nil) == %t, want %t", test.input, err == nil, test.ok) 40 continue 41 } 42 if test.num != nil && (*big.Int)(&num).Cmp(test.num) != 0 { 43 t.Errorf("ParseBig(%q) -> %d, want %d", test.input, (*big.Int)(&num), test.num) 44 } 45 } 46 } 47 48 func TestMustParseBig256(t *testing.T) { 49 defer func() { 50 if recover() == nil { 51 t.Error("MustParseBig should've panicked") 52 } 53 }() 54 MustParseBig256("ggg") 55 } 56 57 func TestBigMax(t *testing.T) { 58 a := big.NewInt(10) 59 b := big.NewInt(5) 60 61 max1 := BigMax(a, b) 62 if max1 != a { 63 t.Errorf("Expected %d got %d", a, max1) 64 } 65 66 max2 := BigMax(b, a) 67 if max2 != a { 68 t.Errorf("Expected %d got %d", a, max2) 69 } 70 } 71 72 func TestBigMin(t *testing.T) { 73 a := big.NewInt(10) 74 b := big.NewInt(5) 75 76 min1 := BigMin(a, b) 77 if min1 != b { 78 t.Errorf("Expected %d got %d", b, min1) 79 } 80 81 min2 := BigMin(b, a) 82 if min2 != b { 83 t.Errorf("Expected %d got %d", b, min2) 84 } 85 } 86 87 func TestFirstBigSet(t *testing.T) { 88 tests := []struct { 89 num *big.Int 90 ix int 91 }{ 92 {big.NewInt(0), 0}, 93 {big.NewInt(1), 0}, 94 {big.NewInt(2), 1}, 95 {big.NewInt(0x100), 8}, 96 } 97 for _, test := range tests { 98 if ix := FirstBitSet(test.num); ix != test.ix { 99 t.Errorf("FirstBitSet(b%b) = %d, want %d", test.num, ix, test.ix) 100 } 101 } 102 } 103 104 func TestPaddedBigBytes(t *testing.T) { 105 tests := []struct { 106 num *big.Int 107 n int 108 result []byte 109 }{ 110 {num: big.NewInt(0), n: 4, result: []byte{0, 0, 0, 0}}, 111 {num: big.NewInt(1), n: 4, result: []byte{0, 0, 0, 1}}, 112 {num: big.NewInt(512), n: 4, result: []byte{0, 0, 2, 0}}, 113 {num: BigPow(2, 32), n: 4, result: []byte{1, 0, 0, 0, 0}}, 114 } 115 for _, test := range tests { 116 if result := PaddedBigBytes(test.num, test.n); !bytes.Equal(result, test.result) { 117 t.Errorf("PaddedBigBytes(%d, %d) = %v, want %v", test.num, test.n, result, test.result) 118 } 119 } 120 } 121 122 func BenchmarkPaddedBigBytesLargePadding(b *testing.B) { 123 bigint := MustParseBig256("123456789123456789123456789123456789") 124 for i := 0; i < b.N; i++ { 125 PaddedBigBytes(bigint, 200) 126 } 127 } 128 129 func BenchmarkPaddedBigBytesSmallPadding(b *testing.B) { 130 bigint := MustParseBig256("0x18F8F8F1000111000110011100222004330052300000000000000000FEFCF3CC") 131 for i := 0; i < b.N; i++ { 132 PaddedBigBytes(bigint, 5) 133 } 134 } 135 136 func BenchmarkPaddedBigBytesSmallOnePadding(b *testing.B) { 137 bigint := MustParseBig256("0x18F8F8F1000111000110011100222004330052300000000000000000FEFCF3CC") 138 for i := 0; i < b.N; i++ { 139 PaddedBigBytes(bigint, 32) 140 } 141 } 142 143 func BenchmarkByteAtBrandNew(b *testing.B) { 144 bigint := MustParseBig256("0x18F8F8F1000111000110011100222004330052300000000000000000FEFCF3CC") 145 for i := 0; i < b.N; i++ { 146 bigEndianByteAt(bigint, 15) 147 } 148 } 149 150 func BenchmarkByteAt(b *testing.B) { 151 bigint := MustParseBig256("0x18F8F8F1000111000110011100222004330052300000000000000000FEFCF3CC") 152 for i := 0; i < b.N; i++ { 153 bigEndianByteAt(bigint, 15) 154 } 155 } 156 157 func BenchmarkByteAtOld(b *testing.B) { 158 159 bigint := MustParseBig256("0x18F8F8F1000111000110011100222004330052300000000000000000FEFCF3CC") 160 for i := 0; i < b.N; i++ { 161 PaddedBigBytes(bigint, 32) 162 } 163 } 164 165 func TestReadBits(t *testing.T) { 166 check := func(input string) { 167 want, _ := hex.DecodeString(input) 168 int, _ := new(big.Int).SetString(input, 16) 169 buf := make([]byte, len(want)) 170 ReadBits(int, buf) 171 if !bytes.Equal(buf, want) { 172 t.Errorf("have: %x\nwant: %x", buf, want) 173 } 174 } 175 check("000000000000000000000000000000000000000000000000000000FEFCF3F8F0") 176 check("0000000000012345000000000000000000000000000000000000FEFCF3F8F0") 177 check("18F8F8F1000111000110011100222004330052300000000000000000FEFCF3F8F0") 178 } 179 180 func TestU256(t *testing.T) { 181 tests := []struct{ x, y *big.Int }{ 182 {x: big.NewInt(0), y: big.NewInt(0)}, 183 {x: big.NewInt(1), y: big.NewInt(1)}, 184 {x: BigPow(2, 255), y: BigPow(2, 255)}, 185 {x: BigPow(2, 256), y: big.NewInt(0)}, 186 {x: new(big.Int).Add(BigPow(2, 256), big.NewInt(1)), y: big.NewInt(1)}, 187 188 {x: big.NewInt(-1), y: new(big.Int).Sub(BigPow(2, 256), big.NewInt(1))}, 189 {x: big.NewInt(-2), y: new(big.Int).Sub(BigPow(2, 256), big.NewInt(2))}, 190 {x: BigPow(2, -255), y: big.NewInt(1)}, 191 } 192 for _, test := range tests { 193 if y := U256(new(big.Int).Set(test.x)); y.Cmp(test.y) != 0 { 194 t.Errorf("U256(%x) = %x, want %x", test.x, y, test.y) 195 } 196 } 197 } 198 199 func TestBigEndianByteAt(t *testing.T) { 200 tests := []struct { 201 x string 202 y int 203 exp byte 204 }{ 205 {"00", 0, 0x00}, 206 {"01", 1, 0x00}, 207 {"00", 1, 0x00}, 208 {"01", 0, 0x01}, 209 {"0000000000000000000000000000000000000000000000000000000000102030", 0, 0x30}, 210 {"0000000000000000000000000000000000000000000000000000000000102030", 1, 0x20}, 211 {"ABCDEF0908070605040302010000000000000000000000000000000000000000", 31, 0xAB}, 212 {"ABCDEF0908070605040302010000000000000000000000000000000000000000", 32, 0x00}, 213 {"ABCDEF0908070605040302010000000000000000000000000000000000000000", 500, 0x00}, 214 } 215 for _, test := range tests { 216 v := new(big.Int).SetBytes(common.Hex2Bytes(test.x)) 217 actual := bigEndianByteAt(v, test.y) 218 if actual != test.exp { 219 t.Fatalf("Expected [%v] %v:th byte to be %v, was %v.", test.x, test.y, test.exp, actual) 220 } 221 222 } 223 } 224 func TestLittleEndianByteAt(t *testing.T) { 225 tests := []struct { 226 x string 227 y int 228 exp byte 229 }{ 230 {"00", 0, 0x00}, 231 {"01", 1, 0x00}, 232 {"00", 1, 0x00}, 233 {"01", 0, 0x00}, 234 {"0000000000000000000000000000000000000000000000000000000000102030", 0, 0x00}, 235 {"0000000000000000000000000000000000000000000000000000000000102030", 1, 0x00}, 236 {"ABCDEF0908070605040302010000000000000000000000000000000000000000", 31, 0x00}, 237 {"ABCDEF0908070605040302010000000000000000000000000000000000000000", 32, 0x00}, 238 {"ABCDEF0908070605040302010000000000000000000000000000000000000000", 0, 0xAB}, 239 {"ABCDEF0908070605040302010000000000000000000000000000000000000000", 1, 0xCD}, 240 {"00CDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff", 0, 0x00}, 241 {"00CDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff", 1, 0xCD}, 242 {"0000000000000000000000000000000000000000000000000000000000102030", 31, 0x30}, 243 {"0000000000000000000000000000000000000000000000000000000000102030", 30, 0x20}, 244 {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 32, 0x0}, 245 {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 31, 0xFF}, 246 {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 0xFFFF, 0x0}, 247 } 248 for _, test := range tests { 249 v := new(big.Int).SetBytes(common.Hex2Bytes(test.x)) 250 actual := Byte(v, 32, test.y) 251 if actual != test.exp { 252 t.Fatalf("Expected [%v] %v:th byte to be %v, was %v.", test.x, test.y, test.exp, actual) 253 } 254 255 } 256 } 257 258 func TestS256(t *testing.T) { 259 tests := []struct{ x, y *big.Int }{ 260 {x: big.NewInt(0), y: big.NewInt(0)}, 261 {x: big.NewInt(1), y: big.NewInt(1)}, 262 {x: big.NewInt(2), y: big.NewInt(2)}, 263 { 264 x: new(big.Int).Sub(BigPow(2, 255), big.NewInt(1)), 265 y: new(big.Int).Sub(BigPow(2, 255), big.NewInt(1)), 266 }, 267 { 268 x: BigPow(2, 255), 269 y: new(big.Int).Neg(BigPow(2, 255)), 270 }, 271 { 272 x: new(big.Int).Sub(BigPow(2, 256), big.NewInt(1)), 273 y: big.NewInt(-1), 274 }, 275 { 276 x: new(big.Int).Sub(BigPow(2, 256), big.NewInt(2)), 277 y: big.NewInt(-2), 278 }, 279 } 280 for _, test := range tests { 281 if y := S256(test.x); y.Cmp(test.y) != 0 { 282 t.Errorf("S256(%x) = %x, want %x", test.x, y, test.y) 283 } 284 } 285 } 286 287 func TestExp(t *testing.T) { 288 tests := []struct{ base, exponent, result *big.Int }{ 289 {base: big.NewInt(0), exponent: big.NewInt(0), result: big.NewInt(1)}, 290 {base: big.NewInt(1), exponent: big.NewInt(0), result: big.NewInt(1)}, 291 {base: big.NewInt(1), exponent: big.NewInt(1), result: big.NewInt(1)}, 292 {base: big.NewInt(1), exponent: big.NewInt(2), result: big.NewInt(1)}, 293 {base: big.NewInt(3), exponent: big.NewInt(144), result: MustParseBig256("507528786056415600719754159741696356908742250191663887263627442114881")}, 294 {base: big.NewInt(2), exponent: big.NewInt(255), result: MustParseBig256("57896044618658097711785492504343953926634992332820282019728792003956564819968")}, 295 } 296 for _, test := range tests { 297 if result := Exp(test.base, test.exponent); result.Cmp(test.result) != 0 { 298 t.Errorf("Exp(%d, %d) = %d, want %d", test.base, test.exponent, result, test.result) 299 } 300 } 301 }