snarkvm_console_program/data/ciphertext/
decrypt.rs1use super::*;
17
18impl<N: Network> Ciphertext<N> {
19 pub fn decrypt(&self, view_key: ViewKey<N>, nonce: Group<N>) -> Result<Plaintext<N>> {
21 let plaintext_view_key = (nonce * *view_key).to_x_coordinate();
23 self.decrypt_symmetric(plaintext_view_key)
25 }
26
27 pub fn decrypt_symmetric(&self, plaintext_view_key: Field<N>) -> Result<Plaintext<N>> {
29 let num_randomizers = self.num_randomizers()?;
31 let randomizers = N::hash_many_psd8(&[N::encryption_domain(), plaintext_view_key], num_randomizers);
33 self.decrypt_with_randomizers(&randomizers)
35 }
36
37 pub(crate) fn decrypt_with_randomizers(&self, randomizers: &[Field<N>]) -> Result<Plaintext<N>> {
39 Plaintext::from_fields(
41 &self
42 .iter()
43 .zip_eq(randomizers)
44 .map(|(ciphertext, randomizer)| *ciphertext - randomizer)
45 .collect::<Vec<_>>(),
46 )
47 }
48}
49
50#[cfg(test)]
51mod tests {
52 use super::*;
53 use crate::Literal;
54 use snarkvm_console_account::{Address, PrivateKey};
55 use snarkvm_console_network::MainnetV0;
56
57 type CurrentNetwork = MainnetV0;
58
59 const ITERATIONS: u64 = 100;
60
61 fn check_encrypt_and_decrypt<N: Network>(rng: &mut TestRng) -> Result<()> {
62 let plaintext_string = r"{
64 foo: 5u8,
65 bar: {
66 baz: 10field,
67 qux: {
68 quux: {
69 corge: {
70 grault: {
71 garply: {
72 waldo: {
73 fred: {
74 plugh: {
75 xyzzy: {
76 thud: true
77 }
78 }
79 }
80 }
81 }
82 }
83 }
84 }
85 }
86 }
87}";
88 let plaintext = Plaintext::<N>::from_str(plaintext_string)?;
89
90 let private_key = PrivateKey::<N>::new(rng)?;
92 let view_key = ViewKey::<N>::try_from(private_key)?;
93 let address = Address::<N>::try_from(view_key)?;
94
95 let randomizer = Uniform::rand(rng);
97 let ciphertext = plaintext.encrypt(&address, randomizer)?;
98
99 let nonce = N::g_scalar_multiply(&randomizer);
101 assert_eq!(plaintext, ciphertext.decrypt(view_key, nonce)?);
102 Ok(())
103 }
104
105 fn check_encrypt_and_decrypt_symmetric<N: Network>(rng: &mut TestRng) -> Result<()> {
106 let plaintext = Plaintext::<N>::from(Literal::Field(Uniform::rand(rng)));
108
109 let plaintext_view_key = Uniform::rand(rng);
111 let ciphertext = plaintext.encrypt_symmetric(plaintext_view_key)?;
112 assert_eq!(plaintext, ciphertext.decrypt_symmetric(plaintext_view_key)?);
114 Ok(())
115 }
116
117 #[test]
118 fn test_encrypt_and_decrypt() -> Result<()> {
119 let mut rng = TestRng::default();
120
121 for _ in 0..ITERATIONS {
122 check_encrypt_and_decrypt::<CurrentNetwork>(&mut rng)?;
123 check_encrypt_and_decrypt_symmetric::<CurrentNetwork>(&mut rng)?;
124 }
125 Ok(())
126 }
127}