liminal_ark_relations/shielder/
path_shape_var.rs

1use core::{borrow::Borrow, ops::Index};
2
3use ark_r1cs_std::{
4    alloc::{AllocVar, AllocationMode},
5    boolean::Boolean,
6};
7use ark_relations::r1cs::{Namespace, SynthesisError};
8use ark_std::{vec, vec::Vec};
9#[cfg(feature = "std")]
10use {
11    ark_r1cs_std::R1CSVar,
12    std::fmt::{Display, Formatter},
13};
14
15use crate::environment::CircuitField;
16
17#[derive(Clone, Debug)]
18pub struct PathShapeVar {
19    shape: Vec<Boolean<CircuitField>>,
20}
21
22#[cfg(feature = "std")]
23impl Display for PathShapeVar {
24    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
25        write!(
26            f,
27            "{:?}",
28            self.shape
29                .iter()
30                .map(|b| b.value().map(|boo| if boo { "left" } else { "right" }))
31                .collect::<Vec<_>>()
32        )
33    }
34}
35
36impl PathShapeVar {
37    pub(super) fn len(&self) -> usize {
38        self.shape.len()
39    }
40}
41
42impl Index<usize> for PathShapeVar {
43    type Output = Boolean<CircuitField>;
44
45    fn index(&self, index: usize) -> &Self::Output {
46        &self.shape[index]
47    }
48}
49
50impl AllocVar<(u8, Result<u64, SynthesisError>), CircuitField> for PathShapeVar {
51    fn new_variable<T: Borrow<(u8, Result<u64, SynthesisError>)>>(
52        cs: impl Into<Namespace<CircuitField>>,
53        f: impl FnOnce() -> Result<T, SynthesisError>,
54        mode: AllocationMode,
55    ) -> Result<Self, SynthesisError> {
56        let ns = cs.into();
57        let cs = ns.cs();
58
59        let mut shape = vec![];
60
61        let (path_length, maybe_leaf_index) = *f()?.borrow();
62
63        for i in 0..path_length {
64            shape.push(Boolean::new_variable(
65                cs.clone(),
66                || {
67                    let current_index = maybe_leaf_index? / (1 << i);
68                    Ok(current_index & 1 != 1 || current_index == 1)
69                },
70                mode,
71            )?);
72        }
73
74        Ok(Self { shape })
75    }
76}