snarkvm_synthesizer_process/stack/helpers/
synthesize.rs1use console::program::{DynamicRecord, ToFields};
17
18use crate::{TranslationAssignment, compute_console_dynamic_or_external_record_id};
19
20use super::*;
21
22impl<N: Network> Stack<N> {
23 #[inline]
25 pub fn synthesize_key<A: circuit::Aleo<Network = N>, R: Rng + CryptoRng>(
26 &self,
27 function_name: &Identifier<N>,
28 rng: &mut R,
29 ) -> Result<()> {
30 if self.contains_proving_key(function_name) && self.contains_verifying_key(function_name) {
32 return Ok(());
33 }
34
35 let program_id = self.program_id();
37 let input_types = self.get_function(function_name)?.input_types();
39 let program_checksum = match self.program().contains_constructor() {
41 true => Some(self.program_checksum_as_field()?),
42 false => None,
43 };
44
45 let burner_private_key = PrivateKey::new(rng)?;
47 let burner_address = Address::try_from(&burner_private_key)?;
49 let inputs = input_types
51 .iter()
52 .map(|input_type| match input_type {
53 ValueType::ExternalRecord(locator) => {
54 let stack = self.get_external_stack(locator.program_id())?;
56 stack.sample_value(&burner_address, &ValueType::Record(*locator.resource()).into(), rng)
58 }
59 _ => self.sample_value(&burner_address, &input_type.into(), rng),
60 })
61 .collect::<Result<Vec<_>>>()?;
62 let is_root = true;
64 let root_tvk = None;
66 let caller = None;
68
69 let request = Request::sign(
71 &burner_private_key,
72 *program_id,
73 *function_name,
74 inputs.into_iter(),
75 &input_types,
76 root_tvk,
77 is_root,
78 program_checksum,
79 false,
80 rng,
81 )?;
82
83 let authorization = Authorization::new(request.clone());
85 let call_stack = CallStack::Synthesize(vec![request], burner_private_key, authorization);
87 let _response = self.execute_function::<A, R>(call_stack, caller, root_tvk, rng)?;
89
90 ensure!(self.contains_proving_key(function_name), "Function '{function_name}' is missing a proving key.");
92 ensure!(self.contains_verifying_key(function_name), "Function '{function_name}' is missing a verifying key.");
94 Ok(())
95 }
96
97 #[inline]
99 pub fn synthesize_from_assignment(
100 &self,
101 function_name: &Identifier<N>,
102 assignment: &circuit::Assignment<N::Field>,
103 ) -> Result<()> {
104 if self.contains_proving_key(function_name) && self.contains_verifying_key(function_name) {
106 return Ok(());
107 }
108
109 let (proving_key, verifying_key) = self.universal_srs.to_circuit_key(&function_name.to_string(), assignment)?;
111 self.insert_proving_key(function_name, proving_key)?;
113 self.insert_verifying_key(function_name, verifying_key)
115 }
116
117 #[inline]
119 pub fn synthesize_translation_key<A: circuit::Aleo<Network = N>, R: Rng + CryptoRng>(
120 &self,
121 record_name: &Identifier<N>,
122 rng: &mut R,
123 ) -> Result<()> {
124 if self.contains_proving_key(record_name) && self.contains_verifying_key(record_name) {
126 return Ok(());
127 }
128
129 let private_key = PrivateKey::new(rng)?;
131 let address = Address::try_from(&private_key)?;
132 let program_id = *self.program_id();
133 let function_id = Field::<N>::from_u64(Uniform::rand(rng));
134 let record_name = *record_name;
135 let record_static = self.sample_record(&address, &record_name, Group::rand(rng), rng)?;
136 let record_dynamic = DynamicRecord::<N>::from_record(&record_static)?;
137 let translation_index: u16 = Uniform::rand(rng);
138 let tvk = Uniform::rand(rng);
139 let record_register_index = Uniform::rand(rng);
140 let record_view_key = UniformExt::rand_option(rng);
141 let gamma = UniformExt::rand_option(rng);
142 let id_dynamic = compute_console_dynamic_or_external_record_id(
144 function_id,
145 record_dynamic.to_fields()?,
146 tvk,
147 U16::new(record_register_index),
148 )?;
149 let is_to_static = Uniform::rand(rng);
150 let is_external_record = Uniform::rand(rng);
151 let id_static = Uniform::rand(rng);
152
153 let translation_assignment = TranslationAssignment::new(
154 record_static,
155 record_dynamic,
156 program_id,
157 function_id,
158 record_name,
159 is_to_static,
160 is_external_record,
161 tvk,
162 record_view_key,
163 gamma,
164 record_register_index,
165 id_dynamic,
166 id_static,
167 );
168
169 let circuit_assignment = translation_assignment.to_circuit_assignment::<A>(translation_index)?;
171
172 let (proving_key, verifying_key) =
174 self.universal_srs.to_circuit_key(&record_name.to_string(), &circuit_assignment)?;
175 self.insert_proving_key(&record_name, proving_key)?;
177 self.insert_verifying_key(&record_name, verifying_key)
179 }
180}