Esempio n. 1
0
// randomSafePrime returns a number, p, of the given size, such that p and
// (p-1)/2 are both prime with high probability.
func randomSafePrime(rand io.Reader, bits int) (p *big.Int, err os.Error) {
	if bits < 1 {
		err = os.EINVAL
	}

	bytes := make([]byte, (bits+7)/8)
	p = new(big.Int)
	p2 := new(big.Int)

	for {
		_, err = io.ReadFull(rand, bytes)
		if err != nil {
			return
		}

		// Don't let the value be too small.
		bytes[0] |= 0x80
		// Make the value odd since an even number this large certainly isn't prime.
		bytes[len(bytes)-1] |= 1

		p.SetBytes(bytes)
		if big.ProbablyPrime(p, 20) {
			p2.Rsh(p, 1) // p2 = (p - 1)/2
			if big.ProbablyPrime(p2, 20) {
				return
			}
		}
	}

	return
}
func binomial(p *primes.Sieve, n, k uint64) *big.Int {

	var r big.Int
	if k > n {
		return &r
	}

	if k > n/2 {
		k = n - k
	}

	if k < 3 {
		switch k {
		case 0:
			return r.SetInt64(1)
		case 1:
			return r.SetInt64(int64(n))
		case 2:
			var n1 big.Int
			return r.Rsh(r.Mul(r.SetInt64(int64(n)), n1.SetInt64(int64(n-1))), 1)
		}
	}

	var i int
	rootN := xmath.FloorSqrt(n)
	factors := make([]uint64, n)

	p.IteratePrimes(2, rootN, func(p uint64) {
		var r, nn, kk uint64 = 0, n, k
		for nn > 0 {
			if nn%p < kk%p+r {
				r = 1
				factors[i] = p
				i++
			} else {
				r = 0
			}
			nn /= p
			kk /= p
		}
	})

	p.IteratePrimes(rootN+1, n/2, func(p uint64) {
		if n%p < k%p {
			factors[i] = p
			i++
		}
	})

	p.IteratePrimes(n-k+1, n, func(p uint64) {
		factors[i] = p
		i++
	})

	return xmath.Product(factors[0:i])
}
Esempio n. 3
0
// hashToInt converts a hash value to an integer. There is some disagreement
// about how this is done. [NSA] suggests that this is done in the obvious
// manner, but [SECG] truncates the hash to the bit-length of the curve order
// first. We follow [SECG] because that's what OpenSSL does.
func hashToInt(hash []byte, c *elliptic.Curve) *big.Int {
	orderBits := c.N.BitLen()
	orderBytes := (orderBits + 7) / 8
	if len(hash) > orderBytes {
		hash = hash[:orderBytes]
	}

	ret := new(big.Int).SetBytes(hash)
	excess := orderBytes*8 - orderBits
	if excess > 0 {
		ret.Rsh(ret, uint(excess))
	}
	return ret
}
Esempio n. 4
0
func bitwise_arithmetic_shift_right(x, y Obj) Obj {
	xfx := (uintptr(unsafe.Pointer(x)) & fixnum_mask) == fixnum_tag
	yfx := (uintptr(unsafe.Pointer(y)) & fixnum_mask) == fixnum_tag
	if !yfx {
		panic("bad shift amount")
	}
	// TODO: check the amount. shouldn't be negative, and perhaps
	// '>>' does a modulo on the amount.
	amount := uint(uintptr(unsafe.Pointer(y)) >> fixnum_shift)
	if xfx {
		i1 := uintptr(unsafe.Pointer(x)) >> fixnum_shift
		return Obj(unsafe.Pointer(uintptr(((i1 >> amount) << fixnum_shift) | fixnum_tag)))
	} else if (uintptr(unsafe.Pointer(x)) & heap_mask) != heap_tag {
		panic("bad type")
	}

	switch vx := (*x).(type) {
	case *big.Int:
		var z *big.Int = big.NewInt(0)
		return wrap(z.Rsh(vx, amount))
	}
	panic("bad type")
}