liminal_ark_relations/shielder/
note.rs

1//! Module exposing some utilities regarding note generation and verification.
2
3use ark_std::{vec, vec::Vec};
4use liminal_ark_poseidon::hash;
5
6use super::types::{
7    FrontendNote, FrontendNullifier, FrontendTokenAmount, FrontendTokenId, FrontendTrapdoor,
8};
9use crate::{environment::CircuitField, shielder::convert_hash};
10
11/// Compute note as the result of hashing `(token_id, token_amount, trapdoor, nullifier)`.
12///
13/// Useful for input preparation and offline note generation.
14pub fn compute_note(
15    token_id: FrontendTokenId,
16    token_amount: FrontendTokenAmount,
17    trapdoor: FrontendTrapdoor,
18    nullifier: FrontendNullifier,
19) -> FrontendNote {
20    hash::four_to_one_hash([
21        CircuitField::from(token_id as u64),
22        CircuitField::from(token_amount),
23        convert_hash(trapdoor),
24        convert_hash(nullifier),
25    ])
26    .0
27     .0
28}
29
30pub fn compute_parent_hash(left: FrontendNote, right: FrontendNote) -> FrontendNote {
31    hash::two_to_one_hash([convert_hash(left), convert_hash(right)])
32        .0
33         .0
34}
35
36/// Create a note from the first 32 bytes of `bytes`.
37pub fn note_from_bytes(bytes: &[u8]) -> FrontendNote {
38    [
39        u64::from_le_bytes(bytes[0..8].try_into().unwrap()),
40        u64::from_le_bytes(bytes[8..16].try_into().unwrap()),
41        u64::from_le_bytes(bytes[16..24].try_into().unwrap()),
42        u64::from_le_bytes(bytes[24..32].try_into().unwrap()),
43    ]
44}
45
46fn convert(x: u64) -> [u8; 8] {
47    x.to_le_bytes()
48}
49
50pub fn bytes_from_note(note: &FrontendNote) -> Vec<u8> {
51    let mut res = vec![];
52    for elem in note {
53        let mut arr: Vec<u8> = convert(*elem).into();
54        res.append(&mut arr);
55    }
56    res
57}
58
59#[cfg(test)]
60mod tests {
61    use super::*;
62
63    #[test]
64    fn note_conversion() {
65        let token_id: FrontendTokenId = 1;
66        let token_amount: FrontendTokenAmount = 10;
67        let trapdoor: FrontendTrapdoor = [17; 4];
68        let nullifier: FrontendNullifier = [19; 4];
69        let note = compute_note(token_id, token_amount, trapdoor, nullifier);
70
71        let bytes = bytes_from_note(&note);
72        let note_again = note_from_bytes(&bytes);
73
74        assert_eq!(note, note_again);
75    }
76}