mina_p2p_messages/
hash_input.rs

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