Commit b80c7e5d authored by Robert Griesemer's avatar Robert Griesemer

math/big: API, documentation cleanup

Fixes #2863.

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/5620058
parent aa716e36
...@@ -102,7 +102,7 @@ GeneratePrimes: ...@@ -102,7 +102,7 @@ GeneratePrimes:
qBytes[0] |= 0x80 qBytes[0] |= 0x80
q.SetBytes(qBytes) q.SetBytes(qBytes)
if !big.ProbablyPrime(q, numMRTests) { if !q.ProbablyPrime(numMRTests) {
continue continue
} }
...@@ -123,7 +123,7 @@ GeneratePrimes: ...@@ -123,7 +123,7 @@ GeneratePrimes:
continue continue
} }
if !big.ProbablyPrime(p, numMRTests) { if !p.ProbablyPrime(numMRTests) {
continue continue
} }
......
...@@ -39,7 +39,7 @@ func Prime(rand io.Reader, bits int) (p *big.Int, err error) { ...@@ -39,7 +39,7 @@ func Prime(rand io.Reader, bits int) (p *big.Int, err error) {
bytes[len(bytes)-1] |= 1 bytes[len(bytes)-1] |= 1
p.SetBytes(bytes) p.SetBytes(bytes)
if big.ProbablyPrime(p, 20) { if p.ProbablyPrime(20) {
return return
} }
} }
......
...@@ -62,7 +62,7 @@ func (priv *PrivateKey) Validate() error { ...@@ -62,7 +62,7 @@ func (priv *PrivateKey) Validate() error {
// ProbablyPrime are deterministic, given the candidate number, it's // ProbablyPrime are deterministic, given the candidate number, it's
// easy for an attack to generate composites that pass this test. // easy for an attack to generate composites that pass this test.
for _, prime := range priv.Primes { for _, prime := range priv.Primes {
if !big.ProbablyPrime(prime, 20) { if !prime.ProbablyPrime(20) {
return errors.New("prime factor is composite") return errors.New("prime factor is composite")
} }
} }
...@@ -85,7 +85,7 @@ func (priv *PrivateKey) Validate() error { ...@@ -85,7 +85,7 @@ func (priv *PrivateKey) Validate() error {
gcd := new(big.Int) gcd := new(big.Int)
x := new(big.Int) x := new(big.Int)
y := 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 { if gcd.Cmp(bigOne) != 0 {
return errors.New("invalid public exponent E") return errors.New("invalid public exponent E")
} }
...@@ -156,7 +156,7 @@ NextSetOfPrimes: ...@@ -156,7 +156,7 @@ NextSetOfPrimes:
priv.D = new(big.Int) priv.D = new(big.Int)
y := new(big.Int) y := new(big.Int)
e := big.NewInt(int64(priv.E)) 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 { if g.Cmp(bigOne) == 0 {
priv.D.Add(priv.D, totient) priv.D.Add(priv.D, totient)
...@@ -284,7 +284,7 @@ func modInverse(a, n *big.Int) (ia *big.Int, ok bool) { ...@@ -284,7 +284,7 @@ func modInverse(a, n *big.Int) (ia *big.Int, ok bool) {
g := new(big.Int) g := new(big.Int)
x := new(big.Int) x := new(big.Int)
y := 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 { if g.Cmp(bigOne) != 0 {
// In this case, a and n aren't coprime and we cannot calculate // In this case, a and n aren't coprime and we cannot calculate
// the inverse. This happens because the values of n are nearly // the inverse. This happens because the values of n are nearly
......
...@@ -211,6 +211,7 @@ func (z *Int) Rem(x, y *Int) *Int { ...@@ -211,6 +211,7 @@ func (z *Int) Rem(x, y *Int) *Int {
// r = x - y*q // r = x - y*q
// //
// (See Daan Leijen, ``Division and Modulus for Computer Scientists''.) // (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) { func (z *Int) QuoRem(x, y, r *Int) (*Int, *Int) {
z.abs, r.abs = z.abs.div(r.abs, x.abs, y.abs) 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 { ...@@ -268,6 +269,7 @@ func (z *Int) Mod(x, y *Int) *Int {
// div and mod''. ACM Transactions on Programming Languages and // div and mod''. ACM Transactions on Programming Languages and
// Systems (TOPLAS), 14(2):127-144, New York, NY, USA, 4/1992. // Systems (TOPLAS), 14(2):127-144, New York, NY, USA, 4/1992.
// ACM press.) // ACM press.)
// See QuoRem for T-division and modulus (like Go).
// //
func (z *Int) DivMod(x, y, m *Int) (*Int, *Int) { func (z *Int) DivMod(x, y, m *Int) (*Int, *Int) {
y0 := y // save y y0 := y // save y
...@@ -579,20 +581,20 @@ func (z *Int) Exp(x, y, m *Int) *Int { ...@@ -579,20 +581,20 @@ func (z *Int) Exp(x, y, m *Int) *Int {
return z return z
} }
// GcdInt sets d to the greatest common divisor of a and b, which must be // GCD sets z to the greatest common divisor of a and b, which must be
// positive numbers. // positive numbers, and returns z.
// If x and y are not nil, GcdInt sets x and y such that d = a*x + b*y. // 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, GcdInt sets d = x = y = 0. // If either a or b is not positive, GCD sets z = x = y = 0.
func GcdInt(d, x, y, a, b *Int) { func (z *Int) GCD(x, y, a, b *Int) *Int {
if a.neg || b.neg { if a.neg || b.neg {
d.SetInt64(0) z.SetInt64(0)
if x != nil { if x != nil {
x.SetInt64(0) x.SetInt64(0)
} }
if y != nil { if y != nil {
y.SetInt64(0) y.SetInt64(0)
} }
return return z
} }
A := new(Int).Set(a) A := new(Int).Set(a)
...@@ -634,13 +636,14 @@ func GcdInt(d, x, y, a, b *Int) { ...@@ -634,13 +636,14 @@ func GcdInt(d, x, y, a, b *Int) {
*y = *lastY *y = *lastY
} }
*d = *A *z = *A
return z
} }
// ProbablyPrime performs n Miller-Rabin tests to check whether x is prime. // 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 true, x is prime with probability 1 - 1/4^n.
// If it returns false, x is not prime. // 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) return !x.neg && x.abs.probablyPrime(n)
} }
...@@ -659,7 +662,7 @@ func (z *Int) Rand(rnd *rand.Rand, n *Int) *Int { ...@@ -659,7 +662,7 @@ func (z *Int) Rand(rnd *rand.Rand, n *Int) *Int {
// p is a prime) and returns z. // p is a prime) and returns z.
func (z *Int) ModInverse(g, p *Int) *Int { func (z *Int) ModInverse(g, p *Int) *Int {
var d 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 // 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. // that modulo p results in g*x = 1, therefore x is the inverse element.
if z.neg { if z.neg {
......
...@@ -824,7 +824,7 @@ func checkGcd(aBytes, bBytes []byte) bool { ...@@ -824,7 +824,7 @@ func checkGcd(aBytes, bBytes []byte) bool {
y := new(Int) y := new(Int)
d := new(Int) d := new(Int)
GcdInt(d, x, y, a, b) d.GCD(x, y, a, b)
x.Mul(x, a) x.Mul(x, a)
y.Mul(y, b) y.Mul(y, b)
x.Add(x, y) x.Add(x, y)
...@@ -852,7 +852,7 @@ func TestGcd(t *testing.T) { ...@@ -852,7 +852,7 @@ func TestGcd(t *testing.T) {
expectedY := NewInt(test.y) expectedY := NewInt(test.y)
expectedD := NewInt(test.d) expectedD := NewInt(test.d)
GcdInt(d, x, y, a, b) d.GCD(x, y, a, b)
if expectedX.Cmp(x) != 0 || if expectedX.Cmp(x) != 0 ||
expectedY.Cmp(y) != 0 || expectedY.Cmp(y) != 0 ||
...@@ -903,14 +903,14 @@ func TestProbablyPrime(t *testing.T) { ...@@ -903,14 +903,14 @@ func TestProbablyPrime(t *testing.T) {
} }
for i, s := range primes { for i, s := range primes {
p, _ := new(Int).SetString(s, 10) 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) t.Errorf("#%d prime found to be non-prime (%s)", i, s)
} }
} }
for i, s := range composites { for i, s := range composites {
c, _ := new(Int).SetString(s, 10) 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) t.Errorf("#%d composite found to be prime (%s)", i, s)
} }
if testing.Short() { if testing.Short() {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment