From b80c7e5dfd71508ed754ec2a02caa51f4444ba10 Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Thu, 2 Feb 2012 19:21:55 -0800 Subject: [PATCH] math/big: API, documentation cleanup Fixes #2863. R=golang-dev, rsc CC=golang-dev https://golang.org/cl/5620058 --- src/pkg/crypto/dsa/dsa.go | 4 ++-- src/pkg/crypto/rand/util.go | 2 +- src/pkg/crypto/rsa/rsa.go | 8 ++++---- src/pkg/math/big/int.go | 23 +++++++++++++---------- src/pkg/math/big/int_test.go | 8 ++++---- 5 files changed, 24 insertions(+), 21 deletions(-) diff --git a/src/pkg/crypto/dsa/dsa.go b/src/pkg/crypto/dsa/dsa.go index 7aaad1ca199..81487f68f41 100644 --- a/src/pkg/crypto/dsa/dsa.go +++ b/src/pkg/crypto/dsa/dsa.go @@ -102,7 +102,7 @@ GeneratePrimes: qBytes[0] |= 0x80 q.SetBytes(qBytes) - if !big.ProbablyPrime(q, numMRTests) { + if !q.ProbablyPrime(numMRTests) { continue } @@ -123,7 +123,7 @@ GeneratePrimes: continue } - if !big.ProbablyPrime(p, numMRTests) { + if !p.ProbablyPrime(numMRTests) { continue } diff --git a/src/pkg/crypto/rand/util.go b/src/pkg/crypto/rand/util.go index fc5fe6c65e9..5391c1829b9 100644 --- a/src/pkg/crypto/rand/util.go +++ b/src/pkg/crypto/rand/util.go @@ -39,7 +39,7 @@ func Prime(rand io.Reader, bits int) (p *big.Int, err error) { bytes[len(bytes)-1] |= 1 p.SetBytes(bytes) - if big.ProbablyPrime(p, 20) { + if p.ProbablyPrime(20) { return } } diff --git a/src/pkg/crypto/rsa/rsa.go b/src/pkg/crypto/rsa/rsa.go index c07e8f90db7..9f3e8a804aa 100644 --- a/src/pkg/crypto/rsa/rsa.go +++ b/src/pkg/crypto/rsa/rsa.go @@ -62,7 +62,7 @@ func (priv *PrivateKey) Validate() error { // ProbablyPrime are deterministic, given the candidate number, it's // easy for an attack to generate composites that pass this test. for _, prime := range priv.Primes { - if !big.ProbablyPrime(prime, 20) { + if !prime.ProbablyPrime(20) { return errors.New("prime factor is composite") } } @@ -85,7 +85,7 @@ func (priv *PrivateKey) Validate() error { gcd := new(big.Int) x := new(big.Int) y := new(big.Int) - big.GcdInt(gcd, x, y, totient, e) + gcd.GCD(x, y, totient, e) if gcd.Cmp(bigOne) != 0 { return errors.New("invalid public exponent E") } @@ -156,7 +156,7 @@ NextSetOfPrimes: priv.D = new(big.Int) y := new(big.Int) e := big.NewInt(int64(priv.E)) - big.GcdInt(g, priv.D, y, e, totient) + g.GCD(priv.D, y, e, totient) if g.Cmp(bigOne) == 0 { priv.D.Add(priv.D, totient) @@ -284,7 +284,7 @@ func modInverse(a, n *big.Int) (ia *big.Int, ok bool) { g := new(big.Int) x := new(big.Int) y := new(big.Int) - big.GcdInt(g, x, y, a, n) + g.GCD(x, y, a, n) if g.Cmp(bigOne) != 0 { // In this case, a and n aren't coprime and we cannot calculate // the inverse. This happens because the values of n are nearly diff --git a/src/pkg/math/big/int.go b/src/pkg/math/big/int.go index 3f6eacf6248..cd2cd0e2da0 100644 --- a/src/pkg/math/big/int.go +++ b/src/pkg/math/big/int.go @@ -211,6 +211,7 @@ func (z *Int) Rem(x, y *Int) *Int { // r = x - y*q // // (See Daan Leijen, ``Division and Modulus for Computer Scientists''.) +// See DivMod for Euclidean division and modulus (unlike Go). // func (z *Int) QuoRem(x, y, r *Int) (*Int, *Int) { z.abs, r.abs = z.abs.div(r.abs, x.abs, y.abs) @@ -268,6 +269,7 @@ func (z *Int) Mod(x, y *Int) *Int { // div and mod''. ACM Transactions on Programming Languages and // Systems (TOPLAS), 14(2):127-144, New York, NY, USA, 4/1992. // ACM press.) +// See QuoRem for T-division and modulus (like Go). // func (z *Int) DivMod(x, y, m *Int) (*Int, *Int) { y0 := y // save y @@ -579,20 +581,20 @@ func (z *Int) Exp(x, y, m *Int) *Int { return z } -// GcdInt sets d to the greatest common divisor of a and b, which must be -// positive numbers. -// If x and y are not nil, GcdInt sets x and y such that d = a*x + b*y. -// If either a or b is not positive, GcdInt sets d = x = y = 0. -func GcdInt(d, x, y, a, b *Int) { +// GCD sets z to the greatest common divisor of a and b, which must be +// positive numbers, and returns z. +// If x and y are not nil, GCD sets x and y such that z = a*x + b*y. +// If either a or b is not positive, GCD sets z = x = y = 0. +func (z *Int) GCD(x, y, a, b *Int) *Int { if a.neg || b.neg { - d.SetInt64(0) + z.SetInt64(0) if x != nil { x.SetInt64(0) } if y != nil { y.SetInt64(0) } - return + return z } A := new(Int).Set(a) @@ -634,13 +636,14 @@ func GcdInt(d, x, y, a, b *Int) { *y = *lastY } - *d = *A + *z = *A + return z } // ProbablyPrime performs n Miller-Rabin tests to check whether x is prime. // If it returns true, x is prime with probability 1 - 1/4^n. // If it returns false, x is not prime. -func ProbablyPrime(x *Int, n int) bool { +func (x *Int) ProbablyPrime(n int) bool { return !x.neg && x.abs.probablyPrime(n) } @@ -659,7 +662,7 @@ func (z *Int) Rand(rnd *rand.Rand, n *Int) *Int { // p is a prime) and returns z. func (z *Int) ModInverse(g, p *Int) *Int { var d Int - GcdInt(&d, z, nil, g, p) + d.GCD(z, nil, g, p) // x and y are such that g*x + p*y = d. Since p is prime, d = 1. Taking // that modulo p results in g*x = 1, therefore x is the inverse element. if z.neg { diff --git a/src/pkg/math/big/int_test.go b/src/pkg/math/big/int_test.go index 9c4b7301874..9700a9b5a7c 100644 --- a/src/pkg/math/big/int_test.go +++ b/src/pkg/math/big/int_test.go @@ -824,7 +824,7 @@ func checkGcd(aBytes, bBytes []byte) bool { y := new(Int) d := new(Int) - GcdInt(d, x, y, a, b) + d.GCD(x, y, a, b) x.Mul(x, a) y.Mul(y, b) x.Add(x, y) @@ -852,7 +852,7 @@ func TestGcd(t *testing.T) { expectedY := NewInt(test.y) expectedD := NewInt(test.d) - GcdInt(d, x, y, a, b) + d.GCD(x, y, a, b) if expectedX.Cmp(x) != 0 || expectedY.Cmp(y) != 0 || @@ -903,14 +903,14 @@ func TestProbablyPrime(t *testing.T) { } for i, s := range primes { p, _ := new(Int).SetString(s, 10) - if !ProbablyPrime(p, nreps) { + if !p.ProbablyPrime(nreps) { t.Errorf("#%d prime found to be non-prime (%s)", i, s) } } for i, s := range composites { c, _ := new(Int).SetString(s, 10) - if ProbablyPrime(c, nreps) { + if c.ProbablyPrime(nreps) { t.Errorf("#%d composite found to be prime (%s)", i, s) } if testing.Short() {