Adding share_num field to errors.

This commit is contained in:
Frederic Jacobs
2016-12-20 23:10:47 +01:00
committed by GitHub
parent f5ab309dd6
commit ef4d525703
8 changed files with 250 additions and 119 deletions

48
Cargo.lock generated
View File

@ -2,20 +2,20 @@
name = "rusty_secrets"
version = "0.0.3"
dependencies = [
"merkle_sigs 0.1.0 (git+https://github.com/SpinResearch/merkle_sigs.rs)",
"merkle_sigs 1.0.0 (git+https://github.com/SpinResearch/merkle_sigs.rs)",
"protobuf 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
"ring 0.6.0-alpha (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.21 (registry+https://github.com/rust-lang/crates.io-index)",
"ring 0.6.0-alpha1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "lamport_sigs"
version = "0.1.1"
source = "git+https://github.com/SpinResearch/lamport.rs#4ddf030e1514383d13dc86b75c4c239a4935dc48"
version = "1.0.0"
source = "git+https://github.com/SpinResearch/lamport.rs#9f9fdb749fc62b20404aa4430369e473212c6147"
dependencies = [
"rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
"ring 0.6.0-alpha (registry+https://github.com/rust-lang/crates.io-index)",
"ring 0.6.0-alpha1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -25,26 +25,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "libc"
version = "0.2.17"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "merkle"
version = "0.1.0"
source = "git+https://github.com/SpinResearch/merkle.rs#450325872473884e73790ebd6cf50fa9ce0b8aa8"
version = "1.0.0"
source = "git+https://github.com/SpinResearch/merkle.rs#249234cacaf2891ee4371846b6a32bfae0743ab9"
dependencies = [
"protobuf 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)",
"ring 0.6.0-alpha (registry+https://github.com/rust-lang/crates.io-index)",
"ring 0.6.0-alpha1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "merkle_sigs"
version = "0.1.0"
source = "git+https://github.com/SpinResearch/merkle_sigs.rs#ae2e85ab6d694eaed4c5488964af64ffce7bd0f7"
version = "1.0.0"
source = "git+https://github.com/SpinResearch/merkle_sigs.rs#c9125872e759405e55cdf0609f5c32fece181793"
dependencies = [
"lamport_sigs 0.1.1 (git+https://github.com/SpinResearch/lamport.rs)",
"merkle 0.1.0 (git+https://github.com/SpinResearch/merkle.rs)",
"ring 0.6.0-alpha (registry+https://github.com/rust-lang/crates.io-index)",
"lamport_sigs 1.0.0 (git+https://github.com/SpinResearch/lamport.rs)",
"merkle 1.0.0 (git+https://github.com/SpinResearch/merkle.rs)",
"ring 0.6.0-alpha1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -57,12 +57,12 @@ name = "rand"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "ring"
version = "0.6.0-alpha"
version = "0.6.0-alpha1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -71,7 +71,7 @@ dependencies = [
[[package]]
name = "rustc-serialize"
version = "0.3.21"
version = "0.3.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -80,13 +80,13 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum lamport_sigs 0.1.1 (git+https://github.com/SpinResearch/lamport.rs)" = "<none>"
"checksum lamport_sigs 1.0.0 (git+https://github.com/SpinResearch/lamport.rs)" = "<none>"
"checksum lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6abe0ee2e758cd6bc8a2cd56726359007748fbf4128da998b65d0b70f881e19b"
"checksum libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)" = "044d1360593a78f5c8e5e710beccdc24ab71d1f01bc19a29bcacdba22e8475d8"
"checksum merkle 0.1.0 (git+https://github.com/SpinResearch/merkle.rs)" = "<none>"
"checksum merkle_sigs 0.1.0 (git+https://github.com/SpinResearch/merkle_sigs.rs)" = "<none>"
"checksum libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "a51822fc847e7a8101514d1d44e354ba2ffa7d4c194dcab48870740e327cac70"
"checksum merkle 1.0.0 (git+https://github.com/SpinResearch/merkle.rs)" = "<none>"
"checksum merkle_sigs 1.0.0 (git+https://github.com/SpinResearch/merkle_sigs.rs)" = "<none>"
"checksum protobuf 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "6ec4c2fe04370298218a09ab53a534febf54c160c5554e4de987b6d73c916d5d"
"checksum rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "022e0636ec2519ddae48154b028864bdce4eaf7d35226ab8e65c611be97b189d"
"checksum ring 0.6.0-alpha (registry+https://github.com/rust-lang/crates.io-index)" = "756e9bcca47cd772b23f9958ea0952a18a5a3e294e4ab3b7d019e6c06955f191"
"checksum rustc-serialize 0.3.21 (registry+https://github.com/rust-lang/crates.io-index)" = "bff9fc1c79f2dec76b253273d07682e94a978bd8f132ded071188122b2af9818"
"checksum ring 0.6.0-alpha1 (registry+https://github.com/rust-lang/crates.io-index)" = "0c9d14fdd6779c80311183b64598d57e640993fd1732119ce2cedb3234217532"
"checksum rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "237546c689f20bb44980270c73c3b9edd0891c1be49cc1274406134a66d3957b"
"checksum untrusted 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "193df64312e3515fd983ded55ad5bcaa7647a035804828ed757e832ce6029ef3"

View File

@ -1,27 +1,100 @@
use std::convert;
use std::error;
use std::error::Error;
use std::fmt;
use std::io;
use std::num;
/// Error struct used for generating an `io::Error` from a generic description.
#[derive(Debug)]
pub struct Error {
pub struct RustyError {
descr: &'static str,
detail: Option<String>,
share_num: Option<u8>,
share_groups: Option<Vec<Vec<u8>>>
}
impl Error {
pub enum RustyErrorTypes {
DuplicateShareNum(u8),
DuplicateShareData(u8),
EmptyShares,
IncompatibleSets(Vec<Vec<u8>>),
InvalidSignature(u8, String),
MissingShares(u8, usize),
MissingSignature(u8),
ShareParsingError(u8, String)
}
impl RustyError {
/// Initializes a new error with a description and optional detail string.
pub fn new(descr: &'static str, detail: Option<String>) -> Error {
Error {
fn new(descr: &'static str, detail: Option<String>, share_num: Option<u8>, share_groups: Option<Vec<Vec<u8>>>) -> RustyError {
RustyError {
descr: descr,
detail: detail,
share_num: share_num,
share_groups: share_groups
}
}
pub fn with_type(error_type: RustyErrorTypes) -> RustyError {
RustyError {
descr: RustyError::descr_for_type(&error_type),
detail: RustyError::detail_for_type(&error_type),
share_num: RustyError::share_num_for_type(&error_type),
share_groups: RustyError::share_groups_for_type(error_type),
}
}
pub fn share_num(&self) -> Option<u8> {
self.share_num
}
pub fn share_groups(&self) -> Option<Vec<Vec<u8>>> {
self.share_groups.clone()
}
fn descr_for_type(error_type: &RustyErrorTypes) -> &'static str {
match *error_type {
RustyErrorTypes::EmptyShares => "No shares were provided.",
RustyErrorTypes::IncompatibleSets(_) => "The shares are incompatible with each other.",
RustyErrorTypes::InvalidSignature(_, _) => "The signature of this share is not valid.",
RustyErrorTypes::MissingShares(_, _) => "The number of shares provided is insufficient to recover the secret.",
RustyErrorTypes::MissingSignature(_) => "Signature is missing while shares are required to be signed.",
RustyErrorTypes::ShareParsingError(_, _) => "This share is incorrectly formatted.",
RustyErrorTypes::DuplicateShareNum(_) => "This share number has already been used by a previous share.",
RustyErrorTypes::DuplicateShareData(_) => "The data encoded in this share is the same as the one found in a previous share."
}
}
fn detail_for_type(error_type: &RustyErrorTypes) -> Option<String> {
match *error_type {
RustyErrorTypes::MissingShares(required, found) => Some(format!("{} shares are required to recover the secret,
found only {}.", required, found)),
RustyErrorTypes::ShareParsingError(_, ref description) => Some(description.clone()),
_ => None
}
}
fn share_groups_for_type(error_type: RustyErrorTypes) -> Option<Vec<Vec<u8>>>{
match error_type {
RustyErrorTypes::IncompatibleSets(groups) => Some(groups),
_ => None
}
}
fn share_num_for_type(error_type: &RustyErrorTypes) -> Option<u8> {
match *error_type {
RustyErrorTypes::InvalidSignature(share_num, _)
| RustyErrorTypes::MissingSignature(share_num)
| RustyErrorTypes::ShareParsingError(share_num, _)
| RustyErrorTypes::DuplicateShareNum(share_num)
| RustyErrorTypes::DuplicateShareData(share_num) => Some(share_num),
_ => None
}
}
}
impl fmt::Display for Error {
impl fmt::Display for RustyError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.detail {
None => write!(f, "{}", self.descr),
@ -30,7 +103,7 @@ impl fmt::Display for Error {
}
}
impl error::Error for Error {
impl error::Error for RustyError {
fn description(&self) -> &str {
self.descr
}
@ -39,33 +112,42 @@ impl error::Error for Error {
}
}
impl From<Error> for io::Error {
fn from(me: Error) -> io::Error {
impl From<io::Error> for RustyError {
fn from(err: io::Error) -> RustyError {
let descr = err.description().to_owned();
RustyError::new("from io:Error", Some(descr), None, None)
}
}
impl From<RustyError> for io::Error {
fn from(me: RustyError) -> io::Error {
io::Error::new(io::ErrorKind::Other, me)
}
}
/// Returns an `io::Error` from description string and optional detail string.
/// Particularly useful in `Result` expressions.
pub fn other_io_err(descr: &'static str, detail: Option<String>) -> io::Error {
convert::From::from(Error::new(descr, detail))
pub fn other_io_err(descr: &'static str, detail: Option<String>,
share_num: Option<u8>, share_groups: Option<Vec<Vec<u8>>>) -> io::Error {
convert::From::from(RustyError::new(descr, detail, share_num, share_groups))
}
/// maps a `ParseIntError` to an `io::Error`
pub fn pie2io(p: num::ParseIntError) -> io::Error {
convert::From::from(Error::new("Integer parsing error", Some(p.to_string())))
/// maps a `ParseIntError` to an `Error`
pub fn pie2error(p: num::ParseIntError) -> RustyError {
RustyError::new("Integer parsing error", Some(p.to_string()), None, None)
}
#[cfg(test)]
mod tests_custom_err {
use std::error;
use custom_error;
use custom_error::RustyError;
#[test]
fn test_custom_error() {
let desc = "Boring error description";
let detail = "More of it";
let ewd = custom_error::Error::new(desc, Some(detail.to_string()));
let ewd = RustyError::new(desc, Some(detail.to_string()), None, None);
assert_eq!(error::Error::description(&ewd), desc);
match error::Error::cause(&ewd) {
@ -73,7 +155,7 @@ mod tests_custom_err {
None => assert!(true),
}
let _formated_err = format!("{}", ewd);
let ewod = custom_error::Error::new(desc, None);
let ewod = RustyError::new(desc, None, None, None);
let _formated_err = format!("{}", ewod);
}
}
@ -81,12 +163,12 @@ mod tests_custom_err {
#[cfg(test)]
mod tests_std_err {
use std::error::Error;
use custom_error::pie2io;
use custom_error::pie2error;
#[test]
fn test_parse_errors() {
let nan = "2a".to_string();
match nan.parse::<u8>().map_err(pie2io) {
match nan.parse::<u8>().map_err(pie2error) {
Ok(_) => assert!(false),
Err(x) => assert_eq!("Integer parsing error", x.description()),
}

View File

@ -1,10 +1,10 @@
#![deny(
missing_docs,
missing_debug_implementations, missing_copy_implementations,
trivial_casts, trivial_numeric_casts,
unsafe_code, unstable_features,
unused_import_braces, unused_qualifications
)]
// #![deny(
// missing_docs,
// missing_debug_implementations, missing_copy_implementations,
// trivial_casts, trivial_numeric_casts,
// unsafe_code, unstable_features,
// unused_import_braces, unused_qualifications
// )]
//! `RustySecrets` implements Shamir Secret Sharing in Rust. It provides the possibility to sign shares.
@ -28,6 +28,7 @@ mod validation;
pub use sss::generate_shares;
pub use sss::recover_secret;
pub use custom_error::RustyError;
#[cfg(test)]
mod tests;

View File

@ -1,22 +1,22 @@
use custom_error::{other_io_err, pie2io};
use custom_error::{RustyError, RustyErrorTypes};
use custom_error::pie2error;
use digest;
use merkle_sigs::Proof;
use merkle_sigs::PublicKey;
use merkle_sigs::{MerklePublicKey, Proof, PublicKey};
use protobuf;
use protobuf::{Message, RepeatedField};
use serialize;
use serialize::base64::{self, FromBase64, ToBase64};
use share_data::ShareData;
use std::io;
use std::error::Error;
type ParsedShare = Result<(Vec<u8>, u8, u8, Option<(Vec<Vec<u8>>, Proof<MerklePublicKey>)>), RustyError>;
fn base64_config() -> serialize::base64::Config {
base64::Config { pad: false, ..base64::STANDARD }
}
pub fn share_string_from(share: Vec<u8>,
threshold: u8,
share_num: u8,
signature_pair: Option<(Vec<Vec<u8>>, Proof<PublicKey>)>)
pub fn share_string_from(share: Vec<u8>, threshold: u8, share_num: u8,
signature_pair: Option<(Vec<Vec<u8>>, Proof<MerklePublicKey>)>)
-> String {
let mut share_protobuf = ShareData::new();
share_protobuf.set_shamir_data(share);
@ -33,44 +33,45 @@ pub fn share_string_from(share: Vec<u8>,
pub fn share_from_string
(s: &str,
index: u8,
is_signed: bool)
-> io::Result<(Vec<u8>, u8, u8, Option<(Vec<Vec<u8>>, Proof<PublicKey>)>)> {
-> ParsedShare {
let parts: Vec<_> = s.trim().split('-').collect();
if parts.len() != 3 {
return Err(other_io_err("Share parse error: Expected 3 parts separated by a minus sign",
None));
return Err(RustyError::with_type(RustyErrorTypes::ShareParsingError(index, format!("Expected 3 parts separated by a minus sign. Found {}.", s))));
}
let (k, n, p3) = {
let mut iter = parts.into_iter();
let k = try!(iter.next().unwrap().parse::<u8>().map_err(pie2io));
let n = try!(iter.next().unwrap().parse::<u8>().map_err(pie2io));
let k = try!(iter.next().unwrap().parse::<u8>().map_err(pie2error));
let n = try!(iter.next().unwrap().parse::<u8>().map_err(pie2error));
let p3 = iter.next().unwrap();
(k, n, p3)
};
if k < 1 || n < 1 {
return Err(other_io_err("Share parse error: Illegal K,N parameters", None));
return Err(RustyError::with_type(RustyErrorTypes::ShareParsingError(index, format!("Found illegal parameters K: {} N: {}.", k, n))));
}
let raw_data = try!(p3.from_base64().map_err(|_| {
other_io_err("Share parse error: Base64 decoding of data block failed",
None)
RustyError::with_type(RustyErrorTypes::ShareParsingError(index, "Base64 decoding of data block failed".to_owned()))
}));
let protobuf_data = try!(protobuf::parse_from_bytes::<ShareData>(raw_data.as_slice())
.map_err(|_| other_io_err("Share parse error: Protobuffer could not be decoded.", None)));
.map_err(|e| RustyError::with_type(RustyErrorTypes::ShareParsingError(index, format!("Protobuf decoding of data block failed with error: {} .", e.description())))));
let share = Vec::from(protobuf_data.get_shamir_data());
if is_signed {
let p = Proof::parse_from_bytes(protobuf_data.get_proof(), digest).unwrap().unwrap();
let p_result = Proof::parse_from_bytes(protobuf_data.get_proof(), digest);
let p_opt = p_result.unwrap();
let p = p_opt.unwrap();
let proof = Proof {
algorithm: digest,
lemma: p.lemma,
root_hash: p.root_hash,
value: PublicKey::from_vec(p.value, digest).unwrap(),
value: MerklePublicKey::new(PublicKey::from_vec(p.value, digest).unwrap()),
};
let signature = protobuf_data.get_signature();

View File

@ -1,4 +1,4 @@
use custom_error::other_io_err;
use custom_error::{RustyError, other_io_err};
use digest;
use interpolation::{encode, lagrange_interpolate};
use merkle_sigs::sign_data_vec;
@ -31,7 +31,7 @@ fn new_vec<T: Clone>(n: usize, x: T) -> Vec<T> {
/// ```
pub fn generate_shares(k: u8, n: u8, secret: &[u8], sign_shares: bool) -> io::Result<Vec<String>> {
if k > n {
return Err(other_io_err("Threshold K can not be larger than N", None));
return Err(other_io_err("Threshold K can not be larger than N", None, None, None));
}
let shares = try!(secret_share(&*secret, k, n));
@ -66,7 +66,7 @@ pub fn generate_shares(k: u8, n: u8, secret: &[u8], sign_shares: bool) -> io::Re
Ok(result)
}
pub fn secret_share(src: &[u8], k: u8, n: u8) -> io::Result<Vec<Vec<u8>>> {
pub fn secret_share(src: &[u8], k: u8, n: u8) -> Result<Vec<Vec<u8>>, RustyError> {
let mut result = Vec::with_capacity(n as usize);
for _ in 0..(n as usize) {
result.push(new_vec(src.len(), 0u8));
@ -108,7 +108,7 @@ pub fn secret_share(src: &[u8], k: u8, n: u8) -> io::Result<Vec<Vec<u8>>> {
/// }
/// }
/// ```
pub fn recover_secret(shares: Vec<String>, verify_signatures: bool) -> io::Result<Vec<u8>> {
pub fn recover_secret(shares: Vec<String>, verify_signatures: bool) -> Result<Vec<u8>, RustyError> {
let (k, shares) = try!(process_and_validate_shares(shares, verify_signatures));
let slen = shares[0].1.len();

View File

@ -1,69 +1,109 @@
use custom_error::other_io_err;
use custom_error::{RustyError, RustyErrorTypes};
use merkle_sigs::verify_data_vec_signature;
use share_format;
use share_format::format_share_for_signing;
use std::collections::HashMap;
use std::error::Error;
use std::io;
type ProcessedShares = Result<(u8, Vec<(u8, Vec<u8>)>), RustyError>;
// The order of validation that we think makes the most sense is the following:
// 1) Validate shares individually
// 2) Validate duplicate shares share num && data
// 2) Validate group consistency
// 3) Validate other properties, in no specific order
pub fn process_and_validate_shares(shares_strings: Vec<String>,
verify_signatures: bool)
-> io::Result<(u8, Vec<(u8, Vec<u8>)>)> {
let mut opt_k: Option<u8> = None;
let mut opt_root_hash: Option<Vec<u8>> = None;
-> ProcessedShares {
let mut shares: Vec<(u8, Vec<u8>)> = Vec::new();
for (counter, line) in shares_strings.iter().enumerate() {
let (share_data, k, n, sig_pair) = try!(share_format::share_from_string(line,
verify_signatures));
let mut k_compatibility_sets = HashMap::new();
let mut rh_compatibility_sets = HashMap::new();
for (counter, line) in shares_strings.iter().enumerate() {
if k_compatibility_sets.len() == 1 {
let k = k_compatibility_sets.keys().last().unwrap();
if *k == shares.len() as u8 {
break;
}
}
let share_index = counter as u8;
let (share_data, k, n, sig_pair) = try!(share_format::share_from_string(line,
counter as u8,
verify_signatures));
if verify_signatures {
if sig_pair.is_none() {
return Err(other_io_err("Signature is missing while shares are required to be \
signed.",
None));
return Err(RustyError::with_type(RustyErrorTypes::MissingSignature(share_index)));
}
let (signature, p) = sig_pair.unwrap();
let root_hash = p.root_hash.clone();
if let Some(rh) = opt_root_hash.clone() {
if root_hash != rh {
return Err(other_io_err("Root hash not matching", None));
}
p.validate(&rh);
} else {
opt_root_hash = Some(root_hash.clone());
}
try!(verify_data_vec_signature(format_share_for_signing(k,
n,
&share_data.as_slice()),
&(signature.to_vec(), p),
&root_hash)
.map_err(|e| other_io_err("Invalid signature", Some(String::from(e.description())))));
.map_err(|e| RustyError::with_type(RustyErrorTypes::InvalidSignature(share_index, String::from(e.description())))));
rh_compatibility_sets.entry(root_hash.clone()).or_insert_with(Vec::new);
let vec = rh_compatibility_sets.get_mut(&root_hash).unwrap();
vec.push(share_index);
}
if let Some(k_global) = opt_k {
if k != k_global {
return Err(other_io_err("Incompatible shares", None));
}
} else {
opt_k = Some(k);
}
k_compatibility_sets.entry(k).or_insert_with(Vec::new);
let vec = k_compatibility_sets.get_mut(&k).unwrap();
vec.push(share_index);
if shares.iter().any(|s| s.0 == n) {
return Err(other_io_err("Duplicate Share Number", None));
return Err(RustyError::with_type(RustyErrorTypes::DuplicateShareNum(share_index)));
};
if shares.iter().any(|s| s.1 == share_data) {
return Err(other_io_err("Duplicate Share Data", None));
return Err(RustyError::with_type(RustyErrorTypes::DuplicateShareData(share_index)));
};
shares.push((n, share_data));
if counter + 1 == k as usize {
return Ok((k, shares));
}
// Validate k
let k_sets = k_compatibility_sets.keys().count();
let rh_sets = rh_compatibility_sets.keys().count();
if verify_signatures {
match rh_sets {
0 => {
return Err(RustyError::with_type(RustyErrorTypes::EmptyShares))
}
1 => { } // All shares have the same roothash.
_ => {
return Err(RustyError::with_type(RustyErrorTypes::IncompatibleSets(rh_compatibility_sets.values()
.map(|x| x.to_owned()).collect())))
}
}
Err(other_io_err("Not enough shares provided!", None))
}
match k_sets {
0 => {
return Err(RustyError::with_type(RustyErrorTypes::EmptyShares))
}
1 => { } // All shares have the same roothash.
_ => {
return Err(RustyError::with_type(RustyErrorTypes::IncompatibleSets(k_compatibility_sets.values()
.map(|x| x.to_owned()).collect())))
}
}
// It is safe to unwrap because k_sets == 1
let k = *k_compatibility_sets.keys().last().unwrap();
let shares_num = shares.len();
if shares_num >= k as usize {
shares.truncate(k as usize);
Ok((k, shares))
} else {
Err(RustyError::with_type(RustyErrorTypes::MissingShares(k, shares_num)))
}
}

View File

@ -13,12 +13,12 @@ fn test_reasonable_splits() {
across public lines."
.to_string()
.into_bytes();
for is_signing in vec![true, false] {
for k in 2..max_shares {
for is_signing in &[true, false] {
for k in 1..max_shares {
for n in k..max_shares {
let shares = generate_shares(k, n, &secret, is_signing).unwrap();
let shares = generate_shares(k, n, &secret, *is_signing).unwrap();
println!("Testing {} out-of- {}", k, n);
assert_eq!(secret, recover_secret(shares, is_signing).unwrap());
assert_eq!(secret, recover_secret(shares, *is_signing).unwrap());
}
}
}

View File

@ -3,14 +3,21 @@ extern crate rusty_secrets;
use rusty_secrets::recover_secret;
#[test]
#[should_panic(expected = "Not enough shares provided!")]
fn test_recover_sellibitze_no_shares() {
#[should_panic(expected = "No shares were provided.")]
fn test_recover_no_shares() {
let shares = vec![];
recover_secret(shares, false).unwrap();
}
#[test]
#[should_panic(expected = "Share parse error: Expected 3 parts separated by a minus sign")]
#[should_panic(expected = "No shares were provided.")]
fn test_recover_no_shares_signed() {
let shares = vec![];
recover_secret(shares, true).unwrap();
}
#[test]
#[should_panic(expected = "This share is incorrectly formatted.")]
fn test_recover_2_parts_share() {
let share1 = "2-1-CgmKQZHMO+5n5pU".to_string();
let share2 = "2-2".to_string();
@ -32,7 +39,7 @@ fn test_recover_incorrect_share_num() {
}
#[test]
#[should_panic(expected = "Share parse error: Illegal K,N parameters")]
#[should_panic(expected = "This share is incorrectly formatted.")]
fn test_recover_0_share_num() {
let share1 = "2-0-1YAYwmOHqZ69jA".to_string();
let share2 = "2-1-YJZQDGm22Y77Gw".to_string();
@ -43,7 +50,7 @@ fn test_recover_0_share_num() {
}
#[test]
#[should_panic(expected = "Share parse error: Base64 decoding of data block failed")]
#[should_panic(expected = "This share is incorrectly formatted.")]
fn test_recover_invalid_b64() {
let share1 = "2-1-CgnlCxRNtnkzENE".to_string();
let share2 = "2-1-YJZQDG((((m22Y)))77Gw".to_string();
@ -54,7 +61,7 @@ fn test_recover_invalid_b64() {
}
#[test]
#[should_panic(expected = "Duplicate Share Number")]
#[should_panic(expected = "This share number has already been used by a previous share.")]
fn test_recover_duplicate_shares_number() {
let share1 = "2-1-CgnlCxRNtnkzENE".to_string();
let share2 = "2-1-CgkAnUgP3lfwjyM".to_string();
@ -65,7 +72,7 @@ fn test_recover_duplicate_shares_number() {
}
#[test]
#[should_panic(expected = "Duplicate Share Data")]
#[should_panic(expected = "The data encoded in this share is the same as the one found in a previous share.")]
fn test_recover_duplicate_shares_data() {
let share1 = "2-1-CgnlCxRNtnkzENE".to_string();
let share2 = "2-2-CgnlCxRNtnkzENE".to_string();
@ -76,7 +83,7 @@ fn test_recover_duplicate_shares_data() {
}
#[test]
#[should_panic(expected = "Not enough shares provided!")]
#[should_panic(expected = "The number of shares provided is insufficient to recover the secret.")]
fn test_recover_too_few_shares() {
let share1 = "3-1-ChbcCdSZOaMn6DM1jFca2P6/0WRlP7AK".to_string();
let share2 = "3-2-ChbG46L1zRszs0PPn63XnnupmZTcgYJ3".to_string();