diff options
Diffstat (limited to 'libgo/go/math/big/int.go')
-rw-r--r-- | libgo/go/math/big/int.go | 49 |
1 files changed, 37 insertions, 12 deletions
diff --git a/libgo/go/math/big/int.go b/libgo/go/math/big/int.go index dab9a5c..8e52f0a 100644 --- a/libgo/go/math/big/int.go +++ b/libgo/go/math/big/int.go @@ -401,16 +401,24 @@ func (x *Int) IsUint64() bool { // (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 -// is 0, the string prefix determines the actual conversion base. A prefix of -// ``0x'' or ``0X'' selects base 16; the ``0'' prefix selects base 8, and a -// ``0b'' or ``0B'' prefix selects base 2. Otherwise the selected base is 10. +// The base argument must be 0 or a value between 2 and MaxBase. +// For base 0, the number prefix determines the actual base: A prefix of +// ``0b'' or ``0B'' selects base 2, ``0'', ``0o'' or ``0O'' selects base 8, +// and ``0x'' or ``0X'' selects base 16. Otherwise, the selected base is 10 +// and no prefix is accepted. // // For bases <= 36, lower and upper case letters are considered the same: // The letters 'a' to 'z' and 'A' to 'Z' represent digit values 10 to 35. // For bases > 36, the upper case letters 'A' to 'Z' represent the digit // values 36 to 61. // +// For base 0, an underscore character ``_'' may appear between a base +// prefix and an adjacent digit, and between successive digits; such +// underscores do not change the value of the number. +// Incorrect placement of underscores is reported as an error if there +// are no other errors. If base != 0, underscores are not recognized +// and act like any other character that is not a valid digit. +// func (z *Int) SetString(s string, base int) (*Int, bool) { return z.setFromScanner(strings.NewReader(s), base) } @@ -448,8 +456,15 @@ func (x *Int) BitLen() int { return x.abs.bitLen() } +// TrailingZeroBits returns the number of consecutive least significant zero +// bits of |x|. +func (x *Int) TrailingZeroBits() uint { + return x.abs.trailingZeroBits() +} + // Exp sets z = x**y mod |m| (i.e. the sign of m is ignored), and returns z. -// If m == nil or m == 0, z = x**y unless y <= 0 then z = 1. +// If m == nil or m == 0, z = x**y unless y <= 0 then z = 1. If m > 0, y < 0, +// and x and n are not relatively prime, z is unchanged and nil is returned. // // Modular exponentation of inputs of a particular size is not a // cryptographically constant-time operation. @@ -461,7 +476,11 @@ func (z *Int) Exp(x, y, m *Int) *Int { return z.SetInt64(1) } // for y < 0: x**y mod m == (x**(-1))**|y| mod m - xWords = new(Int).ModInverse(x, m).abs + inverse := new(Int).ModInverse(x, m) + if inverse == nil { + return nil + } + xWords = inverse.abs } yWords := y.abs @@ -700,15 +719,21 @@ func (z *Int) lehmerGCD(x, y, a, b *Int) *Int { } } - if x != nil { - *x = *Ua - } - if y != nil { + // avoid aliasing b needed in the division below + if y == b { + B.Set(b) + } else { + B = b + } // y = (z - a*x)/b - y.Mul(a, Ua) + y.Mul(a, Ua) // y can safely alias a y.Sub(A, y) - y.Div(y, b) + y.Div(y, B) + } + + if x != nil { + *x = *Ua } *z = *A |