bench_test.go raw
1 package crypto
2
3 import (
4 "crypto/rand"
5 "crypto/sha256"
6 "testing"
7
8 "github.com/btcsuite/btcd/btcec/v2"
9 "github.com/btcsuite/btcd/btcec/v2/schnorr"
10
11 "git.smesh.lol/gnarl-hamadryad/crypto/gnarl"
12 "git.smesh.lol/gnarl-hamadryad/crypto/ring"
13 )
14
15 // --- Hashing ---
16
17 func BenchmarkSHA256_32(b *testing.B) {
18 msg := make([]byte, 32)
19 for i := range msg {
20 msg[i] = byte(i)
21 }
22 b.ResetTimer()
23 for i := 0; i < b.N; i++ {
24 sha256.Sum256(msg)
25 }
26 }
27
28 func BenchmarkSHA256_128(b *testing.B) {
29 msg := make([]byte, 128)
30 for i := range msg {
31 msg[i] = byte(i)
32 }
33 b.ResetTimer()
34 for i := 0; i < b.N; i++ {
35 sha256.Sum256(msg)
36 }
37 }
38
39 func BenchmarkHamadryad_128(b *testing.B) {
40 msg := make([]byte, 128)
41 for i := range msg {
42 msg[i] = byte(i)
43 }
44 b.ResetTimer()
45 for i := 0; i < b.N; i++ {
46 Hash(msg)
47 }
48 }
49
50 func BenchmarkGHash_128(b *testing.B) {
51 msg := make([]byte, 128)
52 for i := range msg {
53 msg[i] = byte(i)
54 }
55 b.ResetTimer()
56 for i := 0; i < b.N; i++ {
57 GHash(msg)
58 }
59 }
60
61 func BenchmarkGMid_128(b *testing.B) {
62 msg := make([]byte, 128)
63 for i := range msg {
64 msg[i] = byte(i)
65 }
66 b.ResetTimer()
67 for i := 0; i < b.N; i++ {
68 GMid(msg)
69 }
70 }
71
72 // --- Key Generation ---
73
74 func BenchmarkBIP340_KeyGen(b *testing.B) {
75 var seed [32]byte
76 for i := 0; i < b.N; i++ {
77 rand.Read(seed[:])
78 privKey, _ := btcec.PrivKeyFromBytes(seed[:])
79 _ = schnorr.SerializePubKey(privKey.PubKey())
80 }
81 }
82
83 func BenchmarkGnarl_KeyGen(b *testing.B) {
84 for i := 0; i < b.N; i++ {
85 _, _, err := gnarl.GenerateKey()
86 if err != nil {
87 b.Fatal(err)
88 }
89 }
90 }
91
92 // --- Signing ---
93
94 func BenchmarkBIP340_Sign(b *testing.B) {
95 var seed [32]byte
96 rand.Read(seed[:])
97 privKey, _ := btcec.PrivKeyFromBytes(seed[:])
98
99 msg := sha256.Sum256([]byte("benchmark message for signing"))
100 b.ResetTimer()
101 for i := 0; i < b.N; i++ {
102 _, err := schnorr.Sign(privKey, msg[:])
103 if err != nil {
104 b.Fatal(err)
105 }
106 }
107 }
108
109 func BenchmarkGnarl_Sign(b *testing.B) {
110 sk, _, err := gnarl.GenerateKey()
111 if err != nil {
112 b.Fatal(err)
113 }
114 msg := []byte("benchmark message for signing")
115 challengeFunc := func(data []byte) [27]byte {
116 return GnarlSchnorrChallenge(data)
117 }
118 b.ResetTimer()
119 for i := 0; i < b.N; i++ {
120 _, err := gnarl.Sign(sk, msg, challengeFunc)
121 if err != nil {
122 b.Fatal(err)
123 }
124 }
125 }
126
127 // --- Verification ---
128
129 func BenchmarkBIP340_Verify(b *testing.B) {
130 var seed [32]byte
131 rand.Read(seed[:])
132 privKey, _ := btcec.PrivKeyFromBytes(seed[:])
133 pubKey := privKey.PubKey()
134
135 msg := sha256.Sum256([]byte("benchmark message for verification"))
136 sig, err := schnorr.Sign(privKey, msg[:])
137 if err != nil {
138 b.Fatal(err)
139 }
140
141 b.ResetTimer()
142 for i := 0; i < b.N; i++ {
143 if !sig.Verify(msg[:], pubKey) {
144 b.Fatal("verification failed")
145 }
146 }
147 }
148
149 func BenchmarkGnarl_Verify(b *testing.B) {
150 sk, pk, err := gnarl.GenerateKey()
151 if err != nil {
152 b.Fatal(err)
153 }
154 msg := []byte("benchmark message for verification")
155 challengeFunc := func(data []byte) [27]byte {
156 return GnarlSchnorrChallenge(data)
157 }
158 sig, err := gnarl.Sign(sk, msg, challengeFunc)
159 if err != nil {
160 b.Fatal(err)
161 }
162
163 b.ResetTimer()
164 for i := 0; i < b.N; i++ {
165 if !gnarl.Verify(pk, msg, sig, challengeFunc) {
166 b.Fatal("verification failed")
167 }
168 }
169 }
170
171 // --- Wire Format ---
172
173 func BenchmarkGnarlSeal_128(b *testing.B) {
174 var secret Hamadryad
175 h := GHash([]byte("bench-secret"))
176 copy(secret[:], h[:])
177 identity := GMid([]byte("bench-id"))
178 nonce := GnarlNonceFromCounter(0, 1)
179
180 msg := make([]byte, 128)
181 for i := range msg {
182 msg[i] = byte(i)
183 }
184 b.ResetTimer()
185 for i := 0; i < b.N; i++ {
186 GnarlSeal(secret, identity, nonce, msg)
187 }
188 }
189
190 func BenchmarkGnarlOpen_128(b *testing.B) {
191 var secret Hamadryad
192 h := GHash([]byte("bench-secret"))
193 copy(secret[:], h[:])
194 identity := GMid([]byte("bench-id"))
195 nonce := GnarlNonceFromCounter(0, 1)
196
197 msg := make([]byte, 128)
198 for i := range msg {
199 msg[i] = byte(i)
200 }
201 pkt := GnarlSeal(secret, identity, nonce, msg)
202 b.ResetTimer()
203 for i := 0; i < b.N; i++ {
204 _, err := GnarlOpen(secret, pkt)
205 if err != nil {
206 b.Fatal(err)
207 }
208 }
209 }
210
211 // --- Lattice Ring (post-quantum SVP-hard) ---
212
213 func BenchmarkRing_KeyGen(b *testing.B) {
214 gp := ring.SmallGPVParams()
215 for i := 0; i < b.N; i++ {
216 ring.GPVKeyGen(gp)
217 }
218 }
219
220 func BenchmarkRing_Sign(b *testing.B) {
221 gp := ring.SmallGPVParams()
222 _, sk := ring.GPVKeyGen(gp)
223 msg := []byte("benchmark message for signing")
224 b.ResetTimer()
225 for i := 0; i < b.N; i++ {
226 ring.GPVSign(sk, msg)
227 }
228 }
229
230 func BenchmarkRing_Verify(b *testing.B) {
231 gp := ring.SmallGPVParams()
232 pk, sk := ring.GPVKeyGen(gp)
233 msg := []byte("benchmark message for verification")
234 sig := ring.GPVSign(sk, msg)
235 b.ResetTimer()
236 for i := 0; i < b.N; i++ {
237 if !ring.GPVVerify(pk, msg, sig) {
238 b.Fatal("verification failed")
239 }
240 }
241 }
242
243 func BenchmarkRing_KEMKeyGen(b *testing.B) {
244 kp := ring.DefaultKEMParams()
245 for i := 0; i < b.N; i++ {
246 ring.KEMKeyGen(kp)
247 }
248 }
249
250 func BenchmarkRing_KEMEncapsulate(b *testing.B) {
251 kp := ring.DefaultKEMParams()
252 pk, _ := ring.KEMKeyGen(kp)
253 b.ResetTimer()
254 for i := 0; i < b.N; i++ {
255 ring.Encapsulate(pk)
256 }
257 }
258
259 func BenchmarkRing_KEMDecapsulate(b *testing.B) {
260 kp := ring.DefaultKEMParams()
261 pk, sk := ring.KEMKeyGen(kp)
262 _, ct, _ := ring.Encapsulate(pk)
263 b.ResetTimer()
264 for i := 0; i < b.N; i++ {
265 ring.Decapsulate(sk, ct)
266 }
267 }
268
269 func BenchmarkRing_HEEncrypt(b *testing.B) {
270 kp := ring.DefaultHEParams()
271 pk, _, _ := ring.HEKeyGen(kp)
272 b.ResetTimer()
273 for i := 0; i < b.N; i++ {
274 ring.HEEncrypt(pk, 1)
275 }
276 }
277
278 func BenchmarkRing_HEAdd(b *testing.B) {
279 kp := ring.DefaultHEParams()
280 pk, _, _ := ring.HEKeyGen(kp)
281 ct0 := ring.HEEncrypt(pk, 0)
282 ct1 := ring.HEEncrypt(pk, 1)
283 b.ResetTimer()
284 for i := 0; i < b.N; i++ {
285 ring.HEAdd(ct0, ct1)
286 }
287 }
288
289 func BenchmarkRing_HEMul(b *testing.B) {
290 kp := ring.DefaultHEParams()
291 pk, _, rlk := ring.HEKeyGen(kp)
292 ct0 := ring.HEEncrypt(pk, 1)
293 ct1 := ring.HEEncrypt(pk, 1)
294 b.ResetTimer()
295 for i := 0; i < b.N; i++ {
296 ring.HEMul(ct0, ct1, rlk)
297 }
298 }
299
300 func BenchmarkRing_SISHash_128(b *testing.B) {
301 sp := ring.HamadryadSISParams()
302 h := ring.NewSISHasher(sp, "hamadryad-swifft-v1-dendrite-kismet")
303 msg := make([]byte, 128)
304 for i := range msg {
305 msg[i] = byte(i)
306 }
307 b.ResetTimer()
308 for i := 0; i < b.N; i++ {
309 h.HashBytes(msg)
310 }
311 }
312