Skip to content
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 Point and BigInt on drop, and other zeroize changes #154

Closed
wants to merge 9 commits into from
21 changes: 1 addition & 20 deletions src/arithmetic/big_gmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,11 @@
*/

use std::convert::{TryFrom, TryInto};
use std::sync::atomic;
use std::{fmt, ops, ptr};
use std::{fmt, ops};

use gmp::mpz::Mpz;
use gmp::sign::Sign;
use num_traits::{One, Zero};
use zeroize::Zeroize;

use super::errors::*;
use super::traits::*;
Expand Down Expand Up @@ -51,23 +49,6 @@ impl BigInt {
}
}

#[allow(deprecated)]
impl ZeroizeBN for BigInt {
fn zeroize_bn(&mut self) {
unsafe { ptr::write_volatile(&mut self.gmp, Mpz::zero()) };
atomic::fence(atomic::Ordering::SeqCst);
atomic::compiler_fence(atomic::Ordering::SeqCst);
}
}

impl Zeroize for BigInt {
fn zeroize(&mut self) {
unsafe { ptr::write_volatile(&mut self.gmp, Mpz::zero()) };
atomic::fence(atomic::Ordering::SeqCst);
atomic::compiler_fence(atomic::Ordering::SeqCst);
}
}

impl Converter for BigInt {
fn to_bytes(&self) -> Vec<u8> {
(&self.gmp).into()
Expand Down
31 changes: 17 additions & 14 deletions src/arithmetic/big_native.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::convert::{TryFrom, TryInto};
use std::{fmt, ops};
use core::{ptr, sync::atomic};

use num_traits::Signed;

Expand All @@ -8,6 +9,7 @@ use super::traits::*;

use num_bigint::BigInt as BN;
use num_bigint::Sign;
use zeroize::Zeroize;

mod primes;
mod ring_algorithms;
Expand All @@ -31,23 +33,24 @@ impl BigInt {
&mut self.num
}
fn into_inner(self) -> BN {
self.num
self.num.clone()
}
}

#[allow(deprecated)]
impl ZeroizeBN for BigInt {
fn zeroize_bn(&mut self) {
zeroize::Zeroize::zeroize(self)
}
}

impl zeroize::Zeroize for BigInt {
fn zeroize(&mut self) {
use std::{ptr, sync::atomic};
unsafe { ptr::write_volatile(&mut self.num, Zero::zero()) };
atomic::fence(atomic::Ordering::SeqCst);
impl Drop for BigInt {
fn drop(&mut self) {
// Copy the inner so we can read the data inside
let original = unsafe { ptr::read(&mut self.num) };
// Replace self with a zeroed integer.
unsafe { ptr::write_volatile(self, Self::zero()) };
let (mut sign, uint) = original.into_parts();
// Zero out the temp sign in case it's a secret somehow
unsafe { ptr::write_volatile(&mut sign, Sign::NoSign) };
// zero out the bigint's data itself.
// This is semi-UB because it's a repr(Rust) type, but because it's a single field we can assume it matches the wrapper.
let mut data: Vec<usize> = unsafe { core::mem::transmute(uint) };
atomic::compiler_fence(atomic::Ordering::SeqCst);
data.zeroize();
}
}

Expand Down Expand Up @@ -351,7 +354,7 @@ crate::__bigint_impl_assigns! {
impl ops::Neg for BigInt {
type Output = BigInt;
fn neg(self) -> Self::Output {
self.num.neg().wrap()
(&self.num).neg().wrap()
}
}
impl ops::Neg for &BigInt {
Expand Down
3 changes: 1 addition & 2 deletions src/arithmetic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -377,10 +377,9 @@ mod test {
T: Converter + BasicOps + Modulo + Samplable + NumberTests + EGCD + BitManipulation,
T: Primes,
// Deprecated but not deleted yet traits from self::traits module
T: ZeroizeBN,
u64: ConvertFrom<BigInt>,
// Foreign traits implementations
T: zeroize::Zeroize + num_traits::One + num_traits::Zero,
T: num_traits::One + num_traits::Zero,
T: num_traits::Num + num_integer::Integer + num_integer::Roots,
// Conversion traits
for<'a> u64: std::convert::TryFrom<&'a BigInt>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

use std::marker::PhantomData;
use zeroize::Zeroizing;

use super::traits::Commitment;
use super::SECURITY_BITS;
Expand All @@ -29,9 +30,9 @@ impl<E: Curve> Commitment<Point<E>> for PedersenCommitment<E> {
let h = Point::base_point2();
let message_scalar: Scalar<E> = Scalar::from(message);
let blinding_scalar: Scalar<E> = Scalar::from(blinding_factor);
let mg = g * message_scalar;
let rh = h * blinding_scalar;
mg + rh
let mg = Zeroizing::new(g * message_scalar);
let rh = Zeroizing::new(h * blinding_scalar);
&*mg + &*rh
}

fn create_commitment(message: &BigInt) -> (Point<E>, BigInt) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
use digest::Digest;
use serde::{Deserialize, Serialize};

use zeroize::Zeroizing;

use crate::cryptographic_primitives::hashing::DigestExt;
use crate::elliptic::curves::{Curve, Point, Scalar};
use crate::marker::HashChoice;
Expand Down Expand Up @@ -56,10 +58,10 @@ impl<E: Curve, H: Digest + Clone> HomoELGamalProof<E, H> {
) -> HomoELGamalProof<E, H> {
let s1: Scalar<E> = Scalar::random();
let s2: Scalar<E> = Scalar::random();
let A1 = &delta.H * &s1;
let A2 = &delta.Y * &s2;
let A1 = Zeroizing::new(&delta.H * &s1);
let A2 = Zeroizing::new(&delta.Y * &s2);
let A3 = &delta.G * &s2;
let T = A1 + A2;
let T = &*A1 + &*A2;
let e = H::new()
.chain_point(&T)
.chain_point(&A3)
Expand All @@ -69,14 +71,12 @@ impl<E: Curve, H: Digest + Clone> HomoELGamalProof<E, H> {
.chain_point(&delta.D)
.chain_point(&delta.E)
.result_scalar();
// dealing with zero field element
let z1 = &s1 + &w.x * &e;
let z2 = s2 + &w.r * e;
HomoELGamalProof {
T,
A3,
z1,
z2,
// dealing with zero field element
z1: &s1 + &w.x * &e,
z2: s2 + &w.r * e,
hash_choice: HashChoice::new(),
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,12 @@ impl<E: Curve, H: Digest + Clone> HomoELGamalDlogProof<E, H> {
let e = H::new()
.chain_points([&A1, &A2, &A3, &delta.G, &delta.Y, &delta.D, &delta.E])
.result_scalar();
let z1 = &s1 + &e * &w.x;
let z2 = &s2 + e * &w.r;
HomoELGamalDlogProof {
A1,
A2,
A3,
z1,
z2,
z1: &s1 + &e * &w.x,
z2: &s2 + e * &w.r,
hash_choice: HashChoice::new(),
}
}
Expand Down
3 changes: 1 addition & 2 deletions src/cryptographic_primitives/proofs/sigma_dlog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,10 @@ impl<E: Curve, H: Digest + Clone> DLogProof<E, H> {
.result_scalar();

let challenge_mul_sk = challenge * sk;
let challenge_response = &sk_t_rand_commitment - &challenge_mul_sk;
DLogProof {
pk,
pk_t_rand_commitment,
challenge_response,
challenge_response: &sk_t_rand_commitment - &challenge_mul_sk,
hash_choice: HashChoice::new(),
}
}
Expand Down
3 changes: 1 addition & 2 deletions src/cryptographic_primitives/proofs/sigma_ec_ddh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,10 @@ impl<E: Curve, H: Digest + Clone> ECDDHProof<E, H> {
.chain_point(&a1)
.chain_point(&a2)
.result_scalar();
let z = &s + e * &w.x;
ECDDHProof {
a1,
a2,
z,
z: &s + e * &w.x,
hash_choice: HashChoice::new(),
}
}
Expand Down
8 changes: 3 additions & 5 deletions src/cryptographic_primitives/proofs/sigma_valid_pedersen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,17 +56,15 @@ impl<E: Curve, H: Digest + Clone> PedersenProof<E, H> {
.result_scalar();

let em = &e * m;
let z1 = &s1 + em;
let er = &e * r;
let z2 = &s2 + er;

PedersenProof {
e,
e: e.clone(),
a1,
a2,
com,
z1,
z2,
z1: &s1 + em,
z2: &s2 + er,
hash_choice: HashChoice::new(),
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,12 @@ impl<E: Curve, H: Digest + Clone> PedersenBlindingProof<E, H> {
.result_scalar();

let er = &e * r;
let z = &s + &er;
PedersenBlindingProof {
e,
e: e.clone(),
m: m.clone(),
a,
com,
z,
z: &s + &er,
hash_choice: HashChoice::new(),
}
}
Expand Down
16 changes: 8 additions & 8 deletions src/cryptographic_primitives/secret_sharing/feldman_vss.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ pub struct ShamirSecretSharing {
/// Feldman VSS, based on Paul Feldman. 1987. A practical scheme for non-interactive verifiable secret sharing.
/// In Foundations of Computer Science, 1987., 28th Annual Symposium on.IEEE, 427–43
///
/// implementation details: The code is using FE and GE. Each party is given an index from 1,..,n and a secret share of type FE.
/// The index of the party is also the point on the polynomial where we treat this number as u32 but converting it to FE internally.
/// Implementation details: The code is generic over the curve. Each party is given an index from `1,..,n` and a secret share of type `Scalar<E>`.
/// The index of the party is also the point on the polynomial where we treat this number as `u32` but converting it to `Scalar<E>` internally.
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
#[serde(bound = "")]
pub struct VerifiableSS<E: Curve> {
Expand Down Expand Up @@ -56,7 +56,7 @@ impl<E: Curve> VerifiableSS<E> {
// generate VerifiableSS from a secret
pub fn share(t: u16, n: u16, secret: &Scalar<E>) -> (VerifiableSS<E>, SecretShares<E>) {
assert!(t < n);
let polynomial = Polynomial::<E>::sample_exact_with_fixed_const_term(t, secret.clone());
let polynomial = Polynomial::<E>::sample_exact_with_fixed_const_term(t, &secret);
let shares = polynomial.evaluate_many_bigint(1..=n).collect();

let g = Point::<E>::generator();
Expand All @@ -83,7 +83,7 @@ impl<E: Curve> VerifiableSS<E> {
let n = self.parameters.share_count;

let one = Scalar::<E>::from(1);
let poly = Polynomial::<E>::sample_exact_with_fixed_const_term(t, one.clone());
let poly = Polynomial::<E>::sample_exact_with_fixed_const_term(t, &one);
let secret_shares_biased: Vec<_> = poly.evaluate_many_bigint(1..=n).collect();
let secret_shares: Vec<_> = (0..secret_shares_biased.len())
.map(|i| &secret_shares_biased[i] - &one)
Expand Down Expand Up @@ -111,7 +111,7 @@ impl<E: Curve> VerifiableSS<E> {
) -> (VerifiableSS<E>, SecretShares<E>) {
assert_eq!(usize::from(n), index_vec.len());

let polynomial = Polynomial::<E>::sample_exact_with_fixed_const_term(t, secret.clone());
let polynomial = Polynomial::<E>::sample_exact_with_fixed_const_term(t, &secret);
let shares = polynomial
.evaluate_many_bigint(index_vec.iter().cloned())
.collect();
Expand All @@ -137,7 +137,7 @@ impl<E: Curve> VerifiableSS<E> {
// returns vector of coefficients
#[deprecated(since = "0.8.0", note = "please use Polynomial::sample instead")]
pub fn sample_polynomial(t: usize, coef0: &Scalar<E>) -> Vec<Scalar<E>> {
Polynomial::<E>::sample_exact_with_fixed_const_term(t.try_into().unwrap(), coef0.clone())
Polynomial::<E>::sample_exact_with_fixed_const_term(t.try_into().unwrap(), &coef0)
.coefficients()
.to_vec()
}
Expand All @@ -153,8 +153,8 @@ impl<E: Curve> VerifiableSS<E> {
}

#[deprecated(since = "0.8.0", note = "please use Polynomial::evaluate instead")]
pub fn mod_evaluate_polynomial(coefficients: &[Scalar<E>], point: Scalar<E>) -> Scalar<E> {
Polynomial::<E>::from_coefficients(coefficients.to_vec()).evaluate(&point)
pub fn mod_evaluate_polynomial(coefficients: &[Scalar<E>], point: &Scalar<E>) -> Scalar<E> {
Polynomial::<E>::from_coefficients(coefficients.to_vec()).evaluate(point)
}

pub fn reconstruct(&self, indices: &[u16], shares: &[Scalar<E>]) -> Scalar<E> {
Expand Down
8 changes: 4 additions & 4 deletions src/cryptographic_primitives/secret_sharing/polynomial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,16 +113,16 @@ impl<E: Curve> Polynomial<E> {
/// use curv::elliptic::curves::{Secp256k1, Scalar};
///
/// let const_term = Scalar::<Secp256k1>::random();
/// let polynomial = Polynomial::<Secp256k1>::sample_exact_with_fixed_const_term(3, const_term.clone());
/// let polynomial = Polynomial::<Secp256k1>::sample_exact_with_fixed_const_term(3, &const_term);
/// assert_eq!(polynomial.degree(), 3.into());
/// assert_eq!(polynomial.evaluate(&Scalar::zero()), const_term);
/// ```
pub fn sample_exact_with_fixed_const_term(n: u16, const_term: Scalar<E>) -> Self {
pub fn sample_exact_with_fixed_const_term(n: u16, const_term: &Scalar<E>) -> Self {
if n == 0 {
Self::from_coefficients(vec![const_term])
Self::from_coefficients(vec![const_term.clone()])
} else {
let random_coefficients = iter::repeat_with(Scalar::random).take(usize::from(n));
Self::from_coefficients(iter::once(const_term).chain(random_coefficients).collect())
Self::from_coefficients(iter::once(const_term.clone()).chain(random_coefficients).collect())
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::cryptographic_primitives::proofs::sigma_valid_pedersen_blind::Pederse
use crate::elliptic::curves::{Curve, Point, Scalar};

/// based on How To Simulate It – A Tutorial on the Simulation
/// Proof Technique. protocol 7.3: Multiple coin tossing. which provide simulatble constant round
/// Proof Technique. protocol 7.3: Multiple coin tossing. which provide simulatable constant round
/// coin toss
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(bound = "")]
Expand Down Expand Up @@ -45,8 +45,7 @@ impl<E: Curve, H: Digest + Clone> Party1FirstMessage<E, H> {
impl<E: Curve> Party2FirstMessage<E> {
pub fn share<H: Digest + Clone>(proof: &PedersenProof<E, H>) -> Party2FirstMessage<E> {
PedersenProof::verify(proof).expect("{(m,r),c} proof failed");
let seed = Scalar::random();
Party2FirstMessage { seed }
Party2FirstMessage { seed: Scalar::random() }
}
}
impl<E: Curve, H: Digest + Clone> Party1SecondMessage<E, H> {
Expand Down
Loading