zkgroup/api/auth/
auth_credential_presentation.rs1use partial_default::PartialDefault;
6use serde::{Deserialize, Serialize, Serializer};
7
8use crate::auth::AuthCredentialWithPniZkcPresentation;
9use crate::common::constants::*;
10use crate::common::errors::*;
11use crate::common::serialization::VersionByte;
12use crate::common::simple_types::*;
13use crate::{api, crypto};
14
15#[derive(Serialize, Deserialize, PartialDefault)]
16pub struct AuthCredentialWithPniPresentation {
17 pub(crate) version: VersionByte<PRESENTATION_VERSION_3>,
18 pub(crate) proof: crypto::proofs::AuthCredentialWithPniPresentationProof,
19 pub(crate) aci_ciphertext: crypto::uid_encryption::Ciphertext,
20 pub(crate) pni_ciphertext: crypto::uid_encryption::Ciphertext,
21 pub(crate) redemption_time: Timestamp,
22}
23
24impl AuthCredentialWithPniPresentation {
25 pub fn get_aci_ciphertext(&self) -> api::groups::UuidCiphertext {
26 api::groups::UuidCiphertext {
27 reserved: Default::default(),
28 ciphertext: self.aci_ciphertext,
29 }
30 }
31
32 pub fn get_pni_ciphertext(&self) -> api::groups::UuidCiphertext {
33 api::groups::UuidCiphertext {
34 reserved: Default::default(),
35 ciphertext: self.pni_ciphertext,
36 }
37 }
38
39 pub fn get_redemption_time(&self) -> Timestamp {
40 self.redemption_time
41 }
42}
43
44#[allow(clippy::large_enum_variant)]
45pub enum AnyAuthCredentialPresentation {
46 V3(AuthCredentialWithPniPresentation),
47 V4(AuthCredentialWithPniZkcPresentation),
48}
49
50#[repr(u8)]
51#[derive(
52 Copy, Clone, Debug, PartialDefault, num_enum::IntoPrimitive, num_enum::TryFromPrimitive,
53)]
54enum PresentationVersion {
55 #[partial_default]
57 V3 = PRESENTATION_VERSION_3,
58 V4 = PRESENTATION_VERSION_4,
59}
60
61impl AnyAuthCredentialPresentation {
62 pub fn new(presentation_bytes: &[u8]) -> Result<Self, ZkGroupDeserializationFailure> {
63 let first = *presentation_bytes
64 .first()
65 .ok_or(ZkGroupDeserializationFailure::new::<Self>())?;
66 let version = PresentationVersion::try_from(first)
67 .map_err(|_| ZkGroupDeserializationFailure::new::<Self>())?;
68 match version {
69 PresentationVersion::V3 => Ok(crate::deserialize::<AuthCredentialWithPniPresentation>(
70 presentation_bytes,
71 )?
72 .into()),
73 PresentationVersion::V4 => Ok(crate::deserialize::<
74 AuthCredentialWithPniZkcPresentation,
75 >(presentation_bytes)?
76 .into()),
77 }
78 }
79
80 pub fn get_uuid_ciphertext(&self) -> api::groups::UuidCiphertext {
81 match self {
82 AnyAuthCredentialPresentation::V3(presentation) => presentation.get_aci_ciphertext(),
83 AnyAuthCredentialPresentation::V4(presentation) => presentation.aci_ciphertext(),
84 }
85 }
86
87 pub fn get_pni_ciphertext(&self) -> Option<api::groups::UuidCiphertext> {
88 Some(match self {
93 AnyAuthCredentialPresentation::V3(presentation) => presentation.get_pni_ciphertext(),
94 AnyAuthCredentialPresentation::V4(presentation) => presentation.pni_ciphertext(),
95 })
96 }
97
98 pub fn get_redemption_time(&self) -> Timestamp {
99 match self {
100 AnyAuthCredentialPresentation::V3(presentation) => presentation.get_redemption_time(),
101 AnyAuthCredentialPresentation::V4(presentation) => presentation.redemption_time(),
102 }
103 }
104}
105
106impl Serialize for AnyAuthCredentialPresentation {
107 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
108 where
109 S: Serializer,
110 {
111 match self {
112 AnyAuthCredentialPresentation::V3(presentation) => presentation.serialize(serializer),
113 AnyAuthCredentialPresentation::V4(presentation) => presentation.serialize(serializer),
114 }
115 }
116}
117
118impl From<AuthCredentialWithPniPresentation> for AnyAuthCredentialPresentation {
119 fn from(presentation: AuthCredentialWithPniPresentation) -> Self {
120 Self::V3(presentation)
121 }
122}
123impl From<AuthCredentialWithPniZkcPresentation> for AnyAuthCredentialPresentation {
124 fn from(presentation: AuthCredentialWithPniZkcPresentation) -> Self {
125 Self::V4(presentation)
126 }
127}