zkgroup/common/
simple_types.rs1use curve25519_dalek_signal::scalar::Scalar;
7use partial_default::PartialDefault;
8use serde::{Deserialize, Serialize};
9use zkcredential::attributes::PublicAttribute;
10
11use crate::common::constants::*;
12
13pub type AesKeyBytes = [u8; AES_KEY_LEN];
14pub type GroupMasterKeyBytes = [u8; GROUP_MASTER_KEY_LEN];
15pub type UidBytes = [u8; UUID_LEN];
16pub type ProfileKeyBytes = [u8; PROFILE_KEY_LEN];
17pub type RandomnessBytes = [u8; RANDOMNESS_LEN];
18pub type SignatureBytes = [u8; SIGNATURE_LEN];
19pub type NotarySignatureBytes = [u8; SIGNATURE_LEN];
20pub type GroupIdentifierBytes = [u8; GROUP_IDENTIFIER_LEN];
21pub type ProfileKeyVersionBytes = [u8; PROFILE_KEY_VERSION_LEN];
22pub type ProfileKeyVersionEncodedBytes = [u8; PROFILE_KEY_VERSION_ENCODED_LEN];
24
25pub type ReceiptSerialBytes = [u8; RECEIPT_SERIAL_LEN];
28
29#[derive(
35 Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize, Deserialize, PartialDefault,
36)]
37#[serde(transparent)]
38#[repr(transparent)]
39pub struct Timestamp(u64);
40
41impl Timestamp {
42 #[inline]
43 pub const fn from_epoch_seconds(seconds: u64) -> Self {
44 Self(seconds)
45 }
46
47 #[inline]
48 pub const fn epoch_seconds(&self) -> u64 {
49 self.0
50 }
51
52 #[inline]
53 pub const fn add_seconds(&self, seconds: u64) -> Self {
54 Self(self.0 + seconds)
55 }
56
57 #[inline]
58 pub const fn sub_seconds(&self, seconds: u64) -> Self {
59 Self(self.0 - seconds)
60 }
61
62 #[inline]
63 pub fn checked_add_seconds(&self, seconds: u64) -> Option<Self> {
64 self.0.checked_add(seconds).map(Self)
65 }
66
67 #[inline]
68 pub fn checked_sub_seconds(&self, seconds: u64) -> Option<Self> {
69 self.0.checked_sub(seconds).map(Self)
70 }
71
72 #[inline]
73 pub const fn is_day_aligned(&self) -> bool {
74 self.0 % SECONDS_PER_DAY == 0
75 }
76
77 #[inline]
78 pub fn to_be_bytes(self) -> [u8; 8] {
79 self.0.to_be_bytes()
80 }
81
82 pub(crate) fn saturating_seconds_since(&self, before: Timestamp) -> u64 {
86 self.0.saturating_sub(before.0)
87 }
88}
89
90impl From<Timestamp> for std::time::SystemTime {
91 fn from(Timestamp(seconds): Timestamp) -> Self {
92 std::time::UNIX_EPOCH + std::time::Duration::from_secs(seconds)
93 }
94}
95
96impl From<std::time::SystemTime> for Timestamp {
97 fn from(timestamp: std::time::SystemTime) -> Self {
98 Self::from_epoch_seconds(
99 timestamp
100 .duration_since(std::time::UNIX_EPOCH)
101 .unwrap_or_default()
102 .as_secs(),
103 )
104 }
105}
106
107impl rand::distr::Distribution<Timestamp> for rand::distr::StandardUniform {
108 fn sample<R: rand::prelude::Rng + ?Sized>(&self, rng: &mut R) -> Timestamp {
109 Timestamp(Self::sample(self, rng))
110 }
111}
112
113impl PublicAttribute for Timestamp {
114 fn hash_into(&self, sho: &mut dyn poksho::ShoApi) {
115 self.0.hash_into(sho)
116 }
117}
118
119pub type ReceiptLevel = u64;
122
123pub fn encode_redemption_time(redemption_time: u32) -> Scalar {
124 let mut scalar_bytes: [u8; 32] = Default::default();
125 scalar_bytes[0..4].copy_from_slice(&redemption_time.to_be_bytes());
126 Scalar::from_bytes_mod_order(scalar_bytes)
127}
128
129pub fn encode_receipt_serial_bytes(receipt_serial_bytes: ReceiptSerialBytes) -> Scalar {
130 let mut scalar_bytes: [u8; 32] = Default::default();
131 scalar_bytes[0..16].copy_from_slice(&receipt_serial_bytes[..]);
132 Scalar::from_bytes_mod_order(scalar_bytes)
133}
134
135#[cfg(test)]
136mod tests {
137 use super::*;
138
139 #[test]
140 fn test_encode_scalar() {
141 let s_bytes = [0xFF; 32];
142 match bincode::deserialize::<Scalar>(&s_bytes) {
143 Err(_) => (),
144 Ok(_) => unreachable!(),
145 }
146 }
147}