// 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]) }
// 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 }
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") }