// p256FromBig sets out = R*in. func p256FromBig(out *[p256Limbs]uint32, in *big.Int) { tmp := new(big.Int).Lsh(in, 257) tmp.Mod(tmp, p256.P) for i := 0; i < p256Limbs; i++ { if bits := tmp.Bits(); len(bits) > 0 { out[i] = uint32(bits[0]) & bottom29Bits } else { out[i] = 0 } tmp.Rsh(tmp, 29) i++ if i == p256Limbs { break } if bits := tmp.Bits(); len(bits) > 0 { out[i] = uint32(bits[0]) & bottom28Bits } else { out[i] = 0 } tmp.Rsh(tmp, 28) } }
func BigAbsCmp(x, y big.Int) int { // SetBits sets to |v|, thus giving an absolute comparison. var x0, y0 big.Int x0.SetBits(x.Bits()) y0.SetBits(y.Bits()) return x0.Cmp(&y0) }
func CountInt(x *big.Int) int { total := 0 for _, w := range x.Bits() { total += Count64(uint64(w)) } return total }
// SmallPrimeTest determins if N is a small prime // or divisible by a small prime. func SmallPrimeTest(N *big.Int) int { if N.Sign() <= 0 { panic("SmallPrimeTest for positive integers only") } if N.BitLen() <= 10 { n := uint16(N.Uint64()) i := sort.Search(len(primes10), func(i int) bool { return primes10[i] >= n }) if i >= len(primes10) || n != primes10[i] { return IsComposite } return IsPrime } // quick test for N even if N.Bits()[0]&1 == 0 { return IsComposite } // compare several small gcds for efficency z := new(big.Int) if z.GCD(nil, nil, N, prodPrimes10A).Cmp(one) == 1 { return IsComposite } if z.GCD(nil, nil, N, prodPrimes10B).Cmp(one) == 1 { return IsComposite } if z.GCD(nil, nil, N, prodPrimes10C).Cmp(one) == 1 { return IsComposite } if z.GCD(nil, nil, N, prodPrimes10D).Cmp(one) == 1 { return IsComposite } return Undetermined }
// Bytes returns the bytes for the absolute value of x in little- // endian binary representation; x must be an Int. func Bytes(x Value) []byte { var val *big.Int switch x := x.(type) { case int64Val: val = new(big.Int).SetInt64(int64(x)) case intVal: val = x.val default: panic(fmt.Sprintf("%v not an Int", x)) } words := val.Bits() bytes := make([]byte, len(words)*wordSize) i := 0 for _, w := range words { for j := 0; j < wordSize; j++ { bytes[i] = byte(w) w >>= 8 i++ } } // remove leading 0's for i > 0 && bytes[i-1] == 0 { i-- } return bytes[:i] }
// BigInt sets all bytes in the passed big int to zero and then sets the // value to 0. This differs from simply setting the value in that it // specifically clears the underlying bytes whereas simply setting the value // does not. This is mostly useful to forcefully clear private keys. func BigInt(x *big.Int) { b := x.Bits() for i := range b { b[i] = 0 } x.SetInt64(0) }
// TrailingZerosBig returns the number of trailing 0 bits in v. // // If v is 0, it returns 0. func TrailingZerosBig(v *big.Int) int { for i, b := range v.Bits() { if b != 0 { return i*wordBits + tzw(b) } } return 0 }
// TrailingOnesBig returns the number of trailing 1 bits in v. func TrailingOnesBig(v *big.Int) int { words := v.Bits() for i, b := range words { if b != ^big.Word(0) { return i*wordBits + tzw(^b) } } return len(words) * wordBits }
// BigInt sets all bytes in the passed big int to zero and then sets the // value to 0. This differs from simply setting the value in that it // specifically clears the underlying bytes whereas simply setting the value // does not. This is mostly useful to forcefully clear private keys. func BigInt(x *big.Int) { b := x.Bits() z := [16]big.Word{} n := uint(copy(b, z[:])) for n < uint(len(b)) { copy(b[n:], b[:n]) n <<= 1 } x.SetInt64(0) }
func big2scalar(out *[4]C.ulonglong, in *big.Int) error { b := in.Bits() if len(b) > 4 { return fmt.Errorf("big.Int needs %d words, cannot be converted to scalar_t", len(b)) } for i, w := range b { out[i] = C.ulonglong(w) } return nil }
// reads num into buf as big-endian bytes. func readBits(buf []byte, num *big.Int) { const wordLen = int(unsafe.Sizeof(big.Word(0))) i := len(buf) for _, d := range num.Bits() { for j := 0; j < wordLen && i > 0; j++ { i-- buf[i] = byte(d) d >>= 8 } } }
// Uint64FromBigInt returns (uint64 value of n, true) if 0 <= n <= // math.MaxUint64. Otherwise it returns (undefined value, false). // // NOTE: This function is DEPRECATED with Go release 1.1 and will be REMOVED // with Go release 1.1+1, b/c of // http://code.google.com/p/go/source/detail?r=954a79ee3ea8 func Uint64FromBigInt(n *big.Int) (uint64, bool) { switch bits := n.BitLen(); { case bits == 0: return 0, true case n.Sign() < 0 || bits > 64: return 0, false case bits <= UintptrBits(): return uint64(n.Bits()[0]), true default: b := n.Bits() return uint64(b[1])<<uint(uintptrBits) | uint64(b[0]), true } }
func big2scalar(out *[4]C.ulonglong, in *big.Int) error { b := in.Bits() if len(b) > 8 { return fmt.Errorf("big.Int needs %d words, cannot be converted to scalar_t", len(b)) } max := len(b) >> 1 for i := 0; i < max; i++ { out[i] = C.ulonglong(b[i<<1]) | (C.ulonglong(b[i<<1+1]) << 32) } if len(b)&0x1 == 1 { out[max] = C.ulonglong(b[len(b)-1]) } return nil }
func TestBigInt(t *testing.T) { tests := []string{ // 16 0xFFFFFFFF 32-bit uintptrs strings.Repeat("FFFFFFFF", 16), // 17 32-bit uintptrs, minimum value which enters loop on 32-bit "01" + strings.Repeat("00000000", 16), // 32 0xFFFFFFFF 32-bit uintptrs, maximum value which enters loop exactly once on 32-bit strings.Repeat("FFFFFFFF", 32), // 33 32-bit uintptrs, minimum value which enters loop twice on 32-bit "01" + strings.Repeat("00000000", 32), // 16 0xFFFFFFFFFFFFFFFF 64-bit uintptrs strings.Repeat("FFFFFFFFFFFFFFFF", 16), // 17 64-bit uintptrs, minimum value which enters loop on 64-bit "01" + strings.Repeat("0000000000000000", 16), // 32 0xFFFFFFFFFFFFFFFF 64-bit uintptrs, maximum value which enters loop exactly once on 64-bit strings.Repeat("FFFFFFFFFFFFFFFF", 32), // 33 64-bit uintptrs, minimum value which enters loop twice on 64-bit "01" + strings.Repeat("0000000000000000", 32), } for i, s := range tests { v, ok := new(big.Int).SetString(s, 16) if !ok { t.Errorf("Test %d includes invalid hex number %s", i, s) continue } BigInt(v) err := checkZeroWords(v.Bits()) if err != nil { t.Errorf("Test %d (s=%s) failed: %v", i, s, err) continue } if v.Cmp(bigZero) != 0 { t.Errorf("Test %d (s=%s) zeroed big.Int represents non-zero number %v", i, s, v) continue } } }
// fromBig converts a *big.Int into a format used by this code. func fromBig(out []uint64, big *big.Int) { for i := range out { out[i] = 0 } for i, v := range big.Bits() { out[i] = uint64(v) } }
// XXX: I don't like this code. I _think_ it matches BN_ext_count_low_zero_bits // in the C++ exactfloat.cc version. Needs more testing. func count_low_zero_bits(bn *big.Int) int { count := 0 words := bn.Bits() for i := 0; i < len(words); i++ { if words[i] == 0 { count += 64 //8 * int(unsafe.Sizeof(&words[i])) } else { for j := 0; j < bn.BitLen(); j++ { if bn.Bit(j) == 0 { count++ } else { break } } break } } return count }
// BigToCompact converts a whole number N to a compact representation using // an unsigned 32-bit number. The compact representation only provides 23 bits // of precision, so values larger than (2^23 - 1) only encode the most // significant digits of the number. See CompactToBig for details. func BigToCompact(n *big.Int) uint32 { // No need to do any work if it's zero. if n.Sign() == 0 { return 0 } // Since the base for the exponent is 256, the exponent can be treated // as the number of bytes. So, shift the number right or left // accordingly. This is equivalent to: // mantissa = mantissa / 256^(exponent-3) var mantissa uint32 exponent := uint(len(n.Bytes())) if exponent <= 3 { mantissa = uint32(n.Bits()[0]) mantissa <<= 8 * (3 - exponent) } else { // Use a copy to avoid modifying the caller's original number. tn := new(big.Int).Set(n) mantissa = uint32(tn.Rsh(tn, 8*(exponent-3)).Bits()[0]) } // When the mantissa already has the sign bit set, the number is too // large to fit into the available 23-bits, so divide the number by 256 // and increment the exponent accordingly. if mantissa&0x00800000 != 0 { mantissa >>= 8 exponent++ } // Pack the exponent, sign bit, and mantissa into an unsigned 32-bit // int and return it. compact := uint32(exponent<<24) | mantissa if n.Sign() < 0 { compact |= 0x00800000 } return compact }
// Compute the Jacobi symbol of (x/y) using Euclid's algorithm. // This is usually much faster modular multiplication via Euler's criterion. func Jacobi(x, y *big.Int) int { // We use the formulation described in chapter 2, section 2.4, // "The Yacas Book of Algorithms": // http://yacas.sourceforge.net/Algo.book.pdf var a, b, c big.Int a.Set(x) b.Set(y) j := 1 for { if a.Cmp(zero) == 0 { return 0 } if b.Cmp(one) == 0 { return j } a.Mod(&a, &b) // Handle factors of 2 in a s := 0 for a.Bit(s) == 0 { s++ } if s&1 != 0 { bmod8 := b.Bits()[0] & 7 if bmod8 == 3 || bmod8 == 5 { j = -j } } c.Rsh(&a, uint(s)) // a = 2^s*c // Swap numerator and denominator if b.Bits()[0]&3 == 3 && c.Bits()[0]&3 == 3 { j = -j } a.Set(&b) b.Set(&c) } }
// PopCountBigInt returns population count of |n| (number of bits set in |n|). func PopCountBigInt(n *big.Int) (r int) { for _, v := range n.Bits() { r += PopCountUintptr(uintptr(v)) } return }
// JacobiSymbol returns the jacobi symbol ( N / D ) of // N (numerator) over D (denominator). // See http://en.wikipedia.org/wiki/Jacobi_symbol func JacobiSymbol(N *big.Int, D *big.Int) int { //Step 0: parse input / easy cases if D.Sign() <= 0 || D.Bit(0) == 0 { // we will assume D is positive // wolfram is ok with negative denominator // im not sure what is standard though panic("JacobiSymbol defined for positive odd denominator only") } var n, d, tmp big.Int n.Set(N) d.Set(D) j := 1 for { // Step 1: Reduce the numerator mod the denominator n.Mod(&n, &d) if n.Sign() == 0 { // if n,d not relatively prime return 0 } if len(n.Bits()) >= len(d.Bits())-1 { // n > d/2 so swap n with d-n // and multiply j by JacobiSymbol(-1 / d) n.Sub(&d, &n) if d.Bits()[0]&3 == 3 { // if d = 3 mod 4 j = -1 * j } } // Step 2: extract factors of 2 s := trailingZeroBits(&n) n.Rsh(&n, s) if s&1 == 1 { switch d.Bits()[0] & 7 { case 3, 5: // d = 3,5 mod 8 j = -1 * j } } // Step 3: check numerator if len(n.Bits()) == 1 && n.Bits()[0] == 1 { // if n = 1 were done return j } // Step 4: flip and go back to step 1 if n.Bits()[0]&3 != 1 { // n = 3 mod 4 if d.Bits()[0]&3 != 1 { // d = 3 mod 4 j = -1 * j } } tmp.Set(&n) n.Set(&d) d.Set(&tmp) } }
func toA(x *big.Int) (r BigIntArray) { for i, v := range x.Bits() { r[i] = v } return }
// PreallocInt preallocates 128-bits of storage for an existing // big.Int value. Will not perform the pre-allocation if the given // pointer is nil, or if the storage has already been allocated. // // This function serves very little purpose as it provides no benefits // whatsoever, and is only included for completeness. func PreallocInt(i *big.Int) { var mem [pS]big.Word if i != nil && cap(i.Bits()) == 0 { i.SetBits(mem[0:0]) } }
func BigAbs(x *big.Int) *big.Int { m := make([]big.Word, len(x.Bits())) copy(m, x.Bits()) return new(big.Int).SetBits(m) }
func cmpBigAbs(x, y big.Int) int { // SetBits sets the absolute value, thus causing an absolute comparison. x0 := new(big.Int).SetBits(x.Bits()) y0 := new(big.Int).SetBits(y.Bits()) return x0.Cmp(y0) }
// bigAbsAlias returns a big.Int set to |x| whose inner slices // alias each other. Do not use unless the return value will not be // modified. func bigAbsAlias(x *big.Int) *big.Int { return new(big.Int).SetBits(x.Bits()) }