solana_zk_token_sdk/zk_token_elgamal/pod/
range_proof.rs1#[cfg(not(target_os = "solana"))]
4use crate::{
5 range_proof::{self as decoded, errors::RangeProofVerificationError},
6 UNIT_LEN,
7};
8use {
9 crate::{RISTRETTO_POINT_LEN, SCALAR_LEN},
10 bytemuck::{Pod, Zeroable},
11};
12
13const RANGE_PROOF_MODULO_INNER_PRODUCT_PROOF_LEN: usize = 5 * RISTRETTO_POINT_LEN + 2 * SCALAR_LEN;
15
16const INNER_PRODUCT_PROOF_U64_LEN: usize = 448;
18
19const RANGE_PROOF_U64_LEN: usize =
21 INNER_PRODUCT_PROOF_U64_LEN + RANGE_PROOF_MODULO_INNER_PRODUCT_PROOF_LEN;
22
23const INNER_PRODUCT_PROOF_U128_LEN: usize = 512;
25
26const RANGE_PROOF_U128_LEN: usize =
28 INNER_PRODUCT_PROOF_U128_LEN + RANGE_PROOF_MODULO_INNER_PRODUCT_PROOF_LEN;
29
30const INNER_PRODUCT_PROOF_U256_LEN: usize = 576;
32
33const RANGE_PROOF_U256_LEN: usize =
35 INNER_PRODUCT_PROOF_U256_LEN + RANGE_PROOF_MODULO_INNER_PRODUCT_PROOF_LEN;
36
37#[derive(Clone, Copy)]
39#[repr(transparent)]
40pub struct RangeProofU64(pub [u8; RANGE_PROOF_U64_LEN]);
41
42#[cfg(not(target_os = "solana"))]
43impl TryFrom<decoded::RangeProof> for RangeProofU64 {
44 type Error = RangeProofVerificationError;
45
46 fn try_from(decoded_proof: decoded::RangeProof) -> Result<Self, Self::Error> {
47 if decoded_proof.ipp_proof.serialized_size() != INNER_PRODUCT_PROOF_U64_LEN {
48 return Err(RangeProofVerificationError::Deserialization);
49 }
50
51 let mut buf = [0_u8; RANGE_PROOF_U64_LEN];
52 copy_range_proof_modulo_inner_product_proof(&decoded_proof, &mut buf);
53 buf[RANGE_PROOF_MODULO_INNER_PRODUCT_PROOF_LEN..RANGE_PROOF_U64_LEN]
54 .copy_from_slice(&decoded_proof.ipp_proof.to_bytes());
55 Ok(RangeProofU64(buf))
56 }
57}
58
59#[cfg(not(target_os = "solana"))]
60impl TryFrom<RangeProofU64> for decoded::RangeProof {
61 type Error = RangeProofVerificationError;
62
63 fn try_from(pod_proof: RangeProofU64) -> Result<Self, Self::Error> {
64 Self::from_bytes(&pod_proof.0)
65 }
66}
67
68#[derive(Clone, Copy)]
70#[repr(transparent)]
71pub struct RangeProofU128(pub [u8; RANGE_PROOF_U128_LEN]);
72
73#[cfg(not(target_os = "solana"))]
74impl TryFrom<decoded::RangeProof> for RangeProofU128 {
75 type Error = RangeProofVerificationError;
76
77 fn try_from(decoded_proof: decoded::RangeProof) -> Result<Self, Self::Error> {
78 if decoded_proof.ipp_proof.serialized_size() != INNER_PRODUCT_PROOF_U128_LEN {
79 return Err(RangeProofVerificationError::Deserialization);
80 }
81
82 let mut buf = [0_u8; RANGE_PROOF_U128_LEN];
83 copy_range_proof_modulo_inner_product_proof(&decoded_proof, &mut buf);
84 buf[RANGE_PROOF_MODULO_INNER_PRODUCT_PROOF_LEN..RANGE_PROOF_U128_LEN]
85 .copy_from_slice(&decoded_proof.ipp_proof.to_bytes());
86 Ok(RangeProofU128(buf))
87 }
88}
89
90#[cfg(not(target_os = "solana"))]
91impl TryFrom<RangeProofU128> for decoded::RangeProof {
92 type Error = RangeProofVerificationError;
93
94 fn try_from(pod_proof: RangeProofU128) -> Result<Self, Self::Error> {
95 Self::from_bytes(&pod_proof.0)
96 }
97}
98
99#[derive(Clone, Copy)]
101#[repr(transparent)]
102pub struct RangeProofU256(pub [u8; RANGE_PROOF_U256_LEN]);
103
104#[cfg(not(target_os = "solana"))]
105impl TryFrom<decoded::RangeProof> for RangeProofU256 {
106 type Error = RangeProofVerificationError;
107
108 fn try_from(decoded_proof: decoded::RangeProof) -> Result<Self, Self::Error> {
109 if decoded_proof.ipp_proof.serialized_size() != INNER_PRODUCT_PROOF_U256_LEN {
110 return Err(RangeProofVerificationError::Deserialization);
111 }
112
113 let mut buf = [0_u8; RANGE_PROOF_U256_LEN];
114 copy_range_proof_modulo_inner_product_proof(&decoded_proof, &mut buf);
115 buf[RANGE_PROOF_MODULO_INNER_PRODUCT_PROOF_LEN..RANGE_PROOF_U256_LEN]
116 .copy_from_slice(&decoded_proof.ipp_proof.to_bytes());
117 Ok(RangeProofU256(buf))
118 }
119}
120
121#[cfg(not(target_os = "solana"))]
122impl TryFrom<RangeProofU256> for decoded::RangeProof {
123 type Error = RangeProofVerificationError;
124
125 fn try_from(pod_proof: RangeProofU256) -> Result<Self, Self::Error> {
126 Self::from_bytes(&pod_proof.0)
127 }
128}
129
130#[cfg(not(target_os = "solana"))]
131fn copy_range_proof_modulo_inner_product_proof(proof: &decoded::RangeProof, buf: &mut [u8]) {
132 let mut chunks = buf.chunks_mut(UNIT_LEN);
133 chunks.next().unwrap().copy_from_slice(proof.A.as_bytes());
134 chunks.next().unwrap().copy_from_slice(proof.S.as_bytes());
135 chunks.next().unwrap().copy_from_slice(proof.T_1.as_bytes());
136 chunks.next().unwrap().copy_from_slice(proof.T_2.as_bytes());
137 chunks.next().unwrap().copy_from_slice(proof.t_x.as_bytes());
138 chunks
139 .next()
140 .unwrap()
141 .copy_from_slice(proof.t_x_blinding.as_bytes());
142 chunks
143 .next()
144 .unwrap()
145 .copy_from_slice(proof.e_blinding.as_bytes());
146}
147
148unsafe impl Zeroable for RangeProofU64 {}
152unsafe impl Pod for RangeProofU64 {}
153
154unsafe impl Zeroable for RangeProofU128 {}
155unsafe impl Pod for RangeProofU128 {}
156
157unsafe impl Zeroable for RangeProofU256 {}
158unsafe impl Pod for RangeProofU256 {}