// ProbablyPrimeBigInt returns true if n is prime or n is a pseudoprime to base // a. It implements the Miller-Rabin primality test for one specific value of // 'a' and k == 1. See also ProbablyPrimeUint32. func ProbablyPrimeBigInt(n, a *big.Int) bool { var d big.Int d.Set(n) d.Sub(&d, _1) // d <- n-1 s := 0 for ; d.Bit(s) == 0; s++ { } nMinus1 := big.NewInt(0).Set(&d) d.Rsh(&d, uint(s)) x := ModPowBigInt(a, &d, n) if x.Cmp(_1) == 0 || x.Cmp(nMinus1) == 0 { return true } for ; s > 1; s-- { if x = x.Mod(x.Mul(x, x), n); x.Cmp(_1) == 0 { return false } if x.Cmp(nMinus1) == 0 { return true } } return false }
/* FromFactorBigInt returns n such that d | Mn if n <= max and d is odd. In other cases zero is returned. It is conjectured that every odd d ∊ N divides infinitely many Mersenne numbers. The returned n should be the exponent of smallest such Mn. NOTE: The computation of n from a given d performs roughly in O(n). It is thus highly recomended to use the 'max' argument to limit the "searched" exponent upper bound as appropriate. Otherwise the computation can take a long time as a large factor can be a divisor of a Mn with exponent above the uint32 limits. The FromFactorBigInt function is a modification of the original Will Edgington's "reverse method", discussed here: http://tech.groups.yahoo.com/group/primenumbers/message/15061 */ func FromFactorBigInt(d *big.Int, max uint32) (n uint32) { if d.Bit(0) == 0 { return } var m big.Int for n < max { m.Add(&m, d) i := 0 for ; m.Bit(i) == 1; i++ { if n == math.MaxUint32 { return 0 } n++ } m.Rsh(&m, uint(i)) if m.Sign() == 0 { if n > max { n = 0 } return } } return 0 }
// polyPowMod computes ``f**n`` in ``GF(p)[x]/(g)`` using repeated squaring. // Given polynomials ``f`` and ``g`` in ``GF(p)[x]`` and a non-negative // integer ``n``, efficiently computes ``f**n (mod g)`` i.e. the remainder // of ``f**n`` from division by ``g``, using the repeated squaring algorithm. // This function was ported from sympy.polys.galoistools. func polyPowMod(f *Poly, n *big.Int, g *Poly) (h *Poly, err error) { zero := big.NewInt(int64(0)) one := big.NewInt(int64(1)) n = big.NewInt(int64(0)).Set(n) if n.BitLen() < 3 { // Small values of n not useful for recon err = powModSmallN return } h = NewPoly(Zi(f.p, 1)) for { if n.Bit(0) > 0 { h = NewPoly().Mul(h, f) h, err = PolyMod(h, g) if err != nil { return } n.Sub(n, one) } n.Rsh(n, 1) if n.Cmp(zero) == 0 { break } f = NewPoly().Mul(f, f) f, err = PolyMod(f, g) if err != nil { return } } return }
// StrongMillerRabin checks if N is a // strong Miller-Rabin pseudoprime in base a. // That is, it checks if a is a witness // for compositeness of N or if N is a strong // pseudoprime base a. // // Use builtin ProbablyPrime if you want to do a lot // of random tests, this is for one specific // base value. func StrongMillerRabin(N *big.Int, a int64) int { // Step 0: parse input if N.Sign() < 0 || N.Bit(0) == 0 || a < 2 { panic("MR is for positive odd integers with a >= 2") } A := big.NewInt(a) if (a == 2 && N.Bit(0) == 0) || new(big.Int).GCD(nil, nil, N, A).Cmp(one) != 0 { return IsComposite } // Step 1: find d,s, so that n - 1 = d*2^s // with d odd d := new(big.Int).Sub(N, one) s := trailingZeroBits(d) d.Rsh(d, s) // Step 2: compute powers a^d // and then a^(d*2^r) for 0<r<s nm1 := new(big.Int).Sub(N, one) Ad := new(big.Int).Exp(A, d, N) if Ad.Cmp(one) == 0 || Ad.Cmp(nm1) == 0 { return Undetermined } for r := uint(1); r < s; r++ { Ad.Exp(Ad, two, N) if Ad.Cmp(nm1) == 0 { return Undetermined } } // Step 3: a is a witness for compositeness return IsComposite }
func EncodePublicKey(x, y *big.Int, compressed bool) ([]byte, error) { var pubkey []byte if compressed { pubkey = make([]byte, 33) pubkey[0] = 2 + byte(y.Bit(0)) } else { pubkey = make([]byte, 65) pubkey[0] = 4 } // Right-align x coordinate bytes := x.Bytes() if len(bytes) > 32 { return nil, fmt.Errorf("Value of x has > 32 bytes") } copy(pubkey[1+(32-len(bytes)):33], bytes) if !compressed { // Right-align y coordinate bytes = y.Bytes() if len(bytes) > 32 { return nil, fmt.Errorf("Value of y has > 32 bytes") } copy(pubkey[33+(32-len(bytes)):65], bytes) } return pubkey, nil }
// ScalarMult computes Q = k * P on EllipticCurve ec. func (ec *EllipticCurve) ScalarMult(k *big.Int, P Point) (Q Point) { /* Note: this function is not constant time, due to the branching nature of * the underlying point Add() function. */ /* Montgomery Ladder Point Multiplication * * Implementation based on pseudocode here: * See https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication#Montgomery_ladder */ var R0 Point var R1 Point R0.X = nil R0.Y = nil R1.X = new(big.Int).Set(P.X) R1.Y = new(big.Int).Set(P.Y) for i := ec.N.BitLen() - 1; i >= 0; i-- { if k.Bit(i) == 0 { R1 = ec.Add(R0, R1) R0 = ec.Add(R0, R0) } else { R0 = ec.Add(R0, R1) R1 = ec.Add(R1, R1) } } return R0 }
func factor2(n *big.Int) int { // could be improved for large factors f := 0 for ; n.Bit(f) == 0; f++ { } return f }
func factor(n *big.Int) (pf []pExp) { var e int64 for ; n.Bit(int(e)) == 0; e++ { } if e > 0 { n.Rsh(n, uint(e)) pf = []pExp{{big.NewInt(2), e}} } s := sqrt(n) q, r := new(big.Int), new(big.Int) for d := big.NewInt(3); n.Cmp(one) > 0; d.Add(d, two) { if d.Cmp(s) > 0 { d.Set(n) } for e = 0; ; e++ { q.QuoRem(n, d, r) if r.BitLen() > 0 { break } n.Set(q) } if e > 0 { pf = append(pf, pExp{new(big.Int).Set(d), e}) s = sqrt(n) } } return }
func ScanLeftInt(x *big.Int) int { for k := 0; k < x.BitLen(); k += 1 { if x.Bit(k) != 0 { return k } } return -1 }
// compute the position of the leading one of a bit vector func rank(hv *big.Int) int { for i := 0; i < hv.BitLen(); i++ { if hv.Bit(i) > 0 { return i + 1 } } return MAX_LEN }
func findSetBit(s *big.Int, start int) int { for i := start; i < s.BitLen(); i++ { if s.Bit(i) == 1 { return i } } return -1 }
func FirstBitSet(v *big.Int) int { for i := 0; i < v.BitLen(); i++ { if v.Bit(i) > 0 { return i } } return v.BitLen() }
// 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) } }
// Set z to one of the square roots of a modulo p if a square root exists. // The modulus p must be an odd prime. // Returns true on success, false if input a is not a square modulo p. func Sqrt(z *big.Int, a *big.Int, p *big.Int) bool { if a.Sign() == 0 { z.SetInt64(0) // sqrt(0) = 0 return true } if Jacobi(a, p) != 1 { return false // a is not a square mod M } // Break p-1 into s*2^e such that s is odd. var s big.Int var e int s.Sub(p, one) for s.Bit(0) == 0 { s.Div(&s, two) e++ } // Find some non-square n var n big.Int n.SetInt64(2) for Jacobi(&n, p) != -1 { n.Add(&n, one) } // Heart of the Tonelli-Shanks algorithm. // Follows the description in // "Square roots from 1; 24, 51, 10 to Dan Shanks" by Ezra Brown. var x, b, g, t big.Int x.Add(&s, one).Div(&x, two).Exp(a, &x, p) b.Exp(a, &s, p) g.Exp(&n, &s, p) r := e for { // Find the least m such that ord_p(b) = 2^m var m int t.Set(&b) for t.Cmp(one) != 0 { t.Exp(&t, two, p) m++ } if m == 0 { z.Set(&x) return true } t.SetInt64(0).SetBit(&t, r-m-1, 1).Exp(&g, &t, p) // t = g^(2^(r-m-1)) mod p g.Mul(&t, &t).Mod(&g, p) // g = g^(2^(r-m)) mod p x.Mul(&x, &t).Mod(&x, p) b.Mul(&b, &g).Mod(&b, p) r = m } }
func modPowBigInt(b, e, m *big.Int) (r *big.Int) { r = big.NewInt(1) for i, n := 0, e.BitLen(); i < n; i++ { if e.Bit(i) != 0 { r.Mod(r.Mul(r, b), m) } b.Mod(b.Mul(b, b), m) } return }
func testBig(s string) { b, _ := new(big.Int).SetString(s, 10) fmt.Printf("Testing big integer %v: ", b) // the Bit function is the only sensible test for big ints. if b.Bit(0) == 0 { fmt.Println("even") } else { fmt.Println("odd") } }
// contiguousScanStrategy tries to allocate starting at 0 and filling in any gaps func contiguousScanStrategy(allocated *big.Int, max, count int) (int, bool) { if count >= max { return 0, false } for i := 0; i < max; i++ { if allocated.Bit(i) == 0 { return i, true } } return 0, false }
// counts the number of zeros at the end of the // binary expansion. So 2=10 ---> 1, 4=100 ---> 2 // 3=111 ---> 0, see test for more examples // also 0 ---> 0 and 1 ---> 0 func trailingZeroBits(x *big.Int) (i uint) { if x.Sign() < 0 { panic("unknown bits of negative") } if x.Sign() == 0 || x.Bit(0) == 1 { return 0 } for i = 1; i < uint(x.BitLen()) && x.Bit(int(i)) != 1; i++ { } return }
// Marshal encodes a ECC Point into it's compressed representation func Marshal(curve elliptic.Curve, x, y *big.Int) []byte { byteLen := (curve.Params().BitSize + 7) >> 3 ret := make([]byte, 1+byteLen) ret[0] = 2 + byte(y.Bit(0)) xBytes := x.Bytes() copy(ret[1+byteLen-len(xBytes):], xBytes) return ret }
func bitSetToString(n *big.Int) string { var b bytes.Buffer b.WriteRune('{') for i, bitsLen := 0, n.BitLen(); i < bitsLen; i++ { if n.Bit(i) == 0 { continue } fmt.Fprintf(&b, "%v, ", i) } b.WriteRune('}') return b.String() }
//primize makes x a prime number. //Result will be bigger than x. func primize(x *big.Int) *big.Int { var tmp big.Int if x.Bit(0) == 0 { x.Add(x, tmp.SetInt64(1)) } for { if x.ProbablyPrime(sprpTestCount) { return x } x.Add(x, tmp.SetInt64(2)) } }
func (d PublicKeyDigest) Log2int() int { var b big.Int b.SetBytes(d[:]) b.Add(&b, big.NewInt(1)) l := len(d)*8 - 1 for i := len(d) * 8; i >= 0 && b.Bit(i) == 0; i-- { l-- } if l < 0 { return 0 } return l }
// mulMod computes z = (x * y) % p. func mulMod(x *big.Int, y *big.Int, p *big.Int) (z *big.Int) { n := new(big.Int).Set(x) z = big.NewInt(0) for i := 0; i < y.BitLen(); i++ { if y.Bit(i) == 1 { z = addMod(z, n, p) } n = addMod(n, n, p) } return z }
// randomScanStrategy chooses a random address from the provided big.Int, and then // scans forward looking for the next available address (it will wrap the range if // necessary). func randomScanStrategy(allocated *big.Int, max, count int) (int, bool) { if count >= max { return 0, false } offset := rand.Intn(max) for i := 0; i < max; i++ { at := (offset + i) % max if allocated.Bit(at) == 0 { return at, true } } return 0, false }
// trunc truncates a value to the range of the given type. func (t *_type) trunc(x *big.Int) *big.Int { r := new(big.Int) m := new(big.Int) m.Lsh(one, t.bits) m.Sub(m, one) r.And(x, m) if t.signed && r.Bit(int(t.bits)-1) == 1 { m.Neg(one) m.Lsh(m, t.bits) r.Or(r, m) } return r }
// ScalarMult returns k*(Bx,By) where k is a number in big-endian form. This // uses the repeated doubling method, which is variable time. // TODO use a constant time method to prevent side channel attacks. func (curve *TwistedEdwardsCurve) ScalarMult(x1, y1 *big.Int, k []byte) (x, y *big.Int) { // Convert the scalar to a big int. s := new(big.Int).SetBytes(k) // Get a new group element to do cached doubling // calculations in. dEGE := new(edwards25519.ExtendedGroupElement) dEGE.Zero() // Use the doubling method for the multiplication. // p := given point // q := point(zero) // for each bit in the scalar, descending: // double(q) // if bit == 1: // add(q, p) // return q // // Note that the addition is skipped for zero bits, // making this variable time and thus vulnerable to // side channel attack vectors. for i := s.BitLen() - 1; i >= 0; i-- { dCGE := new(edwards25519.CompletedGroupElement) dEGE.Double(dCGE) dCGE.ToExtended(dEGE) if s.Bit(i) == 1 { ss := new([32]byte) dEGE.ToBytes(ss) var err error xi, yi, err := curve.EncodedBytesToBigIntPoint(ss) if err != nil { return nil, nil } xAdd, yAdd := curve.Add(xi, yi, x1, y1) dTempBytes := BigIntPointToEncodedBytes(xAdd, yAdd) dEGE.FromBytes(dTempBytes) } } finalBytes := new([32]byte) dEGE.ToBytes(finalBytes) var err error x, y, err = curve.EncodedBytesToBigIntPoint(finalBytes) if err != nil { return nil, nil } return }
// findComplements returns the indices of two character arrays a and b // in charTab such that (a & maskIncl) == (~b & maskIncl), // a & maskExcl == maskExcl, and b & maskExcl == maskExcl. func findComplements(charTab CharTable, maskIncl, maskExcl *big.Int) (s, t int) { // w := maxInt(maskIncl.BitLen(), maskExcl.BitLen()) // fmt.Printf("findComplements\n.incl=%0*b\n.excl=%0*b\n", w, maskIncl, w, maskExcl) if maskIncl.BitLen() == 0 { panic("Empty mask") } var minInclBit int for minInclBit = 0; minInclBit < maskIncl.BitLen(); minInclBit++ { if maskIncl.Bit(minInclBit) != 0 { break } } arraysByNorm := map[string][]int{} for i, a := range charTab { b := &big.Int{} b.And(a, maskExcl) if b.Cmp(maskExcl) != 0 { continue } if a.Bit(minInclBit) == 0 { b.AndNot(maskIncl, a) } else { b.And(maskIncl, a) } key := fmt.Sprintf("%x", b) arraysByNorm[key] = append(arraysByNorm[key], i) } for _, cands := range arraysByNorm { if len(cands) < 2 { continue } for i := 0; i < len(cands)-1; i++ { a := charTab[cands[i]] for j := i + 1; j < len(cands); j++ { b := charTab[cands[j]] c := &big.Int{} c.Xor(a, b) c.And(c, maskIncl) if c.Cmp(maskIncl) == 0 { return cands[i], cands[j] } } } } return -1, -1 }
// Scan a bit-field within x starting from bit i, // either upward or downward to but not including bit j, // for the first bit with value b. // Returns the position of the first b-bit found, // or -1 if every bit in the bit-field is set to 1-b. func BitScan(x *big.Int, i, j int, b uint) int { // XXX could be made a lot more efficient using x.Words() inc := 1 if i > j { inc = -1 } for ; i != j; i += inc { if x.Bit(i) == b { return i } } return -1 }
func compressPublicKey(x *big.Int, y *big.Int) []byte { var key bytes.Buffer // Write header; 0x2 for even y value; 0x3 for odd key.WriteByte(byte(0x2) + byte(y.Bit(0))) // Write X coord; Pad the key so x is aligned with the LSB. Pad size is key length - header size (1) - xBytes size xBytes := x.Bytes() for i := 0; i < (PublicKeyCompressedLength - 1 - len(xBytes)); i++ { key.WriteByte(0x0) } key.Write(xBytes) return key.Bytes() }
// SolovayStrassen chooses k random numbers in [2,...,N] // and checks that there was no // "Euler liar". That is, every number a we chose // satisfied a^((n-1)/2) = Jacobi(a/N) mod N. // See https://en.wikipedia.org/wiki/Solovay%E2%80%93Strassen_primality_test. // Probability it passes and is not prime is 2^(-k). func SolovayStrassen(N *big.Int, k int) int { if N.Bit(0) == 0 && N.BitLen() > 1 { return IsComposite } a := new(big.Int) b := make([]byte, N.BitLen()) for i := 0; i < k; i++ { rand.Read(b) a.SetBytes(b) if basedSolovayStrassen(N, a) == IsComposite { return IsComposite } } return Undetermined }