1use mina_curves::pasta::Fp;
2use mina_signer::CompressedPubKey;
3
4use crate::{proofs::witness::Witness, scan_state::currency};
5use poseidon::hash::{hash_with_kimchi, Inputs, LazyParam};
6
7pub trait ToInputs {
8 fn to_inputs(&self, inputs: &mut Inputs);
9
10 fn to_inputs_owned(&self) -> Inputs {
11 let mut inputs = Inputs::new();
12 self.to_inputs(&mut inputs);
13 inputs
14 }
15
16 fn hash_with_param(&self, param: &LazyParam) -> Fp {
17 let mut inputs = Inputs::new();
18 self.to_inputs(&mut inputs);
19 hash_with_kimchi(param, &inputs.to_fields())
20 }
21
22 fn checked_hash_with_param(&self, param: &LazyParam, w: &mut Witness<Fp>) -> Fp {
23 use crate::proofs::transaction::transaction_snark::checked_hash;
24
25 let inputs = self.to_inputs_owned();
26 checked_hash(param, &inputs.to_fields(), w)
27 }
28}
29
30impl ToInputs for Fp {
31 fn to_inputs(&self, inputs: &mut Inputs) {
32 inputs.append_field(*self);
33 }
34}
35
36impl<const N: usize> ToInputs for [Fp; N] {
37 fn to_inputs(&self, inputs: &mut Inputs) {
38 for field in self {
39 inputs.append(field);
40 }
41 }
42}
43
44impl ToInputs for CompressedPubKey {
45 fn to_inputs(&self, inputs: &mut Inputs) {
46 inputs.append_field(self.x);
47 inputs.append_bool(self.is_odd);
48 }
49}
50
51impl ToInputs for crate::TokenId {
52 fn to_inputs(&self, inputs: &mut Inputs) {
53 inputs.append_field(self.0);
54 }
55}
56
57impl ToInputs for bool {
58 fn to_inputs(&self, inputs: &mut Inputs) {
59 inputs.append_bool(*self);
60 }
61}
62
63impl<T> ToInputs for currency::Signed<T>
64where
65 T: currency::Magnitude,
66 T: ToInputs,
67{
68 fn to_inputs(&self, inputs: &mut Inputs) {
70 self.magnitude.to_inputs(inputs);
71 let sgn = matches!(self.sgn, currency::Sgn::Pos);
72 inputs.append_bool(sgn);
73 }
74}
75
76pub trait AppendToInputs {
77 fn append<T>(&mut self, value: &T)
78 where
79 T: ToInputs;
80}
81
82impl AppendToInputs for Inputs {
83 fn append<T>(&mut self, value: &T)
84 where
85 T: ToInputs,
86 {
87 value.to_inputs(self);
88 }
89}
90
91#[cfg(test)]
92mod tests {
93 use o1_utils::FieldHelpers;
94
95 use poseidon::hash::param_to_field;
96 #[cfg(target_family = "wasm")]
97 use wasm_bindgen_test::wasm_bindgen_test as test;
98
99 use super::*;
100
101 #[test]
102 fn test_param() {
103 for (s, hex) in [
104 (
105 "",
106 "2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a000000000000000000000000",
107 ),
108 (
109 "hello",
110 "68656c6c6f2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a000000000000000000000000",
111 ),
112 (
113 "aaaaaaaaaaaaaaaaaaaa",
114 "6161616161616161616161616161616161616161000000000000000000000000",
115 ),
116 ] {
117 let field = param_to_field(s);
118 assert_eq!(field.to_hex(), hex);
119 }
120 }
121
122 #[test]
123 fn test_inputs() {
124 let mut inputs = Inputs::new();
125
126 inputs.append_bool(true);
127 inputs.append_u64(0); inputs.append_u32(0); inputs.append_u64(0); inputs.append_u32(1); inputs.append_u64(0); elog!("INPUTS={:?}", inputs);
134 elog!("FIELDS={:?}", inputs.to_fields());
135
136 }
162}