1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- // Implementation of CMZ14 credentials (GGM version, which is more
- // efficient, but makes a stronger security assumption): "Algebraic MACs
- // and Keyed-Verification Anonymous Credentials" (Chase, Meiklejohn,
- // and Zaverucha, CCS 2014)
- // The notation follows that of the paper "Hyphae: Social Secret
- // Sharing" (Lovecruft and de Valence, 2017), Section 4.
- #![allow(non_snake_case)]
- use sha2::Sha512;
- use curve25519_dalek::constants as dalek_constants;
- use curve25519_dalek::ristretto::RistrettoPoint;
- use curve25519_dalek::ristretto::RistrettoBasepointTable;
- use curve25519_dalek::scalar::Scalar;
- use lazy_static::lazy_static;
- lazy_static! {
- pub static ref CMZ_A: RistrettoPoint =
- RistrettoPoint::hash_from_bytes::<Sha512>(b"CMZ Generator A");
- pub static ref CMZ_B: RistrettoPoint =
- dalek_constants::RISTRETTO_BASEPOINT_POINT;
- pub static ref CMZ_A_TABLE: RistrettoBasepointTable =
- RistrettoBasepointTable::create(&CMZ_A);
- pub static ref CMZ_B_TABLE: RistrettoBasepointTable =
- dalek_constants::RISTRETTO_BASEPOINT_TABLE;
- }
- #[derive(Clone,Debug)]
- pub struct IssuerPrivKey {
- x0tilde: Scalar,
- x: Vec<Scalar>,
- }
- impl IssuerPrivKey {
- // Create an IssuerPrivKey for credentials with the given number of
- // attributes.
- pub fn new(n: u16) -> IssuerPrivKey {
- let mut rng: rand::rngs::ThreadRng = rand::thread_rng();
- let x0tilde: Scalar = Scalar::random(&mut rng);
- let mut x: Vec<Scalar> = Vec::with_capacity((n+1) as usize);
- // Set x to a vector of n+1 random Scalars
- x.resize_with((n+1) as usize, || { Scalar::random(&mut rng) });
- IssuerPrivKey { x0tilde, x }
- }
- }
- #[derive(Clone,Debug)]
- pub struct IssuerPubKey {
- X: Vec<RistrettoPoint>,
- }
- impl IssuerPubKey {
- // Create an IssuerPubKey from the corresponding IssuerPrivKey
- pub fn new(privkey: &IssuerPrivKey) -> IssuerPubKey {
- let Atable : &RistrettoBasepointTable = &CMZ_A_TABLE;
- let Btable : &RistrettoBasepointTable = &CMZ_B_TABLE;
- let n_plus_one: usize = privkey.x.len();
- let mut X: Vec<RistrettoPoint> = Vec::with_capacity(n_plus_one);
- // The first element is a special case; it is
- // X[0] = x0tilde*A + x[0]*B
- X.push(&privkey.x0tilde * Atable + &privkey.x[0] * Btable);
- // The other elements (1 through n) are X[i] = x[i]*A
- for i in 1..n_plus_one {
- X.push(&privkey.x[i] * Atable);
- }
- IssuerPubKey { X }
- }
- }
- #[derive(Debug)]
- pub struct Issuer {
- privkey: IssuerPrivKey,
- pubkey: IssuerPubKey,
- }
- impl Issuer {
- // Create an issuer for credentials with the given number of
- // attributes
- pub fn new(n: u16) -> Issuer {
- let privkey = IssuerPrivKey::new(n);
- let pubkey = IssuerPubKey::new(&privkey);
- Issuer { privkey, pubkey }
- }
- }
|