Skip to content

Commit

Permalink
Tests & CI.
Browse files Browse the repository at this point in the history
  • Loading branch information
FredericJacobs committed Apr 6, 2016
1 parent 0abd8fa commit 2806bc4
Show file tree
Hide file tree
Showing 10 changed files with 181 additions and 110 deletions.
20 changes: 16 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
addons:
apt:
packages:
- libcurl4-openssl-dev
- libelf-dev
- libdw-dev
language: rust

before_script:
- pip install 'travis-cargo<0.2' --user && export PATH=$HOME/.local/bin:$PATH

script:
- cargo build --verbose
notifications:
email:
on_success: never
- |
travis-cargo build &&
travis-cargo test
after_success:
- travis-cargo coveralls --no-sudo

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
name = "rusty_secrets"
version = "0.0.2"
description = "Implementation of threshold Shamir secret sharing in the Rust programming language."
homepage = "https://github.com/freedomofpress/RustySecrets"
license = "GPLv3"
readme = "README.md"
build = "build.rs"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Rusty Secrets
# Rusty Secrets ![Travis-Badge](https://travis-ci.org/freedomofpress/RustySecrets.svg) [![Coverage Status](https://coveralls.io/repos/github/freedomofpress/RustySecrets/badge.svg?branch=master)](https://coveralls.io/github/freedomofpress/RustySecrets?branch=master)

Rusty Secrets is an implementation of a threshold [Shamir's secret sharing scheme](https://en.wikipedia.org/wiki/Shamir%27s_Secret_Sharing).

Expand Down
16 changes: 16 additions & 0 deletions src/lib/custom_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,19 @@ pub fn pie2io(p: num::ParseIntError) -> io::Error {
Error::new("Integer parsing error", Some(p.to_string()))
)
}

#[test]
fn test_custom_error() {
let desc = "Boring error description";
let detail = "More of it";
let ewd = Error::new(desc, Some(detail.to_string()));

assert_eq!(error::Error::description(&ewd), desc);
match error::Error::cause(&ewd) {
Some(_) => assert!(false),
None => assert!(true),
}
let _formated_err = format!("{}", ewd);
let ewod = Error::new(desc, None);
let _formated_err = format!("{}", ewod);
}
28 changes: 18 additions & 10 deletions src/lib/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ pub mod custom_error;
use self::custom_error::*;

pub fn generate_shares(k: u8, n: u8, secret: &Vec<u8>) -> io::Result<Vec<String>> {
if k > n {
return Err(other_io_err("Threshold K can not be larger than N", None));
}

let shares = try!(secret_share(&*secret, k, n));
let config = base64::Config {
pad: false,
Expand All @@ -40,8 +44,7 @@ pub fn process_shares(shares_strings: Vec<String>) -> io::Result<(u8, Vec<(u8,Ve
for line in shares_strings {
let parts: Vec<_> = line.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(other_io_err("Share parse error: Expected 3 parts separated by a minus sign", None));
}
let (k, n, p3) = {
let mut iter = parts.into_iter();
Expand All @@ -64,20 +67,25 @@ pub fn process_shares(shares_strings: Vec<String>) -> io::Result<(u8, Vec<(u8,Ve
} else {
opt_k_l = Some((k, data.len()));
}
if shares.iter().all(|s| s.0 != n) {
shares.push((n, data));
counter += 1;
if counter == k {
return Ok((k, shares));
}

if shares.iter().any(|s| s.0 == n) {
return Err(other_io_err("Duplicate Share Number", None));
};

if shares.iter().any(|s| s.1 == data) {
return Err(other_io_err("Duplicate Share Data", None));
};

shares.push((n, data));
counter += 1;
if counter == k {
return Ok((k, shares));
}
}
Err(other_io_err("Not enough shares provided!", None))
}

pub fn recover_secret(shares_strings: Vec<String>) -> io::Result<Vec<u8>> {
assert!(!shares_strings.is_empty());

let (k, shares) = try!(process_shares(shares_strings));

let slen = shares[0].1.len();
Expand Down
1 change: 0 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ extern crate getopts;

use getopts::Options;

use std::str;
use lib::custom_error::*;
mod lib;

Expand Down
22 changes: 22 additions & 0 deletions tests/generation-errors.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
extern crate rusty_secrets;

use rusty_secrets::custom_error::{pie2io};
use rusty_secrets::generate_shares;
use std::error::Error;

#[test]
#[should_panic(expected = "Threshold K can not be larger than N")]
fn test_generate_invalid_k() {
let share1 = "2-1-1YAYwmOHqZ69jA".to_string().into_bytes();

generate_shares(10, 5, &share1).unwrap();
}

#[test]
fn test_parse_errors() {
let nan = "2a".to_string();
match nan.parse::<u8>().map_err(pie2io) {
Ok(_) => assert!(false),
Err(x) => assert_eq!("Integer parsing error", x.description()),
}
}
1 change: 0 additions & 1 deletion tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ extern crate rusty_secrets;

use rusty_secrets::{recover_secret, generate_shares};


#[test]
fn test_reasonable_splits() {
let max_shares = 50;
Expand Down
107 changes: 107 additions & 0 deletions tests/recovery-errors.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
extern crate rusty_secrets;

use rusty_secrets::{recover_secret};

#[test]
#[should_panic(expected = "Not enough shares provided!")]
fn test_recover_sellibitze_missing_share() {
let share1 = "2-1-1YAYwmOHqZ69jA".to_string();
let shares = vec![share1];

recover_secret(shares).unwrap();
}

#[test]
#[should_panic(expected = "Not enough shares provided!")]
fn test_recover_sellibitze_no_shares() {
let shares = vec![];
recover_secret(shares).unwrap();
}

#[test]
#[should_panic(expected = "Share parse error: Expected 3 parts separated by a minus sign")]
fn test_recover_2_parts_share() {
let share1 = "2-1-1YAYwmOHqZ69jA".to_string();
let share2 = "2-F7rAjX3UOa53KA".to_string();

let shares = vec![share1, share2];

recover_secret(shares).unwrap();
}

#[test]
#[should_panic(expected = "Integer parsing error")]
fn test_recover_incorrect_share_num() {
let share1 = "2-1-1YAYwmOHqZ69jA".to_string();
let share2 = "2-DEFINITLY_NAN-YJZQDGm22Y77Gw".to_string();

let shares = vec![share1, share2];

recover_secret(shares).unwrap();
}

#[test]
#[should_panic(expected = "Share parse error: Illegal K,N parameters")]
fn test_recover_0_share_num() {
let share1 = "2-0-1YAYwmOHqZ69jA".to_string();
let share2 = "2-1-YJZQDGm22Y77Gw".to_string();

let shares = vec![share1, share2];

recover_secret(shares).unwrap();
}

#[test]
#[should_panic(expected = "Share parse error: Base64 decoding of data block failed")]
fn test_recover_invalid_b64() {
let share1 = "2-5-j0P4PHsw4lW+rg".to_string();
let share2 = "2-1-YJZQDG((((m22Y)))77Gw".to_string();

let shares = vec![share1, share2];

recover_secret(shares).unwrap();
}

#[test]
#[should_panic(expected = "Incompatible shares")]
fn test_recover_invalid_b64_size() {
let share1 = "2-5-j0P4PHsw4lW+rg".to_string();
let share2 = "2-1-YJZQDGm22Y77GwZ69jA".to_string();

let shares = vec![share1, share2];

recover_secret(shares).unwrap();
}

#[test]
#[should_panic(expected = "Duplicate Share Number")]
fn test_recover_duplicate_shares_number() {
let share1 = "2-1-1YAYwmOHqZ69jA".to_string();
let share2 = "2-1-j0P4PHsw4lW+rg".to_string();

let shares = vec![share1, share2];

recover_secret(shares).unwrap();
}

#[test]
#[should_panic(expected = "Duplicate Share Data")]
fn test_recover_duplicate_shares_data() {
let share1 = "2-2-YJZQDGm22Y77Gw".to_string();
let share2 = "2-3-YJZQDGm22Y77Gw".to_string();

let shares = vec![share1, share2];

recover_secret(shares).unwrap();
}

#[test]
#[should_panic(expected = "Not enough shares provided!")]
fn test_recover_too_few_shares() {
let share1 = "5-1-DbuicpLQiCf7bVWiAz8eCpQGpdZmYQ7z2j2+g351tWFLOQPTZkXY8BYfwGGGjkOoz1g9x0ScmLFcWk+2tign".to_string();
let share2 = "5-2-nShdfkY5+SlfybMyqjHXCZ01bq5N/0Lkf0nQZw5x3bnHIEVfa0RA4YcJ4SjG/UdpgO/gOcyLRkSp2Dwf8bvw".to_string();

let shares = vec![share1, share2];

recover_secret(shares).unwrap();
}
93 changes: 0 additions & 93 deletions tests/test_vectors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,96 +42,3 @@ fn test_recover_sellibitze_more_than_threshold_shars() {
secret.push(10);
assert_eq!(recover_secret(shares).unwrap(), secret);
}

#[test]
#[should_panic]
fn test_recover_sellibitze_missing_share() {
let share1 = "2-1-1YAYwmOHqZ69jA".to_string();
let shares = vec![share1];

recover_secret(shares).unwrap();
}

#[test]
#[should_panic]
fn test_recover_sellibitze_no_shares() {
let shares = vec![];
recover_secret(shares).unwrap();
}

#[test]
#[should_panic]
fn test_recover_2_parts_share() {
let share1 = "2-1-1YAYwmOHqZ69jA".to_string();
let share2 = "2-F7rAjX3UOa53KA".to_string();

let shares = vec![share1, share2];

recover_secret(shares).unwrap();
}

#[test]
#[should_panic]
fn test_recover_incorrect_share_num() {
let share1 = "2-1-1YAYwmOHqZ69jA".to_string();
let share2 = "2-DEFINITLY_NAN-YJZQDGm22Y77Gw".to_string();

let shares = vec![share1, share2];

recover_secret(shares).unwrap();
}

#[test]
#[should_panic]
fn test_recover_0_share_num() {
let share1 = "2-0-1YAYwmOHqZ69jA".to_string();
let share2 = "2-1-YJZQDGm22Y77Gw".to_string();

let shares = vec![share1, share2];

recover_secret(shares).unwrap();
}

#[test]
#[should_panic]
fn test_recover_invalid_b64() {
let share1 = "2-0-1YAYwmOHqZ69jA".to_string();
let share2 = "2-1-YJZQDG((((m22Y)))77Gw".to_string();

let shares = vec![share1, share2];

recover_secret(shares).unwrap();
}

#[test]
#[should_panic]
fn test_recover_invalid_b64_size() {
let share1 = "2-0-1YAYwmOHqZ69jA".to_string();
let share2 = "2-1-YJZQDGm22Y77GwZ69jA".to_string();

let shares = vec![share1, share2];

recover_secret(shares).unwrap();
}

#[test]
#[should_panic]
fn test_recover_duplicate_shares() {
let share1 = "2-0-1YAYwmOHqZ69jA".to_string();
let share2 = "2-0-1YAYwmOHqZ69jA".to_string();

let shares = vec![share1, share2];

recover_secret(shares).unwrap();
}

#[test]
#[should_panic]
fn test_recover_too_few_shares() {
let share1 = "5-1-DbuicpLQiCf7bVWiAz8eCpQGpdZmYQ7z2j2+g351tWFLOQPTZkXY8BYfwGGGjkOoz1g9x0ScmLFcWk+2tign".to_string();
let share2 = "5-2-nShdfkY5+SlfybMyqjHXCZ01bq5N/0Lkf0nQZw5x3bnHIEVfa0RA4YcJ4SjG/UdpgO/gOcyLRkSp2Dwf8bvw".to_string();

let shares = vec![share1, share2];

recover_secret(shares).unwrap();
}

0 comments on commit 2806bc4

Please sign in to comment.