github.com/ericlagergren/ctb@v0.0.0-20220810041818-96749d9c394d/xbits/xbits_test.go (about) 1 package xbits 2 3 import ( 4 "fmt" 5 "io" 6 "math" 7 "math/big" 8 "math/rand" 9 "testing" 10 ) 11 12 var ( 13 rng = readFunc(rand.Read) 14 max256 = Uint256{math.MaxUint64, math.MaxUint64, math.MaxUint64, math.MaxUint64} 15 max128 = Uint256{math.MaxUint64, math.MaxUint64, 0, 0} 16 ) 17 18 type readFunc func([]byte) (int, error) 19 20 var _ io.Reader = (readFunc)(nil) 21 22 func (fn readFunc) Read(p []byte) (int, error) { 23 return fn(p) 24 } 25 26 func cmpInt(x *big.Int, y Uint256) int { 27 var yy big.Int 28 setInt(&yy, y) 29 return x.Cmp(&yy) 30 } 31 32 // big256Mask is 1<<256-1. 33 var big256Mask = new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 256), big.NewInt(1)) 34 35 func TestFoo(t *testing.T) { 36 u2 := Uint256{17562291160714782030, 13611842547513532036, 18446744073709551615, 9223372032559808512} 37 N := Uint256{17562291160714782033, 13611842547513532036, 18446744073709551615, 18446744069414584320} 38 39 sq := u2.Add(u2) 40 fmt.Println(u2) 41 fmt.Println(sq) 42 fmt.Println(N) 43 } 44 45 func TestAdd256(t *testing.T) { 46 for i := 0; i < 100_000; i++ { 47 x, err := Rand256(rng, max256) 48 if err != nil { 49 t.Fatal(err) 50 } 51 y, err := Rand256(rng, max256) 52 if err != nil { 53 t.Fatal(err) 54 } 55 z := x.Add(y) 56 57 var bz, bx, by big.Int 58 setInt(&bx, x) 59 setInt(&by, y) 60 bz.Add(&bx, &by) 61 bz.And(&bz, big256Mask) 62 63 if cmpInt(&bz, z) != 0 { 64 t.Fatalf("#%d: expected %s, got %d", i, bz.String(), z) 65 } 66 } 67 } 68 69 func TestSub256(t *testing.T) { 70 for i := 0; i < 100_000; i++ { 71 x, err := Rand256(rng, max256) 72 if err != nil { 73 t.Fatal(err) 74 } 75 y, err := Rand256(rng, max256) 76 if err != nil { 77 t.Fatal(err) 78 } 79 z := x.Sub(y) 80 81 var bz, bx, by big.Int 82 setInt(&bx, x) 83 setInt(&by, y) 84 bz.Sub(&bx, &by) 85 bz.And(&bz, big256Mask) 86 87 if cmpInt(&bz, z) != 0 { 88 t.Fatalf("#%d: expected %s, got %d", i, bz.String(), z) 89 } 90 } 91 } 92 93 func TestMul256(t *testing.T) { 94 for i := 0; i < 100_000; i++ { 95 x, err := Rand256(rng, max256) 96 if err != nil { 97 t.Fatal(err) 98 } 99 y, err := Rand256(rng, max256) 100 if err != nil { 101 t.Fatal(err) 102 } 103 z := x.Mul(y) 104 105 var bz, bx, by big.Int 106 setInt(&bx, x) 107 setInt(&by, y) 108 bz.Mul(&bx, &by) 109 bz.And(&bz, big256Mask) 110 111 if cmpInt(&bz, z) != 0 { 112 t.Fatalf("#%d: expected %s, got %d", i, bz.String(), z) 113 } 114 } 115 } 116 117 func TestLsh256(t *testing.T) { 118 for i := 0; i < 100_000; i++ { 119 x, err := Rand256(rng, max256) 120 if err != nil { 121 t.Fatal(err) 122 } 123 n := uint(rand.Intn(512)) 124 z := x.Lsh(n) 125 126 var bz, bx big.Int 127 setInt(&bx, x) 128 bz.Lsh(&bx, n) 129 bz.And(&bz, big256Mask) 130 131 if cmpInt(&bz, z) != 0 { 132 t.Fatalf("#%d: expected %s, got %d", i, bz.String(), z) 133 } 134 } 135 } 136 137 func TestRsh256(t *testing.T) { 138 for i := 0; i < 100_000; i++ { 139 x, err := Rand256(rng, max256) 140 if err != nil { 141 t.Fatal(err) 142 } 143 n := uint(rand.Intn(512)) 144 z := x.Rsh(n) 145 146 var bz, bx big.Int 147 setInt(&bx, x) 148 bz.Rsh(&bx, n) 149 bz.And(&bz, big256Mask) 150 151 if cmpInt(&bz, z) != 0 { 152 t.Fatalf("#%d: expected %s, got %d", i, bz.String(), z) 153 } 154 } 155 } 156 157 func TestQuoRem256(t *testing.T) { 158 for i := 0; i < 100_000; i++ { 159 x, err := Rand256(rng, max256) 160 if err != nil { 161 t.Fatal(err) 162 } 163 y, err := Rand256(rng, U256(4)) 164 if err != nil { 165 t.Fatal(err) 166 } 167 if y.BitLen() == 0 { 168 y = U256(1) 169 } 170 171 var bq, br, bx, by big.Int 172 setInt(&bx, x) 173 setInt(&by, y) 174 bq.QuoRem(&bx, &by, &br) 175 bq.And(&bq, big256Mask) 176 q, r := x.QuoRem(y) 177 178 if cmpInt(&bq, q) != 0 { 179 t.Fatalf("#%d: expected %s, got %d", i, bq.String(), q) 180 } 181 if cmpInt(&br, r) != 0 { 182 t.Fatalf("#%d: expected %s, got %d", i, br.String(), r) 183 } 184 } 185 } 186 187 func TestAnd256(t *testing.T) { 188 for i := 0; i < 100_000; i++ { 189 x, err := Rand256(rng, max256) 190 if err != nil { 191 t.Fatal(err) 192 } 193 y, err := Rand256(rng, max256) 194 if err != nil { 195 t.Fatal(err) 196 } 197 z := x.And(y) 198 199 var bz, bx, by big.Int 200 setInt(&bx, x) 201 setInt(&by, y) 202 bz.And(&bx, &by) 203 bz.And(&bz, big256Mask) 204 205 if cmpInt(&bz, z) != 0 { 206 t.Fatalf("#%d: expected %s, got %d", i, bz.String(), z) 207 } 208 } 209 } 210 211 func TestXor256(t *testing.T) { 212 for i := 0; i < 100_000; i++ { 213 x, err := Rand256(rng, max256) 214 if err != nil { 215 t.Fatal(err) 216 } 217 y, err := Rand256(rng, max256) 218 if err != nil { 219 t.Fatal(err) 220 } 221 z := x.Xor(y) 222 223 var bz, bx, by big.Int 224 setInt(&bx, x) 225 setInt(&by, y) 226 bz.Xor(&bx, &by) 227 bz.And(&bz, big256Mask) 228 229 if cmpInt(&bz, z) != 0 { 230 t.Fatalf("#%d: expected %s, got %d", i, bz.String(), z) 231 } 232 } 233 } 234 235 func TestOr256(t *testing.T) { 236 for i := 0; i < 100_000; i++ { 237 x, err := Rand256(rng, max256) 238 if err != nil { 239 t.Fatal(err) 240 } 241 y, err := Rand256(rng, max256) 242 if err != nil { 243 t.Fatal(err) 244 } 245 z := x.Or(y) 246 247 var bz, bx, by big.Int 248 setInt(&bx, x) 249 setInt(&by, y) 250 bz.Or(&bx, &by) 251 bz.And(&bz, big256Mask) 252 253 if cmpInt(&bz, z) != 0 { 254 t.Fatalf("#%d: expected %s, got %d", i, bz.String(), z) 255 } 256 } 257 } 258 259 func TestTrailingZeros256(t *testing.T) { 260 for i, tc := range []struct { 261 x Uint256 262 n int 263 }{ 264 {Uint256{0, 0, 0, 0}, 256}, 265 {Uint256{0, 0, 0, math.MaxUint64}, 192}, 266 {Uint256{0, 0, math.MaxUint64, 0}, 128}, 267 {Uint256{0, math.MaxUint64, 0, 0}, 64}, 268 {Uint256{math.MaxUint64, 0, 0, 0}, 0}, 269 {Uint256{1, 0, 0, 0}, 0}, 270 {Uint256{0, 0, 0, 1}, 192}, 271 {Uint256{0, 0, 1 << 8, 0}, 136}, 272 } { 273 got := tc.x.TrailingZeros() 274 if got != tc.n { 275 t.Fatalf("#%d: expected %d, got %d", i, tc.n, got) 276 } 277 } 278 } 279 280 func TestFillBytes256(t *testing.T) { 281 for i := 0; i < 10_000; i++ { 282 x, err := Rand256(rng, max256) 283 if err != nil { 284 t.Fatal(err) 285 } 286 buf := x.FillBytes(make([]byte, 32)) 287 288 var y Uint256 289 y.SetBytes(buf) 290 if x != y { 291 t.Fatalf("#%d: expected %d, got %d", i, x, y) 292 } 293 } 294 295 defer func() { 296 if recover() == nil { 297 t.Fatal("expected a panic") 298 } 299 }() 300 301 var x Uint256 302 x.FillBytes(make([]byte, 31)) 303 } 304 305 func TestExp256(t *testing.T) { 306 for i := 0; i < 10_000; i++ { 307 x, err := Rand256(rng, max256) 308 if err != nil { 309 t.Fatal(err) 310 } 311 y, err := Rand256(rng, max256) 312 if err != nil { 313 t.Fatal(err) 314 } 315 m, err := Rand256(rng, U256(512)) 316 if err != nil { 317 t.Fatal(err) 318 } 319 if m.BitLen() == 0 { 320 m = U256(1) 321 } 322 z := x.Exp(y, m) 323 324 var bz, bx, by, bm big.Int 325 setInt(&bx, x) 326 setInt(&by, y) 327 setInt(&bm, m) 328 bz.Exp(&bx, &by, &bm) 329 // exp(&bz, &bx, &by, &bm) 330 bz.And(&bz, big256Mask) 331 332 if cmpInt(&bz, z) != 0 { 333 t.Fatalf("#%d: expected %s, got %d", i, bz.String(), z) 334 } 335 } 336 } 337 338 func exp(z, g, n, m *big.Int) *big.Int { 339 x1 := new(big.Int).Set(g) 340 x2 := new(big.Int).Mul(g, g) 341 x2.Mod(x2, m) 342 for i := 256 - 2; i >= 0; i-- { 343 if n.Bit(i) == 0 { 344 x2.Mul(x1, x2) 345 x2.Mod(x2, m) 346 x1.Mul(x1, x1) 347 x1.Mod(x1, m) 348 } else { 349 x1.Mul(x1, x2) 350 x1.Mod(x1, m) 351 x2.Mul(x2, x2) 352 x2.Mod(x2, m) 353 } 354 } 355 return z.Set(x1) 356 } 357 358 func TestBits256(t *testing.T) { 359 for i := 0; i < 10_000; i++ { 360 x, err := Rand256(rng, max256) 361 if err != nil { 362 t.Fatal(err) 363 } 364 365 var bx big.Int 366 setInt(&bx, x) 367 368 for j := 0; j < 256*2; j++ { 369 want := bx.Bit(j) 370 got := x.Bit(j) 371 if want != got { 372 t.Fatalf("#%d: expected %d, got %d", i, want, got) 373 } 374 } 375 } 376 } 377 378 var Sink256 Uint256 379 380 func BenchmarkAdd256(b *testing.B) { 381 x, err := Rand256(rng, max256) 382 if err != nil { 383 b.Fatal(err) 384 } 385 y, err := Rand256(rng, max256) 386 if err != nil { 387 b.Fatal(err) 388 } 389 b.ResetTimer() 390 for i := 0; i < b.N; i++ { 391 Sink256 = x.Add(y) 392 } 393 } 394 395 func BenchmarkSub256(b *testing.B) { 396 x, err := Rand256(rng, max256) 397 if err != nil { 398 b.Fatal(err) 399 } 400 y, err := Rand256(rng, max256) 401 if err != nil { 402 b.Fatal(err) 403 } 404 if x.Cmp(y) < 0 { 405 x, y = y, x 406 } 407 b.ResetTimer() 408 for i := 0; i < b.N; i++ { 409 Sink256 = x.Sub(y) 410 } 411 } 412 413 func BenchmarkMul256(b *testing.B) { 414 x, err := Rand256(rng, max256) 415 if err != nil { 416 b.Fatal(err) 417 } 418 y, err := Rand256(rng, max256) 419 if err != nil { 420 b.Fatal(err) 421 } 422 b.ResetTimer() 423 for i := 0; i < b.N; i++ { 424 Sink256 = x.Mul(y) 425 } 426 } 427 428 func BenchmarkLsh256(b *testing.B) { 429 x, err := Rand256(rng, max256) 430 if err != nil { 431 b.Fatal(err) 432 } 433 b.ResetTimer() 434 for i := 0; i < b.N; i++ { 435 Sink256 = x.Lsh(uint(i)) 436 } 437 } 438 439 func BenchmarkRsh256(b *testing.B) { 440 x, err := Rand256(rng, max256) 441 if err != nil { 442 b.Fatal(err) 443 } 444 b.ResetTimer() 445 for i := 0; i < b.N; i++ { 446 Sink256 = x.Rsh(uint(i)) 447 } 448 } 449 450 func BenchmarkQuoRem256(b *testing.B) { 451 x, err := Rand256(rng, max256) 452 if err != nil { 453 b.Fatal(err) 454 } 455 y, err := Rand256(rng, max128) 456 if err != nil { 457 b.Fatal(err) 458 } 459 b.ResetTimer() 460 for i := 0; i < b.N; i++ { 461 Sink256, Sink256 = x.QuoRem(y) 462 } 463 } 464 465 func BenchmarkQuoRem256Small(b *testing.B) { 466 x, err := Rand256(rng, max256) 467 if err != nil { 468 b.Fatal(err) 469 } 470 y, err := Rand256(rng, U256(math.MaxUint64)) 471 if err != nil { 472 b.Fatal(err) 473 } 474 if y.BitLen() == 0 { 475 y = U256(1) 476 } 477 b.ResetTimer() 478 for i := 0; i < b.N; i++ { 479 Sink256, Sink256 = x.QuoRem(y) 480 } 481 } 482 483 func BenchmarkAnd256(b *testing.B) { 484 x, err := Rand256(rng, max256) 485 if err != nil { 486 b.Fatal(err) 487 } 488 y, err := Rand256(rng, max256) 489 if err != nil { 490 b.Fatal(err) 491 } 492 b.ResetTimer() 493 for i := 0; i < b.N; i++ { 494 Sink256 = x.And(y) 495 } 496 } 497 498 func BenchmarkXor256(b *testing.B) { 499 x, err := Rand256(rng, max256) 500 if err != nil { 501 b.Fatal(err) 502 } 503 y, err := Rand256(rng, max256) 504 if err != nil { 505 b.Fatal(err) 506 } 507 b.ResetTimer() 508 for i := 0; i < b.N; i++ { 509 Sink256 = x.Xor(y) 510 } 511 } 512 513 func BenchmarkOr256(b *testing.B) { 514 x, err := Rand256(rng, max256) 515 if err != nil { 516 b.Fatal(err) 517 } 518 y, err := Rand256(rng, max256) 519 if err != nil { 520 b.Fatal(err) 521 } 522 b.ResetTimer() 523 for i := 0; i < b.N; i++ { 524 Sink256 = x.Or(y) 525 } 526 }