Remove CRC-24 dependency. Closes #3

This commit is contained in:
Frederic Jacobs
2016-04-02 11:00:52 +02:00
parent f1ad2b74f1
commit 16be20fcff
5 changed files with 18 additions and 73 deletions

View File

@ -1,8 +0,0 @@
2015-02-03:
* I changed the CRC-24 checksum computation to include the coding parameter
K and the share number N so that these numbers are also protected.
If you have older shares generated with a previous version, you can still
decode the secret by simply removing the checksum part of the shares.
* The README now includes more information about the inner workings of
secretshare and also a note on "perfect secrecy".

10
Cargo.lock generated
View File

@ -2,17 +2,11 @@
name = "secretshare"
version = "0.1.6"
dependencies = [
"crc24 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "crc24"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "getopts"
version = "0.2.14"
@ -20,7 +14,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "libc"
version = "0.2.8"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -28,7 +22,7 @@ name = "rand"
version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]

View File

@ -9,5 +9,4 @@ readme = "README.md"
[dependencies]
getopts = "^0.2.14"
rustc-serialize = "^0.3.18"
crc24 = "^0.1.6"
rand = "^0.3.14"

View File

@ -17,11 +17,11 @@ Passing a secret to secretshare for encoding:
```
$ echo My secret | ./secretshare -e2,5
2-1-1YAYwmOHqZ69jA-v+mz
2-2-YJZQDGm22Y77Gw-IhSh
2-3-+G9ovW9SAnUynQ-Elwi
2-4-F7rAjX3UOa53KA-b2vm
2-5-j0P4PHsw4lW+rg-XyNl
2-1-1YAYwmOHqZ69jA
2-2-YJZQDGm22Y77Gw
2-3-+G9ovW9SAnUynQ
2-4-F7rAjX3UOa53KA
2-5-j0P4PHsw4lW+rg
```
The parameters following the `-e` option tell `secretshare` to create 5 shares of which 2 will be necessary for decoding.
@ -29,7 +29,7 @@ The parameters following the `-e` option tell `secretshare` to create 5 shares o
Decoding a subset of shares (one share per line) can be done like this:
```
$ echo -e "2-2-YJZQDGm22Y77Gw-IhSh \n 2-4-F7rAjX3UOa53KA-b2vm" | ./secretshare -d
$ echo -e "2-2-YJZQDGm22Y77Gw \n 2-4-F7rAjX3UOa53KA" | ./secretshare -d
My secret
```
@ -62,9 +62,9 @@ The generated shares are lines of ASCII text.
# Structure of the shares
```
2-1-LiTyeXwEP71IUA-Qj6n
^ ^ ^^^^^^^^^^^^^^ ^^^^
K N D C
2-1-LiTyeXwEP71IUA
^ ^ ^^^^^^^^^^^^^^
K N D
```
A share is built out of three or four parts separated with a minus: K-N-D-C.
@ -73,10 +73,7 @@ how many distinct
shares of a specific secret are necessary to be able to recover the
secret. The number N identifies the share (ranging from 1 to the number
of shares that have been created). The D part is a Base64 encoding of
a specific share's raw data. The optional part C is a Base64 encoding
of a CRC-24 checksum of the concatenation of K and N as bytes followed
by the share's raw data (before Base64 encoding). The same checksum
algorithm is used in the OpenPGP format for “ASCII amoring”.
a specific share's raw data.
# A word on the secrecy

View File

@ -1,6 +1,5 @@
extern crate rustc_serialize as serialize;
extern crate getopts;
extern crate crc24;
extern crate rand;
use std::convert;
@ -154,22 +153,7 @@ fn parse_k_n(s: &str) -> io::Result<(u8, u8)> {
Ok((k, n))
}
/// computes a CRC-24 hash over the concatenated coding parameters k, n
/// and the raw share data
fn crc24_as_bytes(k: u8, n: u8, octets: &[u8]) -> [u8; 3] {
use std::hash::Hasher;
let mut h = crc24::Crc24Hasher::new();
h.write(&[k, n]);
h.write(octets);
let v = h.finish();
[((v >> 16) & 0xFF) as u8,
((v >> 8) & 0xFF) as u8,
( v & 0xFF) as u8]
}
fn perform_encode(k: u8, n: u8, with_checksums: bool) -> io::Result<()> {
fn perform_encode(k: u8, n: u8) -> io::Result<()> {
let secret = {
let limit: usize = 0x10000;
let stdin = io::stdin();
@ -192,12 +176,7 @@ fn perform_encode(k: u8, n: u8, with_checksums: bool) -> io::Result<()> {
};
for (index, share) in shares.iter().enumerate() {
let salad = share.to_base64(config);
if with_checksums {
let crc_bytes = crc24_as_bytes(k, (index+1) as u8, &**share);
println!("{}-{}-{}-{}", k, index+1, salad, crc_bytes.to_base64(config));
} else {
println!("{}-{}-{}", k, index+1, salad);
}
println!("{}-{}-{}", k, index+1, salad);
}
Ok(())
}
@ -218,13 +197,12 @@ fn read_shares() -> io::Result<(u8, Vec<(u8,Vec<u8>)>)> {
return Err(other_io_err("Share parse error: Expected 3 or 4 \
parts searated by a minus sign", None));
}
let (k, n, p3, opt_p4) = {
let (k, n, p3) = {
let mut iter = parts.into_iter();
let k = try!(iter.next().unwrap().parse::<u8>().map_err(pie2io));
let n = try!(iter.next().unwrap().parse::<u8>().map_err(pie2io));
let p3 = iter.next().unwrap();
let opt_p4 = iter.next();
(k, n, p3, opt_p4)
(k, n, p3)
};
if k < 1 || n < 1 {
return Err(other_io_err("Share parse error: Illegal K,N parameters", None));
@ -233,20 +211,6 @@ fn read_shares() -> io::Result<(u8, Vec<(u8,Vec<u8>)>)> {
p3.from_base64().map_err(|_| other_io_err(
"Share parse error: Base64 decoding of data block failed", None ))
);
if let Some(check) = opt_p4 {
if check.len() != 4 {
return Err(other_io_err("Share parse error: Checksum part is \
expected to be four characters", None));
}
let crc_bytes = try!(
check.from_base64().map_err(|_| other_io_err(
"Share parse error: Base64 decoding of checksum failed", None))
);
let mychksum = crc24_as_bytes(k, n, &*data);
if crc_bytes != mychksum {
return Err(other_io_err("Share parse error: Checksum mismatch", None));
}
}
if let Some((ck, cl)) = opt_k_l {
if ck != k || cl != data.len() {
return Err(other_io_err("Incompatible shares", None));
@ -311,7 +275,7 @@ fn main() {
return;
}
let action: Result<_,_> =
let action: Result<_,_> =
match (opt_matches.opt_present("e"), opt_matches.opt_present("d")) {
(false, false) => Err("Nothing to do! Use -e or -d"),
(true, true) => Err("Use either -e or -d and not both"),
@ -335,7 +299,7 @@ fn main() {
let result =
match action {
Ok(Action::Encode(k,n)) => perform_encode(k, n, true),
Ok(Action::Encode(k,n)) => perform_encode(k, n),
Ok(Action::Decode) => perform_decode(),
Err(e) => Err(other_io_err(e, None))
};
@ -345,4 +309,3 @@ fn main() {
// env::set_exit_status(1); // FIXME: unstable feature
}
}