Beispiel #1
0
// 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
}
Beispiel #2
0
/*
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
}
Beispiel #3
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
}
Beispiel #4
0
// 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
}
Beispiel #5
0
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
}
Beispiel #6
0
// 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
}
Beispiel #7
0
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
}
Beispiel #9
0
func ScanLeftInt(x *big.Int) int {
	for k := 0; k < x.BitLen(); k += 1 {
		if x.Bit(k) != 0 {
			return k
		}
	}
	return -1
}
Beispiel #10
0
// 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
}
Beispiel #11
0
func findSetBit(s *big.Int, start int) int {
	for i := start; i < s.BitLen(); i++ {
		if s.Bit(i) == 1 {
			return i
		}
	}
	return -1
}
Beispiel #12
0
func FirstBitSet(v *big.Int) int {
	for i := 0; i < v.BitLen(); i++ {
		if v.Bit(i) > 0 {
			return i
		}
	}

	return v.BitLen()
}
Beispiel #13
0
// 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)
	}
}
Beispiel #14
0
// 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
	}
}
Beispiel #15
0
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")
	}
}
Beispiel #17
0
// 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
}
Beispiel #18
0
// 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
}
Beispiel #19
0
// 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
}
Beispiel #20
0
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()
}
Beispiel #21
0
//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))
	}
}
Beispiel #22
0
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
}
Beispiel #23
0
// 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
}
Beispiel #24
0
// 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
}
Beispiel #25
0
// 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
}
Beispiel #26
0
// 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
}
Beispiel #27
0
// 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
}
Beispiel #28
0
// 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
}
Beispiel #29
0
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()
}
Beispiel #30
0
// 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
}