open_invite.rs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. /*! A module for the protocol for the user to redeem an open invitation
  2. with the BA (bridge authority) to receive their initial Lox
  3. credential. The credential will have attributes:
  4. - id: jointly chosen by the user and BA
  5. - bucket: set by the BA
  6. - trust_level: 0
  7. - level_since: today
  8. - invites_remaining: 0
  9. - invites_issued: 0
  10. */
  11. use curve25519_dalek::ristretto::RistrettoBasepointTable;
  12. use curve25519_dalek::ristretto::RistrettoPoint;
  13. use curve25519_dalek::scalar::Scalar;
  14. use curve25519_dalek::traits::IsIdentity;
  15. use zkp::CompactProof;
  16. use zkp::ProofError;
  17. use zkp::Transcript;
  18. use super::{BridgeAuth, IssuerPubKey};
  19. use super::{CMZ_A, CMZ_A_TABLE, CMZ_B, CMZ_B_TABLE};
  20. /// The request message for this protocol
  21. pub struct Request {
  22. invite: [u8; super::OPENINV_LENGTH],
  23. D: RistrettoPoint,
  24. EncIdClient: (RistrettoPoint, RistrettoPoint),
  25. piUserBlinding: CompactProof,
  26. }
  27. #[derive(Debug)]
  28. /// The client state for this protocol
  29. pub struct State {
  30. d: Scalar,
  31. D: RistrettoPoint,
  32. EncIdClient: (RistrettoPoint, RistrettoPoint),
  33. id_client: Scalar,
  34. }
  35. /// The response message for this protocol
  36. pub struct Response {
  37. P: RistrettoPoint,
  38. EncQ: (RistrettoPoint, RistrettoPoint),
  39. id_server: Scalar,
  40. TId: RistrettoPoint,
  41. bucket: Scalar,
  42. level_since: Scalar,
  43. P_noopmigration: RistrettoPoint,
  44. EncQ_noopmigration: (RistrettoPoint, RistrettoPoint),
  45. TId_noopmigration: RistrettoPoint,
  46. }
  47. // The userblinding ZKP
  48. define_proof! {
  49. userblinding,
  50. "Open Invitation User Blinding",
  51. (d, eid_client, id_client),
  52. (EncIdClient0, EncIdClient1, D),
  53. (B) :
  54. EncIdClient0 = (eid_client*B),
  55. EncIdClient1 = (id_client*B + eid_client*D),
  56. D = (d*B)
  57. }
  58. /// Submit an open invitation issued by the BridgeDb to receive your
  59. /// first Lox credential
  60. pub fn request(invite: &[u8; super::OPENINV_LENGTH]) -> (Request, State) {
  61. let B: &RistrettoPoint = &CMZ_B;
  62. let Btable: &RistrettoBasepointTable = &CMZ_B_TABLE;
  63. // Pick an ElGamal keypair
  64. let mut rng = rand::thread_rng();
  65. let d = Scalar::random(&mut rng);
  66. let D = &d * Btable;
  67. // Pick a random client component of the id
  68. let id_client = Scalar::random(&mut rng);
  69. // Encrypt it (times the basepoint B) to the ElGamal public key D we
  70. // just created
  71. let eid_client = Scalar::random(&mut rng);
  72. let EncIdClient = (&eid_client * Btable, &id_client * Btable + eid_client * D);
  73. // Construct the proof of correct user blinding
  74. let mut transcript = Transcript::new(b"open invite user blinding");
  75. let piUserBlinding = userblinding::prove_compact(
  76. &mut transcript,
  77. userblinding::ProveAssignments {
  78. B: &B,
  79. EncIdClient0: &EncIdClient.0,
  80. EncIdClient1: &EncIdClient.1,
  81. D: &D,
  82. d: &d,
  83. eid_client: &eid_client,
  84. id_client: &id_client,
  85. },
  86. )
  87. .0;
  88. (
  89. Request {
  90. invite: *invite,
  91. D,
  92. EncIdClient,
  93. piUserBlinding,
  94. },
  95. State {
  96. d,
  97. D,
  98. EncIdClient,
  99. id_client,
  100. },
  101. )
  102. }