Clean up and add parity codec support (#91)
* clean Cargo.toml and add parity codec support * upgrade parity codec * fix travis * make clippy happy * use zeroize instead of memsec * fix zeroize and add test * Update .travis.yml * improve codec support * fix * add TODO for removing clear_frmaster
parent
48c7b7bd40
commit
036b720b7f
@ -0,0 +1,27 @@ |
|||||||
|
#[macro_export] |
||||||
|
/// implement parity codec for type
|
||||||
|
macro_rules! impl_codec_for { |
||||||
|
($type:ty) => { |
||||||
|
impl codec::Encode for $type { |
||||||
|
fn encode(&self) -> Vec<u8> { |
||||||
|
let encoded = bincode::serialize(&self).unwrap(); |
||||||
|
codec::Encode::encode(&encoded) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl codec::Decode for $type { |
||||||
|
fn decode<I: codec::Input>(value: &mut I) -> std::result::Result<Self, codec::Error> { |
||||||
|
let decoded: Vec<u8> = codec::Decode::decode(value)?; |
||||||
|
bincode::deserialize(decoded.as_slice()).map_err(|_| codec::Error) |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
use crate::{Ciphertext, DecryptionShare, PublicKey, PublicKeySet, Signature}; |
||||||
|
|
||||||
|
impl_codec_for!(PublicKey); |
||||||
|
impl_codec_for!(Signature); |
||||||
|
impl_codec_for!(DecryptionShare); |
||||||
|
impl_codec_for!(PublicKeySet); |
||||||
|
impl_codec_for!(Ciphertext); |
@ -1,90 +1,32 @@ |
|||||||
//! Utilities for working with secret values. This module includes functionality for overwriting
|
//! Utilities for working with secret values. This module includes functionality for overwriting
|
||||||
//! memory with zeros.
|
//! memory with zeros.
|
||||||
|
|
||||||
use std::mem::{size_of, size_of_val}; |
use zeroize::Zeroize; |
||||||
use std::ops::{Deref, DerefMut}; |
|
||||||
|
|
||||||
use memsec::memzero; |
use crate::{Fr, FrRepr}; |
||||||
|
|
||||||
use crate::Fr; |
|
||||||
|
|
||||||
pub(crate) const FR_SIZE: usize = size_of::<Fr>(); |
|
||||||
|
|
||||||
/// Overwrites a single field element with zeros.
|
/// Overwrites a single field element with zeros.
|
||||||
pub(crate) fn clear_fr(fr_ptr: *const Fr) { |
pub(crate) fn clear_fr(fr: &mut Fr) { |
||||||
unsafe { memzero(fr_ptr as *mut u8, FR_SIZE) }; |
// TODO: Remove this after pairing support `Zeroize`
|
||||||
} |
let fr_repr = unsafe { &mut *(fr as *mut Fr as *mut FrRepr) }; |
||||||
|
fr_repr.0.zeroize(); |
||||||
pub(crate) struct MemRange { |
|
||||||
pub ptr: *mut u8, |
|
||||||
pub n_bytes: usize, |
|
||||||
} |
|
||||||
|
|
||||||
/// Marks a type as containing some secret value.
|
|
||||||
pub(crate) trait ContainsSecret { |
|
||||||
/// Returns the range of memory marked as secret.
|
|
||||||
fn secret_memory(&self) -> MemRange; |
|
||||||
|
|
||||||
/// Overwrites the secret region of memory with zeros.
|
|
||||||
///
|
|
||||||
/// This method should be called upon destruction of every type that implements `ContainsSecret`.
|
|
||||||
fn zero_secret(&self) { |
|
||||||
let MemRange { ptr, n_bytes } = self.secret_memory(); |
|
||||||
unsafe { memzero(ptr, n_bytes) }; |
|
||||||
} |
|
||||||
} |
} |
||||||
|
|
||||||
/// A wrapper around temporary values to ensure that they are cleared on drop.
|
#[cfg(test)] |
||||||
///
|
mod tests { |
||||||
/// `Safe<T>` is meant to be used a wrapper around `T`, where `T` is either an `&mut U` or
|
use super::*; |
||||||
/// `Box<U>`.
|
use pairing::Field; |
||||||
pub(crate) struct Safe<T: DerefMut>(T); |
use rand::thread_rng; |
||||||
|
use rand04_compat::RngExt; |
||||||
|
|
||||||
impl<T> Deref for Safe<T> |
#[test] |
||||||
where |
fn test_clear() { |
||||||
T: DerefMut, |
let mut rng = thread_rng(); |
||||||
{ |
|
||||||
type Target = T::Target; |
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target { |
let mut fr: Fr = rng.gen04(); |
||||||
&*(self.0) |
assert_ne!(fr, Fr::zero()); |
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
impl<T> DerefMut for Safe<T> |
|
||||||
where |
|
||||||
T: DerefMut, |
|
||||||
{ |
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target { |
|
||||||
&mut *(self.0) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
impl<T> Drop for Safe<T> |
|
||||||
where |
|
||||||
T: DerefMut, |
|
||||||
{ |
|
||||||
fn drop(&mut self) { |
|
||||||
self.zero_secret(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
impl<T> ContainsSecret for Safe<T> |
|
||||||
where |
|
||||||
T: DerefMut, |
|
||||||
{ |
|
||||||
fn secret_memory(&self) -> MemRange { |
|
||||||
let ptr = &*self.0 as *const T::Target as *mut u8; |
|
||||||
let n_bytes = size_of_val(&*self.0); |
|
||||||
MemRange { ptr, n_bytes } |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
impl<T> Safe<T> |
clear_fr(&mut fr); |
||||||
where |
assert_eq!(fr, Fr::zero()); |
||||||
T: DerefMut, |
|
||||||
{ |
|
||||||
pub(crate) fn new(x: T) -> Self { |
|
||||||
Safe(x) |
|
||||||
} |
} |
||||||
} |
} |
||||||
|
Loading…
Reference in new issue