Skip to content

Commit 91a8f97

Browse files
committed
Add tkn20 benchmarks
1 parent 5fabdc7 commit 91a8f97

File tree

1 file changed

+263
-0
lines changed

1 file changed

+263
-0
lines changed

abe/cpabe/tkn20/bench_test.go

Lines changed: 263 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
package tkn20
2+
3+
import (
4+
"crypto/rand"
5+
"crypto/rsa"
6+
"crypto/x509"
7+
"fmt"
8+
"golang.org/x/crypto/nacl/box"
9+
"strconv"
10+
"strings"
11+
"testing"
12+
//cpabe "github.com/cloudflare/circl/abe/cpabe/tkn20"
13+
)
14+
15+
type abeTestCase struct {
16+
desc string
17+
attrs Attributes
18+
policy Policy
19+
msk SystemSecretKey
20+
pk PublicKey
21+
}
22+
23+
var testCases []abeTestCase
24+
25+
var msg = []byte("drink your ovaltine now")
26+
var longMsg = []byte(strings.Repeat("a", 10000))
27+
28+
func generateAttrs() Attributes {
29+
benchableAttrs := make(map[string]string, 50)
30+
for i := 0; i < 50; i++ {
31+
benchableAttrs["k"+strconv.Itoa(i)] = "v" + strconv.Itoa(i)
32+
}
33+
attrs := Attributes{}
34+
attrs.FromMap(benchableAttrs)
35+
return attrs
36+
}
37+
38+
func generatePolicy() string {
39+
var policyBuilder strings.Builder
40+
for i := 0; i < 50; i++ {
41+
policyBuilder.WriteString("k")
42+
policyBuilder.WriteString(strconv.Itoa(i))
43+
policyBuilder.WriteString(":v")
44+
policyBuilder.WriteString(strconv.Itoa(i))
45+
if i != 49 {
46+
if i%2 == 0 {
47+
policyBuilder.WriteString(" and ")
48+
} else {
49+
policyBuilder.WriteString(" or ")
50+
}
51+
}
52+
}
53+
return policyBuilder.String()
54+
}
55+
56+
func init() {
57+
smallPolicy := Policy{}
58+
smallPolicy.FromString("(k1:v1 or k1:v2) and not k2:v3")
59+
smallAttrs := Attributes{}
60+
smallAttrs.FromMap(map[string]string{"k1": "v2", "k2": "v4"})
61+
longPolicy := Policy{}
62+
longPolicy.FromString(generatePolicy())
63+
testCases = []abeTestCase{
64+
{
65+
desc: "smallPolicy/Attrs",
66+
attrs: smallAttrs,
67+
policy: smallPolicy,
68+
},
69+
{
70+
desc: "longPolicy/Attrs",
71+
attrs: generateAttrs(),
72+
policy: longPolicy,
73+
},
74+
}
75+
var err error
76+
for i := range testCases {
77+
testCases[i].pk, testCases[i].msk, err = Setup(rand.Reader)
78+
if err != nil {
79+
panic(err)
80+
}
81+
}
82+
}
83+
84+
func BenchmarkTKN20KeyGen(b *testing.B) {
85+
for _, tc := range testCases {
86+
b.Run(fmt.Sprintf("keygen:%s", tc.desc), func(b *testing.B) {
87+
b.ResetTimer()
88+
for i := 0; i < b.N; i++ {
89+
_, err := tc.msk.KeyGen(rand.Reader, tc.attrs)
90+
if err != nil {
91+
b.Fatal(err)
92+
}
93+
}
94+
})
95+
}
96+
}
97+
98+
func BenchmarkRSAKeyGen(b *testing.B) {
99+
for i := 0; i < b.N; i++ {
100+
_, err := rsa.GenerateKey(rand.Reader, 2048)
101+
if err != nil {
102+
b.Fatal(err)
103+
}
104+
}
105+
}
106+
107+
func BenchmarkX25519KeyGen(b *testing.B) {
108+
for i := 0; i < b.N; i++ {
109+
_, _, err := box.GenerateKey(rand.Reader)
110+
if err != nil {
111+
b.Fatal(err)
112+
}
113+
}
114+
}
115+
116+
func BenchmarkTKN20Encrypt(b *testing.B) {
117+
for _, tc := range testCases {
118+
b.Run(fmt.Sprintf("encrypt:%s", tc.desc), func(b *testing.B) {
119+
b.ResetTimer()
120+
for i := 0; i < b.N; i++ {
121+
_, err := tc.pk.Encrypt(rand.Reader, tc.policy, msg)
122+
if err != nil {
123+
b.Fatal(err)
124+
}
125+
}
126+
})
127+
}
128+
}
129+
130+
func BenchmarkRSAEncrypt(b *testing.B) {
131+
privKey, err := rsa.GenerateKey(rand.Reader, 2048)
132+
if err != nil {
133+
b.Fatal(err)
134+
}
135+
pubKey := privKey.PublicKey
136+
b.ResetTimer()
137+
for i := 0; i < b.N; i++ {
138+
_, err := rsa.EncryptPKCS1v15(rand.Reader, &pubKey, msg)
139+
if err != nil {
140+
b.Fatal(err)
141+
}
142+
}
143+
}
144+
145+
func BenchmarkX25519Encrypt(b *testing.B) {
146+
pubKey, _, err := box.GenerateKey(rand.Reader)
147+
if err != nil {
148+
b.Fatal(err)
149+
}
150+
b.ResetTimer()
151+
for i := 0; i < b.N; i++ {
152+
_, err := box.SealAnonymous(nil, msg, pubKey, rand.Reader)
153+
if err != nil {
154+
b.Fatal(err)
155+
}
156+
}
157+
}
158+
159+
func BenchmarkTKN20Decrypt(b *testing.B) {
160+
for _, tc := range testCases {
161+
b.Run(fmt.Sprintf("decrypt:%s", tc.desc), func(b *testing.B) {
162+
userKey, err := tc.msk.KeyGen(rand.Reader, tc.attrs)
163+
if err != nil {
164+
b.Fatal(err)
165+
}
166+
ciphertext, err := tc.pk.Encrypt(rand.Reader, tc.policy, msg)
167+
if err != nil {
168+
b.Fatal(err)
169+
}
170+
keyBytes, _ := userKey.MarshalBinary()
171+
pubKeyBytes, _ := tc.pk.MarshalBinary()
172+
// longCt is only benchmarked to measure size overhead
173+
longCt, err := tc.pk.Encrypt(rand.Reader, tc.policy, longMsg)
174+
if err != nil {
175+
b.Fatal(err)
176+
}
177+
b.ResetTimer()
178+
for i := 0; i < b.N; i++ {
179+
_, err = userKey.Decrypt(ciphertext)
180+
if err != nil {
181+
b.Fatal(err)
182+
}
183+
}
184+
b.ReportMetric(float64(len(pubKeyBytes)), "public_key_size")
185+
b.ReportMetric(float64(len(keyBytes)), "attribute_secret_key_size")
186+
b.ReportMetric(float64(len(ciphertext)-len(msg)), "ciphertext_bytes_overhead_32b_msg")
187+
b.ReportMetric(float64(len(longCt)-len(longMsg)), "ciphertext_bytes_overhead_10kb_msg")
188+
})
189+
}
190+
}
191+
192+
func BenchmarkRSADecrypt(b *testing.B) {
193+
privKey, err := rsa.GenerateKey(rand.Reader, 2048)
194+
if err != nil {
195+
b.Fatal(err)
196+
}
197+
pubKey := privKey.PublicKey
198+
ct, err := rsa.EncryptPKCS1v15(rand.Reader, &pubKey, msg)
199+
if err != nil {
200+
b.Fatal(err)
201+
}
202+
// longCt is only benchmarked to measure size overhead
203+
longCt, err := rsaEncrypt(longMsg, &privKey.PublicKey)
204+
if err != nil {
205+
b.Fatal(err)
206+
}
207+
b.ResetTimer()
208+
for i := 0; i < b.N; i++ {
209+
_, err := rsa.DecryptPKCS1v15(rand.Reader, privKey, ct)
210+
if err != nil {
211+
b.Fatal(err)
212+
}
213+
}
214+
b.ReportMetric(float64(privKey.PublicKey.Size()), "public_key_size")
215+
b.ReportMetric(float64(len(x509.MarshalPKCS1PrivateKey(privKey))), "secret_key_size")
216+
b.ReportMetric(float64(len(ct)-len(msg)), "ciphertext_bytes_overhead")
217+
b.ReportMetric(float64(len(longCt)-len(longMsg)), "ciphertext_bytes_overhead_10kb_msg")
218+
}
219+
220+
func BenchmarkX25519Decrypt(b *testing.B) {
221+
pubKey, privKey, err := box.GenerateKey(rand.Reader)
222+
if err != nil {
223+
b.Fatal(err)
224+
}
225+
ct, err := box.SealAnonymous(nil, msg, pubKey, rand.Reader)
226+
if err != nil {
227+
b.Fatal(err)
228+
}
229+
// longCt is only benchmarked to measure size overhead
230+
longCt, err := box.SealAnonymous(nil, longMsg, pubKey, rand.Reader)
231+
if err != nil {
232+
b.Fatal(err)
233+
}
234+
b.ResetTimer()
235+
for i := 0; i < b.N; i++ {
236+
_, ok := box.OpenAnonymous(nil, ct, pubKey, privKey)
237+
if !ok {
238+
b.Fatal(err)
239+
}
240+
}
241+
b.ReportMetric(float64(len(pubKey)), "public_key_size")
242+
b.ReportMetric(float64(len(privKey)), "secret_key_size")
243+
b.ReportMetric(float64(len(ct)-len(msg)), "ciphertext_bytes_overhead_32b_msg")
244+
b.ReportMetric(float64(len(longCt)-len(longMsg)), "ciphertext_bytes_overhead_10kb_msg")
245+
}
246+
247+
func rsaEncrypt(data []byte, pubKey *rsa.PublicKey) ([]byte, error) {
248+
chunkSize := 245 // Max chunk size for 2048 bit key with PKCS1v15 padding
249+
var ct []byte
250+
for len(data) > 0 {
251+
if len(data) < chunkSize {
252+
chunkSize = len(data)
253+
}
254+
chunk := data[:chunkSize]
255+
data = data[chunkSize:]
256+
encryptedChunk, err := rsa.EncryptPKCS1v15(rand.Reader, pubKey, chunk)
257+
if err != nil {
258+
return nil, err
259+
}
260+
ct = append(ct, encryptedChunk...)
261+
}
262+
return ct, nil
263+
}

0 commit comments

Comments
 (0)