libsecp256k1_core/
ecdh.rs

1use crate::{
2    ecmult::ECMultContext,
3    group::{Affine, Jacobian},
4    scalar::Scalar,
5};
6use digest::{generic_array::GenericArray, Digest};
7
8impl ECMultContext {
9    pub fn ecdh_raw<D: Digest + Default>(
10        &self,
11        point: &Affine,
12        scalar: &Scalar,
13    ) -> Option<GenericArray<u8, D::OutputSize>> {
14        let mut digest: D = Default::default();
15
16        let mut pt = *point;
17        let s = *scalar;
18
19        if s.is_zero() {
20            return None;
21        }
22
23        let mut res = Jacobian::default();
24        self.ecmult_const(&mut res, &pt, &s);
25        pt.set_gej(&res);
26
27        pt.x.normalize();
28        pt.y.normalize();
29
30        let x = pt.x.b32();
31        let y = 0x02 | (if pt.y.is_odd() { 1 } else { 0 });
32
33        digest.update(&[y]);
34        digest.update(&x);
35        Some(digest.finalize_reset())
36    }
37}