diff --git a/docs/grpc/index.html b/docs/grpc/index.html
index c598fdd7a2..ac4fd9dc06 100644
--- a/docs/grpc/index.html
+++ b/docs/grpc/index.html
@@ -4043,6 +4043,24 @@
Algorithm
|
+
+ | ALGORITHM_MLKEM_768 |
+ 20 |
+ |
+
+
+
+ | ALGORITHM_MLKEM_1024 |
+ 21 |
+ |
+
+
+
+ | ALGORITHM_XWING |
+ 30 |
+ |
+
+
@@ -4154,6 +4172,24 @@ KasPublicKeyAlgEnum
|
+
+ | KAS_PUBLIC_KEY_ALG_ENUM_MLKEM_768 |
+ 20 |
+ |
+
+
+
+ | KAS_PUBLIC_KEY_ALG_ENUM_MLKEM_1024 |
+ 21 |
+ |
+
+
+
+ | KAS_PUBLIC_KEY_ALG_ENUM_XWING |
+ 30 |
+ |
+
+
diff --git a/docs/openapi/authorization/authorization.openapi.yaml b/docs/openapi/authorization/authorization.openapi.yaml
index b17083ebd1..d1c9d25346 100644
--- a/docs/openapi/authorization/authorization.openapi.yaml
+++ b/docs/openapi/authorization/authorization.openapi.yaml
@@ -343,6 +343,9 @@ components:
- ALGORITHM_EC_P256
- ALGORITHM_EC_P384
- ALGORITHM_EC_P521
+ - ALGORITHM_MLKEM_768
+ - ALGORITHM_MLKEM_1024
+ - ALGORITHM_XWING
description: Supported key algorithms.
policy.KasPublicKeyAlgEnum:
type: string
@@ -354,6 +357,9 @@ components:
- KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP256R1
- KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP384R1
- KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP521R1
+ - KAS_PUBLIC_KEY_ALG_ENUM_MLKEM_768
+ - KAS_PUBLIC_KEY_ALG_ENUM_MLKEM_1024
+ - KAS_PUBLIC_KEY_ALG_ENUM_XWING
policy.SourceType:
type: string
title: SourceType
diff --git a/docs/openapi/authorization/v2/authorization.openapi.yaml b/docs/openapi/authorization/v2/authorization.openapi.yaml
index 0f4f92d55f..c0ccd4151d 100644
--- a/docs/openapi/authorization/v2/authorization.openapi.yaml
+++ b/docs/openapi/authorization/v2/authorization.openapi.yaml
@@ -175,6 +175,9 @@ components:
- ALGORITHM_EC_P256
- ALGORITHM_EC_P384
- ALGORITHM_EC_P521
+ - ALGORITHM_MLKEM_768
+ - ALGORITHM_MLKEM_1024
+ - ALGORITHM_XWING
description: Supported key algorithms.
policy.KasPublicKeyAlgEnum:
type: string
@@ -186,6 +189,9 @@ components:
- KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP256R1
- KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP384R1
- KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP521R1
+ - KAS_PUBLIC_KEY_ALG_ENUM_MLKEM_768
+ - KAS_PUBLIC_KEY_ALG_ENUM_MLKEM_1024
+ - KAS_PUBLIC_KEY_ALG_ENUM_XWING
policy.SourceType:
type: string
title: SourceType
diff --git a/docs/openapi/policy/actions/actions.openapi.yaml b/docs/openapi/policy/actions/actions.openapi.yaml
index ec633192ae..c75968d8bb 100644
--- a/docs/openapi/policy/actions/actions.openapi.yaml
+++ b/docs/openapi/policy/actions/actions.openapi.yaml
@@ -203,6 +203,9 @@ components:
- ALGORITHM_EC_P256
- ALGORITHM_EC_P384
- ALGORITHM_EC_P521
+ - ALGORITHM_MLKEM_768
+ - ALGORITHM_MLKEM_1024
+ - ALGORITHM_XWING
description: Supported key algorithms.
policy.AttributeRuleTypeEnum:
type: string
@@ -229,6 +232,9 @@ components:
- KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP256R1
- KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP384R1
- KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP521R1
+ - KAS_PUBLIC_KEY_ALG_ENUM_MLKEM_768
+ - KAS_PUBLIC_KEY_ALG_ENUM_MLKEM_1024
+ - KAS_PUBLIC_KEY_ALG_ENUM_XWING
policy.SourceType:
type: string
title: SourceType
diff --git a/docs/openapi/policy/attributes/attributes.openapi.yaml b/docs/openapi/policy/attributes/attributes.openapi.yaml
index 0fcb66f710..0dd745cedb 100644
--- a/docs/openapi/policy/attributes/attributes.openapi.yaml
+++ b/docs/openapi/policy/attributes/attributes.openapi.yaml
@@ -724,6 +724,9 @@ components:
- ALGORITHM_EC_P256
- ALGORITHM_EC_P384
- ALGORITHM_EC_P521
+ - ALGORITHM_MLKEM_768
+ - ALGORITHM_MLKEM_1024
+ - ALGORITHM_XWING
description: Supported key algorithms.
policy.AttributeRuleTypeEnum:
type: string
@@ -750,6 +753,9 @@ components:
- KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP256R1
- KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP384R1
- KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP521R1
+ - KAS_PUBLIC_KEY_ALG_ENUM_MLKEM_768
+ - KAS_PUBLIC_KEY_ALG_ENUM_MLKEM_1024
+ - KAS_PUBLIC_KEY_ALG_ENUM_XWING
policy.SortDirection:
type: string
title: SortDirection
diff --git a/docs/openapi/policy/kasregistry/key_access_server_registry.openapi.yaml b/docs/openapi/policy/kasregistry/key_access_server_registry.openapi.yaml
index 9cdc346918..cdf0b6a95a 100644
--- a/docs/openapi/policy/kasregistry/key_access_server_registry.openapi.yaml
+++ b/docs/openapi/policy/kasregistry/key_access_server_registry.openapi.yaml
@@ -534,6 +534,9 @@ components:
- ALGORITHM_EC_P256
- ALGORITHM_EC_P384
- ALGORITHM_EC_P521
+ - ALGORITHM_MLKEM_768
+ - ALGORITHM_MLKEM_1024
+ - ALGORITHM_XWING
description: Supported key algorithms.
policy.KasPublicKeyAlgEnum:
type: string
@@ -545,6 +548,9 @@ components:
- KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP256R1
- KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP384R1
- KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP521R1
+ - KAS_PUBLIC_KEY_ALG_ENUM_MLKEM_768
+ - KAS_PUBLIC_KEY_ALG_ENUM_MLKEM_1024
+ - KAS_PUBLIC_KEY_ALG_ENUM_XWING
policy.KeyMode:
type: string
title: KeyMode
@@ -1147,7 +1153,7 @@ components:
Required The algorithm to be used for the key
The key_algorithm must be one of the defined values.:
```
- this in [1, 2, 3, 4, 5]
+ this in [1, 2, 3, 4, 5, 20, 21]
```
$ref: '#/components/schemas/policy.Algorithm'
@@ -1932,7 +1938,7 @@ components:
Required
The key_algorithm must be one of the defined values.:
```
- this in [1, 2, 3, 4, 5]
+ this in [1, 2, 3, 4, 5, 20, 21]
```
$ref: '#/components/schemas/policy.Algorithm'
diff --git a/docs/openapi/policy/namespaces/namespaces.openapi.yaml b/docs/openapi/policy/namespaces/namespaces.openapi.yaml
index 4a5b7e35cb..7db6260890 100644
--- a/docs/openapi/policy/namespaces/namespaces.openapi.yaml
+++ b/docs/openapi/policy/namespaces/namespaces.openapi.yaml
@@ -353,6 +353,9 @@ components:
- ALGORITHM_EC_P256
- ALGORITHM_EC_P384
- ALGORITHM_EC_P521
+ - ALGORITHM_MLKEM_768
+ - ALGORITHM_MLKEM_1024
+ - ALGORITHM_XWING
description: Supported key algorithms.
policy.KasPublicKeyAlgEnum:
type: string
@@ -364,6 +367,9 @@ components:
- KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP256R1
- KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP384R1
- KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP521R1
+ - KAS_PUBLIC_KEY_ALG_ENUM_MLKEM_768
+ - KAS_PUBLIC_KEY_ALG_ENUM_MLKEM_1024
+ - KAS_PUBLIC_KEY_ALG_ENUM_XWING
policy.SortDirection:
type: string
title: SortDirection
diff --git a/docs/openapi/policy/objects.openapi.yaml b/docs/openapi/policy/objects.openapi.yaml
index 917017b1a0..a67d2a1d8a 100644
--- a/docs/openapi/policy/objects.openapi.yaml
+++ b/docs/openapi/policy/objects.openapi.yaml
@@ -21,6 +21,9 @@ components:
- ALGORITHM_EC_P256
- ALGORITHM_EC_P384
- ALGORITHM_EC_P521
+ - ALGORITHM_MLKEM_768
+ - ALGORITHM_MLKEM_1024
+ - ALGORITHM_XWING
description: Supported key algorithms.
policy.AttributeRuleTypeEnum:
type: string
@@ -47,6 +50,9 @@ components:
- KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP256R1
- KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP384R1
- KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP521R1
+ - KAS_PUBLIC_KEY_ALG_ENUM_MLKEM_768
+ - KAS_PUBLIC_KEY_ALG_ENUM_MLKEM_1024
+ - KAS_PUBLIC_KEY_ALG_ENUM_XWING
policy.KeyMode:
type: string
title: KeyMode
diff --git a/docs/openapi/policy/obligations/obligations.openapi.yaml b/docs/openapi/policy/obligations/obligations.openapi.yaml
index dbe62f43ca..7cfbbf3e72 100644
--- a/docs/openapi/policy/obligations/obligations.openapi.yaml
+++ b/docs/openapi/policy/obligations/obligations.openapi.yaml
@@ -518,6 +518,9 @@ components:
- ALGORITHM_EC_P256
- ALGORITHM_EC_P384
- ALGORITHM_EC_P521
+ - ALGORITHM_MLKEM_768
+ - ALGORITHM_MLKEM_1024
+ - ALGORITHM_XWING
description: Supported key algorithms.
policy.AttributeRuleTypeEnum:
type: string
@@ -544,6 +547,9 @@ components:
- KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP256R1
- KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP384R1
- KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP521R1
+ - KAS_PUBLIC_KEY_ALG_ENUM_MLKEM_768
+ - KAS_PUBLIC_KEY_ALG_ENUM_MLKEM_1024
+ - KAS_PUBLIC_KEY_ALG_ENUM_XWING
policy.SourceType:
type: string
title: SourceType
diff --git a/docs/openapi/policy/registeredresources/registered_resources.openapi.yaml b/docs/openapi/policy/registeredresources/registered_resources.openapi.yaml
index 97b2d07814..d30a4cdac1 100644
--- a/docs/openapi/policy/registeredresources/registered_resources.openapi.yaml
+++ b/docs/openapi/policy/registeredresources/registered_resources.openapi.yaml
@@ -413,6 +413,9 @@ components:
- ALGORITHM_EC_P256
- ALGORITHM_EC_P384
- ALGORITHM_EC_P521
+ - ALGORITHM_MLKEM_768
+ - ALGORITHM_MLKEM_1024
+ - ALGORITHM_XWING
description: Supported key algorithms.
policy.AttributeRuleTypeEnum:
type: string
@@ -439,6 +442,9 @@ components:
- KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP256R1
- KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP384R1
- KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP521R1
+ - KAS_PUBLIC_KEY_ALG_ENUM_MLKEM_768
+ - KAS_PUBLIC_KEY_ALG_ENUM_MLKEM_1024
+ - KAS_PUBLIC_KEY_ALG_ENUM_XWING
policy.SourceType:
type: string
title: SourceType
diff --git a/docs/openapi/policy/resourcemapping/resource_mapping.openapi.yaml b/docs/openapi/policy/resourcemapping/resource_mapping.openapi.yaml
index c768b805c0..b1c0cf254e 100644
--- a/docs/openapi/policy/resourcemapping/resource_mapping.openapi.yaml
+++ b/docs/openapi/policy/resourcemapping/resource_mapping.openapi.yaml
@@ -413,6 +413,9 @@ components:
- ALGORITHM_EC_P256
- ALGORITHM_EC_P384
- ALGORITHM_EC_P521
+ - ALGORITHM_MLKEM_768
+ - ALGORITHM_MLKEM_1024
+ - ALGORITHM_XWING
description: Supported key algorithms.
policy.AttributeRuleTypeEnum:
type: string
@@ -439,6 +442,9 @@ components:
- KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP256R1
- KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP384R1
- KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP521R1
+ - KAS_PUBLIC_KEY_ALG_ENUM_MLKEM_768
+ - KAS_PUBLIC_KEY_ALG_ENUM_MLKEM_1024
+ - KAS_PUBLIC_KEY_ALG_ENUM_XWING
policy.SourceType:
type: string
title: SourceType
diff --git a/docs/openapi/policy/subjectmapping/subject_mapping.openapi.yaml b/docs/openapi/policy/subjectmapping/subject_mapping.openapi.yaml
index ce818161fb..2350ded2e0 100644
--- a/docs/openapi/policy/subjectmapping/subject_mapping.openapi.yaml
+++ b/docs/openapi/policy/subjectmapping/subject_mapping.openapi.yaml
@@ -449,6 +449,9 @@ components:
- ALGORITHM_EC_P256
- ALGORITHM_EC_P384
- ALGORITHM_EC_P521
+ - ALGORITHM_MLKEM_768
+ - ALGORITHM_MLKEM_1024
+ - ALGORITHM_XWING
description: Supported key algorithms.
policy.AttributeRuleTypeEnum:
type: string
@@ -475,6 +478,9 @@ components:
- KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP256R1
- KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP384R1
- KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP521R1
+ - KAS_PUBLIC_KEY_ALG_ENUM_MLKEM_768
+ - KAS_PUBLIC_KEY_ALG_ENUM_MLKEM_1024
+ - KAS_PUBLIC_KEY_ALG_ENUM_XWING
policy.SortDirection:
type: string
title: SortDirection
diff --git a/docs/openapi/policy/unsafe/unsafe.openapi.yaml b/docs/openapi/policy/unsafe/unsafe.openapi.yaml
index f52e95b427..be8ff0592c 100644
--- a/docs/openapi/policy/unsafe/unsafe.openapi.yaml
+++ b/docs/openapi/policy/unsafe/unsafe.openapi.yaml
@@ -387,6 +387,9 @@ components:
- ALGORITHM_EC_P256
- ALGORITHM_EC_P384
- ALGORITHM_EC_P521
+ - ALGORITHM_MLKEM_768
+ - ALGORITHM_MLKEM_1024
+ - ALGORITHM_XWING
description: Supported key algorithms.
policy.AttributeRuleTypeEnum:
type: string
@@ -413,6 +416,9 @@ components:
- KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP256R1
- KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP384R1
- KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP521R1
+ - KAS_PUBLIC_KEY_ALG_ENUM_MLKEM_768
+ - KAS_PUBLIC_KEY_ALG_ENUM_MLKEM_1024
+ - KAS_PUBLIC_KEY_ALG_ENUM_XWING
policy.KeyMode:
type: string
title: KeyMode
diff --git a/lib/ocrypto/asym_decryption.go b/lib/ocrypto/asym_decryption.go
index 426f859723..d98f55ccd8 100644
--- a/lib/ocrypto/asym_decryption.go
+++ b/lib/ocrypto/asym_decryption.go
@@ -7,6 +7,7 @@ import (
"crypto/ecdh"
"crypto/ecdsa"
"crypto/elliptic"
+ "crypto/mlkem"
"crypto/rsa"
"crypto/sha256"
"crypto/x509"
@@ -26,6 +27,21 @@ type AsymDecryption struct {
type PrivateKeyDecryptor interface {
// Decrypt decrypts ciphertext with private key.
Decrypt(data []byte) ([]byte, error)
+
+ // DecryptWithEphemeralKey decrypts ciphertext using additional sender material.
+ DecryptWithEphemeralKey(data, ephemeral []byte) ([]byte, error)
+}
+
+type MLKEMDecryptor768 struct {
+ decap *mlkem.DecapsulationKey768
+}
+
+type MLKEMDecryptor1024 struct {
+ decap *mlkem.DecapsulationKey1024
+}
+
+type XWingDecryptor struct {
+ seed [xwingSeedSize]byte
}
// FromPrivatePEM creates and returns a new AsymDecryption.
@@ -44,6 +60,25 @@ func FromPrivatePEMWithSalt(privateKeyInPem string, salt, info []byte) (PrivateK
return AsymDecryption{}, errors.New("failed to parse PEM formatted private key")
}
+ // Try X-Wing PKCS#8 (standard "PRIVATE KEY" PEM with id-XWing OID)
+ if block.Type == "PRIVATE KEY" {
+ if seed, err := parseXWingPrivateKeyFromDER(block.Bytes); err == nil {
+ return &XWingDecryptor{seed: seed}, nil
+ }
+ }
+
+ if block.Type == "MLKEM DECAPSULATION KEY" {
+ decap768, err := mlkem.NewDecapsulationKey768(block.Bytes)
+ if err == nil {
+ return &MLKEMDecryptor768{decap: decap768}, nil
+ }
+ decap1024, err1024 := mlkem.NewDecapsulationKey1024(block.Bytes)
+ if err1024 != nil {
+ return nil, fmt.Errorf("mlkem.NewDecapsulationKey1024 failed after mlkem.NewDecapsulationKey768 failed: %w / %w", err, err1024)
+ }
+ return &MLKEMDecryptor1024{decap: decap1024}, nil
+ }
+
priv, err := x509.ParsePKCS8PrivateKey(block.Bytes)
switch {
case err == nil:
@@ -109,6 +144,13 @@ func (asymDecryption AsymDecryption) Decrypt(data []byte) ([]byte, error) {
return bytes, nil
}
+func (asymDecryption AsymDecryption) DecryptWithEphemeralKey(data, ephemeral []byte) ([]byte, error) {
+ if len(ephemeral) > 0 {
+ return nil, errors.New("ephemeral key is not supported for RSA decryption")
+ }
+ return asymDecryption.Decrypt(data)
+}
+
type ECDecryptor struct {
sk *ecdh.PrivateKey
salt []byte
@@ -196,6 +238,88 @@ func (e ECDecryptor) DecryptWithEphemeralKey(data, ephemeral []byte) ([]byte, er
return plaintext, nil
}
+func (d MLKEMDecryptor768) Decrypt(_ []byte) ([]byte, error) {
+ return nil, errors.New("ciphertext encapsulation is required for ML-KEM decryption")
+}
+
+func (d MLKEMDecryptor1024) Decrypt(_ []byte) ([]byte, error) {
+ return nil, errors.New("ciphertext encapsulation is required for ML-KEM decryption")
+}
+
+func (d MLKEMDecryptor768) DecryptWithEphemeralKey(data, ephemeral []byte) ([]byte, error) {
+ if d.decap == nil {
+ return nil, errors.New("mlkem decapsulation key is nil")
+ }
+ if len(ephemeral) == 0 {
+ return nil, errors.New("ciphertext encapsulation is required for ML-KEM decryption")
+ }
+
+ sharedSecret, err := d.decap.Decapsulate(ephemeral)
+ if err != nil {
+ return nil, fmt.Errorf("mlkem.Decapsulate failed: %w", err)
+ }
+
+ block, err := aes.NewCipher(sharedSecret)
+ if err != nil {
+ return nil, fmt.Errorf("aes.NewCipher failure: %w", err)
+ }
+
+ gcm, err := cipher.NewGCM(block)
+ if err != nil {
+ return nil, fmt.Errorf("cipher.NewGCM failure: %w", err)
+ }
+
+ nonceSize := gcm.NonceSize()
+ if len(data) < nonceSize {
+ return nil, errors.New("ciphertext too short")
+ }
+
+ nonce, ciphertext := data[:nonceSize], data[nonceSize:]
+ plaintext, err := gcm.Open(nil, nonce, ciphertext, nil)
+ if err != nil {
+ return nil, fmt.Errorf("gcm.Open failure: %w", err)
+ }
+
+ return plaintext, nil
+}
+
+func (d MLKEMDecryptor1024) DecryptWithEphemeralKey(data, ephemeral []byte) ([]byte, error) {
+ if d.decap == nil {
+ return nil, errors.New("mlkem decapsulation key is nil")
+ }
+ if len(ephemeral) == 0 {
+ return nil, errors.New("ciphertext encapsulation is required for ML-KEM decryption")
+ }
+
+ sharedSecret, err := d.decap.Decapsulate(ephemeral)
+ if err != nil {
+ return nil, fmt.Errorf("mlkem.Decapsulate failed: %w", err)
+ }
+
+ block, err := aes.NewCipher(sharedSecret)
+ if err != nil {
+ return nil, fmt.Errorf("aes.NewCipher failure: %w", err)
+ }
+
+ gcm, err := cipher.NewGCM(block)
+ if err != nil {
+ return nil, fmt.Errorf("cipher.NewGCM failure: %w", err)
+ }
+
+ nonceSize := gcm.NonceSize()
+ if len(data) < nonceSize {
+ return nil, errors.New("ciphertext too short")
+ }
+
+ nonce, ciphertext := data[:nonceSize], data[nonceSize:]
+ plaintext, err := gcm.Open(nil, nonce, ciphertext, nil)
+ if err != nil {
+ return nil, fmt.Errorf("gcm.Open failure: %w", err)
+ }
+
+ return plaintext, nil
+}
+
func convCurve(c ecdh.Curve) elliptic.Curve {
switch c {
case ecdh.P256():
@@ -208,3 +332,47 @@ func convCurve(c ecdh.Curve) elliptic.Curve {
return nil
}
}
+
+// --- XWingDecryptor ---
+
+func (d XWingDecryptor) Decrypt(_ []byte) ([]byte, error) {
+ return nil, errors.New("X-Wing requires ephemeral ciphertext for decryption")
+}
+
+func (d XWingDecryptor) DecryptWithEphemeralKey(data, ephemeral []byte) ([]byte, error) {
+ // Parse ASN.1-wrapped ciphertext
+ ct, err := parseXWingCiphertext(ephemeral)
+ if err != nil {
+ return nil, fmt.Errorf("xwing: failed to parse ciphertext: %w", err)
+ }
+
+ // Perform X-Wing decapsulation
+ sharedSecret, err := xwingDecapsulate(ct, d.seed)
+ if err != nil {
+ return nil, fmt.Errorf("xwing: decapsulation failed: %w", err)
+ }
+
+ // Decrypt AES-GCM wrapped data
+ block, err := aes.NewCipher(sharedSecret[:])
+ if err != nil {
+ return nil, fmt.Errorf("aes.NewCipher failure: %w", err)
+ }
+
+ gcm, err := cipher.NewGCM(block)
+ if err != nil {
+ return nil, fmt.Errorf("cipher.NewGCM failure: %w", err)
+ }
+
+ nonceSize := gcm.NonceSize()
+ if len(data) < nonceSize {
+ return nil, errors.New("ciphertext too short")
+ }
+
+ nonce, ciphertext := data[:nonceSize], data[nonceSize:]
+ plaintext, err := gcm.Open(nil, nonce, ciphertext, nil)
+ if err != nil {
+ return nil, fmt.Errorf("gcm.Open failure: %w", err)
+ }
+
+ return plaintext, nil
+}
diff --git a/lib/ocrypto/asym_encryption.go b/lib/ocrypto/asym_encryption.go
index c44aa64cce..bfba478cbb 100644
--- a/lib/ocrypto/asym_encryption.go
+++ b/lib/ocrypto/asym_encryption.go
@@ -5,6 +5,7 @@ import (
"crypto/cipher"
"crypto/ecdh"
"crypto/ecdsa"
+ "crypto/mlkem"
"crypto/rand"
"crypto/rsa"
"crypto/sha1" //nolint:gosec // used for padding which is safe
@@ -23,8 +24,10 @@ import (
type SchemeType string
const (
- RSA SchemeType = "wrapped"
- EC SchemeType = "ec-wrapped"
+ RSA SchemeType = "wrapped"
+ EC SchemeType = "ec-wrapped"
+ MLKEM SchemeType = "mlkem-wrapped"
+ Hybrid SchemeType = "hybrid"
)
type PublicKeyEncryptor interface {
@@ -59,6 +62,24 @@ type ECEncryptor struct {
info []byte
}
+type MLKEMEncryptor768 struct {
+ pub *mlkem.EncapsulationKey768
+ cipherText []byte
+ sharedSecret []byte
+}
+
+type MLKEMEncryptor1024 struct {
+ pub *mlkem.EncapsulationKey1024
+ cipherText []byte
+ sharedSecret []byte
+}
+
+type XWingEncryptor struct {
+ pk []byte // 1216-byte X-Wing encapsulation key
+ cipherText []byte // 1120-byte X-Wing ciphertext (ct_M || ct_X)
+ sharedSecret []byte // 32-byte combined shared secret
+}
+
func FromPublicPEM(publicKeyInPem string) (PublicKeyEncryptor, error) {
// TK Move salt and info out of library, into API option functions
digest := sha256.New()
@@ -85,6 +106,12 @@ func FromPublicPEMWithSalt(publicKeyInPem string, salt, info []byte) (PublicKeyE
return newECIES(e, salt, info)
case *ecdh.PublicKey:
return newECIES(pub, salt, info)
+ case *mlkem.EncapsulationKey768:
+ return newMLKEM768(pub), nil
+ case *mlkem.EncapsulationKey1024:
+ return newMLKEM1024(pub), nil
+ case xwingPublicKey:
+ return newXWingEncryptor([]byte(pub))
default:
break
}
@@ -97,6 +124,16 @@ func newECIES(pub *ecdh.PublicKey, salt, info []byte) (ECEncryptor, error) {
return ECEncryptor{pub, ek, salt, info}, err
}
+func newMLKEM768(pub *mlkem.EncapsulationKey768) *MLKEMEncryptor768 {
+ sharedSecret, cipherText := pub.Encapsulate()
+ return &MLKEMEncryptor768{pub: pub, cipherText: cipherText, sharedSecret: sharedSecret}
+}
+
+func newMLKEM1024(pub *mlkem.EncapsulationKey1024) *MLKEMEncryptor1024 {
+ sharedSecret, cipherText := pub.Encapsulate()
+ return &MLKEMEncryptor1024{pub: pub, cipherText: cipherText, sharedSecret: sharedSecret}
+}
+
// NewAsymEncryption creates and returns a new AsymEncryption.
//
// Deprecated: Use FromPublicPEM instead.
@@ -116,6 +153,10 @@ func NewAsymEncryption(publicKeyInPem string) (AsymEncryption, error) {
return AsymEncryption{}, fmt.Errorf("unsupported public key type: %T", pub)
}
+// xwingPublicKey is a wrapper type for the raw 1216-byte X-Wing public key
+// used for type-switching in FromPublicPEMWithSalt.
+type xwingPublicKey []byte
+
func getPublicPart(publicKeyInPem string) (any, error) {
block, _ := pem.Decode([]byte(publicKeyInPem))
if block == nil {
@@ -123,14 +164,31 @@ func getPublicPart(publicKeyInPem string) (any, error) {
}
var pub any
- if strings.Contains(publicKeyInPem, "BEGIN CERTIFICATE") {
+ switch {
+ case strings.Contains(publicKeyInPem, "BEGIN CERTIFICATE"):
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
return nil, fmt.Errorf("x509.ParseCertificate failed: %w", err)
}
pub = cert.PublicKey
- } else {
+ case block.Type == "MLKEM ENCAPSULATOR":
+ encap768, err := mlkem.NewEncapsulationKey768(block.Bytes)
+ if err == nil {
+ pub = encap768
+ break
+ }
+ encap1024, err1024 := mlkem.NewEncapsulationKey1024(block.Bytes)
+ if err1024 != nil {
+ return nil, fmt.Errorf("mlkem.NewEncapsulationKey1024 failed after mlkem.NewEncapsulationKey768 failed: %w / %w", err, err1024)
+ }
+ pub = encap1024
+ default:
+ // Try X-Wing SubjectPublicKeyInfo first (has id-XWing OID)
+ if pk, err := parseXWingPublicKeyFromDER(block.Bytes); err == nil {
+ pub = xwingPublicKey(pk)
+ break
+ }
var err error
pub, err = x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
@@ -160,6 +218,14 @@ func (e ECEncryptor) Type() SchemeType {
return EC
}
+func (e MLKEMEncryptor768) Type() SchemeType {
+ return MLKEM
+}
+
+func (e MLKEMEncryptor1024) Type() SchemeType {
+ return MLKEM
+}
+
func (e ECEncryptor) KeyType() KeyType {
switch e.pub.Curve() {
case ecdh.P256():
@@ -176,6 +242,14 @@ func (e ECEncryptor) KeyType() KeyType {
}
}
+func (e MLKEMEncryptor768) KeyType() KeyType {
+ return MLKEM768Key
+}
+
+func (e MLKEMEncryptor1024) KeyType() KeyType {
+ return MLKEM1024Key
+}
+
func (e AsymEncryption) EphemeralKey() []byte {
return nil
}
@@ -188,6 +262,14 @@ func (e ECEncryptor) EphemeralKey() []byte {
return publicKeyBytes
}
+func (e MLKEMEncryptor768) EphemeralKey() []byte {
+ return e.cipherText
+}
+
+func (e MLKEMEncryptor1024) EphemeralKey() []byte {
+ return e.cipherText
+}
+
func (e AsymEncryption) Metadata() (map[string]string, error) {
return make(map[string]string), nil
}
@@ -198,6 +280,18 @@ func (e ECEncryptor) Metadata() (map[string]string, error) {
return m, nil
}
+func (e MLKEMEncryptor768) Metadata() (map[string]string, error) {
+ m := make(map[string]string)
+ m["encapsulatedKey"] = string(e.EphemeralKey())
+ return m, nil
+}
+
+func (e MLKEMEncryptor1024) Metadata() (map[string]string, error) {
+ m := make(map[string]string)
+ m["encapsulatedKey"] = string(e.EphemeralKey())
+ return m, nil
+}
+
func (e AsymEncryption) Encrypt(data []byte) ([]byte, error) {
if e.PublicKey == nil {
return nil, errors.New("failed to encrypt, public key is empty")
@@ -269,7 +363,125 @@ func (e ECEncryptor) Encrypt(data []byte) ([]byte, error) {
return ciphertext, nil
}
+func (e MLKEMEncryptor768) Encrypt(data []byte) ([]byte, error) {
+ block, err := aes.NewCipher(e.sharedSecret)
+ if err != nil {
+ return nil, fmt.Errorf("aes.NewCipher failed: %w", err)
+ }
+
+ gcm, err := cipher.NewGCM(block)
+ if err != nil {
+ return nil, fmt.Errorf("cipher.NewGCM failed: %w", err)
+ }
+
+ nonce := make([]byte, gcm.NonceSize())
+ if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
+ return nil, fmt.Errorf("nonce generation failed: %w", err)
+ }
+
+ return gcm.Seal(nonce, nonce, data, nil), nil
+}
+
+func (e MLKEMEncryptor1024) Encrypt(data []byte) ([]byte, error) {
+ block, err := aes.NewCipher(e.sharedSecret)
+ if err != nil {
+ return nil, fmt.Errorf("aes.NewCipher failed: %w", err)
+ }
+
+ gcm, err := cipher.NewGCM(block)
+ if err != nil {
+ return nil, fmt.Errorf("cipher.NewGCM failed: %w", err)
+ }
+
+ nonce := make([]byte, gcm.NonceSize())
+ if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
+ return nil, fmt.Errorf("nonce generation failed: %w", err)
+ }
+
+ return gcm.Seal(nonce, nonce, data, nil), nil
+}
+
// PublicKeyInPemFormat Returns public key in pem format.
func (e ECEncryptor) PublicKeyInPemFormat() (string, error) {
return publicKeyInPemFormat(e.ek.Public())
}
+
+func (e MLKEMEncryptor768) PublicKeyInPemFormat() (string, error) {
+ return string(pem.EncodeToMemory(&pem.Block{
+ Type: "MLKEM ENCAPSULATOR",
+ Bytes: e.pub.Bytes(),
+ })), nil
+}
+
+func (e MLKEMEncryptor1024) PublicKeyInPemFormat() (string, error) {
+ return string(pem.EncodeToMemory(&pem.Block{
+ Type: "MLKEM ENCAPSULATOR",
+ Bytes: e.pub.Bytes(),
+ })), nil
+}
+
+// --- XWingEncryptor ---
+
+func newXWingEncryptor(pk []byte) (*XWingEncryptor, error) {
+ ss, ct, err := xwingEncapsulate(pk)
+ if err != nil {
+ return nil, err
+ }
+ return &XWingEncryptor{
+ pk: pk,
+ cipherText: ct[:],
+ sharedSecret: ss[:],
+ }, nil
+}
+
+func (e XWingEncryptor) Type() SchemeType {
+ return Hybrid
+}
+
+func (e XWingEncryptor) KeyType() KeyType {
+ return HybridXWing
+}
+
+func (e XWingEncryptor) EphemeralKey() []byte {
+ ct, err := marshalXWingCiphertext(e.cipherText)
+ if err != nil {
+ return nil
+ }
+ return ct
+}
+
+func (e XWingEncryptor) Metadata() (map[string]string, error) {
+ m := make(map[string]string)
+ m["encapsulatedKey"] = string(e.EphemeralKey())
+ return m, nil
+}
+
+func (e XWingEncryptor) Encrypt(data []byte) ([]byte, error) {
+ block, err := aes.NewCipher(e.sharedSecret)
+ if err != nil {
+ return nil, fmt.Errorf("aes.NewCipher failed: %w", err)
+ }
+
+ gcm, err := cipher.NewGCM(block)
+ if err != nil {
+ return nil, fmt.Errorf("cipher.NewGCM failed: %w", err)
+ }
+
+ nonce := make([]byte, gcm.NonceSize())
+ if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
+ return nil, fmt.Errorf("nonce generation failed: %w", err)
+ }
+
+ return gcm.Seal(nonce, nonce, data, nil), nil
+}
+
+func (e XWingEncryptor) PublicKeyInPemFormat() (string, error) {
+ der, err := marshalXWingPublicKey(e.pk)
+ if err != nil {
+ return "", err
+ }
+ return string(pem.EncodeToMemory(&pem.Block{
+ Type: "PUBLIC KEY",
+ Bytes: der,
+ })), nil
+}
diff --git a/lib/ocrypto/ec_key_pair.go b/lib/ocrypto/ec_key_pair.go
index f9a9554d4f..843236b36b 100644
--- a/lib/ocrypto/ec_key_pair.go
+++ b/lib/ocrypto/ec_key_pair.go
@@ -4,6 +4,7 @@ import (
"crypto/ecdh"
"crypto/ecdsa"
"crypto/elliptic"
+ "crypto/mlkem"
"crypto/rand"
"crypto/sha256"
"crypto/x509"
@@ -22,11 +23,14 @@ type ECCMode uint8
type KeyType string
const (
- RSA2048Key KeyType = "rsa:2048"
- RSA4096Key KeyType = "rsa:4096"
- EC256Key KeyType = "ec:secp256r1"
- EC384Key KeyType = "ec:secp384r1"
- EC521Key KeyType = "ec:secp521r1"
+ RSA2048Key KeyType = "rsa:2048"
+ RSA4096Key KeyType = "rsa:4096"
+ EC256Key KeyType = "ec:secp256r1"
+ EC384Key KeyType = "ec:secp384r1"
+ EC521Key KeyType = "ec:secp521r1"
+ MLKEM768Key KeyType = "mlkem:768"
+ MLKEM1024Key KeyType = "mlkem:1024"
+ HybridXWing KeyType = "hpqt:xwing"
)
const (
@@ -64,6 +68,12 @@ func NewKeyPair(kt KeyType) (KeyPair, error) {
return nil, err
}
return NewECKeyPair(mode)
+ case MLKEM768Key:
+ return NewMLKEMKeyPair()
+ case MLKEM1024Key:
+ return NewMLKEM1024KeyPair()
+ case HybridXWing:
+ return NewXWingKeyPair()
default:
return nil, fmt.Errorf("unsupported key type: %v", kt)
}
@@ -73,6 +83,14 @@ type ECKeyPair struct {
PrivateKey *ecdsa.PrivateKey
}
+type MLKEMKeyPair struct {
+ PrivateKey *mlkem.DecapsulationKey768
+}
+
+type MLKEM1024KeyPair struct {
+ PrivateKey *mlkem.DecapsulationKey1024
+}
+
func IsECKeyType(kt KeyType) bool {
switch kt { //nolint:exhaustive // only handle ec types
case EC256Key, EC384Key, EC521Key:
@@ -184,6 +202,24 @@ func NewECKeyPair(mode ECCMode) (ECKeyPair, error) {
return ecKeyPair, nil
}
+func NewMLKEMKeyPair() (MLKEMKeyPair, error) {
+ privateKey, err := mlkem.GenerateKey768()
+ if err != nil {
+ return MLKEMKeyPair{}, fmt.Errorf("mlkem.GenerateKey768 failed: %w", err)
+ }
+
+ return MLKEMKeyPair{PrivateKey: privateKey}, nil
+}
+
+func NewMLKEM1024KeyPair() (MLKEM1024KeyPair, error) {
+ privateKey, err := mlkem.GenerateKey1024()
+ if err != nil {
+ return MLKEM1024KeyPair{}, fmt.Errorf("mlkem.GenerateKey1024 failed: %w", err)
+ }
+
+ return MLKEM1024KeyPair{PrivateKey: privateKey}, nil
+}
+
// PrivateKeyInPemFormat Returns private key in pem format.
func (keyPair ECKeyPair) PrivateKeyInPemFormat() (string, error) {
if keyPair.PrivateKey == nil {
@@ -224,6 +260,62 @@ func (keyPair ECKeyPair) PublicKeyInPemFormat() (string, error) {
return string(publicKeyPem), nil
}
+func (keyPair MLKEMKeyPair) PrivateKeyInPemFormat() (string, error) {
+ if keyPair.PrivateKey == nil {
+ return "", errors.New("failed to generate PEM formatted private key")
+ }
+
+ privateKeyPEM := pem.EncodeToMemory(
+ &pem.Block{
+ Type: "MLKEM DECAPSULATION KEY",
+ Bytes: keyPair.PrivateKey.Bytes(),
+ },
+ )
+ return string(privateKeyPEM), nil
+}
+
+func (keyPair MLKEMKeyPair) PublicKeyInPemFormat() (string, error) {
+ if keyPair.PrivateKey == nil {
+ return "", errors.New("failed to generate PEM formatted public key")
+ }
+
+ publicKeyPEM := pem.EncodeToMemory(
+ &pem.Block{
+ Type: "MLKEM ENCAPSULATOR",
+ Bytes: keyPair.PrivateKey.EncapsulationKey().Bytes(),
+ },
+ )
+ return string(publicKeyPEM), nil
+}
+
+func (keyPair MLKEM1024KeyPair) PrivateKeyInPemFormat() (string, error) {
+ if keyPair.PrivateKey == nil {
+ return "", errors.New("failed to generate PEM formatted private key")
+ }
+
+ privateKeyPEM := pem.EncodeToMemory(
+ &pem.Block{
+ Type: "MLKEM DECAPSULATION KEY",
+ Bytes: keyPair.PrivateKey.Bytes(),
+ },
+ )
+ return string(privateKeyPEM), nil
+}
+
+func (keyPair MLKEM1024KeyPair) PublicKeyInPemFormat() (string, error) {
+ if keyPair.PrivateKey == nil {
+ return "", errors.New("failed to generate PEM formatted public key")
+ }
+
+ publicKeyPEM := pem.EncodeToMemory(
+ &pem.Block{
+ Type: "MLKEM ENCAPSULATOR",
+ Bytes: keyPair.PrivateKey.EncapsulationKey().Bytes(),
+ },
+ )
+ return string(publicKeyPEM), nil
+}
+
// KeySize Return the size of this ec key pair.
func (keyPair ECKeyPair) KeySize() (int, error) {
if keyPair.PrivateKey == nil {
@@ -494,3 +586,11 @@ func GetECKeySize(pemData []byte) (int, error) {
func (keyPair ECKeyPair) GetKeyType() KeyType {
return EC256Key
}
+
+func (keyPair MLKEMKeyPair) GetKeyType() KeyType {
+ return MLKEM768Key
+}
+
+func (keyPair MLKEM1024KeyPair) GetKeyType() KeyType {
+ return MLKEM1024Key
+}
diff --git a/lib/ocrypto/xwing.go b/lib/ocrypto/xwing.go
new file mode 100644
index 0000000000..78de9e682c
--- /dev/null
+++ b/lib/ocrypto/xwing.go
@@ -0,0 +1,329 @@
+package ocrypto
+
+import (
+ "crypto/ecdh"
+ "crypto/mlkem"
+ "crypto/rand"
+ "crypto/sha3"
+ "encoding/asn1"
+ "encoding/pem"
+ "errors"
+ "fmt"
+)
+
+// X-Wing OID: 1.3.6.1.4.1.62253.25722
+// Per draft-connolly-cfrg-xwing-kem-10
+var oidXWing = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 62253, 25722}
+
+// xwingLabel is the 6-byte ASCII label used in the X-Wing combiner.
+// "\./"+"/^\" = 0x5c2e2f2f5e5c
+var xwingLabel = []byte{0x5c, 0x2e, 0x2f, 0x2f, 0x5e, 0x5c}
+
+const (
+ xwingSeedSize = 32
+ xwingExpandedSize = 96
+ xwingPublicKeySize = 1216 // 1184 (ML-KEM-768 encap key) + 32 (X25519 pub)
+ xwingCiphertextSize = 1120 // 1088 (ML-KEM-768 ct) + 32 (X25519 ct)
+ xwingSharedKeySize = 32
+ mlkem768EncapSize = 1184
+ mlkem768CTSize = 1088
+ x25519KeySize = 32
+)
+
+// XWingKeyPair holds the 32-byte seed that is the X-Wing decapsulation key.
+type XWingKeyPair struct {
+ seed [xwingSeedSize]byte
+}
+
+// NewXWingKeyPair generates a new X-Wing key pair from a random seed.
+func NewXWingKeyPair() (XWingKeyPair, error) {
+ var seed [xwingSeedSize]byte
+ if _, err := rand.Read(seed[:]); err != nil {
+ return XWingKeyPair{}, fmt.Errorf("xwing: failed to generate random seed: %w", err)
+ }
+ return XWingKeyPair{seed: seed}, nil
+}
+
+// expandDecapsulationKey derives the component keys from the 32-byte seed.
+// Returns (mlkemDecapKey, x25519PrivateKey, mlkemEncapKey, x25519PublicKey).
+func expandDecapsulationKey(seed [xwingSeedSize]byte) (*mlkem.DecapsulationKey768, *ecdh.PrivateKey, []byte, []byte, error) {
+ // SHAKE256(seed, 96*8) → 96 bytes
+ expanded := sha3.SumSHAKE256(seed[:], xwingExpandedSize)
+
+ // d = expanded[0:32], z = expanded[32:64] → ML-KEM-768 seed
+ mlkemSeed := expanded[0:64] // d || z
+ skM, err := mlkem.NewDecapsulationKey768(mlkemSeed)
+ if err != nil {
+ return nil, nil, nil, nil, fmt.Errorf("xwing: mlkem.NewDecapsulationKey768 failed: %w", err)
+ }
+ pkM := skM.EncapsulationKey().Bytes()
+
+ // sk_X = expanded[64:96]
+ skX, err := ecdh.X25519().NewPrivateKey(expanded[64:96])
+ if err != nil {
+ return nil, nil, nil, nil, fmt.Errorf("xwing: X25519 NewPrivateKey failed: %w", err)
+ }
+ pkX := skX.PublicKey().Bytes()
+
+ return skM, skX, pkM, pkX, nil
+}
+
+// xwingCombiner computes SHA3-256(ss_M || ss_X || ct_X || pk_X || XWingLabel).
+func xwingCombiner(ssM, ssX, ctX, pkX []byte) [xwingSharedKeySize]byte {
+ var combined []byte
+ combined = append(combined, ssM...)
+ combined = append(combined, ssX...)
+ combined = append(combined, ctX...)
+ combined = append(combined, pkX...)
+ combined = append(combined, xwingLabel...)
+ return sha3.Sum256(combined)
+}
+
+// xwingEncapsulate performs X-Wing encapsulation against a 1216-byte public key.
+// Returns the 32-byte shared secret and 1120-byte ciphertext.
+func xwingEncapsulate(pk []byte) ([xwingSharedKeySize]byte, [xwingCiphertextSize]byte, error) {
+ var ss [xwingSharedKeySize]byte
+ var ct [xwingCiphertextSize]byte
+
+ if len(pk) != xwingPublicKeySize {
+ return ss, ct, fmt.Errorf("xwing: invalid public key size %d, expected %d", len(pk), xwingPublicKeySize)
+ }
+
+ pkM := pk[:mlkem768EncapSize]
+ pkX := pk[mlkem768EncapSize:]
+
+ // ML-KEM-768 encapsulation
+ encapKey, err := mlkem.NewEncapsulationKey768(pkM)
+ if err != nil {
+ return ss, ct, fmt.Errorf("xwing: mlkem encapsulation key parse failed: %w", err)
+ }
+ ssM, ctM := encapKey.Encapsulate()
+
+ // X25519 ephemeral key exchange
+ ekX, err := ecdh.X25519().GenerateKey(rand.Reader)
+ if err != nil {
+ return ss, ct, fmt.Errorf("xwing: X25519 GenerateKey failed: %w", err)
+ }
+ ctX := ekX.PublicKey().Bytes()
+
+ pkXKey, err := ecdh.X25519().NewPublicKey(pkX)
+ if err != nil {
+ return ss, ct, fmt.Errorf("xwing: X25519 NewPublicKey failed: %w", err)
+ }
+ ssX, err := ekX.ECDH(pkXKey)
+ if err != nil {
+ return ss, ct, fmt.Errorf("xwing: X25519 ECDH failed: %w", err)
+ }
+
+ // Combiner
+ ss = xwingCombiner(ssM, ssX, ctX, pkX)
+
+ // Ciphertext = ct_M || ct_X
+ copy(ct[:mlkem768CTSize], ctM)
+ copy(ct[mlkem768CTSize:], ctX)
+
+ return ss, ct, nil
+}
+
+// xwingDecapsulate performs X-Wing decapsulation using the 32-byte seed.
+func xwingDecapsulate(ct []byte, seed [xwingSeedSize]byte) ([xwingSharedKeySize]byte, error) {
+ var ss [xwingSharedKeySize]byte
+
+ if len(ct) != xwingCiphertextSize {
+ return ss, fmt.Errorf("xwing: invalid ciphertext size %d, expected %d", len(ct), xwingCiphertextSize)
+ }
+
+ skM, skX, _, pkX, err := expandDecapsulationKey(seed)
+ if err != nil {
+ return ss, err
+ }
+
+ ctM := ct[:mlkem768CTSize]
+ ctX := ct[mlkem768CTSize:]
+
+ // ML-KEM-768 decapsulation
+ ssM, err := skM.Decapsulate(ctM)
+ if err != nil {
+ return ss, fmt.Errorf("xwing: mlkem decapsulate failed: %w", err)
+ }
+
+ // X25519 key exchange with ephemeral ciphertext
+ ctXKey, err := ecdh.X25519().NewPublicKey(ctX)
+ if err != nil {
+ return ss, fmt.Errorf("xwing: X25519 NewPublicKey(ctX) failed: %w", err)
+ }
+ ssX, err := skX.ECDH(ctXKey)
+ if err != nil {
+ return ss, fmt.Errorf("xwing: X25519 ECDH failed: %w", err)
+ }
+
+ ss = xwingCombiner(ssM, ssX, ctX, pkX)
+ return ss, nil
+}
+
+// --- ASN.1 structures for X-Wing key and ciphertext encoding ---
+
+// pkixAlgorithmIdentifier represents an ASN.1 AlgorithmIdentifier.
+type pkixAlgorithmIdentifier struct {
+ Algorithm asn1.ObjectIdentifier
+}
+
+// subjectPublicKeyInfo represents ASN.1 SubjectPublicKeyInfo.
+type subjectPublicKeyInfo struct {
+ Algorithm pkixAlgorithmIdentifier
+ PublicKey asn1.BitString
+}
+
+// pkcs8PrivateKey represents ASN.1 OneAsymmetricKey / PKCS#8.
+type pkcs8PrivateKey struct {
+ Version int
+ Algorithm pkixAlgorithmIdentifier
+ PrivateKey []byte
+}
+
+// xwingCiphertextASN1 wraps the X-Wing ciphertext with its OID for self-description.
+type xwingCiphertextASN1 struct {
+ Algorithm asn1.ObjectIdentifier
+ Ciphertext []byte
+}
+
+// marshalXWingPublicKey encodes a 1216-byte X-Wing public key as DER SubjectPublicKeyInfo.
+func marshalXWingPublicKey(pk []byte) ([]byte, error) {
+ spki := subjectPublicKeyInfo{
+ Algorithm: pkixAlgorithmIdentifier{Algorithm: oidXWing},
+ PublicKey: asn1.BitString{Bytes: pk, BitLength: len(pk) * 8}, //nolint:mnd // bits per byte
+ }
+ return asn1.Marshal(spki)
+}
+
+// marshalXWingPrivateKey encodes a 32-byte X-Wing seed as DER PKCS#8.
+func marshalXWingPrivateKey(seed []byte) ([]byte, error) {
+ // The privateKey field is an OCTET STRING containing the seed,
+ // which itself is DER-encoded as an OCTET STRING.
+ innerOctet, err := asn1.Marshal(seed)
+ if err != nil {
+ return nil, fmt.Errorf("xwing: failed to marshal seed: %w", err)
+ }
+ pk8 := pkcs8PrivateKey{
+ Version: 0,
+ Algorithm: pkixAlgorithmIdentifier{Algorithm: oidXWing},
+ PrivateKey: innerOctet,
+ }
+ return asn1.Marshal(pk8)
+}
+
+// marshalXWingCiphertext wraps ciphertext bytes with OID for self-describing encoding.
+func marshalXWingCiphertext(ct []byte) ([]byte, error) {
+ return asn1.Marshal(xwingCiphertextASN1{
+ Algorithm: oidXWing,
+ Ciphertext: ct,
+ })
+}
+
+// parseXWingCiphertext extracts raw ciphertext from ASN.1 wrapped form.
+func parseXWingCiphertext(data []byte) ([]byte, error) {
+ var ct xwingCiphertextASN1
+ rest, err := asn1.Unmarshal(data, &ct)
+ if err != nil {
+ return nil, fmt.Errorf("xwing: failed to unmarshal ciphertext ASN.1: %w", err)
+ }
+ if len(rest) > 0 {
+ return nil, errors.New("xwing: trailing data after ciphertext ASN.1")
+ }
+ if !ct.Algorithm.Equal(oidXWing) {
+ return nil, fmt.Errorf("xwing: unexpected OID in ciphertext: %v", ct.Algorithm)
+ }
+ if len(ct.Ciphertext) != xwingCiphertextSize {
+ return nil, fmt.Errorf("xwing: invalid ciphertext size %d in ASN.1", len(ct.Ciphertext))
+ }
+ return ct.Ciphertext, nil
+}
+
+// --- KeyPair interface implementation ---
+
+func (kp XWingKeyPair) GetKeyType() KeyType {
+ return HybridXWing
+}
+
+func (kp XWingKeyPair) PublicKeyInPemFormat() (string, error) {
+ _, _, pkM, pkX, err := expandDecapsulationKey(kp.seed)
+ if err != nil {
+ return "", err
+ }
+
+ pk := make([]byte, 0, xwingPublicKeySize)
+ pk = append(pk, pkM...)
+ pk = append(pk, pkX...)
+
+ der, err := marshalXWingPublicKey(pk)
+ if err != nil {
+ return "", err
+ }
+
+ return string(pem.EncodeToMemory(&pem.Block{
+ Type: "PUBLIC KEY",
+ Bytes: der,
+ })), nil
+}
+
+func (kp XWingKeyPair) PrivateKeyInPemFormat() (string, error) {
+ der, err := marshalXWingPrivateKey(kp.seed[:])
+ if err != nil {
+ return "", err
+ }
+
+ return string(pem.EncodeToMemory(&pem.Block{
+ Type: "PRIVATE KEY",
+ Bytes: der,
+ })), nil
+}
+
+// parseXWingPublicKeyFromDER parses a DER-encoded SubjectPublicKeyInfo and returns
+// the raw 1216-byte X-Wing public key if the OID matches.
+func parseXWingPublicKeyFromDER(der []byte) ([]byte, error) {
+ var spki subjectPublicKeyInfo
+ rest, err := asn1.Unmarshal(der, &spki)
+ if err != nil {
+ return nil, err
+ }
+ if len(rest) > 0 {
+ return nil, errors.New("xwing: trailing data after SubjectPublicKeyInfo")
+ }
+ if !spki.Algorithm.Algorithm.Equal(oidXWing) {
+ return nil, fmt.Errorf("xwing: unexpected OID: %v", spki.Algorithm.Algorithm)
+ }
+ pk := spki.PublicKey.Bytes
+ if len(pk) != xwingPublicKeySize {
+ return nil, fmt.Errorf("xwing: invalid public key size %d", len(pk))
+ }
+ return pk, nil
+}
+
+// parseXWingPrivateKeyFromDER parses a DER-encoded PKCS#8 and returns
+// the 32-byte X-Wing seed if the OID matches.
+func parseXWingPrivateKeyFromDER(der []byte) ([xwingSeedSize]byte, error) {
+ var seed [xwingSeedSize]byte
+ var pk8 pkcs8PrivateKey
+ rest, err := asn1.Unmarshal(der, &pk8)
+ if err != nil {
+ return seed, fmt.Errorf("xwing: failed to unmarshal PKCS#8: %w", err)
+ }
+ if len(rest) > 0 {
+ return seed, errors.New("xwing: trailing data after PKCS#8")
+ }
+ if !pk8.Algorithm.Algorithm.Equal(oidXWing) {
+ return seed, fmt.Errorf("xwing: unexpected OID: %v", pk8.Algorithm.Algorithm)
+ }
+
+ // The privateKey is a DER-encoded OCTET STRING containing the seed.
+ var seedBytes []byte
+ _, err = asn1.Unmarshal(pk8.PrivateKey, &seedBytes)
+ if err != nil {
+ return seed, fmt.Errorf("xwing: failed to unmarshal seed from PKCS#8: %w", err)
+ }
+ if len(seedBytes) != xwingSeedSize {
+ return seed, fmt.Errorf("xwing: invalid seed size %d", len(seedBytes))
+ }
+ copy(seed[:], seedBytes)
+ return seed, nil
+}
diff --git a/lib/ocrypto/xwing_test.go b/lib/ocrypto/xwing_test.go
new file mode 100644
index 0000000000..7e05f85f7d
--- /dev/null
+++ b/lib/ocrypto/xwing_test.go
@@ -0,0 +1,387 @@
+package ocrypto
+
+import (
+ "bytes"
+ "encoding/hex"
+ "testing"
+)
+
+func TestXWingKeyPairGeneration(t *testing.T) {
+ kp, err := NewXWingKeyPair()
+ if err != nil {
+ t.Fatalf("NewXWingKeyPair failed: %v", err)
+ }
+
+ pubPEM, err := kp.PublicKeyInPemFormat()
+ if err != nil {
+ t.Fatalf("PublicKeyInPemFormat failed: %v", err)
+ }
+ if pubPEM == "" {
+ t.Fatal("empty public key PEM")
+ }
+
+ privPEM, err := kp.PrivateKeyInPemFormat()
+ if err != nil {
+ t.Fatalf("PrivateKeyInPemFormat failed: %v", err)
+ }
+ if privPEM == "" {
+ t.Fatal("empty private key PEM")
+ }
+
+ if kp.GetKeyType() != HybridXWing {
+ t.Fatalf("expected key type %s, got %s", HybridXWing, kp.GetKeyType())
+ }
+}
+
+func TestXWingKeyPairViaFactory(t *testing.T) {
+ kp, err := NewKeyPair(HybridXWing)
+ if err != nil {
+ t.Fatalf("NewKeyPair(HybridXWing) failed: %v", err)
+ }
+ if kp.GetKeyType() != HybridXWing {
+ t.Fatalf("expected key type %s, got %s", HybridXWing, kp.GetKeyType())
+ }
+}
+
+func TestXWingPEMRoundTrip(t *testing.T) {
+ kp, err := NewXWingKeyPair()
+ if err != nil {
+ t.Fatalf("NewXWingKeyPair failed: %v", err)
+ }
+
+ // Public key round-trip
+ pubPEM, err := kp.PublicKeyInPemFormat()
+ if err != nil {
+ t.Fatalf("PublicKeyInPemFormat failed: %v", err)
+ }
+
+ enc, err := FromPublicPEM(pubPEM)
+ if err != nil {
+ t.Fatalf("FromPublicPEM failed for X-Wing public key: %v", err)
+ }
+ if enc.Type() != Hybrid {
+ t.Fatalf("expected scheme type %s, got %s", Hybrid, enc.Type())
+ }
+ if enc.KeyType() != HybridXWing {
+ t.Fatalf("expected key type %s, got %s", HybridXWing, enc.KeyType())
+ }
+
+ // Private key round-trip
+ privPEM, err := kp.PrivateKeyInPemFormat()
+ if err != nil {
+ t.Fatalf("PrivateKeyInPemFormat failed: %v", err)
+ }
+
+ dec, err := FromPrivatePEM(privPEM)
+ if err != nil {
+ t.Fatalf("FromPrivatePEM failed for X-Wing private key: %v", err)
+ }
+ if _, ok := dec.(*XWingDecryptor); !ok {
+ t.Fatalf("expected XWingDecryptor, got %T", dec)
+ }
+}
+
+func TestXWingEncryptDecryptRoundTrip(t *testing.T) {
+ kp, err := NewXWingKeyPair()
+ if err != nil {
+ t.Fatalf("NewXWingKeyPair failed: %v", err)
+ }
+
+ pubPEM, err := kp.PublicKeyInPemFormat()
+ if err != nil {
+ t.Fatalf("PublicKeyInPemFormat failed: %v", err)
+ }
+
+ privPEM, err := kp.PrivateKeyInPemFormat()
+ if err != nil {
+ t.Fatalf("PrivateKeyInPemFormat failed: %v", err)
+ }
+
+ // Encrypt
+ enc, err := FromPublicPEM(pubPEM)
+ if err != nil {
+ t.Fatalf("FromPublicPEM failed: %v", err)
+ }
+
+ plaintext := []byte("hello, X-Wing hybrid KEM!")
+ ciphertext, err := enc.Encrypt(plaintext)
+ if err != nil {
+ t.Fatalf("Encrypt failed: %v", err)
+ }
+
+ ephemeralKey := enc.EphemeralKey()
+ if len(ephemeralKey) == 0 {
+ t.Fatal("EphemeralKey returned empty")
+ }
+
+ // Decrypt
+ dec, err := FromPrivatePEM(privPEM)
+ if err != nil {
+ t.Fatalf("FromPrivatePEM failed: %v", err)
+ }
+
+ recovered, err := dec.DecryptWithEphemeralKey(ciphertext, ephemeralKey)
+ if err != nil {
+ t.Fatalf("DecryptWithEphemeralKey failed: %v", err)
+ }
+
+ if !bytes.Equal(plaintext, recovered) {
+ t.Fatalf("plaintext mismatch: got %q, want %q", recovered, plaintext)
+ }
+}
+
+func TestXWingMultipleEncryptions(t *testing.T) {
+ kp, err := NewXWingKeyPair()
+ if err != nil {
+ t.Fatalf("NewXWingKeyPair failed: %v", err)
+ }
+
+ pubPEM, err := kp.PublicKeyInPemFormat()
+ if err != nil {
+ t.Fatalf("PublicKeyInPemFormat failed: %v", err)
+ }
+
+ privPEM, err := kp.PrivateKeyInPemFormat()
+ if err != nil {
+ t.Fatalf("PrivateKeyInPemFormat failed: %v", err)
+ }
+
+ for i := range 5 {
+ plaintext := []byte("message " + string(rune('A'+i)))
+
+ enc, err := FromPublicPEM(pubPEM)
+ if err != nil {
+ t.Fatalf("FromPublicPEM failed: %v", err)
+ }
+
+ ct, err := enc.Encrypt(plaintext)
+ if err != nil {
+ t.Fatalf("Encrypt failed: %v", err)
+ }
+
+ ek := enc.EphemeralKey()
+
+ dec, err := FromPrivatePEM(privPEM)
+ if err != nil {
+ t.Fatalf("FromPrivatePEM failed: %v", err)
+ }
+
+ recovered, err := dec.DecryptWithEphemeralKey(ct, ek)
+ if err != nil {
+ t.Fatalf("DecryptWithEphemeralKey failed for message %d: %v", i, err)
+ }
+
+ if !bytes.Equal(plaintext, recovered) {
+ t.Fatalf("plaintext mismatch for message %d", i)
+ }
+ }
+}
+
+func TestXWingCombiner(t *testing.T) {
+ // Verify the combiner produces deterministic output
+ ssM := make([]byte, 32)
+ ssX := make([]byte, 32)
+ ctX := make([]byte, 32)
+ pkX := make([]byte, 32)
+
+ result1 := xwingCombiner(ssM, ssX, ctX, pkX)
+ result2 := xwingCombiner(ssM, ssX, ctX, pkX)
+
+ if result1 != result2 {
+ t.Fatal("combiner not deterministic")
+ }
+
+ // Different inputs should produce different outputs
+ ssM[0] = 1
+ result3 := xwingCombiner(ssM, ssX, ctX, pkX)
+ if result1 == result3 {
+ t.Fatal("combiner should produce different output for different inputs")
+ }
+}
+
+func TestXWingLabel(t *testing.T) {
+ // Verify the label matches the spec: 0x5c2e2f2f5e5c
+ expected, _ := hex.DecodeString("5c2e2f2f5e5c")
+ if !bytes.Equal(xwingLabel, expected) {
+ t.Fatalf("XWing label mismatch: got %x, want %x", xwingLabel, expected)
+ }
+}
+
+func TestXWingCiphertextASN1RoundTrip(t *testing.T) {
+ // Create a fake 1120-byte ciphertext
+ ct := make([]byte, xwingCiphertextSize)
+ for i := range ct {
+ ct[i] = byte(i % 256)
+ }
+
+ encoded, err := marshalXWingCiphertext(ct)
+ if err != nil {
+ t.Fatalf("marshalXWingCiphertext failed: %v", err)
+ }
+
+ decoded, err := parseXWingCiphertext(encoded)
+ if err != nil {
+ t.Fatalf("parseXWingCiphertext failed: %v", err)
+ }
+
+ if !bytes.Equal(ct, decoded) {
+ t.Fatal("ciphertext round-trip mismatch")
+ }
+}
+
+func TestXWingPublicKeyASN1RoundTrip(t *testing.T) {
+ // Create a fake 1216-byte public key
+ pk := make([]byte, xwingPublicKeySize)
+ for i := range pk {
+ pk[i] = byte(i % 256)
+ }
+
+ der, err := marshalXWingPublicKey(pk)
+ if err != nil {
+ t.Fatalf("marshalXWingPublicKey failed: %v", err)
+ }
+
+ decoded, err := parseXWingPublicKeyFromDER(der)
+ if err != nil {
+ t.Fatalf("parseXWingPublicKeyFromDER failed: %v", err)
+ }
+
+ if !bytes.Equal(pk, decoded) {
+ t.Fatal("public key round-trip mismatch")
+ }
+}
+
+func TestXWingPrivateKeyASN1RoundTrip(t *testing.T) {
+ seed := [32]byte{
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ }
+
+ der, err := marshalXWingPrivateKey(seed[:])
+ if err != nil {
+ t.Fatalf("marshalXWingPrivateKey failed: %v", err)
+ }
+
+ decoded, err := parseXWingPrivateKeyFromDER(der)
+ if err != nil {
+ t.Fatalf("parseXWingPrivateKeyFromDER failed: %v", err)
+ }
+
+ if seed != decoded {
+ t.Fatal("private key round-trip mismatch")
+ }
+}
+
+// TestXWingRFCTestVector1 verifies against the first test vector from
+// draft-connolly-cfrg-xwing-kem-10 Appendix C.
+func TestXWingRFCTestVector1(t *testing.T) {
+ seedHex := "7f9c2ba4e88f827d616045507605853ed73b8093f6efbc88eb1a6eacfa66ef26"
+ expectedSSHex := "d2df0522128f09dd8e2c92b1e905c793d8f57a54c3da25861f10bf4ca613e384"
+
+ seed, err := hex.DecodeString(seedHex)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ expectedSS, err := hex.DecodeString(expectedSSHex)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ // Verify seed expands to produce the expected public key
+ var seedArr [32]byte
+ copy(seedArr[:], seed)
+ _, _, pkM, pkX, err := expandDecapsulationKey(seedArr)
+ if err != nil {
+ t.Fatalf("expandDecapsulationKey failed: %v", err)
+ }
+
+ // The public key should be 1216 bytes
+ pk := make([]byte, 0, xwingPublicKeySize)
+ pk = append(pk, pkM...)
+ pk = append(pk, pkX...)
+ if len(pk) != xwingPublicKeySize {
+ t.Fatalf("public key size: got %d, want %d", len(pk), xwingPublicKeySize)
+ }
+
+ // Verify the expected public key from the test vector (first 68 hex chars = 34 bytes)
+ expectedPKPrefix := "e2236b35a8c24b39b10aa1323a96a919a2ced88400633a7b07131713fc14b2b5"
+ pkHex := hex.EncodeToString(pk)
+ if pkHex[:64] != expectedPKPrefix {
+ t.Fatalf("public key prefix mismatch:\ngot %s\nwant %s", pkHex[:64], expectedPKPrefix)
+ }
+
+ // We can't test encapsulate/decapsulate with the test vector directly because
+ // encapsulation is randomized, but we can verify the shared secret length
+ // and that encapsulate/decapsulate are consistent with our own keys.
+ ss, ct, err := xwingEncapsulate(pk)
+ if err != nil {
+ t.Fatalf("xwingEncapsulate failed: %v", err)
+ }
+
+ if len(ss) != xwingSharedKeySize {
+ t.Fatalf("shared secret size: got %d, want %d", len(ss), xwingSharedKeySize)
+ }
+
+ // Verify decapsulation recovers the same shared secret
+ ssDecap, err := xwingDecapsulate(ct[:], seedArr)
+ if err != nil {
+ t.Fatalf("xwingDecapsulate failed: %v", err)
+ }
+
+ if ss != ssDecap {
+ t.Fatal("encapsulate/decapsulate shared secret mismatch")
+ }
+
+ // The expected shared secret from the RFC is for a specific eseed;
+ // since we used a random eseed, ours will differ. Just verify the format.
+ _ = expectedSS // We verified the format; deterministic test would need EncapsulateDerand
+}
+
+func TestXWingSizes(t *testing.T) {
+ if xwingPublicKeySize != 1216 {
+ t.Fatalf("xwingPublicKeySize: got %d, want 1216", xwingPublicKeySize)
+ }
+ if xwingCiphertextSize != 1120 {
+ t.Fatalf("xwingCiphertextSize: got %d, want 1120", xwingCiphertextSize)
+ }
+ if xwingSeedSize != 32 {
+ t.Fatalf("xwingSeedSize: got %d, want 32", xwingSeedSize)
+ }
+ if xwingSharedKeySize != 32 {
+ t.Fatalf("xwingSharedKeySize: got %d, want 32", xwingSharedKeySize)
+ }
+}
+
+func TestXWingEncapsulateDecapsulateConsistency(t *testing.T) {
+ // Generate multiple key pairs and verify encaps/decaps consistency
+ for range 10 {
+ kp, err := NewXWingKeyPair()
+ if err != nil {
+ t.Fatalf("NewXWingKeyPair failed: %v", err)
+ }
+
+ _, _, pkM, pkX, err := expandDecapsulationKey(kp.seed)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ pk := make([]byte, 0, xwingPublicKeySize)
+ pk = append(pk, pkM...)
+ pk = append(pk, pkX...)
+
+ ss, ct, err := xwingEncapsulate(pk)
+ if err != nil {
+ t.Fatalf("xwingEncapsulate failed: %v", err)
+ }
+
+ ssDecap, err := xwingDecapsulate(ct[:], kp.seed)
+ if err != nil {
+ t.Fatalf("xwingDecapsulate failed: %v", err)
+ }
+
+ if ss != ssDecap {
+ t.Fatal("encapsulate/decapsulate shared secret mismatch")
+ }
+ }
+}
diff --git a/protocol/go/policy/kasregistry/key_access_server_registry.pb.go b/protocol/go/policy/kasregistry/key_access_server_registry.pb.go
index 8e5c7b58b5..5d0d36b958 100644
--- a/protocol/go/policy/kasregistry/key_access_server_registry.pb.go
+++ b/protocol/go/policy/kasregistry/key_access_server_registry.pb.go
@@ -4012,218 +4012,219 @@ var file_policy_kasregistry_key_access_server_registry_proto_rawDesc = []byte{
0x12, 0x34, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, 0x61,
0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69,
- 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x02, 0x18, 0x01, 0x22, 0xcc, 0x0c, 0x0a, 0x10, 0x43,
+ 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x02, 0x18, 0x01, 0x22, 0xd4, 0x0c, 0x0a, 0x10, 0x43,
0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
0x1f, 0x0a, 0x06, 0x6b, 0x61, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42,
0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x05, 0x6b, 0x61, 0x73, 0x49, 0x64,
0x12, 0x1e, 0x0a, 0x06, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x05, 0x6b, 0x65, 0x79, 0x49, 0x64,
- 0x12, 0xa4, 0x01, 0x0a, 0x0d, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74,
+ 0x12, 0xac, 0x01, 0x0a, 0x0d, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74,
0x68, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x11, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63,
- 0x79, 0x2e, 0x41, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x42, 0x6c, 0xba, 0x48, 0x69,
- 0xba, 0x01, 0x66, 0x0a, 0x15, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74,
+ 0x79, 0x2e, 0x41, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x42, 0x74, 0xba, 0x48, 0x71,
+ 0xba, 0x01, 0x6e, 0x0a, 0x15, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74,
0x68, 0x6d, 0x5f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x12, 0x34, 0x54, 0x68, 0x65, 0x20,
0x6b, 0x65, 0x79, 0x5f, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x20, 0x6d, 0x75,
0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65,
0x20, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2e,
- 0x1a, 0x17, 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x5b, 0x31, 0x2c, 0x20, 0x32, 0x2c,
- 0x20, 0x33, 0x2c, 0x20, 0x34, 0x2c, 0x20, 0x35, 0x5d, 0x52, 0x0c, 0x6b, 0x65, 0x79, 0x41, 0x6c,
- 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x12, 0x93, 0x01, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x5f,
- 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x6f, 0x6c,
- 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x65, 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x42, 0x67, 0xba, 0x48, 0x64,
- 0xba, 0x01, 0x61, 0x0a, 0x10, 0x6b, 0x65, 0x79, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x5f, 0x64, 0x65,
- 0x66, 0x69, 0x6e, 0x65, 0x64, 0x12, 0x35, 0x54, 0x68, 0x65, 0x20, 0x6b, 0x65, 0x79, 0x5f, 0x6d,
- 0x6f, 0x64, 0x65, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x6f, 0x6e, 0x65, 0x20,
- 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x76,
- 0x61, 0x6c, 0x75, 0x65, 0x73, 0x20, 0x28, 0x31, 0x2d, 0x34, 0x29, 0x2e, 0x1a, 0x16, 0x74, 0x68,
- 0x69, 0x73, 0x20, 0x3e, 0x3d, 0x20, 0x31, 0x20, 0x26, 0x26, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20,
- 0x3c, 0x3d, 0x20, 0x34, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x42, 0x0a,
- 0x0e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x63, 0x74, 0x78, 0x18,
- 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50,
- 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x43, 0x74, 0x78, 0x42, 0x06, 0xba, 0x48, 0x03,
- 0xc8, 0x01, 0x01, 0x52, 0x0c, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x43, 0x74,
- 0x78, 0x12, 0x3d, 0x0a, 0x0f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79,
- 0x5f, 0x63, 0x74, 0x78, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x6f, 0x6c,
- 0x69, 0x63, 0x79, 0x2e, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x43, 0x74,
- 0x78, 0x52, 0x0d, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x43, 0x74, 0x78,
- 0x12, 0x2c, 0x0a, 0x12, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6e,
- 0x66, 0x69, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x70, 0x72,
- 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x49, 0x64, 0x12, 0x16,
- 0x0a, 0x06, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06,
- 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x12, 0x33, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61,
- 0x74, 0x61, 0x18, 0x64, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f,
- 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4d, 0x75, 0x74, 0x61, 0x62, 0x6c,
- 0x65, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3a, 0xbb, 0x07, 0xba, 0x48,
- 0xb7, 0x07, 0x1a, 0x97, 0x03, 0x0a, 0x23, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b,
- 0x65, 0x79, 0x5f, 0x63, 0x74, 0x78, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x6c,
- 0x79, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0xbc, 0x01, 0x54, 0x68, 0x65,
- 0x20, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x5f, 0x6b, 0x65, 0x79, 0x20, 0x69, 0x73, 0x20,
- 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x20, 0x69, 0x66, 0x20, 0x6b, 0x65, 0x79, 0x5f,
- 0x6d, 0x6f, 0x64, 0x65, 0x20, 0x69, 0x73, 0x20, 0x4b, 0x45, 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x45,
- 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x5f, 0x52, 0x4f, 0x4f, 0x54, 0x5f, 0x4b, 0x45, 0x59,
- 0x20, 0x6f, 0x72, 0x20, 0x4b, 0x45, 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x50, 0x52, 0x4f,
- 0x56, 0x49, 0x44, 0x45, 0x52, 0x5f, 0x52, 0x4f, 0x4f, 0x54, 0x5f, 0x4b, 0x45, 0x59, 0x2e, 0x20,
- 0x54, 0x68, 0x65, 0x20, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x5f, 0x6b, 0x65, 0x79, 0x20,
- 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x20, 0x69, 0x66,
- 0x20, 0x6b, 0x65, 0x79, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x20, 0x69, 0x73, 0x20, 0x4b, 0x45, 0x59,
- 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x52, 0x45, 0x4d, 0x4f, 0x54, 0x45, 0x20, 0x6f, 0x72, 0x20,
- 0x4b, 0x45, 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f,
- 0x4b, 0x45, 0x59, 0x5f, 0x4f, 0x4e, 0x4c, 0x59, 0x2e, 0x1a, 0xb0, 0x01, 0x28, 0x28, 0x74, 0x68,
- 0x69, 0x73, 0x2e, 0x6b, 0x65, 0x79, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x31,
- 0x20, 0x7c, 0x7c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6b, 0x65, 0x79, 0x5f, 0x6d, 0x6f, 0x64,
- 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x32, 0x29, 0x20, 0x26, 0x26, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e,
- 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x63, 0x74, 0x78, 0x2e,
- 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x5f, 0x6b, 0x65, 0x79, 0x20, 0x21, 0x3d, 0x20, 0x27,
- 0x27, 0x29, 0x20, 0x7c, 0x7c, 0x20, 0x28, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6b, 0x65, 0x79,
- 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x33, 0x20, 0x7c, 0x7c, 0x20, 0x74, 0x68,
- 0x69, 0x73, 0x2e, 0x6b, 0x65, 0x79, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x34,
- 0x29, 0x20, 0x26, 0x26, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74,
- 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x63, 0x74, 0x78, 0x2e, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65,
- 0x64, 0x5f, 0x6b, 0x65, 0x79, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x27, 0x29, 0x1a, 0xf4, 0x02, 0x0a,
- 0x26, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
- 0x5f, 0x69, 0x64, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x5f, 0x72,
- 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0xa8, 0x01, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64,
- 0x65, 0x72, 0x20, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x20, 0x69, 0x64, 0x20, 0x69, 0x73, 0x20,
- 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x20, 0x69, 0x66, 0x20, 0x6b, 0x65, 0x79, 0x5f,
- 0x6d, 0x6f, 0x64, 0x65, 0x20, 0x69, 0x73, 0x20, 0x4b, 0x45, 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x45,
- 0x5f, 0x50, 0x52, 0x4f, 0x56, 0x49, 0x44, 0x45, 0x52, 0x5f, 0x52, 0x4f, 0x4f, 0x54, 0x5f, 0x4b,
- 0x45, 0x59, 0x20, 0x6f, 0x72, 0x20, 0x4b, 0x45, 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x52,
- 0x45, 0x4d, 0x4f, 0x54, 0x45, 0x2e, 0x20, 0x49, 0x74, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62,
- 0x65, 0x20, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x4b, 0x45, 0x59, 0x5f,
- 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x5f, 0x52, 0x4f, 0x4f, 0x54,
- 0x5f, 0x4b, 0x45, 0x59, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x4b, 0x45, 0x59, 0x5f, 0x4d, 0x4f, 0x44,
- 0x45, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x4f, 0x4e, 0x4c,
- 0x59, 0x2e, 0x1a, 0x9e, 0x01, 0x28, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6b, 0x65, 0x79, 0x5f,
- 0x6d, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x31, 0x20, 0x7c, 0x7c, 0x20, 0x74, 0x68, 0x69,
- 0x73, 0x2e, 0x6b, 0x65, 0x79, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x34, 0x29,
- 0x20, 0x26, 0x26, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65,
- 0x72, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x64, 0x20, 0x3d, 0x3d, 0x20, 0x27,
- 0x27, 0x29, 0x20, 0x7c, 0x7c, 0x20, 0x28, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6b, 0x65, 0x79,
- 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x32, 0x20, 0x7c, 0x7c, 0x20, 0x74, 0x68,
- 0x69, 0x73, 0x2e, 0x6b, 0x65, 0x79, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x33,
- 0x29, 0x20, 0x26, 0x26, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64,
- 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x64, 0x20, 0x21, 0x3d, 0x20,
- 0x27, 0x27, 0x29, 0x1a, 0xa3, 0x01, 0x0a, 0x23, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f,
- 0x6b, 0x65, 0x79, 0x5f, 0x63, 0x74, 0x78, 0x5f, 0x66, 0x6f, 0x72, 0x5f, 0x70, 0x75, 0x62, 0x6c,
- 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x12, 0x48, 0x70, 0x72, 0x69,
- 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x63, 0x74, 0x78, 0x20, 0x6d, 0x75, 0x73,
- 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x65, 0x20, 0x73, 0x65, 0x74, 0x20, 0x69, 0x66, 0x20,
- 0x6b, 0x65, 0x79, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x20, 0x69, 0x73, 0x20, 0x4b, 0x45, 0x59, 0x5f,
- 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f, 0x4b, 0x45, 0x59, 0x5f,
- 0x4f, 0x4e, 0x4c, 0x59, 0x2e, 0x1a, 0x32, 0x21, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6b, 0x65,
- 0x79, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x34, 0x20, 0x26, 0x26, 0x20, 0x68,
- 0x61, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f,
- 0x6b, 0x65, 0x79, 0x5f, 0x63, 0x74, 0x78, 0x29, 0x29, 0x22, 0x3c, 0x0a, 0x11, 0x43, 0x72, 0x65,
- 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27,
- 0x0a, 0x07, 0x6b, 0x61, 0x73, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
- 0x0e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x61, 0x73, 0x4b, 0x65, 0x79, 0x52,
- 0x06, 0x6b, 0x61, 0x73, 0x4b, 0x65, 0x79, 0x22, 0x7a, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x4b, 0x65,
- 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02,
+ 0x1a, 0x1f, 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x5b, 0x31, 0x2c, 0x20, 0x32, 0x2c,
+ 0x20, 0x33, 0x2c, 0x20, 0x34, 0x2c, 0x20, 0x35, 0x2c, 0x20, 0x32, 0x30, 0x2c, 0x20, 0x32, 0x31,
+ 0x5d, 0x52, 0x0c, 0x6b, 0x65, 0x79, 0x41, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x12,
+ 0x93, 0x01, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x04, 0x20, 0x01,
+ 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x65, 0x79, 0x4d,
+ 0x6f, 0x64, 0x65, 0x42, 0x67, 0xba, 0x48, 0x64, 0xba, 0x01, 0x61, 0x0a, 0x10, 0x6b, 0x65, 0x79,
+ 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x5f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x12, 0x35, 0x54,
+ 0x68, 0x65, 0x20, 0x6b, 0x65, 0x79, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x20, 0x6d, 0x75, 0x73, 0x74,
+ 0x20, 0x62, 0x65, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64,
+ 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x20, 0x28, 0x31,
+ 0x2d, 0x34, 0x29, 0x2e, 0x1a, 0x16, 0x74, 0x68, 0x69, 0x73, 0x20, 0x3e, 0x3d, 0x20, 0x31, 0x20,
+ 0x26, 0x26, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x3c, 0x3d, 0x20, 0x34, 0x52, 0x07, 0x6b, 0x65,
+ 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x42, 0x0a, 0x0e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f,
+ 0x6b, 0x65, 0x79, 0x5f, 0x63, 0x74, 0x78, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e,
+ 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79,
+ 0x43, 0x74, 0x78, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x0c, 0x70, 0x75, 0x62,
+ 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x43, 0x74, 0x78, 0x12, 0x3d, 0x0a, 0x0f, 0x70, 0x72, 0x69,
+ 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x63, 0x74, 0x78, 0x18, 0x06, 0x20, 0x01,
+ 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, 0x72, 0x69, 0x76,
+ 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x43, 0x74, 0x78, 0x52, 0x0d, 0x70, 0x72, 0x69, 0x76, 0x61,
+ 0x74, 0x65, 0x4b, 0x65, 0x79, 0x43, 0x74, 0x78, 0x12, 0x2c, 0x0a, 0x12, 0x70, 0x72, 0x6f, 0x76,
+ 0x69, 0x64, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x07,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x43, 0x6f,
+ 0x6e, 0x66, 0x69, 0x67, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79,
+ 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x12, 0x33,
+ 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x64, 0x20, 0x01, 0x28, 0x0b,
+ 0x32, 0x17, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61,
+ 0x74, 0x61, 0x4d, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64,
+ 0x61, 0x74, 0x61, 0x3a, 0xbb, 0x07, 0xba, 0x48, 0xb7, 0x07, 0x1a, 0x97, 0x03, 0x0a, 0x23, 0x70,
+ 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x63, 0x74, 0x78, 0x5f, 0x6f,
+ 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72,
+ 0x65, 0x64, 0x12, 0xbc, 0x01, 0x54, 0x68, 0x65, 0x20, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64,
+ 0x5f, 0x6b, 0x65, 0x79, 0x20, 0x69, 0x73, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64,
+ 0x20, 0x69, 0x66, 0x20, 0x6b, 0x65, 0x79, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x20, 0x69, 0x73, 0x20,
+ 0x4b, 0x45, 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x5f,
+ 0x52, 0x4f, 0x4f, 0x54, 0x5f, 0x4b, 0x45, 0x59, 0x20, 0x6f, 0x72, 0x20, 0x4b, 0x45, 0x59, 0x5f,
+ 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x50, 0x52, 0x4f, 0x56, 0x49, 0x44, 0x45, 0x52, 0x5f, 0x52, 0x4f,
+ 0x4f, 0x54, 0x5f, 0x4b, 0x45, 0x59, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, 0x77, 0x72, 0x61, 0x70,
+ 0x70, 0x65, 0x64, 0x5f, 0x6b, 0x65, 0x79, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20,
+ 0x65, 0x6d, 0x70, 0x74, 0x79, 0x20, 0x69, 0x66, 0x20, 0x6b, 0x65, 0x79, 0x5f, 0x6d, 0x6f, 0x64,
+ 0x65, 0x20, 0x69, 0x73, 0x20, 0x4b, 0x45, 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x52, 0x45,
+ 0x4d, 0x4f, 0x54, 0x45, 0x20, 0x6f, 0x72, 0x20, 0x4b, 0x45, 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x45,
+ 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x4f, 0x4e, 0x4c, 0x59,
+ 0x2e, 0x1a, 0xb0, 0x01, 0x28, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6b, 0x65, 0x79, 0x5f, 0x6d,
+ 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x31, 0x20, 0x7c, 0x7c, 0x20, 0x74, 0x68, 0x69, 0x73,
+ 0x2e, 0x6b, 0x65, 0x79, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x32, 0x29, 0x20,
+ 0x26, 0x26, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f,
+ 0x6b, 0x65, 0x79, 0x5f, 0x63, 0x74, 0x78, 0x2e, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x5f,
+ 0x6b, 0x65, 0x79, 0x20, 0x21, 0x3d, 0x20, 0x27, 0x27, 0x29, 0x20, 0x7c, 0x7c, 0x20, 0x28, 0x28,
+ 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6b, 0x65, 0x79, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x3d,
+ 0x20, 0x33, 0x20, 0x7c, 0x7c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6b, 0x65, 0x79, 0x5f, 0x6d,
+ 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x34, 0x29, 0x20, 0x26, 0x26, 0x20, 0x74, 0x68, 0x69,
+ 0x73, 0x2e, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x63, 0x74,
+ 0x78, 0x2e, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x5f, 0x6b, 0x65, 0x79, 0x20, 0x3d, 0x3d,
+ 0x20, 0x27, 0x27, 0x29, 0x1a, 0xf4, 0x02, 0x0a, 0x26, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65,
+ 0x72, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x64, 0x5f, 0x6f, 0x70, 0x74, 0x69,
+ 0x6f, 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12,
+ 0xa8, 0x01, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x20, 0x63, 0x6f, 0x6e, 0x66, 0x69,
+ 0x67, 0x20, 0x69, 0x64, 0x20, 0x69, 0x73, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64,
+ 0x20, 0x69, 0x66, 0x20, 0x6b, 0x65, 0x79, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x20, 0x69, 0x73, 0x20,
+ 0x4b, 0x45, 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x50, 0x52, 0x4f, 0x56, 0x49, 0x44, 0x45,
+ 0x52, 0x5f, 0x52, 0x4f, 0x4f, 0x54, 0x5f, 0x4b, 0x45, 0x59, 0x20, 0x6f, 0x72, 0x20, 0x4b, 0x45,
+ 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x52, 0x45, 0x4d, 0x4f, 0x54, 0x45, 0x2e, 0x20, 0x49,
+ 0x74, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x20,
+ 0x66, 0x6f, 0x72, 0x20, 0x4b, 0x45, 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x43, 0x4f, 0x4e,
+ 0x46, 0x49, 0x47, 0x5f, 0x52, 0x4f, 0x4f, 0x54, 0x5f, 0x4b, 0x45, 0x59, 0x20, 0x61, 0x6e, 0x64,
+ 0x20, 0x4b, 0x45, 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43,
+ 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x4f, 0x4e, 0x4c, 0x59, 0x2e, 0x1a, 0x9e, 0x01, 0x28, 0x28, 0x74,
+ 0x68, 0x69, 0x73, 0x2e, 0x6b, 0x65, 0x79, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x3d, 0x20,
+ 0x31, 0x20, 0x7c, 0x7c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6b, 0x65, 0x79, 0x5f, 0x6d, 0x6f,
+ 0x64, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x34, 0x29, 0x20, 0x26, 0x26, 0x20, 0x74, 0x68, 0x69, 0x73,
+ 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+ 0x5f, 0x69, 0x64, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x27, 0x29, 0x20, 0x7c, 0x7c, 0x20, 0x28, 0x28,
+ 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6b, 0x65, 0x79, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x3d,
+ 0x20, 0x32, 0x20, 0x7c, 0x7c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6b, 0x65, 0x79, 0x5f, 0x6d,
+ 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x33, 0x29, 0x20, 0x26, 0x26, 0x20, 0x74, 0x68, 0x69,
+ 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69,
+ 0x67, 0x5f, 0x69, 0x64, 0x20, 0x21, 0x3d, 0x20, 0x27, 0x27, 0x29, 0x1a, 0xa3, 0x01, 0x0a, 0x23,
+ 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x63, 0x74, 0x78, 0x5f,
+ 0x66, 0x6f, 0x72, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x6f,
+ 0x6e, 0x6c, 0x79, 0x12, 0x48, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79,
+ 0x5f, 0x63, 0x74, 0x78, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x65,
+ 0x20, 0x73, 0x65, 0x74, 0x20, 0x69, 0x66, 0x20, 0x6b, 0x65, 0x79, 0x5f, 0x6d, 0x6f, 0x64, 0x65,
+ 0x20, 0x69, 0x73, 0x20, 0x4b, 0x45, 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x50, 0x55, 0x42,
+ 0x4c, 0x49, 0x43, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x4f, 0x4e, 0x4c, 0x59, 0x2e, 0x1a, 0x32, 0x21,
+ 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6b, 0x65, 0x79, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x20, 0x3d,
+ 0x3d, 0x20, 0x34, 0x20, 0x26, 0x26, 0x20, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e,
+ 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x63, 0x74, 0x78, 0x29,
+ 0x29, 0x22, 0x3c, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x65,
+ 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x07, 0x6b, 0x61, 0x73, 0x5f, 0x6b, 0x65,
+ 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79,
+ 0x2e, 0x4b, 0x61, 0x73, 0x4b, 0x65, 0x79, 0x52, 0x06, 0x6b, 0x61, 0x73, 0x4b, 0x65, 0x79, 0x22,
+ 0x7a, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+ 0x12, 0x1a, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48,
+ 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x48, 0x00, 0x52, 0x02, 0x69, 0x64, 0x12, 0x38, 0x0a, 0x03,
+ 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x70, 0x6f, 0x6c, 0x69,
+ 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4b,
+ 0x61, 0x73, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x48,
+ 0x00, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x42, 0x13, 0x0a, 0x0a, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69,
+ 0x66, 0x69, 0x65, 0x72, 0x12, 0x05, 0xba, 0x48, 0x02, 0x08, 0x01, 0x22, 0x39, 0x0a, 0x0e, 0x47,
+ 0x65, 0x74, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a,
+ 0x07, 0x6b, 0x61, 0x73, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e,
+ 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x61, 0x73, 0x4b, 0x65, 0x79, 0x52, 0x06,
+ 0x6b, 0x61, 0x73, 0x4b, 0x65, 0x79, 0x22, 0x96, 0x03, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x4b,
+ 0x65, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0xa7, 0x01, 0x0a, 0x0d, 0x6b,
+ 0x65, 0x79, 0x5f, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x18, 0x01, 0x20, 0x01,
+ 0x28, 0x0e, 0x32, 0x11, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x41, 0x6c, 0x67, 0x6f,
+ 0x72, 0x69, 0x74, 0x68, 0x6d, 0x42, 0x6f, 0xba, 0x48, 0x6c, 0xba, 0x01, 0x69, 0x0a, 0x15, 0x6b,
+ 0x65, 0x79, 0x5f, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x5f, 0x64, 0x65, 0x66,
+ 0x69, 0x6e, 0x65, 0x64, 0x12, 0x34, 0x54, 0x68, 0x65, 0x20, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x6c,
+ 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20,
+ 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x65, 0x66, 0x69, 0x6e,
+ 0x65, 0x64, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2e, 0x1a, 0x1a, 0x74, 0x68, 0x69, 0x73,
+ 0x20, 0x69, 0x6e, 0x20, 0x5b, 0x30, 0x2c, 0x20, 0x31, 0x2c, 0x20, 0x32, 0x2c, 0x20, 0x33, 0x2c,
+ 0x20, 0x34, 0x2c, 0x20, 0x35, 0x5d, 0x52, 0x0c, 0x6b, 0x65, 0x79, 0x41, 0x6c, 0x67, 0x6f, 0x72,
+ 0x69, 0x74, 0x68, 0x6d, 0x12, 0x21, 0x0a, 0x06, 0x6b, 0x61, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x02,
0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x48, 0x00,
- 0x52, 0x02, 0x69, 0x64, 0x12, 0x38, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28,
- 0x0b, 0x32, 0x24, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65,
- 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4b, 0x61, 0x73, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x65,
- 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x48, 0x00, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x42, 0x13,
- 0x0a, 0x0a, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x05, 0xba, 0x48,
- 0x02, 0x08, 0x01, 0x22, 0x39, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73,
- 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x07, 0x6b, 0x61, 0x73, 0x5f, 0x6b, 0x65, 0x79,
- 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e,
- 0x4b, 0x61, 0x73, 0x4b, 0x65, 0x79, 0x52, 0x06, 0x6b, 0x61, 0x73, 0x4b, 0x65, 0x79, 0x22, 0x96,
- 0x03, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
- 0x73, 0x74, 0x12, 0xa7, 0x01, 0x0a, 0x0d, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x6c, 0x67, 0x6f, 0x72,
- 0x69, 0x74, 0x68, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x11, 0x2e, 0x70, 0x6f, 0x6c,
- 0x69, 0x63, 0x79, 0x2e, 0x41, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x42, 0x6f, 0xba,
- 0x48, 0x6c, 0xba, 0x01, 0x69, 0x0a, 0x15, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x6c, 0x67, 0x6f, 0x72,
- 0x69, 0x74, 0x68, 0x6d, 0x5f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x12, 0x34, 0x54, 0x68,
- 0x65, 0x20, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x20,
- 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74,
- 0x68, 0x65, 0x20, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65,
- 0x73, 0x2e, 0x1a, 0x1a, 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x5b, 0x30, 0x2c, 0x20,
- 0x31, 0x2c, 0x20, 0x32, 0x2c, 0x20, 0x33, 0x2c, 0x20, 0x34, 0x2c, 0x20, 0x35, 0x5d, 0x52, 0x0c,
- 0x6b, 0x65, 0x79, 0x41, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x12, 0x21, 0x0a, 0x06,
- 0x6b, 0x61, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48,
- 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x48, 0x00, 0x52, 0x05, 0x6b, 0x61, 0x73, 0x49, 0x64, 0x12,
- 0x24, 0x0a, 0x08, 0x6b, 0x61, 0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28,
- 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x48, 0x00, 0x52, 0x07, 0x6b, 0x61,
- 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x07, 0x6b, 0x61, 0x73, 0x5f, 0x75, 0x72, 0x69,
- 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0xba, 0x48, 0x07, 0x72, 0x05, 0x10, 0x01, 0x88,
- 0x01, 0x01, 0x48, 0x00, 0x52, 0x06, 0x6b, 0x61, 0x73, 0x55, 0x72, 0x69, 0x12, 0x1b, 0x0a, 0x06,
- 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x48, 0x01, 0x52, 0x06,
- 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x88, 0x01, 0x01, 0x12, 0x33, 0x0a, 0x0a, 0x70, 0x61, 0x67,
- 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e,
- 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
- 0x73, 0x74, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x0c,
- 0x0a, 0x0a, 0x6b, 0x61, 0x73, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x42, 0x09, 0x0a, 0x07,
- 0x5f, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x22, 0x73, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x4b,
- 0x65, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x29, 0x0a, 0x08, 0x6b,
- 0x61, 0x73, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e,
- 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x61, 0x73, 0x4b, 0x65, 0x79, 0x52, 0x07, 0x6b,
- 0x61, 0x73, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x34, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61,
- 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x6f, 0x6c,
- 0x69, 0x63, 0x79, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
- 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x86, 0x03, 0x0a,
- 0x10, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
- 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba,
- 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x12, 0x33, 0x0a, 0x08, 0x6d,
- 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x64, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e,
- 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4d,
- 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
- 0x12, 0x54, 0x0a, 0x18, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x75, 0x70, 0x64,
- 0x61, 0x74, 0x65, 0x5f, 0x62, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x18, 0x65, 0x20, 0x01,
- 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61,
- 0x64, 0x61, 0x74, 0x61, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x16,
- 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x65,
- 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x3a, 0xcc, 0x01, 0xba, 0x48, 0xc8, 0x01, 0x1a, 0xc5, 0x01,
- 0x0a, 0x18, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74,
- 0x65, 0x5f, 0x62, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x12, 0x52, 0x4d, 0x65, 0x74, 0x61,
- 0x64, 0x61, 0x74, 0x61, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x62, 0x65, 0x68, 0x61,
- 0x76, 0x69, 0x6f, 0x72, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x65, 0x69, 0x74,
- 0x68, 0x65, 0x72, 0x20, 0x41, 0x50, 0x50, 0x45, 0x4e, 0x44, 0x20, 0x6f, 0x72, 0x20, 0x52, 0x45,
- 0x50, 0x4c, 0x41, 0x43, 0x45, 0x2c, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x75, 0x70, 0x64, 0x61,
- 0x74, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x1a, 0x55,
- 0x28, 0x28, 0x21, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6d, 0x65, 0x74, 0x61,
- 0x64, 0x61, 0x74, 0x61, 0x29, 0x29, 0x20, 0x7c, 0x7c, 0x20, 0x28, 0x68, 0x61, 0x73, 0x28, 0x74,
- 0x68, 0x69, 0x73, 0x2e, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x29, 0x20, 0x26, 0x26,
- 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x75,
- 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x62, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x20, 0x21,
- 0x3d, 0x20, 0x30, 0x29, 0x29, 0x22, 0x3c, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4b,
- 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x07, 0x6b, 0x61,
- 0x73, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x6f,
- 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x61, 0x73, 0x4b, 0x65, 0x79, 0x52, 0x06, 0x6b, 0x61, 0x73,
- 0x4b, 0x65, 0x79, 0x22, 0xa4, 0x01, 0x0a, 0x10, 0x4b, 0x61, 0x73, 0x4b, 0x65, 0x79, 0x49, 0x64,
- 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x21, 0x0a, 0x06, 0x6b, 0x61, 0x73, 0x5f,
- 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0,
- 0x01, 0x01, 0x48, 0x00, 0x52, 0x05, 0x6b, 0x61, 0x73, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x04, 0x6e,
+ 0x52, 0x05, 0x6b, 0x61, 0x73, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x08, 0x6b, 0x61, 0x73, 0x5f, 0x6e,
0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02,
- 0x10, 0x01, 0x48, 0x00, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x03, 0x75, 0x72,
- 0x69, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0xba, 0x48, 0x07, 0x72, 0x05, 0x10, 0x01,
- 0x88, 0x01, 0x01, 0x48, 0x00, 0x52, 0x03, 0x75, 0x72, 0x69, 0x12, 0x19, 0x0a, 0x03, 0x6b, 0x69,
- 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01,
- 0x52, 0x03, 0x6b, 0x69, 0x64, 0x42, 0x13, 0x0a, 0x0a, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66,
- 0x69, 0x65, 0x72, 0x12, 0x05, 0xba, 0x48, 0x02, 0x08, 0x01, 0x22, 0xe5, 0x0e, 0x0a, 0x10, 0x52,
- 0x6f, 0x74, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
- 0x1a, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05,
- 0x72, 0x03, 0xb0, 0x01, 0x01, 0x48, 0x00, 0x52, 0x02, 0x69, 0x64, 0x12, 0x38, 0x0a, 0x03, 0x6b,
- 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63,
- 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4b, 0x61,
- 0x73, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x48, 0x00,
- 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x44, 0x0a, 0x07, 0x6e, 0x65, 0x77, 0x5f, 0x6b, 0x65, 0x79,
- 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e,
- 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x52, 0x6f, 0x74, 0x61,
- 0x74, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4e, 0x65, 0x77,
- 0x4b, 0x65, 0x79, 0x52, 0x06, 0x6e, 0x65, 0x77, 0x4b, 0x65, 0x79, 0x1a, 0xcf, 0x04, 0x0a, 0x06,
- 0x4e, 0x65, 0x77, 0x4b, 0x65, 0x79, 0x12, 0x1e, 0x0a, 0x06, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64,
- 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52,
- 0x05, 0x6b, 0x65, 0x79, 0x49, 0x64, 0x12, 0x9d, 0x01, 0x0a, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72,
- 0x69, 0x74, 0x68, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x11, 0x2e, 0x70, 0x6f, 0x6c,
- 0x69, 0x63, 0x79, 0x2e, 0x41, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x42, 0x6c, 0xba,
- 0x48, 0x69, 0xba, 0x01, 0x66, 0x0a, 0x15, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x6c, 0x67, 0x6f, 0x72,
- 0x69, 0x74, 0x68, 0x6d, 0x5f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x12, 0x34, 0x54, 0x68,
- 0x65, 0x20, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x20,
- 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74,
- 0x68, 0x65, 0x20, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65,
- 0x73, 0x2e, 0x1a, 0x17, 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x5b, 0x31, 0x2c, 0x20,
- 0x32, 0x2c, 0x20, 0x33, 0x2c, 0x20, 0x34, 0x2c, 0x20, 0x35, 0x5d, 0x52, 0x09, 0x61, 0x6c, 0x67,
+ 0x10, 0x01, 0x48, 0x00, 0x52, 0x07, 0x6b, 0x61, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a,
+ 0x07, 0x6b, 0x61, 0x73, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a,
+ 0xba, 0x48, 0x07, 0x72, 0x05, 0x10, 0x01, 0x88, 0x01, 0x01, 0x48, 0x00, 0x52, 0x06, 0x6b, 0x61,
+ 0x73, 0x55, 0x72, 0x69, 0x12, 0x1b, 0x0a, 0x06, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x18, 0x08,
+ 0x20, 0x01, 0x28, 0x08, 0x48, 0x01, 0x52, 0x06, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x88, 0x01,
+ 0x01, 0x12, 0x33, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18,
+ 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50,
+ 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69,
+ 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x0c, 0x0a, 0x0a, 0x6b, 0x61, 0x73, 0x5f, 0x66, 0x69,
+ 0x6c, 0x74, 0x65, 0x72, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x22,
+ 0x73, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
+ 0x6e, 0x73, 0x65, 0x12, 0x29, 0x0a, 0x08, 0x6b, 0x61, 0x73, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18,
+ 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4b,
+ 0x61, 0x73, 0x4b, 0x65, 0x79, 0x52, 0x07, 0x6b, 0x61, 0x73, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x34,
+ 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01,
+ 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, 0x61, 0x67, 0x65,
+ 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61,
+ 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x86, 0x03, 0x0a, 0x10, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4b,
+ 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52,
+ 0x02, 0x69, 0x64, 0x12, 0x33, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18,
+ 0x64, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d,
+ 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4d, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x08,
+ 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x54, 0x0a, 0x18, 0x6d, 0x65, 0x74, 0x61,
+ 0x64, 0x61, 0x74, 0x61, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x62, 0x65, 0x68, 0x61,
+ 0x76, 0x69, 0x6f, 0x72, 0x18, 0x65, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x63, 0x6f, 0x6d,
+ 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x55, 0x70, 0x64, 0x61,
+ 0x74, 0x65, 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x16, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
+ 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x3a, 0xcc,
+ 0x01, 0xba, 0x48, 0xc8, 0x01, 0x1a, 0xc5, 0x01, 0x0a, 0x18, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61,
+ 0x74, 0x61, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x62, 0x65, 0x68, 0x61, 0x76, 0x69,
+ 0x6f, 0x72, 0x12, 0x52, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x20, 0x75, 0x70, 0x64,
+ 0x61, 0x74, 0x65, 0x20, 0x62, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x20, 0x6d, 0x75, 0x73,
+ 0x74, 0x20, 0x62, 0x65, 0x20, 0x65, 0x69, 0x74, 0x68, 0x65, 0x72, 0x20, 0x41, 0x50, 0x50, 0x45,
+ 0x4e, 0x44, 0x20, 0x6f, 0x72, 0x20, 0x52, 0x45, 0x50, 0x4c, 0x41, 0x43, 0x45, 0x2c, 0x20, 0x77,
+ 0x68, 0x65, 0x6e, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x65, 0x74,
+ 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x1a, 0x55, 0x28, 0x28, 0x21, 0x68, 0x61, 0x73, 0x28, 0x74,
+ 0x68, 0x69, 0x73, 0x2e, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x29, 0x29, 0x20, 0x7c,
+ 0x7c, 0x20, 0x28, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6d, 0x65, 0x74, 0x61,
+ 0x64, 0x61, 0x74, 0x61, 0x29, 0x20, 0x26, 0x26, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6d, 0x65,
+ 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x62, 0x65,
+ 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x20, 0x21, 0x3d, 0x20, 0x30, 0x29, 0x29, 0x22, 0x3c, 0x0a,
+ 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+ 0x73, 0x65, 0x12, 0x27, 0x0a, 0x07, 0x6b, 0x61, 0x73, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x61, 0x73,
+ 0x4b, 0x65, 0x79, 0x52, 0x06, 0x6b, 0x61, 0x73, 0x4b, 0x65, 0x79, 0x22, 0xa4, 0x01, 0x0a, 0x10,
+ 0x4b, 0x61, 0x73, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72,
+ 0x12, 0x21, 0x0a, 0x06, 0x6b, 0x61, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
+ 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x48, 0x00, 0x52, 0x05, 0x6b, 0x61,
+ 0x73, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28,
+ 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x48, 0x00, 0x52, 0x04, 0x6e, 0x61,
+ 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x03, 0x75, 0x72, 0x69, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42,
+ 0x0a, 0xba, 0x48, 0x07, 0x72, 0x05, 0x10, 0x01, 0x88, 0x01, 0x01, 0x48, 0x00, 0x52, 0x03, 0x75,
+ 0x72, 0x69, 0x12, 0x19, 0x0a, 0x03, 0x6b, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x42,
+ 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x03, 0x6b, 0x69, 0x64, 0x42, 0x13, 0x0a,
+ 0x0a, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x05, 0xba, 0x48, 0x02,
+ 0x08, 0x01, 0x22, 0xed, 0x0e, 0x0a, 0x10, 0x52, 0x6f, 0x74, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79,
+ 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x48, 0x00, 0x52,
+ 0x02, 0x69, 0x64, 0x12, 0x38, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
+ 0x32, 0x24, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67,
+ 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4b, 0x61, 0x73, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x65, 0x6e,
+ 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x48, 0x00, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x44, 0x0a,
+ 0x07, 0x6e, 0x65, 0x77, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b,
+ 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73,
+ 0x74, 0x72, 0x79, 0x2e, 0x52, 0x6f, 0x74, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71,
+ 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4e, 0x65, 0x77, 0x4b, 0x65, 0x79, 0x52, 0x06, 0x6e, 0x65, 0x77,
+ 0x4b, 0x65, 0x79, 0x1a, 0xd7, 0x04, 0x0a, 0x06, 0x4e, 0x65, 0x77, 0x4b, 0x65, 0x79, 0x12, 0x1e,
+ 0x0a, 0x06, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07,
+ 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x05, 0x6b, 0x65, 0x79, 0x49, 0x64, 0x12, 0xa5,
+ 0x01, 0x0a, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x18, 0x02, 0x20, 0x01,
+ 0x28, 0x0e, 0x32, 0x11, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x41, 0x6c, 0x67, 0x6f,
+ 0x72, 0x69, 0x74, 0x68, 0x6d, 0x42, 0x74, 0xba, 0x48, 0x71, 0xba, 0x01, 0x6e, 0x0a, 0x15, 0x6b,
+ 0x65, 0x79, 0x5f, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x5f, 0x64, 0x65, 0x66,
+ 0x69, 0x6e, 0x65, 0x64, 0x12, 0x34, 0x54, 0x68, 0x65, 0x20, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x6c,
+ 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20,
+ 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x65, 0x66, 0x69, 0x6e,
+ 0x65, 0x64, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2e, 0x1a, 0x1f, 0x74, 0x68, 0x69, 0x73,
+ 0x20, 0x69, 0x6e, 0x20, 0x5b, 0x31, 0x2c, 0x20, 0x32, 0x2c, 0x20, 0x33, 0x2c, 0x20, 0x34, 0x2c,
+ 0x20, 0x35, 0x2c, 0x20, 0x32, 0x30, 0x2c, 0x20, 0x32, 0x31, 0x5d, 0x52, 0x09, 0x61, 0x6c, 0x67,
0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x12, 0x9e, 0x01, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x5f, 0x6d,
0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x6f, 0x6c, 0x69,
0x63, 0x79, 0x2e, 0x4b, 0x65, 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x42, 0x72, 0xba, 0x48, 0x6f, 0xba,
diff --git a/protocol/go/policy/objects.pb.go b/protocol/go/policy/objects.pb.go
index d2c0921c8b..2675402efc 100644
--- a/protocol/go/policy/objects.pb.go
+++ b/protocol/go/policy/objects.pb.go
@@ -243,17 +243,23 @@ const (
KasPublicKeyAlgEnum_KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP256R1 KasPublicKeyAlgEnum = 5
KasPublicKeyAlgEnum_KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP384R1 KasPublicKeyAlgEnum = 6
KasPublicKeyAlgEnum_KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP521R1 KasPublicKeyAlgEnum = 7
+ KasPublicKeyAlgEnum_KAS_PUBLIC_KEY_ALG_ENUM_MLKEM_768 KasPublicKeyAlgEnum = 20
+ KasPublicKeyAlgEnum_KAS_PUBLIC_KEY_ALG_ENUM_MLKEM_1024 KasPublicKeyAlgEnum = 21
+ KasPublicKeyAlgEnum_KAS_PUBLIC_KEY_ALG_ENUM_XWING KasPublicKeyAlgEnum = 30
)
// Enum value maps for KasPublicKeyAlgEnum.
var (
KasPublicKeyAlgEnum_name = map[int32]string{
- 0: "KAS_PUBLIC_KEY_ALG_ENUM_UNSPECIFIED",
- 1: "KAS_PUBLIC_KEY_ALG_ENUM_RSA_2048",
- 2: "KAS_PUBLIC_KEY_ALG_ENUM_RSA_4096",
- 5: "KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP256R1",
- 6: "KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP384R1",
- 7: "KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP521R1",
+ 0: "KAS_PUBLIC_KEY_ALG_ENUM_UNSPECIFIED",
+ 1: "KAS_PUBLIC_KEY_ALG_ENUM_RSA_2048",
+ 2: "KAS_PUBLIC_KEY_ALG_ENUM_RSA_4096",
+ 5: "KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP256R1",
+ 6: "KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP384R1",
+ 7: "KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP521R1",
+ 20: "KAS_PUBLIC_KEY_ALG_ENUM_MLKEM_768",
+ 21: "KAS_PUBLIC_KEY_ALG_ENUM_MLKEM_1024",
+ 30: "KAS_PUBLIC_KEY_ALG_ENUM_XWING",
}
KasPublicKeyAlgEnum_value = map[string]int32{
"KAS_PUBLIC_KEY_ALG_ENUM_UNSPECIFIED": 0,
@@ -262,6 +268,9 @@ var (
"KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP256R1": 5,
"KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP384R1": 6,
"KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP521R1": 7,
+ "KAS_PUBLIC_KEY_ALG_ENUM_MLKEM_768": 20,
+ "KAS_PUBLIC_KEY_ALG_ENUM_MLKEM_1024": 21,
+ "KAS_PUBLIC_KEY_ALG_ENUM_XWING": 30,
}
)
@@ -302,17 +311,23 @@ const (
Algorithm_ALGORITHM_EC_P256 Algorithm = 3
Algorithm_ALGORITHM_EC_P384 Algorithm = 4
Algorithm_ALGORITHM_EC_P521 Algorithm = 5
+ Algorithm_ALGORITHM_MLKEM_768 Algorithm = 20
+ Algorithm_ALGORITHM_MLKEM_1024 Algorithm = 21
+ Algorithm_ALGORITHM_XWING Algorithm = 30
)
// Enum value maps for Algorithm.
var (
Algorithm_name = map[int32]string{
- 0: "ALGORITHM_UNSPECIFIED",
- 1: "ALGORITHM_RSA_2048",
- 2: "ALGORITHM_RSA_4096",
- 3: "ALGORITHM_EC_P256",
- 4: "ALGORITHM_EC_P384",
- 5: "ALGORITHM_EC_P521",
+ 0: "ALGORITHM_UNSPECIFIED",
+ 1: "ALGORITHM_RSA_2048",
+ 2: "ALGORITHM_RSA_4096",
+ 3: "ALGORITHM_EC_P256",
+ 4: "ALGORITHM_EC_P384",
+ 5: "ALGORITHM_EC_P521",
+ 20: "ALGORITHM_MLKEM_768",
+ 21: "ALGORITHM_MLKEM_1024",
+ 30: "ALGORITHM_XWING",
}
Algorithm_value = map[string]int32{
"ALGORITHM_UNSPECIFIED": 0,
@@ -321,6 +336,9 @@ var (
"ALGORITHM_EC_P256": 3,
"ALGORITHM_EC_P384": 4,
"ALGORITHM_EC_P521": 5,
+ "ALGORITHM_MLKEM_768": 20,
+ "ALGORITHM_MLKEM_1024": 21,
+ "ALGORITHM_XWING": 30,
}
)
@@ -3697,7 +3715,7 @@ var file_policy_objects_proto_rawDesc = []byte{
0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x49, 0x4e, 0x54, 0x45,
0x52, 0x4e, 0x41, 0x4c, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45,
0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x58, 0x54, 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x10, 0x02,
- 0x2a, 0x88, 0x02, 0x0a, 0x13, 0x4b, 0x61, 0x73, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65,
+ 0x2a, 0xfa, 0x02, 0x0a, 0x13, 0x4b, 0x61, 0x73, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65,
0x79, 0x41, 0x6c, 0x67, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x27, 0x0a, 0x23, 0x4b, 0x41, 0x53, 0x5f,
0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x41, 0x4c, 0x47, 0x5f, 0x45,
0x4e, 0x55, 0x4d, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10,
@@ -3713,41 +3731,52 @@ var file_policy_objects_proto_rawDesc = []byte{
0x55, 0x4d, 0x5f, 0x45, 0x43, 0x5f, 0x53, 0x45, 0x43, 0x50, 0x33, 0x38, 0x34, 0x52, 0x31, 0x10,
0x06, 0x12, 0x28, 0x0a, 0x24, 0x4b, 0x41, 0x53, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f,
0x4b, 0x45, 0x59, 0x5f, 0x41, 0x4c, 0x47, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x45, 0x43, 0x5f,
- 0x53, 0x45, 0x43, 0x50, 0x35, 0x32, 0x31, 0x52, 0x31, 0x10, 0x07, 0x2a, 0x9b, 0x01, 0x0a, 0x09,
- 0x41, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x12, 0x19, 0x0a, 0x15, 0x41, 0x4c, 0x47,
- 0x4f, 0x52, 0x49, 0x54, 0x48, 0x4d, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49,
- 0x45, 0x44, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x41, 0x4c, 0x47, 0x4f, 0x52, 0x49, 0x54, 0x48,
- 0x4d, 0x5f, 0x52, 0x53, 0x41, 0x5f, 0x32, 0x30, 0x34, 0x38, 0x10, 0x01, 0x12, 0x16, 0x0a, 0x12,
- 0x41, 0x4c, 0x47, 0x4f, 0x52, 0x49, 0x54, 0x48, 0x4d, 0x5f, 0x52, 0x53, 0x41, 0x5f, 0x34, 0x30,
- 0x39, 0x36, 0x10, 0x02, 0x12, 0x15, 0x0a, 0x11, 0x41, 0x4c, 0x47, 0x4f, 0x52, 0x49, 0x54, 0x48,
- 0x4d, 0x5f, 0x45, 0x43, 0x5f, 0x50, 0x32, 0x35, 0x36, 0x10, 0x03, 0x12, 0x15, 0x0a, 0x11, 0x41,
- 0x4c, 0x47, 0x4f, 0x52, 0x49, 0x54, 0x48, 0x4d, 0x5f, 0x45, 0x43, 0x5f, 0x50, 0x33, 0x38, 0x34,
- 0x10, 0x04, 0x12, 0x15, 0x0a, 0x11, 0x41, 0x4c, 0x47, 0x4f, 0x52, 0x49, 0x54, 0x48, 0x4d, 0x5f,
- 0x45, 0x43, 0x5f, 0x50, 0x35, 0x32, 0x31, 0x10, 0x05, 0x2a, 0x56, 0x0a, 0x09, 0x4b, 0x65, 0x79,
- 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1a, 0x0a, 0x16, 0x4b, 0x45, 0x59, 0x5f, 0x53, 0x54,
- 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44,
- 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x4b, 0x45, 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53,
- 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x10, 0x01, 0x12, 0x16, 0x0a, 0x12, 0x4b, 0x45, 0x59,
- 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x4f, 0x54, 0x41, 0x54, 0x45, 0x44, 0x10,
- 0x02, 0x2a, 0x94, 0x01, 0x0a, 0x07, 0x4b, 0x65, 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a,
- 0x14, 0x4b, 0x45, 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43,
- 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x4b, 0x45, 0x59, 0x5f, 0x4d,
- 0x4f, 0x44, 0x45, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x5f, 0x52, 0x4f, 0x4f, 0x54, 0x5f,
- 0x4b, 0x45, 0x59, 0x10, 0x01, 0x12, 0x1e, 0x0a, 0x1a, 0x4b, 0x45, 0x59, 0x5f, 0x4d, 0x4f, 0x44,
- 0x45, 0x5f, 0x50, 0x52, 0x4f, 0x56, 0x49, 0x44, 0x45, 0x52, 0x5f, 0x52, 0x4f, 0x4f, 0x54, 0x5f,
- 0x4b, 0x45, 0x59, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x4b, 0x45, 0x59, 0x5f, 0x4d, 0x4f, 0x44,
- 0x45, 0x5f, 0x52, 0x45, 0x4d, 0x4f, 0x54, 0x45, 0x10, 0x03, 0x12, 0x1c, 0x0a, 0x18, 0x4b, 0x45,
- 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f, 0x4b, 0x45,
- 0x59, 0x5f, 0x4f, 0x4e, 0x4c, 0x59, 0x10, 0x04, 0x42, 0x82, 0x01, 0x0a, 0x0a, 0x63, 0x6f, 0x6d,
- 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x42, 0x0c, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73,
- 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
- 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x64, 0x66, 0x2f, 0x70, 0x6c, 0x61, 0x74,
- 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x67, 0x6f,
- 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0xa2, 0x02, 0x03, 0x50, 0x58, 0x58, 0xaa, 0x02, 0x06,
- 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0xca, 0x02, 0x06, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0xe2,
- 0x02, 0x12, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61,
- 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x06, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x62, 0x06, 0x70,
- 0x72, 0x6f, 0x74, 0x6f, 0x33,
+ 0x53, 0x45, 0x43, 0x50, 0x35, 0x32, 0x31, 0x52, 0x31, 0x10, 0x07, 0x12, 0x25, 0x0a, 0x21, 0x4b,
+ 0x41, 0x53, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x41, 0x4c,
+ 0x47, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x4d, 0x4c, 0x4b, 0x45, 0x4d, 0x5f, 0x37, 0x36, 0x38,
+ 0x10, 0x14, 0x12, 0x26, 0x0a, 0x22, 0x4b, 0x41, 0x53, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43,
+ 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x41, 0x4c, 0x47, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x4d, 0x4c,
+ 0x4b, 0x45, 0x4d, 0x5f, 0x31, 0x30, 0x32, 0x34, 0x10, 0x15, 0x12, 0x21, 0x0a, 0x1d, 0x4b, 0x41,
+ 0x53, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x41, 0x4c, 0x47,
+ 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x58, 0x57, 0x49, 0x4e, 0x47, 0x10, 0x1e, 0x2a, 0xe3, 0x01,
+ 0x0a, 0x09, 0x41, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x12, 0x19, 0x0a, 0x15, 0x41,
+ 0x4c, 0x47, 0x4f, 0x52, 0x49, 0x54, 0x48, 0x4d, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49,
+ 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x41, 0x4c, 0x47, 0x4f, 0x52, 0x49,
+ 0x54, 0x48, 0x4d, 0x5f, 0x52, 0x53, 0x41, 0x5f, 0x32, 0x30, 0x34, 0x38, 0x10, 0x01, 0x12, 0x16,
+ 0x0a, 0x12, 0x41, 0x4c, 0x47, 0x4f, 0x52, 0x49, 0x54, 0x48, 0x4d, 0x5f, 0x52, 0x53, 0x41, 0x5f,
+ 0x34, 0x30, 0x39, 0x36, 0x10, 0x02, 0x12, 0x15, 0x0a, 0x11, 0x41, 0x4c, 0x47, 0x4f, 0x52, 0x49,
+ 0x54, 0x48, 0x4d, 0x5f, 0x45, 0x43, 0x5f, 0x50, 0x32, 0x35, 0x36, 0x10, 0x03, 0x12, 0x15, 0x0a,
+ 0x11, 0x41, 0x4c, 0x47, 0x4f, 0x52, 0x49, 0x54, 0x48, 0x4d, 0x5f, 0x45, 0x43, 0x5f, 0x50, 0x33,
+ 0x38, 0x34, 0x10, 0x04, 0x12, 0x15, 0x0a, 0x11, 0x41, 0x4c, 0x47, 0x4f, 0x52, 0x49, 0x54, 0x48,
+ 0x4d, 0x5f, 0x45, 0x43, 0x5f, 0x50, 0x35, 0x32, 0x31, 0x10, 0x05, 0x12, 0x17, 0x0a, 0x13, 0x41,
+ 0x4c, 0x47, 0x4f, 0x52, 0x49, 0x54, 0x48, 0x4d, 0x5f, 0x4d, 0x4c, 0x4b, 0x45, 0x4d, 0x5f, 0x37,
+ 0x36, 0x38, 0x10, 0x14, 0x12, 0x18, 0x0a, 0x14, 0x41, 0x4c, 0x47, 0x4f, 0x52, 0x49, 0x54, 0x48,
+ 0x4d, 0x5f, 0x4d, 0x4c, 0x4b, 0x45, 0x4d, 0x5f, 0x31, 0x30, 0x32, 0x34, 0x10, 0x15, 0x12, 0x13,
+ 0x0a, 0x0f, 0x41, 0x4c, 0x47, 0x4f, 0x52, 0x49, 0x54, 0x48, 0x4d, 0x5f, 0x58, 0x57, 0x49, 0x4e,
+ 0x47, 0x10, 0x1e, 0x2a, 0x56, 0x0a, 0x09, 0x4b, 0x65, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
+ 0x12, 0x1a, 0x0a, 0x16, 0x4b, 0x45, 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55,
+ 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11,
+ 0x4b, 0x45, 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56,
+ 0x45, 0x10, 0x01, 0x12, 0x16, 0x0a, 0x12, 0x4b, 0x45, 0x59, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55,
+ 0x53, 0x5f, 0x52, 0x4f, 0x54, 0x41, 0x54, 0x45, 0x44, 0x10, 0x02, 0x2a, 0x94, 0x01, 0x0a, 0x07,
+ 0x4b, 0x65, 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x14, 0x4b, 0x45, 0x59, 0x5f, 0x4d,
+ 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10,
+ 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x4b, 0x45, 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x43, 0x4f,
+ 0x4e, 0x46, 0x49, 0x47, 0x5f, 0x52, 0x4f, 0x4f, 0x54, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x01, 0x12,
+ 0x1e, 0x0a, 0x1a, 0x4b, 0x45, 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x50, 0x52, 0x4f, 0x56,
+ 0x49, 0x44, 0x45, 0x52, 0x5f, 0x52, 0x4f, 0x4f, 0x54, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x02, 0x12,
+ 0x13, 0x0a, 0x0f, 0x4b, 0x45, 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x52, 0x45, 0x4d, 0x4f,
+ 0x54, 0x45, 0x10, 0x03, 0x12, 0x1c, 0x0a, 0x18, 0x4b, 0x45, 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x45,
+ 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x4f, 0x4e, 0x4c, 0x59,
+ 0x10, 0x04, 0x42, 0x82, 0x01, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63,
+ 0x79, 0x42, 0x0c, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50,
+ 0x01, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70,
+ 0x65, 0x6e, 0x74, 0x64, 0x66, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x70,
+ 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x67, 0x6f, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63,
+ 0x79, 0xa2, 0x02, 0x03, 0x50, 0x58, 0x58, 0xaa, 0x02, 0x06, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79,
+ 0xca, 0x02, 0x06, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0xe2, 0x02, 0x12, 0x50, 0x6f, 0x6c, 0x69,
+ 0x63, 0x79, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02,
+ 0x06, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
diff --git a/sdk/basekey.go b/sdk/basekey.go
index 5f3cc12004..2f159ba12d 100644
--- a/sdk/basekey.go
+++ b/sdk/basekey.go
@@ -33,6 +33,12 @@ func getKasKeyAlg(alg string) policy.Algorithm {
return policy.Algorithm_ALGORITHM_EC_P384
case string(ocrypto.EC521Key):
return policy.Algorithm_ALGORITHM_EC_P521
+ case string(ocrypto.MLKEM768Key):
+ return policy.Algorithm_ALGORITHM_MLKEM_768
+ case string(ocrypto.MLKEM1024Key):
+ return policy.Algorithm_ALGORITHM_MLKEM_1024
+ case string(ocrypto.HybridXWing):
+ return policy.Algorithm_ALGORITHM_XWING
default:
return policy.Algorithm_ALGORITHM_UNSPECIFIED
}
@@ -51,6 +57,12 @@ func formatAlg(alg policy.Algorithm) (string, error) {
return string(ocrypto.EC384Key), nil
case policy.Algorithm_ALGORITHM_EC_P521:
return string(ocrypto.EC521Key), nil
+ case policy.Algorithm_ALGORITHM_MLKEM_768:
+ return string(ocrypto.MLKEM768Key), nil
+ case policy.Algorithm_ALGORITHM_MLKEM_1024:
+ return string(ocrypto.MLKEM1024Key), nil
+ case policy.Algorithm_ALGORITHM_XWING:
+ return string(ocrypto.HybridXWing), nil
case policy.Algorithm_ALGORITHM_UNSPECIFIED:
fallthrough
default:
diff --git a/sdk/codegen/runner/generate.go b/sdk/codegen/runner/generate.go
index 211cedfdc4..0a8a88e197 100644
--- a/sdk/codegen/runner/generate.go
+++ b/sdk/codegen/runner/generate.go
@@ -177,12 +177,11 @@ func New%s%s%sConnectWrapper(httpClient connect.HTTPClient, baseURL string, opts
func generateInterfaceType(interfaceName string, methods []string, packageName, prefix, suffix string) string {
// Generate the interface type definition
var builder strings.Builder
- builder.WriteString(fmt.Sprintf(`
+ fmt.Fprintf(&builder, `
type %s%s%s interface {
-`, prefix, interfaceName, suffix))
+`, prefix, interfaceName, suffix)
for _, method := range methods {
- builder.WriteString(fmt.Sprintf(` %s(ctx context.Context, req *%s.%sRequest) (*%s.%sResponse, error)
-`, method, packageName, method, packageName, method))
+ fmt.Fprintf(&builder, " %s(ctx context.Context, req *%s.%sRequest) (*%s.%sResponse, error)\n", method, packageName, method, packageName, method)
}
builder.WriteString("}\n")
return builder.String()
diff --git a/sdk/experimental/tdf/keysplit/attributes.go b/sdk/experimental/tdf/keysplit/attributes.go
index e12d838e97..95d30e4da6 100644
--- a/sdk/experimental/tdf/keysplit/attributes.go
+++ b/sdk/experimental/tdf/keysplit/attributes.go
@@ -199,6 +199,12 @@ func formatAlgorithm(alg policy.Algorithm) string {
return "rsa:2048"
case policy.Algorithm_ALGORITHM_RSA_4096:
return "rsa:4096"
+ case policy.Algorithm_ALGORITHM_MLKEM_768:
+ return "mlkem:768"
+ case policy.Algorithm_ALGORITHM_MLKEM_1024:
+ return "mlkem:1024"
+ case policy.Algorithm_ALGORITHM_XWING:
+ return "hpqt:xwing"
default:
return unknownAlgorithm
}
@@ -217,6 +223,12 @@ func convertAlgEnum2Simple(a policy.KasPublicKeyAlgEnum) policy.Algorithm {
return policy.Algorithm_ALGORITHM_RSA_2048
case policy.KasPublicKeyAlgEnum_KAS_PUBLIC_KEY_ALG_ENUM_RSA_4096:
return policy.Algorithm_ALGORITHM_RSA_4096
+ case policy.KasPublicKeyAlgEnum_KAS_PUBLIC_KEY_ALG_ENUM_MLKEM_768:
+ return policy.Algorithm_ALGORITHM_MLKEM_768
+ case policy.KasPublicKeyAlgEnum_KAS_PUBLIC_KEY_ALG_ENUM_MLKEM_1024:
+ return policy.Algorithm_ALGORITHM_MLKEM_1024
+ case policy.KasPublicKeyAlgEnum_KAS_PUBLIC_KEY_ALG_ENUM_XWING:
+ return policy.Algorithm_ALGORITHM_XWING
case policy.KasPublicKeyAlgEnum_KAS_PUBLIC_KEY_ALG_ENUM_UNSPECIFIED:
return policy.Algorithm_ALGORITHM_UNSPECIFIED
default:
diff --git a/sdk/granter.go b/sdk/granter.go
index 8275a04f42..a50f6299fd 100644
--- a/sdk/granter.go
+++ b/sdk/granter.go
@@ -286,6 +286,12 @@ func convertAlgEnum2Simple(a policy.KasPublicKeyAlgEnum) policy.Algorithm {
return policy.Algorithm_ALGORITHM_RSA_2048
case policy.KasPublicKeyAlgEnum_KAS_PUBLIC_KEY_ALG_ENUM_RSA_4096:
return policy.Algorithm_ALGORITHM_RSA_4096
+ case policy.KasPublicKeyAlgEnum_KAS_PUBLIC_KEY_ALG_ENUM_MLKEM_768:
+ return policy.Algorithm_ALGORITHM_MLKEM_768
+ case policy.KasPublicKeyAlgEnum_KAS_PUBLIC_KEY_ALG_ENUM_MLKEM_1024:
+ return policy.Algorithm_ALGORITHM_MLKEM_1024
+ case policy.KasPublicKeyAlgEnum_KAS_PUBLIC_KEY_ALG_ENUM_XWING:
+ return policy.Algorithm_ALGORITHM_XWING
case policy.KasPublicKeyAlgEnum_KAS_PUBLIC_KEY_ALG_ENUM_UNSPECIFIED:
return policy.Algorithm_ALGORITHM_UNSPECIFIED
default:
@@ -306,6 +312,12 @@ func convertStringToAlgorithm(alg string) policy.Algorithm {
return policy.Algorithm_ALGORITHM_RSA_2048
case ocrypto.RSA4096Key:
return policy.Algorithm_ALGORITHM_RSA_4096
+ case ocrypto.MLKEM768Key:
+ return policy.Algorithm_ALGORITHM_MLKEM_768
+ case ocrypto.MLKEM1024Key:
+ return policy.Algorithm_ALGORITHM_MLKEM_1024
+ case ocrypto.HybridXWing:
+ return policy.Algorithm_ALGORITHM_XWING
default:
return policy.Algorithm_ALGORITHM_UNSPECIFIED
}
@@ -490,6 +502,12 @@ func algProto2String(e policy.KasPublicKeyAlgEnum) string {
return string(ocrypto.RSA2048Key)
case policy.KasPublicKeyAlgEnum_KAS_PUBLIC_KEY_ALG_ENUM_RSA_4096:
return string(ocrypto.RSA4096Key)
+ case policy.KasPublicKeyAlgEnum_KAS_PUBLIC_KEY_ALG_ENUM_MLKEM_768:
+ return string(ocrypto.MLKEM768Key)
+ case policy.KasPublicKeyAlgEnum_KAS_PUBLIC_KEY_ALG_ENUM_MLKEM_1024:
+ return string(ocrypto.MLKEM1024Key)
+ case policy.KasPublicKeyAlgEnum_KAS_PUBLIC_KEY_ALG_ENUM_XWING:
+ return string(ocrypto.HybridXWing)
case policy.KasPublicKeyAlgEnum_KAS_PUBLIC_KEY_ALG_ENUM_UNSPECIFIED:
return ""
}
@@ -508,6 +526,12 @@ func algProto2OcryptoKeyType(e policy.Algorithm) ocrypto.KeyType {
return ocrypto.RSA2048Key
case policy.Algorithm_ALGORITHM_RSA_4096:
return ocrypto.RSA4096Key
+ case policy.Algorithm_ALGORITHM_MLKEM_768:
+ return ocrypto.MLKEM768Key
+ case policy.Algorithm_ALGORITHM_MLKEM_1024:
+ return ocrypto.MLKEM1024Key
+ case policy.Algorithm_ALGORITHM_XWING:
+ return ocrypto.HybridXWing
case policy.Algorithm_ALGORITHM_UNSPECIFIED:
return ocrypto.KeyType("")
default:
diff --git a/sdk/tdf.go b/sdk/tdf.go
index db22208b5f..760677e3e9 100644
--- a/sdk/tdf.go
+++ b/sdk/tdf.go
@@ -43,6 +43,8 @@ const (
kKeySize = 32
kWrapped = "wrapped"
kECWrapped = "ec-wrapped"
+ kMLKEMWrapped = "mlkem-wrapped"
+ kHybrid = "hybrid"
kKasProtocol = "kas"
kSplitKeyType = "split"
kGCMCipherAlgorithm = "AES-256-GCM"
@@ -674,7 +676,8 @@ func createKeyAccess(kasInfo KASInfo, symKey []byte, policyBinding PolicyBinding
}
ktype := ocrypto.KeyType(kasInfo.Algorithm)
- if ocrypto.IsECKeyType(ktype) {
+ switch {
+ case ocrypto.IsECKeyType(ktype):
mode, err := ocrypto.ECKeyTypeToMode(ktype)
if err != nil {
return KeyAccess{}, err
@@ -686,7 +689,23 @@ func createKeyAccess(kasInfo KASInfo, symKey []byte, policyBinding PolicyBinding
keyAccess.KeyType = kECWrapped
keyAccess.WrappedKey = wrappedKeyInfo.wrappedKey
keyAccess.EphemeralPublicKey = wrappedKeyInfo.publicKey
- } else {
+ case ktype == ocrypto.MLKEM768Key, ktype == ocrypto.MLKEM1024Key:
+ wrappedKey, encapsulatedKey, err := generateWrapKeyWithMLKEM(kasInfo.PublicKey, symKey)
+ if err != nil {
+ return KeyAccess{}, err
+ }
+ keyAccess.KeyType = kMLKEMWrapped
+ keyAccess.WrappedKey = wrappedKey
+ keyAccess.EphemeralPublicKey = encapsulatedKey
+ case ktype == ocrypto.HybridXWing:
+ wrappedKey, encapsulatedKey, err := generateWrapKeyWithMLKEM(kasInfo.PublicKey, symKey)
+ if err != nil {
+ return KeyAccess{}, err
+ }
+ keyAccess.KeyType = kHybrid
+ keyAccess.WrappedKey = wrappedKey
+ keyAccess.EphemeralPublicKey = encapsulatedKey
+ default:
wrappedKey, err := generateWrapKeyWithRSA(kasInfo.PublicKey, symKey)
if err != nil {
return KeyAccess{}, err
@@ -761,6 +780,25 @@ func generateWrapKeyWithRSA(publicKey string, symKey []byte) (string, error) {
return string(ocrypto.Base64Encode(wrappedKey)), nil
}
+func generateWrapKeyWithMLKEM(publicKey string, symKey []byte) (string, string, error) {
+ publicKeyEncryptor, err := ocrypto.FromPublicPEM(publicKey)
+ if err != nil {
+ return "", "", fmt.Errorf("generateWrapKeyWithMLKEM: ocrypto.FromPublicPEM failed:%w", err)
+ }
+
+ wrappedKey, err := publicKeyEncryptor.Encrypt(symKey)
+ if err != nil {
+ return "", "", fmt.Errorf("generateWrapKeyWithMLKEM: encrypt failed:%w", err)
+ }
+
+ encapsulatedKey := publicKeyEncryptor.EphemeralKey()
+ if len(encapsulatedKey) == 0 {
+ return "", "", errors.New("generateWrapKeyWithMLKEM: encapsulated key missing")
+ }
+
+ return string(ocrypto.Base64Encode(wrappedKey)), string(ocrypto.Base64Encode(encapsulatedKey)), nil
+}
+
// create policy object
func createPolicyObject(attributes []AttributeValueFQN) (PolicyObject, error) {
uuidObj, err := uuid.NewUUID()
diff --git a/service/internal/security/basic_manager.go b/service/internal/security/basic_manager.go
index 6197e50eb3..78ba5b92e5 100644
--- a/service/internal/security/basic_manager.go
+++ b/service/internal/security/basic_manager.go
@@ -97,6 +97,26 @@ func (b *BasicManager) Decrypt(ctx context.Context, keyDetails trust.KeyDetails,
return nil, fmt.Errorf("failed to create protected key: %w", err)
}
return protectedKey, nil
+ case ocrypto.MLKEM768Key, ocrypto.MLKEM1024Key:
+ plaintext, err := decrypter.DecryptWithEphemeralKey(ciphertext, ephemeralPublicKey)
+ if err != nil {
+ return nil, fmt.Errorf("failed to decrypt with ML-KEM: %w", err)
+ }
+ protectedKey, err := ocrypto.NewAESProtectedKey(plaintext)
+ if err != nil {
+ return nil, fmt.Errorf("failed to create protected key: %w", err)
+ }
+ return protectedKey, nil
+ case ocrypto.HybridXWing:
+ plaintext, err := decrypter.DecryptWithEphemeralKey(ciphertext, ephemeralPublicKey)
+ if err != nil {
+ return nil, fmt.Errorf("failed to decrypt with X-Wing hybrid: %w", err)
+ }
+ protectedKey, err := ocrypto.NewAESProtectedKey(plaintext)
+ if err != nil {
+ return nil, fmt.Errorf("failed to create protected key: %w", err)
+ }
+ return protectedKey, nil
}
return nil, fmt.Errorf("unsupported algorithm: %s", keyDetails.Algorithm())
diff --git a/service/internal/security/crypto_provider.go b/service/internal/security/crypto_provider.go
index 24f0f3c2ea..8640bbdd97 100644
--- a/service/internal/security/crypto_provider.go
+++ b/service/internal/security/crypto_provider.go
@@ -11,4 +11,11 @@ const (
// Used for encryption with RSA of the KAO
AlgorithmRSA2048 = "rsa:2048"
AlgorithmRSA4096 = "rsa:4096"
+
+ // Used for encryption with ML-KEM of the KAO
+ AlgorithmMLKEM768 = "mlkem:768"
+ AlgorithmMLKEM1024 = "mlkem:1024"
+
+ // Used for hybrid PQ/T encryption with X-Wing (X25519 + ML-KEM-768)
+ AlgorithmXWing = "hpqt:xwing"
)
diff --git a/service/internal/security/in_process_provider.go b/service/internal/security/in_process_provider.go
index 67c86487aa..619315ce6c 100644
--- a/service/internal/security/in_process_provider.go
+++ b/service/internal/security/in_process_provider.go
@@ -2,7 +2,6 @@ package security
import (
"context"
- "crypto"
"crypto/elliptic"
"crypto/x509"
"encoding/pem"
@@ -80,11 +79,7 @@ func (k *KeyDetailsAdapter) ExportPublicKey(_ context.Context, format trust.KeyT
return jwkKey, nil
case trust.KeyTypePKCS8:
- // Try to get the key as an RSA key first
- if rsaKey, err := k.cryptoProvider.RSAPublicKey(kid); err == nil {
- return rsaKey, nil
- }
- return k.cryptoProvider.ECPublicKey(kid)
+ return k.cryptoProvider.PublicKey(kid)
default:
return "", ErrCertNotFound
}
@@ -92,8 +87,11 @@ func (k *KeyDetailsAdapter) ExportPublicKey(_ context.Context, format trust.KeyT
func (k *KeyDetailsAdapter) ExportCertificate(_ context.Context) (string, error) {
kid := string(k.id)
- if k.algorithm == AlgorithmECP256R1 {
+ switch k.algorithm {
+ case AlgorithmECP256R1, AlgorithmECP384R1, AlgorithmECP521R1:
return k.cryptoProvider.ECCertificate(kid)
+ case ocrypto.RSA2048Key, ocrypto.RSA4096Key, ocrypto.MLKEM768Key, ocrypto.MLKEM1024Key, ocrypto.HybridXWing:
+ return "", errors.New("certificates only available for EC keys")
}
return "", errors.New("certificates only available for EC keys")
}
@@ -170,31 +168,29 @@ func (a *InProcessProvider) FindKeyByAlgorithm(_ context.Context, algorithm stri
// FindKeyByID finds a key by ID
func (a *InProcessProvider) FindKeyByID(_ context.Context, id trust.KeyIdentifier) (trust.KeyDetails, error) {
- // Try to determine the algorithm by checking if the key works with known algorithms
- for _, alg := range []string{AlgorithmECP256R1, AlgorithmRSA2048} {
- // This is a hack since the original provider doesn't have a way to check if a key exists
- switch alg {
- case AlgorithmECP256R1:
- if _, err := a.cryptoProvider.ECPublicKey(string(id)); err == nil {
- return &KeyDetailsAdapter{
- id: id,
- algorithm: ocrypto.KeyType(alg),
- legacy: a.legacyKeys[string(id)],
- cryptoProvider: a.cryptoProvider,
- }, nil
- }
- case AlgorithmRSA2048:
- if _, err := a.cryptoProvider.RSAPublicKey(string(id)); err == nil {
- return &KeyDetailsAdapter{
- id: id,
- algorithm: ocrypto.KeyType(alg),
- legacy: a.legacyKeys[string(id)],
- cryptoProvider: a.cryptoProvider,
- }, nil
- }
- }
+ key, ok := a.cryptoProvider.keysByID[string(id)]
+ if !ok {
+ return nil, ErrCertNotFound
+ }
+
+ switch key := key.(type) {
+ case StandardECCrypto:
+ return &KeyDetailsAdapter{
+ id: id,
+ algorithm: ocrypto.KeyType(key.Algorithm),
+ legacy: a.legacyKeys[string(id)],
+ cryptoProvider: a.cryptoProvider,
+ }, nil
+ case PrivateKeyCrypto:
+ return &KeyDetailsAdapter{
+ id: id,
+ algorithm: ocrypto.KeyType(key.Algorithm),
+ legacy: a.legacyKeys[string(id)],
+ cryptoProvider: a.cryptoProvider,
+ }, nil
+ default:
+ return nil, ErrCertNotFound
}
- return nil, ErrCertNotFound
}
// ListKeys lists all available keys
@@ -203,32 +199,36 @@ func (a *InProcessProvider) ListKeys(ctx context.Context) ([]trust.KeyDetails, e
}
func (a *InProcessProvider) ListKeysWith(ctx context.Context, opts trust.ListKeyOptions) ([]trust.KeyDetails, error) {
- // This is a limited implementation as CryptoProvider doesn't expose a list of all keys
var keys []trust.KeyDetails
- // Try to find keys for known algorithms
- for _, alg := range []string{AlgorithmRSA2048, AlgorithmECP256R1} {
- if kids, err := a.cryptoProvider.ListKIDsByAlgorithm(alg); err == nil && len(kids) > 0 {
- for _, kid := range kids {
- if opts.LegacyOnly && !a.legacyKeys[kid] {
- continue // Skip non-legacy keys if LegacyOnly is true
- }
- keys = append(keys, &KeyDetailsAdapter{
- id: trust.KeyIdentifier(kid),
- algorithm: ocrypto.KeyType(alg),
- cryptoProvider: a.cryptoProvider,
- legacy: a.legacyKeys[kid],
- })
- }
- } else if err != nil {
+ for kid, key := range a.cryptoProvider.keysByID {
+ if opts.LegacyOnly && !a.legacyKeys[kid] {
+ continue
+ }
+
+ var algorithm ocrypto.KeyType
+ switch key := key.(type) {
+ case StandardECCrypto:
+ algorithm = ocrypto.KeyType(key.Algorithm)
+ case PrivateKeyCrypto:
+ algorithm = ocrypto.KeyType(key.Algorithm)
+ default:
if a.logger != nil {
a.logger.WarnContext(ctx,
- "failed to list keys by algorithm",
- slog.String("algorithm", alg),
- slog.Any("error", err),
+ "failed to list key with unsupported type",
+ slog.String("kid", kid),
+ slog.Any("type", fmt.Sprintf("%T", key)),
)
}
+ continue
}
+
+ keys = append(keys, &KeyDetailsAdapter{
+ id: trust.KeyIdentifier(kid),
+ algorithm: algorithm,
+ cryptoProvider: a.cryptoProvider,
+ legacy: a.legacyKeys[kid],
+ })
}
return keys, nil
@@ -237,30 +237,25 @@ func (a *InProcessProvider) ListKeysWith(ctx context.Context, opts trust.ListKey
// Decrypt implements the unified decryption method for both RSA and EC
func (a *InProcessProvider) Decrypt(ctx context.Context, keyDetails trust.KeyDetails, ciphertext []byte, ephemeralPublicKey []byte) (ocrypto.ProtectedKey, error) {
kid := string(keyDetails.ID())
-
- var protectedKey ocrypto.ProtectedKey
- var err error
-
- // Try to determine the key type
- keyType, err := a.determineKeyType(ctx, kid)
- if err != nil {
- return nil, err
+ key, ok := a.cryptoProvider.keysByID[kid]
+ if !ok {
+ return nil, ErrCertNotFound
}
var rawKey []byte
- switch keyType {
- case AlgorithmRSA2048:
- if len(ephemeralPublicKey) > 0 {
- return nil, errors.New("ephemeral public key should not be provided for RSA decryption")
- }
- rawKey, err = a.cryptoProvider.RSADecrypt(crypto.SHA1, kid, "", ciphertext)
-
- case AlgorithmECP256R1:
+ var err error
+ switch key := key.(type) {
+ case StandardECCrypto:
if len(ephemeralPublicKey) == 0 {
return nil, errors.New("ephemeral public key is required for EC decryption")
}
- protectedKey, err = a.cryptoProvider.ECDecrypt(ctx, kid, ephemeralPublicKey, ciphertext)
-
+ protectedKey, err := a.cryptoProvider.ECDecrypt(ctx, kid, ephemeralPublicKey, ciphertext)
+ if err != nil {
+ return nil, err
+ }
+ return protectedKey, nil
+ case PrivateKeyCrypto:
+ rawKey, err = key.dec.DecryptWithEphemeralKey(ciphertext, ephemeralPublicKey)
default:
return nil, errors.New("unsupported key algorithm")
}
@@ -268,15 +263,7 @@ func (a *InProcessProvider) Decrypt(ctx context.Context, keyDetails trust.KeyDet
if err != nil {
return nil, err
}
-
- if protectedKey == nil {
- protectedKey, err = ocrypto.NewAESProtectedKey(rawKey)
- if err != nil {
- return nil, fmt.Errorf("failed to create protected key: %w", err)
- }
- }
-
- return protectedKey, nil
+ return ocrypto.NewAESProtectedKey(rawKey)
}
// DeriveKey computes an ECDH shared secret and derives an AES key via HKDF.
@@ -334,19 +321,3 @@ func (a *InProcessProvider) GenerateECSessionKey(_ context.Context, ephemeralPub
func (a *InProcessProvider) Close() {
a.cryptoProvider.Close()
}
-
-// determineKeyType tries to determine the algorithm of a key based on its ID
-// This is a helper method for the Decrypt method
-func (a *InProcessProvider) determineKeyType(_ context.Context, kid string) (string, error) {
- // First try RSA
- if _, err := a.cryptoProvider.RSAPublicKey(kid); err == nil {
- return AlgorithmRSA2048, nil
- }
-
- // Then try EC
- if _, err := a.cryptoProvider.ECPublicKey(kid); err == nil {
- return AlgorithmECP256R1, nil
- }
-
- return "", errors.New("could not determine key type")
-}
diff --git a/service/internal/security/standard_crypto.go b/service/internal/security/standard_crypto.go
index 6b86abdcbe..c80df2f5f7 100644
--- a/service/internal/security/standard_crypto.go
+++ b/service/internal/security/standard_crypto.go
@@ -52,10 +52,10 @@ type StandardKeyInfo struct {
PublicKeyPath string `mapstructure:"public_key_path" json:"public_key_path"`
}
-type StandardRSACrypto struct {
+type PrivateKeyCrypto struct {
KeyPairInfo
- asymDecryption ocrypto.AsymDecryption
- asymEncryption ocrypto.AsymEncryption
+ dec ocrypto.PrivateKeyDecryptor
+ enc ocrypto.PublicKeyEncryptor
}
type StandardECCrypto struct {
@@ -150,23 +150,19 @@ func loadKey(k KeyPairInfo) (any, error) {
ecPrivateKeyPem: string(privatePEM),
ecCertificatePEM: string(certPEM),
}, nil
- case AlgorithmRSA2048, AlgorithmRSA4096:
- asymDecryption, err := ocrypto.NewAsymDecryption(string(privatePEM))
+ case AlgorithmRSA2048, AlgorithmRSA4096, AlgorithmMLKEM768, AlgorithmMLKEM1024, AlgorithmXWing:
+ decrypter, err := ocrypto.FromPrivatePEM(string(privatePEM))
if err != nil {
- return nil, fmt.Errorf("ocrypto.NewAsymDecryption failed: %w", err)
+ return nil, fmt.Errorf("ocrypto.FromPrivatePEM failed: %w", err)
}
publicKeyEncryptor, err := ocrypto.FromPublicPEM(string(certPEM))
if err != nil {
return nil, fmt.Errorf("ocrypto.FromPublicPEM failed: %w", err)
}
- asymEncryption, ok := publicKeyEncryptor.(*ocrypto.AsymEncryption)
- if !ok {
- return nil, fmt.Errorf("unexpected public key encryptor type: %T", publicKeyEncryptor)
- }
- return StandardRSACrypto{
- KeyPairInfo: k,
- asymDecryption: asymDecryption,
- asymEncryption: *asymEncryption,
+ return PrivateKeyCrypto{
+ KeyPairInfo: k,
+ dec: decrypter,
+ enc: publicKeyEncryptor,
}, nil
default:
return nil, errors.New("unsupported algorithm [" + k.Algorithm + "]")
@@ -199,25 +195,20 @@ func loadDeprecatedKeys(rsaKeys map[string]StandardKeyInfo, ecKeys map[string]St
if err != nil {
return nil, fmt.Errorf("failed to rsa public key file: %w", err)
}
-
publicKeyEncryptor, err := ocrypto.FromPublicPEM(string(publicPemData))
if err != nil {
return nil, fmt.Errorf("ocrypto.FromPublicPEM failed: %w", err)
}
- asymEncryption, ok := publicKeyEncryptor.(*ocrypto.AsymEncryption)
- if !ok {
- return nil, fmt.Errorf("unexpected public key encryptor type: %T", publicKeyEncryptor)
- }
- k := StandardRSACrypto{
+ k := PrivateKeyCrypto{
KeyPairInfo: KeyPairInfo{
Algorithm: AlgorithmRSA2048,
KID: id,
Private: kasInfo.PrivateKeyPath,
Certificate: kasInfo.PublicKeyPath,
},
- asymDecryption: asymDecryption,
- asymEncryption: *asymEncryption,
+ dec: asymDecryption,
+ enc: publicKeyEncryptor,
}
keysByAlg[AlgorithmRSA2048][id] = k
keysByID[id] = k
@@ -266,22 +257,26 @@ func (s StandardCrypto) FindKID(alg string) string {
return ""
}
-func (s StandardCrypto) RSAPublicKey(kid string) (string, error) {
+func (s StandardCrypto) PublicKey(kid string) (string, error) {
k, ok := s.keysByID[kid]
if !ok {
- return "", fmt.Errorf("no rsa key with id [%s]: %w", kid, ErrCertNotFound)
- }
- rsa, ok := k.(StandardRSACrypto)
- if !ok {
- return "", fmt.Errorf("key with id [%s] is not an RSA key: %w", kid, ErrCertNotFound)
+ return "", fmt.Errorf("no public key with id [%s]: %w", kid, ErrCertNotFound)
}
-
- pem, err := rsa.asymEncryption.PublicKeyInPemFormat()
- if err != nil {
- return "", fmt.Errorf("failed to retrieve rsa public key file: %w", err)
+ switch key := k.(type) {
+ case PrivateKeyCrypto:
+ publicKeyPEM, err := key.enc.PublicKeyInPemFormat()
+ if err != nil {
+ return "", fmt.Errorf("failed to retrieve public key file: %w", err)
+ }
+ return publicKeyPEM, nil
+ case StandardECCrypto:
+ if key.ecCertificatePEM != "" {
+ return key.ecCertificatePEM, nil
+ }
+ return s.ECPublicKey(kid)
+ default:
+ return "", fmt.Errorf("key with id [%s] does not expose a public key: %w", kid, ErrCertNotFound)
}
-
- return pem, nil
}
func (s StandardCrypto) ECCertificate(kid string) (string, error) {
@@ -334,12 +329,12 @@ func (s StandardCrypto) RSADecrypt(_ crypto.Hash, kid string, _ string, cipherte
if !ok {
return nil, ErrCertNotFound
}
- rsa, ok := k.(StandardRSACrypto)
+ rsa, ok := k.(PrivateKeyCrypto)
if !ok {
return nil, ErrCertNotFound
}
- data, err := rsa.asymDecryption.Decrypt(ciphertext)
+ data, err := rsa.dec.Decrypt(ciphertext)
if err != nil {
return nil, fmt.Errorf("error decrypting data: %w", err)
}
@@ -355,12 +350,17 @@ func (s StandardCrypto) RSAPublicKeyAsJSON(kid string) (string, error) {
if !ok {
return "", ErrCertNotFound
}
- rsa, ok := k.(StandardRSACrypto)
+ rsa, ok := k.(PrivateKeyCrypto)
if !ok {
return "", ErrCertNotFound
}
- rsaPublicKeyJwk, err := jwk.FromRaw(rsa.asymEncryption.PublicKey)
+ asymEncryption, ok := rsa.enc.(*ocrypto.AsymEncryption)
+ if !ok {
+ return "", fmt.Errorf("key with id [%s] does not support JWK export: %w", kid, ErrCertNotFound)
+ }
+
+ rsaPublicKeyJwk, err := jwk.FromRaw(asymEncryption.PublicKey)
if err != nil {
return "", fmt.Errorf("jwk.FromRaw: %w", err)
}
@@ -429,12 +429,8 @@ func (s *StandardCrypto) Decrypt(_ context.Context, keyID trust.KeyIdentifier, c
return nil, fmt.Errorf("failed to decrypt with ephemeral key: %w", err)
}
- case StandardRSACrypto:
- if len(ephemeralPublicKey) > 0 {
- return nil, errors.New("ephemeral public key should not be provided for RSA decryption")
- }
-
- rawKey, err = key.asymDecryption.Decrypt(ciphertext)
+ case PrivateKeyCrypto:
+ rawKey, err = key.dec.DecryptWithEphemeralKey(ciphertext, ephemeralPublicKey)
if err != nil {
return nil, fmt.Errorf("error decrypting data: %w", err)
}
diff --git a/service/kas/access/publicKey.go b/service/kas/access/publicKey.go
index eb5b1fe780..08b8d66818 100644
--- a/service/kas/access/publicKey.go
+++ b/service/kas/access/publicKey.go
@@ -149,11 +149,11 @@ func (p *Provider) PublicKey(ctx context.Context, req *connect.Request[kaspb.Pub
}
switch algorithm {
- case security.AlgorithmECP256R1:
+ case security.AlgorithmECP256R1, security.AlgorithmECP384R1, security.AlgorithmECP521R1:
// For EC keys, export the public key
ecPublicKeyPem, err := keyDetails.ExportPublicKey(ctx, trust.KeyTypePKCS8)
return r(ecPublicKeyPem, kid, err)
- case security.AlgorithmRSA2048:
+ case security.AlgorithmMLKEM768, security.AlgorithmMLKEM1024, security.AlgorithmXWing, security.AlgorithmRSA2048, security.AlgorithmRSA4096:
fallthrough
case "":
switch fmt {
diff --git a/service/kas/access/rewrap.go b/service/kas/access/rewrap.go
index d62975a480..78ebe0a62e 100644
--- a/service/kas/access/rewrap.go
+++ b/service/kas/access/rewrap.go
@@ -667,6 +667,28 @@ func (p *Provider) verifyRewrapRequests(ctx context.Context, req *kaspb.Unsigned
var dek ocrypto.ProtectedKey
var err error
switch kao.GetKeyAccessObject().GetKeyType() {
+ case string(ocrypto.MLKEM), string(ocrypto.Hybrid):
+ ephemeralCiphertext := kao.GetKeyAccessObject().GetEphemeralPublicKey()
+ if ephemeralCiphertext == "" {
+ p.Logger.WarnContext(ctx, "missing encapsulated key for kem rewrap")
+ failedKAORewrap(results, kao, err400("bad request"))
+ continue
+ }
+
+ encapsulatedKey, err := ocrypto.Base64Decode([]byte(ephemeralCiphertext))
+ if err != nil {
+ p.Logger.WarnContext(ctx, "failed to decode encapsulated key for kem rewrap", slog.Any("error", err))
+ failedKAORewrap(results, kao, err400("bad request"))
+ continue
+ }
+
+ kid := trust.KeyIdentifier(kao.GetKeyAccessObject().GetKid())
+ dek, err = p.KeyDelegator.Decrypt(ctx, kid, kao.GetKeyAccessObject().GetWrappedKey(), encapsulatedKey)
+ if err != nil {
+ p.Logger.WarnContext(ctx, "failed to decrypt KEM key", slog.Any("error", err))
+ failedKAORewrap(results, kao, err400("bad request"))
+ continue
+ }
case "ec-wrapped":
if !p.ECTDFEnabled && !p.Preview.ECTDFEnabled {
diff --git a/service/kas/key_indexer.go b/service/kas/key_indexer.go
index 021b3f418a..20d24a91c0 100644
--- a/service/kas/key_indexer.go
+++ b/service/kas/key_indexer.go
@@ -58,6 +58,12 @@ func convertEnumToAlg(alg policy.Algorithm) ocrypto.KeyType {
return ocrypto.EC384Key
case policy.Algorithm_ALGORITHM_EC_P521:
return ocrypto.EC521Key
+ case policy.Algorithm_ALGORITHM_MLKEM_768:
+ return ocrypto.MLKEM768Key
+ case policy.Algorithm_ALGORITHM_MLKEM_1024:
+ return ocrypto.MLKEM1024Key
+ case policy.Algorithm_ALGORITHM_XWING:
+ return ocrypto.HybridXWing
case policy.Algorithm_ALGORITHM_UNSPECIFIED:
fallthrough
default:
@@ -77,6 +83,12 @@ func convertAlgToEnum(alg string) (policy.Algorithm, error) {
return policy.Algorithm_ALGORITHM_EC_P384, nil
case string(ocrypto.EC521Key):
return policy.Algorithm_ALGORITHM_EC_P521, nil
+ case string(ocrypto.MLKEM768Key):
+ return policy.Algorithm_ALGORITHM_MLKEM_768, nil
+ case string(ocrypto.MLKEM1024Key):
+ return policy.Algorithm_ALGORITHM_MLKEM_1024, nil
+ case string(ocrypto.HybridXWing):
+ return policy.Algorithm_ALGORITHM_XWING, nil
default:
return policy.Algorithm_ALGORITHM_UNSPECIFIED, fmt.Errorf("unsupported algorithm: %s", alg)
}
diff --git a/service/pkg/db/marshalHelpers.go b/service/pkg/db/marshalHelpers.go
index 667ab27e21..1953fc8815 100644
--- a/service/pkg/db/marshalHelpers.go
+++ b/service/pkg/db/marshalHelpers.go
@@ -157,6 +157,12 @@ func FormatAlg(alg policy.Algorithm) (string, error) {
return "ec:secp384r1", nil
case policy.Algorithm_ALGORITHM_EC_P521:
return "ec:secp521r1", nil
+ case policy.Algorithm_ALGORITHM_MLKEM_768:
+ return "mlkem:768", nil
+ case policy.Algorithm_ALGORITHM_MLKEM_1024:
+ return "mlkem:1024", nil
+ case policy.Algorithm_ALGORITHM_XWING:
+ return "hpqt:xwing", nil
case policy.Algorithm_ALGORITHM_UNSPECIFIED:
fallthrough
default:
diff --git a/service/policy/db/grant_mappings.go b/service/policy/db/grant_mappings.go
index 7c3688af58..7e68e11aa7 100644
--- a/service/policy/db/grant_mappings.go
+++ b/service/policy/db/grant_mappings.go
@@ -22,6 +22,12 @@ func mapAlgorithmToKasPublicKeyAlg(alg policy.Algorithm) policy.KasPublicKeyAlgE
return policy.KasPublicKeyAlgEnum_KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP384R1
case policy.Algorithm_ALGORITHM_EC_P521: // ALGORITHM_EC_P521 is an alias
return policy.KasPublicKeyAlgEnum_KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP521R1
+ case policy.Algorithm_ALGORITHM_MLKEM_768:
+ return policy.KasPublicKeyAlgEnum_KAS_PUBLIC_KEY_ALG_ENUM_MLKEM_768
+ case policy.Algorithm_ALGORITHM_MLKEM_1024:
+ return policy.KasPublicKeyAlgEnum_KAS_PUBLIC_KEY_ALG_ENUM_MLKEM_1024
+ case policy.Algorithm_ALGORITHM_XWING:
+ return policy.KasPublicKeyAlgEnum_KAS_PUBLIC_KEY_ALG_ENUM_XWING
case policy.Algorithm_ALGORITHM_UNSPECIFIED:
return policy.KasPublicKeyAlgEnum_KAS_PUBLIC_KEY_ALG_ENUM_UNSPECIFIED
default:
diff --git a/service/policy/kasregistry/key_access_server_registry.proto b/service/policy/kasregistry/key_access_server_registry.proto
index f7c4bdf7f8..ae65fa19f9 100644
--- a/service/policy/kasregistry/key_access_server_registry.proto
+++ b/service/policy/kasregistry/key_access_server_registry.proto
@@ -403,7 +403,7 @@ message CreateKeyRequest {
Algorithm key_algorithm = 3 [(buf.validate.field).cel = {
id: "key_algorithm_defined"
message: "The key_algorithm must be one of the defined values."
- expression: "this in [1, 2, 3, 4, 5]" // Allow ALGORITHM_RSA_2048, ALGORITHM_RSA_4096, ALGORITHM_EC_P256, ALGORITHM_EC_P384, ALGORITHM_EC_P521
+ expression: "this in [1, 2, 3, 4, 5, 20, 21]" // Allow RSA, EC, and ML-KEM algorithms
}]; // The algorithm to be used for the key
// Required
KeyMode key_mode = 4 [(buf.validate.field).cel = {
@@ -550,7 +550,7 @@ message RotateKeyRequest {
Algorithm algorithm = 2 [(buf.validate.field).cel = {
id: "key_algorithm_defined"
message: "The key_algorithm must be one of the defined values."
- expression: "this in [1, 2, 3, 4, 5]" // Allow ALGORITHM_RSA_2048, ALGORITHM_RSA_4096, ALGORITHM_EC_P256, ALGORITHM_EC_P384, ALGORITHM_EC_P521
+ expression: "this in [1, 2, 3, 4, 5, 20, 21]" // Allow RSA, EC, and ML-KEM algorithms
}];
// Required
KeyMode key_mode = 3 [
diff --git a/service/policy/objects.proto b/service/policy/objects.proto
index a54bc2517a..d4ccd939ad 100644
--- a/service/policy/objects.proto
+++ b/service/policy/objects.proto
@@ -388,6 +388,9 @@ enum KasPublicKeyAlgEnum {
KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP256R1 = 5;
KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP384R1 = 6;
KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP521R1 = 7;
+ KAS_PUBLIC_KEY_ALG_ENUM_MLKEM_768 = 20;
+ KAS_PUBLIC_KEY_ALG_ENUM_MLKEM_1024 = 21;
+ KAS_PUBLIC_KEY_ALG_ENUM_XWING = 30;
}
// Deprecated
@@ -553,6 +556,9 @@ enum Algorithm {
ALGORITHM_EC_P256 = 3;
ALGORITHM_EC_P384 = 4;
ALGORITHM_EC_P521 = 5;
+ ALGORITHM_MLKEM_768 = 20;
+ ALGORITHM_MLKEM_1024 = 21;
+ ALGORITHM_XWING = 30;
}
// The status of the key