Skip to content

Commit c7f42c9

Browse files
manishbista28Manish BistaManish Bista
authored
Feat/213 chunked verifier with folded fp12 (BitVM#215)
* init: sync with main branch * chore: reuse constraint synthesizer * fix: g1 hinted msm * fix g2 double line removes coeffs * add assigner and elements trait changing elem trait changing elem trait fix issues with preimage fix issues with preimage wip: cargo fix wip: cargo fix 2 remove comments * feat: undo cargo fix on out of scope files * select assertion to corrupt randomly * feat: undo cargo fix on out of scope files and remove unneeded test * revert changes to winternitz.rs * chunker new line at eof * feat: change wots api to use existing winternitz module * chore: move tapscripts to individual files * chore: move tapscript tests to individual files * doc: add few notes on muls and point ops * chore: add comments * feat: add input validity checks on tapscripts wip: input validity checks added to chunk methods feat: integrate premiller verification checks to next tapscripts feat: integrate msm verification checks to next tapscripts wip: input validity checks during assertion fix(disprove-exec): issue with chunk_precompute_p py zero * feat: cleanup interface to chunker and add more tests init: api utils chore: remove legacy api code feat: update interface to chunker * test(api): add full execution test * chore: sync with main branch * chore: move g16 tests and cleanup chore: replace with braces on script macro chore: move g16 tests to api chore: fix tests chore: adding RUST_MIN_STACK flag to ci * chore: cleanup and reorg methods chore: remove panics add Result chore: cargo lock * chore(bn254_g2): cleanup g2 point ops functions * chore: add comments to data types * fix: handle when input to doubling is inf * feat: remove numerator is zero check * feat: include free subgroup check on last tapscript * fix: remove calculation for s param of proof --------- Co-authored-by: Manish Bista <manishbista@Manishs-MBP.lan> Co-authored-by: Manish Bista <manishbista@Manishs-MacBook-Pro.local>
1 parent ac0ee1a commit c7f42c9

35 files changed

+8735
-54
lines changed

.github/workflows/CI.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ jobs:
6565

6666
- name: Run tests
6767
run: |
68-
cargo test -- --skip bridge::
68+
RUST_MIN_STACK=104857600 cargo test -- --skip bridge::
6969
7070
# test_bridge:
7171
# if: github.event.pull_request.draft == false

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ serde-big-array = "0.5.1"
4848
num-bigint = { version = "0.4.4", features = ["rand"] }
4949
ark-std = { version = "0.4.0", default-features = false, features = ["print-trace"] }
5050
ark-crypto-primitives = { git = "https://github.com/arkworks-rs/crypto-primitives", features = ["snark", "sponge"] }
51-
ark-relations = { git = "https://github.com/arkworks-rs/snark/" }
51+
ark-relations = { version = "0.4.0" }
5252
serial_test = "*"
5353
tqdm = "0.7"
5454
secp256k1 = { version = "0.29.1", features = ["global-context"]}

bitvm/src/bigint/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ pub struct BigIntImpl<const N_BITS: u32, const LIMB_SIZE: u32> {}
1010

1111
impl<const N_BITS: u32, const LIMB_SIZE: u32> BigIntImpl<N_BITS, LIMB_SIZE> {
1212
pub const N_BITS: u32 = N_BITS;
13+
pub const LIMB_SIZE: u32 = LIMB_SIZE;
1314
pub const N_LIMBS: u32 = N_BITS.div_ceil(LIMB_SIZE);
1415
pub const HEAD: u32 = N_BITS - (Self::N_LIMBS - 1) * LIMB_SIZE;
1516
pub const HEAD_OFFSET: u32 = 1u32 << Self::HEAD;

bitvm/src/bn254/fp254impl.rs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,64 @@ pub trait Fp254Impl {
685685

686686
(script, hints)
687687
}
688+
689+
#[allow(clippy::too_many_arguments)]
690+
fn hinted_mul_lc4(
691+
a_depth: u32,
692+
a: ark_bn254::Fq,
693+
b_depth: u32,
694+
b: ark_bn254::Fq,
695+
c_depth: u32,
696+
c: ark_bn254::Fq,
697+
d_depth: u32,
698+
d: ark_bn254::Fq,
699+
700+
e_depth: u32,
701+
e: ark_bn254::Fq,
702+
f_depth: u32,
703+
f: ark_bn254::Fq,
704+
g_depth: u32,
705+
g: ark_bn254::Fq,
706+
h_depth: u32,
707+
h: ark_bn254::Fq,
708+
) -> (Script, Vec<Hint>) {
709+
assert!(a_depth > b_depth && b_depth > c_depth && c_depth > d_depth && d_depth > e_depth && e_depth > f_depth && f_depth > g_depth && g_depth > h_depth);
710+
711+
let mut hints = Vec::new();
712+
713+
let modulus = &Fq::modulus_as_bigint();
714+
715+
let x1 = BigInt::from_str(&a.to_string()).unwrap();
716+
let y1 = BigInt::from_str(&b.to_string()).unwrap();
717+
let z1 = BigInt::from_str(&c.to_string()).unwrap();
718+
let w1 = BigInt::from_str(&d.to_string()).unwrap();
719+
720+
let x2 = BigInt::from_str(&e.to_string()).unwrap();
721+
let y2 = BigInt::from_str(&f.to_string()).unwrap();
722+
let z2 = BigInt::from_str(&g.to_string()).unwrap();
723+
let w2 = BigInt::from_str(&h.to_string()).unwrap();
724+
725+
let q = (x1 * x2 + y1 * y2 + z1 * z2 + w1 * w2) / modulus;
726+
727+
let script = script! {
728+
for _ in 0..Self::N_LIMBS {
729+
OP_DEPTH OP_1SUB OP_ROLL // hints
730+
}
731+
// { fq_push(ark_bn254::Fq::from_str(&q.to_string()).unwrap()) }
732+
{ Fq::roll(a_depth + 1) }
733+
{ Fq::roll(b_depth + 2) }
734+
{ Fq::roll(c_depth + 3) }
735+
{ Fq::roll(d_depth + 4) }
736+
{ Fq::roll(e_depth + 5) }
737+
{ Fq::roll(f_depth + 6) }
738+
{ Fq::roll(g_depth + 7) }
739+
{ Fq::roll(h_depth + 8) }
740+
{ Fq::tmul_lc4() }
741+
};
742+
hints.push(Hint::BigIntegerTmulLC4(q));
743+
744+
(script, hints)
745+
}
688746

689747
#[allow(clippy::too_many_arguments)]
690748
fn hinted_mul_lc2_keep_elements(

bitvm/src/bn254/fq.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ impl Fq {
4747
}
4848
}
4949

50+
pub fn tmul_lc4() -> Script {
51+
script!{
52+
{ <Fq as Fp254Mul4LC>::tmul() }
53+
}
54+
}
55+
5056
pub const fn bigint_tmul_lc_1() -> (u32, u32) {
5157
const X: u32 = <Fq as Fp254Mul>::T::N_BITS;
5258
const Y: u32 = <Fq as Fp254Mul>::LIMB_SIZE;
@@ -58,6 +64,12 @@ impl Fq {
5864
const Y: u32 = <Fq as Fp254Mul2LC>::LIMB_SIZE;
5965
(X, Y)
6066
}
67+
68+
pub const fn bigint_tmul_lc_4() -> (u32, u32) {
69+
const X: u32 = <Fq as Fp254Mul4LC>::T::N_BITS;
70+
const Y: u32 = <Fq as Fp254Mul4LC>::LIMB_SIZE;
71+
(X, Y)
72+
}
6173

6274
#[inline]
6375
pub fn push(a: ark_bn254::Fq) -> Script {
@@ -396,6 +408,7 @@ macro_rules! fp_lc_mul {
396408

397409
fp_lc_mul!(Mul, 4, 4, [true]);
398410
fp_lc_mul!(Mul2LC, 3, 3, [true, true]);
411+
fp_lc_mul!(Mul4LC, 3, 3, [true, true, true, true]);
399412

400413
#[cfg(test)]
401414
mod test {

bitvm/src/bn254/fq2.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,50 @@ impl Fq2 {
217217
(script, hints)
218218
}
219219

220+
pub fn hinted_mul_lc4_keep_elements(
221+
a: ark_bn254::Fq2, b:ark_bn254::Fq2, c:ark_bn254::Fq2, d:ark_bn254::Fq2
222+
) -> (Script, Vec<Hint>) {
223+
224+
let mut hints = Vec::new();
225+
226+
let (hinted_script1, hint1) = Fq::hinted_mul_lc4(7, a.c0, 6, -a.c1, 5, c.c0, 4, -c.c1, 3, b.c0, 2, b.c1, 1, d.c0, 0, d.c1);
227+
let (hinted_script2, hint2) = Fq::hinted_mul_lc4(7, a.c0, 6, a.c1, 5, c.c0, 4, c.c1, 3, b.c1, 2, b.c0, 1, d.c1, 0, d.c0);
228+
229+
let script = script! {
230+
// [a, b, c, d]
231+
{Fq2::copy(6)}
232+
{Fq::neg(0)}
233+
// [a, b, c, d, -a]
234+
{Fq2::copy(4)}
235+
{Fq::neg(0)}
236+
// [a, b, c, d, -a, -c]
237+
{Fq2::copy(8)}
238+
// [a, b, c, d, -a, -c, b]
239+
{Fq2::copy(6)}
240+
// [a, b, c, d, -a, -c, b, d]
241+
{hinted_script1}
242+
{Fq::toaltstack()}
243+
// [a, b, c, d]
244+
{Fq2::copy(6)} {Fq2::copy(6)} {Fq2::copy(6)} {Fq2::copy(6)}
245+
// [a, b, c, d, a, b, c, d]
246+
{Fq2::toaltstack()} {Fq2::roll(2)}
247+
// [a, c, b, d]
248+
{Fq::roll(1)}
249+
{Fq2::fromaltstack()}
250+
{Fq::roll(1)}
251+
// [a, c, b', d']
252+
{hinted_script2}
253+
{Fq::fromaltstack()}
254+
{Fq::roll(1)}
255+
};
256+
257+
hints.extend(hint1);
258+
hints.extend(hint2);
259+
260+
(script, hints)
261+
}
262+
263+
220264
/// Square the top Fq2 element
221265
pub fn hinted_square(a: ark_bn254::Fq2) -> (Script, Vec<Hint>) {
222266
let mut hints = Vec::new();

bitvm/src/bn254/fq6.rs

Lines changed: 119 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
use crate::bn254::fp254impl::Fp254Impl;
22
use crate::bn254::fq::Fq;
3+
use crate::bn254::fq12::Fq12;
34
use crate::bn254::fq2::Fq2;
45
use crate::treepp::{script, Script};
56
use crate::bn254::utils::Hint;
6-
use ark_ff::{Field, Fp6Config};
7+
use ark_ff::{AdditiveGroup, Field, Fp6Config};
78
use num_bigint::BigUint;
89

910
pub struct Fq6;
@@ -41,6 +42,22 @@ impl Fq6 {
4142
}
4243
}
4344

45+
pub fn is_zero() -> Script {
46+
script! (
47+
for _ in 0..6 {
48+
{Fq::push(ark_bn254::Fq::ZERO)}
49+
{Fq::equal(1, 0)}
50+
OP_TOALTSTACK
51+
}
52+
{1}
53+
for _ in 0..6 {
54+
OP_FROMALTSTACK
55+
OP_BOOLAND
56+
}
57+
)
58+
// Fq6::ZERO -> {1} else {0}
59+
}
60+
4461
pub fn fromaltstack() -> Script {
4562
script! {
4663
{ Fq2::fromaltstack() }
@@ -131,7 +148,105 @@ impl Fq6 {
131148
}
132149
}
133150

134-
pub fn hinted_mul(mut a_depth: u32, mut a: ark_bn254::Fq6, mut b_depth: u32, mut b: ark_bn254::Fq6) -> (Script, Vec<Hint>) {
151+
pub fn hinted_square(a: ark_bn254::Fq6) -> (Script, Vec<Hint>) {
152+
let mut hints = Vec::new();
153+
154+
let (hinted_script1, hints1) = Fq2::hinted_square(a.c0);
155+
let (hinted_script2, hints2) = Fq2::hinted_square(a.c0 + a.c1 + a.c2);
156+
let (hinted_script3, hints3) = Fq2::hinted_square(a.c0 - a.c1 + a.c2);
157+
let (hinted_script4, hints4) = Fq2::hinted_mul(2, a.c1,0, a.c2);
158+
let (hinted_script5, hints5) = Fq2::hinted_square(a.c2);
159+
160+
let mut script = script! {};
161+
let script_lines = [
162+
// compute s_0 = a_0 ^ 2
163+
Fq2::copy(4),
164+
hinted_script1,
165+
166+
// compute a_0 + a_2
167+
Fq2::roll(6),
168+
Fq2::copy(4),
169+
Fq2::add(2, 0),
170+
171+
// compute s_1 = (a_0 + a_1 + a_2) ^ 2
172+
Fq2::copy(0),
173+
Fq2::copy(8),
174+
Fq2::add(2, 0),
175+
hinted_script2,
176+
177+
// compute s_2 = (a_0 - a_1 + a_2) ^ 2
178+
Fq2::copy(8),
179+
Fq2::sub(4, 0),
180+
hinted_script3,
181+
182+
// compute s_3 = 2a_1a_2
183+
Fq2::roll(8),
184+
Fq2::copy(8),
185+
hinted_script4,
186+
Fq2::double(0),
187+
188+
// compute s_4 = a_2 ^ 2
189+
Fq2::roll(8),
190+
hinted_script5,
191+
192+
// compute t_1 = (s_1 + s_2) / 2
193+
Fq2::copy(6),
194+
Fq2::roll(6),
195+
Fq2::add(2, 0),
196+
Fq2::div2(),
197+
198+
// at this point, we have s_0, s_1, s_3, s_4, t_1
199+
200+
// compute c_0 = s_0 + \beta s_3
201+
Fq2::copy(4),
202+
Fq6::mul_fq2_by_nonresidue(),
203+
Fq2::copy(10),
204+
Fq2::add(2, 0),
205+
206+
// compute c_1 = s_1 - s_3 - t_1 + \beta s_4
207+
Fq2::copy(4),
208+
Fq6::mul_fq2_by_nonresidue(),
209+
Fq2::copy(4),
210+
Fq2::add(10, 0),
211+
Fq2::sub(10, 0),
212+
Fq2::add(2, 0),
213+
214+
// compute c_2 = t_1 - s_0 - s_4
215+
Fq2::add(8, 6),
216+
Fq2::sub(6, 0),
217+
];
218+
for script_line in script_lines {
219+
script = script.push_script(script_line.compile());
220+
}
221+
222+
hints.extend(hints1);
223+
hints.extend(hints2);
224+
hints.extend(hints3);
225+
hints.extend(hints4);
226+
hints.extend(hints5);
227+
228+
(script, hints)
229+
}
230+
231+
// Input: [A, B]
232+
// Output: [C] where C = A x B
233+
pub fn hinted_mul(a_depth: u32, a: ark_bn254::Fq6, b_depth: u32, b: ark_bn254::Fq6) -> (Script, Vec<Hint>) {
234+
Self::hinted_mul_core(a_depth, a, b_depth, b, script!{})
235+
}
236+
237+
// Input: [A, B]
238+
// Output: [A, B, C] where C = A x B
239+
pub fn hinted_mul_keep_elements(a_depth: u32, a: ark_bn254::Fq6, b_depth: u32, b: ark_bn254::Fq6) -> (Script, Vec<Hint>) {
240+
let preserve_scr = script!{
241+
{Fq6::toaltstack()}
242+
{Fq12::copy(0)}
243+
{Fq6::fromaltstack()}
244+
};
245+
246+
Self::hinted_mul_core(a_depth, a, b_depth, b, preserve_scr)
247+
}
248+
249+
fn hinted_mul_core(mut a_depth: u32, mut a: ark_bn254::Fq6, mut b_depth: u32, mut b: ark_bn254::Fq6, keep_elements_scr: Script) -> (Script, Vec<Hint>) {
135250
// The degree-6 extension on BN254 Fq2 is under the polynomial y^3 - x - 9
136251
// Toom-Cook-3 from https://eprint.iacr.org/2006/471.pdf
137252
if a_depth < b_depth {
@@ -184,6 +299,8 @@ impl Fq6 {
184299
// compute (a-b+c)(d-e+f) = P(-1)
185300
{ hinted_script3 }
186301

302+
{ keep_elements_scr }
303+
187304
// compute 2b
188305
{ Fq2::roll(a_depth + 8) }
189306
{ Fq2::double(0) }

0 commit comments

Comments
 (0)