1 // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 // Copyright by contributors to this project.
3 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
4 
5 use crate::error::IntoAnyError;
6 use alloc::vec;
7 use alloc::vec::Vec;
8 use core::{
9     fmt::{self, Debug},
10     ops::Deref,
11 };
12 use mls_rs_codec::{MlsDecode, MlsEncode, MlsSize};
13 use zeroize::{ZeroizeOnDrop, Zeroizing};
14 
15 mod cipher_suite;
16 pub use self::cipher_suite::*;
17 
18 #[cfg(feature = "test_suite")]
19 pub mod test_suite;
20 
21 #[derive(Clone, PartialEq, Eq, MlsSize, MlsEncode, MlsDecode)]
22 #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
23 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
24 /// Ciphertext produced by [`CipherSuiteProvider::hpke_seal`]
25 pub struct HpkeCiphertext {
26     #[mls_codec(with = "mls_rs_codec::byte_vec")]
27     #[cfg_attr(feature = "serde", serde(with = "crate::vec_serde"))]
28     pub kem_output: Vec<u8>,
29     #[mls_codec(with = "mls_rs_codec::byte_vec")]
30     #[cfg_attr(feature = "serde", serde(with = "crate::vec_serde"))]
31     pub ciphertext: Vec<u8>,
32 }
33 
34 impl Debug for HpkeCiphertext {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result35     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36         f.debug_struct("HpkeCiphertext")
37             .field("kem_output", &crate::debug::pretty_bytes(&self.kem_output))
38             .field("ciphertext", &crate::debug::pretty_bytes(&self.ciphertext))
39             .finish()
40     }
41 }
42 
43 /// Byte representation of an HPKE public key. For ciphersuites using elliptic curves,
44 /// the public key should be represented in the uncompressed format.
45 #[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord, MlsSize, MlsDecode, MlsEncode)]
46 #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
47 #[cfg_attr(
48     all(feature = "ffi", not(test)),
49     safer_ffi_gen::ffi_type(clone, opaque)
50 )]
51 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
52 pub struct HpkePublicKey(
53     #[mls_codec(with = "mls_rs_codec::byte_vec")]
54     #[cfg_attr(feature = "serde", serde(with = "crate::vec_serde"))]
55     Vec<u8>,
56 );
57 
58 impl Debug for HpkePublicKey {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result59     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60         crate::debug::pretty_bytes(&self.0)
61             .named("HpkePublicKey")
62             .fmt(f)
63     }
64 }
65 
66 impl From<Vec<u8>> for HpkePublicKey {
from(data: Vec<u8>) -> Self67     fn from(data: Vec<u8>) -> Self {
68         Self(data)
69     }
70 }
71 
72 impl From<HpkePublicKey> for Vec<u8> {
from(data: HpkePublicKey) -> Self73     fn from(data: HpkePublicKey) -> Self {
74         data.0
75     }
76 }
77 
78 impl Deref for HpkePublicKey {
79     type Target = [u8];
80 
deref(&self) -> &Self::Target81     fn deref(&self) -> &Self::Target {
82         &self.0
83     }
84 }
85 
86 impl AsRef<[u8]> for HpkePublicKey {
as_ref(&self) -> &[u8]87     fn as_ref(&self) -> &[u8] {
88         &self.0
89     }
90 }
91 
92 /// Byte representation of an HPKE secret key.
93 #[derive(Clone, PartialEq, Eq, MlsSize, MlsEncode, MlsDecode, ZeroizeOnDrop)]
94 #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
95 #[cfg_attr(
96     all(feature = "ffi", not(test)),
97     safer_ffi_gen::ffi_type(clone, opaque)
98 )]
99 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
100 pub struct HpkeSecretKey(
101     #[mls_codec(with = "mls_rs_codec::byte_vec")]
102     #[cfg_attr(feature = "serde", serde(with = "crate::vec_serde"))]
103     Vec<u8>,
104 );
105 
106 impl Debug for HpkeSecretKey {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result107     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
108         crate::debug::pretty_bytes(&self.0)
109             .named("HpkeSecretKey")
110             .fmt(f)
111     }
112 }
113 
114 impl From<Vec<u8>> for HpkeSecretKey {
from(data: Vec<u8>) -> Self115     fn from(data: Vec<u8>) -> Self {
116         Self(data)
117     }
118 }
119 
120 impl Deref for HpkeSecretKey {
121     type Target = [u8];
122 
deref(&self) -> &Self::Target123     fn deref(&self) -> &Self::Target {
124         &self.0
125     }
126 }
127 
128 impl AsRef<[u8]> for HpkeSecretKey {
as_ref(&self) -> &[u8]129     fn as_ref(&self) -> &[u8] {
130         &self.0
131     }
132 }
133 
134 /// The HPKE context for sender outputted by [hpke_setup_s](CipherSuiteProvider::hpke_setup_s).
135 /// The context internally stores the secrets generated by [hpke_setup_s](CipherSuiteProvider::hpke_setup_s).
136 ///
137 /// This trait corresponds to ContextS from RFC 9180.
138 #[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)]
139 #[cfg_attr(all(target_arch = "wasm32", mls_build_async), maybe_async::must_be_async(?Send))]
140 #[cfg_attr(
141     all(not(target_arch = "wasm32"), mls_build_async),
142     maybe_async::must_be_async
143 )]
144 pub trait HpkeContextS {
145     type Error: IntoAnyError;
146 
147     /// Encrypt `data` using the cipher key of the context with optional `aad`.
148     /// This function should internally increment the sequence number.
seal(&mut self, aad: Option<&[u8]>, data: &[u8]) -> Result<Vec<u8>, Self::Error>149     async fn seal(&mut self, aad: Option<&[u8]>, data: &[u8]) -> Result<Vec<u8>, Self::Error>;
150 
151     /// Export a secret from the context for the given `exporter_context`.
export(&self, exporter_context: &[u8], len: usize) -> Result<Vec<u8>, Self::Error>152     async fn export(&self, exporter_context: &[u8], len: usize) -> Result<Vec<u8>, Self::Error>;
153 }
154 
155 /// The HPKE context for receiver outputted by [hpke_setup_r](CipherSuiteProvider::hpke_setup_r).
156 /// The context internally stores secrets received from the sender by [hpke_setup_r](CipherSuiteProvider::hpke_setup_r).
157 ///
158 /// This trait corresponds to ContextR from RFC 9180.
159 #[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)]
160 #[cfg_attr(all(target_arch = "wasm32", mls_build_async), maybe_async::must_be_async(?Send))]
161 #[cfg_attr(
162     all(not(target_arch = "wasm32"), mls_build_async),
163     maybe_async::must_be_async
164 )]
165 pub trait HpkeContextR {
166     type Error: IntoAnyError;
167 
168     /// Decrypt `ciphertext` using the cipher key of the context with optional `aad`.
169     /// This function should internally increment the sequence number.
open(&mut self, aad: Option<&[u8]>, ciphertext: &[u8]) -> Result<Vec<u8>, Self::Error>170     async fn open(&mut self, aad: Option<&[u8]>, ciphertext: &[u8])
171         -> Result<Vec<u8>, Self::Error>;
172 
173     /// Export a secret from the context for the given `exporter_context`.
export(&self, exporter_context: &[u8], len: usize) -> Result<Vec<u8>, Self::Error>174     async fn export(&self, exporter_context: &[u8], len: usize) -> Result<Vec<u8>, Self::Error>;
175 }
176 
177 /// Byte representation of a signature public key. For ciphersuites using elliptic curves,
178 /// the public key should be represented in the uncompressed format.
179 #[derive(Clone, PartialEq, Eq, Hash, Ord, PartialOrd, MlsSize, MlsEncode, MlsDecode)]
180 #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
181 #[cfg_attr(all(feature = "ffi", not(test)), ::safer_ffi_gen::ffi_type(opaque))]
182 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
183 pub struct SignaturePublicKey(
184     #[mls_codec(with = "mls_rs_codec::byte_vec")]
185     #[cfg_attr(feature = "serde", serde(with = "crate::vec_serde"))]
186     Vec<u8>,
187 );
188 
189 impl Debug for SignaturePublicKey {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result190     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
191         crate::debug::pretty_bytes(&self.0)
192             .named("SignaturePublicKey")
193             .fmt(f)
194     }
195 }
196 
197 #[cfg_attr(all(feature = "ffi", not(test)), ::safer_ffi_gen::safer_ffi_gen)]
198 impl SignaturePublicKey {
new(bytes: Vec<u8>) -> Self199     pub fn new(bytes: Vec<u8>) -> Self {
200         bytes.into()
201     }
202 
new_slice(data: &[u8]) -> Self203     pub fn new_slice(data: &[u8]) -> Self {
204         Self(data.to_vec())
205     }
206 
as_bytes(&self) -> &[u8]207     pub fn as_bytes(&self) -> &[u8] {
208         &self.0
209     }
210 }
211 
212 impl Deref for SignaturePublicKey {
213     type Target = [u8];
214 
deref(&self) -> &Self::Target215     fn deref(&self) -> &Self::Target {
216         &self.0
217     }
218 }
219 
220 impl AsRef<[u8]> for SignaturePublicKey {
as_ref(&self) -> &[u8]221     fn as_ref(&self) -> &[u8] {
222         &self.0
223     }
224 }
225 
226 impl From<Vec<u8>> for SignaturePublicKey {
from(data: Vec<u8>) -> Self227     fn from(data: Vec<u8>) -> Self {
228         SignaturePublicKey(data)
229     }
230 }
231 
232 /// Byte representation of a signature key.
233 #[cfg_attr(
234     all(feature = "ffi", not(test)),
235     ::safer_ffi_gen::ffi_type(clone, opaque)
236 )]
237 #[derive(Clone, PartialEq, Eq, ZeroizeOnDrop, MlsSize, MlsEncode, MlsDecode)]
238 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
239 pub struct SignatureSecretKey {
240     #[mls_codec(with = "mls_rs_codec::byte_vec")]
241     #[cfg_attr(feature = "serde", serde(with = "crate::vec_serde"))]
242     bytes: Vec<u8>,
243 }
244 
245 impl Debug for SignatureSecretKey {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result246     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
247         crate::debug::pretty_bytes(&self.bytes)
248             .named("SignatureSecretKey")
249             .fmt(f)
250     }
251 }
252 
253 #[cfg_attr(all(feature = "ffi", not(test)), ::safer_ffi_gen::safer_ffi_gen)]
254 impl SignatureSecretKey {
new(bytes: Vec<u8>) -> Self255     pub fn new(bytes: Vec<u8>) -> Self {
256         bytes.into()
257     }
258 
new_slice(data: &[u8]) -> Self259     pub fn new_slice(data: &[u8]) -> Self {
260         Self {
261             bytes: data.to_vec(),
262         }
263     }
264 
as_bytes(&self) -> &[u8]265     pub fn as_bytes(&self) -> &[u8] {
266         &self.bytes
267     }
268 }
269 
270 impl From<Vec<u8>> for SignatureSecretKey {
from(bytes: Vec<u8>) -> Self271     fn from(bytes: Vec<u8>) -> Self {
272         Self { bytes }
273     }
274 }
275 
276 impl Deref for SignatureSecretKey {
277     type Target = Vec<u8>;
278 
deref(&self) -> &Self::Target279     fn deref(&self) -> &Self::Target {
280         &self.bytes
281     }
282 }
283 
284 impl AsRef<[u8]> for SignatureSecretKey {
as_ref(&self) -> &[u8]285     fn as_ref(&self) -> &[u8] {
286         &self.bytes
287     }
288 }
289 
290 /// Provides implementations for several ciphersuites via [`CipherSuiteProvider`].
291 pub trait CryptoProvider: Send + Sync {
292     type CipherSuiteProvider: CipherSuiteProvider + Clone;
293 
294     /// Return the list of all supported ciphersuites.
supported_cipher_suites(&self) -> Vec<CipherSuite>295     fn supported_cipher_suites(&self) -> Vec<CipherSuite>;
296 
297     /// Generate a [CipherSuiteProvider] for the given `cipher_suite`.
cipher_suite_provider(&self, cipher_suite: CipherSuite) -> Option<Self::CipherSuiteProvider>298     fn cipher_suite_provider(&self, cipher_suite: CipherSuite)
299         -> Option<Self::CipherSuiteProvider>;
300 }
301 
302 /// Provides all cryptographic operations required by MLS for a given cipher suite.
303 #[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)]
304 #[cfg_attr(all(target_arch = "wasm32", mls_build_async), maybe_async::must_be_async(?Send))]
305 #[cfg_attr(
306     all(not(target_arch = "wasm32"), mls_build_async),
307     maybe_async::must_be_async
308 )]
309 pub trait CipherSuiteProvider: Send + Sync {
310     type Error: IntoAnyError;
311 
312     type HpkeContextS: HpkeContextS + Send + Sync;
313     type HpkeContextR: HpkeContextR + Send + Sync;
314 
315     /// Return the implemented MLS [CipherSuite](CipherSuite).
cipher_suite(&self) -> CipherSuite316     fn cipher_suite(&self) -> CipherSuite;
317 
318     /// Compute the hash of `data`.
hash(&self, data: &[u8]) -> Result<Vec<u8>, Self::Error>319     async fn hash(&self, data: &[u8]) -> Result<Vec<u8>, Self::Error>;
320 
321     /// Compute the MAC tag of `data` using the `key` of length [kdf_extract_size](CipherSuiteProvider::kdf_extract_size).
322     /// Verifying a MAC tag of `data` using `key` is done by calling this function
323     /// and checking that the result matches the tag.
mac(&self, key: &[u8], data: &[u8]) -> Result<Vec<u8>, Self::Error>324     async fn mac(&self, key: &[u8], data: &[u8]) -> Result<Vec<u8>, Self::Error>;
325 
326     /// Encrypt `data` with public additional authenticated data `aad`, using additional `nonce`
327     /// (sometimes called the initialization vector, IV). The output should include
328     /// the authentication tag, if used by the given AEAD implementation (for example,
329     /// the tag can be appended to the ciphertext).
aead_seal( &self, key: &[u8], data: &[u8], aad: Option<&[u8]>, nonce: &[u8], ) -> Result<Vec<u8>, Self::Error>330     async fn aead_seal(
331         &self,
332         key: &[u8],
333         data: &[u8],
334         aad: Option<&[u8]>,
335         nonce: &[u8],
336     ) -> Result<Vec<u8>, Self::Error>;
337 
338     /// Decrypt the `ciphertext` generated by [aead_seal](CipherSuiteProvider::aead_seal).
339     /// This function should return an error if any of the inputs `key`, `aad` or `nonce` does not match
340     /// the corresponding input passed to [aead_seal](CipherSuiteProvider::aead_seal) to generate `ciphertext`.
aead_open( &self, key: &[u8], ciphertext: &[u8], aad: Option<&[u8]>, nonce: &[u8], ) -> Result<Zeroizing<Vec<u8>>, Self::Error>341     async fn aead_open(
342         &self,
343         key: &[u8],
344         ciphertext: &[u8],
345         aad: Option<&[u8]>,
346         nonce: &[u8],
347     ) -> Result<Zeroizing<Vec<u8>>, Self::Error>;
348 
349     /// Return the length of the secret key `key` passed to [aead_seal](CipherSuiteProvider::aead_seal)
350     /// and [aead_open](CipherSuiteProvider::aead_open).
aead_key_size(&self) -> usize351     fn aead_key_size(&self) -> usize;
352 
353     /// Return the length of the `nonce` passed to [aead_seal](CipherSuiteProvider::aead_seal)
354     /// and [aead_open](CipherSuiteProvider::aead_open).
aead_nonce_size(&self) -> usize355     fn aead_nonce_size(&self) -> usize;
356 
357     /// Generate a pseudo-random key `prk` extracted from the initial key
358     /// material `ikm`, using an optional random `salt`. The outputted `prk` should have
359     /// [kdf_extract_size](CipherSuiteProvider::kdf_extract_size) bytes. It can be used
360     /// as input to [kdf_expand](CipherSuiteProvider::kdf_expand).
361     ///
362     /// This function corresponds to the HKDF-Extract function from RFC 5869.
kdf_extract(&self, salt: &[u8], ikm: &[u8]) -> Result<Zeroizing<Vec<u8>>, Self::Error>363     async fn kdf_extract(&self, salt: &[u8], ikm: &[u8])
364         -> Result<Zeroizing<Vec<u8>>, Self::Error>;
365 
366     /// Generate key material of the desired length `len` by expanding the given pseudo-random key
367     /// `prk` of length [kdf_extract_size](CipherSuiteProvider::kdf_extract_size).
368     /// The additional input `info` contains optional context data.
369     ///
370     /// This function corresponds to the HKDF-Expand function from RFC 5869.
kdf_expand( &self, prk: &[u8], info: &[u8], len: usize, ) -> Result<Zeroizing<Vec<u8>>, Self::Error>371     async fn kdf_expand(
372         &self,
373         prk: &[u8],
374         info: &[u8],
375         len: usize,
376     ) -> Result<Zeroizing<Vec<u8>>, Self::Error>;
377 
378     /// Return the size of pseudo-random key `prk` outputted by [kdf_extract](CipherSuiteProvider::kdf_extract)
379     /// and inputted to [kdf_expand](CipherSuiteProvider::kdf_expand).
kdf_extract_size(&self) -> usize380     fn kdf_extract_size(&self) -> usize;
381 
382     /// Encrypt the plaintext `pt` with optional public additional authenticated data `aad` to the
383     /// public key `remote_key` using additional context information `info` (which can be empty if
384     /// not needed). This function combines the action
385     /// of the [hpke_setup_s](CipherSuiteProvider::hpke_setup_s) and then calling [seal](HpkeContextS::seal)
386     /// on the resulting [HpkeContextS](self::HpkeContextS).
387     ///
388     /// This function corresponds to the one-shot API in base mode in RFC 9180.
hpke_seal( &self, remote_key: &HpkePublicKey, info: &[u8], aad: Option<&[u8]>, pt: &[u8], ) -> Result<HpkeCiphertext, Self::Error>389     async fn hpke_seal(
390         &self,
391         remote_key: &HpkePublicKey,
392         info: &[u8],
393         aad: Option<&[u8]>,
394         pt: &[u8],
395     ) -> Result<HpkeCiphertext, Self::Error>;
396 
397     /// Decrypt the `ciphertext` generated by [hpke_seal](CipherSuiteProvider::hpke_seal).
398     /// This function combines the action of the [hpke_setup_r](CipherSuiteProvider::hpke_setup_r)
399     /// and then calling [open](HpkeContextR::open) on the resulting [HpkeContextR](self::HpkeContextR).
400     ///
401     /// This function corresponds to the one-shot API in base mode in RFC 9180.
hpke_open( &self, ciphertext: &HpkeCiphertext, local_secret: &HpkeSecretKey, local_public: &HpkePublicKey, info: &[u8], aad: Option<&[u8]>, ) -> Result<Vec<u8>, Self::Error>402     async fn hpke_open(
403         &self,
404         ciphertext: &HpkeCiphertext,
405         local_secret: &HpkeSecretKey,
406         local_public: &HpkePublicKey,
407         info: &[u8],
408         aad: Option<&[u8]>,
409     ) -> Result<Vec<u8>, Self::Error>;
410 
411     /// Generate a tuple containing the ciphertext `kem_output` that can
412     /// be used as the input to [hpke_setup_r](CipherSuiteProvider::hpke_setup_r),
413     /// as well as the sender context [HpkeContextS](self::HpkeContextS) that can be
414     /// used to generate AEAD ciphertexts and export keys.
415     ///
416     /// The inputted `remote_key` will normally be generated using
417     /// [kem_derive](CipherSuiteProvider::kem_derive) or
418     /// [kem_generate](CipherSuiteProvider::kem_generate). However, the function
419     /// should return an error if the format is incorrect.
420     ///
421     /// This function corresponds to the SetupBaseS function from RFC 9180.
hpke_setup_s( &self, remote_key: &HpkePublicKey, info: &[u8], ) -> Result<(Vec<u8>, Self::HpkeContextS), Self::Error>422     async fn hpke_setup_s(
423         &self,
424         remote_key: &HpkePublicKey,
425         info: &[u8],
426     ) -> Result<(Vec<u8>, Self::HpkeContextS), Self::Error>;
427 
428     /// Receive the ciphertext `kem_output` generated by [hpke_setup_s](CipherSuiteProvider::hpke_setup_s)
429     /// and the `local_secret` corresponding to the `remote_key` used as input to
430     /// [hpke_setup_s](CipherSuiteProvider::hpke_setup_s). The ouput is the receiver context
431     /// [HpkeContextR](self::HpkeContextR) that can be used to decrypt AEAD ciphertexts
432     /// generated by the sender context [HpkeContextS](self::HpkeContextS) outputted by
433     /// [hpke_setup_r](CipherSuiteProvider::hpke_setup_r)
434     /// and export the same keys as that context.
435     ///
436     /// The inputted `local_secret` will normally be generated using
437     /// [kem_derive](CipherSuiteProvider::kem_derive) or
438     /// [kem_generate](CipherSuiteProvider::kem_generate). However, the function
439     /// should return an error if the format is incorrect.
440     ///
441     /// This function corresponds to the SetupBaseR function from RFC 9180.
hpke_setup_r( &self, kem_output: &[u8], local_secret: &HpkeSecretKey, local_public: &HpkePublicKey, info: &[u8], ) -> Result<Self::HpkeContextR, Self::Error>442     async fn hpke_setup_r(
443         &self,
444         kem_output: &[u8],
445         local_secret: &HpkeSecretKey,
446         local_public: &HpkePublicKey,
447 
448         info: &[u8],
449     ) -> Result<Self::HpkeContextR, Self::Error>;
450 
451     /// Derive from the initial key material `ikm` the KEM keys used as inputs to
452     /// [hpke_setup_r](CipherSuiteProvider::hpke_setup_r),
453     /// [hpke_setup_s](CipherSuiteProvider::hpke_setup_s), [hpke_seal](CipherSuiteProvider::hpke_seal)
454     /// and [hpke_open](CipherSuiteProvider::hpke_open).
kem_derive(&self, ikm: &[u8]) -> Result<(HpkeSecretKey, HpkePublicKey), Self::Error>455     async fn kem_derive(&self, ikm: &[u8]) -> Result<(HpkeSecretKey, HpkePublicKey), Self::Error>;
456 
457     /// Generate fresh KEM keys to be used as inputs to [hpke_setup_r](CipherSuiteProvider::hpke_setup_r),
458     /// [hpke_setup_s](CipherSuiteProvider::hpke_setup_s), [hpke_seal](CipherSuiteProvider::hpke_seal)
459     /// and [hpke_open](CipherSuiteProvider::hpke_open).
kem_generate(&self) -> Result<(HpkeSecretKey, HpkePublicKey), Self::Error>460     async fn kem_generate(&self) -> Result<(HpkeSecretKey, HpkePublicKey), Self::Error>;
461 
462     /// Verify that the given byte vector `key` can be decoded as an HPKE public key.
kem_public_key_validate(&self, key: &HpkePublicKey) -> Result<(), Self::Error>463     fn kem_public_key_validate(&self, key: &HpkePublicKey) -> Result<(), Self::Error>;
464 
465     /// Fill `out` with random bytes.
random_bytes(&self, out: &mut [u8]) -> Result<(), Self::Error>466     fn random_bytes(&self, out: &mut [u8]) -> Result<(), Self::Error>;
467 
468     /// Generate `count` bytes of pseudorandom bytes as a vector. This is a shortcut for
469     /// creating a `Vec<u8>` of `count` bytes and calling [random_bytes](CipherSuiteProvider::random_bytes).
random_bytes_vec(&self, count: usize) -> Result<Vec<u8>, Self::Error>470     fn random_bytes_vec(&self, count: usize) -> Result<Vec<u8>, Self::Error> {
471         let mut vec = vec![0u8; count];
472         self.random_bytes(&mut vec)?;
473 
474         Ok(vec)
475     }
476 
477     /// Generate fresh signature keys to be used as inputs to [sign](CipherSuiteProvider::sign)
478     /// and [verify](CipherSuiteProvider::verify)
signature_key_generate( &self, ) -> Result<(SignatureSecretKey, SignaturePublicKey), Self::Error>479     async fn signature_key_generate(
480         &self,
481     ) -> Result<(SignatureSecretKey, SignaturePublicKey), Self::Error>;
482 
483     /// Output a public key corresponding to `secret_key`.
signature_key_derive_public( &self, secret_key: &SignatureSecretKey, ) -> Result<SignaturePublicKey, Self::Error>484     async fn signature_key_derive_public(
485         &self,
486         secret_key: &SignatureSecretKey,
487     ) -> Result<SignaturePublicKey, Self::Error>;
488 
489     /// Sign `data` using `secret_key`.
sign( &self, secret_key: &SignatureSecretKey, data: &[u8], ) -> Result<Vec<u8>, Self::Error>490     async fn sign(
491         &self,
492         secret_key: &SignatureSecretKey,
493         data: &[u8],
494     ) -> Result<Vec<u8>, Self::Error>;
495 
496     /// Verify that the secret key corresponding to `public_key` created the `signature` over `data`.
verify( &self, public_key: &SignaturePublicKey, signature: &[u8], data: &[u8], ) -> Result<(), Self::Error>497     async fn verify(
498         &self,
499         public_key: &SignaturePublicKey,
500         signature: &[u8],
501         data: &[u8],
502     ) -> Result<(), Self::Error>;
503 }
504