Skip to content

Commit

Permalink
Add tkn20 benchmarks
Browse files Browse the repository at this point in the history
  • Loading branch information
tanyav2 committed May 31, 2023
1 parent 5fabdc7 commit 91a8f97
Showing 1 changed file with 263 additions and 0 deletions.
263 changes: 263 additions & 0 deletions abe/cpabe/tkn20/bench_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,263 @@
package tkn20

import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"fmt"
"golang.org/x/crypto/nacl/box"

Check failure on line 8 in abe/cpabe/tkn20/bench_test.go

View workflow job for this annotation

GitHub Actions / Go-1.19/amd64

File is not `gofumpt`-ed (gofumpt)
"strconv"
"strings"
"testing"

Check failure on line 11 in abe/cpabe/tkn20/bench_test.go

View workflow job for this annotation

GitHub Actions / Go-1.19/amd64

File is not `goimports`-ed (goimports)
//cpabe "github.com/cloudflare/circl/abe/cpabe/tkn20"

Check failure on line 12 in abe/cpabe/tkn20/bench_test.go

View workflow job for this annotation

GitHub Actions / Go-1.19/amd64

File is not `gofumpt`-ed (gofumpt)
)

type abeTestCase struct {
desc string
attrs Attributes
policy Policy
msk SystemSecretKey
pk PublicKey
}

var testCases []abeTestCase

var msg = []byte("drink your ovaltine now")

Check failure on line 25 in abe/cpabe/tkn20/bench_test.go

View workflow job for this annotation

GitHub Actions / Go-1.19/amd64

File is not `gofumpt`-ed (gofumpt)
var longMsg = []byte(strings.Repeat("a", 10000))

func generateAttrs() Attributes {
benchableAttrs := make(map[string]string, 50)
for i := 0; i < 50; i++ {
benchableAttrs["k"+strconv.Itoa(i)] = "v" + strconv.Itoa(i)
}
attrs := Attributes{}
attrs.FromMap(benchableAttrs)
return attrs
}

func generatePolicy() string {
var policyBuilder strings.Builder
for i := 0; i < 50; i++ {
policyBuilder.WriteString("k")
policyBuilder.WriteString(strconv.Itoa(i))
policyBuilder.WriteString(":v")
policyBuilder.WriteString(strconv.Itoa(i))
if i != 49 {
if i%2 == 0 {
policyBuilder.WriteString(" and ")
} else {
policyBuilder.WriteString(" or ")
}
}
}
return policyBuilder.String()
}

func init() {
smallPolicy := Policy{}
smallPolicy.FromString("(k1:v1 or k1:v2) and not k2:v3")

Check failure on line 58 in abe/cpabe/tkn20/bench_test.go

View workflow job for this annotation

GitHub Actions / Go-1.19/amd64

Error return value of `smallPolicy.FromString` is not checked (errcheck)
smallAttrs := Attributes{}
smallAttrs.FromMap(map[string]string{"k1": "v2", "k2": "v4"})
longPolicy := Policy{}
longPolicy.FromString(generatePolicy())

Check failure on line 62 in abe/cpabe/tkn20/bench_test.go

View workflow job for this annotation

GitHub Actions / Go-1.19/amd64

Error return value of `longPolicy.FromString` is not checked (errcheck)
testCases = []abeTestCase{
{
desc: "smallPolicy/Attrs",
attrs: smallAttrs,
policy: smallPolicy,
},
{
desc: "longPolicy/Attrs",
attrs: generateAttrs(),
policy: longPolicy,
},
}
var err error
for i := range testCases {
testCases[i].pk, testCases[i].msk, err = Setup(rand.Reader)
if err != nil {
panic(err)
}
}
}

func BenchmarkTKN20KeyGen(b *testing.B) {
for _, tc := range testCases {
b.Run(fmt.Sprintf("keygen:%s", tc.desc), func(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, err := tc.msk.KeyGen(rand.Reader, tc.attrs)
if err != nil {
b.Fatal(err)
}
}
})
}
}

func BenchmarkRSAKeyGen(b *testing.B) {
for i := 0; i < b.N; i++ {
_, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
b.Fatal(err)
}
}
}

func BenchmarkX25519KeyGen(b *testing.B) {
for i := 0; i < b.N; i++ {
_, _, err := box.GenerateKey(rand.Reader)
if err != nil {
b.Fatal(err)
}
}
}

func BenchmarkTKN20Encrypt(b *testing.B) {
for _, tc := range testCases {
b.Run(fmt.Sprintf("encrypt:%s", tc.desc), func(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, err := tc.pk.Encrypt(rand.Reader, tc.policy, msg)
if err != nil {
b.Fatal(err)
}
}
})
}
}

func BenchmarkRSAEncrypt(b *testing.B) {
privKey, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
b.Fatal(err)
}
pubKey := privKey.PublicKey
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, err := rsa.EncryptPKCS1v15(rand.Reader, &pubKey, msg)
if err != nil {
b.Fatal(err)
}
}
}

func BenchmarkX25519Encrypt(b *testing.B) {
pubKey, _, err := box.GenerateKey(rand.Reader)
if err != nil {
b.Fatal(err)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, err := box.SealAnonymous(nil, msg, pubKey, rand.Reader)
if err != nil {
b.Fatal(err)
}
}
}

func BenchmarkTKN20Decrypt(b *testing.B) {
for _, tc := range testCases {
b.Run(fmt.Sprintf("decrypt:%s", tc.desc), func(b *testing.B) {
userKey, err := tc.msk.KeyGen(rand.Reader, tc.attrs)
if err != nil {
b.Fatal(err)
}
ciphertext, err := tc.pk.Encrypt(rand.Reader, tc.policy, msg)
if err != nil {
b.Fatal(err)
}
keyBytes, _ := userKey.MarshalBinary()
pubKeyBytes, _ := tc.pk.MarshalBinary()
// longCt is only benchmarked to measure size overhead
longCt, err := tc.pk.Encrypt(rand.Reader, tc.policy, longMsg)
if err != nil {
b.Fatal(err)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, err = userKey.Decrypt(ciphertext)
if err != nil {
b.Fatal(err)
}
}
b.ReportMetric(float64(len(pubKeyBytes)), "public_key_size")
b.ReportMetric(float64(len(keyBytes)), "attribute_secret_key_size")
b.ReportMetric(float64(len(ciphertext)-len(msg)), "ciphertext_bytes_overhead_32b_msg")
b.ReportMetric(float64(len(longCt)-len(longMsg)), "ciphertext_bytes_overhead_10kb_msg")
})
}
}

func BenchmarkRSADecrypt(b *testing.B) {
privKey, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
b.Fatal(err)
}
pubKey := privKey.PublicKey
ct, err := rsa.EncryptPKCS1v15(rand.Reader, &pubKey, msg)
if err != nil {
b.Fatal(err)
}
// longCt is only benchmarked to measure size overhead
longCt, err := rsaEncrypt(longMsg, &privKey.PublicKey)
if err != nil {
b.Fatal(err)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, err := rsa.DecryptPKCS1v15(rand.Reader, privKey, ct)
if err != nil {
b.Fatal(err)
}
}
b.ReportMetric(float64(privKey.PublicKey.Size()), "public_key_size")
b.ReportMetric(float64(len(x509.MarshalPKCS1PrivateKey(privKey))), "secret_key_size")
b.ReportMetric(float64(len(ct)-len(msg)), "ciphertext_bytes_overhead")
b.ReportMetric(float64(len(longCt)-len(longMsg)), "ciphertext_bytes_overhead_10kb_msg")
}

func BenchmarkX25519Decrypt(b *testing.B) {
pubKey, privKey, err := box.GenerateKey(rand.Reader)
if err != nil {
b.Fatal(err)
}
ct, err := box.SealAnonymous(nil, msg, pubKey, rand.Reader)
if err != nil {
b.Fatal(err)
}
// longCt is only benchmarked to measure size overhead
longCt, err := box.SealAnonymous(nil, longMsg, pubKey, rand.Reader)
if err != nil {
b.Fatal(err)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, ok := box.OpenAnonymous(nil, ct, pubKey, privKey)
if !ok {
b.Fatal(err)
}
}
b.ReportMetric(float64(len(pubKey)), "public_key_size")
b.ReportMetric(float64(len(privKey)), "secret_key_size")
b.ReportMetric(float64(len(ct)-len(msg)), "ciphertext_bytes_overhead_32b_msg")
b.ReportMetric(float64(len(longCt)-len(longMsg)), "ciphertext_bytes_overhead_10kb_msg")
}

func rsaEncrypt(data []byte, pubKey *rsa.PublicKey) ([]byte, error) {
chunkSize := 245 // Max chunk size for 2048 bit key with PKCS1v15 padding
var ct []byte
for len(data) > 0 {
if len(data) < chunkSize {
chunkSize = len(data)
}
chunk := data[:chunkSize]
data = data[chunkSize:]
encryptedChunk, err := rsa.EncryptPKCS1v15(rand.Reader, pubKey, chunk)
if err != nil {
return nil, err
}
ct = append(ct, encryptedChunk...)
}
return ct, nil
}

0 comments on commit 91a8f97

Please sign in to comment.