mirror of
https://github.com/AleoHQ/leo.git
synced 2025-01-03 07:16:50 +03:00
bounds check
This commit is contained in:
parent
dc91b07e5c
commit
e6b7f0fce3
@ -37,6 +37,33 @@ use snarkvm_gadgets::utilities::{
|
||||
use snarkvm_r1cs::ConstraintSystem;
|
||||
|
||||
impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
pub fn array_bounds_check<CS: ConstraintSystem<F>>(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
index_resolved: &Integer,
|
||||
array_len: u32,
|
||||
span: &Span,
|
||||
) -> Result<(), ExpressionError> {
|
||||
let bounds_check = evaluate_lt::<F, G, CS>(
|
||||
cs,
|
||||
ConstrainedValue::Integer(index_resolved.clone()),
|
||||
ConstrainedValue::Integer(Integer::new(
|
||||
&ConstInt::U32(array_len).cast_to(&index_resolved.get_type()),
|
||||
)),
|
||||
span,
|
||||
)?;
|
||||
let bounds_check = match bounds_check {
|
||||
ConstrainedValue::Boolean(b) => b,
|
||||
_ => unimplemented!("illegal non-Integer returned from lt"),
|
||||
};
|
||||
let namespace_string = format!("evaluate array access bounds {}:{}", span.line_start, span.col_start);
|
||||
let mut unique_namespace = cs.ns(|| namespace_string);
|
||||
bounds_check
|
||||
.enforce_equal(&mut unique_namespace, &Boolean::Constant(true))
|
||||
.map_err(|e| ExpressionError::cannot_enforce("array bounds check".to_string(), e, span))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn enforce_array_access<CS: ConstraintSystem<F>>(
|
||||
&mut self,
|
||||
@ -65,21 +92,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
.len()
|
||||
.try_into()
|
||||
.map_err(|_| ExpressionError::array_length_out_of_bounds(span))?;
|
||||
let bounds_check = evaluate_lt::<F, G, CS>(
|
||||
cs,
|
||||
ConstrainedValue::Integer(index_resolved.clone()),
|
||||
ConstrainedValue::Integer(Integer::new(&ConstInt::U32(array_len))),
|
||||
span,
|
||||
)?;
|
||||
let bounds_check = match bounds_check {
|
||||
ConstrainedValue::Boolean(b) => b,
|
||||
_ => unimplemented!("illegal non-Integer returned from lt"),
|
||||
};
|
||||
let namespace_string = format!("evaluate array access bounds {}:{}", span.line_start, span.col_start);
|
||||
let mut unique_namespace = cs.ns(|| namespace_string);
|
||||
bounds_check
|
||||
.enforce_equal(&mut unique_namespace, &Boolean::Constant(true))
|
||||
.map_err(|e| ExpressionError::cannot_enforce("array bounds check".to_string(), e, span))?;
|
||||
self.array_bounds_check(cs, &&index_resolved, array_len, span)?;
|
||||
}
|
||||
|
||||
let mut current_value = array.pop().unwrap();
|
||||
|
@ -25,7 +25,7 @@ use crate::{
|
||||
GroupType,
|
||||
Integer,
|
||||
};
|
||||
use leo_asg::{ConstInt, Expression};
|
||||
use leo_asg::{ConstInt, Expression, Node};
|
||||
|
||||
use snarkvm_fields::PrimeField;
|
||||
use snarkvm_gadgets::utilities::{eq::EvaluateEqGadget, select::CondSelectGadget};
|
||||
@ -65,25 +65,34 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let span = index.span().cloned().unwrap_or_default();
|
||||
{
|
||||
let array_len: u32 = input
|
||||
.len()
|
||||
.try_into()
|
||||
.map_err(|_| ExpressionError::array_length_out_of_bounds(&span))?;
|
||||
self.array_bounds_check(cs, &&index_resolved, array_len, &span)?;
|
||||
}
|
||||
|
||||
for (i, item) in input.iter_mut().enumerate() {
|
||||
let namespace_string = format!(
|
||||
"evaluate dyn array assignment eq {} {}:{}",
|
||||
i, context.span.line_start, context.span.col_start
|
||||
i, span.line_start, span.col_start
|
||||
);
|
||||
let eq_namespace = cs.ns(|| namespace_string);
|
||||
|
||||
let index_bounded = i
|
||||
.try_into()
|
||||
.map_err(|_| ExpressionError::array_index_out_of_legal_bounds(&context.span))?;
|
||||
.map_err(|_| ExpressionError::array_index_out_of_legal_bounds(&span))?;
|
||||
let const_index = ConstInt::U32(index_bounded).cast_to(&index_resolved.get_type());
|
||||
let index_comparison = index_resolved
|
||||
.evaluate_equal(eq_namespace, &Integer::new(&const_index))
|
||||
.map_err(|_| ExpressionError::cannot_evaluate("==".to_string(), &context.span))?;
|
||||
.map_err(|_| ExpressionError::cannot_evaluate("==".to_string(), &span))?;
|
||||
|
||||
let unique_namespace = cs.ns(|| {
|
||||
format!(
|
||||
"select array dyn assignment {} {}:{}",
|
||||
i, context.span.line_start, context.span.col_start
|
||||
i, span.line_start, span.col_start
|
||||
)
|
||||
});
|
||||
let value = ConstrainedValue::conditionally_select(
|
||||
@ -92,7 +101,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> ConstrainedProgram<'a, F, G> {
|
||||
&context.target_value,
|
||||
&item,
|
||||
)
|
||||
.map_err(|e| ExpressionError::cannot_enforce("conditional select".to_string(), e, &context.span))?;
|
||||
.map_err(|e| ExpressionError::cannot_enforce("conditional select".to_string(), e, &span))?;
|
||||
*item = value;
|
||||
}
|
||||
Ok(())
|
||||
|
Loading…
Reference in New Issue
Block a user