Remove try_ methods.

master
Andreas Fackler 7 years ago committed by Andreas Fackler
parent ad11ceaed6
commit 214e5f81cf
  1. 84
      src/lib.rs
  2. 110
      src/poly.rs
  3. 8
      src/secret.rs

@ -230,18 +230,16 @@ pub struct SecretKey(Box<Fr>);
impl Default for SecretKey { impl Default for SecretKey {
fn default() -> Self { fn default() -> Self {
let mut fr = Fr::zero(); let mut fr = Fr::zero();
SecretKey::try_from_mut(&mut fr) SecretKey::from_mut(&mut fr)
.unwrap_or_else(|e| panic!("Failed to create default `SecretKey`: {}", e))
} }
} }
/// Creates a random `SecretKey` from a given RNG. If you do not need to specify your own RNG, you /// Creates a random `SecretKey` from a given RNG. If you do not need to specify your own RNG, you
/// should use `SecretKey::random()` or `SecretKey::try_random()` as your constructor instead. /// should use `SecretKey::random()` as your constructor instead.
impl Rand for SecretKey { impl Rand for SecretKey {
fn rand<R: Rng>(rng: &mut R) -> Self { fn rand<R: Rng>(rng: &mut R) -> Self {
let mut fr = Fr::rand(rng); let mut fr = Fr::rand(rng);
SecretKey::try_from_mut(&mut fr) SecretKey::from_mut(&mut fr)
.unwrap_or_else(|e| panic!("Failed to create random `SecretKey`: {}", e))
} }
} }
@ -249,16 +247,11 @@ impl Rand for SecretKey {
impl Clone for SecretKey { impl Clone for SecretKey {
fn clone(&self) -> Self { fn clone(&self) -> Self {
let mut fr = *self.0; let mut fr = *self.0;
SecretKey::try_from_mut(&mut fr) SecretKey::from_mut(&mut fr)
.unwrap_or_else(|e| panic!("Failed to clone `SecretKey`: {}", e))
} }
} }
/// Zeroes out and unlocks the memory allocated from the `SecretKey`'s field element. /// Zeroes out and unlocks the memory allocated from the `SecretKey`'s field element.
///
/// # Panics
///
/// Panics if we fail to unlock the memory containing the field element.
impl Drop for SecretKey { impl Drop for SecretKey {
fn drop(&mut self) { fn drop(&mut self) {
self.zero_secret(); self.zero_secret();
@ -288,54 +281,25 @@ impl SecretKey {
/// *WARNING* this constructor will overwrite the referenced `Fr` element with zeros after it /// *WARNING* this constructor will overwrite the referenced `Fr` element with zeros after it
/// has been copied onto the heap. /// has been copied onto the heap.
pub fn from_mut(fr: &mut Fr) -> Self { pub fn from_mut(fr: &mut Fr) -> Self {
SecretKey::try_from_mut(fr)
.unwrap_or_else(|e| panic!("Falied to create `SecretKey`: {}", e))
}
/// Creates a new `SecretKey` from a mutable reference to a field element. This constructor
/// takes a reference to avoid any unnecessary stack copying/moving of secrets (i.e. the field
/// element). The field element is copied bytewise onto the heap, the resulting `Box` is
/// stored in the returned `SecretKey`.
///
/// This constructor is identical to `SecretKey::from_mut()` in every way except that this
/// constructor will return an `Err` where `SecretKey::from_mut()` would panic.
///
/// *WARNING* this constructor will overwrite the referenced `Fr` element with zeros after it
/// has been copied onto the heap.
pub fn try_from_mut(fr: &mut Fr) -> Result<Self> {
let fr_ptr = fr as *mut Fr; let fr_ptr = fr as *mut Fr;
let mut boxed_fr = Box::new(Fr::zero()); let mut boxed_fr = Box::new(Fr::zero());
unsafe { unsafe {
copy_nonoverlapping(fr_ptr, &mut *boxed_fr as *mut Fr, 1); copy_nonoverlapping(fr_ptr, &mut *boxed_fr as *mut Fr, 1);
} }
clear_fr(fr_ptr); clear_fr(fr_ptr);
let sk = SecretKey(boxed_fr); SecretKey(boxed_fr)
Ok(sk)
} }
/// Creates a new random instance of `SecretKey`. If you want to use/define your own random /// Creates a new random instance of `SecretKey`. If you want to use/define your own random
/// number generator, you should use the constructor: `SecretKey::rand()`. If you do not need /// number generator, you should use the constructor: `SecretKey::rand()`. If you do not need
/// to specify your own RNG, you should use the `SecretKey::random()` and /// to specify your own RNG, you should use the `SecretKey::random()` constructor, which uses
/// `SecretKey::try_random()` constructors, which use
/// [`rand::thead_rng()`](https://docs.rs/rand/0.4.3/rand/fn.thread_rng.html) internally as /// [`rand::thead_rng()`](https://docs.rs/rand/0.4.3/rand/fn.thread_rng.html) internally as
/// their RNG. /// its RNG.
pub fn random() -> Self { pub fn random() -> Self {
let mut rng = rand::thread_rng(); let mut rng = rand::thread_rng();
SecretKey::rand(&mut rng) SecretKey::rand(&mut rng)
} }
/// Creates a new random instance of `SecretKey`. If you want to use/define your own random
/// number generator, you should use the constructor: `SecretKey::rand()`. If you do not need
/// to specify your own RNG, you should use the `SecretKey::random()` and
/// `SecretKey::try_random()` constructors, which use
/// [`rand::thead_rng()`](https://docs.rs/rand/0.4.3/rand/fn.thread_rng.html) internally as
/// their RNG.
pub fn try_random() -> Result<Self> {
let mut rng = rand::thread_rng();
let mut fr = Fr::rand(&mut rng);
SecretKey::try_from_mut(&mut fr)
}
/// Returns the matching public key. /// Returns the matching public key.
pub fn public_key(&self) -> PublicKey { pub fn public_key(&self) -> PublicKey {
PublicKey(G1Affine::one().mul(*self.0)) PublicKey(G1Affine::one().mul(*self.0))
@ -390,21 +354,7 @@ impl SecretKeyShare {
/// *WARNING* this constructor will overwrite the pointed to `Fr` element with zeros once it /// *WARNING* this constructor will overwrite the pointed to `Fr` element with zeros once it
/// has been copied into a new `SecretKeyShare`. /// has been copied into a new `SecretKeyShare`.
pub fn from_mut(fr: &mut Fr) -> Self { pub fn from_mut(fr: &mut Fr) -> Self {
match SecretKey::try_from_mut(fr) { SecretKeyShare(SecretKey::from_mut(fr))
Ok(sk) => SecretKeyShare(sk),
Err(e) => panic!(
"Failed to create `SecretKeyShare` from field element: {}",
e
),
}
}
/// Creates a new `SecretKeyShare` from a mutable reference to a field element. This
/// constructor takes a reference to avoid any unnecessary stack copying/moving of secrets
/// field elements. The field element will be copied bytewise onto the heap, the resulting
/// `Box` is stored in the `SecretKey` which is then wrapped in a `SecretKeyShare`.
pub fn try_from_mut(fr: &mut Fr) -> Result<Self> {
SecretKey::try_from_mut(fr).map(SecretKeyShare)
} }
/// Returns the matching public key share. /// Returns the matching public key share.
@ -559,6 +509,10 @@ impl SecretKeySet {
/// Creates a set of secret key shares, where any `threshold + 1` of them can collaboratively /// Creates a set of secret key shares, where any `threshold + 1` of them can collaboratively
/// sign and decrypt. This constuctor is identical to the `SecretKey::try_random()` in every /// sign and decrypt. This constuctor is identical to the `SecretKey::try_random()` in every
/// way except that this constructor panics if the other returns an error. /// way except that this constructor panics if the other returns an error.
///
/// # Panic
///
/// Panics if the `threshold` is too large for the coefficients to fit into a `Vec`.
pub fn random<R: Rng>(threshold: usize, rng: &mut R) -> Self { pub fn random<R: Rng>(threshold: usize, rng: &mut R) -> Self {
SecretKeySet::try_random(threshold, rng) SecretKeySet::try_random(threshold, rng)
.unwrap_or_else(|e| panic!("Failed to create random `SecretKeySet`: {}", e)) .unwrap_or_else(|e| panic!("Failed to create random `SecretKeySet`: {}", e))
@ -577,20 +531,10 @@ impl SecretKeySet {
self.poly.degree() self.poly.degree()
} }
/// Returns the `i`-th secret key share. This method is identical to the /// Returns the `i`-th secret key share.
/// `.try_secret_key_share()` in every way except that this method panics if
/// where `.try_secret_key_share()` would return an `Err`.
pub fn secret_key_share<T: IntoFr>(&self, i: T) -> SecretKeyShare { pub fn secret_key_share<T: IntoFr>(&self, i: T) -> SecretKeyShare {
self.try_secret_key_share(i)
.unwrap_or_else(|e| panic!("Failed to create `SecretKeyShare`: {}", e))
}
/// Returns the `i`-th secret key share. This method is identical to the method
/// `.secret_key_share()` in every way except that this method returns an `Err` if
/// where `.secret_key_share()` would panic.
pub fn try_secret_key_share<T: IntoFr>(&self, i: T) -> Result<SecretKeyShare> {
let mut fr = self.poly.evaluate(into_fr_plus_1(i)); let mut fr = self.poly.evaluate(into_fr_plus_1(i));
SecretKeyShare::try_from_mut(&mut fr) SecretKeyShare::from_mut(&mut fr)
} }
/// Returns the corresponding public key set. That information can be shared publicly. /// Returns the corresponding public key set. That information can be shared publicly.

@ -41,8 +41,7 @@ pub struct Poly {
/// Creates a new `Poly` with the same coefficients as another polynomial. /// Creates a new `Poly` with the same coefficients as another polynomial.
impl Clone for Poly { impl Clone for Poly {
fn clone(&self) -> Self { fn clone(&self) -> Self {
Poly::try_from(self.coeff.clone()) Poly::from(self.coeff.clone())
.unwrap_or_else(|e| panic!("Failed to clone `Poly`: {}", e))
} }
} }
@ -177,8 +176,7 @@ impl<'a, B: Borrow<Poly>> ops::Mul<B> for &'a Poly {
coeffs[i + j].add_assign(&*tmp); coeffs[i + j].add_assign(&*tmp);
} }
} }
Poly::try_from(coeffs) Poly::from(coeffs)
.unwrap_or_else(|e| panic!("Failed to create a new `Poly` during muliplication: {}", e))
} }
} }
@ -265,8 +263,8 @@ impl Drop for Poly {
/// Creates a new `Poly` instance from a vector of prime field elements representing the /// Creates a new `Poly` instance from a vector of prime field elements representing the
/// coefficients of the polynomial. /// coefficients of the polynomial.
impl From<Vec<Fr>> for Poly { impl From<Vec<Fr>> for Poly {
fn from(coeffs: Vec<Fr>) -> Self { fn from(coeff: Vec<Fr>) -> Self {
Poly::try_from(coeffs).unwrap_or_else(|e| panic!("Failed to create `Poly`: {}", e)) Poly { coeff }
} }
} }
@ -279,16 +277,11 @@ impl ContainsSecret for Poly {
} }
impl Poly { impl Poly {
/// Creates a new `Poly` instance from a vector of prime field elements representing the /// Creates a random polynomial.
/// coefficients of the polynomial. ///
pub fn try_from(coeff: Vec<Fr>) -> Result<Self> { /// # Panics
let poly = Poly { coeff }; ///
Ok(poly) /// Panics if the `degree` is too large for the coefficients to fit into a `Vec`.
}
/// Creates a random polynomial. This constructor is identical to the `Poly::try_random()`
/// constructor in every way except that this constructor will panic where `random` would
/// return an error.
pub fn random<R: Rng>(degree: usize, rng: &mut R) -> Self { pub fn random<R: Rng>(degree: usize, rng: &mut R) -> Self {
Poly::try_random(degree, rng) Poly::try_random(degree, rng)
.unwrap_or_else(|e| panic!("Failed to create random `Poly`: {}", e)) .unwrap_or_else(|e| panic!("Failed to create random `Poly`: {}", e))
@ -302,7 +295,7 @@ impl Poly {
return Err(Error::DegreeTooHigh); return Err(Error::DegreeTooHigh);
} }
let coeff: Vec<Fr> = (0..=degree).map(|_| rng.gen()).collect(); let coeff: Vec<Fr> = (0..=degree).map(|_| rng.gen()).collect();
Poly::try_from(coeff) Ok(Poly::from(coeff))
} }
/// Returns the polynomial with constant value `0`. /// Returns the polynomial with constant value `0`.
@ -315,19 +308,9 @@ impl Poly {
self.coeff.iter().all(|coeff| coeff.is_zero()) self.coeff.iter().all(|coeff| coeff.is_zero())
} }
/// Returns the polynomial with constant value `1`. This constructor is identical to /// Returns the polynomial with constant value `1`.
/// `Poly::try_one()` in every way except that this constructor panics where `Poly::try_one()`
/// would return an `Err`.
pub fn one() -> Self { pub fn one() -> Self {
Poly::try_one() Poly::constant(Fr::one())
.unwrap_or_else(|e| panic!("Failed to create constant `Poly` of value 1: {}", e))
}
/// Returns the polynomial with constant value `1`. This constructor is identical to
/// `Poly::one()` in every way except that this constructor returns `Err` if where `Poly::one()`
/// would panic.
pub fn try_one() -> Result<Self> {
Poly::try_constant(Fr::one())
} }
/// Returns the polynomial with constant value `c`. /// Returns the polynomial with constant value `c`.
@ -336,69 +319,28 @@ impl Poly {
// overwrite that portion of memory with zeros once we have copied the element onto the // overwrite that portion of memory with zeros once we have copied the element onto the
// heap as part of the vector of polynomial coefficients. // heap as part of the vector of polynomial coefficients.
let fr_ptr = &c as *const Fr; let fr_ptr = &c as *const Fr;
let poly = Poly::try_from(vec![c]) let poly = Poly::from(vec![c]);
.unwrap_or_else(|e| panic!("Failed to create constant `Poly`: {}", e));
clear_fr(fr_ptr); clear_fr(fr_ptr);
poly poly
} }
/// Returns the polynomial with constant value `c`. This constructor is identical to
/// `Poly::constant()` in every way except that this constructor returns an `Err` where
/// `constant` would panic.
pub fn try_constant(c: Fr) -> Result<Self> {
// We create a raw pointer to the field element within this method's stack frame so we can
// overwrite that portion of memory with zeros once we have copied the element onto the
// heap as part of polynomials `coeff` vector.
let fr_ptr = &c as *const Fr;
let res = Poly::try_from(vec![c]);
clear_fr(fr_ptr);
res
}
/// Returns the identity function, i.e. the polynomial "`x`". /// Returns the identity function, i.e. the polynomial "`x`".
pub fn identity() -> Self { pub fn identity() -> Self {
Poly::monomial(1) Poly::monomial(1)
} }
/// Returns the identity function, i.e. the polynomial `x`.
pub fn try_identity() -> Result<Self> {
Poly::try_monomial(1)
}
/// Returns the (monic) monomial: `x.pow(degree)`. /// Returns the (monic) monomial: `x.pow(degree)`.
pub fn monomial(degree: usize) -> Self { pub fn monomial(degree: usize) -> Self {
Poly::try_monomial(degree).unwrap_or_else(|e| {
panic!(
"Failed to create monomial `Poly` of degree {}: {}",
degree, e
)
})
}
/// Returns the (monic) monomial: `x.pow(degree)`.
pub fn try_monomial(degree: usize) -> Result<Self> {
let coeff: Vec<Fr> = iter::repeat(Fr::zero()) let coeff: Vec<Fr> = iter::repeat(Fr::zero())
.take(degree) .take(degree)
.chain(iter::once(Fr::one())) .chain(iter::once(Fr::one()))
.collect(); .collect();
Poly::try_from(coeff) Poly::from(coeff)
} }
/// Returns the unique polynomial `f` of degree `samples.len() - 1` with the given values /// Returns the unique polynomial `f` of degree `samples.len() - 1` with the given values
/// `(x, f(x))`. /// `(x, f(x))`.
pub fn interpolate<T, U, I>(samples_repr: I) -> Self pub fn interpolate<T, U, I>(samples_repr: I) -> Self
where
I: IntoIterator<Item = (T, U)>,
T: IntoFr,
U: IntoFr,
{
Poly::try_interpolate(samples_repr)
.unwrap_or_else(|e| panic!("Failed to interpolate `Poly`: {}", e))
}
/// Returns the unique polynomial `f` of degree `samples.len() - 1` with the given values
/// `(x, f(x))`.
pub fn try_interpolate<T, U, I>(samples_repr: I) -> Result<Self>
where where
I: IntoIterator<Item = (T, U)>, I: IntoIterator<Item = (T, U)>,
T: IntoFr, T: IntoFr,
@ -445,16 +387,16 @@ impl Poly {
/// Returns the unique polynomial `f` of degree `samples.len() - 1` with the given values /// Returns the unique polynomial `f` of degree `samples.len() - 1` with the given values
/// `(x, f(x))`. /// `(x, f(x))`.
fn compute_interpolation(samples: &[(Fr, Fr)]) -> Result<Self> { fn compute_interpolation(samples: &[(Fr, Fr)]) -> Self {
if samples.is_empty() { if samples.is_empty() {
return Ok(Poly::zero()); return Poly::zero();
} }
// Interpolates on the first `i` samples. // Interpolates on the first `i` samples.
let mut poly = Poly::try_constant(samples[0].1)?; let mut poly = Poly::constant(samples[0].1);
let mut minus_s0 = samples[0].0; let mut minus_s0 = samples[0].0;
minus_s0.negate(); minus_s0.negate();
// Is zero on the first `i` samples. // Is zero on the first `i` samples.
let mut base = Poly::try_from(vec![minus_s0, Fr::one()])?; let mut base = Poly::from(vec![minus_s0, Fr::one()]);
// We update `base` so that it is always zero on all previous samples, and `poly` so that // We update `base` so that it is always zero on all previous samples, and `poly` so that
// it has the correct values on the previous samples. // it has the correct values on the previous samples.
@ -471,9 +413,9 @@ impl Poly {
// Finally, multiply `base` by X - x, so that it is zero at `x`, too, now. // Finally, multiply `base` by X - x, so that it is zero at `x`, too, now.
let mut minus_x = *x; let mut minus_x = *x;
minus_x.negate(); minus_x.negate();
base *= Poly::try_from(vec![minus_x, Fr::one()])?; base *= Poly::from(vec![minus_x, Fr::one()]);
} }
Ok(poly) poly
} }
/// Generates a non-redacted debug string. This method differs from /// Generates a non-redacted debug string. This method differs from
@ -603,6 +545,10 @@ impl ContainsSecret for BivarPoly {
} }
impl BivarPoly { impl BivarPoly {
/// Creates a random polynomial. /// Creates a random polynomial.
///
/// # Panics
///
/// Panics if the degree is too high for the coefficients to fit into a `Vec`.
pub fn random<R: Rng>(degree: usize, rng: &mut R) -> Self { pub fn random<R: Rng>(degree: usize, rng: &mut R) -> Self {
BivarPoly::try_random(degree, rng).unwrap_or_else(|e| { BivarPoly::try_random(degree, rng).unwrap_or_else(|e| {
panic!( panic!(
@ -649,12 +595,6 @@ impl BivarPoly {
/// Returns the `x`-th row, as a univariate polynomial. /// Returns the `x`-th row, as a univariate polynomial.
pub fn row<T: IntoFr>(&self, x: T) -> Poly { pub fn row<T: IntoFr>(&self, x: T) -> Poly {
self.try_row(x)
.unwrap_or_else(|e| panic!("Failed to create `Poly` from row of `BivarPoly: {}`", e))
}
/// Returns the `x`-th row, as a univariate polynomial.
pub fn try_row<T: IntoFr>(&self, x: T) -> Result<Poly> {
let x_pow = self.powers(x); let x_pow = self.powers(x);
let coeff: Vec<Fr> = (0..=self.degree) let coeff: Vec<Fr> = (0..=self.degree)
.map(|i| { .map(|i| {
@ -668,7 +608,7 @@ impl BivarPoly {
} }
result result
}).collect(); }).collect();
Poly::try_from(coeff) Poly::from(coeff)
} }
/// Returns the corresponding commitment. That information can be shared publicly. /// Returns the corresponding commitment. That information can be shared publicly.

@ -7,8 +7,6 @@ use std::ops::{Deref, DerefMut};
use memsec::memzero; use memsec::memzero;
use Fr; use Fr;
use error::Result;
lazy_static! { lazy_static! {
/// The size in bytes of a single field element. /// The size in bytes of a single field element.
pub(crate) static ref FR_SIZE: usize = size_of::<Fr>(); pub(crate) static ref FR_SIZE: usize = size_of::<Fr>();
@ -89,10 +87,6 @@ where
T: DerefMut, T: DerefMut,
{ {
pub(crate) fn new(x: T) -> Self { pub(crate) fn new(x: T) -> Self {
Safe::try_new(x).unwrap_or_else(|e| panic!("Failed to create `Safe`: {}", e)) Safe(x)
}
pub(crate) fn try_new(x: T) -> Result<Self> {
Ok(Safe(x))
} }
} }

Loading…
Cancel
Save