From b71f0d05a6aa159969f1682e1e6660c81679972b Mon Sep 17 00:00:00 2001 From: Chris Stockton Date: Wed, 5 Jul 2017 23:36:23 -0700 Subject: [PATCH 1/2] Remove extraneous allocations. --- ff3/ff3.go | 74 ++++++++++++++++++++++++------------------------------ 1 file changed, 33 insertions(+), 41 deletions(-) diff --git a/ff3/ff3.go b/ff3/ff3.go index ae57e54..48e764e 100644 --- a/ff3/ff3.go +++ b/ff3/ff3.go @@ -215,6 +215,8 @@ func (f Cipher) Encrypt(X string) (string, error) { return ret, nil } +var zeros = make([]byte, 16) + // Decrypt decrypts the string X over the current FF3 parameters // and returns the plaintext of the same length and format func (f Cipher) Decrypt(X string) (string, error) { @@ -246,8 +248,16 @@ func (f Cipher) Decrypt(X string) (string, error) { Tl := f.tweak[:4] Tr := f.tweak[4:] + // cache for c + var ( + P bytes.Buffer + bmod, numA big.Int + br, bm, y, c big.Int + ) + // Main Feistel Round, 8 times for i := numRounds - 1; i >= 0; i-- { + P.Reset() var m uint32 var W []byte @@ -266,45 +276,38 @@ func (f Cipher) Decrypt(X string) (string, error) { if err != nil { return ret, err } - P := bytes.NewBuffer(xored) + P.Write(xored) - var numA *big.Int - numA, err = numRadix(rev(A), f.radix) - if err != nil { - return ret, err + _, ok := numA.SetString(rev(A), f.radix) + if !ok { + return ret, errors.New("numRadix failed") } numABytes := numA.Bytes() - - _, err = P.Write(append(make([]byte, 12-len(numABytes)), numABytes...)) - if err != nil { - return ret, err - } + P.Write(zeros[0 : 12-len(numABytes)]) + P.Write(numABytes) - // Calculate S // Calculate S S, err := f.ciph(revB(P.Bytes())) if err != nil { return ret, err } - copy(S[:], revB(S[:])) // Calculate y - y := big.NewInt(0) y.SetBytes(S[:]) // Calculate c - mod := big.NewInt(0) - mod.Exp(big.NewInt(int64(f.radix)), big.NewInt(int64(m)), nil) + br.SetInt64(int64(f.radix)) + bm.SetInt64(int64(m)) + bmod.Exp(&br, &bm, nil) - c, err := numRadix(rev(B), f.radix) - if err != nil { - return ret, err + _, ok = c.SetString(rev(B), f.radix) + if !ok { + return ret, errors.New("numRadix failed") } - - c.Sub(c, y) - c.Mod(c, mod) + c.Sub(&c, &y) + c.Mod(&c, &bmod) // Need to pad the text with leading 0s first to make sure it's the correct length C := c.Text(f.radix) @@ -327,14 +330,11 @@ func (f *Cipher) ciph(input []byte) ([]byte, error) { if len(input)%aes.BlockSize != 0 { return nil, errors.New("Length of ciph input must be multiple of 16") } - - ciphertext := make([]byte, len(input)) - f.cbcEncryptor.CryptBlocks(ciphertext, input) + f.cbcEncryptor.CryptBlocks(input, input) // Reset IV to 0 f.cbcEncryptor.(cbcMode).SetIV(ivZero[:]) - - return ciphertext, nil + return input, nil } // numRadix interprets a string of digits as a number. Same as ParseUint but using math/big library @@ -354,34 +354,26 @@ func xorBytes(a, b []byte) ([]byte, error) { if len(a) != len(b) { return nil, errors.New("inputs to xorBytes must be of same length") } - ret := make([]byte, len(a)) - for i := 0; i < len(a); i++ { - ret[i] = a[i] ^ b[i] + b[i] = a[i] ^ b[i] } - - return ret, nil + return b, nil } // Returns the reversed version of an arbitrary string func rev(s string) string { r := []rune(s) - for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 { r[i], r[j] = r[j], r[i] } - return string(r) } // Returns the reversed version of a byte array -func revB(in []byte) []byte { - out := make([]byte, len(in)) - - for i := len(in)/2 - 1; i >= 0; i-- { - opp := len(in) - 1 - i - out[i], out[opp] = in[opp], in[i] +func revB(a []byte) []byte { + for i := len(a)/2 - 1; i >= 0; i-- { + opp := len(a) - 1 - i + a[i], a[opp] = a[opp], a[i] } - - return out + return a } From 5d608ed48dedbeeb18017b93dbae8349234c4a2d Mon Sep 17 00:00:00 2001 From: Chris Stockton Date: Sat, 5 Aug 2017 17:16:49 -0700 Subject: [PATCH 2/2] update pull req as requested to use ivZero rather than zeros. --- ff3/ff3.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ff3/ff3.go b/ff3/ff3.go index 48e764e..5646aa0 100644 --- a/ff3/ff3.go +++ b/ff3/ff3.go @@ -215,8 +215,6 @@ func (f Cipher) Encrypt(X string) (string, error) { return ret, nil } -var zeros = make([]byte, 16) - // Decrypt decrypts the string X over the current FF3 parameters // and returns the plaintext of the same length and format func (f Cipher) Decrypt(X string) (string, error) { @@ -284,7 +282,7 @@ func (f Cipher) Decrypt(X string) (string, error) { } numABytes := numA.Bytes() - P.Write(zeros[0 : 12-len(numABytes)]) + P.Write(ivZero[0 : 12-len(numABytes)]) P.Write(numABytes) // Calculate S