1 package hpke_test
2
3 import (
4 "bytes"
5 "crypto/rand"
6 "fmt"
7 "testing"
8
9 "github.com/cloudflare/circl/hpke"
10 )
11
12 func Example() {
13
14
15
16
17 kemID := hpke.KEM_P384_HKDF_SHA384
18 kdfID := hpke.KDF_HKDF_SHA384
19 aeadID := hpke.AEAD_AES256GCM
20 suite := hpke.NewSuite(kemID, kdfID, aeadID)
21 info := []byte("public info string, known to both Alice and Bob")
22
23
24 publicBob, privateBob, err := kemID.Scheme().GenerateKeyPair()
25 if err != nil {
26 panic(err)
27 }
28 Bob, err := suite.NewReceiver(privateBob, info)
29 if err != nil {
30 panic(err)
31 }
32
33
34 Alice, err := suite.NewSender(publicBob, info)
35 if err != nil {
36 panic(err)
37 }
38 enc, sealer, err := Alice.Setup(rand.Reader)
39 if err != nil {
40 panic(err)
41 }
42
43
44 ptAlice := []byte("text encrypted to Bob's public key")
45 aad := []byte("additional public data")
46 ct, err := sealer.Seal(ptAlice, aad)
47 if err != nil {
48 panic(err)
49 }
50
51
52 opener, err := Bob.Setup(enc)
53 if err != nil {
54 panic(err)
55 }
56 ptBob, err := opener.Open(ct, aad)
57 if err != nil {
58 panic(err)
59 }
60
61
62 fmt.Println(bytes.Equal(ptAlice, ptBob))
63
64 }
65
66 func runHpkeBenchmark(b *testing.B, kem hpke.KEM, kdf hpke.KDF, aead hpke.AEAD) {
67 suite := hpke.NewSuite(kem, kdf, aead)
68
69 pkR, skR, err := kem.Scheme().GenerateKeyPair()
70 if err != nil {
71 b.Fatal(err)
72 }
73
74 info := []byte("public info string")
75 sender, err := suite.NewSender(pkR, info)
76 if err != nil {
77 b.Fatal(err)
78 }
79
80 b.Run(fmt.Sprintf("SetupSender-%04x-%04x-%04x", kem, kdf, aead), func(b *testing.B) {
81 for i := 0; i < b.N; i++ {
82 _, _, err = sender.Setup(rand.Reader)
83 if err != nil {
84 b.Fatal(err)
85 }
86 }
87 })
88
89 enc, _, err := sender.Setup(rand.Reader)
90 if err != nil {
91 b.Fatal(err)
92 }
93
94 receiver, err := suite.NewReceiver(skR, info)
95 if err != nil {
96 b.Fatal(err)
97 }
98
99 b.Run(fmt.Sprintf("SetupReceiver-%04x-%04x-%04x", kem, kdf, aead), func(b *testing.B) {
100 for i := 0; i < b.N; i++ {
101 _, err := receiver.Setup(enc)
102 if err != nil {
103 b.Fatal(err)
104 }
105 }
106 })
107
108 b.Run(fmt.Sprintf("Encrypt-%04x-%04x-%04x", kem, kdf, aead), func(b *testing.B) {
109 pt := []byte("plaintext")
110 aad := []byte("additional authenticated data")
111 cts := make([][]byte, b.N)
112 _, sealer, err := sender.Setup(rand.Reader)
113 if err != nil {
114 b.Fatal(err)
115 }
116
117 b.ResetTimer()
118 for i := 0; i < b.N; i++ {
119 cts[i], err = sealer.Seal(pt, aad)
120 if err != nil {
121 b.Fatal(err)
122 }
123 }
124 })
125
126 b.Run(fmt.Sprintf("Decrypt-%04x-%04x-%04x", kem, kdf, aead), func(b *testing.B) {
127 pt := []byte("plaintext")
128 aad := []byte("additional authenticated data")
129 cts := make([][]byte, b.N)
130 enc, sealer, err := sender.Setup(rand.Reader)
131 if err != nil {
132 b.Fatal(err)
133 }
134 opener, err := receiver.Setup(enc)
135 if err != nil {
136 b.Fatal(err)
137 }
138 for i := 0; i < b.N; i++ {
139 cts[i], err = sealer.Seal(pt, aad)
140 if err != nil {
141 b.Fatal(err)
142 }
143 }
144 b.ResetTimer()
145 for i := 0; i < b.N; i++ {
146 _, err = opener.Open(cts[i], aad)
147 if err != nil {
148 b.Log(i)
149 b.Fatal(err)
150 }
151 }
152 })
153 }
154
155 func BenchmarkHpkeRoundTrip(b *testing.B) {
156 tests := []struct {
157 kem hpke.KEM
158 kdf hpke.KDF
159 aead hpke.AEAD
160 }{
161 {hpke.KEM_X25519_HKDF_SHA256, hpke.KDF_HKDF_SHA256, hpke.AEAD_AES128GCM},
162 {hpke.KEM_X25519_KYBER768_DRAFT00, hpke.KDF_HKDF_SHA256, hpke.AEAD_AES128GCM},
163 }
164 for _, test := range tests {
165 runHpkeBenchmark(b, test.kem, test.kdf, test.aead)
166 }
167 }
168
View as plain text