Go high-performance encryption utility.
gohpenc highly resembles hpenc tool (https://github.com/vstakhov/hpenc).
+hpenc solves the problem that there is no simple tool to quickly
+transfer data with encryption and authentication:
-Why it was written? hpenc has some problems: it does not work on aarch64
-and sparc64 architectures under FreeBSD (as seen in the port's Makefile)
-and produces incompatible output (unauthenticated after 8192 blocks)
-between FreeBSD and HardenedBSD systems somehow. Instead of painful
-debugging I decided to write something similar on the Go language,
-widening supported platforms.
+* openssl enc -- uses single CPU, no authentication
+* GnuPG -- complex key generation/management, relatively slow
+* OpenSSH -- uses single CPU, not very fast
+
+Why gohpenc was written? hpenc has some problems: it does not work on
+aarch64 and sparc64 architectures under FreeBSD (as seen in the port's
+Makefile) and produces incompatible output (unauthenticated after 8192
+blocks) between FreeBSD and HardenedBSD systems somehow. Instead of
+painful debugging I decided to write something similar on the Go
+language, widening supported platforms.
gohpenc is incompatible with hpenc and much simpler:
dependent libraries contain assembly-optimized code
* Built-in authentication and integrity check with small data overhead
+Usage is very simple:
+
+ $ gohpenc -psk
+ DTGZI5R2HS4YEDSIO56AFKPONE6KJE3Q2QETODDOH3O6UYFPROHQ
+ $ echo "message to be transmitted" | gohpenc -k DTGZI5R2HS4YEDSIO56AFKPONE6KJE3Q2QETODDOH3O6UYFPROHQ > encrypted
+ $ gohpenc -k DTGZI5R2HS4YEDSIO56AFKPONE6KJE3Q2QETODDOH3O6UYFPROHQ -d < encrypted
+
How encryption/authentication is performed:
-* First 32 bytes of the stream contains random data, called salt
+* First 32 bytes of the stream contain random data -- salt
* BLAKE2X is initialized: unknown length, PSK key as a MAC key. It
creates XOF that will be used as a KDF
* Salt is fed into that XOF
--- /dev/null
+package main
+
+import (
+ "encoding/base32"
+ "strings"
+)
+
+func ToBase32(data []byte) string {
+ return strings.TrimRight(base32.StdEncoding.EncodeToString(data), "=")
+}
+
+func FromBase32(data string) ([]byte, error) {
+ padSize := len(data) % 8
+ if padSize != 0 {
+ padSize = 8 - padSize
+ pad := make([]byte, 0, padSize)
+ for i := 0; i < padSize; i++ {
+ pad = append(pad, '=')
+ }
+ data += string(pad)
+ }
+ return base32.StdEncoding.DecodeString(data)
+}
import (
"bufio"
"crypto/rand"
- "encoding/base32"
"encoding/binary"
"flag"
"fmt"
"io"
"os"
"runtime"
- "strings"
"sync"
"golang.org/x/crypto/blake2b"
SaltSize = 32
)
-func ToBase32(data []byte) string {
- return strings.TrimRight(base32.StdEncoding.EncodeToString(data), "=")
-}
-
-func FromBase32(data string) ([]byte, error) {
- padSize := len(data) % 8
- if padSize != 0 {
- padSize = 8 - padSize
- pad := make([]byte, 0, padSize)
- for i := 0; i < padSize; i++ {
- pad = append(pad, '=')
- }
- data += string(pad)
- }
- return base32.StdEncoding.DecodeString(data)
-}
-
type WorkerTask struct {
key []byte
n int
var w *Worker
for {
key := make([]byte, chacha20poly1305.KeySize)
- _, err = io.ReadFull(keys, key)
- if err != nil {
+ if _, err = io.ReadFull(keys, key); err != nil {
panic(err)
}
w = workers[i%len(workers)]
panic(err)
}
n = int(binary.BigEndian.Uint32(w.buf[:LenSize]))
- n, err = io.ReadFull(stdin, w.buf[LenSize:LenSize+n+tmpAEAD.Overhead()])
- if err != nil {
+ if n, err = io.ReadFull(stdin, w.buf[LenSize:LenSize+n+tmpAEAD.Overhead()]); err != nil {
panic(err)
}
} else {