From 24b2f48a4a5abc4a35e0ddf104e1d22e6ba1cdaa Mon Sep 17 00:00:00 2001 From: Anthony Martin Date: Wed, 18 May 2011 18:55:06 -0700 Subject: [PATCH] crypto/rand: add utility functions for number generation This code is extracted from crypto/rsa with a few variables renamed and a comment fixed. R=agl, rsc, agl CC=golang-dev https://golang.org/cl/4446068 --- src/pkg/crypto/rand/Makefile | 1 + src/pkg/crypto/rand/util.go | 80 +++++++++++++++++++++++++++++++++ src/pkg/crypto/rsa/rsa.go | 86 +++++------------------------------- 3 files changed, 93 insertions(+), 74 deletions(-) create mode 100644 src/pkg/crypto/rand/util.go diff --git a/src/pkg/crypto/rand/Makefile b/src/pkg/crypto/rand/Makefile index 88b6d71e330..d1321297d9b 100644 --- a/src/pkg/crypto/rand/Makefile +++ b/src/pkg/crypto/rand/Makefile @@ -8,6 +8,7 @@ TARG=crypto/rand GOFILES=\ rand.go\ + util.go\ GOFILES_freebsd=\ rand_unix.go\ diff --git a/src/pkg/crypto/rand/util.go b/src/pkg/crypto/rand/util.go new file mode 100644 index 00000000000..77028476e4f --- /dev/null +++ b/src/pkg/crypto/rand/util.go @@ -0,0 +1,80 @@ +// 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< k-2*hash.Size()-2 { @@ -313,7 +251,7 @@ func EncryptOAEP(hash hash.Hash, rand io.Reader, pub *PublicKey, msg []byte, lab db[len(db)-len(msg)-1] = 1 copy(db[len(db)-len(msg):], msg) - _, err = io.ReadFull(rand, seed) + _, err = io.ReadFull(random, seed) if err != nil { return } @@ -405,7 +343,7 @@ func (priv *PrivateKey) Precompute() { // decrypt performs an RSA decryption, resulting in a plaintext integer. If a // random source is given, RSA blinding is used. -func decrypt(rand io.Reader, priv *PrivateKey, c *big.Int) (m *big.Int, err os.Error) { +func decrypt(random io.Reader, priv *PrivateKey, c *big.Int) (m *big.Int, err os.Error) { // TODO(agl): can we get away with reusing blinds? if c.Cmp(priv.N) > 0 { err = DecryptionError{} @@ -413,7 +351,7 @@ func decrypt(rand io.Reader, priv *PrivateKey, c *big.Int) (m *big.Int, err os.E } var ir *big.Int - if rand != nil { + if random != nil { // Blinding enabled. Blinding involves multiplying c by r^e. // Then the decryption operation performs (m^e * r^e)^d mod n // which equals mr mod n. The factor of r can then be removed @@ -422,7 +360,7 @@ func decrypt(rand io.Reader, priv *PrivateKey, c *big.Int) (m *big.Int, err os.E var r *big.Int for { - r, err = randomNumber(rand, priv.N) + r, err = rand.Int(random, priv.N) if err != nil { return } @@ -483,7 +421,7 @@ func decrypt(rand io.Reader, priv *PrivateKey, c *big.Int) (m *big.Int, err os.E // DecryptOAEP decrypts ciphertext using RSA-OAEP. // If rand != nil, DecryptOAEP uses RSA blinding to avoid timing side-channel attacks. -func DecryptOAEP(hash hash.Hash, rand io.Reader, priv *PrivateKey, ciphertext []byte, label []byte) (msg []byte, err os.Error) { +func DecryptOAEP(hash hash.Hash, random io.Reader, priv *PrivateKey, ciphertext []byte, label []byte) (msg []byte, err os.Error) { k := (priv.N.BitLen() + 7) / 8 if len(ciphertext) > k || k < hash.Size()*2+2 { @@ -493,7 +431,7 @@ func DecryptOAEP(hash hash.Hash, rand io.Reader, priv *PrivateKey, ciphertext [] c := new(big.Int).SetBytes(ciphertext) - m, err := decrypt(rand, priv, c) + m, err := decrypt(random, priv, c) if err != nil { return }