Go · 2656 bytes Raw Blame History
1 // SPDX-License-Identifier: AGPL-3.0-or-later
2
3 package secretbox
4
5 import (
6 "bytes"
7 "testing"
8 )
9
10 func mustBox(t *testing.T) *Box {
11 t.Helper()
12 k, err := GenerateKey()
13 if err != nil {
14 t.Fatalf("GenerateKey: %v", err)
15 }
16 b, err := FromBytes(k)
17 if err != nil {
18 t.Fatalf("FromBytes: %v", err)
19 }
20 return b
21 }
22
23 func TestSealOpen_RoundTrip(t *testing.T) {
24 t.Parallel()
25 b := mustBox(t)
26 plaintext := []byte("hunter2-totp-secret-bytes")
27
28 ct, nonce, err := b.Seal(plaintext)
29 if err != nil {
30 t.Fatalf("Seal: %v", err)
31 }
32 if bytes.Contains(ct, plaintext) {
33 t.Fatal("ciphertext contains plaintext substring")
34 }
35 if len(nonce) != NonceSize {
36 t.Fatalf("nonce size = %d, want %d", len(nonce), NonceSize)
37 }
38
39 got, err := b.Open(ct, nonce)
40 if err != nil {
41 t.Fatalf("Open: %v", err)
42 }
43 if !bytes.Equal(got, plaintext) {
44 t.Fatalf("Open mismatch: %s", got)
45 }
46 }
47
48 func TestSealOpen_DifferentNoncesEachCall(t *testing.T) {
49 t.Parallel()
50 b := mustBox(t)
51 plaintext := []byte("same input each time")
52 _, n1, _ := b.Seal(plaintext)
53 _, n2, _ := b.Seal(plaintext)
54 if bytes.Equal(n1, n2) {
55 t.Fatal("nonces collided across two Seal calls")
56 }
57 }
58
59 func TestOpen_RejectsTamper(t *testing.T) {
60 t.Parallel()
61 b := mustBox(t)
62 ct, nonce, _ := b.Seal([]byte("authentic"))
63 ct[0] ^= 0x01
64 if _, err := b.Open(ct, nonce); err == nil {
65 t.Fatal("expected error for tampered ciphertext")
66 }
67 }
68
69 func TestOpen_RejectsWrongNonce(t *testing.T) {
70 t.Parallel()
71 b := mustBox(t)
72 ct, nonce, _ := b.Seal([]byte("authentic"))
73 otherNonce := make([]byte, len(nonce))
74 copy(otherNonce, nonce)
75 otherNonce[0] ^= 0x01
76 if _, err := b.Open(ct, otherNonce); err == nil {
77 t.Fatal("expected error for wrong nonce")
78 }
79 }
80
81 func TestOpen_RejectsWrongKey(t *testing.T) {
82 t.Parallel()
83 a := mustBox(t)
84 b := mustBox(t)
85 ct, nonce, _ := a.Seal([]byte("alice"))
86 if _, err := b.Open(ct, nonce); err == nil {
87 t.Fatal("expected error opening with different key")
88 }
89 }
90
91 func TestFromBase64_InvalidLength(t *testing.T) {
92 t.Parallel()
93 if _, err := FromBase64(EncodeKey([]byte("too short"))); err == nil {
94 t.Fatal("expected error for short key")
95 }
96 if _, err := FromBase64(""); err == nil {
97 t.Fatal("expected error for empty key")
98 }
99 }
100
101 func TestFromBase64_RoundTrip(t *testing.T) {
102 t.Parallel()
103 k, _ := GenerateKey()
104 b1, err := FromBase64(EncodeKey(k))
105 if err != nil {
106 t.Fatalf("FromBase64: %v", err)
107 }
108 b2, err := FromBytes(k)
109 if err != nil {
110 t.Fatalf("FromBytes: %v", err)
111 }
112 pt := []byte("alice")
113 ct, n, _ := b1.Seal(pt)
114 out, err := b2.Open(ct, n)
115 if err != nil {
116 t.Fatalf("Open: %v", err)
117 }
118 if !bytes.Equal(out, pt) {
119 t.Fatal("round-trip mismatch")
120 }
121 }
122