Skip to content

Commit

Permalink
Merge pull request #11 from tdakkota/feat/optmize-allocations
Browse files Browse the repository at this point in the history
feat(ige): reduce allocations for DecryptBlocks/EncryptBlocks
  • Loading branch information
ernado authored Jun 6, 2021
2 parents c397ab8 + 05915c8 commit 56a70f4
Show file tree
Hide file tree
Showing 6 changed files with 151 additions and 2 deletions.
22 changes: 22 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# IntelliJ project files
.idea
*.iml
out
gen
### Go template
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test binary, built with `go test -c`
*.test

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

# Dependency directories (remove the comment below to include it)
# vendor/

11 changes: 11 additions & 0 deletions decrypt.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,14 @@ func (i *igeDecrypter) CryptBlocks(dst, src []byte) {
c = t
}
}

// DecryptBlocks is a simple shorthand for IGE decrypting.
// Note: unlike NewIGEDecrypter, DecryptBlocks does NOT COPY iv.
// So you must not modify passed iv.
func DecryptBlocks(b cipher.Block, iv, dst, src []byte) {
if err := checkIV(b, iv); err != nil {
panic(err.Error())
}
dec := igeDecrypter{block: b, iv: iv}
dec.CryptBlocks(dst, src)
}
53 changes: 53 additions & 0 deletions decrypt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package ige
import (
"bytes"
"crypto/aes"
"fmt"
"testing"
)

Expand Down Expand Up @@ -52,6 +53,23 @@ func TestDecrypterCryptBlocks(t *testing.T) {
}
}

func TestDecryptBlocks(t *testing.T) {
for a, v := range TestVectors {
out := make([]byte, len(v.Ciphertext))

c, err := aes.NewCipher(v.Key)
if err != nil {
t.Fatal(err)
}

DecryptBlocks(c, v.IV, out, v.Ciphertext)

if !bytes.Equal(out, v.Plaintext) {
t.Fatalf("test vector %d has wrong ciphertext\n", a+1)
}
}
}

func TestDecryptCryptBlocksPanicSrc(t *testing.T) {
c, err := aes.NewCipher(make([]byte, 16))
if err != nil {
Expand Down Expand Up @@ -83,3 +101,38 @@ func TestDecryptCryptBlocksPanicDst(t *testing.T) {
i := NewIGEDecrypter(c, make([]byte, 32))
i.CryptBlocks(make([]byte, 1), make([]byte, 16))
}

func BenchmarkDecryptBlocks(b *testing.B) {
for _, payload := range []int{
16,
128,
1024,
8192,
64 * 1024,
512 * 1024,
} {
b.Run(fmt.Sprintf("%d", payload), benchDecrypt(payload))
}
}

func benchDecrypt(n int) func(b *testing.B) {
return func(b *testing.B) {
b.Helper()

src := make([]byte, n)
dst := make([]byte, n)

b.ReportAllocs()
b.SetBytes(int64(n))
b.ResetTimer()

for i := 0; i < b.N; i++ {
c, err := aes.NewCipher(TestVectors[0].Key)
if err != nil {
b.Fatal(err)
}

DecryptBlocks(c, TestVectors[0].IV, dst, src)
}
}
}
11 changes: 11 additions & 0 deletions encrypt.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,14 @@ func (i *igeEncrypter) CryptBlocks(dst, src []byte) {
m = src[o : o+b]
}
}

// EncryptBlocks is a simple shorthand for IGE encrypting.
// Note: unlike NewIGEEncrypter, EncryptBlocks does NOT COPY iv.
// So you must not modify passed iv.
func EncryptBlocks(b cipher.Block, iv, dst, src []byte) {
if err := checkIV(b, iv); err != nil {
panic(err.Error())
}
enc := igeEncrypter{block: b, iv: iv}
enc.CryptBlocks(dst, src)
}
53 changes: 53 additions & 0 deletions encrypt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package ige
import (
"bytes"
"crypto/aes"
"fmt"
"testing"
)

Expand Down Expand Up @@ -52,6 +53,23 @@ func TestEncrypterCryptBlocks(t *testing.T) {
}
}

func TestEncryptBlocks(t *testing.T) {
for a, v := range TestVectors {
out := make([]byte, len(v.Ciphertext))

c, err := aes.NewCipher(v.Key)
if err != nil {
t.Fatal(err)
}

EncryptBlocks(c, v.IV, out, v.Plaintext)

if !bytes.Equal(out, v.Ciphertext) {
t.Fatalf("test vector %d has wrong ciphertext\n", a+1)
}
}
}

func TestEncryptCryptBlocksPanicSrc(t *testing.T) {
c, err := aes.NewCipher(make([]byte, 16))
if err != nil {
Expand Down Expand Up @@ -83,3 +101,38 @@ func TestEncryptCryptBlocksPanicDst(t *testing.T) {
i := NewIGEEncrypter(c, make([]byte, 32))
i.CryptBlocks(make([]byte, 1), make([]byte, 16))
}

func BenchmarkEncryptBlocks(b *testing.B) {
for _, payload := range []int{
16,
128,
1024,
8192,
64 * 1024,
512 * 1024,
} {
b.Run(fmt.Sprintf("%d", payload), benchEncrypt(payload))
}
}

func benchEncrypt(n int) func(b *testing.B) {
return func(b *testing.B) {
b.Helper()

src := make([]byte, n)
dst := make([]byte, n)

b.ReportAllocs()
b.SetBytes(int64(n))
b.ResetTimer()

for i := 0; i < b.N; i++ {
c, err := aes.NewCipher(TestVectors[0].Key)
if err != nil {
b.Fatal(err)
}

EncryptBlocks(c, TestVectors[0].IV, dst, src)
}
}
}
3 changes: 1 addition & 2 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
github.com/gotd/xor v0.1.0 h1:kg9XdEeTpbZbvsyjQq2l+UbgvZanJFRSazrI06+qXG0=
github.com/gotd/xor v0.1.0/go.mod h1:ZTmdgqf6SOHder8/MFp9CNkXIadzID5lIiaZxRZICH0=
github.com/gotd/xor v0.1.1 h1:LSPEeuf7noTo4fi4PrEsAaWXOSwjsY2e+IINPiR+c7s=
github.com/gotd/xor v0.1.1/go.mod h1:ZTmdgqf6SOHder8/MFp9CNkXIadzID5lIiaZxRZICH0=

0 comments on commit 56a70f4

Please sign in to comment.