mina_p2p_messages/
hash_input.rs

1use std::ops::Deref;
2
3use ark_ff::fields::arithmetic::InvalidBigInt;
4use poseidon::hash::Inputs;
5
6use crate::{
7    bigint::BigInt,
8    list::List,
9    number::{Int32, Int64, UInt32, UInt64},
10    string::{ByteString, ZkAppUri},
11};
12
13/// Difference with `ToInputs` in `ledger` is that it can fail here, due
14/// to invalid bigints
15pub trait FailableToInputs {
16    fn to_input(&self, inputs: &mut Inputs) -> Result<(), InvalidBigInt>;
17}
18
19impl FailableToInputs for bool {
20    fn to_input(&self, inputs: &mut Inputs) -> Result<(), InvalidBigInt> {
21        inputs.append_bool(*self);
22        Ok(())
23    }
24}
25
26impl FailableToInputs for BigInt {
27    fn to_input(&self, inputs: &mut Inputs) -> Result<(), InvalidBigInt> {
28        let field = self.to_field()?;
29        inputs.append_field(field);
30        Ok(())
31    }
32}
33
34impl FailableToInputs for Int32 {
35    fn to_input(&self, inputs: &mut Inputs) -> Result<(), InvalidBigInt> {
36        inputs.append_u32(self.as_u32());
37        Ok(())
38    }
39}
40
41impl FailableToInputs for Int64 {
42    fn to_input(&self, inputs: &mut Inputs) -> Result<(), InvalidBigInt> {
43        inputs.append_u64(self.as_u64());
44        Ok(())
45    }
46}
47
48impl FailableToInputs for UInt32 {
49    fn to_input(&self, inputs: &mut Inputs) -> Result<(), InvalidBigInt> {
50        inputs.append_u32(self.as_u32());
51        Ok(())
52    }
53}
54
55impl FailableToInputs for UInt64 {
56    fn to_input(&self, inputs: &mut Inputs) -> Result<(), InvalidBigInt> {
57        inputs.append_u64(self.as_u64());
58        Ok(())
59    }
60}
61
62impl FailableToInputs for ByteString {
63    fn to_input(&self, inputs: &mut Inputs) -> Result<(), InvalidBigInt> {
64        inputs.append_bytes(self.as_ref());
65        Ok(())
66    }
67}
68
69impl FailableToInputs for ZkAppUri {
70    fn to_input(&self, inputs: &mut Inputs) -> Result<(), InvalidBigInt> {
71        inputs.append_bytes(self.as_ref());
72        Ok(())
73    }
74}
75
76impl<T, D> FailableToInputs for List<D>
77where
78    D: Deref<Target = T>,
79    T: FailableToInputs,
80{
81    fn to_input(&self, inputs: &mut Inputs) -> Result<(), InvalidBigInt> {
82        for v in self.deref().iter() {
83            v.to_input(inputs)?;
84        }
85        Ok(())
86    }
87}
88
89#[cfg(test)]
90mod tests {
91    use o1_utils::FieldHelpers;
92
93    use super::Inputs;
94
95    macro_rules! test_to_field {
96        ($test:ident : $fun:ident ( $( $value:expr ),* $(,)? ) = $hex:expr ) => {
97            #[test]
98            fn $test() {
99                let mut inputs = Inputs::new();
100                $(
101                    inputs.$fun($value);
102                )*
103                let fields = inputs.to_fields();
104                assert_eq!(fields.len(), 1);
105                let hex = fields[0].to_hex();
106                assert_eq!(&hex, $hex);
107            }
108        };
109    }
110
111    fn u48(n: u64) -> [u8; 6] {
112        n.to_le_bytes()[..6].try_into().unwrap()
113    }
114
115    test_to_field!(to_field_bools_test: append_bool(true, false) = "0200000000000000000000000000000000000000000000000000000000000000");
116    test_to_field!(to_field_u2_test: append_u2(0, 1, 3, 4) = "1c00000000000000000000000000000000000000000000000000000000000000");
117    test_to_field!(to_field_u8_test: append_u8(u8::MIN, u8::MAX / 2, u8::MAX) = "ff7f000000000000000000000000000000000000000000000000000000000000");
118    test_to_field!(to_field_u32_test: append_u32(u32::MIN, u32::MAX/2, u32::MAX) = "ffffffffffffff7f000000000000000000000000000000000000000000000000");
119    test_to_field!(to_field_u64_test: append_u64(u64::MIN, u64::MAX/2, u64::MAX) = "ffffffffffffffffffffffffffffff7f00000000000000000000000000000000");
120    test_to_field!(to_field_u48_test: append_u48(u48(u64::MIN), u48(u64::MAX/2), u48(u64::MAX)) = "ffffffffffffffffffffffff0000000000000000000000000000000000000000");
121    test_to_field!(to_field_bytes_test: append_bytes(&[0, 1, 255]) = "ff80000000000000000000000000000000000000000000000000000000000000");
122}