| // Copyright 2011 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package rand |
| |
| import ( |
| "big" |
| "io" |
| "os" |
| ) |
| |
| // Prime returns a number, p, of the given size, such that p is prime |
| // with high probability. |
| func Prime(rand io.Reader, bits int) (p *big.Int, err os.Error) { |
| if bits < 1 { |
| err = os.EINVAL |
| } |
| |
| b := uint(bits % 8) |
| if b == 0 { |
| b = 8 |
| } |
| |
| bytes := make([]byte, (bits+7)/8) |
| p = new(big.Int) |
| |
| for { |
| _, err = io.ReadFull(rand, bytes) |
| if err != nil { |
| return nil, err |
| } |
| |
| // Clear bits in the first byte to make sure the candidate has a size <= bits. |
| bytes[0] &= uint8(int(1<<b) - 1) |
| // Don't let the value be too small, i.e, set the most significant bit. |
| bytes[0] |= 1 << (b - 1) |
| // 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) { |
| return |
| } |
| } |
| |
| return |
| } |
| |
| // Int returns a uniform random value in [0, max). |
| func Int(rand io.Reader, max *big.Int) (n *big.Int, err os.Error) { |
| k := (max.BitLen() + 7) / 8 |
| |
| // b is the number of bits in the most significant byte of max. |
| b := uint(max.BitLen() % 8) |
| if b == 0 { |
| b = 8 |
| } |
| |
| bytes := make([]byte, k) |
| n = new(big.Int) |
| |
| for { |
| _, err = io.ReadFull(rand, bytes) |
| if err != nil { |
| return nil, err |
| } |
| |
| // Clear bits in the first byte to increase the probability |
| // that the candidate is < max. |
| bytes[0] &= uint8(int(1<<b) - 1) |
| |
| n.SetBytes(bytes) |
| if n.Cmp(max) < 0 { |
| return |
| } |
| } |
| |
| return |
| } |