/*! A module for the protocol for the user to redeem an open invitation with the BA (bridge authority) to receive their initial Lox credential. The credential will have attributes: - id: jointly chosen by the user and BA - bucket: set by the BA - trust_level: 0 - level_since: today - invites_remaining: 0 - invites_issued: 0 */ use curve25519_dalek::ristretto::RistrettoBasepointTable; use curve25519_dalek::ristretto::RistrettoPoint; use curve25519_dalek::scalar::Scalar; use curve25519_dalek::traits::IsIdentity; use zkp::CompactProof; use zkp::ProofError; use zkp::Transcript; use super::{BridgeAuth, IssuerPubKey}; use super::{CMZ_A, CMZ_A_TABLE, CMZ_B, CMZ_B_TABLE}; /// The request message for this protocol pub struct Request { invite: [u8; super::OPENINV_LENGTH], D: RistrettoPoint, EncIdClient: (RistrettoPoint, RistrettoPoint), piUserBlinding: CompactProof, } #[derive(Debug)] /// The client state for this protocol pub struct State { d: Scalar, D: RistrettoPoint, EncIdClient: (RistrettoPoint, RistrettoPoint), id_client: Scalar, } /// The response message for this protocol pub struct Response { P: RistrettoPoint, EncQ: (RistrettoPoint, RistrettoPoint), id_server: Scalar, TId: RistrettoPoint, bucket: Scalar, level_since: Scalar, P_noopmigration: RistrettoPoint, EncQ_noopmigration: (RistrettoPoint, RistrettoPoint), TId_noopmigration: RistrettoPoint, } // The userblinding ZKP define_proof! { userblinding, "Open Invitation User Blinding", (d, eid_client, id_client), (EncIdClient0, EncIdClient1, D), (B) : EncIdClient0 = (eid_client*B), EncIdClient1 = (id_client*B + eid_client*D), D = (d*B) } /// Submit an open invitation issued by the BridgeDb to receive your /// first Lox credential pub fn request(invite: &[u8; super::OPENINV_LENGTH]) -> (Request, State) { let B: &RistrettoPoint = &CMZ_B; let Btable: &RistrettoBasepointTable = &CMZ_B_TABLE; // Pick an ElGamal keypair let mut rng = rand::thread_rng(); let d = Scalar::random(&mut rng); let D = &d * Btable; // Pick a random client component of the id let id_client = Scalar::random(&mut rng); // Encrypt it (times the basepoint B) to the ElGamal public key D we // just created let eid_client = Scalar::random(&mut rng); let EncIdClient = (&eid_client * Btable, &id_client * Btable + eid_client * D); // Construct the proof of correct user blinding let mut transcript = Transcript::new(b"open invite user blinding"); let piUserBlinding = userblinding::prove_compact( &mut transcript, userblinding::ProveAssignments { B: &B, EncIdClient0: &EncIdClient.0, EncIdClient1: &EncIdClient.1, D: &D, d: &d, eid_client: &eid_client, id_client: &id_client, }, ) .0; ( Request { invite: *invite, D, EncIdClient, piUserBlinding, }, State { d, D, EncIdClient, id_client, }, ) }