Skip to content

Commit b8067f8

Browse files
check intmul doesn't overflow modulo 2^128-1
1 parent 43c8daf commit b8067f8

File tree

3 files changed

+16
-3
lines changed

3 files changed

+16
-3
lines changed

crates/examples/snapshots/ethsign.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ ethsign circuit
22
--
33
Number of gates: 265672
44
Number of evaluation instructions: 311772
5-
Number of AND constraints: 335708
5+
Number of AND constraints: 361166
66
Number of MUL constraints: 25458
77
Length of value vec: 524288
88
Constants: 82

crates/examples/snapshots/zklogin.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ zklogin circuit
22
--
33
Number of gates: 462908
44
Number of evaluation instructions: 550412
5-
Number of AND constraints: 577527
5+
Number of AND constraints: 604407
66
Number of MUL constraints: 26880
77
Length of value vec: 1048576
88
Constants: 710

crates/frontend/src/compiler/gate/imul.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//! Uses the MulConstraint: X * Y = (HI << 64) | LO
33
44
use crate::compiler::{
5-
constraint_builder::ConstraintBuilder,
5+
constraint_builder::{ConstraintBuilder, sll},
66
gate::opcode::OpcodeShape,
77
gate_graph::{Gate, GateData, GateParam, Wire},
88
};
@@ -27,6 +27,19 @@ pub fn constrain(_gate: Gate, data: &GateData, builder: &mut ConstraintBuilder)
2727

2828
// Create MulConstraint: X * Y = (HI << 64) | LO
2929
builder.mul().a(*x).b(*y).hi(*hi).lo(*lo).build();
30+
31+
// To guard against overflow modulo 2^128-1, turns out an additional check
32+
// is required and sufficient:
33+
// x[0] * y[0] = lo[0]
34+
// meaning we're verifying integer multiplication on the least significant bits.
35+
// We extract the least significant bits by moving them to the most significant positions
36+
// and then put them through an AND constraint.
37+
builder
38+
.and()
39+
.a(sll(*x, 63))
40+
.b(sll(*y, 63))
41+
.c(sll(*lo, 63))
42+
.build();
3043
}
3144

3245
pub fn emit_eval_bytecode(

0 commit comments

Comments
 (0)