-
Notifications
You must be signed in to change notification settings - Fork 25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix!: zeroize temporary scalar value #204
Changes from all commits
f24bda1
59a1957
a0bd689
f9c6252
1bbd1e2
65aa742
b0d0a8b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,7 @@ | |
//! Extended range proofs | ||
|
||
use std::{string::ToString, vec::Vec}; | ||
use zeroize::Zeroize; | ||
|
||
use crate::{ | ||
commitment::{ExtensionDegree, HomomorphicCommitment}, | ||
|
@@ -99,13 +100,19 @@ pub trait ExtendedRangeProofService { | |
|
||
/// Extended blinding factor vector used as part of the witness to construct an extended proof, or rewind data | ||
/// extracted from a range proof containing the mask (e.g. blinding factor vector). | ||
#[derive(Debug, Clone, PartialEq, Eq)] | ||
#[derive(Debug, Clone, PartialEq, Eq, Zeroize)] | ||
pub struct ExtendedMask<K> | ||
where K: SecretKey | ||
{ | ||
secrets: Vec<K>, | ||
} | ||
|
||
impl<K:SecretKey> Drop for ExtendedMask<K>{ | ||
fn drop(&mut self) { | ||
self.secrets.zeroize(); | ||
} | ||
} | ||
|
||
impl<K> ExtendedMask<K> | ||
where K: SecretKey | ||
{ | ||
|
@@ -200,7 +207,7 @@ where PK: PublicKey | |
|
||
/// The extended witness contains the extended mask (blinding factor vector), value and a minimum value | ||
/// promise; this will be used to construct the extended range proof | ||
#[derive(Clone)] | ||
#[derive(Clone, Zeroize)] | ||
pub struct ExtendedWitness<K> | ||
where K: SecretKey | ||
{ | ||
|
@@ -212,6 +219,14 @@ where K: SecretKey | |
pub minimum_value_promise: u64, | ||
} | ||
|
||
impl<K: SecretKey> Drop for ExtendedWitness<K>{ | ||
fn drop(&mut self) { | ||
self.mask.zeroize(); | ||
self.value.zeroize(); | ||
self.minimum_value_promise.zeroize(); | ||
} | ||
} | ||
Comment on lines
+222
to
+228
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should be able to get this functionality for free by deriving There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As a side note, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See this branch for the derived traits. |
||
|
||
impl<K> ExtendedWitness<K> | ||
where K: SecretKey | ||
{ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -65,9 +65,19 @@ impl borsh::BorshSerialize for RistrettoSecretKey { | |
impl borsh::BorshDeserialize for RistrettoSecretKey { | ||
fn deserialize_reader<R>(reader: &mut R) -> Result<Self, borsh::maybestd::io::Error> | ||
where R: borsh::maybestd::io::Read { | ||
let bytes: Vec<u8> = borsh::BorshDeserialize::deserialize_reader(reader)?; | ||
Self::from_canonical_bytes(bytes.as_slice()) | ||
let mut bytes: Vec<u8> = borsh::BorshDeserialize::deserialize_reader(reader)?; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can use a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tried, but it doesn't deserialize, I could have added a wrapper after the deserialize, but it's basically the same thing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Which tests fail? I tried it on this branch and everything seems to work fine. |
||
match Self::from_canonical_bytes(bytes.as_slice()) | ||
.map_err(|e| borsh::maybestd::io::Error::new(borsh::maybestd::io::ErrorKind::InvalidInput, e.to_string())) | ||
{ | ||
Ok(k) => { | ||
bytes.zeroize(); | ||
Ok(k) | ||
}, | ||
Err(e) => { | ||
bytes.zeroize(); | ||
Err(e) | ||
}, | ||
} | ||
} | ||
} | ||
|
||
|
@@ -234,12 +244,6 @@ impl From<u64> for RistrettoSecretKey { | |
} | ||
} | ||
|
||
impl From<Scalar> for RistrettoSecretKey { | ||
fn from(s: Scalar) -> Self { | ||
RistrettoSecretKey(s) | ||
} | ||
} | ||
|
||
Comment on lines
-237
to
-242
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a breaking change. Has it been confirmed that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just checked that this doesn't introduce problems against this PR in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Probably worth updating the PR description to clarify that this is a breaking API change. |
||
//--------------------------------------------- Borrow impl -------------------------------------------------// | ||
|
||
impl<'a> Borrow<Scalar> for &'a RistrettoSecretKey { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
SecretKey
trait already enforces zeroizing on drop, so I don't think this is necessary.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you still wanted to separately enforce zeroizing on drop at the
ExtendedMask
level as a safeguard against future structural changes, you should be able to simply deriveZeroizeOnDrop
instead of this manual implementation.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See this branch for the derived traits.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, if you derive
ZeroizeOnDrop
, I'd also doZeroize
too; this will allow a caller to manually callzeroize
if they really want to. You don't getZeroize
for free forZeroizeOnDrop
.