light_compressed_account/instruction_data/
compressed_proof.rs1use light_zero_copy::{errors::ZeroCopyError, traits::ZeroCopyAt, ZeroCopyMut};
2use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout, Ref, Unaligned};
3
4#[repr(C)]
5#[cfg_attr(
6 all(feature = "std", feature = "anchor"),
7 derive(anchor_lang::AnchorDeserialize, anchor_lang::AnchorSerialize)
8)]
9#[cfg_attr(
10 not(feature = "anchor"),
11 derive(borsh::BorshDeserialize, borsh::BorshSerialize)
12)]
13#[derive(
14 Debug,
15 Clone,
16 Copy,
17 PartialEq,
18 Eq,
19 KnownLayout,
20 Immutable,
21 FromBytes,
22 IntoBytes,
23 Unaligned,
24 ZeroCopyMut,
25)]
26pub struct CompressedProof {
27 pub a: [u8; 32],
28 pub b: [u8; 64],
29 pub c: [u8; 32],
30}
31
32impl Default for CompressedProof {
33 fn default() -> Self {
34 Self {
35 a: [0; 32],
36 b: [0; 64],
37 c: [0; 32],
38 }
39 }
40}
41
42impl CompressedProof {
43 pub fn to_array(&self) -> [u8; 128] {
45 let mut result = [0u8; 128];
46 result[0..32].copy_from_slice(&self.a);
47 result[32..96].copy_from_slice(&self.b);
48 result[96..128].copy_from_slice(&self.c);
49 result
50 }
51}
52
53impl TryFrom<&[u8]> for CompressedProof {
54 type Error = crate::CompressedAccountError;
55
56 fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
57 if bytes.len() < 128 {
58 return Err(crate::CompressedAccountError::InvalidProofSize(bytes.len()));
59 }
60 let mut a = [0u8; 32];
61 let mut b = [0u8; 64];
62 let mut c = [0u8; 32];
63 a.copy_from_slice(&bytes[0..32]);
64 b.copy_from_slice(&bytes[32..96]);
65 c.copy_from_slice(&bytes[96..128]);
66 Ok(Self { a, b, c })
67 }
68}
69
70impl<'a> ZeroCopyAt<'a> for CompressedProof {
71 type ZeroCopyAt = Ref<&'a [u8], Self>;
72 fn zero_copy_at(bytes: &'a [u8]) -> Result<(Self::ZeroCopyAt, &'a [u8]), ZeroCopyError> {
73 Ok(Ref::<&[u8], CompressedProof>::from_prefix(bytes)?)
74 }
75}
76
77#[cfg_attr(
78 all(feature = "std", feature = "anchor"),
79 derive(anchor_lang::AnchorDeserialize, anchor_lang::AnchorSerialize)
80)]
81#[cfg_attr(
82 not(feature = "anchor"),
83 derive(borsh::BorshDeserialize, borsh::BorshSerialize)
84)]
85#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
86pub struct ValidityProof(pub Option<CompressedProof>);
87
88impl ValidityProof {
89 pub fn new(proof: Option<CompressedProof>) -> Self {
90 Self(proof)
91 }
92
93 pub fn to_array(&self) -> Option<[u8; 128]> {
96 self.0.as_ref().map(|proof| proof.to_array())
97 }
98}
99
100impl From<CompressedProof> for ValidityProof {
101 fn from(proof: CompressedProof) -> Self {
102 Self(Some(proof))
103 }
104}
105
106impl From<Option<CompressedProof>> for ValidityProof {
107 fn from(proof: Option<CompressedProof>) -> Self {
108 Self(proof)
109 }
110}
111impl From<&CompressedProof> for ValidityProof {
112 fn from(proof: &CompressedProof) -> Self {
113 Self(Some(*proof))
114 }
115}
116
117impl From<&Option<CompressedProof>> for ValidityProof {
118 fn from(proof: &Option<CompressedProof>) -> Self {
119 Self(*proof)
120 }
121}
122
123impl TryFrom<&[u8]> for ValidityProof {
124 type Error = crate::CompressedAccountError;
125
126 fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
129 if bytes.is_empty() {
130 Ok(Self(None))
131 } else {
132 let proof = CompressedProof::try_from(bytes)?;
133 Ok(Self(Some(proof)))
134 }
135 }
136}
137
138#[allow(clippy::from_over_into)]
139impl Into<Option<CompressedProof>> for ValidityProof {
140 fn into(self) -> Option<CompressedProof> {
141 self.0
142 }
143}