mina_tree/
hash.rs

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    /// <https://github.com/MinaProtocol/mina/blob/3fe924c80a4d01f418b69f27398f5f93eb652514/src/lib/currency/currency.ml#L453>
69    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); // initial_minimum_balance
128        inputs.append_u32(0); // cliff_time
129        inputs.append_u64(0); // cliff_amount
130        inputs.append_u32(1); // vesting_period
131        inputs.append_u64(0); // vesting_increment
132
133        elog!("INPUTS={:?}", inputs);
134        elog!("FIELDS={:?}", inputs.to_fields());
135
136        // // Self::timing
137        // match self.timing {
138        //     Timing::Untimed => {
139        //         roi.append_bool(false);
140        //         roi.append_u64(0); // initial_minimum_balance
141        //         roi.append_u32(0); // cliff_time
142        //         roi.append_u64(0); // cliff_amount
143        //         roi.append_u32(1); // vesting_period
144        //         roi.append_u64(0); // vesting_increment
145        //     }
146        //     Timing::Timed {
147        //         initial_minimum_balance,
148        //         cliff_time,
149        //         cliff_amount,
150        //         vesting_period,
151        //         vesting_increment,
152        //     } => {
153        //         roi.append_bool(true);
154        //         roi.append_u64(initial_minimum_balance);
155        //         roi.append_u32(cliff_time);
156        //         roi.append_u64(cliff_amount);
157        //         roi.append_u32(vesting_period);
158        //         roi.append_u64(vesting_increment);
159        //     }
160        // }
161    }
162}