1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
use curve25519_dalek::scalar;
use ring::rand;
use sha3::{Digest, Sha3_256};

use super::*;

// XXX: We probably want to check this (the hash) with NIST SP 800-185 Appendix B
// Using shake128 with some whitty scalar interpretation can safe a lot of cycles.
pub fn agree_to_scalar(
    public: &PublicKey,
    private: &PrivateKey,
) -> crate::crypto::Result<scalar::Scalar> {
    let shared_secret = private.agree_with(public)?;
    Ok(digest_to_scalar::<Sha3_256>(&shared_secret))
}

pub fn digest_to_scalar<D: Digest>(data: &[u8]) -> scalar::Scalar {
    let mut d = D::new();
    d.update(data);
    scalar_from_digest(d)
}

pub fn scalar_from_digest<D: Digest>(d: D) -> scalar::Scalar {
    let mut slice = [0u8; 32];
    slice.copy_from_slice(d.finalize().as_ref());
    scalar::Scalar::from_bytes_mod_order(slice)
}

/// Replacement for curve25519_dalek random,
/// since it depends on `rand` crate.
pub fn random_scalar<R: rand::SecureRandom>(rng: &R) -> crate::crypto::Result<scalar::Scalar> {
    let mut tmp = [0u8; 64];
    rng.fill(&mut tmp)?;
    Ok(scalar::Scalar::from_bytes_mod_order_wide(&tmp))
}