diff --git a/Cargo.toml b/Cargo.toml index 217021a..9b78f15 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,14 +17,16 @@ codecov = { repository = "c0dearm/sharks" } # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [features] -default = ["std"] +default = ["std", "zeroize_memory"] std = ["rand/std", "rand/std_rng"] fuzzing = ["std", "arbitrary"] +zeroize_memory = ["zeroize"] [dependencies] rand = { version = "0.8", default-features = false } hashbrown = "0.9" arbitrary = { version = "0.4.7", features = ["derive"], optional = true } +zeroize = { version = "1.2.0", features = ["zeroize_derive"], optional = true } [dev-dependencies] criterion = "0.3" diff --git a/src/field.rs b/src/field.rs index f2d2d8c..05b4960 100644 --- a/src/field.rs +++ b/src/field.rs @@ -7,6 +7,9 @@ use core::ops::{Add, Div, Mul, Sub}; #[cfg(feature = "fuzzing")] use arbitrary::Arbitrary; +#[cfg(feature = "zeroize_memory")] +use zeroize::Zeroize; + const LOG_TABLE: [u8; 256] = [ 0x00, 0x00, 0x01, 0x19, 0x02, 0x32, 0x1a, 0xc6, 0x03, 0xdf, 0x33, 0xee, 0x1b, 0x68, 0xc7, 0x4b, 0x04, 0x64, 0xe0, 0x0e, 0x34, 0x8d, 0xef, 0x81, 0x1c, 0xc1, 0x69, 0xf8, 0xc8, 0x08, 0x4c, 0x71, @@ -61,8 +64,10 @@ const EXP_TABLE: [u8; 512] = [ 0x58, 0xb0, 0x7d, 0xfa, 0xe9, 0xcf, 0x83, 0x1b, 0x36, 0x6c, 0xd8, 0xad, 0x47, 0x8e, 0x01, 0x02, ]; -#[derive(Debug, PartialEq, Copy, Clone)] +#[derive(Debug, PartialEq, Clone)] #[cfg_attr(feature = "fuzzing", derive(Arbitrary))] +#[cfg_attr(feature = "zeroize_memory", derive(Zeroize))] +#[cfg_attr(feature = "zeroize_memory", zeroize(drop))] pub struct GF256(pub u8); #[allow(clippy::suspicious_arithmetic_impl)] diff --git a/src/lib.rs b/src/lib.rs index e32f44e..b76467c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -201,7 +201,7 @@ mod tests { let sharks = Sharks(255); let mut shares: Vec = sharks.make_shares(&[1]).take(255).collect(); shares[1] = Share { - x: shares[0].x, + x: shares[0].x.clone(), y: shares[0].y.clone(), }; let secret = sharks.recover(&shares); diff --git a/src/math.rs b/src/math.rs index 7279018..ee69252 100644 --- a/src/math.rs +++ b/src/math.rs @@ -20,9 +20,9 @@ pub fn interpolate(shares: &[Share]) -> Vec { shares .iter() .filter(|s_j| s_j.x != s_i.x) - .map(|s_j| s_j.x / (s_j.x - s_i.x)) + .map(|s_j| s_j.x.clone() / (s_j.x.clone() - s_i.x.clone())) .product::() - * s_i.y[s] + * s_i.y[s].clone() }) .sum::() .0 @@ -51,10 +51,13 @@ pub fn random_polynomial(s: GF256, k: u8, rng: &mut R) -> Vec>) -> impl Iterator { (1..=u8::max_value()).map(GF256).map(move |x| Share { - x, + x: x.clone(), y: polys .iter() - .map(|p| p.iter().fold(GF256(0), |acc, c| acc * x + *c)) + .map(|p| { + p.iter() + .fold(GF256(0), |acc, c| acc * x.clone() + c.clone()) + }) .collect(), }) } @@ -76,7 +79,7 @@ mod tests { #[test] fn evaluator_works() { let iter = get_evaluator(vec![vec![GF256(3), GF256(2), GF256(5)]]); - let values: Vec<_> = iter.take(2).map(|s| (s.x, s.y)).collect(); + let values: Vec<_> = iter.take(2).map(|s| (s.x.clone(), s.y.clone())).collect(); assert_eq!( values, vec![(GF256(1), vec![GF256(4)]), (GF256(2), vec![GF256(13)])] diff --git a/src/share.rs b/src/share.rs index 869adc8..c9d1592 100644 --- a/src/share.rs +++ b/src/share.rs @@ -5,6 +5,9 @@ use super::field::GF256; #[cfg(feature = "fuzzing")] use arbitrary::Arbitrary; +#[cfg(feature = "zeroize_memory")] +use zeroize::Zeroize; + /// A share used to reconstruct the secret. Can be serialized to and from a byte array. /// /// Usage example: @@ -31,6 +34,8 @@ use arbitrary::Arbitrary; /// let secret = sharks.recover(&shares).unwrap(); #[derive(Clone)] #[cfg_attr(feature = "fuzzing", derive(Arbitrary, Debug))] +#[cfg_attr(feature = "zeroize_memory", derive(Zeroize))] +#[cfg_attr(feature = "zeroize_memory", zeroize(drop))] pub struct Share { pub x: GF256, pub y: Vec,