github.com/cloudflare/circl@v1.5.0/hpke/hpke_test.go (about) 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 // import "github.com/cloudflare/circl/hpke" 14 // import "crypto/rand" 15 16 // HPKE suite is a domain parameter. 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 // Bob prepares to receive messages and announces his public key. 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 // Alice gets Bob's public key. 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 // Alice encrypts some plaintext and sends the ciphertext to Bob. 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 // Bob decrypts the ciphertext. 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 // Plaintext was sent successfully. 62 fmt.Println(bytes.Equal(ptAlice, ptBob)) 63 // Output: true 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 }