Skip to content

Commit

Permalink
Add IO buffering to encryptfile & decryptfile
Browse files Browse the repository at this point in the history
Add IO buffering with bufio to encryptfile and decryptfile with a buffer
size of 10KB.

By default, golang IO operations arent buffered and so adding buffering
is a key way to gain some performance. Obviously this doesnt work for
everything. For imacry, im not 100% sure it will work.

IO optimization is tricky. The reason we used a stream cypher and
reading blocks 1KB at a time is not to hog memory and allow more
concurrency, unfortunately this leads to possible unnecessary reads.
Buffering IO can possibly get around part of that issue. Hopefully the
buffer size of 10KB(or 10 blocks) can help cut down on that without
hogging too much memory.

The only real way to know for sure is extensive benchmarking which I
probably will not do. Who knows, maybe I will in the future.
  • Loading branch information
prairir committed Dec 28, 2021
1 parent 71d9fcd commit 97eb4e9
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 3 deletions.
13 changes: 12 additions & 1 deletion pkg/decryptfile/decryptfile.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package decryptfile

import (
"bufio"
"crypto/aes"
"crypto/cipher"
"fmt"
Expand Down Expand Up @@ -44,6 +45,8 @@ func (df DecryptFile) Do(filePath string) error {
return fmt.Errorf("decryptfile.Do error: %w", err)
}

outfileBuf := bufio.NewWriterSize(outfile, 10240)

// Get the initialization vector from the beginning of the input file.
iv := make([]byte, cipherBlock.BlockSize())
if _, err := infile.Read(iv); err != nil {
Expand All @@ -57,11 +60,19 @@ func (df DecryptFile) Do(filePath string) error {
n, err := infile.Read(buf)
if n > 0 {
stream.XORKeyStream(buf, buf[:n])
outfile.Write(buf[:n])
_, err := outfileBuf.Write(buf[:n])
if err != nil {
return fmt.Errorf("decryptfile.Do error: %w", err)
}

}

// EOF has been reached
if err == io.EOF {
err := outfileBuf.Flush()
if err != nil {
return fmt.Errorf("decryptfile.Do error: %w", err)
}
break
}

Expand Down
16 changes: 14 additions & 2 deletions pkg/encryptfile/encryptfile.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package encryptfile

import (
"bufio"
"crypto/aes"
"crypto/cipher"
"crypto/rand"
Expand Down Expand Up @@ -48,19 +49,30 @@ func (ef EncryptFile) Do(filePath string) error {
return fmt.Errorf("encryptfile.Do error: %w", err)
}

outfile.Write(iv)
// write buffer with size of 10KB
outfileBuf := bufio.NewWriterSize(outfile, 10240)

outfileBuf.Write(iv)
buf := make([]byte, 1024)
stream := cipher.NewCTR(cipherBlock, iv)

for {
n, err := infile.Read(buf)
if n > 0 {
stream.XORKeyStream(buf, buf[:n])
outfile.Write(buf[:n])
_, err := outfileBuf.Write(buf[:n])
if err != nil {
return fmt.Errorf("encryptfile.Do error: %w", err)
}

}

// if it gets EOF break out of loop
if err == io.EOF {
err := outfileBuf.Flush()
if err != nil {
return fmt.Errorf("encryptfile.Do error: %w", err)
}
break
}

Expand Down

0 comments on commit 97eb4e9

Please sign in to comment.