Commit b9caa4ac authored by Robert Griesemer's avatar Robert Griesemer

big: completed set of Int division routines & cleanups

- renamed Len -> BitLen, simplified implementation
- renamed old Div, Mod, DivMod -> Que, Rem, QuoRem
- implemented Div, Mod, DivMod (Euclidian definition, more
  useful in a mathematical context)
- fixed a bug in Exp (-0 was possible)
- added extra tests to check normalized results everywhere
- uniformly set Int.neg flag at the end of computations
- minor cosmetic cleanups
- ran all tests

R=rsc
CC=golang-dev
https://golang.org/cl/1091041
parent 32df6788
This diff is collapsed.
This diff is collapsed.
......@@ -356,7 +356,7 @@ func karatsuba(z, x, y nat) {
// alias returns true if x and y share the same base array.
func alias(x, y nat) bool {
return &x[0:cap(x)][cap(x)-1] == &y[0:cap(y)][cap(y)-1]
return cap(x) > 0 && cap(y) > 0 && &x[0:cap(x)][cap(x)-1] == &y[0:cap(y)][cap(y)-1]
}
......@@ -412,7 +412,7 @@ func (z nat) mul(x, y nat) nat {
// m >= n > 1
// determine if z can be reused
if len(z) > 0 && (alias(z, x) || alias(z, y)) {
if alias(z, x) || alias(z, y) {
z = nil // z is an alias for x or y - cannot reuse
}
......@@ -757,7 +757,7 @@ func (z nat) shl(x nat, s uint) nat {
// determine if z can be reused
// TODO(gri) change shlVW so we don't need this
if len(z) > 0 && alias(z, x) {
if alias(z, x) {
z = nil // z is an alias for x - cannot reuse
}
......@@ -780,7 +780,7 @@ func (z nat) shr(x nat, s uint) nat {
// determine if z can be reused
// TODO(gri) change shrVW so we don't need this
if len(z) > 0 && alias(z, x) {
if alias(z, x) {
z = nil // z is an alias for x - cannot reuse
}
......
......@@ -253,7 +253,7 @@ func (x *Integer) QuoRem(y *Integer) (*Integer, *Integer) {
// Div and Mod implement Euclidian division and modulus:
//
// q = x.Div(y)
// r = x.Mod(y) with: 0 <= r < |q| and: y = x*q + r
// r = x.Mod(y) with: 0 <= r < |q| and: x = y*q + r
//
// (Raymond T. Boute, ``The Euclidian definition of the functions
// div and mod''. ACM Transactions on Programming Languages and
......
......@@ -18,7 +18,7 @@ import (
// WARNING: use of this function to encrypt plaintexts other than session keys
// is dangerous. Use RSA OAEP in new protocols.
func EncryptPKCS1v15(rand io.Reader, pub *PublicKey, msg []byte) (out []byte, err os.Error) {
k := (pub.N.Len() + 7) / 8
k := (pub.N.BitLen() + 7) / 8
if len(msg) > k-11 {
err = MessageTooLongError{}
return
......@@ -66,7 +66,7 @@ func DecryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) (out [
// Encryption Standard PKCS #1'', Daniel Bleichenbacher, Advances in Cryptology
// (Crypto '98),
func DecryptPKCS1v15SessionKey(rand io.Reader, priv *PrivateKey, ciphertext []byte, key []byte) (err os.Error) {
k := (priv.N.Len() + 7) / 8
k := (priv.N.BitLen() + 7) / 8
if k-(len(key)+3+8) < 0 {
err = DecryptionError{}
return
......@@ -83,7 +83,7 @@ func DecryptPKCS1v15SessionKey(rand io.Reader, priv *PrivateKey, ciphertext []by
}
func decryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) (valid int, msg []byte, err os.Error) {
k := (priv.N.Len() + 7) / 8
k := (priv.N.BitLen() + 7) / 8
if k < 11 {
err = DecryptionError{}
return
......@@ -179,7 +179,7 @@ func SignPKCS1v15(rand io.Reader, priv *PrivateKey, hash PKCS1v15Hash, hashed []
}
tLen := len(prefix) + hashLen
k := (priv.N.Len() + 7) / 8
k := (priv.N.BitLen() + 7) / 8
if k < tLen+11 {
return nil, MessageTooLongError{}
}
......@@ -212,7 +212,7 @@ func VerifyPKCS1v15(pub *PublicKey, hash PKCS1v15Hash, hashed []byte, sig []byte
}
tLen := len(prefix) + hashLen
k := (pub.N.Len() + 7) / 8
k := (pub.N.BitLen() + 7) / 8
if k < tLen+11 {
err = VerificationError{}
return
......
......@@ -67,7 +67,7 @@ func TestEncryptPKCS1v15(t *testing.T) {
if err != nil {
t.Errorf("Failed to open /dev/urandom")
}
k := (rsaPrivateKey.N.Len() + 7) / 8
k := (rsaPrivateKey.N.BitLen() + 7) / 8
tryEncryptDecrypt := func(in []byte, blind bool) bool {
if len(in) > k-11 {
......
......@@ -50,11 +50,11 @@ func randomPrime(rand io.Reader, bits int) (p *big.Int, err os.Error) {
// randomNumber returns a uniform random value in [0, max).
func randomNumber(rand io.Reader, max *big.Int) (n *big.Int, err os.Error) {
k := (max.Len() + 7) / 8
k := (max.BitLen() + 7) / 8
// r is the number of bits in the used in the most significant byte of
// max.
r := uint(max.Len() % 8)
r := uint(max.BitLen() % 8)
if r == 0 {
r = 8
}
......@@ -244,7 +244,7 @@ func encrypt(c *big.Int, pub *PublicKey, m *big.Int) *big.Int {
// twice the hash length plus 2.
func EncryptOAEP(hash hash.Hash, rand io.Reader, pub *PublicKey, msg []byte, label []byte) (out []byte, err os.Error) {
hash.Reset()
k := (pub.N.Len() + 7) / 8
k := (pub.N.BitLen() + 7) / 8
if len(msg) > k-2*hash.Size()-2 {
err = MessageTooLongError{}
return
......@@ -365,7 +365,7 @@ func decrypt(rand io.Reader, priv *PrivateKey, c *big.Int) (m *big.Int, err os.E
// DecryptOAEP decrypts ciphertext using RSA-OAEP.
// If rand != nil, DecryptOAEP uses RSA blinding to avoid timing side-channel attacks.
func DecryptOAEP(hash hash.Hash, rand io.Reader, priv *PrivateKey, ciphertext []byte, label []byte) (msg []byte, err os.Error) {
k := (priv.N.Len() + 7) / 8
k := (priv.N.BitLen() + 7) / 8
if len(ciphertext) > k ||
k < hash.Size()*2+2 {
err = DecryptionError{}
......
......@@ -81,8 +81,8 @@ func extract_digit() int64 {
func next_term(k int64) {
// TODO(eds) If big.Int ever gets a Scale method, y2 and bigk could be int64
y2.New(k*2 + 1)
bigk.New(k)
y2.SetInt64(k*2 + 1)
bigk.SetInt64(k)
tmp1.Lsh(numer, 1)
accum.Add(accum, tmp1)
......
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