Skip to content

Commit

Permalink
fix!: fixed a bug where eq checks for array did not work properly (#283)
Browse files Browse the repository at this point in the history
BREAKING CHANGE: Opcode:Eq now holds the number of elements to compare.
  • Loading branch information
0xThemis authored Nov 27, 2024
1 parent afbb798 commit 3193574
Show file tree
Hide file tree
Showing 12 changed files with 45 additions and 12 deletions.
4 changes: 2 additions & 2 deletions co-circom/circom-mpc-compiler/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,8 +332,8 @@ where
OperatorType::Lesser => self.emit_opcode(MpcOpCode::Lt),
OperatorType::Greater => self.emit_opcode(MpcOpCode::Gt),
OperatorType::Eq(size) => {
assert_ne!(size, 0);
self.emit_opcode(MpcOpCode::Eq);
assert_ne!(size, 0, "size must be > 0");
self.emit_opcode(MpcOpCode::Eq(size));
}
OperatorType::NotEq => self.emit_opcode(MpcOpCode::Neq),
OperatorType::BoolOr => self.emit_opcode(MpcOpCode::BoolOr),
Expand Down
26 changes: 19 additions & 7 deletions co-circom/circom-mpc-vm/src/mpc_vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ impl<F: PrimeField, C: VmCircomWitnessExtension<F>> Component<F, C> {
match inst {
op_codes::MpcOpCode::PushConstant(index) => {
let constant = ctx.constant_table[*index].clone();
tracing::debug!("pushing constant {}", constant);
tracing::trace!("pushing constant {}", constant);
self.push_field(constant);
}
op_codes::MpcOpCode::PushIndex(index) => self.push_index(*index),
Expand All @@ -338,7 +338,7 @@ impl<F: PrimeField, C: VmCircomWitnessExtension<F>> Component<F, C> {
.iter()
.cloned()
.for_each(|signal| {
tracing::debug!("pushing signal {signal}");
tracing::trace!("pushing signal {signal}");
self.push_field(signal);
});
}
Expand Down Expand Up @@ -477,7 +477,7 @@ impl<F: PrimeField, C: VmCircomWitnessExtension<F>> Component<F, C> {
let mut input_signals = vec![C::VmType::default(); *amount];
for i in 0..*amount {
input_signals[*amount - i - 1] = self.pop_field();
tracing::debug!("popping {}", input_signals.last().unwrap());
tracing::trace!("popping {}", input_signals.last().unwrap());
}

let component = &mut self.sub_components[sub_comp_index];
Expand Down Expand Up @@ -602,10 +602,22 @@ impl<F: PrimeField, C: VmCircomWitnessExtension<F>> Component<F, C> {
let lhs = self.pop_field();
self.push_field(protocol.ge(lhs, rhs)?);
}
op_codes::MpcOpCode::Eq => {
let rhs = self.pop_field();
let lhs = self.pop_field();
self.push_field(protocol.eq(lhs, rhs)?);
op_codes::MpcOpCode::Eq(size) => {
let size = *size;
let mut lhs = Vec::with_capacity(size);
let mut rhs = Vec::with_capacity(size);
for _ in 0..size {
rhs.push(self.pop_field());
}
for _ in 0..size {
lhs.push(self.pop_field());
}
let mut result = protocol.public_one();
for (lhs, rhs) in izip!(lhs, rhs) {
let cmp = protocol.eq(lhs, rhs)?;
result = protocol.bool_and(cmp, result)?;
}
self.push_field(result);
}
op_codes::MpcOpCode::Neq => {
let rhs = self.pop_field();
Expand Down
6 changes: 3 additions & 3 deletions co-circom/circom-mpc-vm/src/op_codes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,8 @@ pub enum MpcOpCode {
Gt,
/// Pops two elements from the field stack, compares if the first popped value is greater than or equal to the second, and pushes a boolean result onto the stack.
Ge,
/// Pops two elements from the field stack, compares if the first popped value is equal to the second, and pushes a boolean result onto the stack.
Eq,
/// Pops the provided amount of elements time 2 from the field stack and compares if the first n popped values are equal to the second set, and pushes a boolean result onto the stack.
Eq(usize),
/// Pops two elements from the field stack, compares if the first popped value is not equal to the second, and pushes a boolean result onto the stack.
Neq,
/// Pops two boolean values from the field stack, computes their boolean OR, and pushes the result onto the stack.
Expand Down Expand Up @@ -171,7 +171,7 @@ impl std::fmt::Display for MpcOpCode {
MpcOpCode::Le => "LESS_EQ_OP".to_owned(),
MpcOpCode::Gt => "GREATER_THAN_OP".to_owned(),
MpcOpCode::Ge => "GREATER_EQ_OP".to_owned(),
MpcOpCode::Eq => "IS_EQUAL_OP".to_owned(),
MpcOpCode::Eq(size) => format!("IS_EQUAL_OP {size}"),
MpcOpCode::Neq => "NOT_EQUAL_OP".to_owned(),
MpcOpCode::BoolOr => "BOOL_OR_OP".to_owned(),
MpcOpCode::BoolAnd => "BOOL_AND_OP".to_owned(),
Expand Down
3 changes: 3 additions & 0 deletions test_vectors/WitnessExtension/kats/array_equals/input0.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"in": ["22", "-11", "22", "-11"]
}
3 changes: 3 additions & 0 deletions test_vectors/WitnessExtension/kats/array_equals/input1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"in": ["22", "11", "22", "11"]
}
3 changes: 3 additions & 0 deletions test_vectors/WitnessExtension/kats/array_equals/input2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"in": ["0", "32094032", "0", "32094032"]
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
10 changes: 10 additions & 0 deletions test_vectors/WitnessExtension/tests/array_equals.circom
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
pragma circom 2.0.0;

template Main() {
signal input a[2];
signal input b[2];

a === b;
}

component main = Main();
1 change: 1 addition & 0 deletions tests/tests/circom/witness_extension_tests/plain_vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ pub fn from_test_name(fn_name: &str) -> TestInputs {
}

witness_extension_test_plain!(aliascheck_test);
witness_extension_test_plain!(array_equals);
witness_extension_test_plain!(babyadd_tester);
witness_extension_test_plain!(babycheck_test);
witness_extension_test_plain!(babypbk_test);
Expand Down
1 change: 1 addition & 0 deletions tests/tests/circom/witness_extension_tests/rep3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ macro_rules! witness_extension_test_rep3_ignored {
}

witness_extension_test_rep3!(aliascheck_test);
witness_extension_test_rep3!(array_equals);
witness_extension_test_rep3!(babyadd_tester);
witness_extension_test_rep3!(babycheck_test);
witness_extension_test_rep3!(babypbk_test);
Expand Down

0 comments on commit 3193574

Please sign in to comment.