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