diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml
new file mode 100644
index 0000000..4cdd173
--- /dev/null
+++ b/.github/workflows/go.yml
@@ -0,0 +1,57 @@
+name: Go
+
+on:
+  pull_request:
+    branches:
+    - master
+  push:
+    branches:
+    - master
+
+jobs:
+  build:
+    name: Build Go ${{ matrix.go-version }}
+    runs-on: ubuntu-latest
+    strategy:
+      matrix:
+        go-version: [1.15.x, 1.16.x]
+    steps:
+    - name: Set up Go ${{ matrix.go-version }}
+      uses: actions/setup-go@v1
+      with:
+        go-version: ${{ matrix.go-version }}
+      id: go
+
+    - name: Check out code into the Go module directory
+      uses: actions/checkout@v1
+
+    - name: Build
+      env:
+        GO111MODULE: on
+      run: |
+         curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.33.0
+         $(go env GOPATH)/bin/golangci-lint run --config ./.golangci.yml
+         go vet ./...
+  test:
+    name: Testing Go ${{ matrix.go-version }} on ${{ matrix.os }}
+    runs-on: ${{ matrix.os }}
+    strategy:
+      matrix:
+        go-version: [1.16.x]
+        os: [ubuntu-latest, windows-latest, macos-latest]
+    steps:
+    - name: Set up Go ${{ matrix.go-version }} on ${{ matrix.os }}
+      uses: actions/setup-go@v1
+      with:
+        go-version: ${{ matrix.go-version }}
+      id: go
+
+    - name: Check out code into the Go module directory
+      uses: actions/checkout@v1
+
+    - name: Test on ${{ matrix.os }}
+      env:
+        GO111MODULE: on
+      run: |
+         go test ./...
+
diff --git a/.golangci.yml b/.golangci.yml
new file mode 100644
index 0000000..0cf218c
--- /dev/null
+++ b/.golangci.yml
@@ -0,0 +1,31 @@
+linters-settings:
+  golint:
+    min-confidence: 0
+
+  misspell:
+    locale: US
+
+linters:
+  disable-all: true
+  enable:
+    - typecheck
+    - goimports
+    - misspell
+    - govet
+    - golint
+    - ineffassign
+    - gosimple
+    - deadcode
+    - unused
+    - structcheck
+    - prealloc
+    - unconvert
+
+issues:
+  exclude-use-default: false
+  exclude:
+      - should have a package comment
+      - error strings should not be capitalized or end with punctuation or a newline
+      - don't use ALL_CAPS in Go names
+service:
+  golangci-lint-version: 1.33.0 # use the fixed version to not introduce new linters unexpectedly
diff --git a/cmd/ncrypt/main.go b/cmd/ncrypt/main.go
index 864a735..a4f2afc 100644
--- a/cmd/ncrypt/main.go
+++ b/cmd/ncrypt/main.go
@@ -95,7 +95,7 @@ func init() {
 	sigChan := make(chan os.Signal, 1)
 	signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)
 	go func() {
-		_ = <-sigChan
+		<-sigChan
 		cleanChan <- codeCancel // try to exit gracefully
 		runtime.Goexit()
 	}()
@@ -122,7 +122,6 @@ func main() {
 	} else {
 		encrypt(out, in, cfg)
 	}
-	return
 }
 
 func exit(code int) {
@@ -225,7 +224,10 @@ func readPassword(src *os.File) []byte {
 }
 
 func deriveKey(dst, src *os.File) []byte {
-	password, salt := []byte{}, make([]byte, 32)
+	var (
+		password []byte
+		salt     = make([]byte, 32)
+	)
 	if passwordFlag != "" {
 		password = []byte(passwordFlag)
 	} else if src == os.Stdin {
diff --git a/sio_test.go b/sio_test.go
index 5f0f3b6..494a216 100644
--- a/sio_test.go
+++ b/sio_test.go
@@ -81,31 +81,6 @@ var ioTests = []struct {
 
 }
 
-func dumpDareStream(strm []byte) {
-	i := 0
-	for {
-		hdr := headerV10(strm[i : i+headerSize])
-
-		fmt.Print("[")
-		for i, b := range hdr {
-			fmt.Printf("%02x", b)
-			if i != len(hdr)-1 {
-				fmt.Print(" ")
-			}
-		}
-		fmt.Print("]")
-
-		fmt.Printf(" version=0x%02x, cipher=0x%02x, len=0x%x, sequencenr=0x%x\n", hdr.Version(), hdr.Cipher(), hdr.Len(), hdr.SequenceNumber())
-
-		i += headerSize + hdr.Len() + tagSize
-		if i == len(strm) {
-			break
-		} else if i > len(strm) {
-			panic(fmt.Sprintf("index larger than stream size, %d, %d", i, len(strm)))
-		}
-	}
-}
-
 func TestEncrypt(t *testing.T) {
 	key := make([]byte, 32)
 	if _, err := io.ReadFull(rand.Reader, key); err != nil {
@@ -171,7 +146,7 @@ func TestDecryptBuffer(t *testing.T) {
 					}
 
 					// Test with existing data.
-					decrypted, err = DecryptBuffer(make([]byte, 500, 500), output.Bytes(), config)
+					decrypted, err = DecryptBuffer(make([]byte, 500), output.Bytes(), config)
 					if err != nil {
 						t.Errorf("Version %d: Test %d: Decryption failed: number of bytes: %d vs. %d - %v", version, i, len(decrypted), test.datasize, err)
 						return
@@ -484,14 +459,16 @@ func testFile(t *testing.T, file string) {
 }
 
 func TestFiles(t *testing.T) {
-
 	fileList := []string{}
-	filepath.Walk(".", func(path string, f os.FileInfo, err error) error {
+	err := filepath.Walk(".", func(path string, f os.FileInfo, err error) error {
 		if !f.IsDir() {
 			fileList = append(fileList, path)
 		}
 		return nil
 	})
+	if err != nil {
+		t.Fatalf("Failed to walk directory: %v", err)
+	}
 
 	for _, file := range fileList {
 		testFile(t, file)