|
@@ -2,18 +2,24 @@
|
|
// lowercase letters
|
|
// lowercase letters
|
|
#![allow(non_snake_case)]
|
|
#![allow(non_snake_case)]
|
|
|
|
|
|
-use curve25519_dalek::ristretto::RistrettoPoint as Point;
|
|
|
|
-use curve25519_dalek::scalar::Scalar;
|
|
|
|
|
|
+use ff::PrimeField;
|
|
|
|
+use group::Group;
|
|
|
|
|
|
/// The CMZMac struct represents a MAC on a CMZ credential.
|
|
/// The CMZMac struct represents a MAC on a CMZ credential.
|
|
#[derive(Copy, Clone, Debug, Default)]
|
|
#[derive(Copy, Clone, Debug, Default)]
|
|
-pub struct CMZMac {
|
|
|
|
- pub P: Point,
|
|
|
|
- pub Q: Point,
|
|
|
|
|
|
+pub struct CMZMac<G: Group> {
|
|
|
|
+ pub P: G,
|
|
|
|
+ pub Q: G,
|
|
}
|
|
}
|
|
|
|
|
|
-/// The CMZCredential trail implemented by all CMZ credential struct types.
|
|
|
|
-pub trait CMZCredential {
|
|
|
|
|
|
+/// The CMZCredential trait implemented by all CMZ credential struct types.
|
|
|
|
+pub trait CMZCredential<G: Group> {
|
|
|
|
+ /// The type of attributes for this credential
|
|
|
|
+ type Scalar: PrimeField;
|
|
|
|
+
|
|
|
|
+ /// The type of the coordinates of the MAC for this credential
|
|
|
|
+ type Point: Group;
|
|
|
|
+
|
|
/// Produce a vector of strings containing the names of the
|
|
/// Produce a vector of strings containing the names of the
|
|
/// attributes of this credential. (The MAC is not included.)
|
|
/// attributes of this credential. (The MAC is not included.)
|
|
fn attrs() -> Vec<&'static str>;
|
|
fn attrs() -> Vec<&'static str>;
|
|
@@ -23,35 +29,57 @@ pub trait CMZCredential {
|
|
|
|
|
|
/// Get a reference to one of the attributes, specified by name as a
|
|
/// Get a reference to one of the attributes, specified by name as a
|
|
/// string.
|
|
/// string.
|
|
- fn attr(&self, name: &str) -> &Option<Scalar>;
|
|
|
|
|
|
+ fn attr(&self, name: &str) -> &Option<Self::Scalar>;
|
|
|
|
|
|
/// Get a mutable reference to one of the attributes, specified by
|
|
/// Get a mutable reference to one of the attributes, specified by
|
|
/// name as a string.
|
|
/// name as a string.
|
|
- fn attr_mut(&mut self, name: &str) -> &mut Option<Scalar>;
|
|
|
|
|
|
+ fn attr_mut(&mut self, name: &str) -> &mut Option<Self::Scalar>;
|
|
}
|
|
}
|
|
|
|
|
|
/** The CMZ macro for declaring CMZ credentials.
|
|
/** The CMZ macro for declaring CMZ credentials.
|
|
|
|
|
|
Use this macro to declare a CMZ credential struct type.
|
|
Use this macro to declare a CMZ credential struct type.
|
|
|
|
|
|
-`CMZ!{ Name: attr1, attr2, attr3 }`
|
|
|
|
|
|
+`CMZ!{ Name<Group>: attr1, attr2, attr3 }`
|
|
|
|
|
|
will declare a struct type called `Name`, containing one field for each
|
|
will declare a struct type called `Name`, containing one field for each
|
|
of the listed attributes. The attribute fields will be of type
|
|
of the listed attributes. The attribute fields will be of type
|
|
`Option<Scalar>`. It will also automatically add a field called `MAC`
|
|
`Option<Scalar>`. It will also automatically add a field called `MAC`
|
|
of type `CMZMac`, and an implementation (via the `CMZCred` derive) of
|
|
of type `CMZMac`, and an implementation (via the `CMZCred` derive) of
|
|
-the `CMZCredential` trait.
|
|
|
|
|
|
+the `CMZCredential` trait. The mathematical group used (the field for
|
|
|
|
+the values of the attributes and the group elements for the commitments
|
|
|
|
+and MAC components) is Group (which must satisfy the group::Group
|
|
|
|
+trait). If "<Group>" is omitted, the macro will default to using a
|
|
|
|
+group called "G", which you can define, for example, as:
|
|
|
|
+
|
|
|
|
+use curve25519_dalek::ristretto::RistrettoPoint as G;
|
|
|
|
+
|
|
|
|
+or:
|
|
|
|
+
|
|
|
|
+use curve25519_dalek::ristretto::RistrettoPoint;
|
|
|
|
+type G = RistrettoPoint;
|
|
|
|
|
|
*/
|
|
*/
|
|
#[macro_export]
|
|
#[macro_export]
|
|
macro_rules! CMZ {
|
|
macro_rules! CMZ {
|
|
|
|
+ ( $name: ident < $G: ident > : $( $id: ident ),+ ) => {
|
|
|
|
+ #[derive(CMZCred,Copy,Clone,Debug,Default)]
|
|
|
|
+ #[cmzcred_group(group = $G)]
|
|
|
|
+ pub struct $name {
|
|
|
|
+ $(
|
|
|
|
+ pub $id: Option<<$G as Group>::Scalar>,
|
|
|
|
+ )+
|
|
|
|
+ pub MAC: CMZMac<$G>,
|
|
|
|
+ }
|
|
|
|
+ };
|
|
( $name: ident : $( $id: ident ),+ ) => {
|
|
( $name: ident : $( $id: ident ),+ ) => {
|
|
#[derive(CMZCred,Copy,Clone,Debug,Default)]
|
|
#[derive(CMZCred,Copy,Clone,Debug,Default)]
|
|
|
|
+ #[cmzcred_group(group = G)]
|
|
pub struct $name {
|
|
pub struct $name {
|
|
$(
|
|
$(
|
|
- pub $id: Option<Scalar>,
|
|
|
|
|
|
+ pub $id: Option<<G as Group>::Scalar>,
|
|
)+
|
|
)+
|
|
- pub MAC: CMZMac,
|
|
|
|
|
|
+ pub MAC: CMZMac<G>,
|
|
}
|
|
}
|
|
};
|
|
};
|
|
}
|
|
}
|
|
@@ -63,6 +91,8 @@ mod tests {
|
|
|
|
|
|
#[test]
|
|
#[test]
|
|
fn lox_credential_test() {
|
|
fn lox_credential_test() {
|
|
|
|
+ use curve25519_dalek::ristretto::RistrettoPoint as G;
|
|
|
|
+
|
|
CMZ! { Lox:
|
|
CMZ! { Lox:
|
|
id,
|
|
id,
|
|
bucket,
|
|
bucket,
|
|
@@ -78,13 +108,13 @@ mod tests {
|
|
|
|
|
|
println!("{:#?}", L);
|
|
println!("{:#?}", L);
|
|
|
|
|
|
- L.bucket = Some(Scalar::ONE);
|
|
|
|
|
|
+ L.bucket = Some(<G as Group>::Scalar::ONE);
|
|
|
|
|
|
println!("{:#?}", L);
|
|
println!("{:#?}", L);
|
|
|
|
|
|
println!("{:#?}", L.attr("bucket"));
|
|
println!("{:#?}", L.attr("bucket"));
|
|
|
|
|
|
- *L.attr_mut("id") = Some(Scalar::ONE);
|
|
|
|
|
|
+ *L.attr_mut("id") = Some(<G as Group>::Scalar::ONE);
|
|
|
|
|
|
println!("{:#?}", L);
|
|
println!("{:#?}", L);
|
|
}
|
|
}
|