summaryrefslogtreecommitdiff
path: root/src/pkg/crypto
diff options
context:
space:
mode:
authorAdam Langley <agl@golang.org>2009-11-11 13:21:37 -0800
committerAdam Langley <agl@golang.org>2009-11-11 13:21:37 -0800
commite89d9b71bef704c7f84c437fff6619f6cc5adb53 (patch)
tree95b44ecdc9b12116f07f2d81a813a63c9b5ec852 /src/pkg/crypto
parent4c020d2d45e4077ca07d7c275fe8ff29a6c5361f (diff)
downloadgolang-e89d9b71bef704c7f84c437fff6619f6cc5adb53.tar.gz
Reland a112249da741, this time with missing file.
Diffstat (limited to 'src/pkg/crypto')
-rw-r--r--src/pkg/crypto/rsa/rsa.go64
-rw-r--r--src/pkg/crypto/rsa/rsa_test.go22
2 files changed, 35 insertions, 51 deletions
diff --git a/src/pkg/crypto/rsa/rsa.go b/src/pkg/crypto/rsa/rsa.go
index e425cf91c..42a888835 100644
--- a/src/pkg/crypto/rsa/rsa.go
+++ b/src/pkg/crypto/rsa/rsa.go
@@ -19,15 +19,11 @@ import (
var bigZero = big.NewInt(0)
var bigOne = big.NewInt(1)
-/*
-
-TODO(agl): Enable once big implements ProbablyPrime.
-
// 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;
+ err = os.EINVAL
}
bytes := make([]byte, (bits+7)/8);
@@ -37,7 +33,7 @@ func randomSafePrime(rand io.Reader, bits int) (p *big.Int, err os.Error) {
for {
_, err = io.ReadFull(rand, bytes);
if err != nil {
- return;
+ return
}
// Don't let the value be too small.
@@ -46,10 +42,10 @@ func randomSafePrime(rand io.Reader, bits int) (p *big.Int, err os.Error) {
bytes[len(bytes)-1] |= 1;
p.SetBytes(bytes);
- if p.ProbablyPrime(20) {
+ if big.ProbablyPrime(p, 20) {
p2.Rsh(p, 1); // p2 = (p - 1)/2
- if p2.ProbablyPrime(20) {
- return;
+ if big.ProbablyPrime(p2, 20) {
+ return
}
}
}
@@ -57,8 +53,6 @@ func randomSafePrime(rand io.Reader, bits int) (p *big.Int, err os.Error) {
return;
}
-*/
-
// randomNumber returns a uniform random value in [0, max).
func randomNumber(rand io.Reader, max *big.Int) (n *big.Int, err os.Error) {
k := (max.Len() + 7) / 8;
@@ -84,7 +78,7 @@ func randomNumber(rand io.Reader, max *big.Int) (n *big.Int, err os.Error) {
bytes[0] &= uint8(int(1<<r) - 1);
n.SetBytes(bytes);
- if big.CmpInt(n, max) < 0 {
+ if n.Cmp(max) < 0 {
return
}
}
@@ -109,20 +103,20 @@ type PrivateKey struct {
// It returns nil if the key is valid, or else an os.Error describing a problem.
func (priv PrivateKey) Validate() os.Error {
- /*
- TODO(agl): Enable once big implements ProbablyPrime.
+ // Check that p and q are prime. Note that this is just a sanity
+ // check. Since the random witnesses chosen by ProbablyPrime are
+ // deterministic, given the candidate number, it's easy for an attack
+ // to generate composites that pass this test.
+ if !big.ProbablyPrime(priv.P, 20) {
+ return os.ErrorString("P is composite")
+ }
+ if !big.ProbablyPrime(priv.Q, 20) {
+ return os.ErrorString("Q is composite")
+ }
- // Check that p and q are prime.
- if !priv.P.ProbablyPrime(20) {
- return os.ErrorString("P is composite");
- }
- if !priv.Q.ProbablyPrime(20) {
- return os.ErrorString("Q is composite");
- }
- */
// Check that p*q == n.
modulus := new(big.Int).Mul(priv.P, priv.Q);
- if big.CmpInt(modulus, priv.N) != 0 {
+ if modulus.Cmp(priv.N) != 0 {
return os.ErrorString("invalid modulus")
}
// Check that e and totient(p, q) are coprime.
@@ -134,20 +128,18 @@ func (priv PrivateKey) Validate() os.Error {
x := new(big.Int);
y := new(big.Int);
big.GcdInt(gcd, x, y, totient, e);
- if big.CmpInt(gcd, bigOne) != 0 {
+ if gcd.Cmp(bigOne) != 0 {
return os.ErrorString("invalid public exponent E")
}
// Check that de ≡ 1 (mod totient(p, q))
de := new(big.Int).Mul(priv.D, e);
de.Mod(de, totient);
- if big.CmpInt(de, bigOne) != 0 {
+ if de.Cmp(bigOne) != 0 {
return os.ErrorString("invalid private exponent D")
}
return nil;
}
-/*
-
// GenerateKeyPair generates an RSA keypair of the given bit size.
func GenerateKey(rand io.Reader, bits int) (priv *PrivateKey, err os.Error) {
priv = new(PrivateKey);
@@ -168,16 +160,16 @@ func GenerateKey(rand io.Reader, bits int) (priv *PrivateKey, err os.Error) {
for {
p, err := randomSafePrime(rand, bits/2);
if err != nil {
- return;
+ return
}
q, err := randomSafePrime(rand, bits/2);
if err != nil {
- return;
+ return
}
- if big.CmpInt(p, q) == 0 {
- continue;
+ if p.Cmp(q) == 0 {
+ continue
}
n := new(big.Int).Mul(p, q);
@@ -191,7 +183,7 @@ func GenerateKey(rand io.Reader, bits int) (priv *PrivateKey, err os.Error) {
e := big.NewInt(int64(priv.E));
big.GcdInt(g, priv.D, y, e, totient);
- if big.CmpInt(g, bigOne) == 0 {
+ if g.Cmp(bigOne) == 0 {
priv.D.Add(priv.D, totient);
priv.P = p;
priv.Q = q;
@@ -204,8 +196,6 @@ func GenerateKey(rand io.Reader, bits int) (priv *PrivateKey, err os.Error) {
return;
}
-*/
-
// incCounter increments a four byte, big-endian counter.
func incCounter(c *[4]byte) {
if c[3]++; c[3] != 0 {
@@ -305,7 +295,7 @@ func modInverse(a, n *big.Int) (ia *big.Int) {
x := new(big.Int);
y := new(big.Int);
big.GcdInt(g, x, y, a, n);
- if big.CmpInt(x, bigOne) < 0 {
+ if x.Cmp(bigOne) < 0 {
// 0 is not the multiplicative inverse of any element so, if x
// < 1, then x is negative.
x.Add(x, n)
@@ -318,7 +308,7 @@ func modInverse(a, n *big.Int) (ia *big.Int) {
// random source is given, RSA blinding is used.
func decrypt(rand io.Reader, priv *PrivateKey, c *big.Int) (m *big.Int, err os.Error) {
// TODO(agl): can we get away with reusing blinds?
- if big.CmpInt(c, priv.N) > 0 {
+ if c.Cmp(priv.N) > 0 {
err = DecryptionError{};
return;
}
@@ -335,7 +325,7 @@ func decrypt(rand io.Reader, priv *PrivateKey, c *big.Int) (m *big.Int, err os.E
err = err1;
return;
}
- if big.CmpInt(r, bigZero) == 0 {
+ if r.Cmp(bigZero) == 0 {
r = bigOne
}
ir = modInverse(r, priv.N);
diff --git a/src/pkg/crypto/rsa/rsa_test.go b/src/pkg/crypto/rsa/rsa_test.go
index feeefd476..ae1aa3e71 100644
--- a/src/pkg/crypto/rsa/rsa_test.go
+++ b/src/pkg/crypto/rsa/rsa_test.go
@@ -12,42 +12,36 @@ import (
"testing";
)
-/*
-
-TODO(agl): Enable once big implements ProbablyPrime.
-
func TestKeyGeneration(t *testing.T) {
urandom, err := os.Open("/dev/urandom", os.O_RDONLY, 0);
if err != nil {
- t.Errorf("failed to open /dev/urandom");
+ t.Errorf("failed to open /dev/urandom")
}
priv, err := GenerateKey(urandom, 16);
if err != nil {
- t.Errorf("failed to generate key");
+ t.Errorf("failed to generate key")
}
pub := &priv.PublicKey;
m := big.NewInt(42);
c := encrypt(new(big.Int), pub, m);
m2, err := decrypt(nil, priv, c);
if err != nil {
- t.Errorf("error while decrypting: %s", err);
+ t.Errorf("error while decrypting: %s", err)
}
- if big.CmpInt(m, m2) != 0 {
- t.Errorf("got:%v, want:%v (%s)", m2, m, priv);
+ if m.Cmp(m2) != 0 {
+ t.Errorf("got:%v, want:%v (%s)", m2, m, priv)
}
m3, err := decrypt(urandom, priv, c);
if err != nil {
- t.Errorf("error while decrypting (blind): %s", err);
+ t.Errorf("error while decrypting (blind): %s", err)
}
- if big.CmpInt(m, m3) != 0 {
- t.Errorf("(blind) got:%v, want:%v", m3, m);
+ if m.Cmp(m3) != 0 {
+ t.Errorf("(blind) got:%v, want:%v", m3, m)
}
}
-*/
-
type testEncryptOAEPMessage struct {
in []byte;
seed []byte;