summaryrefslogtreecommitdiff
path: root/libgo/go/math/big/int.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/math/big/int.go')
-rw-r--r--libgo/go/math/big/int.go48
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
+}