diff options
author | Adam Langley <agl@golang.org> | 2009-11-11 13:21:37 -0800 |
---|---|---|
committer | Adam Langley <agl@golang.org> | 2009-11-11 13:21:37 -0800 |
commit | e89d9b71bef704c7f84c437fff6619f6cc5adb53 (patch) | |
tree | 95b44ecdc9b12116f07f2d81a813a63c9b5ec852 /src/pkg/crypto | |
parent | 4c020d2d45e4077ca07d7c275fe8ff29a6c5361f (diff) | |
download | golang-e89d9b71bef704c7f84c437fff6619f6cc5adb53.tar.gz |
Reland a112249da741, this time with missing file.
Diffstat (limited to 'src/pkg/crypto')
-rw-r--r-- | src/pkg/crypto/rsa/rsa.go | 64 | ||||
-rw-r--r-- | src/pkg/crypto/rsa/rsa_test.go | 22 |
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; |