solana_zk_token_sdk/zk_token_elgamal/
convert.rs

1use {super::pod, solana_curve25519::ristretto::PodRistrettoPoint};
2
3impl From<(pod::PedersenCommitment, pod::DecryptHandle)> for pod::ElGamalCiphertext {
4    fn from((commitment, handle): (pod::PedersenCommitment, pod::DecryptHandle)) -> Self {
5        let mut buf = [0_u8; 64];
6        buf[..32].copy_from_slice(&commitment.0);
7        buf[32..].copy_from_slice(&handle.0);
8        pod::ElGamalCiphertext(buf)
9    }
10}
11
12impl From<pod::ElGamalCiphertext> for (pod::PedersenCommitment, pod::DecryptHandle) {
13    fn from(ciphertext: pod::ElGamalCiphertext) -> Self {
14        let commitment: [u8; 32] = ciphertext.0[..32].try_into().unwrap();
15        let handle: [u8; 32] = ciphertext.0[32..].try_into().unwrap();
16
17        (
18            pod::PedersenCommitment(commitment),
19            pod::DecryptHandle(handle),
20        )
21    }
22}
23
24impl From<pod::PedersenCommitment> for PodRistrettoPoint {
25    fn from(commitment: pod::PedersenCommitment) -> Self {
26        PodRistrettoPoint(commitment.0)
27    }
28}
29
30impl From<PodRistrettoPoint> for pod::PedersenCommitment {
31    fn from(point: PodRistrettoPoint) -> Self {
32        pod::PedersenCommitment(point.0)
33    }
34}
35
36impl From<pod::DecryptHandle> for PodRistrettoPoint {
37    fn from(handle: pod::DecryptHandle) -> Self {
38        PodRistrettoPoint(handle.0)
39    }
40}
41
42impl From<PodRistrettoPoint> for pod::DecryptHandle {
43    fn from(point: PodRistrettoPoint) -> Self {
44        pod::DecryptHandle(point.0)
45    }
46}
47
48#[cfg(not(target_os = "solana"))]
49mod target_arch {
50    use {super::pod, curve25519_dalek::ristretto::CompressedRistretto};
51
52    impl From<CompressedRistretto> for pod::CompressedRistretto {
53        fn from(cr: CompressedRistretto) -> Self {
54            Self(cr.to_bytes())
55        }
56    }
57
58    impl From<pod::CompressedRistretto> for CompressedRistretto {
59        fn from(pod: pod::CompressedRistretto) -> Self {
60            Self(pod.0)
61        }
62    }
63}
64
65#[cfg(target_os = "solana")]
66#[allow(unused_variables)]
67mod target_arch {}
68
69#[cfg(test)]
70mod tests {
71    use {
72        super::*,
73        crate::{encryption::pedersen::Pedersen, range_proof::RangeProof},
74        merlin::Transcript,
75        std::convert::TryInto,
76    };
77
78    #[test]
79    fn test_pod_range_proof_64() {
80        let (comm, open) = Pedersen::new(55_u64);
81
82        let mut transcript_create = Transcript::new(b"Test");
83        let mut transcript_verify = Transcript::new(b"Test");
84
85        let proof =
86            RangeProof::new(vec![55], vec![64], vec![&open], &mut transcript_create).unwrap();
87
88        let proof_serialized: pod::RangeProofU64 = proof.try_into().unwrap();
89        let proof_deserialized: RangeProof = proof_serialized.try_into().unwrap();
90
91        assert!(proof_deserialized
92            .verify(vec![&comm], vec![64], &mut transcript_verify)
93            .is_ok());
94
95        // should fail to serialize to pod::RangeProof128
96        let proof =
97            RangeProof::new(vec![55], vec![64], vec![&open], &mut transcript_create).unwrap();
98
99        assert!(TryInto::<pod::RangeProofU128>::try_into(proof).is_err());
100    }
101
102    #[test]
103    fn test_pod_range_proof_128() {
104        let (comm_1, open_1) = Pedersen::new(55_u64);
105        let (comm_2, open_2) = Pedersen::new(77_u64);
106        let (comm_3, open_3) = Pedersen::new(99_u64);
107
108        let mut transcript_create = Transcript::new(b"Test");
109        let mut transcript_verify = Transcript::new(b"Test");
110
111        let proof = RangeProof::new(
112            vec![55, 77, 99],
113            vec![64, 32, 32],
114            vec![&open_1, &open_2, &open_3],
115            &mut transcript_create,
116        )
117        .unwrap();
118
119        let proof_serialized: pod::RangeProofU128 = proof.try_into().unwrap();
120        let proof_deserialized: RangeProof = proof_serialized.try_into().unwrap();
121
122        assert!(proof_deserialized
123            .verify(
124                vec![&comm_1, &comm_2, &comm_3],
125                vec![64, 32, 32],
126                &mut transcript_verify,
127            )
128            .is_ok());
129
130        // should fail to serialize to pod::RangeProof64
131        let proof = RangeProof::new(
132            vec![55, 77, 99],
133            vec![64, 32, 32],
134            vec![&open_1, &open_2, &open_3],
135            &mut transcript_create,
136        )
137        .unwrap();
138
139        assert!(TryInto::<pod::RangeProofU64>::try_into(proof).is_err());
140    }
141}