@@ -15,6 +15,7 @@ import (
1515 "github.com/cloudflare/circl/dh/x448"
1616 "github.com/cloudflare/circl/ecc/p384"
1717 "github.com/cloudflare/circl/kem"
18+ "github.com/cloudflare/circl/kem/kyber/kyber768"
1819 "golang.org/x/crypto/chacha20poly1305"
1920 "golang.org/x/crypto/hkdf"
2021)
@@ -35,6 +36,9 @@ const (
3536 // KEM_X448_HKDF_SHA512 is a KEM using X448 Diffie-Hellman function and
3637 // HKDF with SHA-512.
3738 KEM_X448_HKDF_SHA512 KEM = 0x21
39+ // KEM_X25519_KYBER768_DRAFT00 is a hybrid KEM built on DHKEM(X25519, HKDF-SHA256)
40+ // and Kyber768Draft00
41+ KEM_X25519_KYBER768_DRAFT00 KEM = 0x30
3842)
3943
4044// IsValid returns true if the KEM identifier is supported by the HPKE package.
@@ -44,7 +48,8 @@ func (k KEM) IsValid() bool {
4448 KEM_P384_HKDF_SHA384 ,
4549 KEM_P521_HKDF_SHA512 ,
4650 KEM_X25519_HKDF_SHA256 ,
47- KEM_X448_HKDF_SHA512 :
51+ KEM_X448_HKDF_SHA512 ,
52+ KEM_X25519_KYBER768_DRAFT00 :
4853 return true
4954 default :
5055 return false
@@ -65,32 +70,8 @@ func (k KEM) Scheme() kem.AuthScheme {
6570 return dhkemx25519hkdfsha256
6671 case KEM_X448_HKDF_SHA512 :
6772 return dhkemx448hkdfsha512
68- default :
69- panic (ErrInvalidKEM )
70- }
71- }
72-
73- func (k KEM ) validatePublicKey (pk kem.PublicKey ) bool {
74- switch k {
75- case KEM_P256_HKDF_SHA256 , KEM_P384_HKDF_SHA384 , KEM_P521_HKDF_SHA512 :
76- pub , ok := pk .(* shortKEMPubKey )
77- return ok && k == pub .scheme .id && pub .Validate ()
78- case KEM_X25519_HKDF_SHA256 , KEM_X448_HKDF_SHA512 :
79- pub , ok := pk .(* xKEMPubKey )
80- return ok && k == pub .scheme .id && pub .Validate ()
81- default :
82- panic (ErrInvalidKEM )
83- }
84- }
85-
86- func (k KEM ) validatePrivateKey (sk kem.PrivateKey ) bool {
87- switch k {
88- case KEM_P256_HKDF_SHA256 , KEM_P384_HKDF_SHA384 , KEM_P521_HKDF_SHA512 :
89- priv , ok := sk .(* shortKEMPrivKey )
90- return ok && k == priv .scheme .id && priv .Validate ()
91- case KEM_X25519_HKDF_SHA256 , KEM_X448_HKDF_SHA512 :
92- priv , ok := sk .(* xKEMPrivKey )
93- return ok && k == priv .scheme .id && priv .Validate ()
73+ case KEM_X25519_KYBER768_DRAFT00 :
74+ return hybridkemX25519Kyber768
9475 default :
9576 panic (ErrInvalidKEM )
9677 }
@@ -243,36 +224,43 @@ func (a AEAD) CipherLen(mLen uint) uint {
243224var (
244225 dhkemp256hkdfsha256 , dhkemp384hkdfsha384 , dhkemp521hkdfsha512 shortKEM
245226 dhkemx25519hkdfsha256 , dhkemx448hkdfsha512 xKEM
227+ hybridkemX25519Kyber768 hybridKEM
246228)
247229
248230func init () {
249231 dhkemp256hkdfsha256 .Curve = elliptic .P256 ()
250- dhkemp256hkdfsha256 .kemBase .id = KEM_P256_HKDF_SHA256
251- dhkemp256hkdfsha256 .kemBase .name = "HPKE_KEM_P256_HKDF_SHA256"
252- dhkemp256hkdfsha256 .kemBase .Hash = crypto .SHA256
253- dhkemp256hkdfsha256 .kemBase .dhKEM = dhkemp256hkdfsha256
232+ dhkemp256hkdfsha256 .dhKemBase .id = KEM_P256_HKDF_SHA256
233+ dhkemp256hkdfsha256 .dhKemBase .name = "HPKE_KEM_P256_HKDF_SHA256"
234+ dhkemp256hkdfsha256 .dhKemBase .Hash = crypto .SHA256
235+ dhkemp256hkdfsha256 .dhKemBase .dhKEM = dhkemp256hkdfsha256
254236
255237 dhkemp384hkdfsha384 .Curve = p384 .P384 ()
256- dhkemp384hkdfsha384 .kemBase .id = KEM_P384_HKDF_SHA384
257- dhkemp384hkdfsha384 .kemBase .name = "HPKE_KEM_P384_HKDF_SHA384"
258- dhkemp384hkdfsha384 .kemBase .Hash = crypto .SHA384
259- dhkemp384hkdfsha384 .kemBase .dhKEM = dhkemp384hkdfsha384
238+ dhkemp384hkdfsha384 .dhKemBase .id = KEM_P384_HKDF_SHA384
239+ dhkemp384hkdfsha384 .dhKemBase .name = "HPKE_KEM_P384_HKDF_SHA384"
240+ dhkemp384hkdfsha384 .dhKemBase .Hash = crypto .SHA384
241+ dhkemp384hkdfsha384 .dhKemBase .dhKEM = dhkemp384hkdfsha384
260242
261243 dhkemp521hkdfsha512 .Curve = elliptic .P521 ()
262- dhkemp521hkdfsha512 .kemBase .id = KEM_P521_HKDF_SHA512
263- dhkemp521hkdfsha512 .kemBase .name = "HPKE_KEM_P521_HKDF_SHA512"
264- dhkemp521hkdfsha512 .kemBase .Hash = crypto .SHA512
265- dhkemp521hkdfsha512 .kemBase .dhKEM = dhkemp521hkdfsha512
244+ dhkemp521hkdfsha512 .dhKemBase .id = KEM_P521_HKDF_SHA512
245+ dhkemp521hkdfsha512 .dhKemBase .name = "HPKE_KEM_P521_HKDF_SHA512"
246+ dhkemp521hkdfsha512 .dhKemBase .Hash = crypto .SHA512
247+ dhkemp521hkdfsha512 .dhKemBase .dhKEM = dhkemp521hkdfsha512
266248
267249 dhkemx25519hkdfsha256 .size = x25519 .Size
268- dhkemx25519hkdfsha256 .kemBase .id = KEM_X25519_HKDF_SHA256
269- dhkemx25519hkdfsha256 .kemBase .name = "HPKE_KEM_X25519_HKDF_SHA256"
270- dhkemx25519hkdfsha256 .kemBase .Hash = crypto .SHA256
271- dhkemx25519hkdfsha256 .kemBase .dhKEM = dhkemx25519hkdfsha256
250+ dhkemx25519hkdfsha256 .dhKemBase .id = KEM_X25519_HKDF_SHA256
251+ dhkemx25519hkdfsha256 .dhKemBase .name = "HPKE_KEM_X25519_HKDF_SHA256"
252+ dhkemx25519hkdfsha256 .dhKemBase .Hash = crypto .SHA256
253+ dhkemx25519hkdfsha256 .dhKemBase .dhKEM = dhkemx25519hkdfsha256
272254
273255 dhkemx448hkdfsha512 .size = x448 .Size
274- dhkemx448hkdfsha512 .kemBase .id = KEM_X448_HKDF_SHA512
275- dhkemx448hkdfsha512 .kemBase .name = "HPKE_KEM_X448_HKDF_SHA512"
276- dhkemx448hkdfsha512 .kemBase .Hash = crypto .SHA512
277- dhkemx448hkdfsha512 .kemBase .dhKEM = dhkemx448hkdfsha512
256+ dhkemx448hkdfsha512 .dhKemBase .id = KEM_X448_HKDF_SHA512
257+ dhkemx448hkdfsha512 .dhKemBase .name = "HPKE_KEM_X448_HKDF_SHA512"
258+ dhkemx448hkdfsha512 .dhKemBase .Hash = crypto .SHA512
259+ dhkemx448hkdfsha512 .dhKemBase .dhKEM = dhkemx448hkdfsha512
260+
261+ hybridkemX25519Kyber768 .kemBase .id = KEM_X25519_KYBER768_DRAFT00
262+ hybridkemX25519Kyber768 .kemBase .name = "HPKE_KEM_X25519_KYBER768_HKDF_SHA256"
263+ hybridkemX25519Kyber768 .kemBase .Hash = crypto .SHA256
264+ hybridkemX25519Kyber768 .kemA = dhkemx25519hkdfsha256
265+ hybridkemX25519Kyber768 .kemB = kyber768 .Scheme ()
278266}
0 commit comments