#[allow(non_snake_case)]
pub mod migration {
use super::*;
use sigma_compiler::*;
use group::GroupEncoding;
pub type Scalar = <Lox as CMZCredential>::Scalar;
pub type Point = <Lox as CMZCredential>::Point;
#[serde_as]
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
pub struct Request {
#[serde_as(as = "SerdePoint")]
pub C_iss_cred_N: Point,
#[serde_as(as = "SerdePoint")]
pub P_show_cred_L: Point,
#[serde_as(as = "SerdePoint")]
pub CQ_show_cred_L: Point,
#[serde_as(as = "SerdeScalar")]
pub show_Rattr_L_id: Scalar,
#[serde_as(as = "SerdeScalar")]
pub show_Rattr_L_trust_level: Scalar,
#[serde_as(as = "SerdePoint")]
pub C_show_Hattr_L_level_since: Point,
#[serde_as(as = "SerdeScalar")]
pub show_Rattr_L_invites_remaining: Scalar,
#[serde_as(as = "SerdeScalar")]
pub show_Rattr_L_blockages: Scalar,
#[serde_as(as = "SerdePoint")]
pub C_show_Hattr_L_bucket: Point,
#[serde_as(as = "SerdePoint")]
pub P_show_cred_M: Point,
#[serde_as(as = "SerdePoint")]
pub CQ_show_cred_M: Point,
#[serde_as(as = "SerdeScalar")]
pub show_Rattr_M_lox_id: Scalar,
#[serde_as(as = "SerdePoint")]
pub C_show_Hattr_M_to_bucket: Point,
#[serde_as(as = "SerdePoint")]
pub C_show_Hattr_M_from_bucket: Point,
#[serde(with = "serde_bytes")]
pub cli_proof: Vec<u8>,
}
impl TryFrom<&[u8]> for Request {
type Error = bincode::Error;
fn try_from(bytes: &[u8]) -> bincode::Result<Request> {
bincode::deserialize::<Request>(bytes)
}
}
impl From<&Request> for Vec<u8> {
fn from(req: &Request) -> Vec<u8> {
bincode::serialize(req).unwrap()
}
}
impl Request {
pub fn as_bytes(&self) -> Vec<u8> {
self.into()
}
}
#[serde_as]
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
pub struct Reply {
#[serde_as(as = "SerdeScalar")]
pub iss_Jattr_N_id: Scalar,
#[serde_as(as = "SerdeScalar")]
pub iss_Sattr_N_level_since: Scalar,
#[serde_as(as = "SerdePoint")]
pub P_iss_cred_N: Point,
#[serde_as(as = "SerdePoint")]
pub R_iss_cred_N: Point,
#[serde(with = "serde_bytes")]
pub iss_proof: Vec<u8>,
}
impl TryFrom<&[u8]> for Reply {
type Error = bincode::Error;
fn try_from(bytes: &[u8]) -> bincode::Result<Reply> {
bincode::deserialize::<Reply>(bytes)
}
}
impl From<&Reply> for Vec<u8> {
fn from(rep: &Reply) -> Vec<u8> {
bincode::serialize(rep).unwrap()
}
}
impl Reply {
pub fn as_bytes(&self) -> Vec<u8> {
self.into()
}
}
sigma_compiler! {
client_proof < Point >, (rand s_iss_cred_N, rand zQ_show_cred_L, rand
z_show_Hattr_L_level_since, rand z_show_Hattr_L_bucket, rand zQ_show_cred_M, rand
z_show_Hattr_M_to_bucket, rand z_show_Hattr_M_from_bucket, iss_Jattr_N_id,
iss_Hattr_N_bucket, show_Hattr_L_level_since, show_Hattr_L_bucket,
show_Hattr_M_to_bucket, show_Hattr_M_from_bucket, pub iss_Iattr_N_trust_level,
pub iss_Iattr_N_invites_remaining, pub iss_Iattr_N_blockages, pub
show_Rattr_L_id, pub show_Rattr_L_trust_level, pub
show_Rattr_L_invites_remaining, pub show_Rattr_L_blockages, pub
show_Rattr_M_lox_id, pub show_Iattr_M_migration_type,), (cind X_iss_Jattr_N_id,
cind X_iss_Hattr_N_bucket, cind P_show_cred_L, cind X_show_Hattr_L_level_since,
cind X_show_Hattr_L_bucket, cind P_show_cred_M, cind X_show_Hattr_M_to_bucket,
cind X_show_Hattr_M_from_bucket, C_iss_cred_N, V_show_cred_L,
C_show_Hattr_L_level_since, C_show_Hattr_L_bucket, V_show_cred_M,
C_show_Hattr_M_to_bucket, C_show_Hattr_M_from_bucket, cind const A_generator,
cind const B_generator,), show_Rattr_L_id = show_Rattr_M_lox_id,
show_Hattr_L_bucket = show_Hattr_M_from_bucket, iss_Hattr_N_bucket =
show_Hattr_M_to_bucket, C_iss_cred_N = s_iss_cred_N * A_generator +
iss_Jattr_N_id * X_iss_Jattr_N_id + iss_Hattr_N_bucket * X_iss_Hattr_N_bucket,
C_show_Hattr_L_level_since = show_Hattr_L_level_since * P_show_cred_L +
z_show_Hattr_L_level_since * A_generator, C_show_Hattr_L_bucket =
show_Hattr_L_bucket * P_show_cred_L + z_show_Hattr_L_bucket * A_generator,
V_show_cred_L = zQ_show_cred_L * B_generator + z_show_Hattr_L_level_since *
X_show_Hattr_L_level_since + z_show_Hattr_L_bucket * X_show_Hattr_L_bucket,
C_show_Hattr_M_to_bucket = show_Hattr_M_to_bucket * P_show_cred_M +
z_show_Hattr_M_to_bucket * A_generator, C_show_Hattr_M_from_bucket =
show_Hattr_M_from_bucket * P_show_cred_M + z_show_Hattr_M_from_bucket *
A_generator, V_show_cred_M = zQ_show_cred_M * B_generator +
z_show_Hattr_M_to_bucket * X_show_Hattr_M_to_bucket + z_show_Hattr_M_from_bucket
* X_show_Hattr_M_from_bucket,
}
sigma_compiler! {
issuer_proof < Point >, (rand b_iss_cred_N, x0_iss_cred_N,), (P_iss_cred_N,
X0_iss_cred_N, K_iss_cred_N, R_iss_cred_N, cind const A_generator, cind const
B_generator,), P_iss_cred_N = b_iss_cred_N * A_generator, X0_iss_cred_N =
x0_iss_cred_N * B_generator, R_iss_cred_N = x0_iss_cred_N * P_iss_cred_N +
b_iss_cred_N * K_iss_cred_N,
}
#[serde_as]
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
pub struct ClientState {
#[serde(with = "serde_bytes")]
pub iss_proof_sessid: Vec<u8>,
pub pubkey_iss_cred_N: CMZPubkey<Point>,
#[serde_as(as = "SerdeScalar")]
pub iss_Jattr_N_id: Scalar,
#[serde_as(as = "SerdeScalar")]
pub iss_Iattr_N_trust_level: Scalar,
#[serde_as(as = "SerdeScalar")]
pub iss_Iattr_N_invites_remaining: Scalar,
#[serde_as(as = "SerdeScalar")]
pub iss_Iattr_N_blockages: Scalar,
#[serde_as(as = "SerdeScalar")]
pub iss_Hattr_N_bucket: Scalar,
#[serde_as(as = "SerdeScalar")]
pub s_iss_cred_N: Scalar,
#[serde_as(as = "SerdePoint")]
pub C_iss_cred_N: Point,
}
impl TryFrom<&[u8]> for ClientState {
type Error = bincode::Error;
fn try_from(bytes: &[u8]) -> bincode::Result<ClientState> {
bincode::deserialize::<ClientState>(bytes)
}
}
impl From<&ClientState> for Vec<u8> {
fn from(req: &ClientState) -> Vec<u8> {
bincode::serialize(req).unwrap()
}
}
impl ClientState {
pub fn as_bytes(&self) -> Vec<u8> {
self.into()
}
}
pub fn prepare(
rng: &mut (impl CryptoRng + RngCore),
session_id: &[u8],
show_cred_L: &Lox,
show_cred_M: &Migration,
iss_cred_N: Lox,
) -> Result<(Request, ClientState), CMZError> {
let bp = cmz_basepoints::<Point>();
let mut cli_proof_sessid: Vec<u8> = Vec::new();
cli_proof_sessid.extend(b"cli_");
cli_proof_sessid.extend(session_id);
let mut iss_proof_sessid: Vec<u8> = Vec::new();
iss_proof_sessid.extend(b"iss_");
iss_proof_sessid.extend(session_id);
let s_iss_cred_N = <Scalar as ff::Field>::random(&mut *rng);
let mut C_iss_cred_N = bp.mulA(&s_iss_cred_N);
let A_generator = bp.A();
let B_generator = bp.B();
if iss_cred_N.get_pubkey().X.len() != Lox::num_attrs() {
return Err(CMZError::PubkeyMissing("N"));
}
if iss_cred_N.get_pubkey().Xr.is_some() != true {
return Err(CMZError::WrongProtocol("N"));
}
let pubkey_iss_cred_N = iss_cred_N.get_pubkey().clone();
let iss_Jattr_N_id = <Scalar as ff::Field>::random(&mut *rng);
let X_iss_Jattr_N_id = pubkey_iss_cred_N.X[Lox::attr_num("id")];
C_iss_cred_N += iss_Jattr_N_id * X_iss_Jattr_N_id;
let iss_Iattr_N_trust_level = iss_cred_N
.trust_level
.ok_or(CMZError::ImplicitAttrCliMissing("N", "trust_level"))?;
let iss_Iattr_N_invites_remaining = iss_cred_N
.invites_remaining
.ok_or(CMZError::ImplicitAttrCliMissing("N", "invites_remaining"))?;
let iss_Iattr_N_blockages = iss_cred_N
.blockages
.ok_or(CMZError::ImplicitAttrCliMissing("N", "blockages"))?;
let iss_Hattr_N_bucket = iss_cred_N
.bucket
.ok_or(CMZError::HideAttrMissing("N", "bucket"))?;
let X_iss_Hattr_N_bucket = pubkey_iss_cred_N.X[Lox::attr_num("bucket")];
C_iss_cred_N += iss_Hattr_N_bucket * X_iss_Hattr_N_bucket;
if show_cred_L.get_pubkey().X.len() != Lox::num_attrs() {
return Err(CMZError::PubkeyMissing("L"));
}
if show_cred_L.get_pubkey().Xr.is_some() != true {
return Err(CMZError::WrongProtocol("L"));
}
let t_show_cred_L = <Scalar as ff::Field>::random(&mut *rng);
let P_show_cred_L = t_show_cred_L * show_cred_L.MAC.P;
let Q_show_cred_L = t_show_cred_L * show_cred_L.MAC.Q;
let zQ_show_cred_L = <Scalar as ff::Field>::random(&mut *rng);
let CQ_show_cred_L = Q_show_cred_L - bp.mulB(&zQ_show_cred_L);
let mut V_show_cred_L = bp.mulB(&zQ_show_cred_L);
let show_Rattr_L_id = show_cred_L
.id
.ok_or(CMZError::RevealAttrMissing("L", "id"))?;
let show_Rattr_L_trust_level = show_cred_L
.trust_level
.ok_or(CMZError::RevealAttrMissing("L", "trust_level"))?;
let show_Hattr_L_level_since = show_cred_L
.level_since
.ok_or(CMZError::HideAttrMissing("L", "level_since"))?;
let z_show_Hattr_L_level_since = <Scalar as ff::Field>::random(&mut *rng);
let C_show_Hattr_L_level_since = show_Hattr_L_level_since * P_show_cred_L
+ bp.mulA(&z_show_Hattr_L_level_since);
let X_show_Hattr_L_level_since = show_cred_L.pubkey_X("level_since");
V_show_cred_L += z_show_Hattr_L_level_since * X_show_Hattr_L_level_since;
let show_Rattr_L_invites_remaining = show_cred_L
.invites_remaining
.ok_or(CMZError::RevealAttrMissing("L", "invites_remaining"))?;
let show_Rattr_L_blockages = show_cred_L
.blockages
.ok_or(CMZError::RevealAttrMissing("L", "blockages"))?;
let show_Hattr_L_bucket = show_cred_L
.bucket
.ok_or(CMZError::HideAttrMissing("L", "bucket"))?;
let z_show_Hattr_L_bucket = <Scalar as ff::Field>::random(&mut *rng);
let C_show_Hattr_L_bucket = show_Hattr_L_bucket * P_show_cred_L
+ bp.mulA(&z_show_Hattr_L_bucket);
let X_show_Hattr_L_bucket = show_cred_L.pubkey_X("bucket");
V_show_cred_L += z_show_Hattr_L_bucket * X_show_Hattr_L_bucket;
if show_cred_M.get_pubkey().X.len() != Migration::num_attrs() {
return Err(CMZError::PubkeyMissing("M"));
}
if show_cred_M.get_pubkey().Xr.is_some() != true {
return Err(CMZError::WrongProtocol("M"));
}
let t_show_cred_M = <Scalar as ff::Field>::random(&mut *rng);
let P_show_cred_M = t_show_cred_M * show_cred_M.MAC.P;
let Q_show_cred_M = t_show_cred_M * show_cred_M.MAC.Q;
let zQ_show_cred_M = <Scalar as ff::Field>::random(&mut *rng);
let CQ_show_cred_M = Q_show_cred_M - bp.mulB(&zQ_show_cred_M);
let mut V_show_cred_M = bp.mulB(&zQ_show_cred_M);
let show_Rattr_M_lox_id = show_cred_M
.lox_id
.ok_or(CMZError::RevealAttrMissing("M", "lox_id"))?;
let show_Hattr_M_to_bucket = show_cred_M
.to_bucket
.ok_or(CMZError::HideAttrMissing("M", "to_bucket"))?;
let z_show_Hattr_M_to_bucket = <Scalar as ff::Field>::random(&mut *rng);
let C_show_Hattr_M_to_bucket = show_Hattr_M_to_bucket * P_show_cred_M
+ bp.mulA(&z_show_Hattr_M_to_bucket);
let X_show_Hattr_M_to_bucket = show_cred_M.pubkey_X("to_bucket");
V_show_cred_M += z_show_Hattr_M_to_bucket * X_show_Hattr_M_to_bucket;
let show_Hattr_M_from_bucket = show_cred_M
.from_bucket
.ok_or(CMZError::HideAttrMissing("M", "from_bucket"))?;
let z_show_Hattr_M_from_bucket = <Scalar as ff::Field>::random(&mut *rng);
let C_show_Hattr_M_from_bucket = show_Hattr_M_from_bucket * P_show_cred_M
+ bp.mulA(&z_show_Hattr_M_from_bucket);
let X_show_Hattr_M_from_bucket = show_cred_M.pubkey_X("from_bucket");
V_show_cred_M += z_show_Hattr_M_from_bucket * X_show_Hattr_M_from_bucket;
let show_Iattr_M_migration_type = show_cred_M
.migration_type
.ok_or(CMZError::ImplicitAttrCliMissing("M", "migration_type"))?;
let cli_proof_instance = client_proof::Instance {
C_iss_cred_N,
V_show_cred_L,
C_show_Hattr_L_level_since,
C_show_Hattr_L_bucket,
V_show_cred_M,
C_show_Hattr_M_to_bucket,
C_show_Hattr_M_from_bucket,
A_generator,
B_generator,
X_iss_Jattr_N_id,
X_iss_Hattr_N_bucket,
P_show_cred_L,
X_show_Hattr_L_level_since,
X_show_Hattr_L_bucket,
P_show_cred_M,
X_show_Hattr_M_to_bucket,
X_show_Hattr_M_from_bucket,
iss_Iattr_N_trust_level,
iss_Iattr_N_invites_remaining,
iss_Iattr_N_blockages,
show_Rattr_L_id,
show_Rattr_L_trust_level,
show_Rattr_L_invites_remaining,
show_Rattr_L_blockages,
show_Rattr_M_lox_id,
show_Iattr_M_migration_type,
};
let cli_proof_witness = client_proof::Witness {
s_iss_cred_N,
zQ_show_cred_L,
z_show_Hattr_L_level_since,
z_show_Hattr_L_bucket,
zQ_show_cred_M,
z_show_Hattr_M_to_bucket,
z_show_Hattr_M_from_bucket,
iss_Jattr_N_id,
iss_Hattr_N_bucket,
show_Hattr_L_level_since,
show_Hattr_L_bucket,
show_Hattr_M_to_bucket,
show_Hattr_M_from_bucket,
};
let cli_proof = client_proof::prove(
&cli_proof_instance,
&cli_proof_witness,
&cli_proof_sessid,
rng,
)
.unwrap();
Ok((
Request {
C_iss_cred_N,
P_show_cred_L,
CQ_show_cred_L,
show_Rattr_L_id,
show_Rattr_L_trust_level,
C_show_Hattr_L_level_since,
show_Rattr_L_invites_remaining,
show_Rattr_L_blockages,
C_show_Hattr_L_bucket,
P_show_cred_M,
CQ_show_cred_M,
show_Rattr_M_lox_id,
C_show_Hattr_M_to_bucket,
C_show_Hattr_M_from_bucket,
cli_proof,
},
ClientState {
iss_proof_sessid,
pubkey_iss_cred_N,
iss_Jattr_N_id,
iss_Iattr_N_trust_level,
iss_Iattr_N_invites_remaining,
iss_Iattr_N_blockages,
iss_Hattr_N_bucket,
s_iss_cred_N,
C_iss_cred_N,
},
))
}
impl ClientState {
pub fn finalize(self, reply: Reply) -> Result<Lox, (CMZError, Self)> {
let bp = cmz_basepoints::<Point>();
let mut iss_cred_N = Lox::default();
let mut K_iss_cred_N = self.C_iss_cred_N
+ self.pubkey_iss_cred_N.Xr.unwrap();
let A_generator = bp.A();
let B_generator = bp.B();
iss_cred_N.set_pubkey(&self.pubkey_iss_cred_N);
let iss_Jattr_N_id = reply.iss_Jattr_N_id;
iss_cred_N.id = Some(self.iss_Jattr_N_id + reply.iss_Jattr_N_id);
K_iss_cred_N += (iss_Jattr_N_id * iss_cred_N.pubkey_X("id"));
iss_cred_N.trust_level = Some(self.iss_Iattr_N_trust_level);
K_iss_cred_N
+= (iss_cred_N.trust_level.unwrap()
* iss_cred_N.pubkey_X("trust_level"));
iss_cred_N.level_since = Some(reply.iss_Sattr_N_level_since);
K_iss_cred_N
+= (iss_cred_N.level_since.unwrap()
* iss_cred_N.pubkey_X("level_since"));
iss_cred_N.invites_remaining = Some(self.iss_Iattr_N_invites_remaining);
K_iss_cred_N
+= (iss_cred_N.invites_remaining.unwrap()
* iss_cred_N.pubkey_X("invites_remaining"));
iss_cred_N.blockages = Some(self.iss_Iattr_N_blockages);
K_iss_cred_N
+= (iss_cred_N.blockages.unwrap() * iss_cred_N.pubkey_X("blockages"));
iss_cred_N.bucket = Some(self.iss_Hattr_N_bucket);
let P_iss_cred_N = reply.P_iss_cred_N;
let X0_iss_cred_N = iss_cred_N.get_pubkey().X0.unwrap();
let R_iss_cred_N = reply.R_iss_cred_N;
iss_cred_N.MAC.P = P_iss_cred_N;
iss_cred_N.MAC.Q = reply.R_iss_cred_N
- self.s_iss_cred_N * reply.P_iss_cred_N;
let iss_proof_instance = issuer_proof::Instance {
P_iss_cred_N,
X0_iss_cred_N,
K_iss_cred_N,
R_iss_cred_N,
A_generator,
B_generator,
};
if issuer_proof::verify(
&iss_proof_instance,
&reply.iss_proof,
&self.iss_proof_sessid,
)
.is_err()
{
return Err((CMZError::IssProofFailed, self));
}
Ok(iss_cred_N)
}
}
pub fn handle<F, A>(
rng: &mut (impl CryptoRng + RngCore),
session_id: &[u8],
request: Request,
fill_creds: F,
authorize: A,
) -> Result<(Reply, (Lox, Migration, Lox)), CMZError>
where
F: FnOnce(&mut Lox, &mut Migration, &mut Lox) -> Result<(), CMZError>,
A: FnOnce(&Lox, &Migration, &Lox) -> Result<(), CMZError>,
{
let bp = cmz_basepoints::<Point>();
let mut cli_proof_sessid: Vec<u8> = Vec::new();
cli_proof_sessid.extend(b"cli_");
cli_proof_sessid.extend(session_id);
let mut iss_proof_sessid: Vec<u8> = Vec::new();
iss_proof_sessid.extend(b"iss_");
iss_proof_sessid.extend(session_id);
let mut show_cred_L = Lox::default();
let mut show_cred_M = Migration::default();
let mut iss_cred_N = Lox::default();
let A_generator = bp.A();
let B_generator = bp.B();
let iss_Jattr_N_id = <Scalar as ff::Field>::random(&mut *rng);
let show_Rattr_L_id = request.show_Rattr_L_id;
show_cred_L.id = Some(show_Rattr_L_id);
let show_Rattr_L_trust_level = request.show_Rattr_L_trust_level;
show_cred_L.trust_level = Some(show_Rattr_L_trust_level);
let show_Rattr_L_invites_remaining = request.show_Rattr_L_invites_remaining;
show_cred_L.invites_remaining = Some(show_Rattr_L_invites_remaining);
let show_Rattr_L_blockages = request.show_Rattr_L_blockages;
show_cred_L.blockages = Some(show_Rattr_L_blockages);
let show_Rattr_M_lox_id = request.show_Rattr_M_lox_id;
show_cred_M.lox_id = Some(show_Rattr_M_lox_id);
fill_creds(&mut show_cred_L, &mut show_cred_M, &mut iss_cred_N)?;
let C_iss_cred_N = request.C_iss_cred_N;
let mut K_iss_cred_N = C_iss_cred_N + iss_cred_N.get_pubkey().Xr.unwrap();
if iss_cred_N.get_privkey().x.len() != Lox::num_attrs() {
return Err(CMZError::PrivkeyMissing("N"));
}
if iss_cred_N.get_privkey().muCMZ != true {
return Err(CMZError::WrongProtocol("N"));
}
let X_iss_Jattr_N_id = iss_cred_N.pubkey_X("id");
K_iss_cred_N += (iss_Jattr_N_id * iss_cred_N.pubkey_X("id"));
let iss_Iattr_N_trust_level = iss_cred_N
.trust_level
.ok_or(CMZError::ImplicitAttrIssMissing("N", "trust_level"))?;
K_iss_cred_N += (iss_Iattr_N_trust_level * iss_cred_N.pubkey_X("trust_level"));
let iss_Sattr_N_level_since = iss_cred_N
.level_since
.ok_or(CMZError::SetAttrMissing("N", "level_since"))?;
K_iss_cred_N += (iss_Sattr_N_level_since * iss_cred_N.pubkey_X("level_since"));
let iss_Iattr_N_invites_remaining = iss_cred_N
.invites_remaining
.ok_or(CMZError::ImplicitAttrIssMissing("N", "invites_remaining"))?;
K_iss_cred_N
+= (iss_Iattr_N_invites_remaining
* iss_cred_N.pubkey_X("invites_remaining"));
let iss_Iattr_N_blockages = iss_cred_N
.blockages
.ok_or(CMZError::ImplicitAttrIssMissing("N", "blockages"))?;
K_iss_cred_N += (iss_Iattr_N_blockages * iss_cred_N.pubkey_X("blockages"));
let X_iss_Hattr_N_bucket = iss_cred_N.pubkey_X("bucket");
if show_cred_L.get_privkey().x.len() != Lox::num_attrs() {
return Err(CMZError::PrivkeyMissing("L"));
}
if show_cred_L.get_privkey().muCMZ != true {
return Err(CMZError::WrongProtocol("L"));
}
let P_show_cred_L = request.P_show_cred_L;
if bool::from(P_show_cred_L.is_identity()) {
return Err(CMZError::CliProofFailed);
}
let mut V_show_cred_L = -request.CQ_show_cred_L;
let mut q_show_cred_L = show_cred_L.get_privkey().x0
+ show_cred_L.get_privkey().xr;
q_show_cred_L += show_Rattr_L_id * show_cred_L.privkey_x("id");
q_show_cred_L += show_Rattr_L_trust_level * show_cred_L.privkey_x("trust_level");
let C_show_Hattr_L_level_since = request.C_show_Hattr_L_level_since;
let X_show_Hattr_L_level_since = show_cred_L.pubkey_X("level_since");
V_show_cred_L
+= show_cred_L.privkey_x("level_since") * C_show_Hattr_L_level_since;
q_show_cred_L
+= show_Rattr_L_invites_remaining
* show_cred_L.privkey_x("invites_remaining");
q_show_cred_L += show_Rattr_L_blockages * show_cred_L.privkey_x("blockages");
let C_show_Hattr_L_bucket = request.C_show_Hattr_L_bucket;
let X_show_Hattr_L_bucket = show_cred_L.pubkey_X("bucket");
V_show_cred_L += show_cred_L.privkey_x("bucket") * C_show_Hattr_L_bucket;
V_show_cred_L += q_show_cred_L * P_show_cred_L;
if show_cred_M.get_privkey().x.len() != Migration::num_attrs() {
return Err(CMZError::PrivkeyMissing("M"));
}
if show_cred_M.get_privkey().muCMZ != true {
return Err(CMZError::WrongProtocol("M"));
}
let P_show_cred_M = request.P_show_cred_M;
if bool::from(P_show_cred_M.is_identity()) {
return Err(CMZError::CliProofFailed);
}
let mut V_show_cred_M = -request.CQ_show_cred_M;
let mut q_show_cred_M = show_cred_M.get_privkey().x0
+ show_cred_M.get_privkey().xr;
q_show_cred_M += show_Rattr_M_lox_id * show_cred_M.privkey_x("lox_id");
let C_show_Hattr_M_to_bucket = request.C_show_Hattr_M_to_bucket;
let X_show_Hattr_M_to_bucket = show_cred_M.pubkey_X("to_bucket");
V_show_cred_M += show_cred_M.privkey_x("to_bucket") * C_show_Hattr_M_to_bucket;
let C_show_Hattr_M_from_bucket = request.C_show_Hattr_M_from_bucket;
let X_show_Hattr_M_from_bucket = show_cred_M.pubkey_X("from_bucket");
V_show_cred_M
+= show_cred_M.privkey_x("from_bucket") * C_show_Hattr_M_from_bucket;
let show_Iattr_M_migration_type = show_cred_M
.migration_type
.ok_or(CMZError::ImplicitAttrIssMissing("M", "migration_type"))?;
q_show_cred_M
+= show_Iattr_M_migration_type * show_cred_M.privkey_x("migration_type");
V_show_cred_M += q_show_cred_M * P_show_cred_M;
let cli_proof_instance = client_proof::Instance {
C_iss_cred_N,
V_show_cred_L,
C_show_Hattr_L_level_since,
C_show_Hattr_L_bucket,
V_show_cred_M,
C_show_Hattr_M_to_bucket,
C_show_Hattr_M_from_bucket,
A_generator,
B_generator,
X_iss_Jattr_N_id,
X_iss_Hattr_N_bucket,
P_show_cred_L,
X_show_Hattr_L_level_since,
X_show_Hattr_L_bucket,
P_show_cred_M,
X_show_Hattr_M_to_bucket,
X_show_Hattr_M_from_bucket,
iss_Iattr_N_trust_level,
iss_Iattr_N_invites_remaining,
iss_Iattr_N_blockages,
show_Rattr_L_id,
show_Rattr_L_trust_level,
show_Rattr_L_invites_remaining,
show_Rattr_L_blockages,
show_Rattr_M_lox_id,
show_Iattr_M_migration_type,
};
if client_proof::verify(
&cli_proof_instance,
&request.cli_proof,
&cli_proof_sessid,
)
.is_err()
{
return Err(CMZError::CliProofFailed);
}
authorize(&show_cred_L, &show_cred_M, &iss_cred_N)?;
let b_iss_cred_N = <Scalar as ff::Field>::random(&mut *rng);
let P_iss_cred_N = bp.mulA(&b_iss_cred_N);
iss_cred_N.MAC.P = P_iss_cred_N;
let x0_iss_cred_N = iss_cred_N.get_privkey().x0;
let X0_iss_cred_N = iss_cred_N.get_pubkey().X0.unwrap();
let R_iss_cred_N = b_iss_cred_N * (bp.mulA(&x0_iss_cred_N) + K_iss_cred_N);
let iss_proof_instance = issuer_proof::Instance {
P_iss_cred_N,
X0_iss_cred_N,
K_iss_cred_N,
R_iss_cred_N,
A_generator,
B_generator,
};
let iss_proof_witness = issuer_proof::Witness {
b_iss_cred_N,
x0_iss_cred_N,
};
let iss_proof = issuer_proof::prove(
&iss_proof_instance,
&iss_proof_witness,
&iss_proof_sessid,
rng,
)
.unwrap();
Ok((
Reply {
iss_Jattr_N_id,
iss_Sattr_N_level_since,
P_iss_cred_N,
R_iss_cred_N,
iss_proof,
},
(show_cred_L, show_cred_M, iss_cred_N),
))
}
}