1use ec::point_ops::PointOps;
4
5use crate::scalar::SecretScalar;
6
7#[derive(Debug, Clone, PartialEq, Eq)]
9pub struct KeyPair<P, const LIMBS: usize> {
10 pub secret: SecretScalar<LIMBS>,
12 pub public: P,
14}
15
16pub struct Ecdh;
18
19impl Ecdh {
20 pub fn derive_public_key<P, const LIMBS: usize>(
22 base_point: &P,
23 secret: &SecretScalar<LIMBS>,
24 curve: &P::Curve,
25 ) -> P
26 where
27 P: PointOps,
28 {
29 base_point.scalar_mul(secret.as_limbs(), curve)
30 }
31
32 pub fn keypair_from_secret<P, const LIMBS: usize>(
34 base_point: &P,
35 secret: SecretScalar<LIMBS>,
36 curve: &P::Curve,
37 ) -> KeyPair<P, LIMBS>
38 where
39 P: PointOps,
40 {
41 let public = Self::derive_public_key(base_point, &secret, curve);
42 KeyPair { secret, public }
43 }
44
45 pub fn shared_secret<P, const LIMBS: usize>(
49 my_secret: &SecretScalar<LIMBS>,
50 peer_public: &P,
51 curve: &P::Curve,
52 ) -> Option<P>
53 where
54 P: PointOps,
55 {
56 if peer_public.is_identity() {
57 return None;
58 }
59 Some(peer_public.scalar_mul(my_secret.as_limbs(), curve))
60 }
61}