Implement reused secret keys for Noise protocol.

This commit is contained in:
Isis Lovecruft 2021-04-14 20:00:41 +00:00
parent 3d87bd3c7d
commit 0a1023f4db
No known key found for this signature in database
GPG key ID: AB41313533E8E812

View file

@ -95,6 +95,46 @@ impl<'a> From<&'a EphemeralSecret> for PublicKey {
}
}
/// A Diffie-Hellman secret key which may be used more than once, but is
/// purposefully not serialiseable in order to discourage key-reuse. This is
/// implemented to facilitate protocols such as Noise (e.g. Noise IK key usage,
/// etc.) and X3DH which require an "ephemeral" key to conduct the
/// Diffie-Hellman operation multiple times throughout the protocol, while the
/// protocol run at a higher level is only conducted once per key.
///
/// If you're uncertain about whether you should use this, then you likely
/// should not be using this. Our strongly recommended advice is to use
/// [`EphemeralSecret`] at all times, as that type enforces at compile-time that
/// secret keys are never reused, which can have very serious security
/// implications for many protocols.
#[derive(Zeroize)]
#[zeroize(drop)]
pub struct NonSerializeableSecret(pub(crate) Scalar);
impl NonSerializeableSecret {
/// Perform a Diffie-Hellman key agreement between `self` and
/// `their_public` key to produce a [`SharedSecret`].
pub fn diffie_hellman(&self, their_public: &PublicKey) -> SharedSecret {
SharedSecret(&self.0 * their_public.0)
}
/// Generate a non-serializeable x25519 key.
pub fn new<T: RngCore + CryptoRng>(mut csprng: T) -> Self {
let mut bytes = [0u8; 32];
csprng.fill_bytes(&mut bytes);
NonSerializeableSecret(clamp_scalar(bytes))
}
}
impl<'a> From<&'a NonSerializeableSecret> for PublicKey {
/// Given an x25519 [`NonSerializeableSecret`] key, compute its corresponding [`PublicKey`].
fn from(secret: &'a NonSerializeableSecret) -> PublicKey {
PublicKey((&ED25519_BASEPOINT_TABLE * &secret.0).to_montgomery())
}
}
/// A Diffie-Hellman secret key that can be used to compute multiple [`SharedSecret`]s.
///
/// This type is identical to the [`EphemeralSecret`] type, except that the