diff --git a/Cargo.toml b/Cargo.toml index e7a6ba0..80018b2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,9 +1,11 @@ [package] name = "rusty_secrets" -version = "0.0.1" -description = "Implementation of threshold Shamir secret sharing in the Rust programming language." +version = "0.0.2" +description = "Implementation of threshold Shamir secret sharing in the Rust programming language." license = "GPLv3" readme = "README.md" +build = "build.rs" + [dependencies] getopts = "^0.2.14" diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..e262a97 --- /dev/null +++ b/build.rs @@ -0,0 +1,98 @@ +use std::env; +use std::fs::File; +use std::io::Write; +use std::path::Path; +use std::fmt; +use std::num::Wrapping; + +const POLY: u8 = 0x1D; + +/// replicates the least significant bit to every other bit +#[inline] +fn mask(bit: u8) -> u8 { + (Wrapping(0u8) - Wrapping(bit & 1)).0 +} + +/// multiplies a polynomial with x and returns the residual +/// of the polynomial division with POLY as divisor +#[inline] +fn xtimes(poly: u8) -> u8 { + (poly << 1) ^ (mask(poly >> 7) & POLY) +} + +struct Tables { + exp: [u8; 256], + log: [u8; 256], + inv: [u8; 256] +} + +fn generate_tables(mut file: &File) { + let mut tabs = Tables { + exp: [0; 256], + log: [0; 256], + inv: [0; 256] + }; + + let mut tmp = 1; + for power in 0..255usize { + tabs.exp[power] = tmp; + tabs.log[tmp as usize] = power as u8; + tmp = xtimes(tmp); + } + tabs.exp[255] = 1; + for x in 1..256usize { + let l = tabs.log[x]; + let nl = if l==0 { 0 } else { 255 - l }; + let i = tabs.exp[nl as usize]; + tabs.inv[x] = i; + } + + match write!(file, "{}", tabs) { + Ok(()) => {} + Err(_) => panic!("Could not format the table. Aborting build.") + }; +} + +fn farray(array: [u8; 256], f: &mut fmt::Formatter) -> fmt::Result { + for (index, value) in array.into_iter().enumerate() { + try!(write!(f, "{}", value)); + if index != array.len()-1 { + try!(write!(f, ",")); + } + } + Ok(()) +} + +impl fmt::Display for Tables { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + try!(write!(f, "Tables {{\n")); + try!(write!(f, " exp: [")); + try!(farray(self.exp, f)); + try!(write!(f, "],\n")); + try!(write!(f, " log: [")); + try!(farray(self.log, f)); + try!(write!(f, "],\n")); + try!(write!(f, " inv: [")); + try!(farray(self.inv, f)); + try!(write!(f, "]\n")); + write!(f, "}};") + } +} + +#[allow(unused_must_use)] +fn main() { + let out_dir = env::var("OUT_DIR").unwrap(); + let dest = Path::new(&out_dir).join("nothinghardcoded.rs"); + + let mut f = File::create(&dest).unwrap(); + + write!(f, "pub struct Tables {{ + pub exp: [u8; 256], + pub log: [u8; 256], + pub inv: [u8; 256] +}} + +pub static TABLES: Tables = "); + + generate_tables(&f); +} diff --git a/src/lib/gf256.rs b/src/lib/gf256.rs index 8c026a2..b151c0c 100644 --- a/src/lib/gf256.rs +++ b/src/lib/gf256.rs @@ -1,59 +1,12 @@ //! This module provides the Gf256 type which is used to represent //! elements of a finite field wich 256 elements. -use std::num::Wrapping; use std::ops::{ Add, Sub, Mul, Div }; -use std::sync::{ Once, ONCE_INIT }; -const POLY: u8 = 0x1D; // represents x^8 + x^4 + x^3 + x^2 + 1 - -/// replicates the least significant bit to every other bit -#[inline] -fn mask(bit: u8) -> u8 { - (Wrapping(0u8) - Wrapping(bit & 1)).0 -} - -/// multiplies a polynomial with x and returns the residual -/// of the polynomial division with POLY as divisor -#[inline] -fn xtimes(poly: u8) -> u8 { - (poly << 1) ^ (mask(poly >> 7) & POLY) -} - -/// Tables used for multiplication and division -struct Tables { - exp: [u8; 256], - log: [u8; 256], - inv: [u8; 256] -} - -static INIT: Once = ONCE_INIT; -static mut TABLES: Tables = Tables { - exp: [0; 256], - log: [0; 256], - inv: [0; 256] -}; +include!(concat!(env!("OUT_DIR"), "/nothinghardcoded.rs")); fn get_tables() -> &'static Tables { - INIT.call_once(|| { - // mutable access is fine because of synchronization via INIT - let tabs = unsafe { &mut TABLES }; - let mut tmp = 1; - for power in 0..255usize { - tabs.exp[power] = tmp; - tabs.log[tmp as usize] = power as u8; - tmp = xtimes(tmp); - } - tabs.exp[255] = 1; - for x in 1..256usize { - let l = tabs.log[x]; - let nl = if l==0 { 0 } else { 255 - l }; - let i = tabs.exp[nl as usize]; - tabs.inv[x] = i; - } - }); - // We're guaranteed to have TABLES initialized by now - return unsafe { &TABLES }; + return &TABLES; } /// Type for elements of a finite field with 256 elements @@ -93,11 +46,6 @@ impl Gf256 { let tabs = get_tables(); Gf256 { poly: tabs.exp[power as usize] } } -/* - pub fn inv(&self) -> Option { - self.log().map(|l| Gf256::exp(255 - l)) - } -*/ } impl Add for Gf256 {