Skip to content

Commit

Permalink
Major Cryptor refactor in preparation for v0.5.0
Browse files Browse the repository at this point in the history
  • Loading branch information
cpl committed Apr 15, 2020
1 parent f68eff2 commit d1f9137
Show file tree
Hide file tree
Showing 82 changed files with 914 additions and 3,982 deletions.
18 changes: 0 additions & 18 deletions .github/workflows/go.yml

This file was deleted.

1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@ launch.json
**/.DS_Store
build/
dist/
out/
*.swp
.idea/
105 changes: 85 additions & 20 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,30 +1,95 @@
.PHONY: test clean test-color cover fmt
TARGETS = proto

export GO111MODULE := on

TEST_FLAGS := -coverprofile=build/cover.out -covermode=atomic -v -timeout 30s -count=1 -parallel 8
CMD_DIR := ./cmd
PKG_DIR := ./pkg
OUT_DIR := ./out

DIST_TAR := dist.tar.gz
COV_FILE := cover.out


DIST_OS += linux darwin
DIST_ARCH += amd64

GO_CMD ?= go
CGO_ENABLED ?= 0

EXTERNAL_TOOLS=\
github.com/client9/misspell/cmd/misspell \
github.com/golangci/golangci-lint/cmd/golangci-lint

GO111MODULE := on


GO_TEST_FLAGS := -v -count=1 -race -coverprofile=$(OUT_DIR)/$(COV_FILE) -covermode=atomic -parallel=16

.PHONY: deps
.PHONY: $(OUT_DIR) clean mod purge
.PHONY: test cover test-deps bench
.PHONY: lint-fmt lint-vet lint-misspell lint-ci lint
.PHONY: build dist


all: clean mod lint-fmt lint-vet test build

deps:
@for tool in $(EXTERNAL_TOOLS) ; do \
echo "Installing/Updating $$tool" ; \
GO111MODULE=off $(GO_CMD) get -u $$tool; \
done

$(OUT_DIR):
@mkdir -p $(OUT_DIR)

clean:
rm -rf build/;
rm -f $(shell find . -name cover.out -type f);
@rm -rf $(OUT_DIR)

purge: clean
$(GO_CMD) mod tidy
$(GO_CMD) clean -cache
$(GO_CMD) clean -testcache
$(GO_CMD) clean -modcache

dist: clean $(OUT_DIR)
@$(foreach arch, $(DIST_ARCH), \
$(foreach os,$(DIST_OS), \
$(foreach target, $(TARGETS), \
GOOS=$(os) GOARCH=$(arch) CGO_ENABLED=$(CGO_ENABLED) $(GO_CMD) build -o $(OUT_DIR)/$(target)_$(os)_$(arch) $(CMD_DIR)/$(target)/*.go && \
shasum $(OUT_DIR)/$(target)_$(os)_$(arch) > $(OUT_DIR)/$(target)_$(os)_$(arch).shasum; \
)))
@cd $(OUT_DIR) && \
tar -czvf $(DIST_TAR) --exclude $(DIST_TAR) *

build: $(OUT_DIR)
$(foreach target,$(TARGETS),go build -o $(OUT_DIR)/$(target) $(CMD_DIR)/$(target)/*.go;)

test: $(OUT_DIR)
$(GO_CMD) test $(GO_TEST_FLAGS) ./...

mod:
$(GO_CMD) mod tidy
$(GO_CMD) mod verify

cover: $(OUT_DIR)
$(GO_CMD) tool cover -html=$(OUT_DIR)/$(COV_FILE)

test-deps:
$(GO_CMD) test all

test:
@mkdir -p build/
@go test $(TEST_FLAGS) ./...
lint: lint-fmt lint-vet lint-misspell lint-ci

test-color:
@mkdir -p build/
@go test $(TEST_FLAGS) ./... | sed ''/PASS/s//$$(printf "\033[32mPASS\033[0m")/'' | sed ''/FAIL/s//$$(printf "\033[31mFAIL\033[0m")/'';
lint-fmt:
$(GO_CMD) fmt ./...

lint-vet:
$(GO_CMD) vet ./...

build/cover.out: test
lint-ci:
golangci-lint run -v ./...

cover: build/cover.out
@go tool cover -html=build/cover.out
lint-misspell:
misspell -error ./...

fmt:
$(eval GOFMT_OUT := $(shell gofmt -l . 2>&1))
@if [ "$(GOFMT_OUT)" ]; then \
echo "gofmt err in:\n$(GOFMT_OUT)"; \
exit 1; \
fi
bench:
$(GO_CMD) test -bench=. -benchmem -benchtime=10s ./...
11 changes: 11 additions & 0 deletions cmd/proto/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package main

import (
"fmt"

"cpl.li/go/cryptor"
)

func main() {
fmt.Println("cryptor " + cryptor.Version)
}
5 changes: 3 additions & 2 deletions cryptor.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
package cryptor // import "cpl.li/go/cryptor"

// Version of the Cryptor package.
const Version = "v0.0.3"
// Version is the current master tag release of Cryptor. The notation is: vX.Y.Z, where X is the major
// full release, Y is a minor or experimental release and Z is a patch or update.
const Version = "v0.5.0"
9 changes: 4 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
module cpl.li/go/cryptor

go 1.13
go 1.14

require (
github.com/stretchr/testify v1.4.0
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 // indirect
gopkg.in/go-playground/assert.v1 v1.2.1
github.com/stretchr/testify v1.5.1
golang.org/x/crypto v0.0.0-20200406173513-056763e48d71
golang.org/x/sys v0.0.0-20200409092240-59c9f1ba88fa // indirect
)
20 changes: 12 additions & 8 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,21 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c h1:Vj5n4GlwjmQteupaxJ9+0FNOmBrHfq7vN4btdGoDZgI=
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200406173513-056763e48d71 h1:DOmugCavvUtnUD114C1Wh+UgTgQZ4pMLzXxi1pSt+/Y=
golang.org/x/crypto v0.0.0-20200406173513-056763e48d71/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200409092240-59c9f1ba88fa h1:mQTN3ECqfsViCNBgq+A40vdwhkGykrrQlYe3mPj6BoU=
golang.org/x/sys v0.0.0-20200409092240-59c9f1ba88fa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM=
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
29 changes: 29 additions & 0 deletions internal/crypt/crypt.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package crypt

import (
"crypto/rand"
"encoding/binary"
)

// ZeroBytes will iterate each given array and set each byte to 0.
func ZeroBytes(data ...[]byte) {
for _, set := range data {
for index := range set {
set[index] = 0
}
}
}

// RandomBytes will return a byte array containing `size` random bytes.
func RandomBytes(size uint) []byte {
data := make([]byte, size)
if _, err := rand.Read(data); err != nil {
panic(err)
}
return data
}

// RandomUint64 will generate 8 random bytes and return them as a uint64.
func RandomUint64() uint64 {
return binary.LittleEndian.Uint64(RandomBytes(8))
}
89 changes: 89 additions & 0 deletions internal/crypt/crypt_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package crypt_test

import (
"bytes"
"math"
"testing"

"cpl.li/go/cryptor/internal/crypt"
"cpl.li/go/cryptor/internal/crypt/hashing"

"github.com/stretchr/testify/assert"
chacha "golang.org/x/crypto/chacha20poly1305"
)

func TestRandomBytes(t *testing.T) {
t.Parallel()

for pow := 0.0; pow <= 14; pow++ {
gen := int(math.Pow(2, pow))
zero := make([]byte, gen)

randBytes := crypt.RandomBytes(uint(gen))

assert.Len(t, randBytes, gen, "failed to generate random bytes")
assert.NotEqual(t, randBytes, zero)
}
}

func TestRandomUint64(t *testing.T) {
t.Parallel()
size := 10

values := make([]uint64, size)
for _, v := range values {
assert.Zero(t, v, "got unexpected 0 value")
}

for i := 0; i < size; i++ {
values[i] = crypt.RandomUint64()
}

for _, v := range values {
assert.NotZero(t, v, "got unexpected 0 value")
}
}

func TestZeroBytes(t *testing.T) {
t.Parallel()
size := 10

values := make([][]byte, size)
for i := 0; i < size; i++ {
values[i] = crypt.RandomBytes(1024)
}

crypt.ZeroBytes(values...)

for _, v := range values {
assert.Equal(t, make([]byte, len(v)), v, "found non-zero array")
}
}

func TestAEADEncryption(t *testing.T) {
t.Parallel()

msg := []byte("We attack at dawn")
key := crypt.RandomBytes(chacha.KeySize)

cipher, err := chacha.New(key)
assert.Nil(t, err)

var hash hashing.HashSum

nonce := crypt.RandomBytes(chacha.NonceSize)
hashing.Hash(&hash, msg)

ciphertext := cipher.Seal(nil, nonce, msg, hash[:])

newCipher, err := chacha.New(key)
assert.Nil(t, err)

decrypted, err := newCipher.Open(nil, nonce, ciphertext, hash[:])
assert.Nil(t, err)

if !bytes.Equal(decrypted, msg) {
t.Fatalf("message does not match decrypted message: %s : %s\n",
string(decrypted), string(msg))
}
}
1 change: 1 addition & 0 deletions internal/crypt/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package crypt // import "cpl.li/go/cryptor/internal/crypt"
1 change: 1 addition & 0 deletions internal/crypt/hashing/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package hashing // import "cpl.li/go/cryptor/internal/crypt/hashing"
42 changes: 42 additions & 0 deletions internal/crypt/hashing/hash.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package hashing

import (
"encoding/hex"
"hash"

"golang.org/x/crypto/blake2s"
)

// HashSize ...
const HashSize = blake2s.Size

// HashSum ...
type HashSum [HashSize]byte

// ToHex ...
func (h *HashSum) ToHex() string {
return hex.EncodeToString(h[:])
}

// HashFunction ...
func HashFunction() hash.Hash {
h, _ := blake2s.New256(nil)
return h
}

// Hash ...
func Hash(sum *HashSum, data ...[]byte) {
h := HashFunction()
defer h.Reset()

for _, set := range data {
h.Write(set)
}

if sum == nil {
return
}

h.Sum(sum[:0])
return
}
24 changes: 24 additions & 0 deletions internal/crypt/hashing/hash_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package hashing_test

import (
"testing"

"github.com/stretchr/testify/assert"

"cpl.li/go/cryptor/internal/crypt/hashing"
)

func assertHash(t *testing.T, data, expected string) {
var sum hashing.HashSum
hashing.Hash(&sum, []byte(data))
assert.Equal(t, expected, sum.ToHex(), "non matching hashes")
}

func TestHash(t *testing.T) {
t.Parallel()

assertHash(t, "",
"69217a3079908094e11121d042354a7c1f55b6482ca1a51e1b250dfd1ed0eef9")
assertHash(t, "Hello, World!",
"ec9db904d636ef61f1421b2ba47112a4fa6b8964fd4a0a514834455c21df7812")
}
Loading

0 comments on commit d1f9137

Please sign in to comment.