From: Robert Griesemer Date: Wed, 1 Feb 2012 19:43:40 +0000 (-0800) Subject: mat/big: add raw access to Int bits X-Git-Tag: weekly.2012-02-07~145 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=71c19b610f1f5c0d61cc339d122eba730fc78c71;p=gostls13.git mat/big: add raw access to Int bits This is a minimal API extension, it makes it possible to implement missing Int functionality externally w/o compromising efficiency. It is the hope that this will reduce the number of feature requests going directly into the big package. Also: Fixed some naming inconsistencies: The receiver is only called z when it is also the result. R=golang-dev, agl CC=golang-dev https://golang.org/cl/5607055 --- diff --git a/src/pkg/math/big/int.go b/src/pkg/math/big/int.go index 35e2e29418..3f6eacf624 100644 --- a/src/pkg/math/big/int.go +++ b/src/pkg/math/big/int.go @@ -65,6 +65,26 @@ func (z *Int) Set(x *Int) *Int { return z } +// Bits provides raw (unchecked but fast) access to x by returning its +// absolute value as a little-endian Word slice. The result and x share +// the same underlying array. +// Bits is intended to support implementation of missing low-level Int +// functionality outside this package; it should be avoided otherwise. +func (x *Int) Bits() []Word { + return x.abs +} + +// SetBits provides raw (unchecked but fast) access to z by setting its +// value to abs, interpreted as a little-endian Word slice, and returning +// z. The result and abs share the same underlying array. +// SetBits is intended to support implementation of missing low-level Int +// functionality outside this package; it should be avoided otherwise. +func (z *Int) SetBits(abs []Word) *Int { + z.abs = nat(abs).norm() + z.neg = false + return z +} + // Abs sets z to |x| (the absolute value of x) and returns z. func (z *Int) Abs(x *Int) *Int { z.Set(x) @@ -528,18 +548,18 @@ func (z *Int) SetBytes(buf []byte) *Int { } // Bytes returns the absolute value of z as a big-endian byte slice. -func (z *Int) Bytes() []byte { - buf := make([]byte, len(z.abs)*_S) - return buf[z.abs.bytes(buf):] +func (x *Int) Bytes() []byte { + buf := make([]byte, len(x.abs)*_S) + return buf[x.abs.bytes(buf):] } // BitLen returns the length of the absolute value of z in bits. // The bit length of 0 is 0. -func (z *Int) BitLen() int { - return z.abs.bitLen() +func (x *Int) BitLen() int { + return x.abs.bitLen() } -// Exp sets z = x**y mod m. If m is nil, z = x**y. +// Exp sets z = x**y mod m and returns z. If m is nil, z = x**y. // See Knuth, volume 2, section 4.6.3. func (z *Int) Exp(x, y, m *Int) *Int { if y.neg || len(y.abs) == 0 { @@ -617,11 +637,11 @@ func GcdInt(d, x, y, a, b *Int) { *d = *A } -// ProbablyPrime performs n Miller-Rabin tests to check whether z is prime. -// If it returns true, z is prime with probability 1 - 1/4^n. -// If it returns false, z is not prime. -func ProbablyPrime(z *Int, n int) bool { - return !z.neg && z.abs.probablyPrime(n) +// 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 { + return !x.neg && x.abs.probablyPrime(n) } // Rand sets z to a pseudo-random number in [0, n) and returns z. @@ -671,18 +691,18 @@ func (z *Int) Rsh(x *Int, n uint) *Int { return z } -// Bit returns the value of the i'th bit of z. That is, it -// returns (z>>i)&1. The bit index i must be >= 0. -func (z *Int) Bit(i int) uint { +// Bit returns the value of the i'th bit of x. That is, it +// returns (x>>i)&1. The bit index i must be >= 0. +func (x *Int) Bit(i int) uint { if i < 0 { panic("negative bit index") } - if z.neg { - t := nat(nil).sub(z.abs, natOne) + if x.neg { + t := nat(nil).sub(x.abs, natOne) return t.bit(uint(i)) ^ 1 } - return z.abs.bit(uint(i)) + return x.abs.bit(uint(i)) } // SetBit sets z to x, with x's i'th bit set to b (0 or 1). @@ -847,11 +867,11 @@ func (z *Int) Not(x *Int) *Int { const intGobVersion byte = 1 // GobEncode implements the gob.GobEncoder interface. -func (z *Int) GobEncode() ([]byte, error) { - buf := make([]byte, 1+len(z.abs)*_S) // extra byte for version and sign bit - i := z.abs.bytes(buf) - 1 // i >= 0 +func (x *Int) GobEncode() ([]byte, error) { + buf := make([]byte, 1+len(x.abs)*_S) // extra byte for version and sign bit + i := x.abs.bytes(buf) - 1 // i >= 0 b := intGobVersion << 1 // make space for sign bit - if z.neg { + if x.neg { b |= 1 } buf[i] = b