Skip to content

Commit 938823b

Browse files
author
Andreas Auernhammer
committed
make the algorithm type public API
This commit makes the algorithm type public API by `algorithm` => `Algorithm`. The idea behind this change is that calling code can use the `Algorithm` type e.g. in method calls or struct definitions. This makes calling code more expressive - e.g.: `func Encrypt(alg sio.Algorithm, masterKey []byte, kdf KDF) {...}` Before this change calling code had to pass around strings and match whether that string value is equal to one of the algorithm constants defined by sio. However, the downside of this change is that calling code now can use "invalid" algorithms - e.g.: `var myAlgorithm = sio.Algorithm("foo")` Therefore, `Algorithm.Stream([]byte)` now also returns an error when the `Algorithm` value is not one of the defined constants. So calling code still cannot create or re-define the implementation of an algorithm. However, it is possible to construct invalid `Algorithm` values. Maybe we want to consider a `ParseAlgorithm` or `AlgorithmFromString` function in `sioutil` to fail early when reading the `Algorithm` value from a (untrusted) config / metadata source.
1 parent 9f99f80 commit 938823b

7 files changed

+52
-48
lines changed

benchmark_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import (
1111
)
1212

1313
func BenchmarkEncrypt(b *testing.B) {
14-
s, err := AES_128_GCM.New(make([]byte, 16))
14+
s, err := AES_128_GCM.Stream(make([]byte, 16))
1515
if err != nil {
1616
b.Fatalf("Failed to create Stream: %v", err)
1717
}
@@ -43,7 +43,7 @@ func BenchmarkEncrypt(b *testing.B) {
4343
}
4444

4545
func BenchmarkDecrypt(b *testing.B) {
46-
s, err := AES_128_GCM.New(make([]byte, 16))
46+
s, err := AES_128_GCM.Stream(make([]byte, 16))
4747
if err != nil {
4848
b.Fatalf("Failed to create Stream: %v", err)
4949
}

examples_test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ func ExampleNewStream_aES128GCM() {
2626
// If you want to convert a passphrase to a key, use a suitable
2727
// package like argon2 or scrypt.
2828
key, _ := hex.DecodeString("4c4d737f2199f3ccb13d2c81dfe38eb8")
29-
stream, err := sio.AES_128_GCM.New(key)
29+
stream, err := sio.AES_128_GCM.Stream(key)
3030
if err != nil {
3131
panic(err) // TODO: error handling
3232
}
@@ -68,7 +68,7 @@ func ExampleNewStream_aES256GCM() {
6868
// If you want to convert a passphrase to a key, use a suitable
6969
// package like argon2 or scrypt.
7070
key, _ := hex.DecodeString("5b48c6945ae03a93ecc20e38305d2cbe4a177133d83bf4773f1f3be636e2cc4b")
71-
stream, err := sio.AES_256_GCM.New(key)
71+
stream, err := sio.AES_256_GCM.Stream(key)
7272
if err != nil {
7373
panic(err) // TODO: error handling
7474
}
@@ -90,7 +90,7 @@ func ExampleNewStream_xChaCha20Poly1305() {
9090
// package like argon2 or scrypt - or take a look at the sio/sioutil
9191
// package.
9292
key, _ := hex.DecodeString("f230e700c4f120b623b84ac26cbcb5ae926f44f36589e63745a46ae0ca47137d")
93-
stream, err := sio.XChaCha20Poly1305.New(key)
93+
stream, err := sio.XChaCha20Poly1305.Stream(key)
9494
if err != nil {
9595
panic(err) // TODO: error handling
9696
}

helper_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ func loadTestVectors(filename string) []TestVector {
5858
}
5959

6060
var vec []struct {
61-
Algorithm algorithm
61+
Algorithm Algorithm
6262
BufSize int
6363
Key string
6464
Nonce string

reader_test.go

+10-10
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import (
1313

1414
func TestVectorRead(t *testing.T) {
1515
for i, test := range TestVectors {
16-
stream, err := test.Algorithm.newWithBufSize(test.Key, test.BufSize)
16+
stream, err := test.Algorithm.streamWithBufSize(test.Key, test.BufSize)
1717
if err != nil {
1818
t.Fatalf("Test %d: Failed to create new Stream: %v", i, err)
1919
}
@@ -49,7 +49,7 @@ func TestVectorReadByte(t *testing.T) {
4949
ciphertext.Reset()
5050
plaintext.Reset()
5151

52-
stream, err := test.Algorithm.newWithBufSize(test.Key, test.BufSize)
52+
stream, err := test.Algorithm.streamWithBufSize(test.Key, test.BufSize)
5353
if err != nil {
5454
t.Fatalf("Test %d: Failed to create new Stream: %v", i, err)
5555
}
@@ -81,7 +81,7 @@ func TestVectorWriteTo(t *testing.T) {
8181
ciphertext.Reset()
8282
plaintext.Reset()
8383

84-
stream, err := test.Algorithm.newWithBufSize(test.Key, test.BufSize)
84+
stream, err := test.Algorithm.streamWithBufSize(test.Key, test.BufSize)
8585
if err != nil {
8686
t.Fatalf("Test %d: Failed to create new Stream: %v", i, err)
8787
}
@@ -107,7 +107,7 @@ func TestVectorWriteTo(t *testing.T) {
107107

108108
func TestVectorReadAt(t *testing.T) {
109109
for i, test := range TestVectors {
110-
stream, err := test.Algorithm.newWithBufSize(test.Key, test.BufSize)
110+
stream, err := test.Algorithm.streamWithBufSize(test.Key, test.BufSize)
111111
if err != nil {
112112
t.Fatalf("Test %d: Failed to create new Stream: %v", i, err)
113113
}
@@ -131,7 +131,7 @@ func TestVectorReadAtSection(t *testing.T) {
131131
for i, test := range TestVectors {
132132
plaintext.Reset()
133133

134-
stream, err := test.Algorithm.newWithBufSize(test.Key, test.BufSize)
134+
stream, err := test.Algorithm.streamWithBufSize(test.Key, test.BufSize)
135135
if err != nil {
136136
t.Fatalf("Test %d: Failed to create new Stream: %v", i, err)
137137
}
@@ -150,7 +150,7 @@ func TestVectorReadAtSection(t *testing.T) {
150150

151151
func TestSimpleRead(t *testing.T) {
152152
for i, test := range SimpleTests {
153-
stream, err := test.Algorithm.newWithBufSize(test.Key, test.BufSize)
153+
stream, err := test.Algorithm.streamWithBufSize(test.Key, test.BufSize)
154154
if err != nil {
155155
t.Fatalf("Test %d: Failed to create new Stream: %v", i, err)
156156
}
@@ -182,7 +182,7 @@ func TestSimpleReadByte(t *testing.T) {
182182
ciphertext.Reset()
183183
plaintext.Reset()
184184

185-
stream, err := test.Algorithm.newWithBufSize(test.Key, test.BufSize)
185+
stream, err := test.Algorithm.streamWithBufSize(test.Key, test.BufSize)
186186
if err != nil {
187187
t.Fatalf("Test %d: Failed to create new Stream: %v", i, err)
188188
}
@@ -211,7 +211,7 @@ func TestSimpleWriteTo(t *testing.T) {
211211
ciphertext.Reset()
212212
plaintext.Reset()
213213

214-
stream, err := test.Algorithm.newWithBufSize(test.Key, test.BufSize)
214+
stream, err := test.Algorithm.streamWithBufSize(test.Key, test.BufSize)
215215
if err != nil {
216216
t.Fatalf("Test %d: Failed to create new Stream: %v", i, err)
217217
}
@@ -234,7 +234,7 @@ func TestSimpleWriteTo(t *testing.T) {
234234

235235
func TestSimpleReadAt(t *testing.T) {
236236
for i, test := range SimpleTests {
237-
stream, err := test.Algorithm.newWithBufSize(test.Key, test.BufSize)
237+
stream, err := test.Algorithm.streamWithBufSize(test.Key, test.BufSize)
238238
if err != nil {
239239
t.Fatalf("Test %d: Failed to create new Stream: %v", i, err)
240240
}
@@ -266,7 +266,7 @@ func TestSimpleReadAtSection(t *testing.T) {
266266
ciphertext.Reset()
267267
plaintext.Reset()
268268

269-
stream, err := test.Algorithm.newWithBufSize(test.Key, test.BufSize)
269+
stream, err := test.Algorithm.streamWithBufSize(test.Key, test.BufSize)
270270
if err != nil {
271271
t.Fatalf("Test %d: Failed to create new Stream: %v", i, err)
272272
}

sio.go

+25-21
Original file line numberDiff line numberDiff line change
@@ -46,35 +46,37 @@ type errorType string
4646

4747
func (e errorType) Error() string { return string(e) }
4848

49-
// The following constants specify concrete AEAD algorithms
50-
// which can be used to encrypt and decrypt data streams.
51-
// Therefore, the non-exported type algorithm defines an
52-
// exported New function that you can call to create a new
53-
// Stream:
54-
// // New returns a new Stream that encrypts and decrypts
55-
// // data streams using the given secret key and AEAD
56-
// // algorithm.
57-
// // The returned Stream uses the default buffer size: BufSize.
58-
// func (a algorithm) NewStream(key []byte) (*Stream, error)
49+
// The constants above specify concrete AEAD algorithms
50+
// that can be used to encrypt and decrypt data streams.
5951
//
6052
// For example, you can create a new Stream using AES-GCM like this:
61-
// stream, err := sio.AES_128_GCM.New(key)
53+
// stream, err := sio.AES_128_GCM.Stream(key)
6254
const (
63-
AES_128_GCM algorithm = "AES-128-GCM" // The secret key must be 16 bytes long. See: https://golang.org/pkg/crypto/cipher/#NewGCM
64-
AES_256_GCM algorithm = "AES-256-GCM" // The secret key must be 32 bytes long. See: https://golang.org/pkg/crypto/cipher/#NewGCM
65-
ChaCha20Poly1305 algorithm = "ChaCha20-Poly1305" // The secret key must be 32 bytes long. See: https://godoc.org/golang.org/x/crypto/chacha20poly1305#New
66-
XChaCha20Poly1305 algorithm = "XChaCha20-Poly1305" // The secret key must be 32 bytes long. See: https://godoc.org/golang.org/x/crypto/chacha20poly1305#NewX
55+
AES_128_GCM Algorithm = "AES-128-GCM" // The secret key must be 16 bytes long. See: https://golang.org/pkg/crypto/cipher/#NewGCM
56+
AES_256_GCM Algorithm = "AES-256-GCM" // The secret key must be 32 bytes long. See: https://golang.org/pkg/crypto/cipher/#NewGCM
57+
ChaCha20Poly1305 Algorithm = "ChaCha20-Poly1305" // The secret key must be 32 bytes long. See: https://godoc.org/golang.org/x/crypto/chacha20poly1305#New
58+
XChaCha20Poly1305 Algorithm = "XChaCha20-Poly1305" // The secret key must be 32 bytes long. See: https://godoc.org/golang.org/x/crypto/chacha20poly1305#NewX
6759
)
6860

69-
type algorithm string
61+
// Algorithm specifies an AEAD algorithm that
62+
// can be used to en/decrypt data streams.
63+
//
64+
// Its main purpose is to simplify code that
65+
// wants to use commonly used AEAD algorithms,
66+
// like AES-GCM, by providing a way to directly
67+
// create Streams from secret keys.
68+
type Algorithm string
69+
70+
// String returns the string representation of an
71+
// AEAD algorithm.
72+
func (a Algorithm) String() string { return string(a) }
7073

71-
// New returns a new Stream that encrypts and decrypts
72-
// data streams using the given secret key and AEAD
73-
// algorithm.
74+
// Stream returns a new Stream using the given
75+
// secret key and AEAD algorithm.
7476
// The returned Stream uses the default buffer size: BufSize.
75-
func (a algorithm) New(key []byte) (*Stream, error) { return a.newWithBufSize(key, BufSize) }
77+
func (a Algorithm) Stream(key []byte) (*Stream, error) { return a.streamWithBufSize(key, BufSize) }
7678

77-
func (a algorithm) newWithBufSize(key []byte, bufSize int) (*Stream, error) {
79+
func (a Algorithm) streamWithBufSize(key []byte, bufSize int) (*Stream, error) {
7880
var (
7981
aead cipher.AEAD
8082
err error
@@ -94,6 +96,8 @@ func (a algorithm) newWithBufSize(key []byte, bufSize int) (*Stream, error) {
9496
aead, err = chacha20poly1305.New(key)
9597
case XChaCha20Poly1305:
9698
aead, err = chacha20poly1305.NewX(key)
99+
default:
100+
return nil, errorType("sio: invalid algorithm name")
97101
}
98102
if err != nil {
99103
return nil, err

sio_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import (
99
)
1010

1111
type TestVector struct {
12-
Algorithm algorithm
12+
Algorithm Algorithm
1313
BufSize int
1414
Key []byte
1515
Nonce []byte
@@ -21,7 +21,7 @@ type TestVector struct {
2121
var TestVectors []TestVector = loadTestVectors("./test_vectors.json")
2222

2323
type SimpleTest struct {
24-
Algorithm algorithm
24+
Algorithm Algorithm
2525
BufSize int
2626
Key []byte
2727
Nonce []byte

writer_test.go

+9-9
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ func TestVectorWrite(t *testing.T) {
1919
ciphertext.Reset()
2020
plaintext.Reset()
2121

22-
stream, err := test.Algorithm.newWithBufSize(test.Key, test.BufSize)
22+
stream, err := test.Algorithm.streamWithBufSize(test.Key, test.BufSize)
2323
if err != nil {
2424
t.Fatalf("Test %d: Failed to create new Stream: %v", i, err)
2525
}
@@ -56,7 +56,7 @@ func TestVectorWriteByte(t *testing.T) {
5656
ciphertext.Reset()
5757
plaintext.Reset()
5858

59-
stream, err := test.Algorithm.newWithBufSize(test.Key, test.BufSize)
59+
stream, err := test.Algorithm.streamWithBufSize(test.Key, test.BufSize)
6060
if err != nil {
6161
t.Fatalf("Test %d: Failed to create new Stream: %v", i, err)
6262
}
@@ -93,7 +93,7 @@ func TestVectorReadFrom(t *testing.T) {
9393
ciphertext.Reset()
9494
plaintext.Reset()
9595

96-
stream, err := test.Algorithm.newWithBufSize(test.Key, test.BufSize)
96+
stream, err := test.Algorithm.streamWithBufSize(test.Key, test.BufSize)
9797
if err != nil {
9898
t.Fatalf("Test %d: Failed to create new Stream: %v", i, err)
9999
}
@@ -130,7 +130,7 @@ func TestSimpleWrite(t *testing.T) {
130130
ciphertext.Reset()
131131
plaintext.Reset()
132132

133-
stream, err := test.Algorithm.newWithBufSize(test.Key, test.BufSize)
133+
stream, err := test.Algorithm.streamWithBufSize(test.Key, test.BufSize)
134134
if err != nil {
135135
t.Fatalf("Test %d: Failed to create new Stream: %v", i, err)
136136
}
@@ -165,7 +165,7 @@ func TestSimpleWriteByte(t *testing.T) {
165165
ciphertext.Reset()
166166
plaintext.Reset()
167167

168-
stream, err := test.Algorithm.newWithBufSize(test.Key, test.BufSize)
168+
stream, err := test.Algorithm.streamWithBufSize(test.Key, test.BufSize)
169169
if err != nil {
170170
t.Fatalf("Test %d: Failed to create new Stream: %v", i, err)
171171
}
@@ -200,7 +200,7 @@ func TestSimpleReadFrom(t *testing.T) {
200200
ciphertext.Reset()
201201
plaintext.Reset()
202202

203-
stream, err := test.Algorithm.newWithBufSize(test.Key, test.BufSize)
203+
stream, err := test.Algorithm.streamWithBufSize(test.Key, test.BufSize)
204204
if err != nil {
205205
t.Fatalf("Test %d: Failed to create new Stream: %v", i, err)
206206
}
@@ -237,7 +237,7 @@ func TestWriteAfterClose(t *testing.T) {
237237
w.Write(nil)
238238
}
239239

240-
s, err := AES_128_GCM.New(make([]byte, 16))
240+
s, err := AES_128_GCM.Stream(make([]byte, 16))
241241
if err != nil {
242242
t.Fatalf("Failed to create new Stream: %v", err)
243243
}
@@ -262,7 +262,7 @@ func TestWriteByteAfterClose(t *testing.T) {
262262
w.WriteByte(0)
263263
}
264264

265-
s, err := AES_128_GCM.New(make([]byte, 16))
265+
s, err := AES_128_GCM.Stream(make([]byte, 16))
266266
if err != nil {
267267
t.Fatalf("Failed to create new Stream: %v", err)
268268
}
@@ -286,7 +286,7 @@ func TestReadFromAfterClose(t *testing.T) {
286286
w.ReadFrom(bytes.NewReader(nil))
287287
}
288288

289-
s, err := AES_128_GCM.New(make([]byte, 16))
289+
s, err := AES_128_GCM.Stream(make([]byte, 16))
290290
if err != nil {
291291
t.Fatalf("Failed to create new Stream: %v", err)
292292
}

0 commit comments

Comments
 (0)