github.com/klaytn/klaytn@v1.12.1/common/math/big_test.go (about) 1 // Modifications Copyright 2018 The klaytn Authors 2 // Copyright 2017 The go-ethereum Authors 3 // This file is part of the go-ethereum library. 4 // 5 // The go-ethereum library is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // The go-ethereum library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public License 16 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 17 // 18 // This file is derived from common/math/big_test.go (2018/06/04). 19 // Modified and improved for the klaytn development. 20 21 package math 22 23 import ( 24 "bytes" 25 "encoding/hex" 26 "math/big" 27 "testing" 28 29 "github.com/klaytn/klaytn/common" 30 ) 31 32 func TestHexOrDecimal256(t *testing.T) { 33 tests := []struct { 34 input string 35 num *big.Int 36 ok bool 37 }{ 38 {"", big.NewInt(0), true}, 39 {"0", big.NewInt(0), true}, 40 {"0x0", big.NewInt(0), true}, 41 {"12345678", big.NewInt(12345678), true}, 42 {"0x12345678", big.NewInt(0x12345678), true}, 43 {"0X12345678", big.NewInt(0x12345678), true}, 44 // Tests for leading zero behaviour: 45 {"0123456789", big.NewInt(123456789), true}, // note: not octal 46 {"00", big.NewInt(0), true}, 47 {"0x00", big.NewInt(0), true}, 48 {"0x012345678abc", big.NewInt(0x12345678abc), true}, 49 // Invalid syntax: 50 {"abcdef", nil, false}, 51 {"0xgg", nil, false}, 52 // Larger than 256 bits: 53 {"115792089237316195423570985008687907853269984665640564039457584007913129639936", nil, false}, 54 } 55 for _, test := range tests { 56 var num HexOrDecimal256 57 err := num.UnmarshalText([]byte(test.input)) 58 if (err == nil) != test.ok { 59 t.Errorf("ParseBig(%q) -> (err == nil) == %t, want %t", test.input, err == nil, test.ok) 60 continue 61 } 62 if test.num != nil && (*big.Int)(&num).Cmp(test.num) != 0 { 63 t.Errorf("ParseBig(%q) -> %d, want %d", test.input, (*big.Int)(&num), test.num) 64 } 65 } 66 } 67 68 func TestMustParseBig256(t *testing.T) { 69 defer func() { 70 if recover() == nil { 71 t.Error("MustParseBig should've panicked") 72 } 73 }() 74 MustParseBig256("ggg") 75 } 76 77 func TestBigMax(t *testing.T) { 78 a := big.NewInt(10) 79 b := big.NewInt(5) 80 81 max1 := BigMax(a, b) 82 if max1 != a { 83 t.Errorf("Expected %d got %d", a, max1) 84 } 85 86 max2 := BigMax(b, a) 87 if max2 != a { 88 t.Errorf("Expected %d got %d", a, max2) 89 } 90 } 91 92 func TestBigMin(t *testing.T) { 93 a := big.NewInt(10) 94 b := big.NewInt(5) 95 96 min1 := BigMin(a, b) 97 if min1 != b { 98 t.Errorf("Expected %d got %d", b, min1) 99 } 100 101 min2 := BigMin(b, a) 102 if min2 != b { 103 t.Errorf("Expected %d got %d", b, min2) 104 } 105 } 106 107 func TestFirstBigSet(t *testing.T) { 108 tests := []struct { 109 num *big.Int 110 ix int 111 }{ 112 {big.NewInt(0), 0}, 113 {big.NewInt(1), 0}, 114 {big.NewInt(2), 1}, 115 {big.NewInt(0x100), 8}, 116 } 117 for _, test := range tests { 118 if ix := FirstBitSet(test.num); ix != test.ix { 119 t.Errorf("FirstBitSet(b%b) = %d, want %d", test.num, ix, test.ix) 120 } 121 } 122 } 123 124 func TestPaddedBigBytes(t *testing.T) { 125 tests := []struct { 126 num *big.Int 127 n int 128 result []byte 129 }{ 130 {num: big.NewInt(0), n: 4, result: []byte{0, 0, 0, 0}}, 131 {num: big.NewInt(1), n: 4, result: []byte{0, 0, 0, 1}}, 132 {num: big.NewInt(512), n: 4, result: []byte{0, 0, 2, 0}}, 133 {num: BigPow(2, 32), n: 4, result: []byte{1, 0, 0, 0, 0}}, 134 } 135 for _, test := range tests { 136 if result := PaddedBigBytes(test.num, test.n); !bytes.Equal(result, test.result) { 137 t.Errorf("PaddedBigBytes(%d, %d) = %v, want %v", test.num, test.n, result, test.result) 138 } 139 } 140 } 141 142 func BenchmarkPaddedBigBytesLargePadding(b *testing.B) { 143 bigint := MustParseBig256("123456789123456789123456789123456789") 144 for i := 0; i < b.N; i++ { 145 PaddedBigBytes(bigint, 200) 146 } 147 } 148 149 func BenchmarkPaddedBigBytesSmallPadding(b *testing.B) { 150 bigint := MustParseBig256("0x18F8F8F1000111000110011100222004330052300000000000000000FEFCF3CC") 151 for i := 0; i < b.N; i++ { 152 PaddedBigBytes(bigint, 5) 153 } 154 } 155 156 func BenchmarkPaddedBigBytesSmallOnePadding(b *testing.B) { 157 bigint := MustParseBig256("0x18F8F8F1000111000110011100222004330052300000000000000000FEFCF3CC") 158 for i := 0; i < b.N; i++ { 159 PaddedBigBytes(bigint, 32) 160 } 161 } 162 163 func BenchmarkByteAtBrandNew(b *testing.B) { 164 bigint := MustParseBig256("0x18F8F8F1000111000110011100222004330052300000000000000000FEFCF3CC") 165 for i := 0; i < b.N; i++ { 166 bigEndianByteAt(bigint, 15) 167 } 168 } 169 170 func BenchmarkByteAt(b *testing.B) { 171 bigint := MustParseBig256("0x18F8F8F1000111000110011100222004330052300000000000000000FEFCF3CC") 172 for i := 0; i < b.N; i++ { 173 bigEndianByteAt(bigint, 15) 174 } 175 } 176 177 func BenchmarkByteAtOld(b *testing.B) { 178 bigint := MustParseBig256("0x18F8F8F1000111000110011100222004330052300000000000000000FEFCF3CC") 179 for i := 0; i < b.N; i++ { 180 PaddedBigBytes(bigint, 32) 181 } 182 } 183 184 func TestReadBits(t *testing.T) { 185 check := func(input string) { 186 want, _ := hex.DecodeString(input) 187 int, _ := new(big.Int).SetString(input, 16) 188 buf := make([]byte, len(want)) 189 ReadBits(int, buf) 190 if !bytes.Equal(buf, want) { 191 t.Errorf("have: %x\nwant: %x", buf, want) 192 } 193 } 194 check("000000000000000000000000000000000000000000000000000000FEFCF3F8F0") 195 check("0000000000012345000000000000000000000000000000000000FEFCF3F8F0") 196 check("18F8F8F1000111000110011100222004330052300000000000000000FEFCF3F8F0") 197 } 198 199 func TestU256(t *testing.T) { 200 tests := []struct{ x, y *big.Int }{ 201 {x: big.NewInt(0), y: big.NewInt(0)}, 202 {x: big.NewInt(1), y: big.NewInt(1)}, 203 {x: BigPow(2, 255), y: BigPow(2, 255)}, 204 {x: BigPow(2, 256), y: big.NewInt(0)}, 205 {x: new(big.Int).Add(BigPow(2, 256), big.NewInt(1)), y: big.NewInt(1)}, 206 // negative values 207 {x: big.NewInt(-1), y: new(big.Int).Sub(BigPow(2, 256), big.NewInt(1))}, 208 {x: big.NewInt(-2), y: new(big.Int).Sub(BigPow(2, 256), big.NewInt(2))}, 209 {x: BigPow(2, -255), y: big.NewInt(1)}, 210 } 211 for _, test := range tests { 212 if y := U256(new(big.Int).Set(test.x)); y.Cmp(test.y) != 0 { 213 t.Errorf("U256(%x) = %x, want %x", test.x, y, test.y) 214 } 215 } 216 } 217 218 func TestU256Bytes(t *testing.T) { 219 ubytes := make([]byte, 32) 220 ubytes[31] = 1 221 222 unsigned := U256Bytes(big.NewInt(1)) 223 if !bytes.Equal(unsigned, ubytes) { 224 t.Errorf("expected %x got %x", ubytes, unsigned) 225 } 226 } 227 228 func TestBigEndianByteAt(t *testing.T) { 229 tests := []struct { 230 x string 231 y int 232 exp byte 233 }{ 234 {"00", 0, 0x00}, 235 {"01", 1, 0x00}, 236 {"00", 1, 0x00}, 237 {"01", 0, 0x01}, 238 {"0000000000000000000000000000000000000000000000000000000000102030", 0, 0x30}, 239 {"0000000000000000000000000000000000000000000000000000000000102030", 1, 0x20}, 240 {"ABCDEF0908070605040302010000000000000000000000000000000000000000", 31, 0xAB}, 241 {"ABCDEF0908070605040302010000000000000000000000000000000000000000", 32, 0x00}, 242 {"ABCDEF0908070605040302010000000000000000000000000000000000000000", 500, 0x00}, 243 } 244 for _, test := range tests { 245 v := new(big.Int).SetBytes(common.Hex2Bytes(test.x)) 246 actual := bigEndianByteAt(v, test.y) 247 if actual != test.exp { 248 t.Fatalf("Expected [%v] %v:th byte to be %v, was %v.", test.x, test.y, test.exp, actual) 249 } 250 251 } 252 } 253 254 func TestLittleEndianByteAt(t *testing.T) { 255 tests := []struct { 256 x string 257 y int 258 exp byte 259 }{ 260 {"00", 0, 0x00}, 261 {"01", 1, 0x00}, 262 {"00", 1, 0x00}, 263 {"01", 0, 0x00}, 264 {"0000000000000000000000000000000000000000000000000000000000102030", 0, 0x00}, 265 {"0000000000000000000000000000000000000000000000000000000000102030", 1, 0x00}, 266 {"ABCDEF0908070605040302010000000000000000000000000000000000000000", 31, 0x00}, 267 {"ABCDEF0908070605040302010000000000000000000000000000000000000000", 32, 0x00}, 268 {"ABCDEF0908070605040302010000000000000000000000000000000000000000", 0, 0xAB}, 269 {"ABCDEF0908070605040302010000000000000000000000000000000000000000", 1, 0xCD}, 270 {"00CDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff", 0, 0x00}, 271 {"00CDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff", 1, 0xCD}, 272 {"0000000000000000000000000000000000000000000000000000000000102030", 31, 0x30}, 273 {"0000000000000000000000000000000000000000000000000000000000102030", 30, 0x20}, 274 {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 32, 0x0}, 275 {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 31, 0xFF}, 276 {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 0xFFFF, 0x0}, 277 } 278 for _, test := range tests { 279 v := new(big.Int).SetBytes(common.Hex2Bytes(test.x)) 280 actual := Byte(v, 32, test.y) 281 if actual != test.exp { 282 t.Fatalf("Expected [%v] %v:th byte to be %v, was %v.", test.x, test.y, test.exp, actual) 283 } 284 285 } 286 } 287 288 func TestS256(t *testing.T) { 289 tests := []struct{ x, y *big.Int }{ 290 {x: big.NewInt(0), y: big.NewInt(0)}, 291 {x: big.NewInt(1), y: big.NewInt(1)}, 292 {x: big.NewInt(2), y: big.NewInt(2)}, 293 { 294 x: new(big.Int).Sub(BigPow(2, 255), big.NewInt(1)), 295 y: new(big.Int).Sub(BigPow(2, 255), big.NewInt(1)), 296 }, 297 { 298 x: BigPow(2, 255), 299 y: new(big.Int).Neg(BigPow(2, 255)), 300 }, 301 { 302 x: new(big.Int).Sub(BigPow(2, 256), big.NewInt(1)), 303 y: big.NewInt(-1), 304 }, 305 { 306 x: new(big.Int).Sub(BigPow(2, 256), big.NewInt(2)), 307 y: big.NewInt(-2), 308 }, 309 } 310 for _, test := range tests { 311 if y := S256(test.x); y.Cmp(test.y) != 0 { 312 t.Errorf("S256(%x) = %x, want %x", test.x, y, test.y) 313 } 314 } 315 } 316 317 func TestExp(t *testing.T) { 318 tests := []struct{ base, exponent, result *big.Int }{ 319 {base: big.NewInt(0), exponent: big.NewInt(0), result: big.NewInt(1)}, 320 {base: big.NewInt(1), exponent: big.NewInt(0), result: big.NewInt(1)}, 321 {base: big.NewInt(1), exponent: big.NewInt(1), result: big.NewInt(1)}, 322 {base: big.NewInt(1), exponent: big.NewInt(2), result: big.NewInt(1)}, 323 {base: big.NewInt(3), exponent: big.NewInt(144), result: MustParseBig256("507528786056415600719754159741696356908742250191663887263627442114881")}, 324 {base: big.NewInt(2), exponent: big.NewInt(255), result: MustParseBig256("57896044618658097711785492504343953926634992332820282019728792003956564819968")}, 325 } 326 for _, test := range tests { 327 if result := Exp(test.base, test.exponent); result.Cmp(test.result) != 0 { 328 t.Errorf("Exp(%d, %d) = %d, want %d", test.base, test.exponent, result, test.result) 329 } 330 } 331 }