diff --git a/.travis.yml b/.travis.yml index b92f7e78..07906e39 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,7 +20,16 @@ matrix: before_script: - rustup component add rustfmt-preview script: - - cargo fmt --all -- --write-mode=diff + - cargo fmt --all -- --check + - env: + - NAME='clippy' + # use env so updating versions causes cache invalidation + - CLIPPY_VERSION=0.0.212 + rust: nightly-2018-07-22 + before_script: + - cargo install clippy --version $CLIPPY_VERSION || echo "clippy already installed" + script: + - cargo clippy --all --tests --all-features -- -D clippy - env: NAME='kcov' sudo: required # travis-ci/travis-ci#9061 before_script: @@ -30,7 +39,7 @@ matrix: script: - cargo kcov --print-install-kcov-sh | sh - cargo update # Creates `Cargo.lock` needed by next command - - cargo kcov --verbose --features dss --coveralls -- --verify --exclude-pattern=/.cargo,/usr/lib,src/proto + - cargo kcov --verbose --coveralls -- --verify --exclude-pattern=/.cargo,/usr/lib,src/proto addons: apt: packages: @@ -47,4 +56,4 @@ env: script: - cargo build --verbose --all-features - cargo test --verbose --all-features - - cargo doc --verbose --all-features + - cargo doc --verbose --all-features --no-deps diff --git a/Cargo.toml b/Cargo.toml index 6b5581b6..ff899854 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,10 +20,6 @@ exclude = ["Cargo.lock"] travis-ci = { repository = "SpinResearch/RustySecrets", branch = "master" } coveralls = { repository = "SpinResearch/RustySecrets", branch = "master", service = "github" } -[features] -default = [] -dss = [] - [dependencies] base64 = "0.9.0" rand = "^0.4.2" diff --git a/benches/ss1.rs b/benches/ss1.rs deleted file mode 100644 index f6e993a0..00000000 --- a/benches/ss1.rs +++ /dev/null @@ -1,60 +0,0 @@ -#![cfg(test)] -#![feature(test)] -#![cfg(feature = "dss")] - -extern crate rusty_secrets; -extern crate test; - -mod shared; - -mod ss1 { - - use rusty_secrets::dss::ss1; - use shared; - use test::{black_box, Bencher}; - - macro_rules! bench_generate { - ($name:ident, $k:expr, $n:expr, $secret:ident) => { - #[bench] - fn $name(b: &mut Bencher) { - let secret = shared::$secret(); - - b.iter(move || { - let shares = ss1::split_secret( - $k, - $n, - &secret, - ss1::Reproducibility::reproducible(), - &None, - ).unwrap(); - black_box(shares); - }); - } - }; - } - - macro_rules! bench_recover { - ($name:ident, $k:expr, $n:expr, $secret:ident) => { - #[bench] - fn $name(b: &mut Bencher) { - let secret = shared::$secret(); - let all_shares = - ss1::split_secret($k, $n, &secret, ss1::Reproducibility::reproducible(), &None) - .unwrap(); - let shares = &all_shares.into_iter().take($k).collect::>().clone(); - - b.iter(|| { - let result = ss1::recover_secret(&shares.to_vec()).unwrap(); - black_box(result); - }); - } - }; - } - - bench_generate!(generate_1kb_3_5, 3, 5, secret_1kb); - bench_recover!(recover_1kb_3_5, 3, 5, secret_1kb); - - bench_generate!(generate_1kb_10_25, 10, 25, secret_1kb); - bench_recover!(recover_1kb_10_25, 10, 25, secret_1kb); - -} diff --git a/benches/thss.rs b/benches/thss.rs deleted file mode 100644 index c4dd97d5..00000000 --- a/benches/thss.rs +++ /dev/null @@ -1,52 +0,0 @@ -#![cfg(test)] -#![feature(test)] -#![cfg(feature = "dss")] - -extern crate rusty_secrets; -extern crate test; - -mod shared; - -mod thss { - - use rusty_secrets::dss::thss; - use shared; - use test::{black_box, Bencher}; - - macro_rules! bench_generate { - ($name:ident, $k:expr, $n:expr, $secret:ident) => { - #[bench] - fn $name(b: &mut Bencher) { - let secret = shared::$secret(); - - b.iter(move || { - let shares = thss::split_secret($k, $n, &secret, &None).unwrap(); - black_box(shares); - }); - } - }; - } - - macro_rules! bench_recover { - ($name:ident, $k:expr, $n:expr, $secret:ident) => { - #[bench] - fn $name(b: &mut Bencher) { - let secret = shared::$secret(); - let all_shares = thss::split_secret($k, $n, &secret, &None).unwrap(); - let shares = &all_shares.into_iter().take($k).collect::>().clone(); - - b.iter(|| { - let result = thss::recover_secret(&shares.to_vec()).unwrap(); - black_box(result); - }); - } - }; - } - - bench_generate!(generate_1kb_3_5, 3, 5, secret_1kb); - bench_recover!(recover_1kb_3_5, 3, 5, secret_1kb); - - bench_generate!(generate_1kb_10_25, 10, 25, secret_1kb); - bench_recover!(recover_1kb_10_25, 10, 25, secret_1kb); - -} diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index d84047fe..fba85261 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -20,14 +20,6 @@ git = "https://github.com/rust-fuzz/libfuzzer-sys.git" [workspace] members = ["."] -[[bin]] -name = "ss1_1" -path = "fuzz_targets/ss1_1.rs" - -[[bin]] -name = "thss_1" -path = "fuzz_targets/thss_1.rs" - [[bin]] name = "sss_1" path = "fuzz_targets/sss_1.rs" diff --git a/fuzz/fuzz_targets/ss1_1.rs b/fuzz/fuzz_targets/ss1_1.rs deleted file mode 100644 index 339553ff..00000000 --- a/fuzz/fuzz_targets/ss1_1.rs +++ /dev/null @@ -1,24 +0,0 @@ -#![no_main] -#[macro_use] -extern crate libfuzzer_sys; -extern crate rusty_secrets; -extern crate arbitrary; - -use rusty_secrets::dss::ss1::*; -use arbitrary::{RingBuffer, Unstructured}; - -fuzz_target!(|data: &[u8]| { - // --- - if let Ok(mut buffer) = RingBuffer::new(data, data.len()) { - let mut kn = vec![0; 2]; - buffer.fill_buffer(&mut kn).unwrap(); - - let k = kn[0]; - let n = kn[1]; - - split_secret(k, n, &data, Reproducibility::reproducible(), &None) - .and_then(|ss| recover_secret(&ss)) - .map(|_| ()) - .unwrap_or(()) - } -}); diff --git a/fuzz/fuzz_targets/sss_1.rs b/fuzz/fuzz_targets/sss_1.rs deleted file mode 100644 index ef2a65ee..00000000 --- a/fuzz/fuzz_targets/sss_1.rs +++ /dev/null @@ -1,25 +0,0 @@ -#![no_main] -extern crate arbitrary; -#[macro_use] -extern crate libfuzzer_sys; -extern crate rusty_secrets; - -use rusty_secrets::sss; -use arbitrary::{RingBuffer, Unstructured}; - -fuzz_target!(|data: &[u8]| { - // --- - if let Ok(mut buffer) = RingBuffer::new(data, data.len()) { - let mut kn = vec![0; 2]; - buffer.fill_buffer(&mut kn).unwrap(); - - let k = kn[0]; - let n = kn[1]; - - sss::split_secret(k, n, &data, false) - .map_err(|err| err.into()) - .and_then(|ss| sss::recover_secret(&ss, false)) - .map(|_| ()) - .unwrap_or(()) - } -}); diff --git a/protobuf/Makefile b/protobuf/Makefile index 7ecfba26..aea9e092 100644 --- a/protobuf/Makefile +++ b/protobuf/Makefile @@ -7,24 +7,19 @@ DEST_DIR := ../src/proto BASE_PROTOS := $(wildcard *.proto) BASE_RUSTS := $(addprefix $(DEST_DIR)/, $(BASE_PROTOS:.proto=.rs)) -DSS_PROTOS := $(wildcard dss/*.proto) -DSS_RUSTS := $(addprefix $(DEST_DIR)/, $(DSS_PROTOS:.proto=.rs)) - WRAPPED_PROTOS := $(wildcard wrapped/*.proto) WRAPPED_RUSTS := $(addprefix $(DEST_DIR)/, $(WRAPPED_PROTOS:.proto=.rs)) OUT_DIR := _out -.PHONY: all base wrapped dss clean +.PHONY: all base wrapped clean -all: base wrapped dss +all: base wrapped base: $(BASE_RUSTS) wrapped: $(WRAPPED_RUSTS) -dss: $(DSS_RUSTS) - $(DEST_DIR)/%.rs: %.proto @echo -n "Processing '$<'..." @$(RM) -r $(OUT_DIR) @@ -39,4 +34,3 @@ $(DEST_DIR)/%.rs: %.proto clean: $(RM) $(BASE_RUSTS) $(RM) $(WRAPPED_RUSTS) - $(RM) $(DSS_RUSTS) diff --git a/protobuf/dss/metadata.proto b/protobuf/dss/metadata.proto deleted file mode 100644 index 991cc9de..00000000 --- a/protobuf/dss/metadata.proto +++ /dev/null @@ -1,7 +0,0 @@ -syntax = "proto3"; - -package dss; - -message MetaDataProto { - map tags = 1; -} diff --git a/protobuf/dss/secret.proto b/protobuf/dss/secret.proto deleted file mode 100644 index 872ea1ec..00000000 --- a/protobuf/dss/secret.proto +++ /dev/null @@ -1,10 +0,0 @@ -syntax = "proto3"; - -import "version.proto"; -import "dss/metadata.proto"; - -message SecretProto { - VersionProto version = 1; - bytes secret = 2; - dss.MetaDataProto meta_data = 3; -} diff --git a/protobuf/dss/share.proto b/protobuf/dss/share.proto deleted file mode 100644 index c088010f..00000000 --- a/protobuf/dss/share.proto +++ /dev/null @@ -1,14 +0,0 @@ -syntax = "proto3"; - -package dss; - -import "dss/metadata.proto"; - -message ShareProto { - uint32 id = 1; - uint32 threshold = 2; - uint32 shares_count = 3; - bytes data = 4; - bytes hash = 5; - dss.MetaDataProto meta_data = 6; -} diff --git a/rust-toolchain b/rust-toolchain deleted file mode 100644 index f9e8384b..00000000 --- a/rust-toolchain +++ /dev/null @@ -1 +0,0 @@ -1.24.1 diff --git a/src/dss/format.rs b/src/dss/format.rs deleted file mode 100644 index c4d0386c..00000000 --- a/src/dss/format.rs +++ /dev/null @@ -1,73 +0,0 @@ -use std::error::Error; - -use base64; -use protobuf::{self, Message}; - -use errors::*; -use proto::dss::ShareProto; - -const BASE64_CONFIG: base64::Config = base64::STANDARD_NO_PAD; - -pub(crate) fn format_share_protobuf(share: &ShareProto) -> String { - let bytes = share.write_to_bytes().unwrap(); - let base64_data = base64::encode_config(&bytes, BASE64_CONFIG); - format!("{}-{}-{}", share.threshold, share.id, base64_data) -} - -pub(crate) fn parse_share_protobuf(raw: &str) -> Result { - let (threshold, id, base64_data) = parse_raw_share(raw)?; - - let data = base64::decode_config(&base64_data, BASE64_CONFIG).chain_err(|| { - ErrorKind::ShareParsingError("Base64 decoding of data block failed".to_string()) - })?; - - let share_proto = protobuf::parse_from_bytes::(data.as_slice()).map_err(|e| { - ErrorKind::ShareParsingError(format!( - "Protobuf decoding of data block failed with error: {} .", - e.description() - )) - })?; - - if threshold != share_proto.threshold { - bail! { - ErrorKind::ShareParsingError( - format!( - "Incompatible thresholds between decoded Protobuf provided \ - (k={}) and raw share (k={})", share_proto.threshold, threshold - ) - )} - } - - if id != share_proto.id { - bail! { - ErrorKind::ShareParsingError( - format!( - "Incompatible ids between decoded Protobuf provided \ - (i={}) and raw share (i={})", share_proto.id, id - ) - )} - } - - Ok(share_proto) -} - -fn parse_raw_share(raw: &str) -> Result<(u32, u32, String)> { - let parts: Vec<_> = raw.trim().split('-').collect(); - - if parts.len() != 3 { - bail! { - ErrorKind::ShareParsingError( - format!( - "Expected 3 parts separated by a minus sign. Found {}.", - raw - ), - ) - }; - } - - let mut iter = parts.into_iter(); - let k = iter.next().unwrap().parse::()?; - let i = iter.next().unwrap().parse::()?; - let data = iter.next().unwrap(); - Ok((k, i, data.to_string())) -} diff --git a/src/dss/metadata.rs b/src/dss/metadata.rs deleted file mode 100644 index fa11f24e..00000000 --- a/src/dss/metadata.rs +++ /dev/null @@ -1,31 +0,0 @@ -use ring::digest; -use std::collections::BTreeMap; - -/// A share's public metadata. -#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Default)] -pub struct MetaData { - /// The tags associated with the share - pub tags: BTreeMap, -} - -impl MetaData { - /// Construct a new MetaData struct. - pub fn new() -> Self { - MetaData { - tags: BTreeMap::new(), - } - } - - /// Construct a new MetaData struct, holding the given tags - pub fn with_tags(tags: BTreeMap) -> Self { - Self { tags } - } - - pub(crate) fn hash_into(&self, ctx: &mut digest::Context) { - for (tag, value) in &self.tags { - ctx.update(tag.as_bytes()); - ctx.update(b":"); - ctx.update(value.as_bytes()); - } - } -} diff --git a/src/dss/mod.rs b/src/dss/mod.rs deleted file mode 100644 index f7739d28..00000000 --- a/src/dss/mod.rs +++ /dev/null @@ -1,59 +0,0 @@ -//! Defines two different deterministic sharing schemes, ThSS and SS1. -//! -//! # Deterministic secret sharing -//! -//! TODO: Doc -//! -//! # Schemes -//! -//! The two schemes differ by the security properties that they satisfy. -//! The following table summarizes which properties are satisfied by each scheme. -//! The definitions of the properties can be found under the 'Security properties' section. -//! -//! **Scheme / Property** | **Basic** | **Priv1** | **Priv2** | **Auth1** | **Auth2** | **ErrDet** | **Repro** | -//! :--------------------:|:---------:|:---------:|:---------:|:---------:|:---------:|:----------:|:---------:| -//! **ThSS** | Yes | Yes | No | No | No | Yes | No | -//! **SS1** | Yes | Yes | Yes | Yes | Yes | Yes | Yes | -//! -//! # Security properties -//! -//! **Property** | **Description** -//! :-----------:|----------------|---------------- -//! **Basic** | Basic correctness: If you attempt to recover a secret from an authorized set of shares that were obtained by sharing out a secret **M** using an access structure **A**, you're sure to get back **A** and **M**.
Note: in this implementation **A** is not actually returned, but definitely could. -//! **Priv1** | Standard privacy notation: When the coins are used by the dealer are uniformly random, unauthorized sets of shares have no computationally extractable information about the underlying secret. -//! **Priv2** | Privacy for deterministic or hedged schemes: extract whatever entropy one can from the underlying secret. If it’s adequate, no additional randomness is needed in order to achieve a meaningful notion of privacy. -//! **Auth1** | A share obtained from an honest dealer commits it to a single underlying secret: that and only that value can be recovered. -//! **Auth2** | A share obtained even from a dishonest dealer commits it to a single underlying secret: that and only that value might be recovered. Implies Auth1. -//! **ErrDet** | An inauthentic set of shares produced by an adversary will be flagged as such when fed to the recovery algorithm. -//! **Repro** | Share reproducible: The scheme can produce shares in a deterministic way. - -pub mod ss1; -pub mod thss; - -mod metadata; - -mod format; -mod random; -mod utils; - -/// Define the access structure used to deal and recover the shares. -/// -/// For example, if one wants to deal 10 shares, and require 7 of them to -/// recover the secret, one would express it as: -/// -/// ```rust -/// # use rusty_secrets::dss::AccessStructure; -/// AccessStructure { -/// threshold: 7, -/// shares_count: 10, -/// }; -/// ``` -#[derive(Copy, Clone, Debug)] -pub struct AccessStructure { - /// The minimum amount of shares required to recover the secret. - pub threshold: u8, - - /// The total number of shares generated when splitting up the secret. - /// Always greater than or equal to `threshold`. - pub shares_count: u8, -} diff --git a/src/dss/random.rs b/src/dss/random.rs deleted file mode 100644 index a09a0ec2..00000000 --- a/src/dss/random.rs +++ /dev/null @@ -1,66 +0,0 @@ -use std; - -use errors::*; - -use ring::error::Unspecified; -use ring::rand::SecureRandom; - -/// We bound the message size at about 16MB to avoid overflow in `random_bytes_count`. -/// Moreover, given the current performances, it is almost unpractical to run -/// the sharing scheme on message larger than that. -pub(crate) const MAX_MESSAGE_SIZE: usize = std::usize::MAX / (std::u8::MAX - 1) as usize; -/// Minimum allowed message size in bytes -pub(crate) static MIN_MESSAGE_SIZE: usize = 1; - -/// Returns the number of random bytes to read from the secure random number generator. -/// As defined in section 3.1 of the 'New Directions in Secret Sharing' paper. -pub(crate) fn random_bytes_count(threshold: u8, message_size: usize) -> usize { - assert!(threshold >= MIN_THRESHOLD); - assert!(message_size >= MIN_MESSAGE_SIZE); - assert!(message_size <= MAX_MESSAGE_SIZE); - - (threshold as usize - 1) * message_size -} - -/// Attempts to read `count` random bytes from the given secure random generator. -pub(crate) fn random_bytes(random: &SecureRandom, count: usize) -> Result> { - if count == 0 { - return Ok(Vec::new()); - } - - let mut rl = vec![0; count]; - random - .fill(&mut rl) - .chain_err(|| ErrorKind::CannotGenerateRandomNumbers)?; - - Ok(rl) -} - -/// An implementation of SecureRandom that fills the output slice with the slice in `src`. -/// The length of `src` must be larger than any slice that we attempt to fill. -pub(crate) struct FixedRandom { - src: Vec, -} - -impl FixedRandom { - /// Create a new fixed random generator. - /// The length of `src` must be larger than any slice that we attempt to fill. - pub(crate) fn new(src: Vec) -> Self { - if src.is_empty() { - panic!("The source slice of FixedRandom cannot be empty!"); - } - FixedRandom { src } - } -} - -impl SecureRandom for FixedRandom { - fn fill(&self, dst: &mut [u8]) -> std::result::Result<(), Unspecified> { - if dst.len() > self.src.len() { - return Err(Unspecified); - } - - let len = dst.len(); - dst.copy_from_slice(&self.src[0..len]); - Ok(()) - } -} diff --git a/src/dss/ss1/mod.rs b/src/dss/ss1/mod.rs deleted file mode 100644 index 18a4b066..00000000 --- a/src/dss/ss1/mod.rs +++ /dev/null @@ -1,194 +0,0 @@ -//! Implements the `SS1` deterministic threshold secret sharing scheme. -//! -//! This scheme is implemented as the *T2 transform* over the ThSS threshold sharing scheme. -//! found in the `rusty_secrets::dss::thss` module. -//! -//! # Security properties -//! -//! This scheme satisfies the following security properties: -//! -//! **Property** | **Satisifed?** | **Description** -//! -------------|----------------|---------------- -//! **Basic** | Yes | Basic correctness: If you attempt to recover a secret from an authorized set of shares that were obtained by sharing out a secret **M** using an access structure **A**, you're sure to get back **A** and **M**.
Note: in this implementation **A** is not actually returned, but definitely could. -//! **Priv1** | Yes | Standard privacy notation: When the coins are used by the dealer are uniformly random, unauthorized sets of shares have no computationally extractable information about the underlying secret. -//! **Priv2** | Yes | Privacy for deterministic or hedged schemes: extract whatever entropy one can from the underlying secret. If it’s adequate, no additional randomness is needed in order to achieve a meaningful notion of privacy. -//! **Auth1** | Yes | A share obtained from an honest dealer commits it to a single underlying secret: that and only that value can be recovered. -//! **Auth2** | Yes | A share obtained even from a dishonest dealer commits it to a single underlying secret: that and only that value might be recovered. Implies Auth1. -//! **ErrDet** | Yes | An inauthentic set of shares produced by an adversary will be flagged as such when fed to the recovery algorithm. -//! **Repro** | Yes | Share reproducible: The scheme can produce shares in a deterministic way. -//! -//! # References -//! -//! - *New Directions in Secret Sharing* (TODO: Full reference) - -use errors::*; - -mod serialize; - -mod share; -pub use self::share::*; - -mod scheme; -pub use self::scheme::Reproducibility; -use self::scheme::SS1; - -use dss::AccessStructure; - -/// Performs threshold k-out-of-n deterministic secret sharing. -/// -/// # Examples -/// -/// ``` -/// use rusty_secrets::dss::ss1::{self, Reproducibility, MetaData}; -/// -/// let secret = "These programs were never about terrorism: they’re about economic spying, \ -/// social control, and diplomatic manipulation. They’re about power."; -/// -/// let mut metadata = MetaData::new(); -/// metadata.tags.insert("mime_type".to_string(), "text/plain".to_string()); -/// -/// match ss1::split_secret(7, 10, &secret.as_bytes(), Reproducibility::reproducible(), &Some(metadata)) { -/// Ok(shares) => { -/// // Do something with the shares -/// }, -/// Err(_) => { -/// // Deal with error -/// } -/// } -/// ``` -pub fn split_secret( - k: u8, - n: u8, - secret: &[u8], - reproducibility: Reproducibility, - metadata: &Option, -) -> Result> { - SS1::default().split_secret(k, n, secret, reproducibility, metadata) -} - -/// Recovers the secret from a k-out-of-n deterministic secret sharing scheme (`SS1`). -/// -/// At least `k` distinct shares need to be provided to recover the secret. -/// -/// # Examples -/// -/// ```rust -/// use rusty_secrets::dss::ss1::{self, Reproducibility, MetaData}; -/// -/// let secret = "These programs were never about terrorism: they’re about economic spying, \ -/// social control, and diplomatic manipulation. They’re about power."; -/// -/// let mut metadata = MetaData::new(); -/// metadata.tags.insert("mime_type".to_string(), "text/plain".to_string()); -/// -/// let shares = ss1::split_secret( -/// 7, -/// 10, -/// &secret.as_bytes(), -/// Reproducibility::reproducible(), -/// &Some(metadata) -/// ).unwrap(); -/// -/// match ss1::recover_secret(&shares) { -/// Ok((secret, access_structure, metadata)) => { -/// // Do something with the secret and the metadata -/// }, -/// Err(e) => { -/// // Deal with the error -/// } -/// } -/// ``` -pub fn recover_secret(shares: &[Share]) -> Result<(Vec, AccessStructure, Option)> { - SS1::default().recover_secret(shares) -} - -#[cfg(test)] -mod tests { - - use super::*; - - #[test] - fn nonreproducible_split_then_recover_yields_original_secret() { - let secret = "Hello, World!".to_string().into_bytes(); - - let shares = split_secret(7, 10, &secret, Reproducibility::none(), &None).unwrap(); - - assert_eq!(shares.len(), 10); - - let (recovered, access_structure, metadata) = recover_secret(&shares[2..9]).unwrap(); - - assert_eq!(secret, recovered); - assert_eq!(access_structure.threshold, 7); - assert_eq!(access_structure.shares_count, 10); - assert_eq!(None, metadata); - } - - #[test] - fn reproducible_split_then_recover_yields_original_secret() { - let secret = "Hello, World!".to_string().into_bytes(); - - let shares = split_secret(7, 10, &secret, Reproducibility::reproducible(), &None).unwrap(); - - assert_eq!(shares.len(), 10); - - let (recovered, access_structure, metadata) = recover_secret(&shares[2..9]).unwrap(); - - assert_eq!(secret, recovered); - assert_eq!(access_structure.threshold, 7); - assert_eq!(access_structure.shares_count, 10); - assert_eq!(None, metadata); - } - - #[test] - fn seeded_reproducible_split_then_recover_yields_original_secret() { - let secret = "Hello, World!".to_string().into_bytes(); - - let seed = vec![1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16u8]; - let shares = split_secret(7, 10, &secret, Reproducibility::seeded(seed), &None).unwrap(); - - assert_eq!(shares.len(), 10); - - let (recovered, access_structure, metadata) = recover_secret(&shares[2..9]).unwrap(); - - assert_eq!(secret, recovered); - assert_eq!(access_structure.threshold, 7); - assert_eq!(access_structure.shares_count, 10); - assert_eq!(None, metadata); - } - - #[test] - fn reproducible_split() { - let secret = "Hello, World!".to_string().into_bytes(); - - let shares_1 = - split_secret(7, 10, &secret, Reproducibility::reproducible(), &None).unwrap(); - let shares_2 = - split_secret(7, 10, &secret, Reproducibility::reproducible(), &None).unwrap(); - - assert_eq!(shares_1, shares_2); - } - - #[test] - fn nonreproducible_split() { - let secret = "Hello, World!".to_string().into_bytes(); - - let shares_1 = split_secret(7, 10, &secret, Reproducibility::none(), &None).unwrap(); - let shares_2 = split_secret(7, 10, &secret, Reproducibility::none(), &None).unwrap(); - - assert!(shares_1 != shares_2); - } - - #[test] - fn seeded_split() { - let secret = "Hello, World!".to_string().into_bytes(); - - let seed = vec![1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16u8]; - let shares_1 = - split_secret(7, 10, &secret, Reproducibility::seeded(seed.clone()), &None).unwrap(); - let shares_2 = - split_secret(7, 10, &secret, Reproducibility::seeded(seed.clone()), &None).unwrap(); - - assert_eq!(shares_1, shares_2); - } - -} diff --git a/src/dss/ss1/scheme.rs b/src/dss/ss1/scheme.rs deleted file mode 100644 index 49c9e4e6..00000000 --- a/src/dss/ss1/scheme.rs +++ /dev/null @@ -1,318 +0,0 @@ -use std::collections::HashSet; - -use rand::{ChaChaRng, Rng, SeedableRng}; -use ring::digest::{Context, SHA256}; -use ring::rand::{SecureRandom, SystemRandom}; -use ring::{hkdf, hmac}; - -use super::share::*; -use dss::random::{random_bytes_count, FixedRandom, MAX_MESSAGE_SIZE}; -use dss::thss::{MetaData, ThSS}; -use dss::utils; -use dss::{thss, AccessStructure}; -use errors::*; -use share::validation::{validate_share_count, validate_shares}; -use vol_hash::VOLHash; - -/// We bound the message size at about 16MB to avoid overflow in `random_bytes_count`. -/// Moreover, given the current performances, it is almost unpractical to run -/// the sharing scheme on message larger than that. -const MAX_SECRET_SIZE: usize = MAX_MESSAGE_SIZE; - -const DEFAULT_PRESEED: &[u8] = b"rusty_secrets::dss::ss1"; - -/// There are situations where it's useful to generate shares in a reproducible manner. -/// In particular, this allows a secret that’s in someone’s head, a passphrase, -/// to be shared out in a manner in which different shares can be given to -/// different people at different points in time. -/// -/// On the other hand, there is some privacy cost. -/// For example, if you know the secret is one of two possibilities, -/// M0 or M1, in a share-reproducible scheme, acquiring a single share -/// will probably let you decide which of the two possibilities it was. -#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub enum Reproducibility { - /// Shares will be produced in a deterministic way, using - /// a default, fixed seed for the internal random number generator - /// used to generate entropy. - Reproducible, - /// Shares will be produced in non-deterministic way, using - /// the system's random number generator to produce entropy. - None, - /// Shares will be produced in a deterministic way, using - /// the given seed for the internal random number generator used to - /// generate entropy. - Seeded(Vec), - /// Shares will be produced in a deterministic way, using - /// the given byte vector as the entropy source. - /// *Warning: Never use this variant unless you are sure of what you are doing* - WithEntropy(Vec), -} - -impl Reproducibility { - /// Shares will be produced in a deterministic way, using - /// a default, fixed seed for the internal random number generator - /// used to generate entropy. - pub fn reproducible() -> Self { - Reproducibility::Reproducible - } - - /// Shares will be produced in a deterministic way, using - /// the given seed for the internal random number generator used to - /// generate entropy. - pub fn seeded(seed: Vec) -> Self { - assert!(!seed.is_empty(), "Reproducibility: seed cannot be empty"); - Reproducibility::Seeded(seed) - } - - /// Shares will be produced in a deterministic way, using - /// the given byte vector as the entropy source. - /// *Warning: Never use this variant unless you are sure of what you are doing* - pub fn with_entropy(entropy: Vec) -> Self { - assert!( - !entropy.is_empty(), - "Reproducibility: entropy cannot be empty" - ); - Reproducibility::WithEntropy(entropy) - } - - /// Shares will be produced in non-deterministic way, using - /// the system's random number generator to produce entropy. - pub fn none() -> Self { - Reproducibility::None - } -} - -/// Defines a `SS1` deterministic threshold secret sharing scheme. -/// -/// This scheme is implemented as the *T2 transform* over the ThSS threshold sharing scheme. -/// found in the `rusty_secrets::dss::thss` module. -#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub(crate) struct SS1 { - /// How many random bytes to read from `random` to use as - /// padding to the hash function (param `r` from the paper) - /// and to the message in the underlying ThSS scheme. - pub random_padding_len: usize, - /// The length of the hash used for all shares (param `s` from the paper) - pub hash_len: usize, -} - -// TODO: Are those good parameters? -// TODO: Add max length ? -static DEFAULT_RANDOM_PADDING_LEN: usize = 512; // r -static MIN_RANDOM_PADDING_LEN: usize = 128; // r min -static DEFAULT_HASH_LEN: usize = 256; // s -static MIN_HASH_LEN: usize = 128; // s min - -impl Default for SS1 { - fn default() -> Self { - Self::new(DEFAULT_RANDOM_PADDING_LEN, DEFAULT_HASH_LEN).unwrap() - } -} - -impl SS1 { - /// Constructs a new sharing scheme - pub fn new(random_padding_len: usize, hash_len: usize) -> Result { - if random_padding_len < MIN_RANDOM_PADDING_LEN || hash_len < MIN_HASH_LEN { - bail!(ErrorKind::InvalidSS1Parameters( - random_padding_len, - hash_len, - )); - } - - Ok(Self { - random_padding_len, - hash_len, - }) - } - - /// Split a secret following a given sharing `scheme`, - /// with `threshold` being the number of shares necessary to recover the secret, - /// and `shares_count` the total number of shares to be dealt. - pub fn split_secret( - &self, - threshold: u8, - shares_count: u8, - secret: &[u8], - reproducibility: Reproducibility, - metadata: &Option, - ) -> Result> { - let (threshold, shares_count) = validate_share_count(threshold, shares_count)?; - let secret_len = secret.len(); - - if secret_len == 0 { - bail!(ErrorKind::EmptySecret); - } - if secret_len > MAX_SECRET_SIZE { - bail!(ErrorKind::SecretTooBig(secret_len, MAX_SECRET_SIZE)); - } - - let random_padding = self.generate_random_padding(reproducibility, secret, metadata)?; - - let mut vol_hash = VOLHash::new(&SHA256); - vol_hash.process(&[0]); - vol_hash.process(&[threshold, shares_count]); - vol_hash.process(secret); - vol_hash.process(&random_padding); - - let randomness_len = random_bytes_count(threshold, secret.len() + self.random_padding_len); - let total_hash_len = self.hash_len + randomness_len; - let mut full_hash = vec![0; total_hash_len]; - - vol_hash.finish(&mut full_hash); - let (hash, randomness) = full_hash.split_at(self.hash_len); - - let underlying = ThSS::new(Box::new(FixedRandom::new(randomness.to_vec()))); - - let message = [secret, &random_padding].concat(); - let shares = underlying.split_secret(threshold, shares_count, &message, metadata)?; - - let res = shares - .into_iter() - .map(|share| Share { - id: share.id, - threshold: share.threshold, - shares_count: share.shares_count, - data: share.data, - hash: hash.to_vec(), - metadata: share.metadata.clone(), - }) - .collect(); - - Ok(res) - } - - fn generate_random_padding( - &self, - reproducibility: Reproducibility, - secret: &[u8], - metadata: &Option, - ) -> Result> { - match reproducibility { - Reproducibility::None => { - let rng = SystemRandom::new(); - let mut result = vec![0u8; self.random_padding_len]; - rng.fill(&mut result) - .chain_err(|| ErrorKind::CannotGenerateRandomNumbers)?; - Ok(result) - } - Reproducibility::Reproducible => { - let seed = self.generate_seed(DEFAULT_PRESEED, secret, metadata); - let mut rng = ChaChaRng::from_seed(&seed); - let mut result = vec![0u8; self.random_padding_len]; - rng.fill_bytes(result.as_mut_slice()); - Ok(result) - } - Reproducibility::Seeded(preseed) => { - let seed = self.generate_seed(&preseed, secret, metadata); - let mut rng = ChaChaRng::from_seed(&seed); - let mut result = vec![0u8; self.random_padding_len]; - rng.fill_bytes(result.as_mut_slice()); - Ok(result) - } - Reproducibility::WithEntropy(entropy) => Ok(entropy), - } - } - - /// Generate a seed of 8 32-bits word for the ChaCha20 PRNG by hashing - /// together the preseed, secret, and metadata, in order to obtain a salt - /// for performing HKDF over the preseed. - fn generate_seed( - &self, - preseed: &[u8], - secret: &[u8], - metadata: &Option, - ) -> Vec { - let mut ctx = Context::new(&SHA256); - ctx.update(preseed); - ctx.update(secret); - for md in metadata { - md.hash_into(&mut ctx); - } - let preseed_hash = ctx.finish(); - - let salt = hmac::SigningKey::new(&SHA256, &[]); - let mut seed_bytes = vec![0u8; 32]; - hkdf::extract_and_expand(&salt, preseed_hash.as_ref(), &[], &mut seed_bytes); - - // We can safely call `utils::slice_u8_to_slice_u32` because - // the `digest` produced with `SHA256` is 256 bits long, as is - // `seed_bytes`, and the latter can thus be represented both as a - // slice of 32 bytes or as a slice of 8 32-bit words. - utils::slice_u8_to_slice_u32(&seed_bytes).to_vec() - } - - /// Recover the secret from the given set of shares - pub fn recover_secret( - &self, - shares: &[Share], - ) -> Result<(Vec, AccessStructure, Option)> { - let shares = shares.to_vec(); - validate_shares(&shares)?; - - let underlying_shares = shares - .iter() - .map(|share| thss::Share { - id: share.id, - threshold: share.threshold, - shares_count: share.shares_count, - data: share.data.clone(), - metadata: share.metadata.clone(), - }) - .collect::>(); - - let underlying = ThSS::default(); - let (mut secret, _, metadata) = underlying.recover_secret(&underlying_shares)?; - let secret_len = secret.len() - self.random_padding_len; - let random_padding = secret.split_off(secret_len); - // `secret` nows holds the secret - - let sub_scheme = Self::new(self.random_padding_len, self.hash_len)?; - - let test_shares = sub_scheme.split_secret( - shares[0].threshold, - shares[0].shares_count, - &secret, - Reproducibility::WithEntropy(random_padding.to_vec()), - &metadata, - )?; - - let access_structure = { - let first_share = shares.first().unwrap(); - AccessStructure { - threshold: first_share.threshold, - shares_count: first_share.shares_count, - } - }; - - self.verify_test_shares(shares, test_shares)?; - - Ok((secret, access_structure, metadata)) - } - - fn verify_test_shares( - &self, - mut shares: Vec, - mut test_shares: Vec, - ) -> Result<()> { - shares.sort_by_key(|share| share.id); - test_shares.sort_by_key(|share| share.id); - - let relevant_ids = shares.iter().map(|share| share.id).collect::>(); - let relevant_test_shares = test_shares - .iter() - .filter(|share| relevant_ids.contains(&share.id)); - let matching_shares = shares.iter().zip(relevant_test_shares); - - for (share, test_share) in matching_shares { - if share != test_share { - bail!(ErrorKind::MismatchingShares( - share.clone(), - test_share.clone(), - )); - } - } - - Ok(()) - } -} diff --git a/src/dss/ss1/serialize.rs b/src/dss/ss1/serialize.rs deleted file mode 100644 index 15b48d91..00000000 --- a/src/dss/ss1/serialize.rs +++ /dev/null @@ -1,80 +0,0 @@ -use super::{MetaData, Share}; -use dss::format::{format_share_protobuf, parse_share_protobuf}; -use dss::utils::{btreemap_to_hashmap, hashmap_to_btreemap}; -use errors::*; -use proto::dss::{MetaDataProto, ShareProto}; - -pub(crate) fn share_to_string(share: Share) -> String { - let proto = share_to_protobuf(share); - format_share_protobuf(&proto) -} - -pub(crate) fn share_from_string(raw: &str) -> Result { - let mut proto = parse_share_protobuf(raw)?; - - let metadata_proto = if proto.has_meta_data() { - Some(metadata_from_proto(proto.take_meta_data())) - } else { - None - }; - - let i = proto.get_id() as u8; - let k = proto.get_threshold() as u8; - let n = proto.get_shares_count() as u8; - - if k < 1 || i < 1 { - bail! { - ErrorKind::ShareParsingError( - format!("Found illegal share info: threshold = {}, identifier = {}.", k, i), - ) - } - } - - if n < 1 || k > n || i > n { - bail! { - ErrorKind::ShareParsingError( - format!("Found illegal share info: shares_count = {}, threshold = {}, identifier = {}.", n, k, i), - ) - } - } - - let share = Share { - id: i, - threshold: k, - shares_count: n, - data: proto.take_data(), - hash: proto.take_hash(), - metadata: metadata_proto, - }; - - Ok(share) -} - -pub(crate) fn share_to_protobuf(share: Share) -> ShareProto { - let mut proto = ShareProto::new(); - - proto.set_id(share.id.into()); - proto.set_threshold(share.threshold.into()); - proto.set_shares_count(share.shares_count.into()); - proto.set_data(share.data); - proto.set_hash(share.hash); - - if let Some(meta_data) = share.metadata { - let metadata_proto = metadata_to_proto(meta_data); - proto.set_meta_data(metadata_proto); - } - - proto -} - -fn metadata_to_proto(meta_data: MetaData) -> MetaDataProto { - let mut proto = MetaDataProto::new(); - proto.set_tags(btreemap_to_hashmap(meta_data.tags)); - proto -} - -fn metadata_from_proto(mut proto: MetaDataProto) -> MetaData { - MetaData { - tags: hashmap_to_btreemap(proto.take_tags()), - } -} diff --git a/src/dss/ss1/share.rs b/src/dss/ss1/share.rs deleted file mode 100644 index d1f6fccb..00000000 --- a/src/dss/ss1/share.rs +++ /dev/null @@ -1,57 +0,0 @@ -use super::serialize::{share_from_string, share_to_string}; -use errors::*; -use share::IsShare; - -pub use dss::metadata::MetaData; - -/// A share identified by an `id`, a threshold `k`, a number of total shares `n`, -/// the `data` held in the share, and the share's `metadata`. -#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct Share { - /// The identifier of the share (varies between 1 and n where n is the total number of generated shares) - pub id: u8, - /// The number of shares necessary to recover the secret, aka a threshold - pub threshold: u8, - /// The total number of shares that have been dealt - pub shares_count: u8, - /// The share data itself - pub data: Vec, - /// The hash value common to the whole deal - pub hash: Vec, - /// The metadata associated with this share - pub metadata: Option, -} - -impl Share { - /// Format this share a string suitable for sharing - /// over an ASCII-encoded channel, such as a text file, - /// or an e-mail. - pub fn into_string(self) -> String { - share_to_string(self) - } - - /// Parse the given string into a `Share`. - /// The `raw` string must have been generated by the - /// `Share::to_string` method for it to succeed. - pub fn from_string(raw: &str) -> Result { - share_from_string(raw) - } -} - -impl IsShare for Share { - fn get_id(&self) -> u8 { - self.id - } - - fn get_data(&self) -> &[u8] { - &self.data - } - - fn get_threshold(&self) -> u8 { - self.threshold - } - - fn get_shares_count(&self) -> Option { - Some(self.shares_count) - } -} diff --git a/src/dss/thss/encode.rs b/src/dss/thss/encode.rs deleted file mode 100644 index 01fbc596..00000000 --- a/src/dss/thss/encode.rs +++ /dev/null @@ -1,37 +0,0 @@ -use gf256::Gf256; -use poly::Poly; - -/// Encode the given `secret` using the `ThSS[N].Share` algorithm described -/// in the *New directions in Secret Sharing* paper. -/// -/// Reference: Figure 7 from the *New Directions in Secret Sharing* paper. -pub(crate) fn encode_secret(secret: &[u8], k: u8, share_id: u8, rands: &[u8]) -> Vec { - secret - .into_iter() - .enumerate() - .map(|(i, m)| { - let k_pred = (k - 1) as usize; - let coeffs = (0..k_pred) - .map(|l| { - let n = rands[i * k_pred + l]; - Gf256::from_byte(n) - }) - .collect(); - let poly = Poly::new(coeffs); - encode_secret_byte(*m, share_id, &poly) - }) - .collect() -} - -/// Encode the given secret byte `m`, by evaluating the given -/// polynomial at x = `j`, and adding the result to `m`. -/// -/// Reference: Figure 7 from the *New Directions in Secret Sharing* paper. -pub(crate) fn encode_secret_byte(m: u8, j: u8, poly: &Poly) -> u8 { - let mut acc = Gf256::from_byte(m); - for (l, &r) in poly.coeffs.iter().enumerate() { - let s = Gf256::from_byte(j).pow(l as u8 + 1); - acc += r * s; - } - acc.to_byte() -} diff --git a/src/dss/thss/mod.rs b/src/dss/thss/mod.rs deleted file mode 100644 index 4c3534b4..00000000 --- a/src/dss/thss/mod.rs +++ /dev/null @@ -1,122 +0,0 @@ -//! Implements the `ThSS` threshold secret sharing scheme. -//! -//! This scheme satisfies the following security properties: -//! -//! **Property** | **Satisifed?** | **Description** -//! -------------|----------------|---------------- -//! **Basic** | Yes | Basic correctness: If you attempt to recover a secret from an authorized set of shares that were obtained by sharing out a secret **M** using an access structure **A**, you're sure to get back **A** and **M**.
Note: in this implementation **A** is not actually returned, but definitely could. -//! **Priv1** | Yes | Standard privacy notation: When the coins are used by the dealer are uniformly random, unauthorized sets of shares have no computationally extractable information about the underlying secret. -//! **Priv2** | No | Privacy for deterministic or hedged schemes: extract whatever entropy one can from the underlying secret. If it’s adequate, no additional randomness is needed in order to achieve a meaningful notion of privacy. -//! **Auth1** | No | A share obtained from an honest dealer commits it to a single underlying secret: that and only that value can be recovered. -//! **Auth2** | No | A share obtained even from a dishonest dealer commits it to a single underlying secret: that and only that value might be recovered. Implies Auth1. -//! **ErrDet** | Yes | An inauthentic set of shares produced by an adversary will be flagged as such when fed to the recovery algorithm. -//! **Repro** | No | Share reproducible: The scheme can produce shares in a deterministic way. - -use errors::*; - -mod encode; -mod serialize; - -mod share; -pub use self::share::*; - -mod scheme; -pub(crate) use self::scheme::ThSS; - -use dss::AccessStructure; - -/// Performs threshold k-out-of-n secret sharing using the `ThSS` scheme. -/// -/// # Examples -/// -/// ```rust -/// use rusty_secrets::dss::thss; -/// -/// let secret = "These programs were never about terrorism: they’re about economic spying, \ -/// social control, and diplomatic manipulation. They’re about power."; -/// -/// let mut metadata = thss::MetaData::new(); -/// metadata.tags.insert("mime_type".to_string(), "text/plain".to_string()); -/// -/// let result = thss::split_secret( -/// 7, -/// 10, -/// &secret.as_bytes(), -/// &Some(metadata) -/// ); -/// -/// match result { -/// Ok(shares) => { -/// // Do something with the shares -/// }, -/// Err(e) => { -/// // Deal with error -/// } -/// } -/// -/// ``` -pub fn split_secret( - k: u8, - n: u8, - secret: &[u8], - metadata: &Option, -) -> Result> { - ThSS::default().split_secret(k, n, secret, metadata) -} - -/// Recovers the secret from a k-out-of-n secret sharing scheme (`ThSS`). -/// -/// At least `k` distinct shares need to be provided to recover the secret. -/// -/// # Examples -/// -/// ```rust -/// use rusty_secrets::dss::thss; -/// -/// let secret = "These programs were never about terrorism: they’re about economic spying, \ -/// social control, and diplomatic manipulation. They’re about power."; -/// -/// let mut metadata = thss::MetaData::new(); -/// metadata.tags.insert("mime_type".to_string(), "text/plain".to_string()); -/// -/// let shares = thss::split_secret( -/// 7, -/// 10, -/// &secret.as_bytes(), -/// &Some(metadata) -/// ).unwrap(); -/// -/// match thss::recover_secret(&shares) { -/// Ok((secret, access_structure, metadata)) => { -/// // Do something with the secret and the metadata -/// }, -/// Err(e) => { -/// // Deal with the error -/// } -/// } -/// ``` -pub fn recover_secret(shares: &[Share]) -> Result<(Vec, AccessStructure, Option)> { - ThSS::default().recover_secret(shares) -} - -#[cfg(test)] -mod tests { - - use super::*; - - #[test] - fn split_then_recover_yields_original_secret() { - let secret = "Hello, World!".to_string().into_bytes(); - - let shares = split_secret(7, 10, &secret, &None).unwrap(); - assert_eq!(shares.len(), 10); - - let (recovered, access, metadata) = recover_secret(&shares[2..9]).unwrap(); - - assert_eq!(secret, recovered); - assert_eq!(access.threshold, 7); - assert_eq!(access.shares_count, 10); - assert_eq!(None, metadata); - } - -} diff --git a/src/dss/thss/scheme.rs b/src/dss/thss/scheme.rs deleted file mode 100644 index e7d0d1e2..00000000 --- a/src/dss/thss/scheme.rs +++ /dev/null @@ -1,133 +0,0 @@ -//! Simple threshold secret sharing scheme - -use std::fmt; - -use ring::rand::{SecureRandom, SystemRandom}; - -use dss::random::{random_bytes, random_bytes_count, MAX_MESSAGE_SIZE}; -use errors::*; -use gf256::Gf256; -use lagrange; -use share::validation::{validate_share_count, validate_shares}; - -use super::AccessStructure; -use super::encode::encode_secret; -use super::share::*; - -/// We bound the message size at about 16MB to avoid overflow in `random_bytes_count`. -/// Moreover, given the current performances, it is almost unpractical to run -/// the sharing scheme on message larger than that. -const MAX_SECRET_SIZE: usize = MAX_MESSAGE_SIZE; - -/// A simple threshold sharing scheme -#[allow(missing_debug_implementations)] -pub(crate) struct ThSS { - /// The randomness source - random: Box, -} - -impl fmt::Debug for ThSS { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "ThSS") - } -} - -impl Default for ThSS { - fn default() -> Self { - Self::new(Box::new(SystemRandom::new())) - } -} - -impl ThSS { - /// Constructs a new sharing scheme - pub fn new(random: Box) -> Self { - Self { random } - } - - /// Split a secret following a given sharing `scheme`, - /// with `threshold` being the number of shares necessary to recover the secret, - /// and `shares_count` the total number of shares to be dealt. - pub fn split_secret( - &self, - threshold: u8, - shares_count: u8, - secret: &[u8], - metadata: &Option, - ) -> Result> { - let (threshold, shares_count) = validate_share_count(threshold, shares_count)?; - let secret_len = secret.len(); - - if secret_len == 0 { - bail!(ErrorKind::EmptySecret); - } - if secret_len > MAX_SECRET_SIZE { - bail!(ErrorKind::SecretTooBig(secret_len, MAX_SECRET_SIZE)); - } - - let rands_len = random_bytes_count(threshold, secret_len); - let rands = random_bytes(self.random.as_ref(), rands_len)?; - - let shares = (1..shares_count + 1) - .map(|id| { - let data = encode_secret(secret, threshold, id, &rands); - - Share { - id, - threshold, - shares_count, - data, - metadata: metadata.clone(), - } - }) - .collect(); - - Ok(shares) - } - - /// Recover the secret from the given set of shares - pub fn recover_secret( - &self, - shares: &[Share], - ) -> Result<(Vec, AccessStructure, Option)> { - let shares = shares.to_vec(); - let (threshold, cypher_len) = validate_shares(&shares)?; - - let polys = (0..cypher_len) - .map(|i| { - let points = shares - .iter() - .take(threshold as usize) - .map(|share| (Gf256::from_byte(share.id), Gf256::from_byte(share.data[i]))) - .collect::>(); - - lagrange::interpolate(&points) - }) - .collect::>(); - - for (i, poly) in polys.iter().enumerate() { - // Check remaining shares for consistency. - // See Figure 7 of the paper - let remaining_shares = shares.iter().enumerate().skip(threshold as usize); - - for (u, share) in remaining_shares { - let value = poly.evaluate_at(Gf256::from_byte(u as u8 + 1)).to_byte(); - if value != share.data[i] { - bail!(ErrorKind::InconsistentShares); - } - } - } - - let metadata = shares[0].metadata.clone(); - let secret = polys - .iter() - .map(|p| p.evaluate_at_zero().to_byte()) - .collect(); - - let access_structure = AccessStructure { - threshold: threshold, - shares_count: shares.first().unwrap().shares_count, - }; - - Ok((secret, access_structure, metadata)) - } -} diff --git a/src/dss/thss/serialize.rs b/src/dss/thss/serialize.rs deleted file mode 100644 index 1111f55e..00000000 --- a/src/dss/thss/serialize.rs +++ /dev/null @@ -1,78 +0,0 @@ -use super::{MetaData, Share}; -use dss::format::{format_share_protobuf, parse_share_protobuf}; -use dss::utils::{btreemap_to_hashmap, hashmap_to_btreemap}; -use errors::*; -use proto::dss::{MetaDataProto, ShareProto}; - -pub(crate) fn share_to_string(share: Share) -> String { - let proto = share_to_protobuf(share); - format_share_protobuf(&proto) -} - -pub(crate) fn share_from_string(raw: &str) -> Result { - let mut proto = parse_share_protobuf(raw)?; - - let metadata_proto = if proto.has_meta_data() { - Some(metadata_from_proto(proto.take_meta_data())) - } else { - None - }; - - let i = proto.get_id() as u8; - let k = proto.get_threshold() as u8; - let n = proto.get_shares_count() as u8; - - if k < 1 || i < 1 { - bail! { - ErrorKind::ShareParsingError( - format!("Found illegal share info: threshold = {}, identifier = {}.", k, i), - ) - } - } - - if n < 1 || k > n || i > n { - bail! { - ErrorKind::ShareParsingError( - format!("Found illegal share info: shares_count = {}, threshold = {}, identifier = {}.", n, k, i), - ) - } - } - - let share = Share { - id: i, - threshold: k, - shares_count: n, - data: proto.take_data(), - metadata: metadata_proto, - }; - - Ok(share) -} - -pub(crate) fn share_to_protobuf(share: Share) -> ShareProto { - let mut proto = ShareProto::new(); - - proto.set_id(share.id.into()); - proto.set_threshold(share.threshold.into()); - proto.set_shares_count(share.shares_count.into()); - proto.set_data(share.data); - - if let Some(meta_data) = share.metadata { - let metadata_proto = metadata_to_proto(meta_data); - proto.set_meta_data(metadata_proto); - } - - proto -} - -fn metadata_to_proto(meta_data: MetaData) -> MetaDataProto { - let mut proto = MetaDataProto::new(); - proto.set_tags(btreemap_to_hashmap(meta_data.tags)); - proto -} - -fn metadata_from_proto(mut proto: MetaDataProto) -> MetaData { - MetaData { - tags: hashmap_to_btreemap(proto.take_tags()), - } -} diff --git a/src/dss/thss/share.rs b/src/dss/thss/share.rs deleted file mode 100644 index f68bf15e..00000000 --- a/src/dss/thss/share.rs +++ /dev/null @@ -1,55 +0,0 @@ -use super::serialize::{share_from_string, share_to_string}; -use errors::*; -use share::IsShare; - -pub use dss::metadata::MetaData; - -/// A share identified by an `id`, a threshold `k`, a number of total shares `n`, -/// the `data` held in the share, and the share's `metadata`. -#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct Share { - /// The identifier of the share (varies between 1 and n where n is the total number of generated shares) - pub id: u8, - /// The number of shares necessary to recover the secret, aka a threshold - pub threshold: u8, - /// The total number of shares that have been dealt - pub shares_count: u8, - /// The share data itself - pub data: Vec, - /// The metadata associated with this share - pub metadata: Option, -} - -impl Share { - /// Format this share a string suitable for sharing - /// over an ASCII-encoded channel, such as a text file, - /// or an e-mail. - pub fn into_string(self) -> String { - share_to_string(self) - } - - /// Parse the given string into a `Share`. - /// The `raw` string must have been generated by the - /// `Share::to_string` method for it to succeed. - pub fn from_string(raw: &str) -> Result { - share_from_string(raw) - } -} - -impl IsShare for Share { - fn get_id(&self) -> u8 { - self.id - } - - fn get_data(&self) -> &[u8] { - &self.data - } - - fn get_threshold(&self) -> u8 { - self.threshold - } - - fn get_shares_count(&self) -> Option { - Some(self.shares_count) - } -} diff --git a/src/dss/utils.rs b/src/dss/utils.rs deleted file mode 100644 index 20a0fedf..00000000 --- a/src/dss/utils.rs +++ /dev/null @@ -1,28 +0,0 @@ -use std; - -use std::collections::{BTreeMap, HashMap}; -use std::hash::Hash; - -/// Transmutes a `&[u8]` into a `&[u32]`. -/// Despite `std::mem::transmute` being very unsafe in -/// general, this should actually be safe as long as -/// `input` contains a multiple of 4 bytes. -#[allow(unsafe_code)] -pub(crate) fn slice_u8_to_slice_u32(input: &[u8]) -> &[u32] { - assert_eq!(input.len() % 4, 0); - unsafe { std::mem::transmute(input) } -} - -/// Creates a `HashMap` from a `BTreeMap` -pub(crate) fn btreemap_to_hashmap(btree: BTreeMap) -> HashMap { - let mut hash = HashMap::new(); - hash.extend(btree.into_iter()); - hash -} - -/// Creates a `BTreeMap` from a `HashMap` -pub(crate) fn hashmap_to_btreemap(hash: HashMap) -> BTreeMap { - let mut btree = BTreeMap::new(); - btree.extend(hash.into_iter()); - btree -} diff --git a/src/errors.rs b/src/errors.rs index 1fbe12b9..33466dbc 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -149,7 +149,7 @@ error_chain! { /// Takes a `Vec` and formats it like the normal `fmt::Debug` implementation, unless it has more //than five elements, in which case the rest are replaced by ellipsis. -fn no_more_than_five(vec: &Vec) -> String { +fn no_more_than_five(vec: &[T]) -> String { let len = vec.len(); if len > 5 { let mut string = String::from("["); diff --git a/src/gf256.rs b/src/gf256.rs index 49ad57ea..932a352b 100644 --- a/src/gf256.rs +++ b/src/gf256.rs @@ -1,3 +1,5 @@ +#![allow(suspicious_arithmetic_impl)] + //! This module provides the Gf256 type which is used to represent //! elements of a finite field with 256 elements. @@ -21,24 +23,29 @@ impl Gf256 { pub fn zero() -> Gf256 { Gf256 { poly: 0 } } + /// returns the multiplicative neutral element of the field #[inline] pub fn one() -> Gf256 { Gf256 { poly: 1 } } + #[inline] pub fn from_byte(b: u8) -> Gf256 { Gf256 { poly: b } } + #[inline] - pub fn to_byte(&self) -> u8 { + pub fn to_byte(self) -> u8 { self.poly } + pub fn exp(power: u8) -> Gf256 { let tabs = get_tables(); Gf256::from_byte(tabs.exp[power as usize]) } - pub fn log(&self) -> Option { + + pub fn log(self) -> Option { if self.poly == 0 { None } else { @@ -46,20 +53,22 @@ impl Gf256 { Some(tabs.log[self.poly as usize]) } } - pub fn pow(&self, mut exp: u8) -> Gf256 { - let mut base = *self; + + #[allow(dead_code)] + pub fn pow(self, mut exp: u8) -> Gf256 { + let mut base = self; let mut acc = Self::one(); while exp > 1 { if (exp & 1) == 1 { - acc = acc * base; + acc *= base; } exp /= 2; base = base * base; } if exp == 1 { - acc = acc * base; + acc *= base; } acc @@ -231,6 +240,7 @@ mod tests { (a + b) + c == a + (b + c) } + #[cfg_attr(feature = "cargo-clippy", allow(eq_op))] fn law_commutativity(a: Gf256, b: Gf256) -> bool { a + b == b + a } @@ -257,6 +267,7 @@ mod tests { (a * b) * c == a * (b * c) } + #[cfg_attr(feature = "cargo-clippy", allow(eq_op))] fn law_commutativity(a: Gf256, b: Gf256) -> bool { a * b == b * a } diff --git a/src/lagrange.rs b/src/lagrange.rs index b49a91f4..d5c80368 100644 --- a/src/lagrange.rs +++ b/src/lagrange.rs @@ -1,5 +1,4 @@ use gf256::Gf256; -use poly::Poly; /// Evaluates an interpolated polynomial at `Gf256::zero()` where /// the polynomial is determined using barycentric Lagrange @@ -43,99 +42,3 @@ fn barycentric_interpolate_at(k: usize, points: &[(u8, u8)]) -> u8 { (num / denom).to_byte() } - -/// Computeds the coefficient of the Lagrange polynomial interpolated -/// from the given `points`, in the G(2^8) Galois field. -pub(crate) fn interpolate(points: &[(Gf256, Gf256)]) -> Poly { - let len = points.len(); - - let mut poly = vec![Gf256::zero(); len]; - - for &(x, y) in points { - assert_ne!(x.poly, 0, "Invalid share x = 0"); - let mut coeffs = vec![Gf256::zero(); len]; - coeffs[0] = y; - - let mut prod = Gf256::one(); - for &(x1, _) in points { - if x != x1 { - prod *= x - x1; - - let mut prec = Gf256::zero(); - coeffs = coeffs - .into_iter() - .map(|coeff| { - let new_coeff = coeff * (-x1) + prec; - prec = coeff; - new_coeff - }) - .collect(); - } - } - - poly = poly.iter() - .zip(coeffs.iter()) - .map(|(&old_coeff, &add)| old_coeff + add / prod) - .collect(); - } - - Poly::new(poly) -} - -#[cfg(test)] -#[allow(trivial_casts)] -mod tests { - - use super::*; - use gf256::*; - use quickcheck::*; - use std; - - quickcheck! { - - fn interpolate_evaluate_at_works(ys: Vec) -> TestResult { - if ys.is_empty() || ys.len() > std::u8::MAX as usize { - return TestResult::discard(); - } - - let points = ys.into_iter() - .zip(1..std::u8::MAX) - .map(|(y, x)| (gf256!(x), y)) - .collect::>(); - let poly = interpolate(&points); - - for (x, y) in points { - if poly.evaluate_at(x) != y { - return TestResult::failed(); - } - } - - TestResult::passed() - } - - fn interpolate_evaluate_at_0_eq_evaluate_at(ys: Vec) -> TestResult { - if ys.is_empty() || ys.len() > std::u8::MAX as usize { - return TestResult::discard(); - } - - let points = ys.into_iter() - .zip(1..std::u8::MAX) - .map(|(y, x)| (x, y)) - .collect::>(); - - let elems = points - .iter() - .map(|&(x, y)| (gf256!(x), gf256!(y))) - .collect::>(); - - let poly = interpolate(&elems); - - let equals = poly.evaluate_at(Gf256::zero()).to_byte() - == interpolate_at(points.len() as u8, points.as_slice()); - - TestResult::from_bool(equals) - } - - } - -} diff --git a/src/lib.rs b/src/lib.rs index 90d5c3c0..1cf27568 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,8 +1,16 @@ //! `RustySecrets` implements Shamir's secret sharing in Rust. It provides the possibility to sign shares. -#![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 +)] #![cfg_attr(feature = "cargo-clippy", allow(doc_markdown))] // `error_chain!` can recurse deeply #![recursion_limit = "1024"] @@ -19,18 +27,13 @@ extern crate ring; #[macro_use] mod gf256; mod lagrange; -mod poly; mod share; -mod vol_hash; pub mod errors; pub mod proto; pub mod sss; pub mod wrapped_secrets; -#[cfg(feature = "dss")] -pub mod dss; - #[cfg(test)] extern crate itertools; diff --git a/src/poly.rs b/src/poly.rs deleted file mode 100644 index aaee0b59..00000000 --- a/src/poly.rs +++ /dev/null @@ -1,29 +0,0 @@ -use gf256::Gf256; - -static MAX_COEFFS: usize = 256; - -pub(crate) struct Poly { - pub coeffs: Vec, -} - -impl Poly { - pub fn new(coeffs: Vec) -> Self { - Self { coeffs } - } - - pub fn evaluate_at_zero(&self) -> Gf256 { - self.coeffs[0] - } - - pub fn evaluate_at(&self, x: Gf256) -> Gf256 { - assert!(self.coeffs.len() < MAX_COEFFS); - - let mut result = Gf256::zero(); - - for (i, c) in self.coeffs.iter().enumerate() { - result += *c * x.pow(i as u8); - } - - result - } -} diff --git a/src/proto/dss/metadata.rs b/src/proto/dss/metadata.rs deleted file mode 100644 index 0b27f5dd..00000000 --- a/src/proto/dss/metadata.rs +++ /dev/null @@ -1,253 +0,0 @@ -// This file is generated. Do not edit -// @generated - -// https://github.com/Manishearth/rust-clippy/issues/702 -#![allow(unknown_lints)] -#![allow(clippy)] - -#![cfg_attr(rustfmt, rustfmt_skip)] - -#![allow(box_pointers)] -#![allow(dead_code)] -#![allow(missing_docs)] -#![allow(non_camel_case_types)] -#![allow(non_snake_case)] -#![allow(non_upper_case_globals)] -#![allow(trivial_casts)] -#![allow(unsafe_code)] -#![allow(unused_imports)] -#![allow(unused_results)] - -use protobuf::Message as Message_imported_for_functions; -use protobuf::ProtobufEnum as ProtobufEnum_imported_for_functions; - -#[derive(PartialEq, Clone, Default)] -pub struct MetaDataProto { - // message fields - pub tags: ::std::collections::HashMap<::std::string::String, ::std::string::String>, - // special fields - unknown_fields: ::protobuf::UnknownFields, - cached_size: ::protobuf::CachedSize, -} - -// see codegen.rs for the explanation why impl Sync explicitly -unsafe impl ::std::marker::Sync for MetaDataProto {} - -impl MetaDataProto { - pub fn new() -> MetaDataProto { - ::std::default::Default::default() - } - - pub fn default_instance() -> &'static MetaDataProto { - static mut instance: ::protobuf::lazy::Lazy = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const MetaDataProto, - }; - unsafe { instance.get(MetaDataProto::new) } - } - - // repeated .dss.MetaDataProto.TagsEntry tags = 1; - - pub fn clear_tags(&mut self) { - self.tags.clear(); - } - - // Param is passed by value, moved - pub fn set_tags( - &mut self, - v: ::std::collections::HashMap<::std::string::String, ::std::string::String>, - ) { - self.tags = v; - } - - // Mutable pointer to the field. - pub fn mut_tags( - &mut self, - ) -> &mut ::std::collections::HashMap<::std::string::String, ::std::string::String> { - &mut self.tags - } - - // Take field - pub fn take_tags( - &mut self, - ) -> ::std::collections::HashMap<::std::string::String, ::std::string::String> { - ::std::mem::replace(&mut self.tags, ::std::collections::HashMap::new()) - } - - pub fn get_tags( - &self, - ) -> &::std::collections::HashMap<::std::string::String, ::std::string::String> { - &self.tags - } - - fn get_tags_for_reflect( - &self, - ) -> &::std::collections::HashMap<::std::string::String, ::std::string::String> { - &self.tags - } - - fn mut_tags_for_reflect( - &mut self, - ) -> &mut ::std::collections::HashMap<::std::string::String, ::std::string::String> { - &mut self.tags - } -} - -impl ::protobuf::Message for MetaDataProto { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from( - &mut self, - is: &mut ::protobuf::CodedInputStream, - ) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_map_into::< - ::protobuf::types::ProtobufTypeString, - ::protobuf::types::ProtobufTypeString, - >(wire_type, is, &mut self.tags)?; - } - _ => { - ::protobuf::rt::read_unknown_or_skip_group( - field_number, - wire_type, - is, - self.mut_unknown_fields(), - )?; - } - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - my_size += ::protobuf::rt::compute_map_size::< - ::protobuf::types::ProtobufTypeString, - ::protobuf::types::ProtobufTypeString, - >(1, &self.tags); - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes( - &self, - os: &mut ::protobuf::CodedOutputStream, - ) -> ::protobuf::ProtobufResult<()> { - ::protobuf::rt::write_map_with_cached_sizes::< - ::protobuf::types::ProtobufTypeString, - ::protobuf::types::ProtobufTypeString, - >(1, &self.tags, os)?; - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &::std::any::Any { - self as &::std::any::Any - } - fn as_any_mut(&mut self) -> &mut ::std::any::Any { - self as &mut ::std::any::Any - } - fn into_any(self: Box) -> ::std::boxed::Box<::std::any::Any> { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - ::protobuf::MessageStatic::descriptor_static(None::) - } -} - -impl ::protobuf::MessageStatic for MetaDataProto { - fn new() -> MetaDataProto { - MetaDataProto::new() - } - - fn descriptor_static( - _: ::std::option::Option, - ) -> &'static ::protobuf::reflect::MessageDescriptor { - static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = - ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const ::protobuf::reflect::MessageDescriptor, - }; - unsafe { - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_map_accessor::<_, ::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeString>( - "tags", - MetaDataProto::get_tags_for_reflect, - MetaDataProto::mut_tags_for_reflect, - )); - ::protobuf::reflect::MessageDescriptor::new::( - "MetaDataProto", - fields, - file_descriptor_proto() - ) - }) - } - } -} - -impl ::protobuf::Clear for MetaDataProto { - fn clear(&mut self) { - self.clear_tags(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for MetaDataProto { - fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for MetaDataProto { - fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { - ::protobuf::reflect::ProtobufValueRef::Message(self) - } -} - -static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x12dss/metadata.proto\x12\x03dss\"z\n\rMetaDataProto\x120\n\x04tags\ - \x18\x01\x20\x03(\x0b2\x1c.dss.MetaDataProto.TagsEntryR\x04tags\x1a7\n\t\ - TagsEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\x14\n\x05value\ - \x18\x02\x20\x01(\tR\x05value:\x028\x01Jz\n\x06\x12\x04\0\0\x06\x01\n\ - \x08\n\x01\x0c\x12\x03\0\0\x12\n\x08\n\x01\x02\x12\x03\x02\x08\x0b\n\n\n\ - \x02\x04\0\x12\x04\x04\0\x06\x01\n\n\n\x03\x04\0\x01\x12\x03\x04\x08\x15\ - \n\x0b\n\x04\x04\0\x02\0\x12\x03\x05\x02\x1f\n\r\n\x05\x04\0\x02\0\x04\ - \x12\x04\x05\x02\x04\x17\n\x0c\n\x05\x04\0\x02\0\x06\x12\x03\x05\x02\x15\ - \n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\x05\x16\x1a\n\x0c\n\x05\x04\0\x02\0\ - \x03\x12\x03\x05\x1d\x1eb\x06proto3\ -"; - -static mut file_descriptor_proto_lazy: ::protobuf::lazy::Lazy<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const ::protobuf::descriptor::FileDescriptorProto, -}; - -fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto { - ::protobuf::parse_from_bytes(file_descriptor_proto_data).unwrap() -} - -pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto { - unsafe { file_descriptor_proto_lazy.get(|| parse_descriptor_proto()) } -} diff --git a/src/proto/dss/mod.rs b/src/proto/dss/mod.rs deleted file mode 100644 index aaf9b21c..00000000 --- a/src/proto/dss/mod.rs +++ /dev/null @@ -1,13 +0,0 @@ -#[allow(unused_qualifications, deprecated, missing_docs)] -mod secret; -pub use self::secret::SecretProto; - -#[allow(unused_qualifications, deprecated, missing_docs)] -mod share; -pub use self::share::ShareProto; - -#[allow(unused_qualifications, deprecated, missing_docs)] -mod metadata; -pub use self::metadata::MetaDataProto; - -use super::version; diff --git a/src/proto/dss/secret.rs b/src/proto/dss/secret.rs deleted file mode 100644 index 7b7a4c0a..00000000 --- a/src/proto/dss/secret.rs +++ /dev/null @@ -1,369 +0,0 @@ -// This file is generated. Do not edit -// @generated - -// https://github.com/Manishearth/rust-clippy/issues/702 -#![allow(unknown_lints)] -#![allow(clippy)] - -#![cfg_attr(rustfmt, rustfmt_skip)] - -#![allow(box_pointers)] -#![allow(dead_code)] -#![allow(missing_docs)] -#![allow(non_camel_case_types)] -#![allow(non_snake_case)] -#![allow(non_upper_case_globals)] -#![allow(trivial_casts)] -#![allow(unsafe_code)] -#![allow(unused_imports)] -#![allow(unused_results)] - -use protobuf::Message as Message_imported_for_functions; -use protobuf::ProtobufEnum as ProtobufEnum_imported_for_functions; - -#[derive(PartialEq, Clone, Default)] -pub struct SecretProto { - // message fields - pub version: super::version::VersionProto, - pub secret: ::std::vec::Vec, - pub meta_data: ::protobuf::SingularPtrField, - // special fields - unknown_fields: ::protobuf::UnknownFields, - cached_size: ::protobuf::CachedSize, -} - -// see codegen.rs for the explanation why impl Sync explicitly -unsafe impl ::std::marker::Sync for SecretProto {} - -impl SecretProto { - pub fn new() -> SecretProto { - ::std::default::Default::default() - } - - pub fn default_instance() -> &'static SecretProto { - static mut instance: ::protobuf::lazy::Lazy = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const SecretProto, - }; - unsafe { instance.get(SecretProto::new) } - } - - // .VersionProto version = 1; - - pub fn clear_version(&mut self) { - self.version = super::version::VersionProto::INITIAL_RELEASE; - } - - // Param is passed by value, moved - pub fn set_version(&mut self, v: super::version::VersionProto) { - self.version = v; - } - - pub fn get_version(&self) -> super::version::VersionProto { - self.version - } - - fn get_version_for_reflect(&self) -> &super::version::VersionProto { - &self.version - } - - fn mut_version_for_reflect(&mut self) -> &mut super::version::VersionProto { - &mut self.version - } - - // bytes secret = 2; - - pub fn clear_secret(&mut self) { - self.secret.clear(); - } - - // Param is passed by value, moved - pub fn set_secret(&mut self, v: ::std::vec::Vec) { - self.secret = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_secret(&mut self) -> &mut ::std::vec::Vec { - &mut self.secret - } - - // Take field - pub fn take_secret(&mut self) -> ::std::vec::Vec { - ::std::mem::replace(&mut self.secret, ::std::vec::Vec::new()) - } - - pub fn get_secret(&self) -> &[u8] { - &self.secret - } - - fn get_secret_for_reflect(&self) -> &::std::vec::Vec { - &self.secret - } - - fn mut_secret_for_reflect(&mut self) -> &mut ::std::vec::Vec { - &mut self.secret - } - - // .dss.MetaDataProto meta_data = 3; - - pub fn clear_meta_data(&mut self) { - self.meta_data.clear(); - } - - pub fn has_meta_data(&self) -> bool { - self.meta_data.is_some() - } - - // Param is passed by value, moved - pub fn set_meta_data(&mut self, v: super::metadata::MetaDataProto) { - self.meta_data = ::protobuf::SingularPtrField::some(v); - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_meta_data(&mut self) -> &mut super::metadata::MetaDataProto { - if self.meta_data.is_none() { - self.meta_data.set_default(); - } - self.meta_data.as_mut().unwrap() - } - - // Take field - pub fn take_meta_data(&mut self) -> super::metadata::MetaDataProto { - self.meta_data.take().unwrap_or_else(|| { - super::metadata::MetaDataProto::new() - }) - } - - pub fn get_meta_data(&self) -> &super::metadata::MetaDataProto { - self.meta_data.as_ref().unwrap_or_else(|| { - super::metadata::MetaDataProto::default_instance() - }) - } - - fn get_meta_data_for_reflect( - &self, - ) -> &::protobuf::SingularPtrField { - &self.meta_data - } - - fn mut_meta_data_for_reflect( - &mut self, - ) -> &mut ::protobuf::SingularPtrField { - &mut self.meta_data - } -} - -impl ::protobuf::Message for SecretProto { - fn is_initialized(&self) -> bool { - for v in &self.meta_data { - if !v.is_initialized() { - return false; - } - } - true - } - - fn merge_from( - &mut self, - is: &mut ::protobuf::CodedInputStream, - ) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err( - ::protobuf::rt::unexpected_wire_type(wire_type), - ); - } - let tmp = is.read_enum()?; - self.version = tmp; - } - 2 => { - ::protobuf::rt::read_singular_proto3_bytes_into( - wire_type, - is, - &mut self.secret, - )?; - } - 3 => { - ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.meta_data)?; - } - _ => { - ::protobuf::rt::read_unknown_or_skip_group( - field_number, - wire_type, - is, - self.mut_unknown_fields(), - )?; - } - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if self.version != super::version::VersionProto::INITIAL_RELEASE { - my_size += ::protobuf::rt::enum_size(1, self.version); - } - if !self.secret.is_empty() { - my_size += ::protobuf::rt::bytes_size(2, &self.secret); - } - if let Some(ref v) = self.meta_data.as_ref() { - let len = v.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes( - &self, - os: &mut ::protobuf::CodedOutputStream, - ) -> ::protobuf::ProtobufResult<()> { - if self.version != super::version::VersionProto::INITIAL_RELEASE { - os.write_enum(1, self.version.value())?; - } - if !self.secret.is_empty() { - os.write_bytes(2, &self.secret)?; - } - if let Some(ref v) = self.meta_data.as_ref() { - os.write_tag( - 3, - ::protobuf::wire_format::WireTypeLengthDelimited, - )?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &::std::any::Any { - self as &::std::any::Any - } - fn as_any_mut(&mut self) -> &mut ::std::any::Any { - self as &mut ::std::any::Any - } - fn into_any(self: Box) -> ::std::boxed::Box<::std::any::Any> { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - ::protobuf::MessageStatic::descriptor_static(None::) - } -} - -impl ::protobuf::MessageStatic for SecretProto { - fn new() -> SecretProto { - SecretProto::new() - } - - fn descriptor_static( - _: ::std::option::Option, - ) -> &'static ::protobuf::reflect::MessageDescriptor { - static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = - ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const ::protobuf::reflect::MessageDescriptor, - }; - unsafe { - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( - "version", - SecretProto::get_version_for_reflect, - SecretProto::mut_version_for_reflect, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>( - "secret", - SecretProto::get_secret_for_reflect, - SecretProto::mut_secret_for_reflect, - )); - fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "meta_data", - SecretProto::get_meta_data_for_reflect, - SecretProto::mut_meta_data_for_reflect, - )); - ::protobuf::reflect::MessageDescriptor::new::( - "SecretProto", - fields, - file_descriptor_proto() - ) - }) - } - } -} - -impl ::protobuf::Clear for SecretProto { - fn clear(&mut self) { - self.clear_version(); - self.clear_secret(); - self.clear_meta_data(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for SecretProto { - fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for SecretProto { - fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { - ::protobuf::reflect::ProtobufValueRef::Message(self) - } -} - -static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x10dss/secret.proto\x1a\rversion.proto\x1a\x12dss/metadata.proto\"\ - \x7f\n\x0bSecretProto\x12'\n\x07version\x18\x01\x20\x01(\x0e2\r.VersionP\ - rotoR\x07version\x12\x16\n\x06secret\x18\x02\x20\x01(\x0cR\x06secret\x12\ - /\n\tmeta_data\x18\x03\x20\x01(\x0b2\x12.dss.MetaDataProtoR\x08metaDataJ\ - \x92\x02\n\x06\x12\x04\0\0\t\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\t\n\ - \x02\x03\0\x12\x03\x02\x07\x16\n\t\n\x02\x03\x01\x12\x03\x03\x07\x1b\n\n\ - \n\x02\x04\0\x12\x04\x05\0\t\x01\n\n\n\x03\x04\0\x01\x12\x03\x05\x08\x13\ - \n\x0b\n\x04\x04\0\x02\0\x12\x03\x06\x08!\n\r\n\x05\x04\0\x02\0\x04\x12\ - \x04\x06\x08\x05\x15\n\x0c\n\x05\x04\0\x02\0\x06\x12\x03\x06\x08\x14\n\ - \x0c\n\x05\x04\0\x02\0\x01\x12\x03\x06\x15\x1c\n\x0c\n\x05\x04\0\x02\0\ - \x03\x12\x03\x06\x1f\x20\n\x0b\n\x04\x04\0\x02\x01\x12\x03\x07\x08\x19\n\ - \r\n\x05\x04\0\x02\x01\x04\x12\x04\x07\x08\x06!\n\x0c\n\x05\x04\0\x02\ - \x01\x05\x12\x03\x07\x08\r\n\x0c\n\x05\x04\0\x02\x01\x01\x12\x03\x07\x0e\ - \x14\n\x0c\n\x05\x04\0\x02\x01\x03\x12\x03\x07\x17\x18\n\x0b\n\x04\x04\0\ - \x02\x02\x12\x03\x08\x08(\n\r\n\x05\x04\0\x02\x02\x04\x12\x04\x08\x08\ - \x07\x19\n\x0c\n\x05\x04\0\x02\x02\x06\x12\x03\x08\x08\x19\n\x0c\n\x05\ - \x04\0\x02\x02\x01\x12\x03\x08\x1a#\n\x0c\n\x05\x04\0\x02\x02\x03\x12\ - \x03\x08&'b\x06proto3\ -"; - -static mut file_descriptor_proto_lazy: ::protobuf::lazy::Lazy<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const ::protobuf::descriptor::FileDescriptorProto, -}; - -fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto { - ::protobuf::parse_from_bytes(file_descriptor_proto_data).unwrap() -} - -pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto { - unsafe { file_descriptor_proto_lazy.get(|| parse_descriptor_proto()) } -} diff --git a/src/proto/dss/share.rs b/src/proto/dss/share.rs deleted file mode 100644 index 4eb8e408..00000000 --- a/src/proto/dss/share.rs +++ /dev/null @@ -1,492 +0,0 @@ -// This file is generated. Do not edit -// @generated - -// https://github.com/Manishearth/rust-clippy/issues/702 -#![allow(unknown_lints)] -#![allow(clippy)] - -#![cfg_attr(rustfmt, rustfmt_skip)] - -#![allow(box_pointers)] -#![allow(dead_code)] -#![allow(missing_docs)] -#![allow(non_camel_case_types)] -#![allow(non_snake_case)] -#![allow(non_upper_case_globals)] -#![allow(trivial_casts)] -#![allow(unsafe_code)] -#![allow(unused_imports)] -#![allow(unused_results)] - -use protobuf::Message as Message_imported_for_functions; -use protobuf::ProtobufEnum as ProtobufEnum_imported_for_functions; - -#[derive(PartialEq,Clone,Default)] -pub struct ShareProto { - // message fields - pub id: u32, - pub threshold: u32, - pub shares_count: u32, - pub data: ::std::vec::Vec, - pub hash: ::std::vec::Vec, - pub meta_data: ::protobuf::SingularPtrField, - // special fields - unknown_fields: ::protobuf::UnknownFields, - cached_size: ::protobuf::CachedSize, -} - -// see codegen.rs for the explanation why impl Sync explicitly -unsafe impl ::std::marker::Sync for ShareProto {} - -impl ShareProto { - pub fn new() -> ShareProto { - ::std::default::Default::default() - } - - pub fn default_instance() -> &'static ShareProto { - static mut instance: ::protobuf::lazy::Lazy = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const ShareProto, - }; - unsafe { - instance.get(ShareProto::new) - } - } - - // uint32 id = 1; - - pub fn clear_id(&mut self) { - self.id = 0; - } - - // Param is passed by value, moved - pub fn set_id(&mut self, v: u32) { - self.id = v; - } - - pub fn get_id(&self) -> u32 { - self.id - } - - fn get_id_for_reflect(&self) -> &u32 { - &self.id - } - - fn mut_id_for_reflect(&mut self) -> &mut u32 { - &mut self.id - } - - // uint32 threshold = 2; - - pub fn clear_threshold(&mut self) { - self.threshold = 0; - } - - // Param is passed by value, moved - pub fn set_threshold(&mut self, v: u32) { - self.threshold = v; - } - - pub fn get_threshold(&self) -> u32 { - self.threshold - } - - fn get_threshold_for_reflect(&self) -> &u32 { - &self.threshold - } - - fn mut_threshold_for_reflect(&mut self) -> &mut u32 { - &mut self.threshold - } - - // uint32 shares_count = 3; - - pub fn clear_shares_count(&mut self) { - self.shares_count = 0; - } - - // Param is passed by value, moved - pub fn set_shares_count(&mut self, v: u32) { - self.shares_count = v; - } - - pub fn get_shares_count(&self) -> u32 { - self.shares_count - } - - fn get_shares_count_for_reflect(&self) -> &u32 { - &self.shares_count - } - - fn mut_shares_count_for_reflect(&mut self) -> &mut u32 { - &mut self.shares_count - } - - // bytes data = 4; - - pub fn clear_data(&mut self) { - self.data.clear(); - } - - // Param is passed by value, moved - pub fn set_data(&mut self, v: ::std::vec::Vec) { - self.data = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_data(&mut self) -> &mut ::std::vec::Vec { - &mut self.data - } - - // Take field - pub fn take_data(&mut self) -> ::std::vec::Vec { - ::std::mem::replace(&mut self.data, ::std::vec::Vec::new()) - } - - pub fn get_data(&self) -> &[u8] { - &self.data - } - - fn get_data_for_reflect(&self) -> &::std::vec::Vec { - &self.data - } - - fn mut_data_for_reflect(&mut self) -> &mut ::std::vec::Vec { - &mut self.data - } - - // bytes hash = 5; - - pub fn clear_hash(&mut self) { - self.hash.clear(); - } - - // Param is passed by value, moved - pub fn set_hash(&mut self, v: ::std::vec::Vec) { - self.hash = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_hash(&mut self) -> &mut ::std::vec::Vec { - &mut self.hash - } - - // Take field - pub fn take_hash(&mut self) -> ::std::vec::Vec { - ::std::mem::replace(&mut self.hash, ::std::vec::Vec::new()) - } - - pub fn get_hash(&self) -> &[u8] { - &self.hash - } - - fn get_hash_for_reflect(&self) -> &::std::vec::Vec { - &self.hash - } - - fn mut_hash_for_reflect(&mut self) -> &mut ::std::vec::Vec { - &mut self.hash - } - - // .dss.MetaDataProto meta_data = 6; - - pub fn clear_meta_data(&mut self) { - self.meta_data.clear(); - } - - pub fn has_meta_data(&self) -> bool { - self.meta_data.is_some() - } - - // Param is passed by value, moved - pub fn set_meta_data(&mut self, v: super::metadata::MetaDataProto) { - self.meta_data = ::protobuf::SingularPtrField::some(v); - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_meta_data(&mut self) -> &mut super::metadata::MetaDataProto { - if self.meta_data.is_none() { - self.meta_data.set_default(); - } - self.meta_data.as_mut().unwrap() - } - - // Take field - pub fn take_meta_data(&mut self) -> super::metadata::MetaDataProto { - self.meta_data.take().unwrap_or_else(|| super::metadata::MetaDataProto::new()) - } - - pub fn get_meta_data(&self) -> &super::metadata::MetaDataProto { - self.meta_data.as_ref().unwrap_or_else(|| super::metadata::MetaDataProto::default_instance()) - } - - fn get_meta_data_for_reflect(&self) -> &::protobuf::SingularPtrField { - &self.meta_data - } - - fn mut_meta_data_for_reflect(&mut self) -> &mut ::protobuf::SingularPtrField { - &mut self.meta_data - } -} - -impl ::protobuf::Message for ShareProto { - fn is_initialized(&self) -> bool { - for v in &self.meta_data { - if !v.is_initialized() { - return false; - } - }; - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_uint32()?; - self.id = tmp; - }, - 2 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_uint32()?; - self.threshold = tmp; - }, - 3 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_uint32()?; - self.shares_count = tmp; - }, - 4 => { - ::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.data)?; - }, - 5 => { - ::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.hash)?; - }, - 6 => { - ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.meta_data)?; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if self.id != 0 { - my_size += ::protobuf::rt::value_size(1, self.id, ::protobuf::wire_format::WireTypeVarint); - } - if self.threshold != 0 { - my_size += ::protobuf::rt::value_size(2, self.threshold, ::protobuf::wire_format::WireTypeVarint); - } - if self.shares_count != 0 { - my_size += ::protobuf::rt::value_size(3, self.shares_count, ::protobuf::wire_format::WireTypeVarint); - } - if !self.data.is_empty() { - my_size += ::protobuf::rt::bytes_size(4, &self.data); - } - if !self.hash.is_empty() { - my_size += ::protobuf::rt::bytes_size(5, &self.hash); - } - if let Some(ref v) = self.meta_data.as_ref() { - let len = v.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream) -> ::protobuf::ProtobufResult<()> { - if self.id != 0 { - os.write_uint32(1, self.id)?; - } - if self.threshold != 0 { - os.write_uint32(2, self.threshold)?; - } - if self.shares_count != 0 { - os.write_uint32(3, self.shares_count)?; - } - if !self.data.is_empty() { - os.write_bytes(4, &self.data)?; - } - if !self.hash.is_empty() { - os.write_bytes(5, &self.hash)?; - } - if let Some(ref v) = self.meta_data.as_ref() { - os.write_tag(6, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &::std::any::Any { - self as &::std::any::Any - } - fn as_any_mut(&mut self) -> &mut ::std::any::Any { - self as &mut ::std::any::Any - } - fn into_any(self: Box) -> ::std::boxed::Box<::std::any::Any> { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - ::protobuf::MessageStatic::descriptor_static(None::) - } -} - -impl ::protobuf::MessageStatic for ShareProto { - fn new() -> ShareProto { - ShareProto::new() - } - - fn descriptor_static(_: ::std::option::Option) -> &'static ::protobuf::reflect::MessageDescriptor { - static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const ::protobuf::reflect::MessageDescriptor, - }; - unsafe { - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeUint32>( - "id", - ShareProto::get_id_for_reflect, - ShareProto::mut_id_for_reflect, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeUint32>( - "threshold", - ShareProto::get_threshold_for_reflect, - ShareProto::mut_threshold_for_reflect, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeUint32>( - "shares_count", - ShareProto::get_shares_count_for_reflect, - ShareProto::mut_shares_count_for_reflect, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>( - "data", - ShareProto::get_data_for_reflect, - ShareProto::mut_data_for_reflect, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>( - "hash", - ShareProto::get_hash_for_reflect, - ShareProto::mut_hash_for_reflect, - )); - fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "meta_data", - ShareProto::get_meta_data_for_reflect, - ShareProto::mut_meta_data_for_reflect, - )); - ::protobuf::reflect::MessageDescriptor::new::( - "ShareProto", - fields, - file_descriptor_proto() - ) - }) - } - } -} - -impl ::protobuf::Clear for ShareProto { - fn clear(&mut self) { - self.clear_id(); - self.clear_threshold(); - self.clear_shares_count(); - self.clear_data(); - self.clear_hash(); - self.clear_meta_data(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for ShareProto { - fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for ShareProto { - fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { - ::protobuf::reflect::ProtobufValueRef::Message(self) - } -} - -static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x0fdss/share.proto\x12\x03dss\x1a\x12dss/metadata.proto\"\xb6\x01\n\n\ - ShareProto\x12\x0e\n\x02id\x18\x01\x20\x01(\rR\x02id\x12\x1c\n\tthreshol\ - d\x18\x02\x20\x01(\rR\tthreshold\x12!\n\x0cshares_count\x18\x03\x20\x01(\ - \rR\x0bsharesCount\x12\x12\n\x04data\x18\x04\x20\x01(\x0cR\x04data\x12\ - \x12\n\x04hash\x18\x05\x20\x01(\x0cR\x04hash\x12/\n\tmeta_data\x18\x06\ - \x20\x01(\x0b2\x12.dss.MetaDataProtoR\x08metaDataJ\xe3\x03\n\x06\x12\x04\ - \0\0\r\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\x08\n\x01\x02\x12\x03\x02\ - \x08\x0b\n\t\n\x02\x03\0\x12\x03\x04\x07\x1b\n\n\n\x02\x04\0\x12\x04\x06\ - \0\r\x01\n\n\n\x03\x04\0\x01\x12\x03\x06\x08\x12\n\x0b\n\x04\x04\0\x02\0\ - \x12\x03\x07\x02\x10\n\r\n\x05\x04\0\x02\0\x04\x12\x04\x07\x02\x06\x14\n\ - \x0c\n\x05\x04\0\x02\0\x05\x12\x03\x07\x02\x08\n\x0c\n\x05\x04\0\x02\0\ - \x01\x12\x03\x07\t\x0b\n\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x07\x0e\x0f\n\ - \x0b\n\x04\x04\0\x02\x01\x12\x03\x08\x02\x17\n\r\n\x05\x04\0\x02\x01\x04\ - \x12\x04\x08\x02\x07\x10\n\x0c\n\x05\x04\0\x02\x01\x05\x12\x03\x08\x02\ - \x08\n\x0c\n\x05\x04\0\x02\x01\x01\x12\x03\x08\t\x12\n\x0c\n\x05\x04\0\ - \x02\x01\x03\x12\x03\x08\x15\x16\n\x0b\n\x04\x04\0\x02\x02\x12\x03\t\x02\ - \x1a\n\r\n\x05\x04\0\x02\x02\x04\x12\x04\t\x02\x08\x17\n\x0c\n\x05\x04\0\ - \x02\x02\x05\x12\x03\t\x02\x08\n\x0c\n\x05\x04\0\x02\x02\x01\x12\x03\t\t\ - \x15\n\x0c\n\x05\x04\0\x02\x02\x03\x12\x03\t\x18\x19\n\x0b\n\x04\x04\0\ - \x02\x03\x12\x03\n\x02\x11\n\r\n\x05\x04\0\x02\x03\x04\x12\x04\n\x02\t\ - \x1a\n\x0c\n\x05\x04\0\x02\x03\x05\x12\x03\n\x02\x07\n\x0c\n\x05\x04\0\ - \x02\x03\x01\x12\x03\n\x08\x0c\n\x0c\n\x05\x04\0\x02\x03\x03\x12\x03\n\ - \x0f\x10\n\x0b\n\x04\x04\0\x02\x04\x12\x03\x0b\x02\x11\n\r\n\x05\x04\0\ - \x02\x04\x04\x12\x04\x0b\x02\n\x11\n\x0c\n\x05\x04\0\x02\x04\x05\x12\x03\ - \x0b\x02\x07\n\x0c\n\x05\x04\0\x02\x04\x01\x12\x03\x0b\x08\x0c\n\x0c\n\ - \x05\x04\0\x02\x04\x03\x12\x03\x0b\x0f\x10\n\x0b\n\x04\x04\0\x02\x05\x12\ - \x03\x0c\x02\"\n\r\n\x05\x04\0\x02\x05\x04\x12\x04\x0c\x02\x0b\x11\n\x0c\ - \n\x05\x04\0\x02\x05\x06\x12\x03\x0c\x02\x13\n\x0c\n\x05\x04\0\x02\x05\ - \x01\x12\x03\x0c\x14\x1d\n\x0c\n\x05\x04\0\x02\x05\x03\x12\x03\x0c\x20!b\ - \x06proto3\ -"; - -static mut file_descriptor_proto_lazy: ::protobuf::lazy::Lazy<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const ::protobuf::descriptor::FileDescriptorProto, -}; - -fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto { - ::protobuf::parse_from_bytes(file_descriptor_proto_data).unwrap() -} - -pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto { - unsafe { - file_descriptor_proto_lazy.get(|| { - parse_descriptor_proto() - }) - } -} diff --git a/src/proto/mod.rs b/src/proto/mod.rs index f6dc96ab..0d1fb34c 100644 --- a/src/proto/mod.rs +++ b/src/proto/mod.rs @@ -3,10 +3,6 @@ #[allow(unused_qualifications, deprecated, missing_docs)] pub mod wrapped; -#[cfg(feature = "dss")] -#[allow(unused_qualifications, deprecated, missing_docs)] -pub mod dss; - #[allow(unused_qualifications, deprecated, missing_docs)] mod version; diff --git a/src/share/validation.rs b/src/share/validation.rs index 1b894cf7..f6c46861 100644 --- a/src/share/validation.rs +++ b/src/share/validation.rs @@ -9,7 +9,7 @@ use share::{IsShare, IsSignedShare}; /// TODO: Doc pub(crate) fn validate_signed_shares( - shares: &Vec, + shares: &[S], verify_signatures: bool, ) -> Result<(u8, usize)> { let result = validate_shares(shares)?; @@ -22,7 +22,7 @@ pub(crate) fn validate_signed_shares( } /// TODO: Doc -pub(crate) fn validate_shares(shares: &Vec) -> Result<(u8, usize)> { +pub(crate) fn validate_shares(shares: &[S]) -> Result<(u8, usize)> { if shares.is_empty() { bail!(ErrorKind::EmptyShares); } @@ -57,10 +57,7 @@ pub(crate) fn validate_shares(shares: &Vec) -> Result<(u8, usize) threshold = threshold_; } else if threshold_ != threshold { bail!(ErrorKind::InconsistentThresholds( - id, - threshold_, - ids, - threshold + id, threshold_, ids, threshold )) } diff --git a/src/sss/mod.rs b/src/sss/mod.rs index 1cb8f3ae..5d37adff 100644 --- a/src/sss/mod.rs +++ b/src/sss/mod.rs @@ -114,5 +114,5 @@ pub fn split_secret_rng( /// ``` pub fn recover_secret(shares: &[String], verify_signatures: bool) -> Result> { let shares = Share::parse_all(shares, verify_signatures)?; - SSS::recover_secret(shares, verify_signatures) + SSS::recover_secret(&shares, verify_signatures) } diff --git a/src/sss/scheme.rs b/src/sss/scheme.rs index 3cbc8e66..be487591 100644 --- a/src/sss/scheme.rs +++ b/src/sss/scheme.rs @@ -18,7 +18,7 @@ pub(crate) struct SSS; impl SSS { /// Performs threshold k-out-of-n Shamir's secret sharing. pub fn split_secret( - &self, + self, rng: &mut R, threshold: u8, shares_count: u8, @@ -97,7 +97,7 @@ impl SSS { /// Recovers the secret from a k-out-of-n Shamir's secret sharing. /// /// At least `k` distinct shares need to be provided to recover the share. - pub fn recover_secret(shares: Vec, verify_signatures: bool) -> Result> { + pub fn recover_secret(shares: &[Share], verify_signatures: bool) -> Result> { let (threshold, slen) = validate_signed_shares(&shares, verify_signatures)?; let mut col_in = Vec::with_capacity(threshold as usize); diff --git a/src/vol_hash.rs b/src/vol_hash.rs deleted file mode 100644 index 1db0310d..00000000 --- a/src/vol_hash.rs +++ /dev/null @@ -1,55 +0,0 @@ -use std; -use std::mem::transmute; - -use ring::digest::{Algorithm, Context}; - -#[allow(unsafe_code)] -fn u32_to_bytes(x: u32) -> [u8; 4] { - unsafe { transmute(x.to_be()) } -} - -pub struct VOLHash { - algorithm: &'static Algorithm, - bytes: Vec, -} - -impl VOLHash { - pub fn new(algorithm: &'static Algorithm) -> VOLHash { - Self { - algorithm, - bytes: Vec::new(), - } - } - - pub fn process(&mut self, bytes: &[u8]) { - self.bytes.extend_from_slice(bytes) - } - - pub fn finish(self, dest: &mut [u8]) { - let len = dest.len(); - assert!(len < std::u32::MAX as usize); - - let mut ctx = Context::new(self.algorithm); - ctx.update(&[0u8]); - ctx.update(&u32_to_bytes(len as u32)); - ctx.update(&self.bytes); - - let mut state = ctx.finish().as_ref().to_vec(); - - let iter_num = len / self.algorithm.output_len; - - for i in 0..iter_num { - let mut inner_ctx = Context::new(self.algorithm); - inner_ctx.update(&[255u8]); - inner_ctx.update(&u32_to_bytes(1 + i as u32)); - inner_ctx.update(&state); - - state.extend_from_slice(inner_ctx.finish().as_ref()) - } - - assert!(state.len() >= len); - - let src = state.drain(0..len).collect::>(); - dest.copy_from_slice(&src); - } -} diff --git a/src/wrapped_secrets/mod.rs b/src/wrapped_secrets/mod.rs index 5be7e082..9cf65b34 100644 --- a/src/wrapped_secrets/mod.rs +++ b/src/wrapped_secrets/mod.rs @@ -120,5 +120,5 @@ pub fn split_secret_rng( /// ``` pub fn recover_secret(shares: &[String], verify_signatures: bool) -> Result { let shares = Share::parse_all(shares, verify_signatures)?; - WrappedSecrets::recover_secret(shares, verify_signatures) + WrappedSecrets::recover_secret(&shares, verify_signatures) } diff --git a/src/wrapped_secrets/scheme.rs b/src/wrapped_secrets/scheme.rs index a704e396..00f89004 100644 --- a/src/wrapped_secrets/scheme.rs +++ b/src/wrapped_secrets/scheme.rs @@ -1,12 +1,12 @@ use errors::*; -use proto::VersionProto; use proto::wrapped::SecretProto; +use proto::VersionProto; use protobuf; use protobuf::Message; use rand::Rng; -use sss::SSS; pub(crate) use sss::Share; +use sss::SSS; #[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord)] pub(crate) struct WrappedSecrets; @@ -14,7 +14,7 @@ pub(crate) struct WrappedSecrets; impl WrappedSecrets { /// Performs threshold k-out-of-n Shamir's secret sharing. pub fn split_secret( - &self, + self, rng: &mut R, k: u8, n: u8, @@ -38,7 +38,7 @@ impl WrappedSecrets { /// Recovers the secret from a k-out-of-n Shamir's secret sharing. /// /// At least `k` distinct shares need to be provided to recover the share. - pub fn recover_secret(shares: Vec, verify_signatures: bool) -> Result { + pub fn recover_secret(shares: &[Share], verify_signatures: bool) -> Result { let secret = SSS::recover_secret(shares, verify_signatures)?; protobuf::parse_from_bytes::(secret.as_slice()) diff --git a/tests/recovery_errors.rs b/tests/recovery_errors.rs index 0e1e8f5b..041c9ed1 100644 --- a/tests/recovery_errors.rs +++ b/tests/recovery_errors.rs @@ -121,8 +121,8 @@ fn test_recover_too_few_shares_bug() { let mut share_1 = shares[0].clone().into_bytes(); let mut share_2 = shares[3].clone().into_bytes(); - share_1[0] = '2' as u8; - share_2[0] = '2' as u8; + share_1[0] = b'2'; + share_2[0] = b'2'; let sub_shares = vec![ String::from_utf8_lossy(&share_1).into_owned(),