From 532ccc0f583d601d7ba2bb7f98f9b7355f7f5c4f Mon Sep 17 00:00:00 2001
From: Aaron Feickert <66188213+AaronFeickert@users.noreply.github.com>
Date: Tue, 25 Oct 2022 09:47:24 +0200
Subject: [PATCH] feat: add `Zeroize` support to key types, and create new
shared secret type (#137)
* Add `Zeroize` support to key types
* Use zeroize-on-drop macro
* Ensure ECDH secrets are zeroized on drop
* Add new DHKE shared secret type
---
src/dhke.rs | 48 +++++++++++++++++++++++++++++++
src/keys.rs | 8 ------
src/lib.rs | 1 +
src/ristretto/ristretto_keys.rs | 51 +++++++++++++++++++++------------
4 files changed, 82 insertions(+), 26 deletions(-)
create mode 100644 src/dhke.rs
diff --git a/src/dhke.rs b/src/dhke.rs
new file mode 100644
index 00000000..07859a1c
--- /dev/null
+++ b/src/dhke.rs
@@ -0,0 +1,48 @@
+// Copyright 2022 The Tari Project
+// SPDX-License-Identifier: BSD-3-Clause
+
+//! The robotic innards of a Diffie-Hellman key exchange (DHKE) producing a shared secret.
+//! Even though the result of a DHKE is the same type as a public key, it is typically treated as a secret value.
+//! To make this work more safely, we ensure that a DHKE result is cleared after use (but beware of subsequent copies or moves).
+//! Because a DHKE shared secret is intended to be used in further key derivation, the only visibility into it is as a byte array; it's not possible to directly extract the underlying public key type, and you probably shouldn't clone the byte array without a very good reason.
+//! If you need the underlying public key itself, you probably should be using something else.
+
+use std::ops::Mul;
+
+use zeroize::Zeroize;
+
+use crate::keys::PublicKey;
+
+pub struct DiffieHellmanSharedSecret
(P)
+where P: Zeroize;
+
+impl
DiffieHellmanSharedSecret
+where
+ P: PublicKey + Zeroize,
+ for<'a> &'a
::K: Mul<&'a P, Output = P>,
+{
+ /// Perform a Diffie-Hellman key exchange
+ pub fn new(sk: &P::K, pk: &P) -> Self {
+ Self(sk * pk)
+ }
+
+ /// Get the shared secret as a byte array
+ pub fn as_bytes(&self) -> &[u8] {
+ self.0.as_bytes()
+ }
+}
+
+impl
Zeroize for DiffieHellmanSharedSecret
where P: Zeroize {
+ /// Zeroize the shared secret's underlying public key
+ fn zeroize(&mut self) {
+ self.0.zeroize();
+ }
+}
+
+impl
Drop for DiffieHellmanSharedSecret
where P: Zeroize {
+ /// Zeroize the shared secret when out of scope or otherwise dropped
+ fn drop(&mut self) {
+ self.zeroize();
+ }
+}
+
diff --git a/src/keys.rs b/src/keys.rs
index ba62b982..893721a7 100644
--- a/src/keys.rs
+++ b/src/keys.rs
@@ -68,11 +68,3 @@ pub trait PublicKey:
(k, pk)
}
}
-
-/// This trait provides a common mechanism to calculate a shared secret using the private and public key of two parties
-pub trait DiffieHellmanSharedSecret: ByteArray + Clone + PartialEq + Eq + Add