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  }