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  }