mirror of
https://github.com/mii443/RustySecrets.git
synced 2025-08-22 16:25:32 +00:00
@ -9,3 +9,7 @@ rust:
|
|||||||
matrix:
|
matrix:
|
||||||
allow_failures:
|
allow_failures:
|
||||||
- rust: nightly
|
- rust: nightly
|
||||||
|
|
||||||
|
script:
|
||||||
|
- cargo build --verbose --all-features
|
||||||
|
- cargo test --verbose --all-features
|
||||||
|
359
Cargo.lock
generated
359
Cargo.lock
generated
@ -1,12 +1,18 @@
|
|||||||
[root]
|
[[package]]
|
||||||
name = "rusty_secrets"
|
name = "aho-corasick"
|
||||||
version = "0.0.3"
|
version = "0.5.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"merkle_sigs 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"protobuf 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
]
|
||||||
"rand 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"ring 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
[[package]]
|
||||||
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
name = "base64"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -14,189 +20,332 @@ name = "bitflags"
|
|||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "byteorder"
|
||||||
|
version = "1.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cc"
|
||||||
|
version = "1.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "coco"
|
name = "coco"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"either 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"scopeguard 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "conv"
|
|
||||||
version = "0.3.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"custom_derive 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "custom_derive"
|
|
||||||
version = "0.1.7"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "either"
|
name = "either"
|
||||||
version = "1.1.0"
|
version = "1.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures"
|
name = "env_logger"
|
||||||
version = "0.1.14"
|
version = "0.3.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "gcc"
|
|
||||||
version = "0.3.51"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "lamport_sigs"
|
|
||||||
version = "0.3.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rand 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ring 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lazy_static"
|
name = "error-chain"
|
||||||
version = "0.2.8"
|
version = "0.11.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "flate2"
|
||||||
version = "0.2.29"
|
version = "0.2.20"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "magenta"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"conv 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"magenta-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"miniz-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "magenta-sys"
|
name = "fuchsia-zircon"
|
||||||
version = "0.1.1"
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fuchsia-zircon-sys"
|
||||||
|
version = "0.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "merkle"
|
name = "gcc"
|
||||||
version = "1.3.0"
|
version = "0.3.54"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itertools"
|
||||||
|
version = "0.7.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"protobuf 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ring 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "kernel32-sys"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lamport_sigs"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazy_static"
|
||||||
|
version = "0.2.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.33"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "log"
|
||||||
|
version = "0.3.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memchr"
|
||||||
|
version = "0.1.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "merkle"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"protobuf 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "merkle_sigs"
|
name = "merkle_sigs"
|
||||||
version = "1.2.1"
|
version = "1.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lamport_sigs 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lamport_sigs 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"merkle 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"merkle 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ring 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "miniz-sys"
|
||||||
|
version = "0.1.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num_cpus"
|
name = "num_cpus"
|
||||||
version = "1.6.2"
|
version = "1.7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "protobuf"
|
name = "protobuf"
|
||||||
version = "1.4.1"
|
version = "1.4.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand"
|
name = "quickcheck"
|
||||||
version = "0.3.16"
|
version = "0.4.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
"env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"magenta 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand"
|
||||||
|
version = "0.3.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rayon"
|
name = "rayon"
|
||||||
version = "0.7.1"
|
version = "0.8.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rayon-core 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rayon-core 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rayon-core"
|
name = "rayon-core"
|
||||||
version = "1.2.1"
|
version = "1.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"coco 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"coco 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"futures 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"num_cpus 1.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex"
|
||||||
|
version = "0.1.80"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-syntax"
|
||||||
|
version = "0.3.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ring"
|
name = "ring"
|
||||||
version = "0.11.0"
|
version = "0.12.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"gcc 0.3.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rayon 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"untrusted 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc-serialize"
|
name = "rusty_secrets"
|
||||||
version = "0.3.24"
|
version = "0.0.3"
|
||||||
|
dependencies = [
|
||||||
|
"base64 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"flate2 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"itertools 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"merkle_sigs 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"protobuf 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"quickcheck 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "safemem"
|
||||||
|
version = "0.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scopeguard"
|
name = "scopeguard"
|
||||||
version = "0.3.2"
|
version = "0.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thread-id"
|
||||||
|
version = "2.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thread_local"
|
||||||
|
version = "0.2.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "untrusted"
|
name = "untrusted"
|
||||||
version = "0.5.0"
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "utf8-ranges"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi"
|
||||||
|
version = "0.2.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-build"
|
||||||
|
version = "0.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
"checksum aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ca972c2ea5f742bfce5687b9aef75506a764f61d37f8f649047846a9686ddb66"
|
||||||
|
"checksum base64 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "229d032f1a99302697f10b27167ae6d03d49d032e6a8e2550e8d3fc13356d2b4"
|
||||||
"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
|
"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
|
||||||
|
"checksum byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "652805b7e73fada9d85e9a6682a4abd490cb52d96aeecc12e33a0de34dfd0d23"
|
||||||
|
"checksum cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a9b13a57efd6b30ecd6598ebdb302cca617930b5470647570468a65d12ef9719"
|
||||||
"checksum coco 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c06169f5beb7e31c7c67ebf5540b8b472d23e3eade3b2ec7d1f5b504a85f91bd"
|
"checksum coco 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c06169f5beb7e31c7c67ebf5540b8b472d23e3eade3b2ec7d1f5b504a85f91bd"
|
||||||
"checksum conv 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "78ff10625fd0ac447827aa30ea8b861fead473bb60aeb73af6c1c58caf0d1299"
|
"checksum either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "740178ddf48b1a9e878e6d6509a1442a2d42fd2928aae8e7a6f8a36fb01981b3"
|
||||||
"checksum custom_derive 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "ef8ae57c4978a2acd8b869ce6b9ca1dfe817bff704c220209fdef2c0b75a01b9"
|
"checksum env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "15abd780e45b3ea4f76b4e9a26ff4843258dd8a3eed2775a0e7368c2e7936c2f"
|
||||||
"checksum either 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18785c1ba806c258137c937e44ada9ee7e69a37e3c72077542cd2f069d78562a"
|
"checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3"
|
||||||
"checksum futures 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "4b63a4792d4f8f686defe3b39b92127fea6344de5d38202b2ee5a11bbbf29d6a"
|
"checksum flate2 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)" = "e6234dd4468ae5d1e2dbb06fe2b058696fdc50a339c68a393aefbf00bc81e423"
|
||||||
"checksum gcc 0.3.51 (registry+https://github.com/rust-lang/crates.io-index)" = "120d07f202dcc3f72859422563522b66fe6463a4c513df062874daad05f85f0a"
|
"checksum fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f6c0581a4e363262e52b87f59ee2afe3415361c6ec35e665924eb08afe8ff159"
|
||||||
"checksum lamport_sigs 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2169eee511fb4b2af1d9581f74d9503b5a86e4dbfa52ca1f5ee0d1193bf1d913"
|
"checksum fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "43f3795b4bae048dc6123a6b972cadde2e676f9ded08aef6bb77f5f157684a82"
|
||||||
"checksum lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3b37545ab726dd833ec6420aaba8231c5b320814b9029ad585555d2a03e94fbf"
|
"checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb"
|
||||||
"checksum libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)" = "8a014d9226c2cc402676fbe9ea2e15dd5222cd1dd57f576b5b283178c944a264"
|
"checksum itertools 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "99f3f75d7cf195a7eedb0611efe8684b55c6c7264afe3d8bc00b704f061c0fdf"
|
||||||
"checksum magenta 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4bf0336886480e671965f794bc9b6fce88503563013d1bfb7a502c81fe3ac527"
|
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
||||||
"checksum magenta-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "40d014c7011ac470ae28e2f76a02bfea4a8480f73e701353b49ad7a8d75f4699"
|
"checksum lamport_sigs 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5dff26ae558be16afda65815c847447c81eede19c639982e49e33bd15973d857"
|
||||||
"checksum merkle 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "204bbb6953e7cc6c2cec3f63e108f0d61311a3dab33d33582b1f6f4d4ae6f992"
|
"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73"
|
||||||
"checksum merkle_sigs 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b446a57d9a060a9db764b6c6bd44bf79e46c512733ed9b6c23206e74394d3255"
|
"checksum libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "5ba3df4dcb460b9dfbd070d41c94c19209620c191b0340b929ce748a2bcd42d2"
|
||||||
"checksum num_cpus 1.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "aec53c34f2d0247c5ca5d32cca1478762f301740468ee9ee6dcb7a0dd7a0c584"
|
"checksum log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "880f77541efa6e5cc74e76910c9884d9859683118839d6a1dc3b11e63512565b"
|
||||||
"checksum protobuf 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "568a15e4d572d9a5e63ae3a55f84328c984842887db179b40b4cc6a608bac6a4"
|
"checksum memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d8b629fb514376c675b98c1421e80b151d3817ac42d7c667717d282761418d20"
|
||||||
"checksum rand 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)" = "eb250fd207a4729c976794d03db689c9be1d634ab5a1c9da9492a13d8fecbcdf"
|
"checksum merkle 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a6311caa1c5c71548021dfc5f6113fca485d453185fdc44da92bafe266f6a5fe"
|
||||||
"checksum rayon 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a77c51c07654ddd93f6cb543c7a849863b03abc7e82591afda6dc8ad4ac3ac4a"
|
"checksum merkle_sigs 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94367864019d3b781c28c67d0a7057da0df498525982869c47ecfd73ece29f26"
|
||||||
"checksum rayon-core 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7febc28567082c345f10cddc3612c6ea020fc3297a1977d472cf9fdb73e6e493"
|
"checksum miniz-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "609ce024854aeb19a0ef7567d348aaa5a746b32fb72e336df7fcc16869d7e2b4"
|
||||||
"checksum ring 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1f2a6dc7fc06a05e6de183c5b97058582e9da2de0c136eafe49609769c507724"
|
"checksum num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "514f0d73e64be53ff320680ca671b64fe3fb91da01e1ae2ddc99eb51d453b20d"
|
||||||
"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
|
"checksum protobuf 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "99c7a6694a7896f7c039bc20a6947b83781b019d7d40df77ae069cd2a432e4a7"
|
||||||
"checksum scopeguard 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c79eb2c3ac4bc2507cda80e7f3ac5b88bd8eae4c0914d5663e6a8933994be918"
|
"checksum quickcheck 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "02c2411d418cea2364325b18a205664f9ef8252e06b2e911db97c0b0d98b1406"
|
||||||
"checksum untrusted 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6b65243989ef6aacd9c0d6bd2b822765c3361d8ed352185a6f3a41f3a718c673"
|
"checksum rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)" = "6475140dfd8655aeb72e1fd4b7a1cc1c202be65d71669476e392fe62532b9edd"
|
||||||
|
"checksum rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b614fe08b6665cb9a231d07ac1364b0ef3cb3698f1239ee0c4c3a88a524f54c8"
|
||||||
|
"checksum rayon-core 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e64b609139d83da75902f88fd6c01820046840a18471e4dfcd5ac7c0f46bea53"
|
||||||
|
"checksum regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)" = "4fd4ace6a8cf7860714a2c2280d6c1f7e6a413486c13298bbc86fd3da019402f"
|
||||||
|
"checksum regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f9ec002c35e86791825ed294b50008eea9ddfc8def4420124fbc6b08db834957"
|
||||||
|
"checksum ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6f7d28b30a72c01b458428e0ae988d4149c20d902346902be881e3edc4bb325c"
|
||||||
|
"checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f"
|
||||||
|
"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
|
||||||
|
"checksum thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9539db560102d1cef46b8b78ce737ff0bb64e7e18d35b2a5688f7d097d0ff03"
|
||||||
|
"checksum thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8576dbbfcaef9641452d5cf0df9b0e7eeab7694956dd33bb61515fb8f18cfdd5"
|
||||||
|
"checksum untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f392d7819dbe58833e26872f5f6f0d68b7bbbe90fc3667e98731c4a15ad9a7ae"
|
||||||
|
"checksum utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1ca13c08c41c9c3e04224ed9ff80461d97e121589ff27c753a16cb10830ae0f"
|
||||||
|
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
|
||||||
|
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
|
||||||
|
40
Cargo.toml
40
Cargo.toml
@ -8,10 +8,38 @@ license = "BSD-3-Clause"
|
|||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
|
|
||||||
[dependencies]
|
[features]
|
||||||
rustc-serialize = "^0.3.18"
|
default = []
|
||||||
rand = "^0.3.14"
|
dss = []
|
||||||
ring = "^0.11.0"
|
|
||||||
merkle_sigs = "^1.2.1"
|
|
||||||
protobuf = "^1.2.0"
|
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
base64 = "0.9.0"
|
||||||
|
rand = "^0.3"
|
||||||
|
ring = "^0.12"
|
||||||
|
merkle_sigs = "^1.4"
|
||||||
|
protobuf = "^1.4"
|
||||||
|
|
||||||
|
[dependencies.error-chain]
|
||||||
|
version = "0.11.0"
|
||||||
|
default-features = false
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
itertools = "^0.7"
|
||||||
|
quickcheck = "^0.4"
|
||||||
|
flate2 = "^0.2"
|
||||||
|
|
||||||
|
[profile.bench]
|
||||||
|
opt-level = 3
|
||||||
|
debug = false
|
||||||
|
rpath = false
|
||||||
|
lto = true
|
||||||
|
debug-assertions = false
|
||||||
|
codegen-units = 1
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
opt-level = 3
|
||||||
|
debug = false
|
||||||
|
rpath = false
|
||||||
|
lto = true
|
||||||
|
debug-assertions = false
|
||||||
|
codegen-units = 1
|
||||||
|
1
benches/resources/1KB.txt
Normal file
1
benches/resources/1KB.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
Privacy isn't about something to hide. Privacy is about something to protect. That's who you are. That's what you believe in, that's who you want to become. Privacy is the right to the self. Privacy is what gives you the ability to share with the world who you are, on your own terms, for them to understand what you're trying to be. And to protect for yourself the parts of you that you're not sure about, that you're still experimenting with. If we don't have privacy, what we're losing is the ability to make mistakes. We're losing the ability to be ourselves. Privacy is the fountainhead of all other rights. Freedom of speech doesn't have a lot of meaning if you can't have a quiet space. . . . to decide what it is that you actually wanna say. Freedom of religion doesn't mean that if you can't figure out what you actually believe without being influenced by the criticisms and sort of outside direction and peer pressure of others. And it goes on and on and on. But privacy is baked into our language, our core concepts of government and self in every way . . . without privacy, you won't have anything for yourself. So when people say that to me, I say back arguing that you don't have privacy because you have nothing to hide is like arguing that you don't care about free speech because you have nothing to say.
|
5
benches/shared.rs
Normal file
5
benches/shared.rs
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#![cfg(test)]
|
||||||
|
|
||||||
|
pub fn secret_1kb() -> &'static [u8] {
|
||||||
|
include_bytes!("resources/1KB.txt")
|
||||||
|
}
|
51
benches/ss1.rs
Normal file
51
benches/ss1.rs
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#![cfg(test)]
|
||||||
|
#![feature(test)]
|
||||||
|
|
||||||
|
extern crate rusty_secrets;
|
||||||
|
extern crate test;
|
||||||
|
|
||||||
|
mod shared;
|
||||||
|
|
||||||
|
mod ss1 {
|
||||||
|
|
||||||
|
use rusty_secrets::dss::ss1;
|
||||||
|
use test::{black_box, Bencher};
|
||||||
|
use shared;
|
||||||
|
|
||||||
|
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::<Vec<_>>().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);
|
||||||
|
|
||||||
|
}
|
57
benches/sss.rs
Normal file
57
benches/sss.rs
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
#![cfg(test)]
|
||||||
|
#![feature(test)]
|
||||||
|
|
||||||
|
extern crate rusty_secrets;
|
||||||
|
extern crate test;
|
||||||
|
|
||||||
|
mod shared;
|
||||||
|
|
||||||
|
mod sss {
|
||||||
|
|
||||||
|
use test::{black_box, Bencher};
|
||||||
|
use rusty_secrets::sss;
|
||||||
|
use shared;
|
||||||
|
|
||||||
|
macro_rules! bench_generate {
|
||||||
|
($name:ident, $k:expr, $n:expr, $secret:ident, $signed:expr) => (
|
||||||
|
#[bench]
|
||||||
|
fn $name(b: &mut Bencher) {
|
||||||
|
let secret = shared::$secret();
|
||||||
|
|
||||||
|
b.iter(move || {
|
||||||
|
let shares = sss::split_secret($k, $n, secret, $signed).unwrap();
|
||||||
|
black_box(shares);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! bench_recover {
|
||||||
|
($name:ident, $k:expr, $n:expr, $secret:ident, $signed:expr) => (
|
||||||
|
#[bench]
|
||||||
|
fn $name(b: &mut Bencher) {
|
||||||
|
let secret = shared::$secret();
|
||||||
|
let all_shares = sss::split_secret($k, $n, &secret, $signed).unwrap();
|
||||||
|
let shares = all_shares.into_iter().take($k).collect::<Vec<_>>();
|
||||||
|
|
||||||
|
b.iter(|| {
|
||||||
|
let result = sss::recover_secret(&shares, $signed).unwrap();
|
||||||
|
black_box(result);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
bench_generate!(generate_1kb_3_5, 3, 5, secret_1kb, false);
|
||||||
|
bench_recover!(recover_1kb_3_5, 3, 5, secret_1kb, false);
|
||||||
|
|
||||||
|
bench_generate!(generate_1kb_3_5_signed, 3, 5, secret_1kb, true);
|
||||||
|
bench_recover!(recover_1kb_3_5_signed, 3, 5, secret_1kb, true);
|
||||||
|
|
||||||
|
bench_generate!(generate_1kb_10_25, 10, 25, secret_1kb, false);
|
||||||
|
bench_recover!(recover_1kb_10_25, 10, 25, secret_1kb, false);
|
||||||
|
|
||||||
|
bench_generate!(generate_1kb_10_25_signed, 10, 25, secret_1kb, true);
|
||||||
|
bench_recover!(recover_1kb_10_25_signed, 10, 25, secret_1kb, true);
|
||||||
|
|
||||||
|
}
|
51
benches/thss.rs
Normal file
51
benches/thss.rs
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#![cfg(test)]
|
||||||
|
#![feature(test)]
|
||||||
|
|
||||||
|
extern crate rusty_secrets;
|
||||||
|
extern crate test;
|
||||||
|
|
||||||
|
mod shared;
|
||||||
|
|
||||||
|
mod thss {
|
||||||
|
|
||||||
|
use rusty_secrets::dss::thss;
|
||||||
|
use test::{black_box, Bencher};
|
||||||
|
use shared;
|
||||||
|
|
||||||
|
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::<Vec<_>>().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);
|
||||||
|
|
||||||
|
}
|
57
benches/wrapped_secrets.rs
Normal file
57
benches/wrapped_secrets.rs
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
#![cfg(test)]
|
||||||
|
#![feature(test)]
|
||||||
|
|
||||||
|
extern crate rusty_secrets;
|
||||||
|
extern crate test;
|
||||||
|
|
||||||
|
mod shared;
|
||||||
|
|
||||||
|
mod wrapped_secrets {
|
||||||
|
|
||||||
|
use test::{black_box, Bencher};
|
||||||
|
use rusty_secrets::wrapped_secrets;
|
||||||
|
use shared;
|
||||||
|
|
||||||
|
macro_rules! bench_generate {
|
||||||
|
($name:ident, $k:expr, $n:expr, $secret:ident, $signed:expr) => (
|
||||||
|
#[bench]
|
||||||
|
fn $name(b: &mut Bencher) {
|
||||||
|
let secret = shared::$secret();
|
||||||
|
|
||||||
|
b.iter(move || {
|
||||||
|
let shares = wrapped_secrets::split_secret($k, $n, secret, None, $signed).unwrap();
|
||||||
|
black_box(shares);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! bench_recover {
|
||||||
|
($name:ident, $k:expr, $n:expr, $secret:ident, $signed:expr) => (
|
||||||
|
#[bench]
|
||||||
|
fn $name(b: &mut Bencher) {
|
||||||
|
let secret = shared::$secret();
|
||||||
|
let all_shares = wrapped_secrets::split_secret($k, $n, &secret, None, $signed).unwrap();
|
||||||
|
let shares = all_shares.into_iter().take($k).collect::<Vec<_>>();
|
||||||
|
|
||||||
|
b.iter(|| {
|
||||||
|
let result = wrapped_secrets::recover_secret(&shares, $signed).unwrap();
|
||||||
|
black_box(result);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
bench_generate!(generate_1kb_3_5, 3, 5, secret_1kb, false);
|
||||||
|
bench_recover!(recover_1kb_3_5, 3, 5, secret_1kb, false);
|
||||||
|
|
||||||
|
bench_generate!(generate_1kb_3_5_signed, 3, 5, secret_1kb, true);
|
||||||
|
bench_recover!(recover_1kb_3_5_signed, 3, 5, secret_1kb, true);
|
||||||
|
|
||||||
|
bench_generate!(generate_1kb_10_25, 10, 25, secret_1kb, false);
|
||||||
|
bench_recover!(recover_1kb_10_25, 10, 25, secret_1kb, false);
|
||||||
|
|
||||||
|
bench_generate!(generate_1kb_10_25_signed, 10, 25, secret_1kb, true);
|
||||||
|
bench_recover!(recover_1kb_10_25_signed, 10, 25, secret_1kb, true);
|
||||||
|
|
||||||
|
}
|
35
build.rs
35
build.rs
@ -17,38 +17,38 @@ fn mask(bit: u8) -> u8 {
|
|||||||
/// of the polynomial division with POLY as divisor
|
/// of the polynomial division with POLY as divisor
|
||||||
#[inline]
|
#[inline]
|
||||||
fn xtimes(poly: u8) -> u8 {
|
fn xtimes(poly: u8) -> u8 {
|
||||||
(poly << 1) ^ (mask(poly >> 7) & POLY)
|
(poly << 1) ^ (mask(poly >> 7) & POLY)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Tables {
|
struct Tables {
|
||||||
exp: [u8; 256],
|
exp: [u8; 256],
|
||||||
log: [u8; 256],
|
log: [u8; 256],
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_tables(mut file: &File) {
|
fn generate_tables(mut file: &File) {
|
||||||
let mut tabs = Tables {
|
let mut tabs = Tables {
|
||||||
exp: [0; 256],
|
exp: [0; 256],
|
||||||
log: [0; 256],
|
log: [0; 256],
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut tmp = 1;
|
let mut tmp = 1;
|
||||||
for power in 0..255usize {
|
for power in 0..255usize {
|
||||||
tabs.exp[power] = tmp;
|
tabs.exp[power] = tmp;
|
||||||
tabs.log[tmp as usize] = power as u8;
|
tabs.log[tmp as usize] = power as u8;
|
||||||
tmp = xtimes(tmp);
|
tmp = xtimes(tmp);
|
||||||
}
|
}
|
||||||
tabs.exp[255] = 1;
|
tabs.exp[255] = 1;
|
||||||
|
|
||||||
match write!(file, "{}", tabs) {
|
match write!(file, "{}", tabs) {
|
||||||
Ok(()) => {}
|
Ok(()) => {}
|
||||||
Err(_) => panic!("Could not format the table. Aborting build.")
|
Err(_) => panic!("Could not format the table. Aborting build."),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn farray(array: [u8; 256], f: &mut fmt::Formatter) -> fmt::Result {
|
fn farray(array: [u8; 256], f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
for (index, value) in array.into_iter().enumerate() {
|
for (index, value) in array.into_iter().enumerate() {
|
||||||
try!(write!(f, "{}", value));
|
try!(write!(f, "{}", value));
|
||||||
if index != array.len()-1 {
|
if index != array.len() - 1 {
|
||||||
try!(write!(f, ","));
|
try!(write!(f, ","));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -75,12 +75,15 @@ fn main() {
|
|||||||
|
|
||||||
let mut f = File::create(&dest).unwrap();
|
let mut f = File::create(&dest).unwrap();
|
||||||
|
|
||||||
write!(f, "pub struct Tables {{
|
write!(
|
||||||
pub exp: [u8; 256],
|
f,
|
||||||
pub log: [u8; 256]
|
"pub struct Tables {{ \
|
||||||
}}
|
pub exp: [u8; 256], \
|
||||||
|
pub log: [u8; 256] \
|
||||||
pub static TABLES: Tables = ");
|
}} \
|
||||||
|
\
|
||||||
|
pub static TABLES: Tables = "
|
||||||
|
);
|
||||||
|
|
||||||
generate_tables(&f);
|
generate_tables(&f);
|
||||||
}
|
}
|
||||||
|
4
fuzz/.gitignore
vendored
Normal file
4
fuzz/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
|
||||||
|
target
|
||||||
|
corpus
|
||||||
|
artifacts
|
304
fuzz/Cargo.lock
generated
Normal file
304
fuzz/Cargo.lock
generated
Normal file
@ -0,0 +1,304 @@
|
|||||||
|
[root]
|
||||||
|
name = "rusty_secrets-fuzz"
|
||||||
|
version = "0.0.1"
|
||||||
|
dependencies = [
|
||||||
|
"arbitrary 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libfuzzer-sys 0.1.0 (git+https://github.com/rust-fuzz/libfuzzer-sys.git)",
|
||||||
|
"rusty_secrets 0.0.3",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "arbitrary"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "block-buffer"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"generic-array 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "byte-tools"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "coco"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"either 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"scopeguard 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "conv"
|
||||||
|
version = "0.3.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"custom_derive 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "custom_derive"
|
||||||
|
version = "0.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "digest"
|
||||||
|
version = "0.6.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"generic-array 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "either"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "error-chain"
|
||||||
|
version = "0.11.0-rc.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures"
|
||||||
|
version = "0.1.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gcc"
|
||||||
|
version = "0.3.53"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "generic-array"
|
||||||
|
version = "0.8.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"nodrop 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"typenum 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lamport_sigs"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"rand 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"ring 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazy_static"
|
||||||
|
version = "0.2.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.29"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libfuzzer-sys"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "git+https://github.com/rust-fuzz/libfuzzer-sys.git#67f73995f183099b2c8a736bc95b07d8b5903afe"
|
||||||
|
dependencies = [
|
||||||
|
"arbitrary 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"gcc 0.3.53 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "magenta"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"conv 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"magenta-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "magenta-sys"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "merkle"
|
||||||
|
version = "1.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"protobuf 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"ring 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "merkle_sigs"
|
||||||
|
version = "1.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"lamport_sigs 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"merkle 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"ring 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nodrop"
|
||||||
|
version = "0.1.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"odds 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num_cpus"
|
||||||
|
version = "1.6.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "odds"
|
||||||
|
version = "0.2.25"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "protobuf"
|
||||||
|
version = "1.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand"
|
||||||
|
version = "0.3.16"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"magenta 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rayon"
|
||||||
|
version = "0.7.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"rayon-core 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rayon-core"
|
||||||
|
version = "1.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"coco 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"futures 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num_cpus 1.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rand 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ring"
|
||||||
|
version = "0.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"gcc 0.3.53 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rayon 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"untrusted 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc-serialize"
|
||||||
|
version = "0.3.24"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rusty_secrets"
|
||||||
|
version = "0.0.3"
|
||||||
|
dependencies = [
|
||||||
|
"digest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"error-chain 0.11.0-rc.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"merkle_sigs 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"protobuf 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rand 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"ring 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"sha3 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "scopeguard"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sha3"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"block-buffer 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"digest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"generic-array 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "typenum"
|
||||||
|
version = "1.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "untrusted"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
"checksum arbitrary 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "baa5f4eaa3a3603a0d83861560ab55dfa6c8dd094b05604e5d006b41ffaeb1d3"
|
||||||
|
"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
|
||||||
|
"checksum block-buffer 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1339a1042f5d9f295737ad4d9a6ab6bf81c84a933dba110b9200cd6d1448b814"
|
||||||
|
"checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40"
|
||||||
|
"checksum coco 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c06169f5beb7e31c7c67ebf5540b8b472d23e3eade3b2ec7d1f5b504a85f91bd"
|
||||||
|
"checksum conv 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "78ff10625fd0ac447827aa30ea8b861fead473bb60aeb73af6c1c58caf0d1299"
|
||||||
|
"checksum custom_derive 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "ef8ae57c4978a2acd8b869ce6b9ca1dfe817bff704c220209fdef2c0b75a01b9"
|
||||||
|
"checksum digest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e5b29bf156f3f4b3c4f610a25ff69370616ae6e0657d416de22645483e72af0a"
|
||||||
|
"checksum either 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18785c1ba806c258137c937e44ada9ee7e69a37e3c72077542cd2f069d78562a"
|
||||||
|
"checksum error-chain 0.11.0-rc.2 (registry+https://github.com/rust-lang/crates.io-index)" = "38d3a55d9a7a456748f2a3912c0941a5d9a68006eb15b3c3c9836b8420dc102d"
|
||||||
|
"checksum futures 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "4b63a4792d4f8f686defe3b39b92127fea6344de5d38202b2ee5a11bbbf29d6a"
|
||||||
|
"checksum gcc 0.3.53 (registry+https://github.com/rust-lang/crates.io-index)" = "e8310f7e9c890398b0e80e301c4f474e9918d2b27fca8f48486ca775fa9ffc5a"
|
||||||
|
"checksum generic-array 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6181b378c58e5aacf4d3e17836737465cb2857750b53f6b46672a3509f2a8d9d"
|
||||||
|
"checksum lamport_sigs 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2169eee511fb4b2af1d9581f74d9503b5a86e4dbfa52ca1f5ee0d1193bf1d913"
|
||||||
|
"checksum lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3b37545ab726dd833ec6420aaba8231c5b320814b9029ad585555d2a03e94fbf"
|
||||||
|
"checksum libc 0.2.29 (registry+https://github.com/rust-lang/crates.io-index)" = "8a014d9226c2cc402676fbe9ea2e15dd5222cd1dd57f576b5b283178c944a264"
|
||||||
|
"checksum libfuzzer-sys 0.1.0 (git+https://github.com/rust-fuzz/libfuzzer-sys.git)" = "<none>"
|
||||||
|
"checksum magenta 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4bf0336886480e671965f794bc9b6fce88503563013d1bfb7a502c81fe3ac527"
|
||||||
|
"checksum magenta-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "40d014c7011ac470ae28e2f76a02bfea4a8480f73e701353b49ad7a8d75f4699"
|
||||||
|
"checksum merkle 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "204bbb6953e7cc6c2cec3f63e108f0d61311a3dab33d33582b1f6f4d4ae6f992"
|
||||||
|
"checksum merkle_sigs 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b446a57d9a060a9db764b6c6bd44bf79e46c512733ed9b6c23206e74394d3255"
|
||||||
|
"checksum nodrop 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "52cd74cd09beba596430cc6e3091b74007169a56246e1262f0ba451ea95117b2"
|
||||||
|
"checksum num_cpus 1.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "aec53c34f2d0247c5ca5d32cca1478762f301740468ee9ee6dcb7a0dd7a0c584"
|
||||||
|
"checksum odds 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)" = "c3df9b730298cea3a1c3faa90b7e2f9df3a9c400d0936d6015e6165734eefcba"
|
||||||
|
"checksum protobuf 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "568a15e4d572d9a5e63ae3a55f84328c984842887db179b40b4cc6a608bac6a4"
|
||||||
|
"checksum rand 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)" = "eb250fd207a4729c976794d03db689c9be1d634ab5a1c9da9492a13d8fecbcdf"
|
||||||
|
"checksum rayon 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a77c51c07654ddd93f6cb543c7a849863b03abc7e82591afda6dc8ad4ac3ac4a"
|
||||||
|
"checksum rayon-core 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7febc28567082c345f10cddc3612c6ea020fc3297a1977d472cf9fdb73e6e493"
|
||||||
|
"checksum ring 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1f2a6dc7fc06a05e6de183c5b97058582e9da2de0c136eafe49609769c507724"
|
||||||
|
"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
|
||||||
|
"checksum scopeguard 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c79eb2c3ac4bc2507cda80e7f3ac5b88bd8eae4c0914d5663e6a8933994be918"
|
||||||
|
"checksum sha3 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "26405905b6a56a94c60109cfda62610507ac14a65be531f5767dec5c5a8dd6a0"
|
||||||
|
"checksum typenum 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "13a99dc6780ef33c78780b826cf9d2a78840b72cae9474de4bcaf9051e60ebbd"
|
||||||
|
"checksum untrusted 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6b65243989ef6aacd9c0d6bd2b822765c3361d8ed352185a6f3a41f3a718c673"
|
37
fuzz/Cargo.toml
Normal file
37
fuzz/Cargo.toml
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
|
||||||
|
[package]
|
||||||
|
name = "rusty_secrets-fuzz"
|
||||||
|
version = "0.0.1"
|
||||||
|
authors = ["Automatically generated"]
|
||||||
|
publish = false
|
||||||
|
|
||||||
|
[package.metadata]
|
||||||
|
cargo-fuzz = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
arbitrary = "0.1.0"
|
||||||
|
|
||||||
|
[dependencies.rusty_secrets]
|
||||||
|
path = ".."
|
||||||
|
[dependencies.libfuzzer-sys]
|
||||||
|
git = "https://github.com/rust-fuzz/libfuzzer-sys.git"
|
||||||
|
|
||||||
|
# Prevent this from interfering with workspaces
|
||||||
|
[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"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "wrapped_secrets_1"
|
||||||
|
path = "fuzz_targets/wrapped_secrets_1.rs"
|
24
fuzz/fuzz_targets/ss1_1.rs
Normal file
24
fuzz/fuzz_targets/ss1_1.rs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#![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(())
|
||||||
|
}
|
||||||
|
});
|
25
fuzz/fuzz_targets/sss_1.rs
Normal file
25
fuzz/fuzz_targets/sss_1.rs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#![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(())
|
||||||
|
}
|
||||||
|
});
|
24
fuzz/fuzz_targets/thss_1.rs
Normal file
24
fuzz/fuzz_targets/thss_1.rs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#![no_main]
|
||||||
|
#[macro_use]
|
||||||
|
extern crate libfuzzer_sys;
|
||||||
|
extern crate rusty_secrets;
|
||||||
|
extern crate arbitrary;
|
||||||
|
|
||||||
|
use rusty_secrets::dss::thss::*;
|
||||||
|
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, &None)
|
||||||
|
.and_then(|ss| recover_secret(&ss))
|
||||||
|
.map(|_| ())
|
||||||
|
.unwrap_or(())
|
||||||
|
}
|
||||||
|
});
|
25
fuzz/fuzz_targets/wrapped_secrets_1.rs
Normal file
25
fuzz/fuzz_targets/wrapped_secrets_1.rs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#![no_main]
|
||||||
|
extern crate arbitrary;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate libfuzzer_sys;
|
||||||
|
extern crate rusty_secrets;
|
||||||
|
|
||||||
|
use rusty_secrets::wrapped_secrets;
|
||||||
|
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];
|
||||||
|
|
||||||
|
wrapped_secrets::split_secret(k, n, &data, false)
|
||||||
|
.map_err(|err| err.into())
|
||||||
|
.and_then(|ss| wrapped_secrets::recover_secret(&ss, false))
|
||||||
|
.map(|_| ())
|
||||||
|
.unwrap_or(())
|
||||||
|
}
|
||||||
|
});
|
1
protobuf/.gitignore
vendored
Normal file
1
protobuf/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
_out/
|
42
protobuf/Makefile
Normal file
42
protobuf/Makefile
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
SHELL = bash
|
||||||
|
|
||||||
|
PROTOC := protoc
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
all: base wrapped dss
|
||||||
|
|
||||||
|
base: $(BASE_RUSTS)
|
||||||
|
|
||||||
|
wrapped: $(WRAPPED_RUSTS)
|
||||||
|
|
||||||
|
dss: $(DSS_RUSTS)
|
||||||
|
|
||||||
|
$(DEST_DIR)/%.rs: %.proto
|
||||||
|
@echo -n "Processing '$<'..."
|
||||||
|
@$(RM) -r $(OUT_DIR)
|
||||||
|
@mkdir -p $(OUT_DIR)
|
||||||
|
@$(PROTOC) --rust_out $(OUT_DIR) $<
|
||||||
|
@echo " Done."
|
||||||
|
@echo -n "Moving generated file to '$(dir $@)'..."
|
||||||
|
@mkdir -p $(dir $@)
|
||||||
|
@mv $(OUT_DIR)/*.rs $(dir $@)
|
||||||
|
@echo " Done."
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(RM) $(BASE_RUSTS)
|
||||||
|
$(RM) $(WRAPPED_RUSTS)
|
||||||
|
$(RM) $(DSS_RUSTS)
|
@ -1,11 +0,0 @@
|
|||||||
syntax = "proto3";
|
|
||||||
|
|
||||||
enum RustySecretsVersions {
|
|
||||||
INITIAL_RELEASE = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
message RustySecret {
|
|
||||||
RustySecretsVersions version = 1;
|
|
||||||
bytes secret = 2;
|
|
||||||
string mime_type = 3;
|
|
||||||
}
|
|
7
protobuf/dss/metadata.proto
Normal file
7
protobuf/dss/metadata.proto
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package dss;
|
||||||
|
|
||||||
|
message MetaDataProto {
|
||||||
|
map<string, string> tags = 1;
|
||||||
|
}
|
10
protobuf/dss/secret.proto
Normal file
10
protobuf/dss/secret.proto
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
import "version.proto";
|
||||||
|
import "dss/metadata.proto";
|
||||||
|
|
||||||
|
message SecretProto {
|
||||||
|
VersionProto version = 1;
|
||||||
|
bytes secret = 2;
|
||||||
|
dss.MetaDataProto meta_data = 3;
|
||||||
|
}
|
14
protobuf/dss/share.proto
Normal file
14
protobuf/dss/share.proto
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
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;
|
||||||
|
}
|
6
protobuf/version.proto
Normal file
6
protobuf/version.proto
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
enum VersionProto {
|
||||||
|
INITIAL_RELEASE = 0;
|
||||||
|
}
|
11
protobuf/wrapped/secret.proto
Normal file
11
protobuf/wrapped/secret.proto
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package wrapped;
|
||||||
|
|
||||||
|
import "version.proto";
|
||||||
|
|
||||||
|
message SecretProto {
|
||||||
|
VersionProto version = 1;
|
||||||
|
bytes secret = 2;
|
||||||
|
string mime_type = 3;
|
||||||
|
}
|
@ -1,6 +1,8 @@
|
|||||||
syntax = "proto3";
|
syntax = "proto3";
|
||||||
|
|
||||||
message ShareData {
|
package wrapped;
|
||||||
|
|
||||||
|
message ShareProto {
|
||||||
bytes shamir_data = 1;
|
bytes shamir_data = 1;
|
||||||
repeated bytes signature = 2;
|
repeated bytes signature = 2;
|
||||||
bytes proof = 3;
|
bytes proof = 3;
|
@ -1,183 +0,0 @@
|
|||||||
use std::convert;
|
|
||||||
use std::error::Error;
|
|
||||||
use std::fmt;
|
|
||||||
use std::io;
|
|
||||||
use std::num;
|
|
||||||
|
|
||||||
/// Error struct used for generating an `io::Error` from a generic description.
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct RustyError {
|
|
||||||
descr: &'static str,
|
|
||||||
detail: Option<String>,
|
|
||||||
share_index: Option<u8>,
|
|
||||||
share_groups: Option<Vec<Vec<u8>>>
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum RustyErrorTypes {
|
|
||||||
DuplicateShareNum(u8),
|
|
||||||
DuplicateShareData(u8),
|
|
||||||
EmptyShares,
|
|
||||||
IncompatibleSets(Vec<Vec<u8>>),
|
|
||||||
InvalidSignature(u8, String),
|
|
||||||
MissingShares(u8, usize),
|
|
||||||
MissingSignature(u8),
|
|
||||||
SecretDeserializationIssue,
|
|
||||||
ShareParsingError(u8, String)
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RustyError {
|
|
||||||
/// Initializes a new error with a description and optional detail string.
|
|
||||||
fn new(descr: &'static str, detail: Option<String>, share_index: Option<u8>, share_groups: Option<Vec<Vec<u8>>>) -> RustyError {
|
|
||||||
RustyError {
|
|
||||||
descr: descr,
|
|
||||||
detail: detail,
|
|
||||||
share_index: share_index,
|
|
||||||
share_groups: share_groups
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a `RustyError` with a given `RustyErrorType`.
|
|
||||||
pub fn with_type(error_type: RustyErrorTypes) -> RustyError {
|
|
||||||
RustyError {
|
|
||||||
descr: RustyError::descr_for_type(&error_type),
|
|
||||||
detail: RustyError::detail_for_type(&error_type),
|
|
||||||
share_index: RustyError::share_num_for_type(&error_type),
|
|
||||||
share_groups: RustyError::share_groups_for_type(error_type),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the index of the share that raised the error, if any.
|
|
||||||
pub fn share_index(&self) -> Option<u8> {
|
|
||||||
self.share_index
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the group of shares that were generated during the same secret share.
|
|
||||||
/// It can be used to provide a debug message to the user telling him what shares are incompatible.
|
|
||||||
pub fn share_groups(&self) -> Option<Vec<Vec<u8>>> {
|
|
||||||
self.share_groups.clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn descr_for_type(error_type: &RustyErrorTypes) -> &'static str {
|
|
||||||
match *error_type {
|
|
||||||
RustyErrorTypes::EmptyShares => "No shares were provided.",
|
|
||||||
RustyErrorTypes::IncompatibleSets(_) => "The shares are incompatible with each other.",
|
|
||||||
RustyErrorTypes::InvalidSignature(_, _) => "The signature of this share is not valid.",
|
|
||||||
RustyErrorTypes::MissingShares(_, _) => "The number of shares provided is insufficient to recover the secret.",
|
|
||||||
RustyErrorTypes::MissingSignature(_) => "Signature is missing while shares are required to be signed.",
|
|
||||||
RustyErrorTypes::SecretDeserializationIssue => "An issue was encountered deserializing the secret.
|
|
||||||
Updating to the latest version of RustySecrets might help fix this.",
|
|
||||||
RustyErrorTypes::ShareParsingError(_, _) => "This share is incorrectly formatted.",
|
|
||||||
RustyErrorTypes::DuplicateShareNum(_) => "This share number has already been used by a previous share.",
|
|
||||||
RustyErrorTypes::DuplicateShareData(_) => "The data encoded in this share is the same as the one found in a previous share."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn detail_for_type(error_type: &RustyErrorTypes) -> Option<String> {
|
|
||||||
match *error_type {
|
|
||||||
RustyErrorTypes::MissingShares(required, found) => Some(format!("{} shares are required to recover the secret,
|
|
||||||
found only {}.", required, found)),
|
|
||||||
RustyErrorTypes::ShareParsingError(_, ref description) => Some(description.clone()),
|
|
||||||
_ => None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn share_groups_for_type(error_type: RustyErrorTypes) -> Option<Vec<Vec<u8>>>{
|
|
||||||
match error_type {
|
|
||||||
RustyErrorTypes::IncompatibleSets(groups) => Some(groups),
|
|
||||||
_ => None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn share_num_for_type(error_type: &RustyErrorTypes) -> Option<u8> {
|
|
||||||
match *error_type {
|
|
||||||
RustyErrorTypes::InvalidSignature(share_num, _)
|
|
||||||
| RustyErrorTypes::MissingSignature(share_num)
|
|
||||||
| RustyErrorTypes::ShareParsingError(share_num, _)
|
|
||||||
| RustyErrorTypes::DuplicateShareNum(share_num)
|
|
||||||
| RustyErrorTypes::DuplicateShareData(share_num) => Some(share_num),
|
|
||||||
_ => None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for RustyError {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
match self.detail {
|
|
||||||
None => write!(f, "{}", self.descr),
|
|
||||||
Some(ref detail) => write!(f, "{} ({})", self.descr, detail),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Error for RustyError {
|
|
||||||
fn description(&self) -> &str {
|
|
||||||
self.descr
|
|
||||||
}
|
|
||||||
fn cause(&self) -> Option<&Error> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<io::Error> for RustyError {
|
|
||||||
fn from(err: io::Error) -> RustyError {
|
|
||||||
let descr = err.description().to_owned();
|
|
||||||
|
|
||||||
RustyError::new("from io:Error", Some(descr), None, None)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<RustyError> for io::Error {
|
|
||||||
fn from(me: RustyError) -> io::Error {
|
|
||||||
io::Error::new(io::ErrorKind::Other, me)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns an `io::Error` from description string and optional detail string.
|
|
||||||
/// Particularly useful in `Result` expressions.
|
|
||||||
pub fn other_io_err(descr: &'static str, detail: Option<String>,
|
|
||||||
share_num: Option<u8>, share_groups: Option<Vec<Vec<u8>>>) -> io::Error {
|
|
||||||
convert::From::from(RustyError::new(descr, detail, share_num, share_groups))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// maps a `ParseIntError` to an `Error`
|
|
||||||
pub fn pie2error(p: num::ParseIntError) -> RustyError {
|
|
||||||
RustyError::new("Integer parsing error", Some(p.to_string()), None, None)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests_custom_err {
|
|
||||||
use std::error;
|
|
||||||
use custom_error::RustyError;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_custom_error() {
|
|
||||||
let desc = "Boring error description";
|
|
||||||
let detail = "More of it";
|
|
||||||
let ewd = RustyError::new(desc, Some(detail.to_string()), None, None);
|
|
||||||
|
|
||||||
assert_eq!(error::Error::description(&ewd), desc);
|
|
||||||
match error::Error::cause(&ewd) {
|
|
||||||
Some(_) => assert!(false),
|
|
||||||
None => assert!(true),
|
|
||||||
}
|
|
||||||
let _formated_err = format!("{}", ewd);
|
|
||||||
let ewod = RustyError::new(desc, None, None, None);
|
|
||||||
let _formated_err = format!("{}", ewod);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests_std_err {
|
|
||||||
use std::error::Error;
|
|
||||||
use custom_error::pie2error;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_parse_errors() {
|
|
||||||
let nan = "2a".to_string();
|
|
||||||
match nan.parse::<u8>().map_err(pie2error) {
|
|
||||||
Ok(_) => assert!(false),
|
|
||||||
Err(x) => assert_eq!("Integer parsing error", x.description()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
73
src/dss/format.rs
Normal file
73
src/dss/format.rs
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
use std::error::Error;
|
||||||
|
|
||||||
|
use protobuf::{self, Message};
|
||||||
|
use base64;
|
||||||
|
|
||||||
|
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<ShareProto> {
|
||||||
|
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::<ShareProto>(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::<u32>()?;
|
||||||
|
let i = iter.next().unwrap().parse::<u32>()?;
|
||||||
|
let data = iter.next().unwrap();
|
||||||
|
Ok((k, i, data.to_string()))
|
||||||
|
}
|
31
src/dss/metadata.rs
Normal file
31
src/dss/metadata.rs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
use std::collections::BTreeMap;
|
||||||
|
use ring::digest;
|
||||||
|
|
||||||
|
/// 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<String, String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
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<String, String>) -> 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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
59
src/dss/mod.rs
Normal file
59
src/dss/mod.rs
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
//! 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**.<br> <em>Note: in this implementation **A** is not actually returned, but definitely could.</em>
|
||||||
|
//! **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 thss;
|
||||||
|
pub mod ss1;
|
||||||
|
|
||||||
|
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,
|
||||||
|
}
|
66
src/dss/random.rs
Normal file
66
src/dss/random.rs
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
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<Vec<u8>> {
|
||||||
|
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<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
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<u8>) -> 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(())
|
||||||
|
}
|
||||||
|
}
|
194
src/dss/ss1/mod.rs
Normal file
194
src/dss/ss1/mod.rs
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
//! 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**.<br> <em>Note: in this implementation **A** is not actually returned, but definitely could.</em>
|
||||||
|
//! **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;
|
||||||
|
use self::scheme::SS1;
|
||||||
|
pub use self::scheme::Reproducibility;
|
||||||
|
|
||||||
|
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<MetaData>,
|
||||||
|
) -> Result<Vec<Share>> {
|
||||||
|
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<u8>, AccessStructure, Option<MetaData>)> {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
317
src/dss/ss1/scheme.rs
Normal file
317
src/dss/ss1/scheme.rs
Normal file
@ -0,0 +1,317 @@
|
|||||||
|
use std::collections::HashSet;
|
||||||
|
|
||||||
|
use ring::{hkdf, hmac};
|
||||||
|
use ring::rand::{SecureRandom, SystemRandom};
|
||||||
|
use ring::digest::{Context, SHA256};
|
||||||
|
use rand::{ChaChaRng, Rng, SeedableRng};
|
||||||
|
|
||||||
|
use errors::*;
|
||||||
|
use dss::{thss, AccessStructure};
|
||||||
|
use dss::thss::{MetaData, ThSS};
|
||||||
|
use dss::random::{random_bytes_count, FixedRandom, MAX_MESSAGE_SIZE};
|
||||||
|
use share::validation::{validate_share_count, validate_shares};
|
||||||
|
use super::share::*;
|
||||||
|
use dss::utils;
|
||||||
|
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<u8>),
|
||||||
|
/// 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<u8>),
|
||||||
|
}
|
||||||
|
|
||||||
|
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<u8>) -> 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<u8>) -> 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<Self> {
|
||||||
|
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<MetaData>,
|
||||||
|
) -> Result<Vec<Share>> {
|
||||||
|
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<MetaData>,
|
||||||
|
) -> Result<Vec<u8>> {
|
||||||
|
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<MetaData>,
|
||||||
|
) -> Vec<u32> {
|
||||||
|
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<u8>, AccessStructure, Option<MetaData>)> {
|
||||||
|
let (_, shares) = validate_shares(shares.to_vec())?;
|
||||||
|
|
||||||
|
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::<Vec<_>>();
|
||||||
|
|
||||||
|
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<Share>,
|
||||||
|
mut test_shares: Vec<Share>,
|
||||||
|
) -> 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::<HashSet<_>>();
|
||||||
|
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(())
|
||||||
|
}
|
||||||
|
}
|
80
src/dss/ss1/serialize.rs
Normal file
80
src/dss/ss1/serialize.rs
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
use errors::*;
|
||||||
|
use super::{MetaData, Share};
|
||||||
|
use dss::format::{format_share_protobuf, parse_share_protobuf};
|
||||||
|
use proto::dss::{MetaDataProto, ShareProto};
|
||||||
|
use dss::utils::{btreemap_to_hashmap, hashmap_to_btreemap};
|
||||||
|
|
||||||
|
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<Share> {
|
||||||
|
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()),
|
||||||
|
}
|
||||||
|
}
|
57
src/dss/ss1/share.rs
Normal file
57
src/dss/ss1/share.rs
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
use errors::*;
|
||||||
|
use share::IsShare;
|
||||||
|
use super::serialize::{share_from_string, share_to_string};
|
||||||
|
|
||||||
|
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<u8>,
|
||||||
|
/// The hash value common to the whole deal
|
||||||
|
pub hash: Vec<u8>,
|
||||||
|
/// The metadata associated with this share
|
||||||
|
pub metadata: Option<MetaData>,
|
||||||
|
}
|
||||||
|
|
||||||
|
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<Self> {
|
||||||
|
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<u8> {
|
||||||
|
Some(self.shares_count)
|
||||||
|
}
|
||||||
|
}
|
37
src/dss/thss/encode.rs
Normal file
37
src/dss/thss/encode.rs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
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<u8> {
|
||||||
|
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 = acc + r * s;
|
||||||
|
}
|
||||||
|
acc.to_byte()
|
||||||
|
}
|
122
src/dss/thss/mod.rs
Normal file
122
src/dss/thss/mod.rs
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
//! 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**.<br> <em>Note: in this implementation **A** is not actually returned, but definitely could.</em>
|
||||||
|
//! **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<MetaData>,
|
||||||
|
) -> Result<Vec<Share>> {
|
||||||
|
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<u8>, AccessStructure, Option<MetaData>)> {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
134
src/dss/thss/scheme.rs
Normal file
134
src/dss/thss/scheme.rs
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
//! Simple threshold secret sharing scheme
|
||||||
|
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
|
use ring::rand::{SecureRandom, SystemRandom};
|
||||||
|
|
||||||
|
use errors::*;
|
||||||
|
use gf256::Gf256;
|
||||||
|
use dss::random::{random_bytes, random_bytes_count, MAX_MESSAGE_SIZE};
|
||||||
|
use share::validation::{validate_share_count, validate_shares};
|
||||||
|
use lagrange;
|
||||||
|
|
||||||
|
use super::AccessStructure;
|
||||||
|
use super::share::*;
|
||||||
|
use super::encode::encode_secret;
|
||||||
|
|
||||||
|
/// 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<SecureRandom>,
|
||||||
|
}
|
||||||
|
|
||||||
|
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<SecureRandom>) -> 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<MetaData>,
|
||||||
|
) -> Result<Vec<Share>> {
|
||||||
|
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<u8>, AccessStructure, Option<MetaData>)> {
|
||||||
|
let (threshold, shares) = validate_shares(shares.to_vec())?;
|
||||||
|
|
||||||
|
let cypher_len = shares[0].data.len();
|
||||||
|
|
||||||
|
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::<Vec<_>>();
|
||||||
|
|
||||||
|
lagrange::interpolate(&points)
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
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))
|
||||||
|
}
|
||||||
|
}
|
78
src/dss/thss/serialize.rs
Normal file
78
src/dss/thss/serialize.rs
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
use errors::*;
|
||||||
|
use super::{MetaData, Share};
|
||||||
|
use dss::format::{format_share_protobuf, parse_share_protobuf};
|
||||||
|
use proto::dss::{MetaDataProto, ShareProto};
|
||||||
|
use dss::utils::{btreemap_to_hashmap, hashmap_to_btreemap};
|
||||||
|
|
||||||
|
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<Share> {
|
||||||
|
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()),
|
||||||
|
}
|
||||||
|
}
|
55
src/dss/thss/share.rs
Normal file
55
src/dss/thss/share.rs
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
use errors::*;
|
||||||
|
use share::IsShare;
|
||||||
|
use super::serialize::{share_from_string, share_to_string};
|
||||||
|
|
||||||
|
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<u8>,
|
||||||
|
/// The metadata associated with this share
|
||||||
|
pub metadata: Option<MetaData>,
|
||||||
|
}
|
||||||
|
|
||||||
|
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<Self> {
|
||||||
|
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<u8> {
|
||||||
|
Some(self.shares_count)
|
||||||
|
}
|
||||||
|
}
|
28
src/dss/utils.rs
Normal file
28
src/dss/utils.rs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
use std;
|
||||||
|
|
||||||
|
use std::hash::Hash;
|
||||||
|
use std::collections::{BTreeMap, HashMap};
|
||||||
|
|
||||||
|
/// 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<A: Eq + Hash, B>(btree: BTreeMap<A, B>) -> HashMap<A, B> {
|
||||||
|
let mut hash = HashMap::new();
|
||||||
|
hash.extend(btree.into_iter());
|
||||||
|
hash
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a `BTreeMap` from a `HashMap`
|
||||||
|
pub(crate) fn hashmap_to_btreemap<A: Ord + Hash, B>(hash: HashMap<A, B>) -> BTreeMap<A, B> {
|
||||||
|
let mut btree = BTreeMap::new();
|
||||||
|
btree.extend(hash.into_iter());
|
||||||
|
btree
|
||||||
|
}
|
141
src/errors.rs
Normal file
141
src/errors.rs
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
//! Define the various error kinds specific to deterministic secret sharing.
|
||||||
|
|
||||||
|
#![allow(unknown_lints, missing_docs)]
|
||||||
|
|
||||||
|
use std::collections::HashSet;
|
||||||
|
|
||||||
|
#[cfg(feature = "dss")]
|
||||||
|
use dss::ss1;
|
||||||
|
|
||||||
|
/// Minimum allowed number of shares (n)
|
||||||
|
pub(crate) static MIN_SHARES: u8 = 2;
|
||||||
|
/// Minimum allowed threshold (k)
|
||||||
|
pub(crate) static MIN_THRESHOLD: u8 = 2;
|
||||||
|
/// Maximum allowed number of shares (k,n)
|
||||||
|
pub(crate) static MAX_SHARES: u8 = 255;
|
||||||
|
/// SSS Shares should be structured as k-n-data hence 3 parts
|
||||||
|
pub(crate) static SSS_SHARE_PARTS_COUNT: usize = 3;
|
||||||
|
|
||||||
|
/// Create the Error, ErrorKind, ResultExt, and Result types
|
||||||
|
error_chain! {
|
||||||
|
errors {
|
||||||
|
ThresholdTooBig(k: u8, n: u8) {
|
||||||
|
description("Threshold k must be smaller than or equal to n")
|
||||||
|
display("Threshold k must be smaller than or equal to n, got: k = {}, n = {}.", k, n)
|
||||||
|
}
|
||||||
|
|
||||||
|
ThresholdTooSmall(k: u8) {
|
||||||
|
description("Threshold k must be bigger than or equal to 2")
|
||||||
|
display("Threshold k must be bigger than or equal to 2, got: k = {}", k)
|
||||||
|
}
|
||||||
|
|
||||||
|
SecretTooBig(len: usize, max: usize) {
|
||||||
|
description("The secret is too long")
|
||||||
|
display("The secret is too long, maximum allowed size = {} bytes, got {} bytes", max, len)
|
||||||
|
}
|
||||||
|
|
||||||
|
InvalidShareCountMax(nb_shares: u8, max: u8) {
|
||||||
|
description("Number of shares is too big")
|
||||||
|
display("Number of shares must be smaller than or equal {}, got: {} shares.", max, nb_shares)
|
||||||
|
}
|
||||||
|
|
||||||
|
InvalidShareCountMin(nb_shares: u8, min: u8) {
|
||||||
|
description("Number of shares is too small")
|
||||||
|
display("Number of shares must be larger than or equal {}, got: {} shares.", min, nb_shares)
|
||||||
|
}
|
||||||
|
|
||||||
|
EmptySecret {
|
||||||
|
description("The secret cannot be empty")
|
||||||
|
display("The secret cannot be empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
EmptyShares {
|
||||||
|
description("No shares provided")
|
||||||
|
display("No shares were provided.")
|
||||||
|
}
|
||||||
|
|
||||||
|
IncompatibleSets(sets: Vec<HashSet<u8>>) {
|
||||||
|
description("The shares are incompatible with each other.")
|
||||||
|
display("The shares are incompatible with each other.")
|
||||||
|
}
|
||||||
|
|
||||||
|
ShareIdentifierTooBig(id: u8, n: u8) {
|
||||||
|
description("Share identifier too big")
|
||||||
|
display("Found share identifier ({}) bigger than the maximum number of shares ({}).", id, n)
|
||||||
|
}
|
||||||
|
|
||||||
|
MissingShares(provided: usize, required: usize) {
|
||||||
|
description("The number of shares provided is insufficient to recover the secret.")
|
||||||
|
display("{} shares are required to recover the secret, found only {}.", required, provided)
|
||||||
|
}
|
||||||
|
|
||||||
|
InvalidSignature(share_id: u8, signature: String) {
|
||||||
|
description("The signature of this share is not valid.")
|
||||||
|
}
|
||||||
|
|
||||||
|
MissingSignature(share_id: u8) {
|
||||||
|
description("Signature is missing while shares are required to be signed.")
|
||||||
|
}
|
||||||
|
|
||||||
|
SecretDeserializationError {
|
||||||
|
description("An issue was encountered deserializing the secret. \
|
||||||
|
Updating to the latest version of RustySecrets might help fix this.")
|
||||||
|
}
|
||||||
|
|
||||||
|
ShareParsingError(reason: String) {
|
||||||
|
description("This share is incorrectly formatted.")
|
||||||
|
display("This share is incorrectly formatted. Reason: {}", reason)
|
||||||
|
}
|
||||||
|
|
||||||
|
ShareParsingErrorEmptyShare(share_id: u8) {
|
||||||
|
description("This share is empty.")
|
||||||
|
display("Found empty share for share identifier ({})", share_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
ShareParsingInvalidShareId(share_id: u8) {
|
||||||
|
description("Invalid share identifier.")
|
||||||
|
display("Found invalid share identifier ({})", share_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
InvalidSS1Parameters(r: usize, s: usize) {
|
||||||
|
description("Invalid parameters for the SS1 sharing scheme")
|
||||||
|
display("Invalid parameters for the SS1 sharing scheme: r = {}, s = {}.", r, s)
|
||||||
|
}
|
||||||
|
|
||||||
|
InvalidSplitParametersZero(k: u8, n: u8) {
|
||||||
|
description("Parameters k and n must be greater than zero")
|
||||||
|
display("Parameters k and n must be greater than zero.")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "dss")]
|
||||||
|
MismatchingShares(got: ss1::Share, expected: ss1::Share) {
|
||||||
|
description("Share mismatch during verification of secret recovery")
|
||||||
|
display("Share mismatch during verification of secret recovery.")
|
||||||
|
}
|
||||||
|
|
||||||
|
CannotGenerateRandomNumbers {
|
||||||
|
description("Cannot generate random numbers")
|
||||||
|
display("Cannot generate random numbers.")
|
||||||
|
}
|
||||||
|
|
||||||
|
DuplicateShareId(share_id: u8) {
|
||||||
|
description("This share number has already been used by a previous share.")
|
||||||
|
display("This share number ({}) has already been used by a previous share.", share_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
DuplicateShareData(share_id: u8) {
|
||||||
|
description("The data encoded in this share is the same as the one found in a previous share")
|
||||||
|
display("The data encoded in share #{} is the same as the one found in a previous share.", share_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
InconsistentShares {
|
||||||
|
description("The shares are inconsistent")
|
||||||
|
display("The shares are inconsistent")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreign_links {
|
||||||
|
Io(::std::io::Error);
|
||||||
|
IntegerParsingError(::std::num::ParseIntError);
|
||||||
|
}
|
||||||
|
}
|
181
src/gf256.rs
181
src/gf256.rs
@ -1,7 +1,7 @@
|
|||||||
//! This module provides the Gf256 type which is used to represent
|
//! This module provides the Gf256 type which is used to represent
|
||||||
//! elements of a finite field with 256 elements.
|
//! elements of a finite field with 256 elements.
|
||||||
|
|
||||||
use std::ops::{Add, Div, Mul, Sub};
|
use std::ops::{Add, Div, Mul, Neg, Sub};
|
||||||
|
|
||||||
include!(concat!(env!("OUT_DIR"), "/nothinghardcoded.rs"));
|
include!(concat!(env!("OUT_DIR"), "/nothinghardcoded.rs"));
|
||||||
|
|
||||||
@ -10,7 +10,7 @@ fn get_tables() -> &'static Tables {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Type for elements of a finite field with 256 elements
|
/// Type for elements of a finite field with 256 elements
|
||||||
#[derive(Copy,Clone,PartialEq,Eq)]
|
#[derive(Copy, Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct Gf256 {
|
pub struct Gf256 {
|
||||||
pub poly: u8,
|
pub poly: u8,
|
||||||
}
|
}
|
||||||
@ -34,6 +34,10 @@ impl Gf256 {
|
|||||||
pub fn to_byte(&self) -> u8 {
|
pub fn to_byte(&self) -> u8 {
|
||||||
self.poly
|
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<u8> {
|
pub fn log(&self) -> Option<u8> {
|
||||||
if self.poly == 0 {
|
if self.poly == 0 {
|
||||||
None
|
None
|
||||||
@ -42,9 +46,23 @@ impl Gf256 {
|
|||||||
Some(tabs.log[self.poly as usize])
|
Some(tabs.log[self.poly as usize])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn exp(power: u8) -> Gf256 {
|
pub fn pow(&self, mut exp: u8) -> Gf256 {
|
||||||
let tabs = get_tables();
|
let mut base = *self;
|
||||||
Gf256 { poly: tabs.exp[power as usize] }
|
let mut acc = Self::one();
|
||||||
|
|
||||||
|
while exp > 1 {
|
||||||
|
if (exp & 1) == 1 {
|
||||||
|
acc = acc * base;
|
||||||
|
}
|
||||||
|
exp /= 2;
|
||||||
|
base = base * base;
|
||||||
|
}
|
||||||
|
|
||||||
|
if exp == 1 {
|
||||||
|
acc = acc * base;
|
||||||
|
}
|
||||||
|
|
||||||
|
acc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,7 +86,7 @@ impl Mul<Gf256> for Gf256 {
|
|||||||
type Output = Gf256;
|
type Output = Gf256;
|
||||||
fn mul(self, rhs: Gf256) -> Gf256 {
|
fn mul(self, rhs: Gf256) -> Gf256 {
|
||||||
if let (Some(l1), Some(l2)) = (self.log(), rhs.log()) {
|
if let (Some(l1), Some(l2)) = (self.log(), rhs.log()) {
|
||||||
let tmp = ((l1 as u16) + (l2 as u16)) % 255;
|
let tmp = (u16::from(l1) + u16::from(l2)) % 255;
|
||||||
Gf256::exp(tmp as u8)
|
Gf256::exp(tmp as u8)
|
||||||
} else {
|
} else {
|
||||||
Gf256 { poly: 0 }
|
Gf256 { poly: 0 }
|
||||||
@ -81,10 +99,159 @@ impl Div<Gf256> for Gf256 {
|
|||||||
fn div(self, rhs: Gf256) -> Gf256 {
|
fn div(self, rhs: Gf256) -> Gf256 {
|
||||||
let l2 = rhs.log().expect("division by zero");
|
let l2 = rhs.log().expect("division by zero");
|
||||||
if let Some(l1) = self.log() {
|
if let Some(l1) = self.log() {
|
||||||
let tmp = ((l1 as u16) + 255 - (l2 as u16)) % 255;
|
let tmp = (u16::from(l1) + 255 - u16::from(l2)) % 255;
|
||||||
Gf256::exp(tmp as u8)
|
Gf256::exp(tmp as u8)
|
||||||
} else {
|
} else {
|
||||||
Gf256 { poly: 0 }
|
Gf256 { poly: 0 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Neg for Gf256 {
|
||||||
|
type Output = Gf256;
|
||||||
|
fn neg(self) -> Gf256 {
|
||||||
|
Gf256::zero() - self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
#[doc(hidden)]
|
||||||
|
macro_rules! gf256 {
|
||||||
|
($e:expr) => (Gf256::from_byte($e))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
#[doc(hidden)]
|
||||||
|
macro_rules! gf256_vec {
|
||||||
|
( $( ($x:expr, $y:expr) ),* ) => {
|
||||||
|
{
|
||||||
|
let mut temp_vec = Vec::new();
|
||||||
|
$(
|
||||||
|
temp_vec.push((Gf256::from_byte($x), Gf256::from_byte($y)));
|
||||||
|
)*
|
||||||
|
temp_vec
|
||||||
|
}
|
||||||
|
};
|
||||||
|
( $( $x:expr ),* ) => {
|
||||||
|
{
|
||||||
|
let mut temp_vec = Vec::new();
|
||||||
|
$(
|
||||||
|
temp_vec.push(Gf256::from_byte($x));
|
||||||
|
)*
|
||||||
|
temp_vec
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
#[allow(trivial_casts)]
|
||||||
|
mod tests {
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
use quickcheck::*;
|
||||||
|
|
||||||
|
mod vectors {
|
||||||
|
use super::*;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::{BufRead, BufReader};
|
||||||
|
use itertools::Itertools;
|
||||||
|
use flate2::read::GzDecoder;
|
||||||
|
|
||||||
|
macro_rules! mk_test {
|
||||||
|
($id:ident, $op:expr, $val:expr) => {
|
||||||
|
mk_test!($id, $op, $val, 0);
|
||||||
|
};
|
||||||
|
($id:ident, $op:expr, $val:expr, $y:expr) => {
|
||||||
|
#[test]
|
||||||
|
fn $id() {
|
||||||
|
let results = (0..256).cartesian_product($y..256).map(|(i, j)| {
|
||||||
|
let (i, j) = (Gf256::from_byte(i as u8), Gf256::from_byte(j as u8));
|
||||||
|
(i.to_byte(), j.to_byte(), $val(i, j).to_byte())
|
||||||
|
});
|
||||||
|
|
||||||
|
let ref_path = format!("tests/fixtures/gf256/gf256_{}.txt.gz", stringify!($id));
|
||||||
|
let reference = BufReader::new(GzDecoder::new(File::open(ref_path).unwrap()).unwrap());
|
||||||
|
|
||||||
|
for ((i, j, k), line) in results.zip(reference.lines()) {
|
||||||
|
let left = format!("{} {} {} = {}", i, $op, j, k);
|
||||||
|
let right = line.unwrap();
|
||||||
|
assert_eq!(left, right);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mk_test!(add, "+", |i: Gf256, j: Gf256| i + j);
|
||||||
|
mk_test!(sub, "-", |i: Gf256, j: Gf256| i - j);
|
||||||
|
mk_test!(mul, "*", |i: Gf256, j: Gf256| i * j);
|
||||||
|
mk_test!(div, "/", |i: Gf256, j: Gf256| i.div(j), 1);
|
||||||
|
mk_test!(pow, "^", |i: Gf256, j: Gf256| i.pow(j.to_byte()));
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Arbitrary for Gf256 {
|
||||||
|
fn arbitrary<G: Gen>(gen: &mut G) -> Gf256 {
|
||||||
|
Gf256::from_byte(u8::arbitrary(gen))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod addition {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
quickcheck! {
|
||||||
|
fn law_associativity(a: Gf256, b: Gf256, c: Gf256) -> bool {
|
||||||
|
(a + b) + c == a + (b + c)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn law_commutativity(a: Gf256, b: Gf256) -> bool {
|
||||||
|
a + b == b + a
|
||||||
|
}
|
||||||
|
|
||||||
|
fn law_distributivity(a: Gf256, b: Gf256, c: Gf256) -> bool {
|
||||||
|
a * (b + c) == a * b + a * c
|
||||||
|
}
|
||||||
|
|
||||||
|
fn law_identity(a: Gf256) -> bool {
|
||||||
|
a + Gf256::zero() == a && Gf256::zero() + a == a
|
||||||
|
}
|
||||||
|
|
||||||
|
fn law_inverses(a: Gf256) -> bool {
|
||||||
|
a + (-a) == Gf256::zero() && (-a) + a == Gf256::zero()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod multiplication {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
quickcheck! {
|
||||||
|
fn law_associativity(a: Gf256, b: Gf256, c: Gf256) -> bool {
|
||||||
|
(a * b) * c == a * (b * c)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn law_commutativity(a: Gf256, b: Gf256) -> bool {
|
||||||
|
a * b == b * a
|
||||||
|
}
|
||||||
|
|
||||||
|
fn law_distributivity(a: Gf256, b: Gf256, c: Gf256) -> bool {
|
||||||
|
(a + b) * c == a * c + b * c
|
||||||
|
}
|
||||||
|
|
||||||
|
fn law_identity(a: Gf256) -> bool {
|
||||||
|
a * Gf256::one() == a && Gf256::one() * a == a
|
||||||
|
}
|
||||||
|
|
||||||
|
fn law_inverses(a: Gf256) -> TestResult {
|
||||||
|
if a == Gf256::zero() {
|
||||||
|
return TestResult::discard();
|
||||||
|
}
|
||||||
|
|
||||||
|
let left = a * (Gf256::one() / a) == Gf256::one();
|
||||||
|
let right = (Gf256::one() / a) * a == Gf256::one();
|
||||||
|
|
||||||
|
TestResult::from_bool(left && right)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -1,40 +0,0 @@
|
|||||||
use gf256::Gf256;
|
|
||||||
use std::io;
|
|
||||||
use std::io::prelude::*;
|
|
||||||
|
|
||||||
/// evaluates a polynomial at x=1, 2, 3, ... n (inclusive)
|
|
||||||
pub fn encode<W: Write>(src: &[u8], n: u8, w: &mut W) -> io::Result<()> {
|
|
||||||
for raw_x in 1..((n as u16) + 1) {
|
|
||||||
let x = Gf256::from_byte(raw_x as u8);
|
|
||||||
let mut fac = Gf256::one();
|
|
||||||
let mut acc = Gf256::zero();
|
|
||||||
for &coeff in src.iter() {
|
|
||||||
acc = acc + fac * Gf256::from_byte(coeff);
|
|
||||||
fac = fac * x;
|
|
||||||
}
|
|
||||||
try!(w.write(&[acc.to_byte()]));
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// evaluates an interpolated polynomial at `Gf256::zero()` where
|
|
||||||
/// the polynomial is determined using Lagrangian interpolation
|
|
||||||
/// based on the given x/y coordinates `src`.
|
|
||||||
pub fn lagrange_interpolate(src: &[(u8, u8)]) -> u8 {
|
|
||||||
let mut sum = Gf256::zero();
|
|
||||||
for (i, &(raw_xi, raw_yi)) in src.iter().enumerate() {
|
|
||||||
let xi = Gf256::from_byte(raw_xi);
|
|
||||||
let yi = Gf256::from_byte(raw_yi);
|
|
||||||
let mut prod = Gf256::one();
|
|
||||||
for (j, &(raw_xj, _)) in src.iter().enumerate() {
|
|
||||||
if i != j {
|
|
||||||
let xj = Gf256::from_byte(raw_xj);
|
|
||||||
let delta = xi - xj;
|
|
||||||
assert!(delta.poly != 0, "Duplicate shares");
|
|
||||||
prod = prod * xj / delta;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sum = sum + prod * yi;
|
|
||||||
}
|
|
||||||
sum.to_byte()
|
|
||||||
}
|
|
124
src/lagrange.rs
Normal file
124
src/lagrange.rs
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
use gf256::Gf256;
|
||||||
|
use poly::Poly;
|
||||||
|
|
||||||
|
/// Evaluates an interpolated polynomial at `Gf256::zero()` where
|
||||||
|
/// the polynomial is determined using Lagrangian interpolation
|
||||||
|
/// based on the given `points` in the G(2^8) Galois field.
|
||||||
|
pub(crate) fn interpolate_at(points: &[(u8, u8)]) -> u8 {
|
||||||
|
let mut sum = Gf256::zero();
|
||||||
|
for (i, &(raw_xi, raw_yi)) in points.iter().enumerate() {
|
||||||
|
let xi = Gf256::from_byte(raw_xi);
|
||||||
|
let yi = Gf256::from_byte(raw_yi);
|
||||||
|
let mut prod = Gf256::one();
|
||||||
|
for (j, &(raw_xj, _)) in points.iter().enumerate() {
|
||||||
|
if i != j {
|
||||||
|
let xj = Gf256::from_byte(raw_xj);
|
||||||
|
let delta = xi - xj;
|
||||||
|
assert_ne!(delta.poly, 0, "Duplicate shares");
|
||||||
|
prod = prod * xj / delta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sum = sum + prod * yi;
|
||||||
|
}
|
||||||
|
sum.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 {
|
||||||
|
let mut coeffs = vec![Gf256::zero(); len];
|
||||||
|
coeffs[0] = y;
|
||||||
|
|
||||||
|
let mut prod = Gf256::one();
|
||||||
|
for &(x1, _) in points {
|
||||||
|
if x != x1 {
|
||||||
|
prod = 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 std;
|
||||||
|
use super::*;
|
||||||
|
use gf256::*;
|
||||||
|
use quickcheck::*;
|
||||||
|
|
||||||
|
quickcheck! {
|
||||||
|
|
||||||
|
fn evaluate_at_works(ys: Vec<u8>) -> TestResult {
|
||||||
|
if ys.is_empty() || ys.len() > std::u8::MAX as usize {
|
||||||
|
return TestResult::discard();
|
||||||
|
}
|
||||||
|
|
||||||
|
let points = ys.iter().enumerate().map(|(x, y)| (x as u8, *y)).collect::<Vec<_>>();
|
||||||
|
let equals = interpolate_at(points.as_slice()) == ys[0];
|
||||||
|
|
||||||
|
TestResult::from_bool(equals)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn interpolate_evaluate_at_works(ys: Vec<Gf256>) -> TestResult {
|
||||||
|
if ys.is_empty() || ys.len() > std::u8::MAX as usize {
|
||||||
|
return TestResult::discard();
|
||||||
|
}
|
||||||
|
|
||||||
|
let points = ys.into_iter().enumerate().map(|(x, y)| (gf256!(x as u8), y)).collect::<Vec<_>>();
|
||||||
|
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<u8>) -> TestResult {
|
||||||
|
if ys.len() > std::u8::MAX as usize {
|
||||||
|
return TestResult::discard();
|
||||||
|
}
|
||||||
|
|
||||||
|
let points = ys.into_iter().enumerate().map(|(x, y)| (x as u8, y)).collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let elems = points
|
||||||
|
.iter()
|
||||||
|
.map(|&(x, y)| (gf256!(x), gf256!(y)))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let poly = interpolate(&elems);
|
||||||
|
|
||||||
|
let equals = poly.evaluate_at(Gf256::zero()).to_byte() == interpolate_at(points.as_slice());
|
||||||
|
|
||||||
|
TestResult::from_bool(equals)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
55
src/lib.rs
55
src/lib.rs
@ -1,37 +1,42 @@
|
|||||||
//! `RustySecrets` implements Shamir's secret sharing in Rust. It provides the possibility to sign shares.
|
//! `RustySecrets` implements Shamir's secret sharing in Rust. It provides the possibility to sign shares.
|
||||||
|
|
||||||
#![deny(
|
#![deny(missing_docs, missing_debug_implementations, missing_copy_implementations, trivial_casts,
|
||||||
missing_docs,
|
trivial_numeric_casts, unsafe_code, unstable_features, unused_import_braces,
|
||||||
missing_debug_implementations, missing_copy_implementations,
|
unused_qualifications)]
|
||||||
trivial_casts, trivial_numeric_casts,
|
#![cfg_attr(feature = "cargo-clippy", allow(doc_markdown))]
|
||||||
unsafe_code, unstable_features,
|
// `error_chain!` can recurse deeply
|
||||||
unused_import_braces, unused_qualifications
|
#![recursion_limit = "1024"]
|
||||||
)]
|
|
||||||
|
|
||||||
extern crate protobuf;
|
#[macro_use]
|
||||||
extern crate rustc_serialize as serialize;
|
extern crate error_chain;
|
||||||
extern crate rand;
|
|
||||||
|
extern crate base64;
|
||||||
extern crate merkle_sigs;
|
extern crate merkle_sigs;
|
||||||
|
extern crate protobuf;
|
||||||
|
extern crate rand;
|
||||||
extern crate ring;
|
extern crate ring;
|
||||||
|
|
||||||
use ring::digest::{Algorithm, SHA512};
|
#[macro_use]
|
||||||
#[allow(non_upper_case_globals)]
|
|
||||||
static digest: &'static Algorithm = &SHA512;
|
|
||||||
|
|
||||||
mod custom_error;
|
|
||||||
mod gf256;
|
mod gf256;
|
||||||
mod interpolation;
|
mod share;
|
||||||
#[allow(unused_qualifications)]
|
mod poly;
|
||||||
mod secret;
|
mod lagrange;
|
||||||
#[allow(unused_qualifications)]
|
mod vol_hash;
|
||||||
mod share_data;
|
|
||||||
mod share_format;
|
|
||||||
mod validation;
|
|
||||||
|
|
||||||
pub use custom_error::RustyError;
|
|
||||||
|
|
||||||
|
pub mod errors;
|
||||||
pub mod sss;
|
pub mod sss;
|
||||||
pub mod wrapped_secrets;
|
pub mod wrapped_secrets;
|
||||||
|
pub mod proto;
|
||||||
|
|
||||||
|
#[cfg(feature = "dss")]
|
||||||
|
pub mod dss;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
extern crate itertools;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
extern crate flate2;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
#[macro_use]
|
||||||
|
extern crate quickcheck;
|
||||||
|
29
src/poly.rs
Normal file
29
src/poly.rs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
use gf256::Gf256;
|
||||||
|
|
||||||
|
static MAX_COEFFS: usize = 256;
|
||||||
|
|
||||||
|
pub(crate) struct Poly {
|
||||||
|
pub coeffs: Vec<Gf256>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Poly {
|
||||||
|
pub fn new(coeffs: Vec<Gf256>) -> 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 = result + *c * x.pow(i as u8);
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
253
src/proto/dss/metadata.rs
Normal file
253
src/proto/dss/metadata.rs
Normal file
@ -0,0 +1,253 @@
|
|||||||
|
// 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<MetaDataProto> = ::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<Self>) -> ::std::boxed::Box<::std::any::Any> {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
|
||||||
|
::protobuf::MessageStatic::descriptor_static(None::<Self>)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ::protobuf::MessageStatic for MetaDataProto {
|
||||||
|
fn new() -> MetaDataProto {
|
||||||
|
MetaDataProto::new()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn descriptor_static(
|
||||||
|
_: ::std::option::Option<MetaDataProto>,
|
||||||
|
) -> &'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>(
|
||||||
|
"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()) }
|
||||||
|
}
|
13
src/proto/dss/mod.rs
Normal file
13
src/proto/dss/mod.rs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#[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;
|
||||||
|
|
||||||
|
pub use super::version;
|
369
src/proto/dss/secret.rs
Normal file
369
src/proto/dss/secret.rs
Normal file
@ -0,0 +1,369 @@
|
|||||||
|
// 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<u8>,
|
||||||
|
pub meta_data: ::protobuf::SingularPtrField<super::metadata::MetaDataProto>,
|
||||||
|
// 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<SecretProto> = ::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<u8>) {
|
||||||
|
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<u8> {
|
||||||
|
&mut self.secret
|
||||||
|
}
|
||||||
|
|
||||||
|
// Take field
|
||||||
|
pub fn take_secret(&mut self) -> ::std::vec::Vec<u8> {
|
||||||
|
::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<u8> {
|
||||||
|
&self.secret
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mut_secret_for_reflect(&mut self) -> &mut ::std::vec::Vec<u8> {
|
||||||
|
&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<super::metadata::MetaDataProto> {
|
||||||
|
&self.meta_data
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mut_meta_data_for_reflect(
|
||||||
|
&mut self,
|
||||||
|
) -> &mut ::protobuf::SingularPtrField<super::metadata::MetaDataProto> {
|
||||||
|
&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<Self>) -> ::std::boxed::Box<::std::any::Any> {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
|
||||||
|
::protobuf::MessageStatic::descriptor_static(None::<Self>)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ::protobuf::MessageStatic for SecretProto {
|
||||||
|
fn new() -> SecretProto {
|
||||||
|
SecretProto::new()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn descriptor_static(
|
||||||
|
_: ::std::option::Option<SecretProto>,
|
||||||
|
) -> &'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<super::version::VersionProto>>(
|
||||||
|
"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<super::metadata::MetaDataProto>>(
|
||||||
|
"meta_data",
|
||||||
|
SecretProto::get_meta_data_for_reflect,
|
||||||
|
SecretProto::mut_meta_data_for_reflect,
|
||||||
|
));
|
||||||
|
::protobuf::reflect::MessageDescriptor::new::<SecretProto>(
|
||||||
|
"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()) }
|
||||||
|
}
|
492
src/proto/dss/share.rs
Normal file
492
src/proto/dss/share.rs
Normal file
@ -0,0 +1,492 @@
|
|||||||
|
// 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<u8>,
|
||||||
|
pub hash: ::std::vec::Vec<u8>,
|
||||||
|
pub meta_data: ::protobuf::SingularPtrField<super::metadata::MetaDataProto>,
|
||||||
|
// 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<ShareProto> = ::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<u8>) {
|
||||||
|
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<u8> {
|
||||||
|
&mut self.data
|
||||||
|
}
|
||||||
|
|
||||||
|
// Take field
|
||||||
|
pub fn take_data(&mut self) -> ::std::vec::Vec<u8> {
|
||||||
|
::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<u8> {
|
||||||
|
&self.data
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mut_data_for_reflect(&mut self) -> &mut ::std::vec::Vec<u8> {
|
||||||
|
&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<u8>) {
|
||||||
|
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<u8> {
|
||||||
|
&mut self.hash
|
||||||
|
}
|
||||||
|
|
||||||
|
// Take field
|
||||||
|
pub fn take_hash(&mut self) -> ::std::vec::Vec<u8> {
|
||||||
|
::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<u8> {
|
||||||
|
&self.hash
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mut_hash_for_reflect(&mut self) -> &mut ::std::vec::Vec<u8> {
|
||||||
|
&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<super::metadata::MetaDataProto> {
|
||||||
|
&self.meta_data
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mut_meta_data_for_reflect(&mut self) -> &mut ::protobuf::SingularPtrField<super::metadata::MetaDataProto> {
|
||||||
|
&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<Self>) -> ::std::boxed::Box<::std::any::Any> {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
|
||||||
|
::protobuf::MessageStatic::descriptor_static(None::<Self>)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ::protobuf::MessageStatic for ShareProto {
|
||||||
|
fn new() -> ShareProto {
|
||||||
|
ShareProto::new()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn descriptor_static(_: ::std::option::Option<ShareProto>) -> &'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<super::metadata::MetaDataProto>>(
|
||||||
|
"meta_data",
|
||||||
|
ShareProto::get_meta_data_for_reflect,
|
||||||
|
ShareProto::mut_meta_data_for_reflect,
|
||||||
|
));
|
||||||
|
::protobuf::reflect::MessageDescriptor::new::<ShareProto>(
|
||||||
|
"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()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
12
src/proto/mod.rs
Normal file
12
src/proto/mod.rs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
//! Protocol buffer definitions
|
||||||
|
|
||||||
|
#[allow(unused_qualifications, deprecated, missing_docs)]
|
||||||
|
pub mod wrapped;
|
||||||
|
|
||||||
|
#[allow(unused_qualifications, deprecated, missing_docs)]
|
||||||
|
pub mod dss;
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
#[allow(unused_qualifications, deprecated, missing_docs)]
|
||||||
|
pub mod version;
|
||||||
|
pub use self::version::VersionProto;
|
100
src/proto/version.rs
Normal file
100
src/proto/version.rs
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
// 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(Clone,PartialEq,Eq,Debug,Hash)]
|
||||||
|
pub enum VersionProto {
|
||||||
|
INITIAL_RELEASE = 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ::protobuf::ProtobufEnum for VersionProto {
|
||||||
|
fn value(&self) -> i32 {
|
||||||
|
*self as i32
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_i32(value: i32) -> ::std::option::Option<VersionProto> {
|
||||||
|
match value {
|
||||||
|
0 => ::std::option::Option::Some(VersionProto::INITIAL_RELEASE),
|
||||||
|
_ => ::std::option::Option::None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn values() -> &'static [Self] {
|
||||||
|
static values: &'static [VersionProto] = &[
|
||||||
|
VersionProto::INITIAL_RELEASE,
|
||||||
|
];
|
||||||
|
values
|
||||||
|
}
|
||||||
|
|
||||||
|
fn enum_descriptor_static(_: ::std::option::Option<VersionProto>) -> &'static ::protobuf::reflect::EnumDescriptor {
|
||||||
|
static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::EnumDescriptor> = ::protobuf::lazy::Lazy {
|
||||||
|
lock: ::protobuf::lazy::ONCE_INIT,
|
||||||
|
ptr: 0 as *const ::protobuf::reflect::EnumDescriptor,
|
||||||
|
};
|
||||||
|
unsafe {
|
||||||
|
descriptor.get(|| {
|
||||||
|
::protobuf::reflect::EnumDescriptor::new("VersionProto", file_descriptor_proto())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ::std::marker::Copy for VersionProto {
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ::std::default::Default for VersionProto {
|
||||||
|
fn default() -> Self {
|
||||||
|
VersionProto::INITIAL_RELEASE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ::protobuf::reflect::ProtobufValue for VersionProto {
|
||||||
|
fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef {
|
||||||
|
::protobuf::reflect::ProtobufValueRef::Enum(self.descriptor())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static file_descriptor_proto_data: &'static [u8] = b"\
|
||||||
|
\n\rversion.proto*#\n\x0cVersionProto\x12\x13\n\x0fINITIAL_RELEASE\x10\0\
|
||||||
|
JS\n\x06\x12\x04\x01\0\x05\x01\n\x08\n\x01\x0c\x12\x03\x01\0\x12\n\n\n\
|
||||||
|
\x02\x05\0\x12\x04\x03\0\x05\x01\n\n\n\x03\x05\0\x01\x12\x03\x03\x05\x11\
|
||||||
|
\n\x0b\n\x04\x05\0\x02\0\x12\x03\x04\x02\x16\n\x0c\n\x05\x05\0\x02\0\x01\
|
||||||
|
\x12\x03\x04\x02\x11\n\x0c\n\x05\x05\0\x02\0\x02\x12\x03\x04\x14\x15b\
|
||||||
|
\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()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
9
src/proto/wrapped/mod.rs
Normal file
9
src/proto/wrapped/mod.rs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#[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;
|
||||||
|
|
||||||
|
pub use super::version;
|
328
src/proto/wrapped/secret.rs
Normal file
328
src/proto/wrapped/secret.rs
Normal file
@ -0,0 +1,328 @@
|
|||||||
|
// 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<u8>,
|
||||||
|
pub mime_type: ::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 SecretProto {}
|
||||||
|
|
||||||
|
impl SecretProto {
|
||||||
|
pub fn new() -> SecretProto {
|
||||||
|
::std::default::Default::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn default_instance() -> &'static SecretProto {
|
||||||
|
static mut instance: ::protobuf::lazy::Lazy<SecretProto> = ::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<u8>) {
|
||||||
|
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<u8> {
|
||||||
|
&mut self.secret
|
||||||
|
}
|
||||||
|
|
||||||
|
// Take field
|
||||||
|
pub fn take_secret(&mut self) -> ::std::vec::Vec<u8> {
|
||||||
|
::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<u8> {
|
||||||
|
&self.secret
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mut_secret_for_reflect(&mut self) -> &mut ::std::vec::Vec<u8> {
|
||||||
|
&mut self.secret
|
||||||
|
}
|
||||||
|
|
||||||
|
// string mime_type = 3;
|
||||||
|
|
||||||
|
pub fn clear_mime_type(&mut self) {
|
||||||
|
self.mime_type.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Param is passed by value, moved
|
||||||
|
pub fn set_mime_type(&mut self, v: ::std::string::String) {
|
||||||
|
self.mime_type = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mutable pointer to the field.
|
||||||
|
// If field is not initialized, it is initialized with default value first.
|
||||||
|
pub fn mut_mime_type(&mut self) -> &mut ::std::string::String {
|
||||||
|
&mut self.mime_type
|
||||||
|
}
|
||||||
|
|
||||||
|
// Take field
|
||||||
|
pub fn take_mime_type(&mut self) -> ::std::string::String {
|
||||||
|
::std::mem::replace(&mut self.mime_type, ::std::string::String::new())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_mime_type(&self) -> &str {
|
||||||
|
&self.mime_type
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_mime_type_for_reflect(&self) -> &::std::string::String {
|
||||||
|
&self.mime_type
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mut_mime_type_for_reflect(&mut self) -> &mut ::std::string::String {
|
||||||
|
&mut self.mime_type
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ::protobuf::Message for SecretProto {
|
||||||
|
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 => {
|
||||||
|
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_proto3_string_into(wire_type, is, &mut self.mime_type)?;
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
::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 !self.mime_type.is_empty() {
|
||||||
|
my_size += ::protobuf::rt::string_size(3, &self.mime_type);
|
||||||
|
}
|
||||||
|
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 !self.mime_type.is_empty() {
|
||||||
|
os.write_string(3, &self.mime_type)?;
|
||||||
|
}
|
||||||
|
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<Self>) -> ::std::boxed::Box<::std::any::Any> {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
|
||||||
|
::protobuf::MessageStatic::descriptor_static(None::<Self>)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ::protobuf::MessageStatic for SecretProto {
|
||||||
|
fn new() -> SecretProto {
|
||||||
|
SecretProto::new()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn descriptor_static(_: ::std::option::Option<SecretProto>) -> &'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<super::version::VersionProto>>(
|
||||||
|
"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_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
|
||||||
|
"mime_type",
|
||||||
|
SecretProto::get_mime_type_for_reflect,
|
||||||
|
SecretProto::mut_mime_type_for_reflect,
|
||||||
|
));
|
||||||
|
::protobuf::reflect::MessageDescriptor::new::<SecretProto>(
|
||||||
|
"SecretProto",
|
||||||
|
fields,
|
||||||
|
file_descriptor_proto()
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ::protobuf::Clear for SecretProto {
|
||||||
|
fn clear(&mut self) {
|
||||||
|
self.clear_version();
|
||||||
|
self.clear_secret();
|
||||||
|
self.clear_mime_type();
|
||||||
|
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\x14wrapped/secret.proto\x12\x07wrapped\x1a\rversion.proto\"k\n\x0bSec\
|
||||||
|
retProto\x12'\n\x07version\x18\x01\x20\x01(\x0e2\r.VersionProtoR\x07vers\
|
||||||
|
ion\x12\x16\n\x06secret\x18\x02\x20\x01(\x0cR\x06secret\x12\x1b\n\tmime_\
|
||||||
|
type\x18\x03\x20\x01(\tR\x08mimeTypeJ\x91\x02\n\x06\x12\x04\0\0\n\x01\n\
|
||||||
|
\x08\n\x01\x0c\x12\x03\0\0\x12\n\x08\n\x01\x02\x12\x03\x02\x08\x0f\n\t\n\
|
||||||
|
\x02\x03\0\x12\x03\x04\x07\x16\n\n\n\x02\x04\0\x12\x04\x06\0\n\x01\n\n\n\
|
||||||
|
\x03\x04\0\x01\x12\x03\x06\x08\x13\n\x0b\n\x04\x04\0\x02\0\x12\x03\x07\
|
||||||
|
\x08!\n\r\n\x05\x04\0\x02\0\x04\x12\x04\x07\x08\x06\x15\n\x0c\n\x05\x04\
|
||||||
|
\0\x02\0\x06\x12\x03\x07\x08\x14\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\x07\
|
||||||
|
\x15\x1c\n\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x07\x1f\x20\n\x0b\n\x04\x04\
|
||||||
|
\0\x02\x01\x12\x03\x08\x08\x19\n\r\n\x05\x04\0\x02\x01\x04\x12\x04\x08\
|
||||||
|
\x08\x07!\n\x0c\n\x05\x04\0\x02\x01\x05\x12\x03\x08\x08\r\n\x0c\n\x05\
|
||||||
|
\x04\0\x02\x01\x01\x12\x03\x08\x0e\x14\n\x0c\n\x05\x04\0\x02\x01\x03\x12\
|
||||||
|
\x03\x08\x17\x18\n\x0b\n\x04\x04\0\x02\x02\x12\x03\t\x08\x1d\n\r\n\x05\
|
||||||
|
\x04\0\x02\x02\x04\x12\x04\t\x08\x08\x19\n\x0c\n\x05\x04\0\x02\x02\x05\
|
||||||
|
\x12\x03\t\x08\x0e\n\x0c\n\x05\x04\0\x02\x02\x01\x12\x03\t\x0f\x18\n\x0c\
|
||||||
|
\n\x05\x04\0\x02\x02\x03\x12\x03\t\x1b\x1cb\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()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
333
src/proto/wrapped/share.rs
Normal file
333
src/proto/wrapped/share.rs
Normal file
@ -0,0 +1,333 @@
|
|||||||
|
// 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 shamir_data: ::std::vec::Vec<u8>,
|
||||||
|
pub signature: ::protobuf::RepeatedField<::std::vec::Vec<u8>>,
|
||||||
|
pub proof: ::std::vec::Vec<u8>,
|
||||||
|
// 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<ShareProto> = ::protobuf::lazy::Lazy {
|
||||||
|
lock: ::protobuf::lazy::ONCE_INIT,
|
||||||
|
ptr: 0 as *const ShareProto,
|
||||||
|
};
|
||||||
|
unsafe {
|
||||||
|
instance.get(ShareProto::new)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// bytes shamir_data = 1;
|
||||||
|
|
||||||
|
pub fn clear_shamir_data(&mut self) {
|
||||||
|
self.shamir_data.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Param is passed by value, moved
|
||||||
|
pub fn set_shamir_data(&mut self, v: ::std::vec::Vec<u8>) {
|
||||||
|
self.shamir_data = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mutable pointer to the field.
|
||||||
|
// If field is not initialized, it is initialized with default value first.
|
||||||
|
pub fn mut_shamir_data(&mut self) -> &mut ::std::vec::Vec<u8> {
|
||||||
|
&mut self.shamir_data
|
||||||
|
}
|
||||||
|
|
||||||
|
// Take field
|
||||||
|
pub fn take_shamir_data(&mut self) -> ::std::vec::Vec<u8> {
|
||||||
|
::std::mem::replace(&mut self.shamir_data, ::std::vec::Vec::new())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_shamir_data(&self) -> &[u8] {
|
||||||
|
&self.shamir_data
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_shamir_data_for_reflect(&self) -> &::std::vec::Vec<u8> {
|
||||||
|
&self.shamir_data
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mut_shamir_data_for_reflect(&mut self) -> &mut ::std::vec::Vec<u8> {
|
||||||
|
&mut self.shamir_data
|
||||||
|
}
|
||||||
|
|
||||||
|
// repeated bytes signature = 2;
|
||||||
|
|
||||||
|
pub fn clear_signature(&mut self) {
|
||||||
|
self.signature.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Param is passed by value, moved
|
||||||
|
pub fn set_signature(&mut self, v: ::protobuf::RepeatedField<::std::vec::Vec<u8>>) {
|
||||||
|
self.signature = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mutable pointer to the field.
|
||||||
|
pub fn mut_signature(&mut self) -> &mut ::protobuf::RepeatedField<::std::vec::Vec<u8>> {
|
||||||
|
&mut self.signature
|
||||||
|
}
|
||||||
|
|
||||||
|
// Take field
|
||||||
|
pub fn take_signature(&mut self) -> ::protobuf::RepeatedField<::std::vec::Vec<u8>> {
|
||||||
|
::std::mem::replace(&mut self.signature, ::protobuf::RepeatedField::new())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_signature(&self) -> &[::std::vec::Vec<u8>] {
|
||||||
|
&self.signature
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_signature_for_reflect(&self) -> &::protobuf::RepeatedField<::std::vec::Vec<u8>> {
|
||||||
|
&self.signature
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mut_signature_for_reflect(&mut self) -> &mut ::protobuf::RepeatedField<::std::vec::Vec<u8>> {
|
||||||
|
&mut self.signature
|
||||||
|
}
|
||||||
|
|
||||||
|
// bytes proof = 3;
|
||||||
|
|
||||||
|
pub fn clear_proof(&mut self) {
|
||||||
|
self.proof.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Param is passed by value, moved
|
||||||
|
pub fn set_proof(&mut self, v: ::std::vec::Vec<u8>) {
|
||||||
|
self.proof = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mutable pointer to the field.
|
||||||
|
// If field is not initialized, it is initialized with default value first.
|
||||||
|
pub fn mut_proof(&mut self) -> &mut ::std::vec::Vec<u8> {
|
||||||
|
&mut self.proof
|
||||||
|
}
|
||||||
|
|
||||||
|
// Take field
|
||||||
|
pub fn take_proof(&mut self) -> ::std::vec::Vec<u8> {
|
||||||
|
::std::mem::replace(&mut self.proof, ::std::vec::Vec::new())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_proof(&self) -> &[u8] {
|
||||||
|
&self.proof
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_proof_for_reflect(&self) -> &::std::vec::Vec<u8> {
|
||||||
|
&self.proof
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mut_proof_for_reflect(&mut self) -> &mut ::std::vec::Vec<u8> {
|
||||||
|
&mut self.proof
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ::protobuf::Message for ShareProto {
|
||||||
|
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_singular_proto3_bytes_into(wire_type, is, &mut self.shamir_data)?;
|
||||||
|
},
|
||||||
|
2 => {
|
||||||
|
::protobuf::rt::read_repeated_bytes_into(wire_type, is, &mut self.signature)?;
|
||||||
|
},
|
||||||
|
3 => {
|
||||||
|
::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.proof)?;
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
::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.shamir_data.is_empty() {
|
||||||
|
my_size += ::protobuf::rt::bytes_size(1, &self.shamir_data);
|
||||||
|
}
|
||||||
|
for value in &self.signature {
|
||||||
|
my_size += ::protobuf::rt::bytes_size(2, &value);
|
||||||
|
};
|
||||||
|
if !self.proof.is_empty() {
|
||||||
|
my_size += ::protobuf::rt::bytes_size(3, &self.proof);
|
||||||
|
}
|
||||||
|
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.shamir_data.is_empty() {
|
||||||
|
os.write_bytes(1, &self.shamir_data)?;
|
||||||
|
}
|
||||||
|
for v in &self.signature {
|
||||||
|
os.write_bytes(2, &v)?;
|
||||||
|
};
|
||||||
|
if !self.proof.is_empty() {
|
||||||
|
os.write_bytes(3, &self.proof)?;
|
||||||
|
}
|
||||||
|
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<Self>) -> ::std::boxed::Box<::std::any::Any> {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
|
||||||
|
::protobuf::MessageStatic::descriptor_static(None::<Self>)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ::protobuf::MessageStatic for ShareProto {
|
||||||
|
fn new() -> ShareProto {
|
||||||
|
ShareProto::new()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn descriptor_static(_: ::std::option::Option<ShareProto>) -> &'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::ProtobufTypeBytes>(
|
||||||
|
"shamir_data",
|
||||||
|
ShareProto::get_shamir_data_for_reflect,
|
||||||
|
ShareProto::mut_shamir_data_for_reflect,
|
||||||
|
));
|
||||||
|
fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
|
||||||
|
"signature",
|
||||||
|
ShareProto::get_signature_for_reflect,
|
||||||
|
ShareProto::mut_signature_for_reflect,
|
||||||
|
));
|
||||||
|
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
|
||||||
|
"proof",
|
||||||
|
ShareProto::get_proof_for_reflect,
|
||||||
|
ShareProto::mut_proof_for_reflect,
|
||||||
|
));
|
||||||
|
::protobuf::reflect::MessageDescriptor::new::<ShareProto>(
|
||||||
|
"ShareProto",
|
||||||
|
fields,
|
||||||
|
file_descriptor_proto()
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ::protobuf::Clear for ShareProto {
|
||||||
|
fn clear(&mut self) {
|
||||||
|
self.clear_shamir_data();
|
||||||
|
self.clear_signature();
|
||||||
|
self.clear_proof();
|
||||||
|
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\x13wrapped/share.proto\x12\x07wrapped\"a\n\nShareProto\x12\x1f\n\x0bs\
|
||||||
|
hamir_data\x18\x01\x20\x01(\x0cR\nshamirData\x12\x1c\n\tsignature\x18\
|
||||||
|
\x02\x20\x03(\x0cR\tsignature\x12\x14\n\x05proof\x18\x03\x20\x01(\x0cR\
|
||||||
|
\x05proofJ\x85\x02\n\x06\x12\x04\0\0\x08\x01\n\x08\n\x01\x0c\x12\x03\0\0\
|
||||||
|
\x12\n\x08\n\x01\x02\x12\x03\x02\x08\x0f\n\n\n\x02\x04\0\x12\x04\x04\0\
|
||||||
|
\x08\x01\n\n\n\x03\x04\0\x01\x12\x03\x04\x08\x12\n\x0b\n\x04\x04\0\x02\0\
|
||||||
|
\x12\x03\x05\x08\x1e\n\r\n\x05\x04\0\x02\0\x04\x12\x04\x05\x08\x04\x14\n\
|
||||||
|
\x0c\n\x05\x04\0\x02\0\x05\x12\x03\x05\x08\r\n\x0c\n\x05\x04\0\x02\0\x01\
|
||||||
|
\x12\x03\x05\x0e\x19\n\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x05\x1c\x1d\n\
|
||||||
|
\x0b\n\x04\x04\0\x02\x01\x12\x03\x06\x08%\n\x0c\n\x05\x04\0\x02\x01\x04\
|
||||||
|
\x12\x03\x06\x08\x10\n\x0c\n\x05\x04\0\x02\x01\x05\x12\x03\x06\x11\x16\n\
|
||||||
|
\x0c\n\x05\x04\0\x02\x01\x01\x12\x03\x06\x17\x20\n\x0c\n\x05\x04\0\x02\
|
||||||
|
\x01\x03\x12\x03\x06#$\n\x0b\n\x04\x04\0\x02\x02\x12\x03\x07\x08\x18\n\r\
|
||||||
|
\n\x05\x04\0\x02\x02\x04\x12\x04\x07\x08\x06%\n\x0c\n\x05\x04\0\x02\x02\
|
||||||
|
\x05\x12\x03\x07\x08\r\n\x0c\n\x05\x04\0\x02\x02\x01\x12\x03\x07\x0e\x13\
|
||||||
|
\n\x0c\n\x05\x04\0\x02\x02\x03\x12\x03\x07\x16\x17b\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()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
391
src/secret.rs
391
src/secret.rs
@ -1,391 +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(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(Clone,Default)]
|
|
||||||
pub struct RustySecret {
|
|
||||||
// message fields
|
|
||||||
version: ::std::option::Option<RustySecretsVersions>,
|
|
||||||
secret: ::protobuf::SingularField<::std::vec::Vec<u8>>,
|
|
||||||
mime_type: ::protobuf::SingularField<::std::string::String>,
|
|
||||||
// special fields
|
|
||||||
unknown_fields: ::protobuf::UnknownFields,
|
|
||||||
cached_size: ::std::cell::Cell<u32>,
|
|
||||||
}
|
|
||||||
|
|
||||||
// see codegen.rs for the explanation why impl Sync explicitly
|
|
||||||
unsafe impl ::std::marker::Sync for RustySecret {}
|
|
||||||
|
|
||||||
impl RustySecret {
|
|
||||||
pub fn new() -> RustySecret {
|
|
||||||
::std::default::Default::default()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn default_instance() -> &'static RustySecret {
|
|
||||||
static mut instance: ::protobuf::lazy::Lazy<RustySecret> = ::protobuf::lazy::Lazy {
|
|
||||||
lock: ::protobuf::lazy::ONCE_INIT,
|
|
||||||
ptr: 0 as *const RustySecret,
|
|
||||||
};
|
|
||||||
unsafe {
|
|
||||||
instance.get(|| {
|
|
||||||
RustySecret {
|
|
||||||
version: ::std::option::Option::None,
|
|
||||||
secret: ::protobuf::SingularField::none(),
|
|
||||||
mime_type: ::protobuf::SingularField::none(),
|
|
||||||
unknown_fields: ::protobuf::UnknownFields::new(),
|
|
||||||
cached_size: ::std::cell::Cell::new(0),
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// optional .RustySecretsVersions version = 1;
|
|
||||||
|
|
||||||
pub fn clear_version(&mut self) {
|
|
||||||
self.version = ::std::option::Option::None;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn has_version(&self) -> bool {
|
|
||||||
self.version.is_some()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Param is passed by value, moved
|
|
||||||
pub fn set_version(&mut self, v: RustySecretsVersions) {
|
|
||||||
self.version = ::std::option::Option::Some(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_version(&self) -> RustySecretsVersions {
|
|
||||||
self.version.unwrap_or(RustySecretsVersions::INITIAL_RELEASE)
|
|
||||||
}
|
|
||||||
|
|
||||||
// optional bytes secret = 2;
|
|
||||||
|
|
||||||
pub fn clear_secret(&mut self) {
|
|
||||||
self.secret.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn has_secret(&self) -> bool {
|
|
||||||
self.secret.is_some()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Param is passed by value, moved
|
|
||||||
pub fn set_secret(&mut self, v: ::std::vec::Vec<u8>) {
|
|
||||||
self.secret = ::protobuf::SingularField::some(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<u8> {
|
|
||||||
if self.secret.is_none() {
|
|
||||||
self.secret.set_default();
|
|
||||||
};
|
|
||||||
self.secret.as_mut().unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Take field
|
|
||||||
pub fn take_secret(&mut self) -> ::std::vec::Vec<u8> {
|
|
||||||
self.secret.take().unwrap_or_else(|| ::std::vec::Vec::new())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_secret(&self) -> &[u8] {
|
|
||||||
match self.secret.as_ref() {
|
|
||||||
Some(v) => &v,
|
|
||||||
None => &[],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// optional string mime_type = 3;
|
|
||||||
|
|
||||||
pub fn clear_mime_type(&mut self) {
|
|
||||||
self.mime_type.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn has_mime_type(&self) -> bool {
|
|
||||||
self.mime_type.is_some()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Param is passed by value, moved
|
|
||||||
pub fn set_mime_type(&mut self, v: ::std::string::String) {
|
|
||||||
self.mime_type = ::protobuf::SingularField::some(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mutable pointer to the field.
|
|
||||||
// If field is not initialized, it is initialized with default value first.
|
|
||||||
pub fn mut_mime_type(&mut self) -> &mut ::std::string::String {
|
|
||||||
if self.mime_type.is_none() {
|
|
||||||
self.mime_type.set_default();
|
|
||||||
};
|
|
||||||
self.mime_type.as_mut().unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Take field
|
|
||||||
pub fn take_mime_type(&mut self) -> ::std::string::String {
|
|
||||||
self.mime_type.take().unwrap_or_else(|| ::std::string::String::new())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_mime_type(&self) -> &str {
|
|
||||||
match self.mime_type.as_ref() {
|
|
||||||
Some(v) => &v,
|
|
||||||
None => "",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ::protobuf::Message for RustySecret {
|
|
||||||
fn is_initialized(&self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> {
|
|
||||||
while !try!(is.eof()) {
|
|
||||||
let (field_number, wire_type) = try!(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 = try!(is.read_enum());
|
|
||||||
self.version = ::std::option::Option::Some(tmp);
|
|
||||||
},
|
|
||||||
2 => {
|
|
||||||
try!(::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.secret));
|
|
||||||
},
|
|
||||||
3 => {
|
|
||||||
try!(::protobuf::rt::read_singular_string_into(wire_type, is, &mut self.mime_type));
|
|
||||||
},
|
|
||||||
_ => {
|
|
||||||
try!(::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;
|
|
||||||
for value in &self.version {
|
|
||||||
my_size += ::protobuf::rt::enum_size(1, *value);
|
|
||||||
};
|
|
||||||
for value in &self.secret {
|
|
||||||
my_size += ::protobuf::rt::bytes_size(2, &value);
|
|
||||||
};
|
|
||||||
for value in &self.mime_type {
|
|
||||||
my_size += ::protobuf::rt::string_size(3, &value);
|
|
||||||
};
|
|
||||||
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 let Some(v) = self.version {
|
|
||||||
try!(os.write_enum(1, v.value()));
|
|
||||||
};
|
|
||||||
if let Some(v) = self.secret.as_ref() {
|
|
||||||
try!(os.write_bytes(2, &v));
|
|
||||||
};
|
|
||||||
if let Some(v) = self.mime_type.as_ref() {
|
|
||||||
try!(os.write_string(3, &v));
|
|
||||||
};
|
|
||||||
try!(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 type_id(&self) -> ::std::any::TypeId {
|
|
||||||
::std::any::TypeId::of::<RustySecret>()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_any(&self) -> &::std::any::Any {
|
|
||||||
self as &::std::any::Any
|
|
||||||
}
|
|
||||||
|
|
||||||
fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
|
|
||||||
::protobuf::MessageStatic::descriptor_static(None::<Self>)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ::protobuf::MessageStatic for RustySecret {
|
|
||||||
fn new() -> RustySecret {
|
|
||||||
RustySecret::new()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn descriptor_static(_: ::std::option::Option<RustySecret>) -> &'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_singular_enum_accessor(
|
|
||||||
"version",
|
|
||||||
RustySecret::has_version,
|
|
||||||
RustySecret::get_version,
|
|
||||||
));
|
|
||||||
fields.push(::protobuf::reflect::accessor::make_singular_bytes_accessor(
|
|
||||||
"secret",
|
|
||||||
RustySecret::has_secret,
|
|
||||||
RustySecret::get_secret,
|
|
||||||
));
|
|
||||||
fields.push(::protobuf::reflect::accessor::make_singular_string_accessor(
|
|
||||||
"mime_type",
|
|
||||||
RustySecret::has_mime_type,
|
|
||||||
RustySecret::get_mime_type,
|
|
||||||
));
|
|
||||||
::protobuf::reflect::MessageDescriptor::new::<RustySecret>(
|
|
||||||
"RustySecret",
|
|
||||||
fields,
|
|
||||||
file_descriptor_proto()
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ::protobuf::Clear for RustySecret {
|
|
||||||
fn clear(&mut self) {
|
|
||||||
self.clear_version();
|
|
||||||
self.clear_secret();
|
|
||||||
self.clear_mime_type();
|
|
||||||
self.unknown_fields.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ::std::cmp::PartialEq for RustySecret {
|
|
||||||
fn eq(&self, other: &RustySecret) -> bool {
|
|
||||||
self.version == other.version &&
|
|
||||||
self.secret == other.secret &&
|
|
||||||
self.mime_type == other.mime_type &&
|
|
||||||
self.unknown_fields == other.unknown_fields
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ::std::fmt::Debug for RustySecret {
|
|
||||||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
|
||||||
::protobuf::text_format::fmt(self, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone,PartialEq,Eq,Debug,Hash)]
|
|
||||||
pub enum RustySecretsVersions {
|
|
||||||
INITIAL_RELEASE = 0,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ::protobuf::ProtobufEnum for RustySecretsVersions {
|
|
||||||
fn value(&self) -> i32 {
|
|
||||||
*self as i32
|
|
||||||
}
|
|
||||||
|
|
||||||
fn from_i32(value: i32) -> ::std::option::Option<RustySecretsVersions> {
|
|
||||||
match value {
|
|
||||||
0 => ::std::option::Option::Some(RustySecretsVersions::INITIAL_RELEASE),
|
|
||||||
_ => ::std::option::Option::None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn values() -> &'static [Self] {
|
|
||||||
static values: &'static [RustySecretsVersions] = &[
|
|
||||||
RustySecretsVersions::INITIAL_RELEASE,
|
|
||||||
];
|
|
||||||
values
|
|
||||||
}
|
|
||||||
|
|
||||||
fn enum_descriptor_static(_: Option<RustySecretsVersions>) -> &'static ::protobuf::reflect::EnumDescriptor {
|
|
||||||
static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::EnumDescriptor> = ::protobuf::lazy::Lazy {
|
|
||||||
lock: ::protobuf::lazy::ONCE_INIT,
|
|
||||||
ptr: 0 as *const ::protobuf::reflect::EnumDescriptor,
|
|
||||||
};
|
|
||||||
unsafe {
|
|
||||||
descriptor.get(|| {
|
|
||||||
::protobuf::reflect::EnumDescriptor::new("RustySecretsVersions", file_descriptor_proto())
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ::std::marker::Copy for RustySecretsVersions {
|
|
||||||
}
|
|
||||||
|
|
||||||
static file_descriptor_proto_data: &'static [u8] = &[
|
|
||||||
0x0a, 0x0c, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x73,
|
|
||||||
0x0a, 0x0b, 0x52, 0x75, 0x73, 0x74, 0x79, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x2f, 0x0a,
|
|
||||||
0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15,
|
|
||||||
0x2e, 0x52, 0x75, 0x73, 0x74, 0x79, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x56, 0x65, 0x72,
|
|
||||||
0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16,
|
|
||||||
0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06,
|
|
||||||
0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x69, 0x6d, 0x65, 0x5f, 0x74,
|
|
||||||
0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x69, 0x6d, 0x65, 0x54,
|
|
||||||
0x79, 0x70, 0x65, 0x2a, 0x2b, 0x0a, 0x14, 0x52, 0x75, 0x73, 0x74, 0x79, 0x53, 0x65, 0x63, 0x72,
|
|
||||||
0x65, 0x74, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x13, 0x0a, 0x0f, 0x49,
|
|
||||||
0x4e, 0x49, 0x54, 0x49, 0x41, 0x4c, 0x5f, 0x52, 0x45, 0x4c, 0x45, 0x41, 0x53, 0x45, 0x10, 0x00,
|
|
||||||
0x4a, 0xbd, 0x02, 0x0a, 0x06, 0x12, 0x04, 0x00, 0x00, 0x0a, 0x01, 0x0a, 0x08, 0x0a, 0x01, 0x0c,
|
|
||||||
0x12, 0x03, 0x00, 0x00, 0x12, 0x0a, 0x0a, 0x0a, 0x02, 0x05, 0x00, 0x12, 0x04, 0x02, 0x00, 0x04,
|
|
||||||
0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x05, 0x00, 0x01, 0x12, 0x03, 0x02, 0x05, 0x19, 0x0a, 0x0b, 0x0a,
|
|
||||||
0x04, 0x05, 0x00, 0x02, 0x00, 0x12, 0x03, 0x03, 0x08, 0x1c, 0x0a, 0x0c, 0x0a, 0x05, 0x05, 0x00,
|
|
||||||
0x02, 0x00, 0x01, 0x12, 0x03, 0x03, 0x08, 0x17, 0x0a, 0x0c, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x00,
|
|
||||||
0x02, 0x12, 0x03, 0x03, 0x1a, 0x1b, 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x00, 0x12, 0x04, 0x06, 0x00,
|
|
||||||
0x0a, 0x01, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x00, 0x01, 0x12, 0x03, 0x06, 0x08, 0x13, 0x0a, 0x0b,
|
|
||||||
0x0a, 0x04, 0x04, 0x00, 0x02, 0x00, 0x12, 0x03, 0x07, 0x08, 0x29, 0x0a, 0x0d, 0x0a, 0x05, 0x04,
|
|
||||||
0x00, 0x02, 0x00, 0x04, 0x12, 0x04, 0x07, 0x08, 0x06, 0x15, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00,
|
|
||||||
0x02, 0x00, 0x06, 0x12, 0x03, 0x07, 0x08, 0x1c, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00,
|
|
||||||
0x01, 0x12, 0x03, 0x07, 0x1d, 0x24, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x03, 0x12,
|
|
||||||
0x03, 0x07, 0x27, 0x28, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x01, 0x12, 0x03, 0x08, 0x08,
|
|
||||||
0x19, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x04, 0x12, 0x04, 0x08, 0x08, 0x07, 0x29,
|
|
||||||
0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x05, 0x12, 0x03, 0x08, 0x08, 0x0d, 0x0a, 0x0c,
|
|
||||||
0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x03, 0x08, 0x0e, 0x14, 0x0a, 0x0c, 0x0a, 0x05,
|
|
||||||
0x04, 0x00, 0x02, 0x01, 0x03, 0x12, 0x03, 0x08, 0x17, 0x18, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x00,
|
|
||||||
0x02, 0x02, 0x12, 0x03, 0x09, 0x08, 0x1d, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x04,
|
|
||||||
0x12, 0x04, 0x09, 0x08, 0x08, 0x19, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x05, 0x12,
|
|
||||||
0x03, 0x09, 0x08, 0x0e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x03, 0x09,
|
|
||||||
0x0f, 0x18, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x03, 0x12, 0x03, 0x09, 0x1b, 0x1c,
|
|
||||||
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
|
||||||
];
|
|
||||||
|
|
||||||
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()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
40
src/share/mod.rs
Normal file
40
src/share/mod.rs
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
//! Define the traits used to distinguish the various
|
||||||
|
//! kind of shares internally used by the library.
|
||||||
|
//! These traits are currently not exposed, but this might
|
||||||
|
//! change in the future.
|
||||||
|
|
||||||
|
use errors::*;
|
||||||
|
|
||||||
|
pub(crate) mod validation;
|
||||||
|
|
||||||
|
/// All types of share should implement this trait.
|
||||||
|
pub(crate) trait IsShare: Sized {
|
||||||
|
/// Returns the identifier of the share.
|
||||||
|
/// Varies between 1 and n where n is the total number of generated shares.
|
||||||
|
fn get_id(&self) -> u8;
|
||||||
|
|
||||||
|
/// Returns the share data itself
|
||||||
|
fn get_data(&self) -> &[u8];
|
||||||
|
|
||||||
|
/// Returns the number of shares necessary to recover the secret, aka the threshold
|
||||||
|
fn get_threshold(&self) -> u8;
|
||||||
|
|
||||||
|
/// Returns the total number of shares that have been dealt
|
||||||
|
fn get_shares_count(&self) -> Option<u8>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This trait must be implemented by shares' types wich can be signed.
|
||||||
|
pub(crate) trait IsSignedShare: IsShare {
|
||||||
|
/// The type of shares' sigature.
|
||||||
|
type Signature;
|
||||||
|
|
||||||
|
/// Returns whether this share is signed or not.
|
||||||
|
fn is_signed(&self) -> bool;
|
||||||
|
|
||||||
|
/// Return the signature itself.
|
||||||
|
fn get_signature(&self) -> &Self::Signature;
|
||||||
|
|
||||||
|
/// Verify the signatures of the given batch of shares.
|
||||||
|
/// Returns `Ok(())` if validation succeeds, and an `Err` otherwise.
|
||||||
|
fn verify_signatures(shares: &[Self]) -> Result<()>;
|
||||||
|
}
|
113
src/share/validation.rs
Normal file
113
src/share/validation.rs
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
use std::collections::{HashMap, HashSet};
|
||||||
|
|
||||||
|
use errors::*;
|
||||||
|
use share::{IsShare, IsSignedShare};
|
||||||
|
|
||||||
|
// The order of validation that we think makes the most sense is the following:
|
||||||
|
// 1) Validate shares individually
|
||||||
|
// 2) Validate duplicate shares share num && data
|
||||||
|
// 2) Validate group consistency
|
||||||
|
// 3) Validate other properties, in no specific order
|
||||||
|
|
||||||
|
/// TODO: Doc
|
||||||
|
pub(crate) fn validate_signed_shares<S: IsSignedShare>(
|
||||||
|
shares: Vec<S>,
|
||||||
|
verify_signatures: bool,
|
||||||
|
) -> Result<(u8, Vec<S>)> {
|
||||||
|
let (threshold, shares) = validate_shares(shares)?;
|
||||||
|
|
||||||
|
if verify_signatures {
|
||||||
|
S::verify_signatures(&shares)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok((threshold, shares))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// TODO: Doc
|
||||||
|
pub(crate) fn validate_shares<S: IsShare>(shares: Vec<S>) -> Result<(u8, Vec<S>)> {
|
||||||
|
if shares.is_empty() {
|
||||||
|
bail!(ErrorKind::EmptyShares);
|
||||||
|
}
|
||||||
|
|
||||||
|
let shares_count = shares.len();
|
||||||
|
let mut result: Vec<S> = Vec::with_capacity(shares_count);
|
||||||
|
|
||||||
|
let mut k_compatibility_sets = HashMap::new();
|
||||||
|
|
||||||
|
for share in shares {
|
||||||
|
let (id, threshold) = (share.get_id(), share.get_threshold());
|
||||||
|
|
||||||
|
if id > MAX_SHARES {
|
||||||
|
bail!(ErrorKind::ShareIdentifierTooBig(id, MAX_SHARES))
|
||||||
|
}
|
||||||
|
|
||||||
|
if id < 1 {
|
||||||
|
bail!(ErrorKind::ShareParsingInvalidShareId(id))
|
||||||
|
}
|
||||||
|
|
||||||
|
k_compatibility_sets
|
||||||
|
.entry(threshold)
|
||||||
|
.or_insert_with(HashSet::new);
|
||||||
|
let k_set = k_compatibility_sets.get_mut(&threshold).unwrap();
|
||||||
|
k_set.insert(id);
|
||||||
|
|
||||||
|
if result.iter().any(|s| s.get_id() == id) {
|
||||||
|
bail!(ErrorKind::DuplicateShareId(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
if share.get_data().is_empty() {
|
||||||
|
bail!(ErrorKind::ShareParsingErrorEmptyShare(id))
|
||||||
|
}
|
||||||
|
|
||||||
|
if result.iter().any(|s| s.get_data() == share.get_data()) && share.get_threshold() != 1 {
|
||||||
|
// When threshold = 1, shares data can be the same
|
||||||
|
bail!(ErrorKind::DuplicateShareData(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
result.push(share);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate threshold
|
||||||
|
let k_sets = k_compatibility_sets.keys().count();
|
||||||
|
|
||||||
|
match k_sets {
|
||||||
|
0 => bail!(ErrorKind::EmptyShares),
|
||||||
|
1 => {} // All shares have the same roothash.
|
||||||
|
_ => {
|
||||||
|
bail! {
|
||||||
|
ErrorKind::IncompatibleSets(
|
||||||
|
k_compatibility_sets
|
||||||
|
.values()
|
||||||
|
.map(|x| x.to_owned())
|
||||||
|
.collect(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// It is safe to unwrap because k_sets == 1
|
||||||
|
let threshold = k_compatibility_sets.keys().last().unwrap().to_owned();
|
||||||
|
|
||||||
|
if shares_count < threshold as usize {
|
||||||
|
bail!(ErrorKind::MissingShares(threshold as usize, shares_count));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok((threshold, result))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn validate_share_count(threshold: u8, shares_count: u8) -> Result<(u8, u8)> {
|
||||||
|
if threshold < MIN_SHARES {
|
||||||
|
bail!(ErrorKind::ThresholdTooSmall(threshold));
|
||||||
|
}
|
||||||
|
if shares_count > MAX_SHARES {
|
||||||
|
bail!(ErrorKind::InvalidShareCountMax(shares_count, MAX_SHARES));
|
||||||
|
}
|
||||||
|
if shares_count < MIN_SHARES {
|
||||||
|
bail!(ErrorKind::InvalidShareCountMin(shares_count, MIN_SHARES));
|
||||||
|
}
|
||||||
|
if threshold > shares_count {
|
||||||
|
bail!(ErrorKind::ThresholdTooBig(threshold, shares_count));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok((threshold, shares_count))
|
||||||
|
}
|
@ -1,345 +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(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(Clone,Default)]
|
|
||||||
pub struct ShareData {
|
|
||||||
// message fields
|
|
||||||
shamir_data: ::protobuf::SingularField<::std::vec::Vec<u8>>,
|
|
||||||
signature: ::protobuf::RepeatedField<::std::vec::Vec<u8>>,
|
|
||||||
proof: ::protobuf::SingularField<::std::vec::Vec<u8>>,
|
|
||||||
// special fields
|
|
||||||
unknown_fields: ::protobuf::UnknownFields,
|
|
||||||
cached_size: ::std::cell::Cell<u32>,
|
|
||||||
}
|
|
||||||
|
|
||||||
// see codegen.rs for the explanation why impl Sync explicitly
|
|
||||||
unsafe impl ::std::marker::Sync for ShareData {}
|
|
||||||
|
|
||||||
impl ShareData {
|
|
||||||
pub fn new() -> ShareData {
|
|
||||||
::std::default::Default::default()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn default_instance() -> &'static ShareData {
|
|
||||||
static mut instance: ::protobuf::lazy::Lazy<ShareData> = ::protobuf::lazy::Lazy {
|
|
||||||
lock: ::protobuf::lazy::ONCE_INIT,
|
|
||||||
ptr: 0 as *const ShareData,
|
|
||||||
};
|
|
||||||
unsafe {
|
|
||||||
instance.get(|| {
|
|
||||||
ShareData {
|
|
||||||
shamir_data: ::protobuf::SingularField::none(),
|
|
||||||
signature: ::protobuf::RepeatedField::new(),
|
|
||||||
proof: ::protobuf::SingularField::none(),
|
|
||||||
unknown_fields: ::protobuf::UnknownFields::new(),
|
|
||||||
cached_size: ::std::cell::Cell::new(0),
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// optional bytes shamir_data = 1;
|
|
||||||
|
|
||||||
pub fn clear_shamir_data(&mut self) {
|
|
||||||
self.shamir_data.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn has_shamir_data(&self) -> bool {
|
|
||||||
self.shamir_data.is_some()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Param is passed by value, moved
|
|
||||||
pub fn set_shamir_data(&mut self, v: ::std::vec::Vec<u8>) {
|
|
||||||
self.shamir_data = ::protobuf::SingularField::some(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mutable pointer to the field.
|
|
||||||
// If field is not initialized, it is initialized with default value first.
|
|
||||||
pub fn mut_shamir_data(&mut self) -> &mut ::std::vec::Vec<u8> {
|
|
||||||
if self.shamir_data.is_none() {
|
|
||||||
self.shamir_data.set_default();
|
|
||||||
};
|
|
||||||
self.shamir_data.as_mut().unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Take field
|
|
||||||
pub fn take_shamir_data(&mut self) -> ::std::vec::Vec<u8> {
|
|
||||||
self.shamir_data.take().unwrap_or_else(|| ::std::vec::Vec::new())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_shamir_data(&self) -> &[u8] {
|
|
||||||
match self.shamir_data.as_ref() {
|
|
||||||
Some(v) => &v,
|
|
||||||
None => &[],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// repeated bytes signature = 2;
|
|
||||||
|
|
||||||
pub fn clear_signature(&mut self) {
|
|
||||||
self.signature.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Param is passed by value, moved
|
|
||||||
pub fn set_signature(&mut self, v: ::protobuf::RepeatedField<::std::vec::Vec<u8>>) {
|
|
||||||
self.signature = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mutable pointer to the field.
|
|
||||||
pub fn mut_signature(&mut self) -> &mut ::protobuf::RepeatedField<::std::vec::Vec<u8>> {
|
|
||||||
&mut self.signature
|
|
||||||
}
|
|
||||||
|
|
||||||
// Take field
|
|
||||||
pub fn take_signature(&mut self) -> ::protobuf::RepeatedField<::std::vec::Vec<u8>> {
|
|
||||||
::std::mem::replace(&mut self.signature, ::protobuf::RepeatedField::new())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_signature(&self) -> &[::std::vec::Vec<u8>] {
|
|
||||||
&self.signature
|
|
||||||
}
|
|
||||||
|
|
||||||
// optional bytes proof = 3;
|
|
||||||
|
|
||||||
pub fn clear_proof(&mut self) {
|
|
||||||
self.proof.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn has_proof(&self) -> bool {
|
|
||||||
self.proof.is_some()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Param is passed by value, moved
|
|
||||||
pub fn set_proof(&mut self, v: ::std::vec::Vec<u8>) {
|
|
||||||
self.proof = ::protobuf::SingularField::some(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mutable pointer to the field.
|
|
||||||
// If field is not initialized, it is initialized with default value first.
|
|
||||||
pub fn mut_proof(&mut self) -> &mut ::std::vec::Vec<u8> {
|
|
||||||
if self.proof.is_none() {
|
|
||||||
self.proof.set_default();
|
|
||||||
};
|
|
||||||
self.proof.as_mut().unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Take field
|
|
||||||
pub fn take_proof(&mut self) -> ::std::vec::Vec<u8> {
|
|
||||||
self.proof.take().unwrap_or_else(|| ::std::vec::Vec::new())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_proof(&self) -> &[u8] {
|
|
||||||
match self.proof.as_ref() {
|
|
||||||
Some(v) => &v,
|
|
||||||
None => &[],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ::protobuf::Message for ShareData {
|
|
||||||
fn is_initialized(&self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream) -> ::protobuf::ProtobufResult<()> {
|
|
||||||
while !try!(is.eof()) {
|
|
||||||
let (field_number, wire_type) = try!(is.read_tag_unpack());
|
|
||||||
match field_number {
|
|
||||||
1 => {
|
|
||||||
try!(::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.shamir_data));
|
|
||||||
},
|
|
||||||
2 => {
|
|
||||||
try!(::protobuf::rt::read_repeated_bytes_into(wire_type, is, &mut self.signature));
|
|
||||||
},
|
|
||||||
3 => {
|
|
||||||
try!(::protobuf::rt::read_singular_bytes_into(wire_type, is, &mut self.proof));
|
|
||||||
},
|
|
||||||
_ => {
|
|
||||||
try!(::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;
|
|
||||||
for value in &self.shamir_data {
|
|
||||||
my_size += ::protobuf::rt::bytes_size(1, &value);
|
|
||||||
};
|
|
||||||
for value in &self.signature {
|
|
||||||
my_size += ::protobuf::rt::bytes_size(2, &value);
|
|
||||||
};
|
|
||||||
for value in &self.proof {
|
|
||||||
my_size += ::protobuf::rt::bytes_size(3, &value);
|
|
||||||
};
|
|
||||||
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 let Some(v) = self.shamir_data.as_ref() {
|
|
||||||
try!(os.write_bytes(1, &v));
|
|
||||||
};
|
|
||||||
for v in &self.signature {
|
|
||||||
try!(os.write_bytes(2, &v));
|
|
||||||
};
|
|
||||||
if let Some(v) = self.proof.as_ref() {
|
|
||||||
try!(os.write_bytes(3, &v));
|
|
||||||
};
|
|
||||||
try!(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 type_id(&self) -> ::std::any::TypeId {
|
|
||||||
::std::any::TypeId::of::<ShareData>()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_any(&self) -> &::std::any::Any {
|
|
||||||
self as &::std::any::Any
|
|
||||||
}
|
|
||||||
|
|
||||||
fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor {
|
|
||||||
::protobuf::MessageStatic::descriptor_static(None::<Self>)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ::protobuf::MessageStatic for ShareData {
|
|
||||||
fn new() -> ShareData {
|
|
||||||
ShareData::new()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn descriptor_static(_: ::std::option::Option<ShareData>) -> &'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_singular_bytes_accessor(
|
|
||||||
"shamir_data",
|
|
||||||
ShareData::has_shamir_data,
|
|
||||||
ShareData::get_shamir_data,
|
|
||||||
));
|
|
||||||
fields.push(::protobuf::reflect::accessor::make_repeated_bytes_accessor(
|
|
||||||
"signature",
|
|
||||||
ShareData::get_signature,
|
|
||||||
));
|
|
||||||
fields.push(::protobuf::reflect::accessor::make_singular_bytes_accessor(
|
|
||||||
"proof",
|
|
||||||
ShareData::has_proof,
|
|
||||||
ShareData::get_proof,
|
|
||||||
));
|
|
||||||
::protobuf::reflect::MessageDescriptor::new::<ShareData>(
|
|
||||||
"ShareData",
|
|
||||||
fields,
|
|
||||||
file_descriptor_proto()
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ::protobuf::Clear for ShareData {
|
|
||||||
fn clear(&mut self) {
|
|
||||||
self.clear_shamir_data();
|
|
||||||
self.clear_signature();
|
|
||||||
self.clear_proof();
|
|
||||||
self.unknown_fields.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ::std::cmp::PartialEq for ShareData {
|
|
||||||
fn eq(&self, other: &ShareData) -> bool {
|
|
||||||
self.shamir_data == other.shamir_data &&
|
|
||||||
self.signature == other.signature &&
|
|
||||||
self.proof == other.proof &&
|
|
||||||
self.unknown_fields == other.unknown_fields
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ::std::fmt::Debug for ShareData {
|
|
||||||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
|
||||||
::protobuf::text_format::fmt(self, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static file_descriptor_proto_data: &'static [u8] = &[
|
|
||||||
0x0a, 0x18, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x53, 0x68, 0x61, 0x72, 0x65,
|
|
||||||
0x44, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x60, 0x0a, 0x09, 0x53, 0x68,
|
|
||||||
0x61, 0x72, 0x65, 0x44, 0x61, 0x74, 0x61, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x68, 0x61, 0x6d, 0x69,
|
|
||||||
0x72, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x73, 0x68,
|
|
||||||
0x61, 0x6d, 0x69, 0x72, 0x44, 0x61, 0x74, 0x61, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e,
|
|
||||||
0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67,
|
|
||||||
0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18,
|
|
||||||
0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x4a, 0xfb, 0x01, 0x0a,
|
|
||||||
0x06, 0x12, 0x04, 0x00, 0x00, 0x06, 0x01, 0x0a, 0x08, 0x0a, 0x01, 0x0c, 0x12, 0x03, 0x00, 0x00,
|
|
||||||
0x12, 0x0a, 0x0a, 0x0a, 0x02, 0x04, 0x00, 0x12, 0x04, 0x02, 0x00, 0x06, 0x01, 0x0a, 0x0a, 0x0a,
|
|
||||||
0x03, 0x04, 0x00, 0x01, 0x12, 0x03, 0x02, 0x08, 0x11, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x00, 0x02,
|
|
||||||
0x00, 0x12, 0x03, 0x03, 0x08, 0x1e, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x04, 0x12,
|
|
||||||
0x04, 0x03, 0x08, 0x02, 0x13, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x05, 0x12, 0x03,
|
|
||||||
0x03, 0x08, 0x0d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x03, 0x0e,
|
|
||||||
0x19, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x03, 0x1c, 0x1d, 0x0a,
|
|
||||||
0x0b, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x01, 0x12, 0x03, 0x04, 0x08, 0x25, 0x0a, 0x0c, 0x0a, 0x05,
|
|
||||||
0x04, 0x00, 0x02, 0x01, 0x04, 0x12, 0x03, 0x04, 0x08, 0x10, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00,
|
|
||||||
0x02, 0x01, 0x05, 0x12, 0x03, 0x04, 0x11, 0x16, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01,
|
|
||||||
0x01, 0x12, 0x03, 0x04, 0x17, 0x20, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x03, 0x12,
|
|
||||||
0x03, 0x04, 0x23, 0x24, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x02, 0x12, 0x03, 0x05, 0x08,
|
|
||||||
0x18, 0x0a, 0x0d, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x04, 0x12, 0x04, 0x05, 0x08, 0x04, 0x25,
|
|
||||||
0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x05, 0x12, 0x03, 0x05, 0x08, 0x0d, 0x0a, 0x0c,
|
|
||||||
0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x03, 0x05, 0x0e, 0x13, 0x0a, 0x0c, 0x0a, 0x05,
|
|
||||||
0x04, 0x00, 0x02, 0x02, 0x03, 0x12, 0x03, 0x05, 0x16, 0x17, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
|
|
||||||
0x6f, 0x33,
|
|
||||||
];
|
|
||||||
|
|
||||||
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()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,87 +0,0 @@
|
|||||||
use custom_error::{RustyError, RustyErrorTypes};
|
|
||||||
use custom_error::pie2error;
|
|
||||||
use digest;
|
|
||||||
use merkle_sigs::{MerklePublicKey, Proof, PublicKey};
|
|
||||||
use protobuf;
|
|
||||||
use protobuf::{Message, RepeatedField};
|
|
||||||
use serialize;
|
|
||||||
use serialize::base64::{self, FromBase64, ToBase64};
|
|
||||||
use share_data::ShareData;
|
|
||||||
use std::error::Error;
|
|
||||||
|
|
||||||
type ParsedShare = Result<(Vec<u8>, u8, u8, Option<(Vec<Vec<u8>>, Proof<MerklePublicKey>)>), RustyError>;
|
|
||||||
|
|
||||||
fn base64_config() -> serialize::base64::Config {
|
|
||||||
base64::Config { pad: false, ..base64::STANDARD }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn share_string_from(share: Vec<u8>, threshold: u8, share_num: u8,
|
|
||||||
signature_pair: Option<(Vec<Vec<u8>>, Proof<MerklePublicKey>)>)
|
|
||||||
-> String {
|
|
||||||
let mut share_protobuf = ShareData::new();
|
|
||||||
share_protobuf.set_shamir_data(share);
|
|
||||||
|
|
||||||
if signature_pair.is_some() {
|
|
||||||
let (signature, proof) = signature_pair.unwrap();
|
|
||||||
share_protobuf.set_signature(RepeatedField::from_vec(signature));
|
|
||||||
share_protobuf.set_proof(proof.write_to_bytes().unwrap());
|
|
||||||
}
|
|
||||||
|
|
||||||
let b64_share = share_protobuf.write_to_bytes().unwrap().to_base64(base64_config());
|
|
||||||
format!("{}-{}-{}", threshold, share_num, b64_share)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn share_from_string
|
|
||||||
(s: &str,
|
|
||||||
index: u8,
|
|
||||||
is_signed: bool)
|
|
||||||
-> ParsedShare {
|
|
||||||
let parts: Vec<_> = s.trim().split('-').collect();
|
|
||||||
|
|
||||||
if parts.len() != 3 {
|
|
||||||
return Err(RustyError::with_type(RustyErrorTypes::ShareParsingError(index, format!("Expected 3 parts separated by a minus sign. Found {}.", s))));
|
|
||||||
}
|
|
||||||
let (k, n, p3) = {
|
|
||||||
let mut iter = parts.into_iter();
|
|
||||||
let k = try!(iter.next().unwrap().parse::<u8>().map_err(pie2error));
|
|
||||||
let n = try!(iter.next().unwrap().parse::<u8>().map_err(pie2error));
|
|
||||||
let p3 = iter.next().unwrap();
|
|
||||||
(k, n, p3)
|
|
||||||
};
|
|
||||||
if k < 1 || n < 1 {
|
|
||||||
return Err(RustyError::with_type(RustyErrorTypes::ShareParsingError(index, format!("Found illegal parameters K: {} N: {}.", k, n))));
|
|
||||||
}
|
|
||||||
|
|
||||||
let raw_data = try!(p3.from_base64().map_err(|_| {
|
|
||||||
RustyError::with_type(RustyErrorTypes::ShareParsingError(index, "Base64 decoding of data block failed".to_owned()))
|
|
||||||
}));
|
|
||||||
|
|
||||||
let protobuf_data = try!(protobuf::parse_from_bytes::<ShareData>(raw_data.as_slice())
|
|
||||||
.map_err(|e| RustyError::with_type(RustyErrorTypes::ShareParsingError(index, format!("Protobuf decoding of data block failed with error: {} .", e.description())))));
|
|
||||||
|
|
||||||
let share = Vec::from(protobuf_data.get_shamir_data());
|
|
||||||
|
|
||||||
if is_signed {
|
|
||||||
let p_result = Proof::parse_from_bytes(protobuf_data.get_proof(), digest);
|
|
||||||
|
|
||||||
let p_opt = p_result.unwrap();
|
|
||||||
let p = p_opt.unwrap();
|
|
||||||
|
|
||||||
let proof = Proof {
|
|
||||||
algorithm: digest,
|
|
||||||
lemma: p.lemma,
|
|
||||||
root_hash: p.root_hash,
|
|
||||||
value: MerklePublicKey::new(PublicKey::from_vec(p.value, digest).unwrap()),
|
|
||||||
};
|
|
||||||
|
|
||||||
let signature = protobuf_data.get_signature();
|
|
||||||
|
|
||||||
Ok((share, k, n, Some((Vec::from(signature), proof))))
|
|
||||||
} else {
|
|
||||||
Ok((share, k, n, None))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn format_share_for_signing(k: u8, i: u8, data: &[u8]) -> Vec<u8> {
|
|
||||||
format!("{}-{}-{}", k, i, data.to_base64(base64_config())).into_bytes()
|
|
||||||
}
|
|
128
src/sss.rs
128
src/sss.rs
@ -1,128 +0,0 @@
|
|||||||
//! SSS provides Shamir's secret sharing with raw data.
|
|
||||||
|
|
||||||
use custom_error::{RustyError, other_io_err};
|
|
||||||
use digest;
|
|
||||||
use interpolation::{encode, lagrange_interpolate};
|
|
||||||
use merkle_sigs::sign_data_vec;
|
|
||||||
use rand::{OsRng, Rng};
|
|
||||||
use share_format::format_share_for_signing;
|
|
||||||
use share_format::share_string_from;
|
|
||||||
use std::io;
|
|
||||||
use std::iter::repeat;
|
|
||||||
use validation::process_and_validate_shares;
|
|
||||||
|
|
||||||
fn new_vec<T: Clone>(n: usize, x: T) -> Vec<T> {
|
|
||||||
repeat(x).take(n).collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Performs threshold k-out-of-n Shamir's secret sharing.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use rusty_secrets::sss::generate_shares;
|
|
||||||
/// let secret = "These programs were never about terrorism: they’re about economic spying,
|
|
||||||
/// social control, and diplomatic manipulation. They’re about power.".to_string();
|
|
||||||
///
|
|
||||||
/// match generate_shares(7, 10, &secret.into_bytes(), true){
|
|
||||||
/// Ok(shares) => {
|
|
||||||
/// // Do something with the shares
|
|
||||||
/// },
|
|
||||||
/// Err(_) => {}// Deal with error}
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
pub fn generate_shares(k: u8, n: u8, secret: &[u8], sign_shares: bool) -> io::Result<Vec<String>> {
|
|
||||||
if k > n {
|
|
||||||
return Err(other_io_err("Threshold K can not be larger than N", None, None, None));
|
|
||||||
}
|
|
||||||
|
|
||||||
let shares = try!(secret_share(secret, k, n));
|
|
||||||
|
|
||||||
let signatures = if sign_shares {
|
|
||||||
let shares_to_sign = shares.iter()
|
|
||||||
.enumerate()
|
|
||||||
.map(|(i, x)| format_share_for_signing(k, (i + 1) as u8, x))
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
let sign = sign_data_vec(&shares_to_sign, digest)
|
|
||||||
.unwrap()
|
|
||||||
.into_iter()
|
|
||||||
.map(Some)
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
Some(sign)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut result = Vec::with_capacity(n as usize);
|
|
||||||
|
|
||||||
for ((index, share), signature_pair) in
|
|
||||||
shares.into_iter()
|
|
||||||
.enumerate()
|
|
||||||
.zip(signatures.unwrap_or_else(|| vec![None; n as usize]).into_iter()) {
|
|
||||||
let share_string = share_string_from(share, k, (index + 1) as u8, signature_pair);
|
|
||||||
result.push(share_string);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(result)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn secret_share(src: &[u8], k: u8, n: u8) -> Result<Vec<Vec<u8>>, RustyError> {
|
|
||||||
let mut result = Vec::with_capacity(n as usize);
|
|
||||||
for _ in 0..(n as usize) {
|
|
||||||
result.push(new_vec(src.len(), 0u8));
|
|
||||||
}
|
|
||||||
let mut col_in = new_vec(k as usize, 0u8);
|
|
||||||
let mut col_out = Vec::with_capacity(n as usize);
|
|
||||||
let mut osrng = try!(OsRng::new());
|
|
||||||
for (c, &s) in src.iter().enumerate() {
|
|
||||||
col_in[0] = s;
|
|
||||||
osrng.fill_bytes(&mut col_in[1..]);
|
|
||||||
col_out.clear();
|
|
||||||
try!(encode(&*col_in, n, &mut col_out));
|
|
||||||
for (&y, share) in col_out.iter().zip(result.iter_mut()) {
|
|
||||||
share[c] = y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(result)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// 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.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use rusty_secrets::sss::recover_secret;
|
|
||||||
/// let share1 = "2-1-Cha7s14Q/mSwWko0ittr+/Uf79RHQMIP".to_string();
|
|
||||||
/// let share2 = "2-4-ChaydsUJDypD9ZWxwvIICh/cmZvzusOF".to_string();
|
|
||||||
/// let shares = vec![share1, share2];
|
|
||||||
///
|
|
||||||
/// match recover_secret(shares, false) {
|
|
||||||
/// Ok(secret) => {
|
|
||||||
/// // Do something with the secret
|
|
||||||
/// },
|
|
||||||
/// Err(e) => {
|
|
||||||
/// // Deal with the error
|
|
||||||
/// }
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
pub fn recover_secret(shares: Vec<String>, verify_signatures: bool) -> Result<Vec<u8>, RustyError> {
|
|
||||||
let (k, shares) = try!(process_and_validate_shares(shares, verify_signatures));
|
|
||||||
|
|
||||||
let slen = shares[0].1.len();
|
|
||||||
let mut col_in = Vec::with_capacity(k as usize);
|
|
||||||
let mut secret = Vec::with_capacity(slen);
|
|
||||||
for byteindex in 0..slen {
|
|
||||||
col_in.clear();
|
|
||||||
for s in shares.iter().take(k as usize) {
|
|
||||||
col_in.push((s.0, s.1[byteindex]));
|
|
||||||
}
|
|
||||||
secret.push(lagrange_interpolate(&*col_in));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(secret)
|
|
||||||
}
|
|
18
src/sss/encode.rs
Normal file
18
src/sss/encode.rs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
use gf256::Gf256;
|
||||||
|
use std::io;
|
||||||
|
use std::io::prelude::*;
|
||||||
|
|
||||||
|
/// evaluates a polynomial at x=1, 2, 3, ... n (inclusive)
|
||||||
|
pub(crate) fn encode_secret_byte<W: Write>(src: &[u8], n: u8, w: &mut W) -> io::Result<()> {
|
||||||
|
for raw_x in 1..(u16::from(n) + 1) {
|
||||||
|
let x = Gf256::from_byte(raw_x as u8);
|
||||||
|
let mut fac = Gf256::one();
|
||||||
|
let mut acc = Gf256::zero();
|
||||||
|
for &coeff in src.iter() {
|
||||||
|
acc = acc + fac * Gf256::from_byte(coeff);
|
||||||
|
fac = fac * x;
|
||||||
|
}
|
||||||
|
w.write_all(&[acc.to_byte()])?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
104
src/sss/format.rs
Normal file
104
src/sss/format.rs
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
use errors::*;
|
||||||
|
use merkle_sigs::{MerklePublicKey, Proof, PublicKey};
|
||||||
|
use protobuf::{self, Message, RepeatedField};
|
||||||
|
use base64;
|
||||||
|
use sss::{Share, HASH_ALGO};
|
||||||
|
use proto::wrapped::ShareProto;
|
||||||
|
use std::error::Error;
|
||||||
|
|
||||||
|
const BASE64_CONFIG: base64::Config = base64::STANDARD_NO_PAD;
|
||||||
|
|
||||||
|
pub(crate) fn share_to_string(
|
||||||
|
share: Vec<u8>,
|
||||||
|
threshold: u8,
|
||||||
|
share_num: u8,
|
||||||
|
signature_pair: Option<(Vec<Vec<u8>>, Proof<MerklePublicKey>)>,
|
||||||
|
) -> String {
|
||||||
|
let mut share_protobuf = ShareProto::new();
|
||||||
|
share_protobuf.set_shamir_data(share);
|
||||||
|
|
||||||
|
if signature_pair.is_some() {
|
||||||
|
let (signature, proof) = signature_pair.unwrap();
|
||||||
|
share_protobuf.set_signature(RepeatedField::from_vec(signature));
|
||||||
|
share_protobuf.set_proof(proof.write_to_bytes().unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
let proto_buf = share_protobuf.write_to_bytes().unwrap();
|
||||||
|
let b64_share = base64::encode_config(&proto_buf, BASE64_CONFIG);
|
||||||
|
format!("{}-{}-{}", threshold, share_num, b64_share)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn share_from_string(s: &str, is_signed: bool) -> Result<Share> {
|
||||||
|
let parts: Vec<_> = s.trim().split('-').collect();
|
||||||
|
|
||||||
|
if parts.len() != SSS_SHARE_PARTS_COUNT {
|
||||||
|
bail! {
|
||||||
|
ErrorKind::ShareParsingError(
|
||||||
|
format!(
|
||||||
|
"Expected 3 parts separated by a minus sign. Found {}.",
|
||||||
|
s
|
||||||
|
),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
let (k, i, p3) = {
|
||||||
|
let mut iter = parts.into_iter();
|
||||||
|
let k = iter.next().unwrap().parse::<u8>()?;
|
||||||
|
let i = iter.next().unwrap().parse::<u8>()?;
|
||||||
|
let p3 = iter.next().unwrap();
|
||||||
|
(k, i, p3)
|
||||||
|
};
|
||||||
|
|
||||||
|
if k < 1 || i < 1 {
|
||||||
|
bail! {
|
||||||
|
ErrorKind::ShareParsingError(
|
||||||
|
format!("Found illegal share info: threshold = {}, identifier = {}.", k, i),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let raw_data = base64::decode_config(p3, BASE64_CONFIG).chain_err(|| {
|
||||||
|
ErrorKind::ShareParsingError("Base64 decoding of data block failed".to_owned())
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let protobuf_data =
|
||||||
|
protobuf::parse_from_bytes::<ShareProto>(raw_data.as_slice()).map_err(|e| {
|
||||||
|
ErrorKind::ShareParsingError(format!(
|
||||||
|
"Protobuf decoding of data block failed with error: {} .",
|
||||||
|
e.description()
|
||||||
|
))
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let data = Vec::from(protobuf_data.get_shamir_data());
|
||||||
|
|
||||||
|
let signature_pair = if is_signed {
|
||||||
|
let p_result = Proof::parse_from_bytes(protobuf_data.get_proof(), HASH_ALGO);
|
||||||
|
|
||||||
|
let p_opt = p_result.unwrap();
|
||||||
|
let p = p_opt.unwrap();
|
||||||
|
|
||||||
|
let proof = Proof {
|
||||||
|
algorithm: HASH_ALGO,
|
||||||
|
lemma: p.lemma,
|
||||||
|
root_hash: p.root_hash,
|
||||||
|
value: MerklePublicKey::new(PublicKey::from_vec(p.value, HASH_ALGO).unwrap()),
|
||||||
|
};
|
||||||
|
|
||||||
|
let signature = protobuf_data.get_signature();
|
||||||
|
Some((Vec::from(signature), proof).into())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(Share {
|
||||||
|
id: i,
|
||||||
|
data,
|
||||||
|
threshold: k,
|
||||||
|
signature_pair,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn format_share_for_signing(k: u8, i: u8, data: &[u8]) -> Vec<u8> {
|
||||||
|
let b64_data = base64::encode_config(data, BASE64_CONFIG);
|
||||||
|
format!("{}-{}-{}", k, i, b64_data).into_bytes()
|
||||||
|
}
|
69
src/sss/mod.rs
Normal file
69
src/sss/mod.rs
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
//! SSS provides Shamir's secret sharing with raw data.
|
||||||
|
|
||||||
|
use errors::*;
|
||||||
|
|
||||||
|
mod share;
|
||||||
|
pub(crate) use self::share::*;
|
||||||
|
|
||||||
|
mod format;
|
||||||
|
// pub use self::format::*;
|
||||||
|
|
||||||
|
mod scheme;
|
||||||
|
pub(crate) use self::scheme::*;
|
||||||
|
|
||||||
|
mod encode;
|
||||||
|
|
||||||
|
use ring::digest::{Algorithm, SHA512};
|
||||||
|
static HASH_ALGO: &'static Algorithm = &SHA512;
|
||||||
|
|
||||||
|
/// Performs threshold k-out-of-n Shamir's secret sharing.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use rusty_secrets::sss::split_secret;
|
||||||
|
///
|
||||||
|
/// let secret = "These programs were never about terrorism: they’re about economic spying, \
|
||||||
|
/// social control, and diplomatic manipulation. They’re about power.";
|
||||||
|
///
|
||||||
|
/// match split_secret(7, 10, &secret.as_bytes(), true) {
|
||||||
|
/// Ok(shares) => {
|
||||||
|
/// // Do something with the shares
|
||||||
|
/// },
|
||||||
|
/// Err(_) => {
|
||||||
|
/// // Deal with error
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
pub fn split_secret(k: u8, n: u8, secret: &[u8], sign_shares: bool) -> Result<Vec<String>> {
|
||||||
|
SSS::default()
|
||||||
|
.split_secret(k, n, secret, sign_shares)
|
||||||
|
.map(|shares| shares.into_iter().map(Share::into_string).collect())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Recovers the secret from a k-out-of-n Shamir's secret sharing scheme.
|
||||||
|
///
|
||||||
|
/// At least `k` distinct shares need to be provided to recover the secret.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use rusty_secrets::sss::recover_secret;
|
||||||
|
///
|
||||||
|
/// let share1 = "2-1-Cha7s14Q/mSwWko0ittr+/Uf79RHQMIP".to_string();
|
||||||
|
/// let share2 = "2-4-ChaydsUJDypD9ZWxwvIICh/cmZvzusOF".to_string();
|
||||||
|
/// let shares = vec![share1, share2];
|
||||||
|
///
|
||||||
|
/// match recover_secret(&shares, false) {
|
||||||
|
/// Ok(secret) => {
|
||||||
|
/// // Do something with the secret
|
||||||
|
/// },
|
||||||
|
/// Err(e) => {
|
||||||
|
/// // Deal with the error
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
pub fn recover_secret(shares: &[String], verify_signatures: bool) -> Result<Vec<u8>> {
|
||||||
|
let shares = Share::parse_all(shares, verify_signatures)?;
|
||||||
|
SSS::recover_secret(shares, verify_signatures)
|
||||||
|
}
|
109
src/sss/scheme.rs
Normal file
109
src/sss/scheme.rs
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
//! SSS provides Shamir's secret sharing with raw data.
|
||||||
|
|
||||||
|
use rand::{OsRng, Rng};
|
||||||
|
use merkle_sigs::sign_data_vec;
|
||||||
|
|
||||||
|
use errors::*;
|
||||||
|
use sss::{Share, HASH_ALGO};
|
||||||
|
use sss::format::format_share_for_signing;
|
||||||
|
use share::validation::{validate_share_count, validate_signed_shares};
|
||||||
|
use lagrange::interpolate_at;
|
||||||
|
|
||||||
|
use super::encode::encode_secret_byte;
|
||||||
|
|
||||||
|
/// SSS provides Shamir's secret sharing with raw data.
|
||||||
|
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
|
pub(crate) struct SSS;
|
||||||
|
|
||||||
|
impl SSS {
|
||||||
|
/// Performs threshold k-out-of-n Shamir's secret sharing.
|
||||||
|
pub fn split_secret(
|
||||||
|
&self,
|
||||||
|
threshold: u8,
|
||||||
|
shares_count: u8,
|
||||||
|
secret: &[u8],
|
||||||
|
sign_shares: bool,
|
||||||
|
) -> Result<Vec<Share>> {
|
||||||
|
let (threshold, shares_count) = validate_share_count(threshold, shares_count)?;
|
||||||
|
let shares = Self::secret_share(secret, threshold, shares_count)?;
|
||||||
|
|
||||||
|
let signatures = if sign_shares {
|
||||||
|
let shares_to_sign = shares
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(i, x)| format_share_for_signing(threshold, (i + 1) as u8, x))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let sign = sign_data_vec(&shares_to_sign, HASH_ALGO)
|
||||||
|
.unwrap()
|
||||||
|
.into_iter()
|
||||||
|
.map(Some)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
Some(sign)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
let sig_pairs = signatures
|
||||||
|
.unwrap_or_else(|| vec![None; shares_count as usize])
|
||||||
|
.into_iter()
|
||||||
|
.map(|sig_pair| sig_pair.map(From::from));
|
||||||
|
|
||||||
|
let shares_and_sigs = shares.into_iter().enumerate().zip(sig_pairs);
|
||||||
|
|
||||||
|
let result = shares_and_sigs.map(|((index, data), signature_pair)| {
|
||||||
|
// This is actually safe since we alwaays generate less than 256 shares.
|
||||||
|
let id = (index + 1) as u8;
|
||||||
|
|
||||||
|
Share {
|
||||||
|
id,
|
||||||
|
threshold,
|
||||||
|
data,
|
||||||
|
signature_pair,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok(result.collect())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn secret_share(src: &[u8], threshold: u8, shares_count: u8) -> Result<Vec<Vec<u8>>> {
|
||||||
|
let mut result = Vec::with_capacity(shares_count as usize);
|
||||||
|
for _ in 0..(shares_count as usize) {
|
||||||
|
result.push(vec![0u8; src.len()]);
|
||||||
|
}
|
||||||
|
let mut col_in = vec![0u8, threshold];
|
||||||
|
let mut col_out = Vec::with_capacity(shares_count as usize);
|
||||||
|
let mut osrng = OsRng::new()?;
|
||||||
|
for (c, &s) in src.iter().enumerate() {
|
||||||
|
col_in[0] = s;
|
||||||
|
osrng.fill_bytes(&mut col_in[1..]);
|
||||||
|
col_out.clear();
|
||||||
|
encode_secret_byte(&*col_in, shares_count, &mut col_out)?;
|
||||||
|
for (&y, share) in col_out.iter().zip(result.iter_mut()) {
|
||||||
|
share[c] = y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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<Share>, verify_signatures: bool) -> Result<Vec<u8>> {
|
||||||
|
let (threshold, shares) = validate_signed_shares(shares, verify_signatures)?;
|
||||||
|
|
||||||
|
let slen = shares[0].data.len();
|
||||||
|
let mut col_in = Vec::with_capacity(threshold as usize);
|
||||||
|
let mut secret = Vec::with_capacity(slen);
|
||||||
|
for byteindex in 0..slen {
|
||||||
|
col_in.clear();
|
||||||
|
for s in shares.iter().take(threshold as usize) {
|
||||||
|
col_in.push((s.id, s.data[byteindex]));
|
||||||
|
}
|
||||||
|
secret.push(interpolate_at(&*col_in));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(secret)
|
||||||
|
}
|
||||||
|
}
|
177
src/sss/share.rs
Normal file
177
src/sss/share.rs
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
use std::error::Error;
|
||||||
|
use std::collections::{HashMap, HashSet};
|
||||||
|
|
||||||
|
use merkle_sigs::{MerklePublicKey, Proof};
|
||||||
|
use merkle_sigs::verify_data_vec_signature;
|
||||||
|
|
||||||
|
use errors::*;
|
||||||
|
use share::{IsShare, IsSignedShare};
|
||||||
|
use sss::format::{format_share_for_signing, share_from_string, share_to_string};
|
||||||
|
|
||||||
|
/// 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(Clone, Debug, Hash, PartialEq, Eq)]
|
||||||
|
// TODO: Write manual instances which ignore the signature / fix merkle_sigs+merkle.rs
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub(crate) 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 share data itself
|
||||||
|
pub data: Vec<u8>,
|
||||||
|
/// If the share is signed, this fields holds the signature
|
||||||
|
/// along with the proof of inclusion into the underlying MerkleTree.
|
||||||
|
pub signature_pair: Option<SignaturePair>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Share {
|
||||||
|
/// Attempts to parse the given string into a share which should have the given `id`.
|
||||||
|
/// The string `raw` should follow the format of `Share::into_string`.
|
||||||
|
pub(crate) fn from_string(raw: &str, is_signed: bool) -> Result<Self> {
|
||||||
|
share_from_string(raw, is_signed)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Attempts to parse all the given strings into shares.
|
||||||
|
/// Calls out to `Share::from_string`.
|
||||||
|
pub(crate) fn parse_all(raws: &[String], is_signed: bool) -> Result<Vec<Share>> {
|
||||||
|
raws.into_iter()
|
||||||
|
.map(|raw| Self::from_string(raw, is_signed))
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Format the share as a string suitable for being stored in a file.
|
||||||
|
/// The format is the following:
|
||||||
|
///
|
||||||
|
/// ```text
|
||||||
|
/// 2-1-LiTyeXwEP71IUA
|
||||||
|
/// ^ ^ ^^^^^^^^^^^^^^
|
||||||
|
/// K N D
|
||||||
|
///
|
||||||
|
/// It is built out of three parts separated with a dash: K-N-D.
|
||||||
|
///
|
||||||
|
/// - K specifies the number of shares necessary to recover the secret.
|
||||||
|
/// - N is the identifier of the share and varies between 1 and n where
|
||||||
|
/// n is the total number of generated shares.
|
||||||
|
/// - D is a Base64 encoding of a ShareData protobuf containing
|
||||||
|
/// information about the share, and if signed, the signature.
|
||||||
|
/// ```
|
||||||
|
pub fn into_string(self) -> String {
|
||||||
|
share_to_string(
|
||||||
|
self.data,
|
||||||
|
self.threshold,
|
||||||
|
self.id,
|
||||||
|
self.signature_pair.map(Into::into),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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<u8> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IsSignedShare for Share {
|
||||||
|
type Signature = Option<SignaturePair>;
|
||||||
|
|
||||||
|
fn verify_signatures(shares: &[Self]) -> Result<()> {
|
||||||
|
let mut rh_compatibility_sets = HashMap::new();
|
||||||
|
|
||||||
|
for share in shares {
|
||||||
|
if !share.is_signed() {
|
||||||
|
bail!(ErrorKind::MissingSignature(share.get_id()));
|
||||||
|
}
|
||||||
|
|
||||||
|
let sig_pair = share.signature_pair.as_ref().unwrap();
|
||||||
|
let signature = &sig_pair.signature;
|
||||||
|
let proof = &sig_pair.proof;
|
||||||
|
let root_hash = &proof.root_hash;
|
||||||
|
|
||||||
|
verify_data_vec_signature(
|
||||||
|
format_share_for_signing(share.threshold, share.id, share.data.as_slice()),
|
||||||
|
&(signature.to_vec(), proof.clone()),
|
||||||
|
root_hash,
|
||||||
|
).map_err(|e| ErrorKind::InvalidSignature(share.id, String::from(e.description())))?;
|
||||||
|
|
||||||
|
rh_compatibility_sets
|
||||||
|
.entry(root_hash)
|
||||||
|
.or_insert_with(HashSet::new);
|
||||||
|
|
||||||
|
let rh_set = rh_compatibility_sets.get_mut(&root_hash).unwrap();
|
||||||
|
rh_set.insert(share.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
let rh_sets = rh_compatibility_sets.keys().count();
|
||||||
|
|
||||||
|
match rh_sets {
|
||||||
|
0 => bail!(ErrorKind::EmptyShares),
|
||||||
|
1 => {} // All shares have the same roothash.
|
||||||
|
_ => {
|
||||||
|
bail! {
|
||||||
|
ErrorKind::IncompatibleSets(
|
||||||
|
rh_compatibility_sets
|
||||||
|
.values()
|
||||||
|
.map(|x| x.to_owned())
|
||||||
|
.collect(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_signed(&self) -> bool {
|
||||||
|
self.signature_pair.is_some()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_signature(&self) -> &Self::Signature {
|
||||||
|
&self.signature_pair
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
/// Holds the signature along with the proof of inclusion
|
||||||
|
/// in the underlying Merkle tree used in the Lamport signature scheme.
|
||||||
|
pub struct SignaturePair {
|
||||||
|
/// The signature
|
||||||
|
pub signature: Vec<Vec<u8>>,
|
||||||
|
/// The proof of inclusion
|
||||||
|
pub proof: Proof<MerklePublicKey>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<SignaturePair> for (Vec<Vec<u8>>, Proof<MerklePublicKey>) {
|
||||||
|
fn from(pair: SignaturePair) -> Self {
|
||||||
|
(pair.signature, pair.proof)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<(Vec<Vec<u8>>, Proof<MerklePublicKey>)> for SignaturePair {
|
||||||
|
fn from(pair: (Vec<Vec<u8>>, Proof<MerklePublicKey>)) -> Self {
|
||||||
|
Self {
|
||||||
|
signature: pair.0,
|
||||||
|
proof: pair.1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Uncomment when re-implementating standard traits for `Share`
|
||||||
|
// impl Hash for SignaturePair {
|
||||||
|
// fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
|
// self.signature.hash(state);
|
||||||
|
// self.proof.root_hash.hash(state);
|
||||||
|
// }
|
||||||
|
// }
|
@ -1 +0,0 @@
|
|||||||
mod test_vectors;
|
|
@ -1,102 +0,0 @@
|
|||||||
use custom_error::{RustyError, RustyErrorTypes};
|
|
||||||
use merkle_sigs::verify_data_vec_signature;
|
|
||||||
use share_format;
|
|
||||||
use share_format::format_share_for_signing;
|
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::error::Error;
|
|
||||||
|
|
||||||
type ProcessedShares = Result<(u8, Vec<(u8, Vec<u8>)>), RustyError>;
|
|
||||||
|
|
||||||
// The order of validation that we think makes the most sense is the following:
|
|
||||||
// 1) Validate shares individually
|
|
||||||
// 2) Validate duplicate shares share num && data
|
|
||||||
// 2) Validate group consistency
|
|
||||||
// 3) Validate other properties, in no specific order
|
|
||||||
|
|
||||||
pub fn process_and_validate_shares(shares_strings: Vec<String>,
|
|
||||||
verify_signatures: bool)
|
|
||||||
-> ProcessedShares {
|
|
||||||
let mut shares: Vec<(u8, Vec<u8>)> = Vec::new();
|
|
||||||
|
|
||||||
let mut k_compatibility_sets = HashMap::new();
|
|
||||||
let mut rh_compatibility_sets = HashMap::new();
|
|
||||||
|
|
||||||
for (counter, line) in shares_strings.iter().enumerate() {
|
|
||||||
let share_index = counter as u8;
|
|
||||||
let (share_data, k, n, sig_pair) = try!(share_format::share_from_string(line,
|
|
||||||
counter as u8,
|
|
||||||
verify_signatures));
|
|
||||||
if verify_signatures {
|
|
||||||
if sig_pair.is_none() {
|
|
||||||
return Err(RustyError::with_type(RustyErrorTypes::MissingSignature(share_index)));
|
|
||||||
}
|
|
||||||
|
|
||||||
let (signature, p) = sig_pair.unwrap();
|
|
||||||
let root_hash = p.root_hash.clone();
|
|
||||||
|
|
||||||
try!(verify_data_vec_signature(format_share_for_signing(k,
|
|
||||||
n,
|
|
||||||
&share_data.as_slice()),
|
|
||||||
&(signature.to_vec(), p),
|
|
||||||
&root_hash)
|
|
||||||
.map_err(|e| RustyError::with_type(RustyErrorTypes::InvalidSignature(share_index, String::from(e.description())))));
|
|
||||||
rh_compatibility_sets.entry(root_hash.clone()).or_insert_with(Vec::new);
|
|
||||||
let vec = rh_compatibility_sets.get_mut(&root_hash).unwrap();
|
|
||||||
vec.push(share_index);
|
|
||||||
}
|
|
||||||
|
|
||||||
k_compatibility_sets.entry(k).or_insert_with(Vec::new);
|
|
||||||
let vec = k_compatibility_sets.get_mut(&k).unwrap();
|
|
||||||
vec.push(share_index);
|
|
||||||
|
|
||||||
if shares.iter().any(|s| s.0 == n) {
|
|
||||||
return Err(RustyError::with_type(RustyErrorTypes::DuplicateShareNum(share_index)));
|
|
||||||
};
|
|
||||||
|
|
||||||
if shares.iter().any(|s| s.1 == share_data) && k != 1 { // When k = 1, shares data can be the same
|
|
||||||
return Err(RustyError::with_type(RustyErrorTypes::DuplicateShareData(share_index)));
|
|
||||||
};
|
|
||||||
|
|
||||||
shares.push((n, share_data));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate k
|
|
||||||
|
|
||||||
let k_sets = k_compatibility_sets.keys().count();
|
|
||||||
let rh_sets = rh_compatibility_sets.keys().count();
|
|
||||||
|
|
||||||
if verify_signatures {
|
|
||||||
match rh_sets {
|
|
||||||
0 => {
|
|
||||||
return Err(RustyError::with_type(RustyErrorTypes::EmptyShares))
|
|
||||||
}
|
|
||||||
1 => { } // All shares have the same roothash.
|
|
||||||
_ => {
|
|
||||||
return Err(RustyError::with_type(RustyErrorTypes::IncompatibleSets(rh_compatibility_sets.values()
|
|
||||||
.map(|x| x.to_owned()).collect())))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
match k_sets {
|
|
||||||
0 => {
|
|
||||||
return Err(RustyError::with_type(RustyErrorTypes::EmptyShares))
|
|
||||||
}
|
|
||||||
1 => { } // All shares have the same roothash.
|
|
||||||
_ => {
|
|
||||||
return Err(RustyError::with_type(RustyErrorTypes::IncompatibleSets(k_compatibility_sets.values()
|
|
||||||
.map(|x| x.to_owned()).collect())))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// It is safe to unwrap because k_sets == 1
|
|
||||||
let k = *k_compatibility_sets.keys().last().unwrap();
|
|
||||||
let shares_num = shares.len();
|
|
||||||
|
|
||||||
if shares_num >= k as usize {
|
|
||||||
shares.truncate(k as usize);
|
|
||||||
Ok((k, shares))
|
|
||||||
} else {
|
|
||||||
Err(RustyError::with_type(RustyErrorTypes::MissingShares(k, shares_num)))
|
|
||||||
}
|
|
||||||
}
|
|
55
src/vol_hash.rs
Normal file
55
src/vol_hash.rs
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
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<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
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::<Vec<_>>();
|
||||||
|
dest.copy_from_slice(&src);
|
||||||
|
}
|
||||||
|
}
|
@ -1,64 +0,0 @@
|
|||||||
//! (Beta) `wrapped_secrets` provides Shamir's secret sharing with a wrapped secret. It currently offers versioning and MIME information about the data.
|
|
||||||
|
|
||||||
use custom_error::{RustyError, RustyErrorTypes};
|
|
||||||
use protobuf;
|
|
||||||
use protobuf::Message;
|
|
||||||
use secret::{RustySecret, RustySecretsVersions};
|
|
||||||
use sss;
|
|
||||||
use std::io;
|
|
||||||
|
|
||||||
/// Performs threshold k-out-of-n Shamir's secret sharing.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use rusty_secrets::wrapped_secrets::generate_shares;
|
|
||||||
/// let secret = "These programs were never about terrorism: they’re about economic spying,
|
|
||||||
/// social control, and diplomatic manipulation. They’re about power.".to_string();
|
|
||||||
///
|
|
||||||
/// match generate_shares(7, 10, &secret.into_bytes(), Some("text/html".to_string()), true){
|
|
||||||
/// Ok(shares) => {
|
|
||||||
/// // Do something with the shares
|
|
||||||
/// },
|
|
||||||
/// Err(_) => {}// Deal with error}
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
pub fn generate_shares(k: u8, n: u8, secret: &[u8], mime_type: Option<String>, sign_shares: bool) -> io::Result<Vec<String>> {
|
|
||||||
let mut rusty_secret = RustySecret::new();
|
|
||||||
rusty_secret.set_version(RustySecretsVersions::INITIAL_RELEASE);
|
|
||||||
rusty_secret.set_secret(secret.to_owned());
|
|
||||||
|
|
||||||
for mt in mime_type {
|
|
||||||
rusty_secret.set_mime_type(mt);
|
|
||||||
}
|
|
||||||
|
|
||||||
sss::generate_shares(k, n, rusty_secret.write_to_bytes().unwrap().as_slice(), sign_shares)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 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.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use rusty_secrets::wrapped_secrets::recover_secret;
|
|
||||||
/// let share1 = "2-1-Cha7s14Q/mSwWko0ittr+/Uf79RHQMIP".to_string();
|
|
||||||
/// let share2 = "2-4-ChaydsUJDypD9ZWxwvIICh/cmZvzusOF".to_string();
|
|
||||||
/// let shares = vec![share1, share2];
|
|
||||||
///
|
|
||||||
/// match recover_secret(shares, false) {
|
|
||||||
/// Ok(secret) => {
|
|
||||||
/// // Do something with the secret
|
|
||||||
/// },
|
|
||||||
/// Err(e) => {
|
|
||||||
/// // Deal with the error
|
|
||||||
/// }
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
pub fn recover_secret(shares: Vec<String>, verify_signatures: bool) -> Result<RustySecret, RustyError> {
|
|
||||||
let secret = try!(sss::recover_secret(shares, verify_signatures));
|
|
||||||
|
|
||||||
protobuf::parse_from_bytes::<RustySecret>(secret.as_slice())
|
|
||||||
.map_err(|_| RustyError::with_type(RustyErrorTypes::SecretDeserializationIssue))
|
|
||||||
}
|
|
73
src/wrapped_secrets/mod.rs
Normal file
73
src/wrapped_secrets/mod.rs
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
//! (Beta) `wrapped_secrets` provides Shamir's secret sharing with a wrapped secret. It currently offers versioning and MIME information about the data.
|
||||||
|
|
||||||
|
use errors::*;
|
||||||
|
use proto::wrapped::SecretProto;
|
||||||
|
|
||||||
|
mod scheme;
|
||||||
|
pub(crate) use self::scheme::*;
|
||||||
|
|
||||||
|
/// Performs threshold k-out-of-n Shamir's secret sharing.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use rusty_secrets::wrapped_secrets::split_secret;
|
||||||
|
///
|
||||||
|
/// let secret = "These programs were never about terrorism: they’re about economic spying, \
|
||||||
|
/// social control, and diplomatic manipulation. They’re about power.";
|
||||||
|
///
|
||||||
|
/// let result = split_secret(
|
||||||
|
/// 7,
|
||||||
|
/// 10,
|
||||||
|
/// &secret.as_bytes(),
|
||||||
|
/// Some("text/html".to_string()),
|
||||||
|
/// true,
|
||||||
|
/// );
|
||||||
|
///
|
||||||
|
/// match result {
|
||||||
|
/// Ok(shares) => {
|
||||||
|
/// // Do something with the shares
|
||||||
|
/// },
|
||||||
|
/// Err(_) => {
|
||||||
|
/// // Deal with error
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
pub fn split_secret(
|
||||||
|
k: u8,
|
||||||
|
n: u8,
|
||||||
|
secret: &[u8],
|
||||||
|
mime_type: Option<String>,
|
||||||
|
sign_shares: bool,
|
||||||
|
) -> Result<Vec<String>> {
|
||||||
|
WrappedSecrets::default()
|
||||||
|
.split_secret(k, n, secret, mime_type, sign_shares)
|
||||||
|
.map(|shares| shares.into_iter().map(Share::into_string).collect())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use rusty_secrets::wrapped_secrets::recover_secret;
|
||||||
|
///
|
||||||
|
/// let share1 = "2-1-Cha7s14Q/mSwWko0ittr+/Uf79RHQMIP".to_string();
|
||||||
|
/// let share2 = "2-4-ChaydsUJDypD9ZWxwvIICh/cmZvzusOF".to_string();
|
||||||
|
/// let shares = vec![share1, share2];
|
||||||
|
///
|
||||||
|
/// match recover_secret(&shares, false) {
|
||||||
|
/// Ok(secret) => {
|
||||||
|
/// // Do something with the secret
|
||||||
|
/// },
|
||||||
|
/// Err(e) => {
|
||||||
|
/// // Deal with the error
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
pub fn recover_secret(shares: &[String], verify_signatures: bool) -> Result<SecretProto> {
|
||||||
|
let shares = Share::parse_all(shares, verify_signatures)?;
|
||||||
|
WrappedSecrets::recover_secret(shares, verify_signatures)
|
||||||
|
}
|
45
src/wrapped_secrets/scheme.rs
Normal file
45
src/wrapped_secrets/scheme.rs
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
use errors::*;
|
||||||
|
use protobuf;
|
||||||
|
use protobuf::Message;
|
||||||
|
use proto::VersionProto;
|
||||||
|
use proto::wrapped::SecretProto;
|
||||||
|
|
||||||
|
use sss::SSS;
|
||||||
|
pub(crate) use sss::Share;
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
|
pub(crate) struct WrappedSecrets;
|
||||||
|
|
||||||
|
impl WrappedSecrets {
|
||||||
|
/// Performs threshold k-out-of-n Shamir's secret sharing.
|
||||||
|
pub fn split_secret(
|
||||||
|
&self,
|
||||||
|
k: u8,
|
||||||
|
n: u8,
|
||||||
|
secret: &[u8],
|
||||||
|
mime_type: Option<String>,
|
||||||
|
sign_shares: bool,
|
||||||
|
) -> Result<Vec<Share>> {
|
||||||
|
let mut rusty_secret = SecretProto::new();
|
||||||
|
rusty_secret.set_version(VersionProto::INITIAL_RELEASE);
|
||||||
|
rusty_secret.set_secret(secret.to_owned());
|
||||||
|
|
||||||
|
if let Some(mt) = mime_type {
|
||||||
|
rusty_secret.set_mime_type(mt);
|
||||||
|
}
|
||||||
|
|
||||||
|
let data = rusty_secret.write_to_bytes().unwrap();
|
||||||
|
|
||||||
|
SSS::default().split_secret(k, n, data.as_slice(), sign_shares)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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<Share>, verify_signatures: bool) -> Result<SecretProto> {
|
||||||
|
let secret = SSS::recover_secret(shares, verify_signatures)?;
|
||||||
|
|
||||||
|
protobuf::parse_from_bytes::<SecretProto>(secret.as_slice())
|
||||||
|
.chain_err(|| ErrorKind::SecretDeserializationError)
|
||||||
|
}
|
||||||
|
}
|
3
tests/fixtures/gf256/.gitignore
vendored
Normal file
3
tests/fixtures/gf256/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
*.py
|
||||||
|
*.pyc
|
||||||
|
*.sage.py
|
18
tests/fixtures/gf256/Makefile
vendored
Normal file
18
tests/fixtures/gf256/Makefile
vendored
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
|
||||||
|
SAGE = sage
|
||||||
|
|
||||||
|
TARGETS = gf256_add.txt.gz gf256_sub.txt.gz gf256_div.txt.gz gf256_mul.txt.gz gf256_pow.txt.gz
|
||||||
|
|
||||||
|
.PHONY: all clean
|
||||||
|
|
||||||
|
all: $(TARGETS)
|
||||||
|
|
||||||
|
%.txt.gz: %.sage common.py
|
||||||
|
$(SAGE) $< | gzip > $@
|
||||||
|
|
||||||
|
common.py: common.sage
|
||||||
|
$(SAGE) --preparse $<
|
||||||
|
mv common.sage.py common.py
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(RM) $(TARGETS) common.py
|
2
tests/fixtures/gf256/common.sage
vendored
Normal file
2
tests/fixtures/gf256/common.sage
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
field = GF(2**8, name='a', modulus=x^8+x^4+x^3+x^2+1, repr='int')
|
5
tests/fixtures/gf256/gf256_add.sage
vendored
Normal file
5
tests/fixtures/gf256/gf256_add.sage
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
from common import field
|
||||||
|
|
||||||
|
for i in sorted(field):
|
||||||
|
for j in sorted(field):
|
||||||
|
print("{} + {} = {}".format(i, j, i + j))
|
BIN
tests/fixtures/gf256/gf256_add.txt.gz
vendored
Normal file
BIN
tests/fixtures/gf256/gf256_add.txt.gz
vendored
Normal file
Binary file not shown.
5
tests/fixtures/gf256/gf256_div.sage
vendored
Normal file
5
tests/fixtures/gf256/gf256_div.sage
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
from common import field
|
||||||
|
|
||||||
|
for i in sorted(field):
|
||||||
|
for j in sorted(field)[1:]:
|
||||||
|
print("{} / {} = {}".format(i, j, i / j))
|
BIN
tests/fixtures/gf256/gf256_div.txt.gz
vendored
Normal file
BIN
tests/fixtures/gf256/gf256_div.txt.gz
vendored
Normal file
Binary file not shown.
5
tests/fixtures/gf256/gf256_mul.sage
vendored
Normal file
5
tests/fixtures/gf256/gf256_mul.sage
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
from common import field
|
||||||
|
|
||||||
|
for i in sorted(field):
|
||||||
|
for j in sorted(field):
|
||||||
|
print("{} * {} = {}".format(i, j, i * j))
|
BIN
tests/fixtures/gf256/gf256_mul.txt.gz
vendored
Normal file
BIN
tests/fixtures/gf256/gf256_mul.txt.gz
vendored
Normal file
Binary file not shown.
5
tests/fixtures/gf256/gf256_pow.sage
vendored
Normal file
5
tests/fixtures/gf256/gf256_pow.sage
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
from common import field
|
||||||
|
|
||||||
|
for i in sorted(field):
|
||||||
|
for j in range(0, 256):
|
||||||
|
print("{} ^ {} = {}".format(i, j, i ^ j))
|
BIN
tests/fixtures/gf256/gf256_pow.txt.gz
vendored
Normal file
BIN
tests/fixtures/gf256/gf256_pow.txt.gz
vendored
Normal file
Binary file not shown.
5
tests/fixtures/gf256/gf256_sub.sage
vendored
Normal file
5
tests/fixtures/gf256/gf256_sub.sage
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
from common import field
|
||||||
|
|
||||||
|
for i in sorted(field):
|
||||||
|
for j in sorted(field):
|
||||||
|
print("{} - {} = {}".format(i, j, i - j))
|
BIN
tests/fixtures/gf256/gf256_sub.txt.gz
vendored
Normal file
BIN
tests/fixtures/gf256/gf256_sub.txt.gz
vendored
Normal file
Binary file not shown.
@ -1,11 +1,11 @@
|
|||||||
extern crate rusty_secrets;
|
extern crate rusty_secrets;
|
||||||
|
|
||||||
use rusty_secrets::sss::generate_shares;
|
use rusty_secrets::sss;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic(expected = "Threshold K can not be larger than N")]
|
#[should_panic(expected = "ThresholdTooBig")]
|
||||||
fn test_generate_invalid_k() {
|
fn test_generate_invalid_k() {
|
||||||
let share1 = "2-1-1YAYwmOHqZ69jA".to_string().into_bytes();
|
let share1 = "2-1-1YAYwmOHqZ69jA".to_string().into_bytes();
|
||||||
|
|
||||||
generate_shares(10, 5, share1.as_slice(), true).unwrap();
|
sss::split_secret(10, 5, share1.as_slice(), true).unwrap();
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
extern crate rusty_secrets;
|
extern crate rusty_secrets;
|
||||||
|
|
||||||
use rusty_secrets::*;
|
use rusty_secrets::wrapped_secrets;
|
||||||
|
|
||||||
#[ignore]
|
#[ignore]
|
||||||
#[test]
|
#[test]
|
||||||
@ -19,12 +19,17 @@ fn test_reasonable_splits() {
|
|||||||
for is_signing in &[true, false] {
|
for is_signing in &[true, false] {
|
||||||
for k in 1..max_shares {
|
for k in 1..max_shares {
|
||||||
for n in k..max_shares {
|
for n in k..max_shares {
|
||||||
let shares = wrapped_secrets::generate_shares(k, n, &secret, Some(mime_type.clone()), *is_signing).unwrap();
|
let shares = wrapped_secrets::split_secret(
|
||||||
|
k,
|
||||||
|
n,
|
||||||
|
&secret,
|
||||||
|
Some(mime_type.clone()),
|
||||||
|
*is_signing,
|
||||||
|
).unwrap();
|
||||||
println!("Testing {} out-of- {}", k, n);
|
println!("Testing {} out-of- {}", k, n);
|
||||||
|
|
||||||
let s = wrapped_secrets::recover_secret(shares, *is_signing).unwrap();
|
let s = wrapped_secrets::recover_secret(&shares, *is_signing).unwrap();
|
||||||
assert_eq!(s.get_secret().to_owned(), secret);
|
assert_eq!(s.get_secret().to_owned(), secret);
|
||||||
assert!(s.has_mime_type());
|
|
||||||
assert_eq!(mime_type, s.get_mime_type());
|
assert_eq!(mime_type, s.get_mime_type());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,92 +3,87 @@ extern crate rusty_secrets;
|
|||||||
use rusty_secrets::sss::recover_secret;
|
use rusty_secrets::sss::recover_secret;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic(expected = "No shares were provided.")]
|
#[should_panic(expected = "EmptyShares")]
|
||||||
fn test_recover_no_shares() {
|
fn test_recover_no_shares() {
|
||||||
let shares = vec![];
|
for signed in &[true, false] {
|
||||||
recover_secret(shares, false).unwrap();
|
let shares = vec![];
|
||||||
|
recover_secret(&shares, *signed).unwrap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic(expected = "No shares were provided.")]
|
#[should_panic(expected = "ShareParsingError")]
|
||||||
fn test_recover_no_shares_signed() {
|
|
||||||
let shares = vec![];
|
|
||||||
recover_secret(shares, true).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[should_panic(expected = "This share is incorrectly formatted.")]
|
|
||||||
fn test_recover_2_parts_share() {
|
fn test_recover_2_parts_share() {
|
||||||
let share1 = "2-1-CgmKQZHMO+5n5pU".to_string();
|
let share1 = "2-1-CgmKQZHMO+5n5pU".to_string();
|
||||||
let share2 = "2-2".to_string();
|
let share2 = "2-2".to_string();
|
||||||
|
|
||||||
let shares = vec![share1, share2];
|
let shares = vec![share1, share2];
|
||||||
|
|
||||||
recover_secret(shares, false).unwrap();
|
recover_secret(&shares, false).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic(expected = "Integer parsing error")]
|
#[should_panic(expected = "IntegerParsingError")]
|
||||||
fn test_recover_incorrect_share_num() {
|
fn test_recover_incorrect_share_num() {
|
||||||
let share1 = "2-1-CgnlCxRNtnkzENE".to_string();
|
let share1 = "2-1-CgnlCxRNtnkzENE".to_string();
|
||||||
let share2 = "2-DEFINITLY_NAN-CgkAnUgP3lfwjyM".to_string();
|
let share2 = "2-DEFINITLY_NAN-CgkAnUgP3lfwjyM".to_string();
|
||||||
|
|
||||||
let shares = vec![share1, share2];
|
let shares = vec![share1, share2];
|
||||||
|
|
||||||
recover_secret(shares, false).unwrap();
|
recover_secret(&shares, false).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic(expected = "This share is incorrectly formatted.")]
|
#[should_panic(expected = "ShareParsingError")]
|
||||||
fn test_recover_0_share_num() {
|
fn test_recover_0_share_num() {
|
||||||
let share1 = "2-0-1YAYwmOHqZ69jA".to_string();
|
let share1 = "2-0-1YAYwmOHqZ69jA".to_string();
|
||||||
let share2 = "2-1-YJZQDGm22Y77Gw".to_string();
|
let share2 = "2-1-YJZQDGm22Y77Gw".to_string();
|
||||||
|
|
||||||
let shares = vec![share1, share2];
|
let shares = vec![share1, share2];
|
||||||
|
|
||||||
recover_secret(shares, false).unwrap();
|
recover_secret(&shares, false).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic(expected = "This share is incorrectly formatted.")]
|
#[should_panic(expected = "ShareParsingError")]
|
||||||
fn test_recover_invalid_b64() {
|
fn test_recover_invalid_b64() {
|
||||||
let share1 = "2-1-CgnlCxRNtnkzENE".to_string();
|
let share1 = "2-1-CgnlCxRNtnkzENE".to_string();
|
||||||
let share2 = "2-1-YJZQDG((((m22Y)))77Gw".to_string();
|
let share2 = "2-2-YJZQDG((((m22Y)))77Gw".to_string();
|
||||||
|
|
||||||
let shares = vec![share1, share2];
|
let shares = vec![share1, share2];
|
||||||
|
|
||||||
recover_secret(shares, false).unwrap();
|
recover_secret(&shares, false).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic(expected = "This share number has already been used by a previous share.")]
|
#[should_panic(expected = "DuplicateShareId")]
|
||||||
fn test_recover_duplicate_shares_number() {
|
fn test_recover_duplicate_shares_number() {
|
||||||
let share1 = "2-1-CgnlCxRNtnkzENE".to_string();
|
let share1 = "2-1-CgnlCxRNtnkzENE".to_string();
|
||||||
let share2 = "2-1-CgkAnUgP3lfwjyM".to_string();
|
let share2 = "2-1-CgkAnUgP3lfwjyM".to_string();
|
||||||
|
|
||||||
let shares = vec![share1, share2];
|
let shares = vec![share1, share2];
|
||||||
|
|
||||||
recover_secret(shares, false).unwrap();
|
recover_secret(&shares, false).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic(expected = "The data encoded in this share is the same as the one found in a previous share.")]
|
#[should_panic(expected = "DuplicateShareData")]
|
||||||
fn test_recover_duplicate_shares_data() {
|
fn test_recover_duplicate_shares_data() {
|
||||||
let share1 = "2-1-CgnlCxRNtnkzENE".to_string();
|
let share1 = "2-1-CgnlCxRNtnkzENE".to_string();
|
||||||
let share2 = "2-2-CgnlCxRNtnkzENE".to_string();
|
let share2 = "2-2-CgnlCxRNtnkzENE".to_string();
|
||||||
|
|
||||||
let shares = vec![share1, share2];
|
let shares = vec![share1, share2];
|
||||||
|
|
||||||
recover_secret(shares, false).unwrap();
|
recover_secret(&shares, false).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic(expected = "The number of shares provided is insufficient to recover the secret.")]
|
#[should_panic(expected = "MissingShares")]
|
||||||
fn test_recover_too_few_shares() {
|
fn test_recover_too_few_shares() {
|
||||||
let share1 = "3-1-ChbcCdSZOaMn6DM1jFca2P6/0WRlP7AK".to_string();
|
let share1 = "3-1-ChbcCdSZOaMn6DM1jFca2P6/0WRlP7AK".to_string();
|
||||||
let share2 = "3-2-ChbG46L1zRszs0PPn63XnnupmZTcgYJ3".to_string();
|
let share2 = "3-2-ChbG46L1zRszs0PPn63XnnupmZTcgYJ3".to_string();
|
||||||
|
|
||||||
let shares = vec![share1, share2];
|
let shares = vec![share1, share2];
|
||||||
|
|
||||||
recover_secret(shares, false).unwrap();
|
recover_secret(&shares, false).unwrap();
|
||||||
}
|
}
|
||||||
|
188
tests/ss1_recovery_errors.rs
Normal file
188
tests/ss1_recovery_errors.rs
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
#![cfg(feature = "dss")]
|
||||||
|
|
||||||
|
extern crate rusty_secrets;
|
||||||
|
use rusty_secrets::dss::ss1::{recover_secret, split_secret, Reproducibility, Share};
|
||||||
|
|
||||||
|
const TEST_THRESHOLD: u8 = 2;
|
||||||
|
const TEST_SHARES_COUNT: u8 = 2;
|
||||||
|
const TEST_REPRODUCIBILITY: Reproducibility = Reproducibility::Reproducible;
|
||||||
|
const TEST_SECRET: &[u8] =
|
||||||
|
b"These programs were never about terrorism: they're about economic spying, \
|
||||||
|
social control, and diplomatic manipulation. They're about power.";
|
||||||
|
|
||||||
|
fn get_test_hash() -> Vec<u8> {
|
||||||
|
let good_shares = split_secret(
|
||||||
|
TEST_THRESHOLD,
|
||||||
|
TEST_SHARES_COUNT,
|
||||||
|
TEST_SECRET,
|
||||||
|
TEST_REPRODUCIBILITY,
|
||||||
|
&None,
|
||||||
|
).unwrap();
|
||||||
|
|
||||||
|
good_shares[0].hash.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic(expected = "EmptyShares")]
|
||||||
|
fn test_recover_no_shares() {
|
||||||
|
let shares = vec![];
|
||||||
|
recover_secret(&shares).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic(expected = "ShareParsingErrorEmptyShare")]
|
||||||
|
fn test_recover_2_parts_share() {
|
||||||
|
let hash = get_test_hash();
|
||||||
|
|
||||||
|
let share1 = Share {
|
||||||
|
id: 1,
|
||||||
|
threshold: TEST_THRESHOLD,
|
||||||
|
shares_count: TEST_SHARES_COUNT,
|
||||||
|
data: "CgmKQZHMO+5n5pU".to_string().into_bytes(),
|
||||||
|
hash: hash.clone(),
|
||||||
|
metadata: None,
|
||||||
|
};
|
||||||
|
let share2 = Share {
|
||||||
|
id: 2,
|
||||||
|
threshold: TEST_THRESHOLD,
|
||||||
|
shares_count: TEST_SHARES_COUNT,
|
||||||
|
data: "".to_string().into_bytes(),
|
||||||
|
hash: hash.clone(),
|
||||||
|
metadata: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let shares = vec![share1, share2];
|
||||||
|
|
||||||
|
recover_secret(&shares).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic(expected = "ShareParsingInvalidShareId")]
|
||||||
|
fn test_recover_0_share_num() {
|
||||||
|
let hash = get_test_hash();
|
||||||
|
|
||||||
|
let share1 = Share {
|
||||||
|
id: 0,
|
||||||
|
threshold: TEST_THRESHOLD,
|
||||||
|
shares_count: TEST_SHARES_COUNT,
|
||||||
|
data: "1YAYwmOHqZ69jA".to_string().into_bytes(),
|
||||||
|
hash: hash.clone(),
|
||||||
|
metadata: None,
|
||||||
|
};
|
||||||
|
let share2 = Share {
|
||||||
|
id: 1,
|
||||||
|
threshold: TEST_THRESHOLD,
|
||||||
|
shares_count: TEST_SHARES_COUNT,
|
||||||
|
data: "YJZQDGm22Y77Gw".to_string().into_bytes(),
|
||||||
|
hash: hash.clone(),
|
||||||
|
metadata: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let shares = vec![share1, share2];
|
||||||
|
|
||||||
|
recover_secret(&shares).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---
|
||||||
|
// TODO: will be implemented when serialization is done for ss1 shares
|
||||||
|
// ---
|
||||||
|
// #[test]
|
||||||
|
// #[should_panic(expected = "ShareParsingError")]
|
||||||
|
// fn test_recover_invalid_b64() {
|
||||||
|
// let share1 = Share {
|
||||||
|
// id: 1,
|
||||||
|
// threshold: 2,
|
||||||
|
// shares_count: 2,
|
||||||
|
// data: "1YAYwmOHqZ69jA".to_string().into_bytes(),
|
||||||
|
// metadata: None
|
||||||
|
// };
|
||||||
|
// let share2 = Share {
|
||||||
|
// id: 2,
|
||||||
|
// threshold: 2,
|
||||||
|
// shares_count: 2,
|
||||||
|
// data: "YJZQDG((((m22Y)))77Gw".to_string().into_bytes(),
|
||||||
|
// metadata: None
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// let shares = vec![share1, share2];
|
||||||
|
//
|
||||||
|
// recover_secret(&shares).unwrap();
|
||||||
|
// }
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic(expected = "DuplicateShareId")]
|
||||||
|
fn test_recover_duplicate_shares_number() {
|
||||||
|
let hash = get_test_hash();
|
||||||
|
let share1 = Share {
|
||||||
|
id: 1,
|
||||||
|
threshold: TEST_THRESHOLD,
|
||||||
|
shares_count: TEST_SHARES_COUNT,
|
||||||
|
data: "1YAYwmOHqZ69jA".to_string().into_bytes(),
|
||||||
|
hash: hash.clone(),
|
||||||
|
metadata: None,
|
||||||
|
};
|
||||||
|
let share2 = Share {
|
||||||
|
id: 1,
|
||||||
|
threshold: TEST_THRESHOLD,
|
||||||
|
shares_count: TEST_SHARES_COUNT,
|
||||||
|
data: "YJZQDGm22Y77Gw".to_string().into_bytes(),
|
||||||
|
hash: hash.clone(),
|
||||||
|
metadata: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let shares = vec![share1, share2];
|
||||||
|
|
||||||
|
recover_secret(&shares).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic(expected = "DuplicateShareData")]
|
||||||
|
fn test_recover_duplicate_shares_data() {
|
||||||
|
let hash = get_test_hash();
|
||||||
|
let share1 = Share {
|
||||||
|
id: 1,
|
||||||
|
threshold: TEST_THRESHOLD,
|
||||||
|
shares_count: TEST_SHARES_COUNT,
|
||||||
|
data: "1YAYwmOHqZ69jA".to_string().into_bytes(),
|
||||||
|
hash: hash.clone(),
|
||||||
|
metadata: None,
|
||||||
|
};
|
||||||
|
let share2 = Share {
|
||||||
|
id: 2,
|
||||||
|
threshold: TEST_THRESHOLD,
|
||||||
|
shares_count: TEST_SHARES_COUNT,
|
||||||
|
data: "1YAYwmOHqZ69jA".to_string().into_bytes(),
|
||||||
|
hash: hash.clone(),
|
||||||
|
metadata: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let shares = vec![share1, share2];
|
||||||
|
|
||||||
|
recover_secret(&shares).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic(expected = "MissingShares")]
|
||||||
|
fn test_recover_too_few_shares() {
|
||||||
|
let hash = get_test_hash();
|
||||||
|
let share1 = Share {
|
||||||
|
id: 1,
|
||||||
|
threshold: TEST_THRESHOLD + 1,
|
||||||
|
shares_count: TEST_SHARES_COUNT + 1,
|
||||||
|
data: "1YAYwmOHqZ69jA".to_string().into_bytes(),
|
||||||
|
hash: hash.clone(),
|
||||||
|
metadata: None,
|
||||||
|
};
|
||||||
|
let share2 = Share {
|
||||||
|
id: 2,
|
||||||
|
threshold: TEST_THRESHOLD + 1,
|
||||||
|
shares_count: TEST_SHARES_COUNT + 1,
|
||||||
|
data: "YJZQDGm22Y77Gw".to_string().into_bytes(),
|
||||||
|
hash: hash.clone(),
|
||||||
|
metadata: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let shares = vec![share1, share2];
|
||||||
|
|
||||||
|
recover_secret(&shares).unwrap();
|
||||||
|
}
|
@ -1,21 +1,22 @@
|
|||||||
|
extern crate base64;
|
||||||
extern crate protobuf;
|
extern crate protobuf;
|
||||||
extern crate rustc_serialize as serialize;
|
extern crate rusty_secrets;
|
||||||
|
|
||||||
use protobuf::Message;
|
use protobuf::Message;
|
||||||
use share_data;
|
|
||||||
use sss::recover_secret;
|
use rusty_secrets::proto::wrapped::ShareProto;
|
||||||
use serialize::base64::{self, FromBase64, ToBase64};
|
use rusty_secrets::sss::recover_secret;
|
||||||
|
|
||||||
|
const BASE64_CONFIG: base64::Config = base64::STANDARD_NO_PAD;
|
||||||
|
|
||||||
pub fn wrap_from_sellibitze(share: &str) -> String {
|
pub fn wrap_from_sellibitze(share: &str) -> String {
|
||||||
let parts: Vec<_> = share.trim().split('-').collect();
|
let parts: Vec<_> = share.trim().split('-').collect();
|
||||||
let share_data = parts[2].from_base64().unwrap();
|
let share_data = base64::decode_config(parts[2], BASE64_CONFIG).unwrap();
|
||||||
|
|
||||||
let config = base64::Config { pad: false, ..base64::STANDARD };
|
let mut share_protobuf = ShareProto::new();
|
||||||
|
|
||||||
let mut share_protobuf = share_data::ShareData::new();
|
|
||||||
share_protobuf.set_shamir_data(share_data);
|
share_protobuf.set_shamir_data(share_data);
|
||||||
|
|
||||||
let b64_share = share_protobuf.write_to_bytes().unwrap().to_base64(config);
|
let b64_share = base64::encode_config(&share_protobuf.write_to_bytes().unwrap(), BASE64_CONFIG);
|
||||||
|
|
||||||
format!("{}-{}-{}", parts[0], parts[1], b64_share)
|
format!("{}-{}-{}", parts[0], parts[1], b64_share)
|
||||||
}
|
}
|
||||||
@ -25,48 +26,47 @@ fn test_recover_sellibitze() {
|
|||||||
let share1 = "2-1-1YAYwmOHqZ69jA";
|
let share1 = "2-1-1YAYwmOHqZ69jA";
|
||||||
let share2 = "2-4-F7rAjX3UOa53KA";
|
let share2 = "2-4-F7rAjX3UOa53KA";
|
||||||
|
|
||||||
let shares = vec![share1, share2].iter().map(|x| wrap_from_sellibitze(x)).collect::<Vec<_>>();
|
let shares = vec![share1, share2]
|
||||||
|
.iter()
|
||||||
|
.map(|x| wrap_from_sellibitze(x))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let mut secret = "My secret".to_string().into_bytes();
|
let mut secret = "My secret".to_string().into_bytes();
|
||||||
secret.push(10);
|
secret.push(10);
|
||||||
assert_eq!(recover_secret(shares, false).unwrap(), secret);
|
assert_eq!(recover_secret(&shares, false).unwrap(), secret);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generated with code on master branch on the 6th of April.
|
// Generated with code on master branch on the 6th of April.
|
||||||
#[test]
|
#[test]
|
||||||
fn test_recover_es_test_vectors() {
|
fn test_recover_es_test_vectors() {
|
||||||
let share1 =
|
let share1 =
|
||||||
"5-1-DbuicpLQiCf7bVWiAz8eCpQGpdZmYQ7z2j2+g351tWFLOQPTZkXY8BYfwGGGjkOoz1g9x0ScmLFcWk+2tign"
|
"5-1-DbuicpLQiCf7bVWiAz8eCpQGpdZmYQ7z2j2+g351tWFLOQPTZkXY8BYfwGGGjkOoz1g9x0ScmLFcWk+2tign";
|
||||||
.to_string();
|
|
||||||
let share2 =
|
let share2 =
|
||||||
"5-2-nShdfkY5+SlfybMyqjHXCZ01bq5N/0Lkf0nQZw5x3bnHIEVfa0RA4YcJ4SjG/UdpgO/gOcyLRkSp2Dwf8bvw"
|
"5-2-nShdfkY5+SlfybMyqjHXCZ01bq5N/0Lkf0nQZw5x3bnHIEVfa0RA4YcJ4SjG/UdpgO/gOcyLRkSp2Dwf8bvw";
|
||||||
.to_string();
|
|
||||||
let share3 =
|
let share3 =
|
||||||
"5-3-qEhJ3IVEdbDkiRoy+jOJ/KuGE9jWyGeOYEcDwPfEV8E9rfD1Bc17BQAbJ51Xd8oexS2M1qMvNgJHZUQZbUgQ"
|
"5-3-qEhJ3IVEdbDkiRoy+jOJ/KuGE9jWyGeOYEcDwPfEV8E9rfD1Bc17BQAbJ51Xd8oexS2M1qMvNgJHZUQZbUgQ";
|
||||||
.to_string();
|
|
||||||
let share4 =
|
let share4 =
|
||||||
"5-6-yyVPUeaYPPiWK0wIV5OQ/t61V0lSEO+7X++EWeHRlIq3sRBNwUpKNfx/C+Vc9xTzUftrqBKvkWDZQal7nyi2"
|
"5-6-yyVPUeaYPPiWK0wIV5OQ/t61V0lSEO+7X++EWeHRlIq3sRBNwUpKNfx/C+Vc9xTzUftrqBKvkWDZQal7nyi2";
|
||||||
.to_string();
|
|
||||||
let share5 =
|
let share5 =
|
||||||
"5-7-i8iL6bVf272B3qIjp0QqSny6AIm+DkP7oQjkVVLvx9EMhlvd4HJOxPpmtNF/RjA/zz21d7DY/B//saOPpBQa"
|
"5-7-i8iL6bVf272B3qIjp0QqSny6AIm+DkP7oQjkVVLvx9EMhlvd4HJOxPpmtNF/RjA/zz21d7DY/B//saOPpBQa";
|
||||||
.to_string();
|
|
||||||
|
|
||||||
let shares = vec![share1, share2, share3, share4, share5]
|
let shares = vec![share1, share2, share3, share4, share5]
|
||||||
.iter()
|
.iter()
|
||||||
.map(|x| wrap_from_sellibitze(x))
|
.map(|x| wrap_from_sellibitze(x))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let secret =
|
let secret = "The immoral cannot be made moral through the use of secret law."
|
||||||
"The immoral cannot be made moral through the use of secret law.".to_string().into_bytes();
|
.to_string()
|
||||||
assert_eq!(recover_secret(shares, false).unwrap(), secret);
|
.into_bytes();
|
||||||
|
assert_eq!(recover_secret(&shares, false).unwrap(), secret);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_recover_sellibitze_more_than_threshold_shars() {
|
fn test_recover_sellibitze_more_than_threshold_shars() {
|
||||||
let share1 = "2-1-1YAYwmOHqZ69jA".to_string();
|
let share1 = "2-1-1YAYwmOHqZ69jA";
|
||||||
let share2 = "2-4-F7rAjX3UOa53KA".to_string();
|
let share2 = "2-4-F7rAjX3UOa53KA";
|
||||||
let share3 = "2-2-YJZQDGm22Y77Gw".to_string();
|
let share3 = "2-2-YJZQDGm22Y77Gw";
|
||||||
let share4 = "2-5-j0P4PHsw4lW+rg".to_string();
|
let share4 = "2-5-j0P4PHsw4lW+rg";
|
||||||
|
|
||||||
let shares = vec![share1, share2, share3, share4]
|
let shares = vec![share1, share2, share3, share4]
|
||||||
.iter()
|
.iter()
|
||||||
@ -75,5 +75,5 @@ fn test_recover_sellibitze_more_than_threshold_shars() {
|
|||||||
|
|
||||||
let mut secret = "My secret".to_string().into_bytes();
|
let mut secret = "My secret".to_string().into_bytes();
|
||||||
secret.push(10);
|
secret.push(10);
|
||||||
assert_eq!(recover_secret(shares, false).unwrap(), secret);
|
assert_eq!(recover_secret(&shares, false).unwrap(), secret);
|
||||||
}
|
}
|
14
tests/thss_generation_errors.rs
Normal file
14
tests/thss_generation_errors.rs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#![cfg(feature = "dss")]
|
||||||
|
|
||||||
|
extern crate rusty_secrets;
|
||||||
|
|
||||||
|
use rusty_secrets::dss::thss;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic(expected = "ThresholdTooBig")]
|
||||||
|
fn test_generate_invalid_k() {
|
||||||
|
let secret = b"These programs were never about terrorism: they're about economic spying, \
|
||||||
|
social control, and diplomatic manipulation. They're about power.";
|
||||||
|
|
||||||
|
thss::split_secret(10, 7, secret, &None).unwrap();
|
||||||
|
}
|
153
tests/thss_recovery_errors.rs
Normal file
153
tests/thss_recovery_errors.rs
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
#![cfg(feature = "dss")]
|
||||||
|
|
||||||
|
extern crate rusty_secrets;
|
||||||
|
|
||||||
|
use rusty_secrets::dss::thss::{recover_secret, Share};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic(expected = "EmptyShares")]
|
||||||
|
fn test_recover_no_shares() {
|
||||||
|
let shares = vec![];
|
||||||
|
recover_secret(&shares).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic(expected = "ShareParsingErrorEmptyShare")]
|
||||||
|
fn test_recover_2_parts_share() {
|
||||||
|
let share1 = Share {
|
||||||
|
id: 1,
|
||||||
|
threshold: 2,
|
||||||
|
shares_count: 2,
|
||||||
|
data: "CgmKQZHMO+5n5pU".to_string().into_bytes(),
|
||||||
|
metadata: None,
|
||||||
|
};
|
||||||
|
let share2 = Share {
|
||||||
|
id: 2,
|
||||||
|
threshold: 2,
|
||||||
|
shares_count: 2,
|
||||||
|
data: "".to_string().into_bytes(),
|
||||||
|
metadata: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let shares = vec![share1, share2];
|
||||||
|
|
||||||
|
recover_secret(&shares).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic(expected = "ShareParsingInvalidShareId")]
|
||||||
|
fn test_recover_0_share_num() {
|
||||||
|
let share1 = Share {
|
||||||
|
id: 0,
|
||||||
|
threshold: 2,
|
||||||
|
shares_count: 2,
|
||||||
|
data: "1YAYwmOHqZ69jA".to_string().into_bytes(),
|
||||||
|
metadata: None,
|
||||||
|
};
|
||||||
|
let share2 = Share {
|
||||||
|
id: 1,
|
||||||
|
threshold: 2,
|
||||||
|
shares_count: 2,
|
||||||
|
data: "YJZQDGm22Y77Gw".to_string().into_bytes(),
|
||||||
|
metadata: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let shares = vec![share1, share2];
|
||||||
|
|
||||||
|
recover_secret(&shares).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---
|
||||||
|
// TODO: will be implemented when serialization is done for thss shares
|
||||||
|
// ---
|
||||||
|
// #[test]
|
||||||
|
// #[should_panic(expected = "ShareParsingError")]
|
||||||
|
// fn test_recover_invalid_b64() {
|
||||||
|
// let share1 = Share {
|
||||||
|
// id: 1,
|
||||||
|
// threshold: 2,
|
||||||
|
// shares_count: 2,
|
||||||
|
// data: "1YAYwmOHqZ69jA".to_string().into_bytes(),
|
||||||
|
// metadata: None
|
||||||
|
// };
|
||||||
|
// let share2 = Share {
|
||||||
|
// id: 2,
|
||||||
|
// threshold: 2,
|
||||||
|
// shares_count: 2,
|
||||||
|
// data: "YJZQDG((((m22Y)))77Gw".to_string().into_bytes(),
|
||||||
|
// metadata: None
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// let shares = vec![share1, share2];
|
||||||
|
//
|
||||||
|
// recover_secret(&shares).unwrap();
|
||||||
|
// }
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic(expected = "DuplicateShareId")]
|
||||||
|
fn test_recover_duplicate_shares_number() {
|
||||||
|
let share1 = Share {
|
||||||
|
id: 1,
|
||||||
|
threshold: 2,
|
||||||
|
shares_count: 2,
|
||||||
|
data: "1YAYwmOHqZ69jA".to_string().into_bytes(),
|
||||||
|
metadata: None,
|
||||||
|
};
|
||||||
|
let share2 = Share {
|
||||||
|
id: 1,
|
||||||
|
threshold: 2,
|
||||||
|
shares_count: 2,
|
||||||
|
data: "YJZQDGm22Y77Gw".to_string().into_bytes(),
|
||||||
|
metadata: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let shares = vec![share1, share2];
|
||||||
|
|
||||||
|
recover_secret(&shares).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic(expected = "DuplicateShareData")]
|
||||||
|
fn test_recover_duplicate_shares_data() {
|
||||||
|
let share1 = Share {
|
||||||
|
id: 1,
|
||||||
|
threshold: 2,
|
||||||
|
shares_count: 2,
|
||||||
|
data: "1YAYwmOHqZ69jA".to_string().into_bytes(),
|
||||||
|
metadata: None,
|
||||||
|
};
|
||||||
|
let share2 = Share {
|
||||||
|
id: 2,
|
||||||
|
threshold: 2,
|
||||||
|
shares_count: 2,
|
||||||
|
data: "1YAYwmOHqZ69jA".to_string().into_bytes(),
|
||||||
|
metadata: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let shares = vec![share1, share2];
|
||||||
|
|
||||||
|
recover_secret(&shares).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic(expected = "MissingShares")]
|
||||||
|
fn test_recover_too_few_shares() {
|
||||||
|
let share1 = Share {
|
||||||
|
id: 1,
|
||||||
|
threshold: 3,
|
||||||
|
shares_count: 3,
|
||||||
|
data: "1YAYwmOHqZ69jA".to_string().into_bytes(),
|
||||||
|
metadata: None,
|
||||||
|
};
|
||||||
|
let share2 = Share {
|
||||||
|
id: 2,
|
||||||
|
threshold: 3,
|
||||||
|
shares_count: 3,
|
||||||
|
data: "YJZQDGm22Y77Gw".to_string().into_bytes(),
|
||||||
|
metadata: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let shares = vec![share1, share2];
|
||||||
|
|
||||||
|
recover_secret(&shares).unwrap();
|
||||||
|
}
|
Reference in New Issue
Block a user