snarkvm_console_program/request/input_id/
mod.rs1mod bytes;
17mod serialize;
18mod string;
19
20use crate::{Identifier, Plaintext, ProgramID, Record, Value};
21use snarkvm_console_account::ViewKey;
22use snarkvm_console_network::Network;
23use snarkvm_console_types::prelude::*;
24
25#[derive(Copy, Clone, PartialEq, Eq, Hash)]
26pub enum InputID<N: Network> {
27 Constant(Field<N>),
29 Public(Field<N>),
31 Private(Field<N>),
33 Record(Field<N>, Group<N>, Field<N>, Field<N>, Field<N>),
35 ExternalRecord(Field<N>),
37 DynamicRecord(Field<N>),
39}
40
41impl<N: Network> InputID<N> {
42 pub const fn id(&self) -> &Field<N> {
44 match self {
45 InputID::Constant(id) => id,
46 InputID::Public(id) => id,
47 InputID::Private(id) => id,
48 InputID::Record(id, ..) => id,
49 InputID::ExternalRecord(id) => id,
50 InputID::DynamicRecord(id) => id,
51 }
52 }
53
54 pub fn constant(function_id: Field<N>, input: &Value<N>, tcm: Field<N>, index: u16) -> Result<Self> {
57 ensure!(matches!(input, Value::Plaintext(..)), "Expected a plaintext input");
59
60 let index = Field::from_u16(index);
62 let mut preimage = Vec::new();
64 preimage.push(function_id);
65 preimage.extend(input.to_fields()?);
66 preimage.push(tcm);
67 preimage.push(index);
68 let hash = N::hash_psd8(&preimage)?;
70
71 Ok(Self::Constant(hash))
72 }
73
74 pub fn public(function_id: Field<N>, input: &Value<N>, tcm: Field<N>, index: u16) -> Result<Self> {
77 ensure!(matches!(input, Value::Plaintext(..)), "Expected a plaintext input");
79
80 let index = Field::from_u16(index);
82 let mut preimage = Vec::new();
84 preimage.push(function_id);
85 preimage.extend(input.to_fields()?);
86 preimage.push(tcm);
87 preimage.push(index);
88 let hash = N::hash_psd8(&preimage)?;
90
91 Ok(Self::Public(hash))
92 }
93
94 pub fn private(function_id: Field<N>, input: &Value<N>, tvk: Field<N>, index: u16) -> Result<Self> {
97 ensure!(matches!(input, Value::Plaintext(..)), "Expected a plaintext input");
99
100 let index = Field::from_u16(index);
102 let input_view_key = N::hash_psd4(&[function_id, tvk, index])?;
104 let ciphertext = match &input {
106 Value::Plaintext(plaintext) => plaintext.encrypt_symmetric(input_view_key)?,
107 Value::Record(..) => bail!("Expected a plaintext input, found a record input"),
109 Value::Future(..) => bail!("Expected a plaintext input, found a future input"),
110 Value::DynamicRecord(..) => bail!("Expected a plaintext input, found a dynamic record input"),
111 Value::DynamicFuture(..) => bail!("Expected a plaintext input, found a dynamic future input"),
112 };
113 let hash = N::hash_psd8(&ciphertext.to_fields()?)?;
115
116 Ok(Self::Private(hash))
117 }
118
119 pub fn record(
122 program_id: &ProgramID<N>,
123 record_name: &Identifier<N>,
124 input: &Value<N>,
125 signer: &Address<N>,
126 view_key: &ViewKey<N>,
127 sk_sig: &Scalar<N>,
128 sk_tag: Field<N>,
129 ) -> Result<Self> {
130 let record = match &input {
132 Value::Record(record) => record,
133 Value::Plaintext(..) => bail!("Expected a record input, found a plaintext input"),
135 Value::Future(..) => bail!("Expected a record input, found a future input"),
136 Value::DynamicRecord(..) => bail!("Expected a record input, found a dynamic record input"),
137 Value::DynamicFuture(..) => bail!("Expected a record input, found a dynamic future input"),
138 };
139 ensure!(**record.owner() == *signer, "Input record '{program_id}/{record_name}' must belong to the signer");
141 let record_view_key = (*record.nonce() * **view_key).to_x_coordinate();
143 let commitment = record.to_commitment(program_id, record_name, &record_view_key)?;
145
146 let h = N::hash_to_group_psd2(&[N::serial_number_domain(), commitment])?;
148 let gamma = h * sk_sig;
150
151 let serial_number = Record::<N, Plaintext<N>>::serial_number_from_gamma(&gamma, commitment)?;
153 let tag = Record::<N, Plaintext<N>>::tag(sk_tag, commitment)?;
155
156 Ok(InputID::Record(commitment, gamma, record_view_key, serial_number, tag))
157 }
158
159 pub fn external_record(function_id: Field<N>, input: &Value<N>, tvk: Field<N>, index: u16) -> Result<Self> {
162 ensure!(matches!(input, Value::Record(..)), "Expected a record input");
164
165 let index = Field::from_u16(index);
167 let mut preimage = Vec::new();
169 preimage.push(function_id);
170 preimage.extend(input.to_fields()?);
171 preimage.push(tvk);
172 preimage.push(index);
173 let hash = N::hash_psd8(&preimage)?;
175
176 Ok(Self::ExternalRecord(hash))
177 }
178
179 pub fn dynamic_record(function_id: Field<N>, input: &Value<N>, tvk: Field<N>, index: u16) -> Result<Self> {
182 ensure!(matches!(input, Value::DynamicRecord(..)), "Expected a dynamic record input");
184
185 let index = Field::from_u16(index);
187 let mut preimage = Vec::new();
189 preimage.push(function_id);
190 preimage.extend(input.to_fields()?);
191 preimage.push(tvk);
192 preimage.push(index);
193 let hash = N::hash_psd8(&preimage)?;
195
196 Ok(Self::DynamicRecord(hash))
197 }
198}