// Int returns a uniform random value in [0, max). func Int(rand io.Reader, max *big.Int) (n *big.Int, err 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 }
func info(a *big.Int, n uint) { dtrunc := int64(float64(a.BitLen())*.30103) - 10 var first, rest big.Int rest.Exp(first.SetInt64(10), rest.SetInt64(dtrunc), nil) first.Quo(a, &rest) fstr := first.String() fmt.Printf("%d! begins %s... and has %d digits.\n", n, fstr, int64(len(fstr))+dtrunc) }
func intLength(n *big.Int) int { length := 4 /* length bytes */ if n.Sign() < 0 { nMinus1 := new(big.Int).Neg(n) nMinus1.Sub(nMinus1, bigOne) bitLen := nMinus1.BitLen() if bitLen%8 == 0 { // The number will need 0xff padding length++ } length += (bitLen + 7) / 8 } else if n.Sign() == 0 { // A zero is the zero length string } else { bitLen := n.BitLen() if bitLen%8 == 0 { // The number will need 0x00 padding length++ } length += (bitLen + 7) / 8 } return length }
// GenerateParameters puts a random, valid set of DSA parameters into params. // This function takes many seconds, even on fast machines. func GenerateParameters(params *Parameters, rand io.Reader, sizes ParameterSizes) (err os.Error) { // This function doesn't follow FIPS 186-3 exactly in that it doesn't // use a verification seed to generate the primes. The verification // seed doesn't appear to be exported or used by other code and // omitting it makes the code cleaner. var L, N int switch sizes { case L1024N160: L = 1024 N = 160 case L2048N224: L = 2048 N = 224 case L2048N256: L = 2048 N = 256 case L3072N256: L = 3072 N = 256 default: return os.ErrorString("crypto/dsa: invalid ParameterSizes") } qBytes := make([]byte, N/8) pBytes := make([]byte, L/8) q := new(big.Int) p := new(big.Int) rem := new(big.Int) one := new(big.Int) one.SetInt64(1) GeneratePrimes: for { _, err = io.ReadFull(rand, qBytes) if err != nil { return } qBytes[len(qBytes)-1] |= 1 qBytes[0] |= 0x80 q.SetBytes(qBytes) if !big.ProbablyPrime(q, numMRTests) { continue } for i := 0; i < 4*L; i++ { _, err = io.ReadFull(rand, pBytes) if err != nil { return } pBytes[len(pBytes)-1] |= 1 pBytes[0] |= 0x80 p.SetBytes(pBytes) rem.Mod(p, q) rem.Sub(rem, one) p.Sub(p, rem) if p.BitLen() < L { continue } if !big.ProbablyPrime(p, numMRTests) { continue } params.P = p params.Q = q break GeneratePrimes } } h := new(big.Int) h.SetInt64(2) g := new(big.Int) pm1 := new(big.Int).Sub(p, one) e := new(big.Int).Div(pm1, q) for { g.Exp(h, e, p) if g.Cmp(one) == 0 { h.Add(h, one) continue } params.G = g return } panic("unreachable") }
// writeBig serializes a *big.Int to w. func writeBig(w io.Writer, i *big.Int) os.Error { return writeMPI(w, uint16(i.BitLen()), i.Bytes()) }
func fromBig(n *big.Int) parsedMPI { return parsedMPI{ bytes: n.Bytes(), bitLength: uint16(n.BitLen()), } }
// mpiLength returns the length of the given *big.Int when serialized as an // MPI. func mpiLength(n *big.Int) (mpiLengthInBytes int) { mpiLengthInBytes = 2 /* MPI length */ mpiLengthInBytes += (n.BitLen() + 7) / 8 return }