snarkvm_console_program/data/plaintext/
mod.rs

1// Copyright 2024-2025 Aleo Network Foundation
2// This file is part of the snarkVM library.
3
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at:
7
8// http://www.apache.org/licenses/LICENSE-2.0
9
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16mod bytes;
17mod encrypt;
18mod equal;
19mod find;
20mod from_bits;
21mod from_fields;
22mod num_randomizers;
23mod parse;
24mod serialize;
25mod size_in_fields;
26mod to_bits;
27mod to_fields;
28
29use crate::{Access, Ciphertext, Identifier, Literal};
30use snarkvm_console_network::Network;
31use snarkvm_console_types::prelude::*;
32
33use indexmap::IndexMap;
34use once_cell::sync::OnceCell;
35
36#[derive(Clone)]
37pub enum Plaintext<N: Network> {
38    /// A literal.
39    Literal(Literal<N>, OnceCell<Vec<bool>>),
40    /// A struct.
41    Struct(IndexMap<Identifier<N>, Plaintext<N>>, OnceCell<Vec<bool>>),
42    /// An array.
43    Array(Vec<Plaintext<N>>, OnceCell<Vec<bool>>),
44}
45
46impl<N: Network> From<Literal<N>> for Plaintext<N> {
47    /// Returns a new `Plaintext` from a `Literal`.
48    fn from(literal: Literal<N>) -> Self {
49        Self::Literal(literal, OnceCell::new())
50    }
51}
52
53impl<N: Network> From<&Literal<N>> for Plaintext<N> {
54    /// Returns a new `Plaintext` from a `&Literal`.
55    fn from(literal: &Literal<N>) -> Self {
56        Self::Literal(literal.clone(), OnceCell::new())
57    }
58}
59
60#[cfg(test)]
61mod tests {
62    use super::*;
63    use snarkvm_console_network::MainnetV0;
64    use snarkvm_console_types::Field;
65
66    use core::str::FromStr;
67
68    type CurrentNetwork = MainnetV0;
69
70    #[test]
71    fn test_plaintext() -> Result<()> {
72        let run_test = |value: Plaintext<CurrentNetwork>| {
73            assert_eq!(
74                value.to_bits_le(),
75                Plaintext::<CurrentNetwork>::from_bits_le(&value.to_bits_le()).unwrap().to_bits_le()
76            );
77            assert_eq!(value, Plaintext::<CurrentNetwork>::from_fields(&value.to_fields().unwrap()).unwrap());
78            assert_eq!(value, Plaintext::<CurrentNetwork>::from_str(&value.to_string()).unwrap());
79            assert!(*value.is_equal(&value));
80            assert!(*!value.is_not_equal(&value));
81        };
82
83        let mut rng = TestRng::default();
84
85        // Test booleans.
86        run_test(Plaintext::<CurrentNetwork>::from_str("true")?);
87        run_test(Plaintext::<CurrentNetwork>::from_str("false")?);
88
89        // Test a random field element.
90        run_test(Plaintext::<CurrentNetwork>::Literal(
91            Literal::Field(Field::new(Uniform::rand(&mut rng))),
92            OnceCell::new(),
93        ));
94
95        // Test a random struct with literal members.
96        run_test(Plaintext::<CurrentNetwork>::Struct(
97            IndexMap::from_iter(vec![
98                (Identifier::from_str("a")?, Plaintext::<CurrentNetwork>::from_str("true")?),
99                (
100                    Identifier::from_str("b")?,
101                    Plaintext::<CurrentNetwork>::Literal(
102                        Literal::Field(Field::new(Uniform::rand(&mut rng))),
103                        OnceCell::new(),
104                    ),
105                ),
106            ]),
107            OnceCell::new(),
108        ));
109
110        // Test a random struct with array members.
111        run_test(Plaintext::<CurrentNetwork>::Struct(
112            IndexMap::from_iter(vec![
113                (Identifier::from_str("a")?, Plaintext::<CurrentNetwork>::from_str("true")?),
114                (
115                    Identifier::from_str("b")?,
116                    Plaintext::<CurrentNetwork>::Array(
117                        vec![
118                            Plaintext::<CurrentNetwork>::from_str("true")?,
119                            Plaintext::<CurrentNetwork>::from_str("false")?,
120                        ],
121                        OnceCell::new(),
122                    ),
123                ),
124            ]),
125            OnceCell::new(),
126        ));
127
128        // Test random deeply-nested struct.
129        run_test(Plaintext::<CurrentNetwork>::Struct(
130            IndexMap::from_iter(vec![
131                (Identifier::from_str("a")?, Plaintext::<CurrentNetwork>::from_str("true")?),
132                (
133                    Identifier::from_str("b")?,
134                    Plaintext::<CurrentNetwork>::Struct(
135                        IndexMap::from_iter(vec![
136                            (Identifier::from_str("c")?, Plaintext::<CurrentNetwork>::from_str("true")?),
137                            (
138                                Identifier::from_str("d")?,
139                                Plaintext::<CurrentNetwork>::Struct(
140                                    IndexMap::from_iter(vec![
141                                        (Identifier::from_str("e")?, Plaintext::<CurrentNetwork>::from_str("true")?),
142                                        (
143                                            Identifier::from_str("f")?,
144                                            Plaintext::<CurrentNetwork>::Literal(
145                                                Literal::Field(Field::new(Uniform::rand(&mut rng))),
146                                                OnceCell::new(),
147                                            ),
148                                        ),
149                                    ]),
150                                    OnceCell::new(),
151                                ),
152                            ),
153                            (
154                                Identifier::from_str("g")?,
155                                Plaintext::Array(
156                                    vec![
157                                        Plaintext::<CurrentNetwork>::from_str("true")?,
158                                        Plaintext::<CurrentNetwork>::from_str("false")?,
159                                    ],
160                                    OnceCell::new(),
161                                ),
162                            ),
163                        ]),
164                        OnceCell::new(),
165                    ),
166                ),
167                (
168                    Identifier::from_str("h")?,
169                    Plaintext::<CurrentNetwork>::Literal(
170                        Literal::Field(Field::new(Uniform::rand(&mut rng))),
171                        OnceCell::new(),
172                    ),
173                ),
174            ]),
175            OnceCell::new(),
176        ));
177
178        // Test an array of literals.
179        run_test(Plaintext::<CurrentNetwork>::Array(
180            vec![
181                Plaintext::<CurrentNetwork>::from_str("0field")?,
182                Plaintext::<CurrentNetwork>::from_str("1field")?,
183                Plaintext::<CurrentNetwork>::from_str("2field")?,
184                Plaintext::<CurrentNetwork>::from_str("3field")?,
185                Plaintext::<CurrentNetwork>::from_str("4field")?,
186            ],
187            OnceCell::new(),
188        ));
189
190        // Test an array of structs.
191        run_test(Plaintext::<CurrentNetwork>::Array(
192            vec![
193                Plaintext::<CurrentNetwork>::from_str("{ x: 0field, y: 1field }")?,
194                Plaintext::<CurrentNetwork>::from_str("{ x: 2field, y: 3field }")?,
195                Plaintext::<CurrentNetwork>::from_str("{ x: 4field, y: 5field }")?,
196                Plaintext::<CurrentNetwork>::from_str("{ x: 6field, y: 7field }")?,
197                Plaintext::<CurrentNetwork>::from_str("{ x: 8field, y: 9field }")?,
198            ],
199            OnceCell::new(),
200        ));
201
202        // Test a non-uniform array.
203        run_test(Plaintext::<CurrentNetwork>::Array(
204            vec![
205                Plaintext::<CurrentNetwork>::from_str("true")?,
206                Plaintext::<CurrentNetwork>::from_str("1field")?,
207                Plaintext::<CurrentNetwork>::from_str("{ x: 4field, y: 1u8 }")?,
208            ],
209            OnceCell::new(),
210        ));
211
212        Ok(())
213    }
214}