github.com/ericlagergren/ctb@v0.0.0-20220810041818-96749d9c394d/xbits/xbits.go (about)

     1  // Package xbits augments math/bits with larger integers.
     2  package xbits
     3  
     4  import (
     5  	"crypto/subtle"
     6  	"encoding/binary"
     7  	"fmt"
     8  	"io"
     9  	"math/big"
    10  	"math/bits"
    11  
    12  	"github.com/elagergren/ctb/xbits/ct"
    13  )
    14  
    15  // Uint256 is an unsigned 256-bit integer.
    16  type Uint256 struct {
    17  	u0, u1, u2, u3 uint64
    18  }
    19  
    20  var (
    21  	_ fmt.Stringer  = Uint256{}
    22  	_ fmt.Formatter = Uint256{}
    23  )
    24  
    25  // U256 creates a Uint256 from a uint64.
    26  func U256(x uint64) Uint256 {
    27  	return Uint256{x, 0, 0, 0}
    28  }
    29  
    30  // Add returns x + y.
    31  //
    32  // This function's execution time does not depend on its inputs.
    33  //go:noinline
    34  func (x Uint256) Add(y Uint256) Uint256 {
    35  	var z Uint256
    36  	var c uint64
    37  	z.u0, c = bits.Add64(x.u0, y.u0, c)
    38  	z.u1, c = bits.Add64(x.u1, y.u1, c)
    39  	z.u2, c = bits.Add64(x.u2, y.u2, c)
    40  	z.u3, _ = bits.Add64(x.u3, y.u3, c)
    41  	return z
    42  }
    43  
    44  // And returns x & y.
    45  //
    46  // This function's execution time does not depend on its inputs.
    47  func (x Uint256) And(y Uint256) Uint256 {
    48  	var z Uint256
    49  	z.u0 = x.u0 & y.u0
    50  	z.u1 = x.u1 & y.u1
    51  	z.u2 = x.u2 & y.u2
    52  	z.u3 = x.u3 & y.u3
    53  	return z
    54  }
    55  
    56  // Bit returns the value of bit at index i.
    57  //
    58  // That is, Bit returns (x>>i)&1.
    59  // The index must be >= 0.
    60  func (x Uint256) Bit(i int) uint {
    61  	if i < 0 {
    62  		panic("negative bit index")
    63  	}
    64  	if i >= 256 {
    65  		return 0
    66  	}
    67  	n := make([]uint64, 4)
    68  	n[0] = x.u0
    69  	n[1] = x.u1
    70  	n[2] = x.u2
    71  	n[3] = x.u3
    72  	return uint(n[i/64] >> (i % 64) & 1)
    73  }
    74  
    75  // BitLen returns the absolute value of x in bits.
    76  //
    77  // In other words, the number of bits needed to
    78  // represent x.
    79  func (x Uint256) BitLen() int {
    80  	switch {
    81  	case x.u3 != 0:
    82  		return 192 + bits.Len64(x.u3)
    83  	case x.u2 != 0:
    84  		return 128 + bits.Len64(x.u2)
    85  	case x.u1 != 0:
    86  		return 64 + bits.Len64(x.u1)
    87  	default:
    88  		return bits.Len64(x.u0)
    89  	}
    90  }
    91  
    92  // Cmp compares u and x and returns
    93  //
    94  //    +1 if x > y
    95  //     0 if x == y
    96  //    -1 if x < y
    97  //
    98  func (x Uint256) Cmp(y Uint256) int {
    99  	var z Uint256
   100  	var b uint64
   101  	z.u0, b = bits.Sub64(x.u0, y.u0, b)
   102  	z.u1, b = bits.Sub64(x.u1, y.u1, b)
   103  	z.u2, b = bits.Sub64(x.u2, y.u2, b)
   104  	z.u3, b = bits.Sub64(x.u3, y.u3, b)
   105  
   106  	r := z.u0 ^ z.u1 ^ z.u2 ^ z.u3
   107  	// If r == 0 then x == y
   108  	// If r != 0 then x != y
   109  	// If b == 0 then x > y
   110  	// If b == 1 then x <= y
   111  	if b == 0 {
   112  		return +1
   113  	}
   114  	if r == 0 {
   115  		return +0
   116  	}
   117  	return -1
   118  }
   119  
   120  // Exp returns x**y mod m.
   121  func (x Uint256) Exp(y, m Uint256) Uint256 {
   122  	x1 := x
   123  	x2 := x.MulMod(x, m)
   124  	for i := 256 - 2; i >= 0; i-- {
   125  		if y.Bit(i) == 0 {
   126  			// x2 = x1*x2 mod m
   127  			x2 = x1.MulMod(x2, m)
   128  			// x1 = x1^2 mod m
   129  			x1 = x1.MulMod(x1, m)
   130  		} else {
   131  			// x1 = x1*x2 mod m
   132  			x1 = x1.MulMod(x2, m)
   133  			// x2 = x2^2 mod m
   134  			x2 = x2.MulMod(x2, m)
   135  		}
   136  	}
   137  	return x1
   138  }
   139  
   140  // FillBytes sets buf to x, storing it as a zero-extended
   141  // big-endian byte slice, and returns buf.
   142  //
   143  // If x does not fit into buf, FillBytes will panic.
   144  func (x Uint256) FillBytes(buf []byte) []byte {
   145  	binary.BigEndian.PutUint64(buf[24:], x.u0)
   146  	binary.BigEndian.PutUint64(buf[16:24], x.u1)
   147  	binary.BigEndian.PutUint64(buf[8:16], x.u2)
   148  	binary.BigEndian.PutUint64(buf[:8], x.u3)
   149  	return buf
   150  }
   151  
   152  func (x Uint256) Format(s fmt.State, ch rune) {
   153  	// Implementation borrowed from math/big.
   154  
   155  	var base int
   156  	switch ch {
   157  	case 'b':
   158  		base = 2
   159  	case 'o', 'O':
   160  		base = 8
   161  	case 'd', 's', 'v':
   162  		base = 10
   163  	case 'x', 'X':
   164  		base = 16
   165  	default:
   166  		fmt.Fprintf(s, "%%!%c(xbits.Uint256=%s)", ch, x.String())
   167  		return
   168  	}
   169  
   170  	sign := ""
   171  	switch {
   172  	case s.Flag('+'):
   173  		sign = "+"
   174  	case s.Flag(' '):
   175  		sign = " "
   176  	}
   177  
   178  	prefix := ""
   179  	if s.Flag('#') {
   180  		switch ch {
   181  		case 'b':
   182  			prefix = "0b"
   183  		case 'o':
   184  			prefix = "0"
   185  		case 'x':
   186  			prefix = "0x"
   187  		case 'X':
   188  			prefix = "0X"
   189  		}
   190  	}
   191  	if ch == 'O' {
   192  		prefix = "0o"
   193  	}
   194  
   195  	digits := []byte(x.Text(base))
   196  	if ch == 'X' {
   197  		for i, d := range digits {
   198  			if 'a' <= d && d <= 'z' {
   199  				digits[i] = 'A' + (d - 'a')
   200  			}
   201  		}
   202  	}
   203  
   204  	var left int
   205  	var zeros int
   206  	var right int
   207  
   208  	precision, precisionSet := s.Precision()
   209  	if precisionSet {
   210  		switch {
   211  		case len(digits) < precision:
   212  			zeros = precision - len(digits)
   213  		case len(digits) == 1 && digits[0] == '0' && precision == 0:
   214  			return
   215  		}
   216  	}
   217  
   218  	length := len(sign) + len(prefix) + zeros + len(digits)
   219  	if width, widthSet := s.Width(); widthSet && length < width {
   220  		switch d := width - length; {
   221  		case s.Flag('-'):
   222  			right = d
   223  		case s.Flag('0') && !precisionSet:
   224  			zeros = d
   225  		default:
   226  			left = d
   227  		}
   228  	}
   229  
   230  	writeMultiple(s, " ", left)
   231  	writeMultiple(s, sign, 1)
   232  	writeMultiple(s, prefix, 1)
   233  	writeMultiple(s, "0", zeros)
   234  	s.Write(digits)
   235  	writeMultiple(s, " ", right)
   236  }
   237  
   238  // write count copies of text to s
   239  func writeMultiple(s fmt.State, text string, count int) {
   240  	if len(text) > 0 {
   241  		b := []byte(text)
   242  		for ; count > 0; count-- {
   243  			s.Write(b)
   244  		}
   245  	}
   246  }
   247  
   248  // Lsh returns x<<n.
   249  //
   250  // This function's execution time does not depend on its inputs.
   251  func (x Uint256) Lsh(n uint) Uint256 {
   252  	s := n % 64
   253  	ŝ := 64 - s
   254  
   255  	// If n is in [0, 256) set i = n/64.
   256  	// Otherwise, set i = 4.
   257  	i := subtle.ConstantTimeSelect(int(ct.LessOrEq(n, 255)), int(n/64), 4)
   258  
   259  	res := make([]uint64, 8)
   260  	res[i+3] = x.u3<<s | x.u2>>ŝ
   261  	res[i+2] = x.u2<<s | x.u1>>ŝ
   262  	res[i+1] = x.u1<<s | x.u0>>ŝ
   263  	res[i+0] = x.u0 << s
   264  
   265  	var z Uint256
   266  	z.u0 = res[0]
   267  	z.u1 = res[1]
   268  	z.u2 = res[2]
   269  	z.u3 = res[3]
   270  	return z
   271  }
   272  
   273  // shr sets z = x<<n for n in [0, 64].
   274  func shl(z, x []uint64, n uint) uint64 {
   275  	s := n % 64
   276  	ŝ := 64 - s
   277  
   278  	c := x[len(z)-1] >> ŝ
   279  	for i := len(z) - 1; i > 0; i-- {
   280  		z[i] = x[i]<<s | x[i-1]>>ŝ
   281  	}
   282  	z[0] = x[0] << s
   283  	return c
   284  }
   285  
   286  // ModInverse returns the multiplicative inverse
   287  // of x in the ring ℤ/nℤ.
   288  //
   289  // If x and n are not relatively prime, x has no
   290  // multiplicative inverse in the ring ℤ/nℤ and
   291  // ModInverse will panic.
   292  func (x Uint256) ModInverse(n Uint256) Uint256 {
   293  	panic("TODO")
   294  }
   295  
   296  // Mul returns x * y.
   297  //
   298  // This function's execution time does not depend on its inputs.
   299  func (x Uint256) Mul(y Uint256) Uint256 {
   300  	z := make([]uint64, 8)
   301  	mul512(z, x, y)
   302  	return Uint256{z[0], z[1], z[2], z[3]}
   303  }
   304  
   305  // MulMod returns x*y mod m.
   306  func (x Uint256) MulMod(y, m Uint256) Uint256 {
   307  	z := make([]uint64, 8)
   308  	mul512(z, x, y)
   309  
   310  	if m.BitLen() <= 64 {
   311  		return U256(mod64(z, m.u0))
   312  	}
   313  
   314  	v := make([]uint64, 4)
   315  	v[0] = m.u0
   316  	v[1] = m.u1
   317  	v[2] = m.u2
   318  	v[3] = m.u3
   319  
   320  	q := make([]uint64, 8)
   321  	r := div512(q, z, v)
   322  	return Uint256{r[0], r[1], r[2], r[3]}
   323  }
   324  
   325  // mul512 returns the 512-bit product of x*y.
   326  //
   327  // mul512 has the following conditions:
   328  //
   329  //    len(z) == 8
   330  //
   331  // This function's execution time does not depend on its inputs.
   332  func mul512(z []uint64, x, y Uint256) {
   333  	var (
   334  		c      uint64
   335  		z1, z0 uint64
   336  	)
   337  
   338  	// y_0 * x
   339  	//
   340  	// Store in z[0:4]
   341  
   342  	c, z[0] = mul128(x.u0, y.u0, z[0])
   343  
   344  	z1, z0 = mul128(x.u1, y.u0, z[1])
   345  	lo, cc := bits.Add64(z0, c, 0)
   346  	c, z[1] = cc, lo
   347  	c += z1
   348  
   349  	z1, z0 = mul128(x.u2, y.u0, z[2])
   350  	lo, cc = bits.Add64(z0, c, 0)
   351  	c, z[2] = cc, lo
   352  	c += z1
   353  
   354  	z1, z0 = mul128(x.u3, y.u0, z[3])
   355  	lo, cc = bits.Add64(z0, c, 0)
   356  	c, z[3] = cc, lo
   357  	c += z1
   358  
   359  	z[4] = c
   360  
   361  	// y_1 * x
   362  	//
   363  	// Store in z[1:5]
   364  
   365  	c, z[1] = mul128(x.u0, y.u1, z[1])
   366  
   367  	z1, z0 = mul128(x.u1, y.u1, z[2])
   368  	lo, cc = bits.Add64(z0, c, 0)
   369  	c, z[2] = cc, lo
   370  	c += z1
   371  
   372  	z1, z0 = mul128(x.u2, y.u1, z[3])
   373  	lo, cc = bits.Add64(z0, c, 0)
   374  	c, z[3] = cc, lo
   375  	c += z1
   376  
   377  	z1, z0 = mul128(x.u3, y.u1, z[4])
   378  	lo, cc = bits.Add64(z0, c, 0)
   379  	c, z[4] = cc, lo
   380  	c += z1
   381  
   382  	z[5] = c
   383  
   384  	// y_2 * x
   385  	//
   386  	// Store in z[2:6]
   387  
   388  	c, z[2] = mul128(x.u0, y.u2, z[2])
   389  
   390  	z1, z0 = mul128(x.u1, y.u2, z[3])
   391  	lo, cc = bits.Add64(z0, c, 0)
   392  	c, z[3] = cc, lo
   393  	c += z1
   394  
   395  	z1, z0 = mul128(x.u2, y.u2, z[4])
   396  	lo, cc = bits.Add64(z0, c, 0)
   397  	c, z[4] = cc, lo
   398  	c += z1
   399  
   400  	z1, z0 = mul128(x.u3, y.u2, z[5])
   401  	lo, cc = bits.Add64(z0, c, 0)
   402  	c, z[5] = cc, lo
   403  	c += z1
   404  
   405  	z[6] = c
   406  
   407  	// y_3 * x
   408  	//
   409  	// Store in z[3:7]
   410  
   411  	c, z[3] = mul128(x.u0, y.u3, z[3])
   412  
   413  	z1, z0 = mul128(x.u1, y.u3, z[4])
   414  	lo, cc = bits.Add64(z0, c, 0)
   415  	c, z[4] = cc, lo
   416  	c += z1
   417  
   418  	z1, z0 = mul128(x.u2, y.u3, z[5])
   419  	lo, cc = bits.Add64(z0, c, 0)
   420  	c, z[5] = cc, lo
   421  	c += z1
   422  
   423  	z1, z0 = mul128(x.u3, y.u3, z[6])
   424  	lo, cc = bits.Add64(z0, c, 0)
   425  	c, z[6] = cc, lo
   426  	c += z1
   427  
   428  	z[7] = c
   429  }
   430  
   431  func mul128(x, y, c uint64) (z1, z0 uint64) {
   432  	hi, lo := bits.Mul64(x, y)
   433  	lo, c = bits.Add64(lo, c, 0)
   434  	return hi + c, lo
   435  }
   436  
   437  // LeadingZeros returns the number of leading
   438  // zero bits in x.
   439  //
   440  // The result is 256 if x == 0.
   441  func (x Uint256) LeadingZeros() int {
   442  	return 256 - x.BitLen()
   443  }
   444  
   445  // OnesCount returns the number of one bits
   446  // in x.
   447  //
   448  // Also known as the "population count."
   449  func (x Uint256) OnesCount() int {
   450  	var n int
   451  	n += bits.OnesCount64(x.u0)
   452  	n += bits.OnesCount64(x.u1)
   453  	n += bits.OnesCount64(x.u2)
   454  	n += bits.OnesCount64(x.u3)
   455  	return n
   456  }
   457  
   458  // Or returns x | y.
   459  //
   460  // This function's execution time does not depend on its inputs.
   461  func (x Uint256) Or(y Uint256) Uint256 {
   462  	var z Uint256
   463  	z.u0 = x.u0 | y.u0
   464  	z.u1 = x.u1 | y.u1
   465  	z.u2 = x.u2 | y.u2
   466  	z.u3 = x.u3 | y.u3
   467  	return z
   468  }
   469  
   470  // Quo returns x / y.
   471  //
   472  // Quo implements truncated division, like Go.
   473  func (x Uint256) Quo(y Uint256) Uint256 {
   474  	q, _ := x.QuoRem(y)
   475  	return q
   476  }
   477  
   478  // QuoRem returns x / y and x % y.
   479  //
   480  // QuoRem implements truncated division and
   481  // modulus, like Go.
   482  func (x Uint256) QuoRem(y Uint256) (Uint256, Uint256) {
   483  	// QuoRem is largely borrowed from math/big.
   484  
   485  	if l := y.BitLen(); l <= 64 {
   486  		if l == 0 {
   487  			panic("division by zero")
   488  		}
   489  		y := y.u0
   490  		rec := reciprocal(y)
   491  		var q Uint256
   492  		var r uint64
   493  		q.u3, r = divWW(r, x.u3, y, rec)
   494  		q.u2, r = divWW(r, x.u2, y, rec)
   495  		q.u1, r = divWW(r, x.u1, y, rec)
   496  		q.u0, r = divWW(r, x.u0, y, rec)
   497  		return q, U256(r)
   498  	}
   499  
   500  	u := make([]uint64, 5)
   501  	u[0] = x.u0
   502  	u[1] = x.u1
   503  	u[2] = x.u2
   504  	u[3] = x.u3
   505  
   506  	v := make([]uint64, 4)
   507  	v[0] = y.u0
   508  	v[1] = y.u1
   509  	v[2] = y.u2
   510  	v[3] = y.u3
   511  
   512  	q := make([]uint64, 5)
   513  	r := div512(q, u, v)
   514  
   515  	quo := Uint256{q[0], q[1], q[2], q[3]}
   516  	rem := Uint256{r[0], r[1], r[2], r[3]}
   517  	return quo, rem
   518  }
   519  
   520  // mod64 return u%v.
   521  func mod64(uIn []uint64, v uint64) (r uint64) {
   522  	rec := reciprocal(v)
   523  	for i := len(uIn) - 1; i >= 0; i-- {
   524  		_, r = divWW(r, uIn[i], v, rec)
   525  	}
   526  	return r
   527  }
   528  
   529  // div512 sets q = u/v and returns r = u%v.
   530  //
   531  // div512 has the following conditions:
   532  //
   533  //    len(v) >= 2
   534  //    len(u) >= len(v) + 1
   535  //    u[len(u)-1] must be zero (reserved for r)
   536  //    len(q) >= len(u)
   537  //    u must not alias z
   538  //
   539  // div512 reuses u as storage for r.
   540  // div512 modifies v.
   541  func div512(q, uIn, vIn []uint64) (r []uint64) {
   542  	_ = vIn[2-1]
   543  	_ = uIn[len(vIn)+1-1]
   544  	_ = q[len(uIn)-len(vIn)+1-1]
   545  
   546  	// Normalize v.
   547  	n := len(vIn)
   548  	for n > 0 && vIn[n-1] == 0 {
   549  		n--
   550  	}
   551  	vIn = vIn[:n]
   552  
   553  	// Normalize u.
   554  	uIn[len(uIn)-1] = 0
   555  	m := len(uIn) - 1
   556  	for m > 0 && uIn[m-1] == 0 {
   557  		m--
   558  	}
   559  	uIn = uIn[:m]
   560  	m -= n
   561  
   562  	// D1.
   563  	shift := uint(bits.LeadingZeros64(vIn[n-1]))
   564  
   565  	v := vIn
   566  	shl(v, vIn, shift)
   567  
   568  	u := uIn[:len(uIn)+1]
   569  	u[m] = shl(u[:len(uIn)], uIn, shift)
   570  
   571  	q = q[:m+1]
   572  
   573  	qhatv := make([]uint64, 8)
   574  	qhatvLen := n + 1
   575  
   576  	// D2.
   577  	vn1 := v[n-1]
   578  	rec := reciprocal(vn1)
   579  	for j := m; j >= 0; j-- {
   580  		// D3.
   581  		const mask = 1<<64 - 1
   582  		qhat := uint64(mask)
   583  		var ujn uint64
   584  		if j+n < len(u) {
   585  			ujn = u[j+n]
   586  		}
   587  		if ujn != vn1 {
   588  			var rhat uint64
   589  			qhat, rhat = divWW(ujn, u[j+n-1], vn1, rec)
   590  
   591  			// x1 | x2 = q̂v_{n-2}
   592  			vn2 := v[n-2]
   593  			x1, x2 := bits.Mul64(qhat, vn2)
   594  			// test if q̂v_{n-2} > br̂ + u_{j+n-2}
   595  			ujn2 := u[j+n-2]
   596  			for greaterThan(x1, x2, rhat, ujn2) {
   597  				qhat--
   598  				prevRhat := rhat
   599  				rhat += vn1
   600  				// v[n-1] >= 0, so this tests for overflow.
   601  				if rhat < prevRhat {
   602  					break
   603  				}
   604  				x1, x2 = bits.Mul64(qhat, vn2)
   605  			}
   606  		}
   607  
   608  		// D4.
   609  		// Compute the remainder u - (q̂*v) << (_W*j).
   610  		// The subtraction may overflow if q̂ estimate was off by one.
   611  		qhatv[n] = mulAddVWW(qhatv[0:n], v, qhat, 0)
   612  		qhl := qhatvLen
   613  		if j+qhl > len(u) && qhatv[n] == 0 {
   614  			qhl--
   615  		}
   616  		c := subVV(u[j:j+qhl], u[j:], qhatv)
   617  		if c != 0 {
   618  			c := addVV(u[j:j+n], u[j:], v)
   619  			// If n == qhl, the carry from subVV and the carry from addVV
   620  			// cancel out and don't affect u[j+n].
   621  			if n < qhl {
   622  				u[j+n] += c
   623  			}
   624  			qhat--
   625  		}
   626  
   627  		if j == m && m == len(q) && qhat == 0 {
   628  			continue
   629  		}
   630  		q[j] = qhat
   631  	}
   632  	shr(u, u, shift)
   633  	r = u
   634  	return r
   635  }
   636  
   637  // Rem returns x % y.
   638  //
   639  // Rem implements truncated modulus, like Go.
   640  func (x Uint256) Rem(y Uint256) Uint256 {
   641  	_, r := x.QuoRem(y)
   642  	return r
   643  }
   644  
   645  // RotateLeft returns the value of x rotated left
   646  // by (k mod 256) bits.
   647  //
   648  // This function's execution time does not depend on its inputs.
   649  func (x Uint256) RotateLeft(k int) Uint256 {
   650  	const n = 256
   651  	s := uint(k) & (n - 1)
   652  	return x.Lsh(s).Or(x.Rsh(n - s))
   653  }
   654  
   655  // RoateRight returns the value of x rotated right
   656  // by (k mod 256) bits.
   657  //
   658  // This function's execution time does not depend on its inputs.
   659  func (x Uint256) RotateRight(k int) Uint256 {
   660  	return x.RotateLeft(-k)
   661  }
   662  
   663  // Reverse returns the value of x with its bits in
   664  // reversed order.
   665  func (x Uint256) Reverse() Uint256 {
   666  	var z Uint256
   667  	z.u0 = bits.Reverse64(x.u0)
   668  	z.u1 = bits.Reverse64(x.u1)
   669  	z.u2 = bits.Reverse64(x.u2)
   670  	z.u3 = bits.Reverse64(x.u3)
   671  	return z
   672  }
   673  
   674  // ReverseBytes returns the value of x with its bytes
   675  // in reversed order.
   676  //
   677  // This function's execution time does not depend on its inputs.
   678  func (x Uint256) ReverseBytes() Uint256 {
   679  	var z Uint256
   680  	z.u0 = bits.ReverseBytes64(x.u0)
   681  	z.u1 = bits.ReverseBytes64(x.u1)
   682  	z.u2 = bits.ReverseBytes64(x.u2)
   683  	z.u3 = bits.ReverseBytes64(x.u3)
   684  	return z
   685  }
   686  
   687  // Rsh returns x>>n.
   688  //
   689  // This function's execution time does not depend on its inputs.
   690  func (x Uint256) Rsh(n uint) Uint256 {
   691  	s := n % 64
   692  	ŝ := 64 - s
   693  
   694  	res := make([]uint64, 8)
   695  	res[0] = x.u0>>s | x.u1<<ŝ
   696  	res[1] = x.u1>>s | x.u2<<ŝ
   697  	res[2] = x.u2>>s | x.u3<<ŝ
   698  	res[3] = x.u3 >> s
   699  
   700  	// If n is in [0, 256) set i = n/64.
   701  	// Otherwise, set i = 4.
   702  	i := subtle.ConstantTimeSelect(int(ct.LessOrEq(n, 255)), int(n/64), 4)
   703  
   704  	var z Uint256
   705  	z.u0 = res[i+0]
   706  	z.u1 = res[i+1]
   707  	z.u2 = res[i+2]
   708  	z.u3 = res[i+3]
   709  	return z
   710  }
   711  
   712  // shr sets z = x>>n for n in [0, 64].
   713  func shr(z, x []uint64, n uint) uint64 {
   714  	s := n % 64
   715  	ŝ := 64 - s
   716  
   717  	c := x[0] << ŝ
   718  	z[0] = x[0]>>s | x[1]<<ŝ
   719  	z[1] = x[1]>>s | x[2]<<ŝ
   720  	z[2] = x[2]>>s | x[3]<<ŝ
   721  	z[3] = x[3] >> s
   722  	return c
   723  }
   724  
   725  // SetBytes sets z to the big-endian unsigned integer buf.
   726  //
   727  // SetBytes panics if buf overflows z (buf > 1<<256-1).
   728  func (z *Uint256) SetBytes(buf []byte) {
   729  	if len(buf) > 32 {
   730  		panic("SetBytes: integer too large")
   731  	}
   732  
   733  	*z = Uint256{}
   734  	if len(buf) > 24 {
   735  		z.u3 = be64(buf[:len(buf)-24])
   736  		buf = buf[len(buf)-24:]
   737  	}
   738  	if len(buf) > 16 {
   739  		z.u2 = be64(buf[:len(buf)-16])
   740  		buf = buf[len(buf)-16:]
   741  	}
   742  	if len(buf) > 8 {
   743  		z.u1 = be64(buf[:len(buf)-8])
   744  		buf = buf[len(buf)-8:]
   745  	}
   746  	if len(buf) > 0 {
   747  		z.u0 = be64(buf)
   748  	}
   749  }
   750  
   751  func be64(b []byte) uint64 {
   752  	switch len(b) {
   753  	case 8:
   754  		return binary.BigEndian.Uint64(b)
   755  	case 7:
   756  		_ = b[6] // bounds check hint to compiler; see golang.org/issue/14808
   757  		return uint64(b[6]) | uint64(b[5])<<8 | uint64(b[4])<<16 |
   758  			uint64(b[3])<<24 | uint64(b[2])<<32 | uint64(b[1])<<40 |
   759  			uint64(b[0])<<48
   760  	case 6:
   761  		_ = b[5] // bounds check hint to compiler; see golang.org/issue/14808
   762  		return uint64(b[5]) | uint64(b[4])<<8 | uint64(b[3])<<16 |
   763  			uint64(b[2])<<24 | uint64(b[1])<<32 | uint64(b[0])<<40
   764  	case 5:
   765  		_ = b[4] // bounds check hint to compiler; see golang.org/issue/14808
   766  		return uint64(b[4]) | uint64(b[3])<<8 | uint64(b[2])<<16 |
   767  			uint64(b[1])<<24 | uint64(b[0])<<32
   768  	case 4:
   769  		return uint64(binary.BigEndian.Uint32(b))
   770  	case 3:
   771  		_ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
   772  		return uint64(b[2]) | uint64(b[1])<<8 | uint64(b[0])<<16
   773  	case 2:
   774  		return uint64(binary.BigEndian.Uint16(b))
   775  	case 1:
   776  		return uint64(b[0])
   777  	case 0:
   778  		return 0
   779  	default:
   780  		panic("unreachable")
   781  	}
   782  }
   783  
   784  // Sub returns x - y.
   785  //
   786  // This function's execution time does not depend on its inputs.
   787  func (x Uint256) Sub(y Uint256) Uint256 {
   788  	var z Uint256
   789  	var b uint64
   790  	z.u0, b = bits.Sub64(x.u0, y.u0, b)
   791  	z.u1, b = bits.Sub64(x.u1, y.u1, b)
   792  	z.u2, b = bits.Sub64(x.u2, y.u2, b)
   793  	z.u3, _ = bits.Sub64(x.u3, y.u3, b)
   794  	return z
   795  }
   796  
   797  func (x Uint256) String() string {
   798  	return x.Text(10)
   799  }
   800  
   801  // Text returns the textual representation of
   802  // x in the provided base.
   803  //
   804  // The base must be in [2, 62].
   805  func (x Uint256) Text(base int) string {
   806  	var z big.Int
   807  	setInt(&z, x)
   808  	return z.Text(base)
   809  }
   810  
   811  // TrailingZeros returns the number of trailing
   812  // zero bits in x.
   813  //
   814  // The result is 256 if x == 0.
   815  func (x Uint256) TrailingZeros() int {
   816  	switch {
   817  	case x.u0 != 0:
   818  		return bits.TrailingZeros64(x.u0)
   819  	case x.u1 != 0:
   820  		return 64 + bits.TrailingZeros64(x.u1)
   821  	case x.u2 != 0:
   822  		return 128 + bits.TrailingZeros64(x.u2)
   823  	default:
   824  		return 192 + bits.TrailingZeros64(x.u3)
   825  	}
   826  }
   827  
   828  // Uint64 returns the uint64 representation of x.
   829  //
   830  // The result is undefined if x cannot be
   831  // represented as a uint64.
   832  func (x Uint256) Uint64() uint64 {
   833  	return x.u0
   834  }
   835  
   836  // Xor returns x ^ y.
   837  //
   838  // This function's execution time does not depend on its inputs.
   839  func (x Uint256) Xor(y Uint256) Uint256 {
   840  	var z Uint256
   841  	z.u0 = x.u0 ^ y.u0
   842  	z.u1 = x.u1 ^ y.u1
   843  	z.u2 = x.u2 ^ y.u2
   844  	z.u3 = x.u3 ^ y.u3
   845  	return z
   846  }
   847  
   848  // Rand256 returns a Uint256 in [0, max).
   849  //
   850  // Rand256 panics if max = 0.
   851  func Rand256(rand io.Reader, max Uint256) (Uint256, error) {
   852  	// Implementation borrowed from crypto/rand.
   853  	if max.BitLen() == 0 {
   854  		panic("xbits: argument to Rand256 is 0")
   855  	}
   856  	n := max.Sub(U256(1))
   857  	// bitLen is the maximum bit length needed to encode a value < max.
   858  	bitLen := n.BitLen()
   859  	if bitLen == 0 {
   860  		// the only valid result is 0
   861  		return U256(0), nil
   862  	}
   863  	// k is the maximum byte length needed to encode a value < max.
   864  	k := (bitLen + 7) / 8
   865  	// b is the number of bits in the most significant byte of max-1.
   866  	b := uint(bitLen % 8)
   867  	if b == 0 {
   868  		b = 8
   869  	}
   870  
   871  	bytes := make([]byte, k)
   872  	for {
   873  		_, err := io.ReadFull(rand, bytes)
   874  		if err != nil {
   875  			return U256(0), err
   876  		}
   877  
   878  		// Clear bits in the first byte to increase the probability
   879  		// that the candidate is < max.
   880  		bytes[0] &= uint8(int(1<<b) - 1)
   881  
   882  		n.SetBytes(bytes)
   883  		if n.Cmp(max) < 0 {
   884  			return n, nil
   885  		}
   886  	}
   887  }
   888  
   889  func setInt(z *big.Int, x Uint256) {
   890  	const _W = bits.UintSize
   891  	if _W == 64 {
   892  		z.SetBits([]big.Word{
   893  			big.Word(x.u0),
   894  			big.Word(x.u1),
   895  			big.Word(x.u2),
   896  			big.Word(x.u3),
   897  		})
   898  	} else {
   899  		// _W == 32
   900  		z.SetBits([]big.Word{
   901  			big.Word(x.u0),
   902  			big.Word(x.u0 >> 32),
   903  			big.Word(x.u1),
   904  			big.Word(x.u1 >> 32),
   905  			big.Word(x.u2),
   906  			big.Word(x.u2 >> 32),
   907  			big.Word(x.u3),
   908  			big.Word(x.u3 >> 32),
   909  		})
   910  	}
   911  }