pub mod issue_secret;
pub use issue_secret::IssueSecret;
pub mod issue_params;
pub use issue_params::IssueParams;
pub mod issue_certificate;
pub use issue_certificate::IssueCertificate;
pub mod ver_req_secret;
pub use ver_req_secret::VerificationRequestSecret;
pub mod ver_req;
pub use ver_req::VerificationRequest;
pub mod ver_challenge;
pub use ver_challenge::VerificationChallenge;
pub mod ver_response;
pub use ver_response::VerificationResponse;
use crate::Group;
use digest::Digest;
use rand_core::{CryptoRng, RngCore};
use serde::{Deserialize, Serialize};
#[derive(Clone, Serialize, Deserialize)]
pub struct Identification<G: Group> {
pub(crate) group: G,
}
impl<G: Group> Identification<G> {
pub fn random_identity<R: RngCore + CryptoRng>(&self, rng: &mut R) -> G::P {
self.group.random_element(rng)
}
pub fn issue_params<R: RngCore + CryptoRng>(
&self,
rng: &mut R,
i: G::P,
) -> (IssueSecret<G>, IssueParams<G>) {
let e = self.group.random_scalar(rng);
let neg_e = self.group.neg(&e);
let v = self.group.mul_by_generator(&neg_e);
(IssueSecret { e }, IssueParams { i, v })
}
pub fn issue_certificate<R, H, S>(
&self,
rng: &mut R,
signer: &S,
params: IssueParams<G>,
) -> IssueCertificate<G>
where
R: CryptoRng + RngCore,
H: Digest,
S: signature::RandomizedDigestSigner<H, Vec<u8>>,
{
let digest =
H::new().chain_update([G::map_point(¶ms.i), G::map_point(¶ms.v)].concat());
let s = signer.sign_digest_with_rng(rng, digest);
IssueCertificate { params, s }
}
pub fn verification_request<R: RngCore + CryptoRng>(
&self,
rng: &mut R,
certificate: IssueCertificate<G>,
) -> (VerificationRequestSecret<G>, VerificationRequest<G>) {
let k = self.group.random_scalar(rng);
let y = self.group.mul_by_generator(&k);
(
VerificationRequestSecret { k },
VerificationRequest { certificate, y },
)
}
pub fn verification_challenge<R, H, V>(
&self,
rng: &mut R,
verifier: &V,
request: VerificationRequest<G>,
) -> Option<VerificationChallenge<G>>
where
R: CryptoRng + RngCore,
H: Digest,
V: signature::DigestVerifier<H, Vec<u8>>,
{
let digest = H::new().chain_update(
[
G::map_point(&request.certificate.params.i),
G::map_point(&request.certificate.params.v),
]
.concat(),
);
verifier
.verify_digest(digest, &request.certificate.s)
.ok()
.map(|_| VerificationChallenge {
r: self.group.random_scalar(rng),
})
}
pub fn verification_response(
&self,
challenge: VerificationChallenge<G>,
iss_secret: IssueSecret<G>,
ver_secret: VerificationRequestSecret<G>,
) -> VerificationResponse<G> {
VerificationResponse {
p: self
.group
.add_mul_scalar(&ver_secret.k, &challenge.r, &iss_secret.e),
}
}
pub fn verification(
&self,
request: VerificationRequest<G>,
challenge: VerificationChallenge<G>,
response: VerificationResponse<G>,
) -> bool {
let lhs = {
let a_p = self.group.mul_by_generator(&response.p);
let v_r = self.group.mul(&request.certificate.params.v, &challenge.r);
self.group.dot(&a_p, &v_r)
};
let rhs = request.y;
G::is_equivalent_points(&lhs, &rhs)
}
}