ggm.rs 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. // Implementation of CMZ14 credentials (GGM version, which is more
  2. // efficient, but makes a stronger security assumption): "Algebraic MACs
  3. // and Keyed-Verification Anonymous Credentials" (Chase, Meiklejohn,
  4. // and Zaverucha, CCS 2014)
  5. // The notation follows that of the paper "Hyphae: Social Secret
  6. // Sharing" (Lovecruft and de Valence, 2017), Section 4.
  7. #![allow(non_snake_case)]
  8. use sha2::Sha512;
  9. use curve25519_dalek::constants as dalek_constants;
  10. use curve25519_dalek::ristretto::RistrettoPoint;
  11. use curve25519_dalek::ristretto::RistrettoBasepointTable;
  12. use curve25519_dalek::scalar::Scalar;
  13. use lazy_static::lazy_static;
  14. lazy_static! {
  15. pub static ref CMZ_A: RistrettoPoint =
  16. RistrettoPoint::hash_from_bytes::<Sha512>(b"CMZ Generator A");
  17. pub static ref CMZ_B: RistrettoPoint =
  18. dalek_constants::RISTRETTO_BASEPOINT_POINT;
  19. pub static ref CMZ_A_TABLE: RistrettoBasepointTable =
  20. RistrettoBasepointTable::create(&CMZ_A);
  21. pub static ref CMZ_B_TABLE: RistrettoBasepointTable =
  22. dalek_constants::RISTRETTO_BASEPOINT_TABLE;
  23. }
  24. #[derive(Clone,Debug)]
  25. pub struct IssuerPrivKey {
  26. x0tilde: Scalar,
  27. x: Vec<Scalar>,
  28. }
  29. impl IssuerPrivKey {
  30. // Create an IssuerPrivKey for credentials with the given number of
  31. // attributes.
  32. pub fn new(n: u16) -> IssuerPrivKey {
  33. let mut rng: rand::rngs::ThreadRng = rand::thread_rng();
  34. let x0tilde: Scalar = Scalar::random(&mut rng);
  35. let mut x: Vec<Scalar> = Vec::with_capacity((n+1) as usize);
  36. // Set x to a vector of n+1 random Scalars
  37. x.resize_with((n+1) as usize, || { Scalar::random(&mut rng) });
  38. IssuerPrivKey { x0tilde, x }
  39. }
  40. }
  41. #[derive(Clone,Debug)]
  42. pub struct IssuerPubKey {
  43. X: Vec<RistrettoPoint>,
  44. }
  45. impl IssuerPubKey {
  46. // Create an IssuerPubKey from the corresponding IssuerPrivKey
  47. pub fn new(privkey: &IssuerPrivKey) -> IssuerPubKey {
  48. let Atable : &RistrettoBasepointTable = &CMZ_A_TABLE;
  49. let Btable : &RistrettoBasepointTable = &CMZ_B_TABLE;
  50. let n_plus_one: usize = privkey.x.len();
  51. let mut X: Vec<RistrettoPoint> = Vec::with_capacity(n_plus_one);
  52. // The first element is a special case; it is
  53. // X[0] = x0tilde*A + x[0]*B
  54. X.push(&privkey.x0tilde * Atable + &privkey.x[0] * Btable);
  55. // The other elements (1 through n) are X[i] = x[i]*A
  56. for i in 1..n_plus_one {
  57. X.push(&privkey.x[i] * Atable);
  58. }
  59. IssuerPubKey { X }
  60. }
  61. }
  62. #[derive(Debug)]
  63. pub struct Issuer {
  64. privkey: IssuerPrivKey,
  65. pubkey: IssuerPubKey,
  66. }
  67. impl Issuer {
  68. // Create an issuer for credentials with the given number of
  69. // attributes
  70. pub fn new(n: u16) -> Issuer {
  71. let privkey = IssuerPrivKey::new(n);
  72. let pubkey = IssuerPubKey::new(&privkey);
  73. Issuer { privkey, pubkey }
  74. }
  75. }