use noah_algebra::bls12_381::BLSPairingEngine;
use noah_algebra::bls12_381::BLSG2;
use noah_algebra::{
bls12_381::{BLSScalar, BLSG1},
prelude::*,
traits::Pairing,
};
use noah_crypto::{
anon_creds::{Attribute, CommOutput},
basic::elgamal::elgamal_key_gen,
};
type G1 = BLSG1;
type G2 = BLSG2;
type S = BLSScalar;
pub type ACIssuerPublicKey = noah_crypto::anon_creds::CredentialIssuerPK<G1, G2>;
pub type ACIssuerSecretKey = noah_crypto::anon_creds::CredentialIssuerSK<G1, S>;
pub type ACSignature = noah_crypto::anon_creds::CredentialSig<G1>;
pub type ACUserPublicKey = noah_crypto::anon_creds::CredentialUserPK<G1>;
pub type ACUserSecretKey = noah_crypto::anon_creds::CredentialUserSK<S>;
pub type ACRevealSig = noah_crypto::anon_creds::CredentialSigOpenProof<G1, G2, S>;
pub type ACPoK = noah_crypto::anon_creds::CredentialPoK<G2, S>;
pub type ACCommitmentKey = noah_crypto::anon_creds::CredentialCommRandomizer<S>;
pub type ACCommitment = noah_crypto::anon_creds::CredentialComm<G1>;
pub type Credential = noah_crypto::anon_creds::Credential<G1, G2, Attr>;
pub type ACRevealProof = noah_crypto::anon_creds::CredentialCommOpenProof<G2, S>;
pub type ACConfidentialRevealProof = noah_crypto::confidential_anon_creds::CACPoK<G1, G2, S>;
pub type Attr = u32;
pub fn ac_keygen_issuer<R: CryptoRng + RngCore>(
prng: &mut R,
num_attrs: usize,
) -> (ACIssuerSecretKey, ACIssuerPublicKey) {
noah_crypto::anon_creds::issuer_keygen::<_, BLSPairingEngine>(prng, num_attrs)
}
pub fn ac_keygen_user<R: CryptoRng + RngCore>(
prng: &mut R,
issuer_pk: &ACIssuerPublicKey,
) -> (ACUserSecretKey, ACUserPublicKey) {
noah_crypto::anon_creds::user_keygen::<_, BLSPairingEngine>(prng, issuer_pk)
}
pub fn ac_sign<R: CryptoRng + RngCore>(
prng: &mut R,
issuer_sk: &ACIssuerSecretKey,
user_pk: &ACUserPublicKey,
attrs: &[Attr],
) -> Result<ACSignature> {
let attrs_scalar: Vec<BLSScalar> = attrs.iter().map(|x| BLSScalar::from(*x)).collect();
noah_crypto::anon_creds::grant_credential::<_, BLSPairingEngine>(
prng,
issuer_sk,
user_pk,
attrs_scalar.as_slice(),
)
.c(d!())
}
pub fn ac_keygen_commitment<R: CryptoRng + RngCore>(prng: &mut R) -> ACCommitmentKey {
noah_crypto::anon_creds::randomizer_gen::<_, BLSPairingEngine>(prng)
}
pub fn ac_commit<R: CryptoRng + RngCore>(
prng: &mut R,
user_sk: &ACUserSecretKey,
credential: &Credential,
msg: &[u8],
) -> Result<
CommOutput<
<BLSPairingEngine as Pairing>::G1,
<BLSPairingEngine as Pairing>::G2,
<BLSPairingEngine as Pairing>::ScalarField,
>,
> {
let c = noah_crypto::anon_creds::Credential {
sig: credential.sig.clone(),
attrs: credential
.attrs
.iter()
.map(|x| BLSScalar::from(*x))
.collect_vec(),
ipk: credential.ipk.clone(),
};
noah_crypto::anon_creds::commit_without_randomizer::<_, BLSPairingEngine>(
prng, user_sk, &c, msg,
)
.c(d!())
}
pub fn ac_commit_with_key<R: CryptoRng + RngCore>(
prng: &mut R,
user_sk: &ACUserSecretKey,
credential: &Credential,
key: &ACCommitmentKey,
msg: &[u8],
) -> Result<
CommOutput<
<BLSPairingEngine as Pairing>::G1,
<BLSPairingEngine as Pairing>::G2,
<BLSPairingEngine as Pairing>::ScalarField,
>,
> {
let c = noah_crypto::anon_creds::Credential {
sig: credential.sig.clone(),
attrs: credential
.attrs
.iter()
.map(|x| BLSScalar::from(*x))
.collect_vec(),
ipk: credential.ipk.clone(),
};
noah_crypto::anon_creds::commit::<_, BLSPairingEngine>(prng, user_sk, &c, key, msg).c(d!())
}
pub fn ac_verify_commitment(
issuer_pub_key: &ACIssuerPublicKey,
sig_commitment: &ACCommitment,
sok: &ACPoK,
msg: &[u8],
) -> Result<()> {
noah_crypto::anon_creds::check_comm::<BLSPairingEngine>(
issuer_pub_key,
sig_commitment,
sok,
msg,
)
.c(d!())
}
pub fn ac_open_commitment<R: CryptoRng + RngCore>(
prng: &mut R,
usk: &ACUserSecretKey,
credential: &Credential,
rand: &ACCommitmentKey,
reveal_map: &[bool],
) -> Result<ACRevealProof> {
let c = noah_crypto::anon_creds::Credential {
sig: credential.sig.clone(),
attrs: credential
.attrs
.iter()
.map(|a| BLSScalar::from(*a))
.collect_vec(),
ipk: credential.ipk.clone(),
};
let cm = ACCommitment::new(&credential.sig, &rand);
noah_crypto::anon_creds::open_comm::<_, BLSPairingEngine>(prng, usk, &c, &cm, &rand, reveal_map)
.c(d!())
}
pub fn ac_reveal<R: CryptoRng + RngCore>(
prng: &mut R,
user_sk: &ACUserSecretKey,
credential: &Credential,
reveal_bitmap: &[bool],
) -> Result<ACRevealSig> {
let c = noah_crypto::anon_creds::Credential {
sig: credential.sig.clone(),
attrs: credential
.attrs
.iter()
.map(|a| BLSScalar::from(*a))
.collect_vec(),
ipk: credential.ipk.clone(),
};
noah_crypto::anon_creds::open_credential::<_, BLSPairingEngine>(
prng,
user_sk,
&c,
reveal_bitmap,
)
.c(d!())
}
pub fn ac_verify(
issuer_pub_key: &ACIssuerPublicKey,
attrs: &[Option<Attr>],
cm: &ACCommitment,
proof_open: &ACRevealProof,
) -> Result<()> {
let attrs_scalar: Vec<Attribute<S>> = attrs
.iter()
.map(|attr| match attr {
Some(x) => Attribute::Revealed(BLSScalar::from(*x)),
None => Attribute::Hidden(None),
})
.collect();
noah_crypto::anon_creds::verify_open::<BLSPairingEngine>(
issuer_pub_key,
&cm,
&proof_open,
attrs_scalar.as_slice(),
)
.c(d!())
}
pub type AttributeEncKey = noah_crypto::basic::elgamal::ElGamalEncKey<G1>;
pub type AttributeDecKey = noah_crypto::basic::elgamal::ElGamalDecKey<S>;
pub type AttributeCiphertext = noah_crypto::basic::elgamal::ElGamalCiphertext<G1>;
pub type ConfidentialAC = noah_crypto::confidential_anon_creds::ConfidentialAC<G1, G2, S>;
pub fn ac_confidential_open_commitment<R: CryptoRng + RngCore>(
prng: &mut R,
usk: &ACUserSecretKey,
credential: &Credential,
rand: &ACCommitmentKey,
enc_key: &AttributeEncKey,
reveal_map: &[bool],
msg: &[u8],
) -> Result<ConfidentialAC> {
let attrs_scalar = credential
.attrs
.iter()
.map(|x| BLSScalar::from(*x))
.collect_vec();
let c = noah_crypto::anon_creds::Credential {
sig: credential.sig.clone(),
attrs: attrs_scalar,
ipk: credential.ipk.clone(),
};
let cm = ACCommitment::new(&credential.sig, &rand);
noah_crypto::confidential_anon_creds::confidential_open_comm::<R, BLSPairingEngine>(
prng, usk, &c, &cm, rand, reveal_map, enc_key, msg,
)
.c(d!())
}
pub fn ac_confidential_verify(
issuer_pk: &ACIssuerPublicKey,
enc_key: &AttributeEncKey,
reveal_map: &[bool],
sig_commitment: &ACCommitment,
attr_ctext: &[AttributeCiphertext],
cac_proof: &ACConfidentialRevealProof,
msg: &[u8],
) -> Result<()> {
noah_crypto::confidential_anon_creds::confidential_verify_open::<BLSPairingEngine>(
issuer_pk,
enc_key,
reveal_map,
sig_commitment,
attr_ctext,
cac_proof,
msg,
)
.c(d!())
}
pub fn ac_confidential_gen_encryption_keys<R: CryptoRng + RngCore>(
prng: &mut R,
) -> (AttributeDecKey, AttributeEncKey) {
elgamal_key_gen::<_, G1>(prng)
}