diff options
Diffstat (limited to 'libgo/go/math/big/int.go')
-rw-r--r-- | libgo/go/math/big/int.go | 48 |
1 files changed, 27 insertions, 21 deletions
diff --git a/libgo/go/math/big/int.go b/libgo/go/math/big/int.go index 67ab7042ff..1d8dabce12 100644 --- a/libgo/go/math/big/int.go +++ b/libgo/go/math/big/int.go @@ -361,7 +361,8 @@ func (x *Int) Uint64() uint64 { } // SetString sets z to the value of s, interpreted in the given base, -// and returns z and a boolean indicating success. If SetString fails, +// and returns z and a boolean indicating success. The entire string +// (not just a prefix) must be valid for success. If SetString fails, // the value of z is undefined but the returned value is nil. // // The base argument must be 0 or a value between 2 and MaxBase. If the base @@ -371,12 +372,11 @@ func (x *Int) Uint64() uint64 { // func (z *Int) SetString(s string, base int) (*Int, bool) { r := strings.NewReader(s) - _, _, err := z.scan(r, base) - if err != nil { + if _, _, err := z.scan(r, base); err != nil { return nil, false } - _, err = r.ReadByte() - if err != io.EOF { + // entire string must have been consumed + if _, err := r.ReadByte(); err != io.EOF { return nil, false } return z, true // err == io.EOF => scan consumed all of s @@ -404,8 +404,11 @@ func (x *Int) BitLen() int { // Exp sets z = x**y mod |m| (i.e. the sign of m is ignored), and returns z. // If y <= 0, the result is 1 mod |m|; if m == nil or m == 0, z = x**y. -// See Knuth, volume 2, section 4.6.3. +// +// Modular exponentation of inputs of a particular size is not a +// cryptographically constant-time operation. func (z *Int) Exp(x, y, m *Int) *Int { + // See Knuth, volume 2, section 4.6.3. var yWords nat if !y.neg { yWords = y.abs @@ -459,11 +462,11 @@ func (z *Int) GCD(x, y, a, b *Int) *Int { q := new(Int) temp := new(Int) + r := new(Int) for len(B.abs) > 0 { - r := new(Int) q, r = q.QuoRem(A, B, r) - A, B = B, r + A, B, r = B, r, A temp.Set(X) X.Mul(X, q) @@ -550,19 +553,6 @@ func (z *Int) binaryGCD(a, b *Int) *Int { return z.Lsh(u, k) } -// ProbablyPrime performs n Miller-Rabin tests to check whether x is prime. -// If x is prime, it returns true. -// If x is not prime, it returns false with probability at least 1 - ¼ⁿ. -// -// It is not suitable for judging primes that an adversary may have crafted -// to fool this test. -func (x *Int) ProbablyPrime(n int) bool { - if n <= 0 { - panic("non-positive n for ProbablyPrime") - } - return !x.neg && x.abs.probablyPrime(n) -} - // Rand sets z to a pseudo-random number in [0, n) and returns z. func (z *Int) Rand(rnd *rand.Rand, n *Int) *Int { z.neg = false @@ -577,6 +567,11 @@ func (z *Int) Rand(rnd *rand.Rand, n *Int) *Int { // ModInverse sets z to the multiplicative inverse of g in the ring ℤ/nℤ // and returns z. If g and n are not relatively prime, the result is undefined. func (z *Int) ModInverse(g, n *Int) *Int { + if g.neg { + // GCD expects parameters a and b to be > 0. + var g2 Int + g = g2.Mod(g, n) + } var d Int d.GCD(z, nil, g, n) // x and y are such that g*x + n*y = d. Since g and n are @@ -932,3 +927,14 @@ func (z *Int) Not(x *Int) *Int { z.neg = true // z cannot be zero if x is positive return z } + +// Sqrt sets z to ⌊√x⌋, the largest integer such that z² ≤ x, and returns z. +// It panics if x is negative. +func (z *Int) Sqrt(x *Int) *Int { + if x.neg { + panic("square root of negative number") + } + z.neg = false + z.abs = z.abs.sqrt(x.abs) + return z +} |