src/pkg/crypto/rand/util.go - The Go Programming Language

Golang

Source file src/pkg/crypto/rand/util.go

     1	// Copyright 2011 The Go Authors.  All rights reserved.
     2	// Use of this source code is governed by a BSD-style
     3	// license that can be found in the LICENSE file.
     4	
     5	package rand
     6	
     7	import (
     8		"errors"
     9		"io"
    10		"math/big"
    11	)
    12	
    13	// Prime returns a number, p, of the given size, such that p is prime
    14	// with high probability.
    15	func Prime(rand io.Reader, bits int) (p *big.Int, err error) {
    16		if bits < 1 {
    17			err = errors.New("crypto/rand: prime size must be positive")
    18		}
    19	
    20		b := uint(bits % 8)
    21		if b == 0 {
    22			b = 8
    23		}
    24	
    25		bytes := make([]byte, (bits+7)/8)
    26		p = new(big.Int)
    27	
    28		for {
    29			_, err = io.ReadFull(rand, bytes)
    30			if err != nil {
    31				return nil, err
    32			}
    33	
    34			// Clear bits in the first byte to make sure the candidate has a size <= bits.
    35			bytes[0] &= uint8(int(1<<b) - 1)
    36			// Don't let the value be too small, i.e, set the most significant bit.
    37			bytes[0] |= 1 << (b - 1)
    38			// Make the value odd since an even number this large certainly isn't prime.
    39			bytes[len(bytes)-1] |= 1
    40	
    41			p.SetBytes(bytes)
    42			if p.ProbablyPrime(20) {
    43				return
    44			}
    45		}
    46	
    47		return
    48	}
    49	
    50	// Int returns a uniform random value in [0, max).
    51	func Int(rand io.Reader, max *big.Int) (n *big.Int, err error) {
    52		k := (max.BitLen() + 7) / 8
    53	
    54		// b is the number of bits in the most significant byte of max.
    55		b := uint(max.BitLen() % 8)
    56		if b == 0 {
    57			b = 8
    58		}
    59	
    60		bytes := make([]byte, k)
    61		n = new(big.Int)
    62	
    63		for {
    64			_, err = io.ReadFull(rand, bytes)
    65			if err != nil {
    66				return nil, err
    67			}
    68	
    69			// Clear bits in the first byte to increase the probability
    70			// that the candidate is < max.
    71			bytes[0] &= uint8(int(1<<b) - 1)
    72	
    73			n.SetBytes(bytes)
    74			if n.Cmp(max) < 0 {
    75				return
    76			}
    77		}
    78	
    79		return
    80	}