Browse Source

Initial commit.

Michele Orrù 10 months ago
commit
8518600545
4 changed files with 578 additions and 0 deletions
  1. 228 0
      Cargo.lock
  2. 15 0
      Cargo.toml
  3. 33 0
      src/lib.rs
  4. 302 0
      src/msp/mod.rs

+ 228 - 0
Cargo.lock

@@ -0,0 +1,228 @@
+[[package]]
+name = "abe"
+version = "0.1.0"
+dependencies = [
+ "nalgebra 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "nom 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pairing 0.13.2",
+ "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "alga"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "approx 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-complex 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "approx"
+version = "0.1.1"
+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 = "blake2"
+version = "0.6.1"
+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)",
+ "crypto-mac 0.4.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.3 (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 = "byteorder"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "compiler_error"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "constant_time_eq"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "crypto-mac"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "generic-array 0.8.3 (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.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "fuchsia-zircon"
+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"
+dependencies = [
+ "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "generic-array"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "typenum 1.9.0 (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 = "matrixmultiply"
+version = "0.1.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rawpointer 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "memchr"
+version = "1.0.2"
+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 = "nalgebra"
+version = "0.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "alga 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "approx 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "generic-array 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "matrixmultiply 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-complex 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
+ "typenum 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "nodrop"
+version = "0.1.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "nom"
+version = "3.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "compiler_error 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "num-complex"
+version = "0.1.41"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "num-traits"
+version = "0.1.41"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "pairing"
+version = "0.13.2"
+dependencies = [
+ "alga 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "blake2 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.1.41 (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]]
+name = "rawpointer"
+version = "0.1.0"
+source = "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 = "typenum"
+version = "1.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[metadata]
+"checksum alga 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9a9749cf5cfdca30ac35de67358fb24e2d26a88e2819ee83efb794a09f0b421b"
+"checksum approx 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08abcc3b4e9339e33a3d0a5ed15d84a687350c05689d825e0f6655eef9e76a94"
+"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
+"checksum blake2 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "53bf612c0f2839b7e764ebac65d6cb985f7c6812de399d0728038f4b1da141bc"
+"checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40"
+"checksum byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff81738b726f5d099632ceaffe7fb65b90212e8dce59d518729e7e8634032d3d"
+"checksum compiler_error 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ef975f6d3622b15ea669c8075fefa5a9bc4bfae1b8b221ab9962daff003b3047"
+"checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e"
+"checksum crypto-mac 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "779015233ac67d65098614aec748ac1c756ab6677fa2e14cf8b37c08dfed1198"
+"checksum digest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e5b29bf156f3f4b3c4f610a25ff69370616ae6e0657d416de22645483e72af0a"
+"checksum fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f6c0581a4e363262e52b87f59ee2afe3415361c6ec35e665924eb08afe8ff159"
+"checksum fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "43f3795b4bae048dc6123a6b972cadde2e676f9ded08aef6bb77f5f157684a82"
+"checksum generic-array 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fceb69994e330afed50c93524be68c42fa898c2d9fd4ee8da03bd7363acd26f2"
+"checksum libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "5ba3df4dcb460b9dfbd070d41c94c19209620c191b0340b929ce748a2bcd42d2"
+"checksum matrixmultiply 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "cac1a66eab356036af85ea093101a14223dc6e3f4c02a59b7d572e5b93270bf7"
+"checksum memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a"
+"checksum nalgebra 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c8516d8710f28c64cfc75b274c75c55c967ad4ece7090521b3c065de1d12336b"
+"checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2"
+"checksum nom 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05aec50c70fd288702bcd93284a8444607f3292dbdf2a30de5ea5dcdbe72287b"
+"checksum num-complex 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "58de7b4bf7cf5dbecb635a5797d489864eadd03b107930cbccf9e0fd7428b47c"
+"checksum num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cacfcab5eb48250ee7d0c7896b51a2c5eec99c1feea5f32025635f5ae4b00070"
+"checksum rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)" = "6475140dfd8655aeb72e1fd4b7a1cc1c202be65d71669476e392fe62532b9edd"
+"checksum rawpointer 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ebac11a9d2e11f2af219b8b8d833b76b1ea0e054aa0e8d8e9e4cbde353bdf019"
+"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
+"checksum typenum 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "13a99dc6780ef33c78780b826cf9d2a78840b72cae9474de4bcaf9051e60ebbd"

+ 15 - 0
Cargo.toml

@@ -0,0 +1,15 @@
+[package]
+name = "abe"
+version = "0.1.0"
+authors = ["Michele Orrù <michele.orru@ens.fr>"]
+
+[dependencies]
+rand = "0.3.18"
+nalgebra = "0.13"
+
+[dependencies.pairing]
+path = "/home/maker/dev/pairing"
+
+[dependencies.nom]
+version = "^3.2"
+features = ["nightly"]

+ 33 - 0
src/lib.rs

@@ -0,0 +1,33 @@
+#[macro_use]
+extern crate nom;
+extern crate nalgebra as na;
+extern crate pairing;
+extern crate rand;
+
+use std::collections::HashMap;
+
+use pairing::{CurveProjective, Engine, Field, PrimeField};
+use rand::{Rng, Rand};
+
+pub mod msp;
+
+pub struct Mk<E: Engine> {
+    alpha: E::Fr,
+    w:     E::Fr,
+}
+
+pub struct Pk<E: Engine> {
+    alpha_t: E::Fqk,
+    w_1:     E::G1,
+}
+
+
+
+impl<E: Engine> Mk<E> {
+    fn new(mut rng: &mut Rng, n: u32) -> Self {
+        Mk {
+            alpha: E::Fr::rand(&mut rng),
+            w:     E::Fr::rand(&mut rng),
+        }
+    }
+}

+ 302 - 0
src/msp/mod.rs

@@ -0,0 +1,302 @@
+use na::{DMatrix, DVector};
+
+use pairing::{PrimeField, Field};
+use pairing::bls12_381::{Fq, FqRepr};
+
+pub fn u64_to_field<F: PrimeField>(x: u64) -> F {
+    F::from_repr(
+        <F::Repr as From<u64>>::from(x)
+    ).unwrap()
+}
+
+
+#[derive(Debug, Clone, PartialEq)]
+pub enum Gate<'a> {
+    Attribute(&'a [u8]),
+    Threshold {t: usize,  children: Vec<Gate<'a>>},
+}
+
+impl<'a> Gate<'a> {
+    fn children(self) -> Vec<Gate<'a>> {
+        match self {
+            Gate::Threshold {children, ..} => children,
+            Gate::Attribute (_) => Vec::new(),
+        }
+    }
+
+    fn label(self) -> &'a [u8] {
+        match self {
+            Gate::Threshold {..} => b"",
+            Gate::Attribute (l)  => l,
+        }
+    }
+
+    fn lsss(&self) -> DMatrix<u64> {
+        match self {
+            &Gate::Attribute (_)  => DMatrix::from_row_slice(1, 1, &[1u64]),
+            &Gate::Threshold {t, ref children} => {
+                let m = children.len();
+                DMatrix::from_fn(m, t, |i, j| {
+                    ((i as u64) + 1).pow(j as u32)
+                })
+            }
+        }
+    }
+
+    fn rec_msp(ast: AS<'a>)  -> AS<'a>{
+        // find the first threshold-tree string rather than a simple attribute
+        let at = ast.rho.iter().enumerate().skip_while(|&(_, g)| {
+            match *g {
+                Gate::Attribute (_) => true,
+                Gate::Threshold {..} => false,
+            }
+        }).next();
+
+        // if none is found, simply return ast, we're done.
+        // otherwise, [cont.]
+        if let Some((i, g)) = at {
+            let mg = g.lsss();
+
+            // refresh rho with the resolved attribute
+            let mut rho = ast.rho.clone();
+            rho.remove(i);
+            // XXX. lots of cloning for the safety god.
+            // perhaps the fact that we're inside a class can spare us
+            // the copy of all the gates?
+            for c in g.clone().children().iter() {
+                rho.insert(i, c.clone());
+            }
+
+            let (m1, d1) = ast.m.shape();
+            let (m2, d2) = mg.shape();
+
+            // insert the lsss matrix into m
+            let w = ast.m.row(i).kronecker(&mg.column(0));
+            let mg = mg.remove_column(0);
+            let m = ast.m.remove_row(i);
+
+            let m = DMatrix::from_fn(
+                m1 + m2 - 1,
+                d1 + d2 - 1,
+                |row, col| {
+                    if row < i && col < d1           { m[(row, col)] }
+                    else if row < i && col >= d1     { 0 }
+                    else if row < i+m2 && col < d1   { w[(row-i, col)] }
+                    else if row < i+m2 && col >= d1  { mg[(row-i, col-d1)] }
+                    else if row >= i+m2 && col < d1  { m[(row-m2, col)] }
+                    else                             { 0 }
+                }
+            );
+            Self::rec_msp(AS {m, rho})
+        } else {
+            ast.clone()
+        }
+    }
+
+    fn msp(self) -> AS<'a> {
+        let rho = vec![self];
+        let m = DMatrix::from_row_slice(1, 1, &[1u64]);
+        let ast = Self::rec_msp(AS {m, rho});
+        ast
+    }
+
+}
+
+#[derive(Clone)]
+struct AS<'a> {
+    m: DMatrix<u64>,
+    rho: Vec<Gate<'a>>,
+}
+
+impl<'a> AS<'a> {
+    fn gen_shares<F: PrimeField>(&self) -> DVector<F> {
+        let m = DMatrix::<F>::from_fn(self.m.nrows(), self.m.ncols(),
+                                  |row, col| { u64_to_field(self.m[(row, col)]) }
+        );
+        DVector::from_fn(self.m.nrows(),
+                         |row, col| { F::one() }
+        )
+    }
+
+}
+
+mod tc {
+    use std::str;
+    use std::str::FromStr;
+    use nom::{digit, alphanumeric};
+    use msp::Gate;
+
+    named!(parens <Gate>, ws!(delimited!(tag!("("), threshold_gate, tag!(")") )) );
+
+    named!(threshold_gate <Gate>,
+           do_parse!(
+               t: threshold >>
+               children: attributes >>
+               (Gate::Threshold {t, children})
+           )
+    );
+
+    named!(attributes < Vec<Gate<'a>> >,
+           many1!(preceded!(tag!(","), parse))
+    );
+
+    named!(threshold <usize>,
+           map_res!(map_res!(ws!(digit), str::from_utf8),
+                FromStr::from_str)
+    );
+
+
+    named!(attribute <Gate>,
+           map!(ws!(alphanumeric), Gate::Attribute)
+    );
+
+    named!(pub parse <Gate>,
+           alt!(attribute | parens)
+    );
+}
+
+
+mod bc {
+    use nom::{IResult, alphanumeric};
+    use msp::Gate;
+
+    named!(parens<Gate>, ws!(delimited!( tag!("("), expr, tag!(")") )) );
+
+    named!(attribute <Gate>,
+           map!(ws!(alphanumeric), Gate::Attribute)
+    );
+
+    named!(gate <Gate>,
+           alt!(attribute | parens)
+    );
+
+    named!(term <Gate<'a>>,
+           do_parse!(
+               init: gate >>
+               res:  fold_many0!(
+                   pair!(alt!(tag!("^") | tag!("∧") | tag!("and")), gate),
+                   init,
+                   |acc, (op, g): (&[u8], Gate<'a>)| {
+                       let  v: Vec<Gate<'a>> = vec![acc, g];
+                       Gate::Threshold {t: 2usize, children: v}
+                   }
+               ) >>
+               (res)
+           )
+    );
+
+    named!(expr <Gate<'a>>,
+           do_parse!(
+               init: term >>
+               res:  fold_many0!(
+                   pair!(alt!(tag!("v") | tag!("or") | tag!("∨")), term),
+                   init,
+                   |acc, (op, g): (&[u8], Gate<'a>)| {
+                       let  v: Vec<Gate<'a>> = vec![acc, g];
+                       Gate::Threshold {t: 2usize, children: v}
+                   }
+               ) >>
+               (res)
+           )
+    );
+
+    // XXX. this needs to be changed into a result type.
+    // Also note that making instead "expr" pub will fuck up everything
+    // because the "lifetime is not defined" - not sure I really understood why.
+    pub fn parse(i: &[u8]) -> IResult<&[u8], Gate, u32> {
+        expr(i)
+    }
+}
+
+
+#[test]
+fn test_tc_parse() {
+    // see eprint 2010/374
+    let policy = b"(2, (2, (3, I, J, K, L), G, H), (2, A, B, C), (2, D, E, F))";
+    let (_, pp) = tc::parse(policy).unwrap();
+    let msp = pp.msp();
+    assert_eq!(msp.rho.len(), 12);
+    let expected = DMatrix::from_row_slice(12, 2 + (2-1) + (3-1) + (2-1) + (2-1),
+                                           &[1, 1, 1, 0, 0, 0, 0,
+                                             1, 1, 2, 0, 0, 0, 0,
+                                             1, 1, 3, 0, 0, 0, 0,
+                                             1, 2, 0, 1, 0, 0, 0,
+                                             1, 2, 0, 2, 0, 0, 0,
+                                             1, 2, 0, 3, 0, 0, 0,
+                                             1, 3, 0, 0, 1, 0, 0,
+                                             1, 3, 0, 0, 2, 0, 0,
+                                             1, 3, 0, 0, 3, 1, 1,
+                                             1, 3, 0, 0, 3, 2, 4,
+                                             1, 3, 0, 0, 3, 3, 9,
+                                             1, 3, 0, 0, 3, 4, 16,
+                                           ]
+    );
+    assert_eq!(expected, msp.m)
+}
+
+
+
+use std::collections::VecDeque;
+
+pub struct Bfs<'a> {
+    stack: VecDeque<Gate<'a>>
+}
+
+impl<'a> Bfs<'a> {
+    fn new(g: Gate<'a>) -> Self {
+        let mut stack = VecDeque::new();
+        stack.push_back(g);
+        Bfs { stack }
+    }
+
+}
+
+impl<'a> Iterator for Bfs<'a> {
+    type Item = Gate<'a>;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        let g = self.stack.pop_front()?;
+        let children = g.clone().children();
+        self.stack.extend(children.iter().cloned());
+        Some(g)
+    }
+
+}
+
+#[test]
+fn test_bc_parse() {
+    let policy = b"intern and topsecret or xkeyscore";
+    let (_, gate) = bc::parse(policy).unwrap();
+    let children = gate.children();
+    assert_eq!(children.len(), 2);
+}
+
+
+#[test]
+fn test_bfs() {
+    let policy = b"1 and (3 and 4)";
+    let (_, gate) = bc::parse(policy).unwrap();
+    assert_eq!(gate.clone().children().len(), 2);
+    let mut bfs = Bfs::new(gate);
+    let root = bfs.next();
+    let expected = Gate::Attribute(b"1");
+    assert_eq!(Some(expected), bfs.next());
+    assert_eq!(bfs.next().unwrap().children().len(), 2);
+}
+
+#[test]
+fn test_matrix_field() {
+    let policy = b"1 and 2";
+    let (_, gate) = bc::parse(policy).unwrap();
+    let msp = gate.msp();
+    let m = msp.m;
+    let mm = DVector::<Fq>::from_fn(m.ncols(),
+                              |row, col| {
+                                  u64_to_field(m[(row, col)])
+                              }
+    );
+    let v  = DVector::from_fn(m.ncols(), |row, col| { 1u64 });
+    let vv = DVector::from_fn(m.ncols(), |row, col| { Fq::one() });
+    let d = mm.dot(&vv);
+
+}