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 mls_rs_core::{
6     crypto::{HpkePublicKey, HpkeSecretKey},
7     error::IntoAnyError,
8 };
9 
10 use alloc::vec::Vec;
11 
12 #[cfg(feature = "mock")]
13 use mockall::automock;
14 
15 /// A trait that provides the required DH functions, as in RFC 9180,Section 4.1
16 #[cfg_attr(feature = "mock", automock(type Error = crate::mock::TestError;))]
17 #[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)]
18 #[cfg_attr(all(target_arch = "wasm32", mls_build_async), maybe_async::must_be_async(?Send))]
19 #[cfg_attr(
20     all(not(target_arch = "wasm32"), mls_build_async),
21     maybe_async::must_be_async
22 )]
23 pub trait DhType: Send + Sync {
24     type Error: IntoAnyError + Send + Sync;
25 
dh( &self, secret_key: &HpkeSecretKey, public_key: &HpkePublicKey, ) -> Result<Vec<u8>, Self::Error>26     async fn dh(
27         &self,
28         secret_key: &HpkeSecretKey,
29         public_key: &HpkePublicKey,
30     ) -> Result<Vec<u8>, Self::Error>;
31 
32     /// Generate a fresh key pair. This is the only place where randomness is used in this
33     /// module. The function could be implemented in the same way as `derive` with random
34     /// `ikm`, but it could also be implemented directly with a crypto provider like OpenSSL.
generate(&self) -> Result<(HpkeSecretKey, HpkePublicKey), Self::Error>35     async fn generate(&self) -> Result<(HpkeSecretKey, HpkePublicKey), Self::Error>;
36 
37     /// Outputs the public key corresponding to the given secret key bytes. If the secret
38     /// key is malformed, the function should return an error.
to_public(&self, secret_key: &HpkeSecretKey) -> Result<HpkePublicKey, Self::Error>39     async fn to_public(&self, secret_key: &HpkeSecretKey) -> Result<HpkePublicKey, Self::Error>;
40 
41     /// If the output is `Some(bitmask)`, then the `Kem::derive` function will generate
42     /// the secret key by rejection sampling over random byte sequences with `bitmask`
43     /// applied to the most significant byte.
44     ///
45     /// Typical outputs for ECDH are:
46     /// * `None` for curves 25519 and X448 (no rejection sampling is needed),
47     /// * `Some(0x01)` for curve P-521 (all bits  of the first byte except the least
48     ///   significant one are filtered out),
49     /// * `Some(0xFF)`for curves P-256 and P-384 (rejection sampling is needed but no
50     ///   bits need to be filtered).
bitmask_for_rejection_sampling(&self) -> Option<u8>51     fn bitmask_for_rejection_sampling(&self) -> Option<u8>;
52 
secret_key_size(&self) -> usize53     fn secret_key_size(&self) -> usize;
54 
public_key_validate(&self, key: &HpkePublicKey) -> Result<(), Self::Error>55     fn public_key_validate(&self, key: &HpkePublicKey) -> Result<(), Self::Error>;
56 }
57