From 02157f615d00691be53671ca52636aafdb029f33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=9Eevket=20Onur=20YILMAZ?= Date: Thu, 16 Jan 2025 19:55:21 +0300 Subject: [PATCH] Fix failing tests (#196) * fix test_hinted_quad_miller * fixed generate_f * fix stable_script in chunk_scalar_mul by changing names to run1 and run2 * use script macro in pairing * use script macro in fq12 * use script macro in fq6 * use script macro in fq2, verifier, chunk_evaluate_lines * uncomment message in winternitz test * remove unused hint variables, remove P_POW3, add new constants --------- Co-authored-by: Hakkush-07 Co-authored-by: just-erray --- bitvm/src/bn254/fq12.rs | 139 ++-- bitvm/src/bn254/fq2.rs | 56 +- bitvm/src/bn254/fq6.rs | 388 +++++------ bitvm/src/bn254/pairing.rs | 651 +++++++++--------- bitvm/src/chunker/chunk_evaluate_line.rs | 86 ++- bitvm/src/chunker/chunk_groth16_verifier.rs | 15 - bitvm/src/chunker/chunk_hinted_accumulator.rs | 21 +- bitvm/src/chunker/chunk_scalar_mul.rs | 8 +- bitvm/src/groth16/constants.rs | 45 +- bitvm/src/groth16/offchain_checker.rs | 66 +- bitvm/src/groth16/verifier.rs | 83 +-- bitvm/src/signatures/winternitz.rs | 8 +- 12 files changed, 716 insertions(+), 850 deletions(-) diff --git a/bitvm/src/bn254/fq12.rs b/bitvm/src/bn254/fq12.rs index b47f00c5d..96bcc3a10 100644 --- a/bitvm/src/bn254/fq12.rs +++ b/bitvm/src/bn254/fq12.rs @@ -90,27 +90,23 @@ impl Fq12 { let (hinted_script2, hint2) = Fq6::hinted_mul(6, a.c1, 0, b.c1); let (hinted_script3, hint3) = Fq6::hinted_mul(6, a.c0 + a.c1, 0, b.c0 + b.c1); - let mut script = script! {}; - let script_lines = [ - Fq6::copy(a_depth + 6), - Fq6::copy(b_depth + 12), - hinted_script1, - Fq6::copy(a_depth + 6), - Fq6::copy(b_depth + 12), - hinted_script2, - Fq6::add(a_depth + 12, a_depth + 18), - Fq6::add(b_depth + 18, b_depth + 24), - hinted_script3, - Fq6::copy(12), - Fq6::copy(12), - Fq12::mul_fq6_by_nonresidue(), - Fq6::add(6, 0), - Fq6::add(18, 12), - Fq6::sub(12, 0), - ]; - for script_line in script_lines { - script = script.push_script(script_line.compile()); - } + let script = script! { + { Fq6::copy(a_depth + 6) } + { Fq6::copy(b_depth + 12) } + { hinted_script1 } + { Fq6::copy(a_depth + 6) } + { Fq6::copy(b_depth + 12) } + { hinted_script2 } + { Fq6::add(a_depth + 12, a_depth + 18) } + { Fq6::add(b_depth + 18, b_depth + 24) } + { hinted_script3 } + { Fq6::copy(12) } + { Fq6::copy(12) } + { Fq12::mul_fq6_by_nonresidue() } + { Fq6::add(6, 0) } + { Fq6::add(18, 12) } + { Fq6::sub(12, 0) } + }; hints.extend(hint1); hints.extend(hint2); @@ -135,59 +131,54 @@ impl Fq12 { let (hinted_script2, hint2) = Fq6::hinted_mul_by_01(p.c0 + p.c1, c3 + ark_bn254::Fq2::ONE, c4); - let mut script = script! {}; - - let script_lines = [ + let script = script! { // copy p.c1, c3, c4 - Fq6::copy(4), - Fq2::copy(8), - Fq2::copy(8), + { Fq6::copy(4) } + { Fq2::copy(8) } + { Fq2::copy(8) } // [p, c3, c4, p.c1, c3, c4] // compute b = p.c1 * (c3, c4) - hinted_script1, + { hinted_script1 } // [p, c3, c4, b] // a = p.c0 * c0, where c0 = 1 - Fq6::copy(16), + { Fq6::copy(16) } // [p, c3, c4, b, a] // compute beta * b - Fq6::copy(6), - Fq12::mul_fq6_by_nonresidue(), + { Fq6::copy(6) } + { Fq12::mul_fq6_by_nonresidue() } // [p, c3, c4, b, a, beta * b] // compute final c0 = a + beta * b - Fq6::copy(6), - Fq6::add(6, 0), + { Fq6::copy(6) } + { Fq6::add(6, 0) } // [p, c3, c4, b, a, c0] // compute e = p.c0 + p.c1 - Fq6::add(28, 22), + { Fq6::add(28, 22) } // [c3, c4, b, a, c0, e] // compute c0 + c3, where c0 = 1 - Fq2::roll(26), - Fq2::push_one(), - Fq2::add(2, 0), + { Fq2::roll(26) } + { Fq2::push_one() } + { Fq2::add(2, 0) } // [c4, b, a, c0, e, 1 + c3] // update e = e * (c0 + c3, c4), where c0 = 1 - Fq2::roll(26), - hinted_script2, + { Fq2::roll(26) } + { hinted_script2 } // [b, a, c0, e] // sum a and b - Fq6::add(18, 12), + { Fq6::add(18, 12) } // [c0, e, a + b] // compute final c1 = e - (a + b) - Fq6::sub(6, 0), - ]; + { Fq6::sub(6, 0) } + }; - for script_line in script_lines { - script = script.push_script(script_line.compile()); - } hints.extend(hint1); hints.extend(hint2); @@ -216,35 +207,29 @@ impl Fq12 { ark_bn254::Fq12Config::mul_fp6_by_nonresidue_in_place(&mut beta_ac1); let (hinted_script2, hints2) = Fq6::hinted_mul(12, a.c0 + a.c1, 6, a.c0 + beta_ac1); - let mut script = script! {}; - - let script_lines = [ + let script = script! { // v0 = c0 + c1 - Fq6::copy(6), - Fq6::copy(6), - Fq6::add(6, 0), + { Fq6::copy(6) } + { Fq6::copy(6) } + { Fq6::add(6, 0) } // v3 = c0 + beta * c1 - Fq6::copy(6), - Fq12::mul_fq6_by_nonresidue(), - Fq6::copy(18), - Fq6::add(0, 6), + { Fq6::copy(6) } + { Fq12::mul_fq6_by_nonresidue() } + { Fq6::copy(18) } + { Fq6::add(0, 6) } // v2 = c0 * c1 - hinted_script1, + { hinted_script1 } // v0 = v0 * v3 - hinted_script2, + { hinted_script2 } // final c0 = v0 - (beta + 1) * v2 - Fq6::copy(6), - Fq12::mul_fq6_by_nonresidue(), - Fq6::copy(12), - Fq6::add(6, 0), - Fq6::sub(6, 0), + { Fq6::copy(6) } + { Fq12::mul_fq6_by_nonresidue() } + { Fq6::copy(12) } + { Fq6::add(6, 0) } + { Fq6::sub(6, 0) } // final c1 = 2 * v2 - Fq6::double(6), - ]; - - for script_line in script_lines { - script = script.push_script(script_line.compile()); - } + { Fq6::double(6) } + }; hints.extend(hints1); hints.extend(hints2); @@ -349,17 +334,13 @@ impl Fq12 { [i % ark_bn254::Fq12Config::FROBENIUS_COEFF_FP12_C1.len()], ); - let mut script = script! {}; - let script_lines = [ - Fq6::roll(6), - hinted_script1, - Fq6::roll(6), - hinted_script2, - hinted_script3, - ]; - for script_line in script_lines { - script = script.push_script(script_line.compile()); - } + let script = script! { + { Fq6::roll(6) } + { hinted_script1 } + { Fq6::roll(6) } + { hinted_script2 } + { hinted_script3 } + }; hints.extend(hint1); hints.extend(hint2); diff --git a/bitvm/src/bn254/fq2.rs b/bitvm/src/bn254/fq2.rs index 22da07373..00f68e787 100644 --- a/bitvm/src/bn254/fq2.rs +++ b/bitvm/src/bn254/fq2.rs @@ -46,27 +46,23 @@ impl Fq2 { let (hinted_script1, hint1) = Fq::hinted_mul_keep_element(1, a.c0, 0, a.c1); let (hinted_script2, hint2) = Fq::hinted_mul(1, a.c0 - a.c1, 0, a.c0 + a.c1); - let mut script = script! {}; - let script_lines = [ + let script = script! { // a0, a1 - Fq::copy(1), - Fq::copy(1), + { Fq::copy(1) } + { Fq::copy(1) } // a0, a1, a0, a1 - hinted_script1, + { hinted_script1 } // a0, a1, a0, a1, a0*a1 - Fq::double(0), + { Fq::double(0) } // a0, a1, a0, a1, 2*a0*a1 - Fq::sub(2, 1), - Fq::add(3, 2), + { Fq::sub(2, 1) } + { Fq::add(3, 2) } // 2*a0*a1, a0-a1, a0+a1 - hinted_script2, + { hinted_script2 } // 2*a0*a1, a0^2-a1^2 - Fq::roll(1), + { Fq::roll(1) } // a0^2-a1^2, 2*a0*a1 - ]; - for script_line in script_lines { - script = script.push_script(script_line.compile()); - } + }; hints.extend(hint1); hints.extend(hint2); @@ -267,24 +263,20 @@ impl Fq2 { let (hinted_script2, hint2) = Fq::hinted_mul_by_constant(a.c1, &constant.c1); let (hinted_script3, hint3) = Fq::hinted_mul_by_constant(a.c0+a.c1, &(constant.c0+constant.c1)); - let mut script = script! {}; - let script_lines = [ - Fq::copy(1), - hinted_script1, - Fq::copy(1), - hinted_script2, - Fq::add(3, 2), - hinted_script3, - Fq::copy(2), - Fq::copy(2), - Fq::add(1, 0), - Fq::sub(1, 0), - Fq::sub(2, 1), - Fq::roll(1), - ]; - for script_line in script_lines { - script = script.push_script(script_line.compile()); - } + let script = script! { + { Fq::copy(1) } + { hinted_script1 } + { Fq::copy(1) } + { hinted_script2 } + { Fq::add(3, 2) } + { hinted_script3 } + { Fq::copy(2) } + { Fq::copy(2) } + { Fq::add(1, 0) } + { Fq::sub(1, 0) } + { Fq::sub(2, 1) } + { Fq::roll(1) } + }; hints.extend(hint1); hints.extend(hint2); diff --git a/bitvm/src/bn254/fq6.rs b/bitvm/src/bn254/fq6.rs index 2e1fd1f5c..a938ac60f 100644 --- a/bitvm/src/bn254/fq6.rs +++ b/bitvm/src/bn254/fq6.rs @@ -75,24 +75,17 @@ impl Fq6 { let (hinted_script2, hint2) = Fq2::hinted_mul_by_constant(a.c1, constant); let (hinted_script3, hint3) = Fq2::hinted_mul_by_constant(a.c2, constant); - let mut script = script! {}; - let script_lines = [ + let script = script! { // compute p.c0 * c0 - Fq2::roll(4), - hinted_script1, - + { Fq2::roll(4) } + { hinted_script1 } // compute p.c1 * c1 - Fq2::roll(4), - hinted_script2, - + { Fq2::roll(4) } + { hinted_script2 } // compute p.c2 * c2 - Fq2::roll(4), - hinted_script3, - ]; - for script_line in script_lines { - script = script.push_script(script_line.compile()); - } - + { Fq2::roll(4) } + { hinted_script3 } + }; hints.extend(hint1); hints.extend(hint2); hints.extend(hint3); @@ -133,153 +126,147 @@ impl Fq6 { 0, b.c0+b.c1+b.c1+b.c2+b.c2+b.c2+b.c2); let (hinted_script5, hint5) = Fq2::hinted_mul(2, a.c2, 0, b.c2); - let mut script = script! {}; - let script_lines = [ + let script = script! { // compute ad = P(0) - Fq2::copy(a_depth + 4), - Fq2::copy(b_depth + 6), - hinted_script1, + { Fq2::copy(a_depth + 4) } + { Fq2::copy(b_depth + 6) } + { hinted_script1 } // compute a+c - Fq2::copy(a_depth + 6), - Fq2::copy(a_depth + 4), - Fq2::add(2, 0), + { Fq2::copy(a_depth + 6) } + { Fq2::copy(a_depth + 4) } + { Fq2::add(2, 0) } // compute a+b+c, a-b+c - Fq2::copy(0), - Fq2::copy(a_depth + 8), - Fq2::copy(0), - Fq2::add(4, 0), - Fq2::sub(4, 2), + { Fq2::copy(0) } + { Fq2::copy(a_depth + 8) } + { Fq2::copy(0) } + { Fq2::add(4, 0) } + { Fq2::sub(4, 2) } // compute d+f - Fq2::copy(b_depth + 10), - Fq2::copy(b_depth + 8), - Fq2::add(2, 0), + { Fq2::copy(b_depth + 10) } + { Fq2::copy(b_depth + 8) } + { Fq2::add(2, 0) } // compute d+e+f, d-e+f - Fq2::copy(0), - Fq2::copy(b_depth + 12), - Fq2::copy(0), - Fq2::add(4, 0), - Fq2::sub(4, 2), + { Fq2::copy(0) } + { Fq2::copy(b_depth + 12) } + { Fq2::copy(0) } + { Fq2::add(4, 0) } + { Fq2::sub(4, 2) } // compute (a+b+c)(d+e+f) = P(1) - hinted_script2, + { hinted_script2 } // compute (a-b+c)(d-e+f) = P(-1) - hinted_script3, + { hinted_script3 } // compute 2b - Fq2::roll(a_depth + 8), - Fq2::double(0), + { Fq2::roll(a_depth + 8) } + { Fq2::double(0) } // compute 4c - Fq2::copy(a_depth + 8), - Fq2::double(0), - Fq2::double(0), - + { Fq2::copy(a_depth + 8) } + { Fq2::double(0) } + { Fq2::double(0) } // compute a+2b+4c - Fq2::add(2, 0), - Fq2::roll(a_depth + 10), - Fq2::add(2, 0), + { Fq2::add(2, 0) } + { Fq2::roll(a_depth + 10) } + { Fq2::add(2, 0) } // compute 2e - Fq2::roll(b_depth + 10), - Fq2::double(0), + { Fq2::roll(b_depth + 10) } + { Fq2::double(0) } // compute 4f - Fq2::copy(b_depth + 10), - Fq2::double(0), - Fq2::double(0), + { Fq2::copy(b_depth + 10) } + { Fq2::double(0) } + { Fq2::double(0) } // compute d+2e+4f - Fq2::add(2, 0), - Fq2::roll(b_depth + 12), - Fq2::add(2, 0), + { Fq2::add(2, 0) } + { Fq2::roll(b_depth + 12) } + { Fq2::add(2, 0) } // compute (a+2b+4c)(d+2e+4f) = P(2) - hinted_script4, + { hinted_script4 } // compute cf = P(inf) - Fq2::roll(a_depth + 4), - Fq2::roll(b_depth + 10), - hinted_script5, + { Fq2::roll(a_depth + 4) } + { Fq2::roll(b_depth + 10) } + { hinted_script5 } // // at this point, we have v_0, v_1, v_2, v_3, v_4 // compute 3v_0 - Fq2::triple(8), + { Fq2::triple(8) } // compute 3v_1 - Fq2::triple(8), + { Fq2::triple(8) } // compute 6v_4 - Fq2::triple(4), - Fq2::double(0), + { Fq2::triple(4) } + { Fq2::double(0) } // compute x = 3v_0 - 3v_1 - v_2 + v_3 - 12v_4 - Fq2::copy(4), - Fq2::copy(4), - Fq2::sub(2, 0), - Fq2::copy(10), - Fq2::sub(2, 0), - Fq2::copy(8), - Fq2::add(2, 0), - Fq2::copy(2), - Fq2::double(0), - Fq2::sub(2, 0), + { Fq2::copy(4) } + { Fq2::copy(4) } + { Fq2::sub(2, 0) } + { Fq2::copy(10) } + { Fq2::sub(2, 0) } + { Fq2::copy(8) } + { Fq2::add(2, 0) } + { Fq2::copy(2) } + { Fq2::double(0) } + { Fq2::sub(2, 0) } // compute c_0 = 6v_0 + \beta x - Fq6::mul_fq2_by_nonresidue(), - Fq2::copy(6), - Fq2::double(0), - Fq2::add(2, 0), + { Fq6::mul_fq2_by_nonresidue() } + { Fq2::copy(6) } + { Fq2::double(0) } + { Fq2::add(2, 0) } // compute y = -3v_0 + 6v_1 - 2v_2 - v_3 + 12v_4 - Fq2::copy(4), - Fq2::double(0), - Fq2::copy(8), - Fq2::sub(2, 0), - Fq2::copy(12), - Fq2::double(0), - Fq2::sub(2, 0), - Fq2::roll(10), - Fq2::sub(2, 0), - Fq2::copy(4), - Fq2::double(0), - Fq2::add(2, 0), + { Fq2::copy(4) } + { Fq2::double(0) } + { Fq2::copy(8) } + { Fq2::sub(2, 0) } + { Fq2::copy(12) } + { Fq2::double(0) } + { Fq2::sub(2, 0) } + { Fq2::roll(10) } + { Fq2::sub(2, 0) } + { Fq2::copy(4) } + { Fq2::double(0) } + { Fq2::add(2, 0) } // compute c_1 = y + \beta 6v_4 - Fq2::copy(4), - Fq6::mul_fq2_by_nonresidue(), - Fq2::add(2, 0), + { Fq2::copy(4) } + { Fq6::mul_fq2_by_nonresidue() } + { Fq2::add(2, 0) } // compute c_2 = 3v_1 - 6v_0 + 3v_2 - 6v_4 - Fq2::roll(6), - Fq2::roll(8), - Fq2::double(0), - Fq2::sub(2, 0), - Fq2::roll(8), - Fq2::triple(0), - Fq2::add(2, 0), - Fq2::sub(0, 6), + { Fq2::roll(6) } + { Fq2::roll(8) } + { Fq2::double(0) } + { Fq2::sub(2, 0) } + { Fq2::roll(8) } + { Fq2::triple(0) } + { Fq2::add(2, 0) } + { Fq2::sub(0, 6) } // divide by 6 - Fq2::roll(4), - Fq2::div2(), - Fq2::div3(), - Fq2::roll(4), - Fq2::div2(), - Fq2::div3(), - Fq2::roll(4), - Fq2::div2(), - Fq2::div3(), - ]; - for script_line in script_lines { - script = script.push_script(script_line.compile()); - } - + { Fq2::roll(4) } + { Fq2::div2() } + { Fq2::div3() } + { Fq2::roll(4) } + { Fq2::div2() } + { Fq2::div3() } + { Fq2::roll(4) } + { Fq2::div2() } + { Fq2::div3() } + }; hints.extend(hint1); hints.extend(hint2); hints.extend(hint3); @@ -304,75 +291,70 @@ impl Fq6 { let (hinted_script4, hint4) = Fq2::hinted_mul(2, p.c0+p.c1, 0, c0+c1); let (hinted_script5, hint5) = Fq2::hinted_mul(10, c0, 0, p.c0+p.c2); - let mut script = script! {}; - let script_lines = [ + let script = script! { // compute a_a = p.c0 * c0 - Fq2::copy(8), - Fq2::copy(4), - hinted_script1, + { Fq2::copy(8) } + { Fq2::copy(4) } + { hinted_script1 } // compute b_b = p.c1 * c1 - Fq2::copy(8), - Fq2::copy(4), - hinted_script2, + { Fq2::copy(8) } + { Fq2::copy(4) } + { hinted_script2 } // compute tmp = p.c1 + p.c2 - Fq2::copy(10), - Fq2::copy(10), - Fq2::add(2, 0), + { Fq2::copy(10) } + { Fq2::copy(10) } + { Fq2::add(2, 0) } // t1 = c1 * tmp - Fq2::copy(6), - hinted_script3, + { Fq2::copy(6) } + { hinted_script3 } // t1 = t1 - b_b - Fq2::copy(2), - Fq2::sub(2, 0), + { Fq2::copy(2) } + { Fq2::sub(2, 0) } // t1 = t1 * nonresidue - Fq6::mul_fq2_by_nonresidue(), + { Fq6::mul_fq2_by_nonresidue() } // t1 = t1 + a_a - Fq2::copy(4), - Fq2::add(2, 0), + { Fq2::copy(4) } + { Fq2::add(2, 0) } // compute tmp = p.c0 + p.c1 - Fq2::copy(14), - Fq2::roll(14), - Fq2::add(2, 0), + { Fq2::copy(14) } + { Fq2::roll(14) } + { Fq2::add(2, 0) } // t2 = c0 + c1 - Fq2::copy(10), - Fq2::roll(10), - Fq2::add(2, 0), + { Fq2::copy(10) } + { Fq2::roll(10) } + { Fq2::add(2, 0) } // t2 = t2 * tmp - hinted_script4, + { hinted_script4 } // t2 = t2 - a_a - Fq2::copy(6), - Fq2::sub(2, 0), + { Fq2::copy(6) } + { Fq2::sub(2, 0) } // t2 = t2 - b_b - Fq2::copy(4), - Fq2::sub(2, 0), + { Fq2::copy(4) } + { Fq2::sub(2, 0) } // compute tmp = p.c0 + p.c2 - Fq2::add(12, 10), + { Fq2::add(12, 10) } // t3 = c0 * tmp - hinted_script5, + { hinted_script5 } // t3 = t3 - a_a - Fq2::sub(0, 8), + { Fq2::sub(0, 8) } // t3 = t3 + b_b - Fq2::add(0, 6), - ]; - for script_line in script_lines { - script = script.push_script(script_line.compile()); - } - + { Fq2::add(0, 6) } + }; hints.extend(hint1); hints.extend(hint2); hints.extend(hint3); @@ -394,68 +376,63 @@ impl Fq6 { let (hinted_script4, hints4) = Fq2::hinted_mul(2, a.c1,0, a.c2); let (hinted_script5, hints5) = Fq2::hinted_square(a.c2); - let mut script = script! {}; - let script_lines = [ + let script = script! { // compute s_0 = a_0 ^ 2 - Fq2::copy(4), - hinted_script1, + { Fq2::copy(4) } + { hinted_script1 } // compute a_0 + a_2 - Fq2::roll(6), - Fq2::copy(4), - Fq2::add(2, 0), + { Fq2::roll(6) } + { Fq2::copy(4) } + { Fq2::add(2, 0) } // compute s_1 = (a_0 + a_1 + a_2) ^ 2 - Fq2::copy(0), - Fq2::copy(8), - Fq2::add(2, 0), - hinted_script2, + { Fq2::copy(0) } + { Fq2::copy(8) } + { Fq2::add(2, 0) } + { hinted_script2 } // compute s_2 = (a_0 - a_1 + a_2) ^ 2 - Fq2::copy(8), - Fq2::sub(4, 0), - hinted_script3, + { Fq2::copy(8) } + { Fq2::sub(4, 0) } + { hinted_script3 } // compute s_3 = 2a_1a_2 - Fq2::roll(8), - Fq2::copy(8), - hinted_script4, - Fq2::double(0), + { Fq2::roll(8) } + { Fq2::copy(8) } + { hinted_script4 } + { Fq2::double(0) } // compute s_4 = a_2 ^ 2 - Fq2::roll(8), - hinted_script5, + { Fq2::roll(8) } + { hinted_script5 } // compute t_1 = (s_1 + s_2) / 2 - Fq2::copy(6), - Fq2::roll(6), - Fq2::add(2, 0), - Fq2::div2(), + { Fq2::copy(6) } + { Fq2::roll(6) } + { Fq2::add(2, 0) } + { Fq2::div2() } // at this point, we have s_0, s_1, s_3, s_4, t_1 // compute c_0 = s_0 + \beta s_3 - Fq2::copy(4), - Fq6::mul_fq2_by_nonresidue(), - Fq2::copy(10), - Fq2::add(2, 0), + { Fq2::copy(4) } + { Fq6::mul_fq2_by_nonresidue() } + { Fq2::copy(10) } + { Fq2::add(2, 0) } // compute c_1 = s_1 - s_3 - t_1 + \beta s_4 - Fq2::copy(4), - Fq6::mul_fq2_by_nonresidue(), - Fq2::copy(4), - Fq2::add(10, 0), - Fq2::sub(10, 0), - Fq2::add(2, 0), + { Fq2::copy(4) } + { Fq6::mul_fq2_by_nonresidue() } + { Fq2::copy(4) } + { Fq2::add(10, 0) } + { Fq2::sub(10, 0) } + { Fq2::add(2, 0) } // compute c_2 = t_1 - s_0 - s_4 - Fq2::add(8, 6), - Fq2::sub(6, 0), - ]; - for script_line in script_lines { - script = script.push_script(script_line.compile()); - } - + { Fq2::add(8, 6) } + { Fq2::sub(6, 0) } + }; hints.extend(hints1); hints.extend(hints2); hints.extend(hints3); @@ -662,21 +639,16 @@ impl Fq6 { let (hinted_script4, hint4) = Fq2::hinted_frobenius_map(i, a.c2); let (hinted_script5, hint5) = Fq2::hinted_mul_by_constant(a.c2.frobenius_map(i), &ark_bn254::Fq6Config::FROBENIUS_COEFF_FP6_C2[i % ark_bn254::Fq6Config::FROBENIUS_COEFF_FP6_C2.len()]); - let mut script = script! {}; - let script_lines = [ - Fq2::roll(4), - hinted_script1, - Fq2::roll(4), - hinted_script2, - hinted_script3, - Fq2::roll(4), - hinted_script4, - hinted_script5, - ]; - for script_line in script_lines { - script = script.push_script(script_line.compile()); - } - + let script = script! { + { Fq2::roll(4) } + { hinted_script1 } + { Fq2::roll(4) } + { hinted_script2 } + { hinted_script3 } + { Fq2::roll(4) } + { hinted_script4 } + { hinted_script5 } + }; hints.extend(hint1); hints.extend(hint2); hints.extend(hint3); diff --git a/bitvm/src/bn254/pairing.rs b/bitvm/src/bn254/pairing.rs index 035f52b20..ed8f40ce7 100644 --- a/bitvm/src/bn254/pairing.rs +++ b/bitvm/src/bn254/pairing.rs @@ -351,349 +351,344 @@ impl Pairing { let mut scripts_iter = scripts.into_iter(); - let mut script_lines = Vec::new(); + let script=script!{ - // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), c(12), c_inv(12), wi(12), T4(4)] - // 1. f = c_inv - script_lines.push(Fq12::copy(16)); - // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), c(12), c_inv(12), wi(12), T4(4), f(12)] - - // ATE_LOOP_COUNT len: 65 - for i in (1..ark_bn254::Config::ATE_LOOP_COUNT.len()).rev() { - // update f, squaring - script_lines.push(scripts_iter.next().unwrap()); - // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), c(12), c_inv(12), wi(12), T4(4), f(12)] - - // update f, multiplying - // f = f * c_inv, if digit == 1 - // f = f * c, if digit == -1 - if ark_bn254::Config::ATE_LOOP_COUNT[i - 1] == 1 { - // copy c_inv - script_lines.push(Fq12::copy(28)); - // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), c(12), c_inv(12), wi(12), T4(4), f(12), c_inv(12)] - // f = f * c_inv - script_lines.push(scripts_iter.next().unwrap()); - } else if ark_bn254::Config::ATE_LOOP_COUNT[i - 1] == -1 { - // copy c - script_lines.push(Fq12::copy(40)); - // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), c(12), c_inv(12), wi(12), T4(4), f(12), c(12)] - // f = f * c - script_lines.push(scripts_iter.next().unwrap()); - } + // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), c(12), c_inv(12), wi(12), T4(4)] + // 1. f = c_inv + { Fq12::copy(16) } // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), c(12), c_inv(12), wi(12), T4(4), f(12)] - // update f with double line evaluation - for j in 0..num_line_groups { - // copy P_j(p1, p2, p3, p4) to stack - script_lines.push(Fq2::copy((26 + 36 - j * 2) as u32)); - // update f with double line evaluation - script_lines.push(scripts_iter.next().unwrap()); // ell_by_constant_affine(&line_coeffs[num_lines - (i + 2)][j][0]) - // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), c(12), c_inv(12), wi(12), T4(4), f(12)] - - // non-fixed part - if j == num_constant { - // check line coeff is satisfied with T4 - script_lines.push(Fq12::toaltstack()); - // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), c(12), c_inv(12), wi(12), T4(4) | f(12)] - script_lines.push(Fq2::copy(2)); - script_lines.push(Fq2::copy(2)); - // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), c(12), c_inv(12), wi(12), T4(4), T4(4) | f(12)] - - // -- push c3,c4 to stack - script_lines.push(Fq2::push(line_coeffs[num_lines - (i + 2)][j][0].1)); - script_lines.push(Fq2::push(line_coeffs[num_lines - (i + 2)][j][0].2)); - // [...T4(4),T4(4),C3(2),C4(2)] - // -- move t4 to stack top - script_lines.push(Fq2::roll(6)); - script_lines.push(Fq2::roll(6)); - // -- [...T4(4),C3(2),C4(2),T4(4)] - script_lines.push(scripts_iter.next().unwrap()); // check_tangent_line(line_coeffs[num_lines - (i + 2)][j][0].1, line_coeffs[num_lines - (i + 2)][j][0].2) - // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), c(12), c_inv(12), wi(12), T4(4) | f(12)] - - // -- [...T4(4),c3(2),c4(2)] - // -- move c3,c4 to alt stack - script_lines.push(Fq2::toaltstack()); - script_lines.push(Fq2::toaltstack()); - // -- [...T4(4), | c3(2),c4(2),f(12)] - // - // update T4 - // drop T4.y, leave T4.x - script_lines.push(Fq2::drop()); - - // -- [...T4.x(2),| c3(2),c4(2),fq(12)] - // -- move c3 c4 to stack - script_lines.push(Fq2::fromaltstack()); - script_lines.push(Fq2::fromaltstack()); - // -- [...T4.x(2),c3(2),c4(2)|f(12)] - // -- move T4.x(2) to stack top - script_lines.push(Fq2::roll(4)); - // -- [...,c3(2),c4(2),T4.x(2)|f(12)] - // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), c(12), c_inv(12), wi(12), T4.x(2) | f(12)] - script_lines.push(scripts_iter.next().unwrap()); // affine_double_line(line_coeffs[num_lines - (i + 2)][j][0].1, line_coeffs[num_lines - (i + 2)][j][0].2) - // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), c(12), c_inv(12), wi(12), T4(4) | f(12)] - // -- [...c3(2),c4(2),T4(4)|f(12)] - // -- drop c3,c4 [...T4(4)|f(12)] - script_lines.push(Fq2::roll(6)); - script_lines.push(Fq2::roll(6)); - script_lines.push(Fq2::drop()); - script_lines.push(Fq2::drop()); - - script_lines.push(Fq12::fromaltstack()); - // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), c(12), c_inv(12), wi(12), T4(4), f(12)] + // ATE_LOOP_COUNT len: 65 + for i in (1..ark_bn254::Config::ATE_LOOP_COUNT.len()).rev() { + // update f, squaring + { scripts_iter.next().unwrap() } + // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), c(12), c_inv(12), wi(12), T4(4), f(12)] + + // update f, multiplying + // f = f * c_inv, if digit == 1 + // f = f * c, if digit == -1 + if ark_bn254::Config::ATE_LOOP_COUNT[i - 1] == 1 { + // copy c_inv + { Fq12::copy(28) } + // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), c(12), c_inv(12), wi(12), T4(4), f(12), c_inv(12)] + // f = f * c_inv + { scripts_iter.next().unwrap() } + } else if ark_bn254::Config::ATE_LOOP_COUNT[i - 1] == -1 { + // copy c + { Fq12::copy(40) } + // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), c(12), c_inv(12), wi(12), T4(4), f(12), c(12)] + // f = f * c + { scripts_iter.next().unwrap() } } - } + // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), c(12), c_inv(12), wi(12), T4(4), f(12)] - // update f with add line evaluation - if ark_bn254::Config::ATE_LOOP_COUNT[i - 1] == 1 - || ark_bn254::Config::ATE_LOOP_COUNT[i - 1] == -1 - { + // update f with double line evaluation for j in 0..num_line_groups { // copy P_j(p1, p2, p3, p4) to stack - script_lines.push(Fq2::copy((26 + 36 - j * 2) as u32)); - // update f with adding line evaluation - script_lines.push(scripts_iter.next().unwrap()); // ell_by_constant_affine(&line_coeffs[num_lines - (i + 2)][j][1]) - // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), c(12), c_inv(12), wi(12), T4(4), f(12)] + { Fq2::copy((26 + 36 - j * 2) as u32) } + // update f with double line evaluation + { scripts_iter.next().unwrap() } // ell_by_constant_affine(&line_coeffs[num_lines - (i + 2)][j][0]) + // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), c(12), c_inv(12), wi(12), T4(4), f(12)] // non-fixed part if j == num_constant { - script_lines.push(Fq12::toaltstack()); + // check line coeff is satisfied with T4 + { Fq12::toaltstack() } // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), c(12), c_inv(12), wi(12), T4(4) | f(12)] - - // copy T4 - script_lines.push(Fq2::copy(2)); - script_lines.push(Fq2::copy(2)); + { Fq2::copy(2) } + { Fq2::copy(2) } // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), c(12), c_inv(12), wi(12), T4(4), T4(4) | f(12)] - // copy Q4 - script_lines.push(Fq2::copy(10 + 36)); - script_lines.push(Fq2::copy(10 + 36)); - // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), c(12), c_inv(12), wi(12), T4(4), T4(4), Q4(4) | f(12)] - if ark_bn254::Config::ATE_LOOP_COUNT[i - 1] == -1 { - script_lines.push(Fq2::neg(0)); - } - // -- push c3,c4 to stack - script_lines.push(Fq2::push(line_coeffs[num_lines - (i + 2)][j][1].1)); - script_lines.push(Fq2::push(line_coeffs[num_lines - (i + 2)][j][1].2)); - // -- [...T4(4),Q4(4),c3(2),c4(2)|f(12)] - // -- move t4,q4 to stack top - script_lines.push(Fq2::roll(10)); - script_lines.push(Fq2::roll(10)); - script_lines.push(Fq2::roll(10)); - script_lines.push(Fq2::roll(10)); - // -- [...c3(2),c4(2),T4(4),Q4(4),|f(12)] - script_lines.push(scripts_iter.next().unwrap()); // check_chord_line(line_coeffs[num_lines - (i + 2)][j][1].1, line_coeffs[num_lines - (i + 2)][j][1].2) - // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), c(12), c_inv(12), wi(12), T4(4) | f(12)] - - // -- [...T4(4),c3(2),c4(2)|f(12)] - // -- move c3 c4 to altstack - script_lines.push(Fq2::toaltstack()); - script_lines.push(Fq2::toaltstack()); - // -- [...T4(4)|c3(2),c4(2),f(12)] + // -- push c3,c4 to stack + { Fq2::push(line_coeffs[num_lines - (i + 2)][j][0].1) } + { Fq2::push(line_coeffs[num_lines - (i + 2)][j][0].2) } + // [...T4(4),T4(4),C3(2),C4(2)] + // -- move t4 to stack top + { Fq2::roll(6) } + { Fq2::roll(6) } + // -- [...T4(4),C3(2),C4(2),T4(4)] + { scripts_iter.next().unwrap() } // check_tangent_line(line_coeffs[num_lines - (i + 2)][j][0].1, line_coeffs[num_lines - (i + 2)][j][0].2) + // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), c(12), c_inv(12), wi(12), T4(4) | f(12)] + + // -- [...T4(4),c3(2),c4(2)] + // -- move c3,c4 to alt stack + { Fq2::toaltstack() } + { Fq2::toaltstack() } + // -- [...T4(4), | c3(2),c4(2),f(12)] + // // update T4 // drop T4.y, leave T4.x - script_lines.push(Fq2::drop()); + { Fq2::drop() } + + // -- [...T4.x(2),| c3(2),c4(2),fq(12)] + // -- move c3 c4 to stack + { Fq2::fromaltstack() } + { Fq2::fromaltstack() } + // -- [...T4.x(2),c3(2),c4(2)|f(12)] + // -- move T4.x(2) to stack top + { Fq2::roll(4) } + // -- [...,c3(2),c4(2),T4.x(2)|f(12)] // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), c(12), c_inv(12), wi(12), T4.x(2) | f(12)] - // copy Q4.x - script_lines.push(Fq2::copy(4 + 36)); - // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), c(12), c_inv(12), wi(12), T4.x(2), Q4.x(2) | f(12)] - - // -- move c3,c4 to stack - script_lines.push(Fq2::fromaltstack()); - script_lines.push(Fq2::fromaltstack()); - // -- [...T4.x(2), Q4.x(2),c3(2),c4(2) | f(12)] - // -- move t4.x,q4.x to stack top - script_lines.push(Fq2::roll(6)); - script_lines.push(Fq2::roll(6)); - // -- [...,c3(2),c4(2),T4.x(2), Q4.x(2) | f(12)] - script_lines.push(scripts_iter.next().unwrap()); // affine_add_line(line_coeffs[num_lines - (i + 2)][j][1].1, line_coeffs[num_lines - (i + 2)][j][1].2) - // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), c(12), c_inv(12), wi(12), T4(4) | f(12)] - // -- [... c3(2),c4(2),T4(4)|f(12)] - // -- drop c3,c4 [... T4(4)|f(12)] - script_lines.push(Fq2::roll(6)); - script_lines.push(Fq2::roll(6)); - script_lines.push(Fq2::drop()); - script_lines.push(Fq2::drop()); - - script_lines.push(Fq12::fromaltstack()); + { scripts_iter.next().unwrap() } // affine_double_line(line_coeffs[num_lines - (i + 2)][j][0].1, line_coeffs[num_lines - (i + 2)][j][0].2) + // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), c(12), c_inv(12), wi(12), T4(4) | f(12)] + // -- [...c3(2),c4(2),T4(4)|f(12)] + // -- drop c3,c4 [...T4(4)|f(12)] + { Fq2::roll(6) } + { Fq2::roll(6) } + { Fq2::drop() } + { Fq2::drop() } + + { Fq12::fromaltstack() } // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), c(12), c_inv(12), wi(12), T4(4), f(12)] } } - } - } - // update f with frobenius of c, say f = f * c_inv^p * c^{p^2} - script_lines.push(Fq12::roll(28)); - script_lines.push(Fq12::copy(0)); - script_lines.push(Fq12::toaltstack()); - // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), c(12), wi(12), T4(4), f(12), c_inv(12)] - script_lines.push(scripts_iter.next().unwrap()); // Fq12::frobenius_map(1) - // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), c(12), wi(12), T4(4), f(12), c_inv^p(12)] - script_lines.push(scripts_iter.next().unwrap()); // Fq12::mul(12, 0) - // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), c(12), wi(12), T4(4), f(12)] - script_lines.push(Fq12::roll(28)); - // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), wi(12), T4(4), f(12), c(12)] - script_lines.push(scripts_iter.next().unwrap()); // Fq12::frobenius_map(2) - // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), wi(12), T4(4), f(12), c^{p^2}(12)] - script_lines.push(scripts_iter.next().unwrap()); // Fq12::mul(12, 0) - // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), wi(12), T4(4), f(12)] - - script_lines.push(Fq12::fromaltstack()); // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), wi(12), T4(4), f(12), c_inv(12)] - script_lines.push(scripts_iter.next().unwrap()); // Fq12::frobenius_map(3) - // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), wi(12), T4(4), f(12), c_inv^{p^3}(12)] - script_lines.push(scripts_iter.next().unwrap()); // Fq12::mul(12, 0) - // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), wi(12), T4(4), f(12)] - // update f with scalar wi, say f = f * wi - script_lines.push(Fq12::roll(16)); - // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), T4(4), f(12), wi(12)] - script_lines.push(scripts_iter.next().unwrap()); // Fq12::mul(12, 0) - // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), T4(4), f(12)] - - // update f with add line evaluation of one-time of frobenius map on Q4 - for j in 0..num_line_groups { - // copy P_j(p1, p2, p3, p4) to stack - script_lines.push(Fq2::copy((26 - j * 2) as u32)); - // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), T4(4), f(12), P_j(2)] - script_lines.push(scripts_iter.next().unwrap()); // ell_by_constant_affine(&line_coeffs[num_lines - 2][j][0]) - // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), T4(4), f(12)] - - // non-fixed part - if j == num_constant { - script_lines.push(Fq12::toaltstack()); - // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), T4(4) | f(12)] - - // Qx' = Qx.conjugate * beta^{2 * (p - 1) / 6} - script_lines.push(Fq2::copy(6)); - // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), T4(4), Q4.x(2) | f(12)] - script_lines.push(Fq::neg(0)); - // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), T4(4), -Q4.x(2) | f(12)] - script_lines.push(Fq2::roll(22)); - // [beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), T4(4), -Q4.x(2), beta_12(2) | f(12)] - script_lines.push(scripts_iter.next().unwrap()); // Fq2::mul(2, 0) - // Q4.x' = -Q4.x * beta_12 (2) - // [beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), T4(4), Q4.x'(2) | f(12)] - - // Qy' = Qy.conjugate * beta^{3 * (p - 1) / 6} - script_lines.push(Fq2::copy(6)); - // [beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), T4(4), Q4.x'(2), Q4.y(2) | f(12)] - script_lines.push(Fq::neg(0)); - // [beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), T4(4), Q4.x'(2), -Q4.y(2) | f(12)] - script_lines.push(Fq2::roll(22)); - // [beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), T4(4), Q4.x'(2), -Q4.y(2), beta_13(2) | f(12)] - script_lines.push(scripts_iter.next().unwrap()); // Fq2::mul(2, 0) - // Q4.y' = -Q4.y * beta_13 (2) - // [beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), T4(4), Q4.x'(2), Q4.y'(2) | f(12)] - // phi(Q4) = (Q4.x', Q4.y') - // [beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), T4(4), phi(Q4)(4) | f(12)] - - // check chord line - script_lines.push(Fq2::copy(6)); - script_lines.push(Fq2::copy(6)); - // [beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), T4(4), phi(Q4)(4), T4(4) | f(12)] - script_lines.push(Fq2::copy(6)); - script_lines.push(Fq2::copy(6)); - // [beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), T4(4), phi(Q4)(4), T4(4), phi(Q4)(4) | f(12)] - - // -- [...T4(4),Q4(4), T4(4),Q4(4)|f(12)] - // -- push c3,c4 to stack - script_lines.push(Fq2::push(line_coeffs[num_lines - 2][j][0].1)); - script_lines.push(Fq2::push(line_coeffs[num_lines - 2][j][0].2)); - // -- [... T4(4),Q4(4),T4(4),Q4(4),c3(2),c4(2)|f(12)] - // -- move T4,Q4 to stack top - script_lines.push(Fq2::roll(10)); - script_lines.push(Fq2::roll(10)); - script_lines.push(Fq2::roll(10)); - script_lines.push(Fq2::roll(10)); - // -- [... T4(4),Q4(4),c3(2),c4(2),T4(4),Q4(4),|f(12)] - script_lines.push(scripts_iter.next().unwrap()); // check_chord_line(line_coeffs[num_lines - 2][j][0].1, line_coeffs[num_lines - 2][j][0].2) - // [beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), T4(4), phi(Q4)(4) | f(12)] - // -- [... T4(4),Q4(4),c3(2),c4(2)|f(12)] - // -- move c3,c4 to altstack - script_lines.push(Fq2::toaltstack()); - script_lines.push(Fq2::toaltstack()); - // -- [... T4(4),Q4(4)|,c3(2),c4(2),f(12)] - // update T4 - script_lines.push(Fq2::drop()); - // [beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), T4(4), phi(Q4).x(2) | f(12)] - script_lines.push(Fq2::toaltstack()); - // [beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), T4(4) | phi(Q4).x(2), f(12)] - script_lines.push(Fq2::drop()); - // [beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), T4.x(2) | phi(Q4).x(2), f(12)] - script_lines.push(Fq2::fromaltstack()); - // [beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), T4.x(2), phi(Q4).x(2) | f(12)] - // -- move c3,c4 to stack - script_lines.push(Fq2::fromaltstack()); - script_lines.push(Fq2::fromaltstack()); - // -- [... T4.x(2), phi(Q4).x(2) ,c3(2),c4(2)|f(12)] - // -- move T4.x Q4.x to stack top - script_lines.push(Fq2::roll(6)); // [... phi(Q4).x(2) ,c3(2),c4(2),T4.x(2), |f(12)] - script_lines.push(Fq2::roll(6)); - // -- [... ,c3(2),c4(2), T4.x(2), phi(Q4).x(2) |f(12)] - script_lines.push(scripts_iter.next().unwrap()); // affine_add_line(line_coeffs[num_lines - 2][j][0].1, line_coeffs[num_lines - 2][j][0].2) - // [beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), T4(4) | f(12)] - // -- [...c3(2),c4(2),T4(4)|f(12)] - // -- drop c3,c4 - script_lines.push(Fq2::roll(6)); - script_lines.push(Fq2::roll(6)); - script_lines.push(Fq2::drop()); - script_lines.push(Fq2::drop()); - // -- [...,T4(4)|f(12)] - script_lines.push(Fq12::fromaltstack()); - // [beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), T4(4), f(12)] + // update f with add line evaluation + if ark_bn254::Config::ATE_LOOP_COUNT[i - 1] == 1 + || ark_bn254::Config::ATE_LOOP_COUNT[i - 1] == -1 + { + for j in 0..num_line_groups { + // copy P_j(p1, p2, p3, p4) to stack + { Fq2::copy((26 + 36 - j * 2) as u32) } + // update f with adding line evaluation + { scripts_iter.next().unwrap() } // ell_by_constant_affine(&line_coeffs[num_lines - (i + 2)][j][1]) + // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), c(12), c_inv(12), wi(12), T4(4), f(12)] + + // non-fixed part + if j == num_constant { + { Fq12::toaltstack() } + // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), c(12), c_inv(12), wi(12), T4(4) | f(12)] + + // copy T4 + { Fq2::copy(2) } + { Fq2::copy(2) } + // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), c(12), c_inv(12), wi(12), T4(4), T4(4) | f(12)] + + // copy Q4 + { Fq2::copy(10 + 36) } + { Fq2::copy(10 + 36) } + // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), c(12), c_inv(12), wi(12), T4(4), T4(4), Q4(4) | f(12)] + if ark_bn254::Config::ATE_LOOP_COUNT[i - 1] == -1 { + { Fq2::neg(0) } + } + // -- push c3,c4 to stack + { Fq2::push(line_coeffs[num_lines - (i + 2)][j][1].1) } + { Fq2::push(line_coeffs[num_lines - (i + 2)][j][1].2) } + // -- [...T4(4),Q4(4),c3(2),c4(2)|f(12)] + // -- move t4,q4 to stack top + { Fq2::roll(10) } + { Fq2::roll(10) } + { Fq2::roll(10) } + { Fq2::roll(10) } + // -- [...c3(2),c4(2),T4(4),Q4(4),|f(12)] + { scripts_iter.next().unwrap() } // check_chord_line(line_coeffs[num_lines - (i + 2)][j][1].1, line_coeffs[num_lines - (i + 2)][j][1].2) + // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), c(12), c_inv(12), wi(12), T4(4) | f(12)] + + // -- [...T4(4),c3(2),c4(2)|f(12)] + // -- move c3 c4 to altstack + { Fq2::toaltstack() } + { Fq2::toaltstack() } + // -- [...T4(4)|c3(2),c4(2),f(12)] + // update T4 + // drop T4.y, leave T4.x + { Fq2::drop() } + // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), c(12), c_inv(12), wi(12), T4.x(2) | f(12)] + // copy Q4.x + { Fq2::copy(4 + 36) } + // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), c(12), c_inv(12), wi(12), T4.x(2), Q4.x(2) | f(12)] + + // -- move c3,c4 to stack + { Fq2::fromaltstack() } + { Fq2::fromaltstack() } + // -- [...T4.x(2), Q4.x(2),c3(2),c4(2) | f(12)] + // -- move t4.x,q4.x to stack top + { Fq2::roll(6) } + { Fq2::roll(6) } + // -- [...,c3(2),c4(2),T4.x(2), Q4.x(2) | f(12)] + { scripts_iter.next().unwrap() } // affine_add_line(line_coeffs[num_lines - (i + 2)][j][1].1, line_coeffs[num_lines - (i + 2)][j][1].2) + // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), c(12), c_inv(12), wi(12), T4(4) | f(12)] + // -- [... c3(2),c4(2),T4(4)|f(12)] + // -- drop c3,c4 [... T4(4)|f(12)] + { Fq2::roll(6) } + { Fq2::roll(6) } + { Fq2::drop() } + { Fq2::drop() } + + { Fq12::fromaltstack() } + // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), c(12), c_inv(12), wi(12), T4(4), f(12)] + } + } + } } - } - // update f with add line evaluation of two-times of frobenius map on Q4 - for j in 0..num_line_groups { - // update f with adding line evaluation by rolling each Pi(2) element to the right(stack top) - script_lines.push(Fq2::roll((26 - j * 2) as u32)); - script_lines.push(scripts_iter.next().unwrap()); // ell_by_constant_affine(&line_coeffs[num_lines - 1][j][0]) - // [beta_22(2), Q4(4), T4(4), f(12)] + // update f with frobenius of c, say f = f * c_inv^p * c^{p^2} + { Fq12::roll(28) } + { Fq12::copy(0) } + { Fq12::toaltstack() } + // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), c(12), wi(12), T4(4), f(12), c_inv(12)] + { scripts_iter.next().unwrap() } // Fq12::frobenius_map(1) + // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), c(12), wi(12), T4(4), f(12), c_inv^p(12)] + { scripts_iter.next().unwrap() } // Fq12::mul(12, 0) + // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), c(12), wi(12), T4(4), f(12)] + { Fq12::roll(28) } + // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), wi(12), T4(4), f(12), c(12)] + { scripts_iter.next().unwrap() } // Fq12::frobenius_map(2) + // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), wi(12), T4(4), f(12), c^{p^2}(12)] + { scripts_iter.next().unwrap() } // Fq12::mul(12, 0) + // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), wi(12), T4(4), f(12)] + + { Fq12::fromaltstack() } // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), wi(12), T4(4), f(12), c_inv(12)] + { scripts_iter.next().unwrap() } // Fq12::frobenius_map(3) + // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), wi(12), T4(4), f(12), c_inv^{p^3}(12)] + { scripts_iter.next().unwrap() } // Fq12::mul(12, 0) + // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), wi(12), T4(4), f(12)] + // update f with scalar wi, say f = f * wi + { Fq12::roll(16) } + // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), T4(4), f(12), wi(12)] + { scripts_iter.next().unwrap() } // Fq12::mul(12, 0) + // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), T4(4), f(12)] + + // update f with add line evaluation of one-time of frobenius map on Q4 + for j in 0..num_line_groups { + // copy P_j(p1, p2, p3, p4) to stack + { Fq2::copy((26 - j * 2) as u32) } + // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), T4(4), f(12), P_j(2)] + { scripts_iter.next().unwrap() } // ell_by_constant_affine(&line_coeffs[num_lines - 2][j][0]) + // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), T4(4), f(12)] - // non-fixed part(Q4) - if j == num_constant { - script_lines.push(Fq12::toaltstack()); - // [beta_22(2), Q4(4), T4(4) | f(12)] - script_lines.push(Fq2::roll(8)); - // [Q4(4), T4(4), beta_22(2) | f(12)] - script_lines.push(Fq2::roll(8)); - // [Q4.y(2), T4(4), beta_22(2), Q4.x(2) | f(12)] - script_lines.push(scripts_iter.next().unwrap()); // Fq2::mul(2, 0) - // [Q4.y(2), T4(4), beta_22(2) * Q4.x(2) | f(12)] - // Q4.x' = Q4.x * beta^{2 * (p^2 - 1) / 6} - // [Q4.y(2), T4(4), Q4.x'(2) | f(12)] - script_lines.push(Fq2::roll(6)); - // [T4(4), Q4.x'(2), Q4.y(2) | f(12)] - // phi(Q4)^2 = (Q4.x', Qy) - // [T4(4), phi(Q4)^2(4) | f(12)] - - // -- push c3,c4 to stack - script_lines.push(Fq2::push(line_coeffs[num_lines - 1][j][0].1)); - script_lines.push(Fq2::push(line_coeffs[num_lines - 1][j][0].2)); - // [T4.x(2),T4.y(2),Q4.x(2),Q4.y(2),c3(2),c4(2)|f(12)] - // -- move T4,Q4 to stack top - script_lines.push(Fq2::roll(10));// [T4.y(2),Q4.x(2),Q4.y(2),c3(2),c4(2),T4.x(2),|f(12)] - script_lines.push(Fq2::roll(10));// [Q4.x(2),Q4.y(2),c3(2),c4(2),T4.x(2),T4.y(2),|f(12)] - script_lines.push(Fq2::roll(10));// [Q4.y(2),c3(2),c4(2),T4.x(2),T4.y(2),Q4.x(2),|f(12)] - script_lines.push(Fq2::roll(10));// [c3(2),c4(2),T4.x(2),T4.y(2),Q4.x(2),Q4.y(2),|f(12)] - // -- [c3(2),c4(2),T4(4),Q4.x(2),Q4.y(2)|f(12)] - // check whether the chord line through T4 and phi(Q4)^2 - script_lines.push(scripts_iter.next().unwrap()); // check_chord_line(line_coeffs[num_lines - 1][j][0].1, line_coeffs[num_lines - 1][j][0].2) - // [ | f(12)] - // -- [c3(2),c4(2)|f(12)] - // -- drop c3,c4 - script_lines.push(Fq2::drop());//[c3(2)|f(12)] - script_lines.push(Fq2::drop());//[|f(12)] - // -- [|f(12)] - script_lines.push(Fq12::fromaltstack()); - // [f(12)] + // non-fixed part + if j == num_constant { + { Fq12::toaltstack() } + // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), T4(4) | f(12)] + + // Qx' = Qx.conjugate * beta^{2 * (p - 1) / 6} + { Fq2::copy(6) } + // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), T4(4), Q4.x(2) | f(12)] + { Fq::neg(0) } + // [beta_12(2), beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), T4(4), -Q4.x(2) | f(12)] + { Fq2::roll(22) } + // [beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), T4(4), -Q4.x(2), beta_12(2) | f(12)] + { scripts_iter.next().unwrap() } // Fq2::mul(2, 0) + // Q4.x' = -Q4.x * beta_12 (2) + // [beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), T4(4), Q4.x'(2) | f(12)] + + // Qy' = Qy.conjugate * beta^{3 * (p - 1) / 6} + { Fq2::copy(6) } + // [beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), T4(4), Q4.x'(2), Q4.y(2) | f(12)] + { Fq::neg(0) } + // [beta_13(2), beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), T4(4), Q4.x'(2), -Q4.y(2) | f(12)] + { Fq2::roll(22) } + // [beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), T4(4), Q4.x'(2), -Q4.y(2), beta_13(2) | f(12)] + { scripts_iter.next().unwrap() } // Fq2::mul(2, 0) + // Q4.y' = -Q4.y * beta_13 (2) + // [beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), T4(4), Q4.x'(2), Q4.y'(2) | f(12)] + // phi(Q4) = (Q4.x', Q4.y') + // [beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), T4(4), phi(Q4)(4) | f(12)] + + // check chord line + { Fq2::copy(6) } + { Fq2::copy(6) } + // [beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), T4(4), phi(Q4)(4), T4(4) | f(12)] + { Fq2::copy(6) } + { Fq2::copy(6) } + // [beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), T4(4), phi(Q4)(4), T4(4), phi(Q4)(4) | f(12)] + + // -- [...T4(4),Q4(4), T4(4),Q4(4)|f(12)] + // -- push c3,c4 to stack + { Fq2::push(line_coeffs[num_lines - 2][j][0].1) } + { Fq2::push(line_coeffs[num_lines - 2][j][0].2) } + // -- [... T4(4),Q4(4),T4(4),Q4(4),c3(2),c4(2)|f(12)] + // -- move T4,Q4 to stack top + { Fq2::roll(10) } + { Fq2::roll(10) } + { Fq2::roll(10) } + { Fq2::roll(10) } + // -- [... T4(4),Q4(4),c3(2),c4(2),T4(4),Q4(4),|f(12)] + { scripts_iter.next().unwrap() } // check_chord_line(line_coeffs[num_lines - 2][j][0].1, line_coeffs[num_lines - 2][j][0].2) + // [beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), T4(4), phi(Q4)(4) | f(12)] + // -- [... T4(4),Q4(4),c3(2),c4(2)|f(12)] + // -- move c3,c4 to altstack + { Fq2::toaltstack() } + { Fq2::toaltstack() } + // -- [... T4(4),Q4(4)|,c3(2),c4(2),f(12)] + // update T4 + { Fq2::drop() } + // [beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), T4(4), phi(Q4).x(2) | f(12)] + { Fq2::toaltstack() } + // [beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), T4(4) | phi(Q4).x(2), f(12)] + { Fq2::drop() } + // [beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), T4.x(2) | phi(Q4).x(2), f(12)] + { Fq2::fromaltstack() } + // [beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), T4.x(2), phi(Q4).x(2) | f(12)] + // -- move c3,c4 to stack + { Fq2::fromaltstack() } + { Fq2::fromaltstack() } + // -- [... T4.x(2), phi(Q4).x(2) ,c3(2),c4(2)|f(12)] + // -- move T4.x Q4.x to stack top + { Fq2::roll(6) } // [... phi(Q4).x(2) ,c3(2),c4(2),T4.x(2), |f(12)] + { Fq2::roll(6) } + // -- [... ,c3(2),c4(2), T4.x(2), phi(Q4).x(2) |f(12)] + { scripts_iter.next().unwrap() } // affine_add_line(line_coeffs[num_lines - 2][j][0].1, line_coeffs[num_lines - 2][j][0].2) + // [beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), T4(4) | f(12)] + // -- [...c3(2),c4(2),T4(4)|f(12)] + // -- drop c3,c4 + { Fq2::roll(6) } + { Fq2::roll(6) } + { Fq2::drop() } + { Fq2::drop() } + // -- [...,T4(4)|f(12)] + { Fq12::fromaltstack() } + // [beta_22(2), P1(2), P2(2), P3(2), P4(2), Q4(4), T4(4), f(12)] + } } - } - let mut script = script! {}; - for script_line in script_lines { - script = script.push_script(script_line.compile()); - } + // update f with add line evaluation of two-times of frobenius map on Q4 + for j in 0..num_line_groups { + // update f with adding line evaluation by rolling each Pi(2) element to the right(stack top) + { Fq2::roll((26 - j * 2) as u32) } + { scripts_iter.next().unwrap() } // ell_by_constant_affine(&line_coeffs[num_lines - 1][j][0]) + // [beta_22(2), Q4(4), T4(4), f(12)] + // non-fixed part(Q4) + if j == num_constant { + { Fq12::toaltstack() } + // [beta_22(2), Q4(4), T4(4) | f(12)] + { Fq2::roll(8) } + // [Q4(4), T4(4), beta_22(2) | f(12)] + { Fq2::roll(8) } + // [Q4.y(2), T4(4), beta_22(2), Q4.x(2) | f(12)] + { scripts_iter.next().unwrap() } // Fq2::mul(2, 0) + // [Q4.y(2), T4(4), beta_22(2) * Q4.x(2) | f(12)] + // Q4.x' = Q4.x * beta^{2 * (p^2 - 1) / 6} + // [Q4.y(2), T4(4), Q4.x'(2) | f(12)] + { Fq2::roll(6) } + // [T4(4), Q4.x'(2), Q4.y(2) | f(12)] + // phi(Q4)^2 = (Q4.x', Qy) + // [T4(4), phi(Q4)^2(4) | f(12)] + + // -- push c3,c4 to stack + { Fq2::push(line_coeffs[num_lines - 1][j][0].1) } + { Fq2::push(line_coeffs[num_lines - 1][j][0].2) } + // [T4.x(2),T4.y(2),Q4.x(2),Q4.y(2),c3(2),c4(2)|f(12)] + // -- move T4,Q4 to stack top + { Fq2::roll(10) }// [T4.y(2),Q4.x(2),Q4.y(2),c3(2),c4(2),T4.x(2),|f(12)] + { Fq2::roll(10) }// [Q4.x(2),Q4.y(2),c3(2),c4(2),T4.x(2),T4.y(2),|f(12)] + { Fq2::roll(10) }// [Q4.y(2),c3(2),c4(2),T4.x(2),T4.y(2),Q4.x(2),|f(12)] + { Fq2::roll(10) }// [c3(2),c4(2),T4.x(2),T4.y(2),Q4.x(2),Q4.y(2),|f(12)] + // -- [c3(2),c4(2),T4(4),Q4.x(2),Q4.y(2)|f(12)] + // check whether the chord line through T4 and phi(Q4)^2 + { scripts_iter.next().unwrap() } // check_chord_line(line_coeffs[num_lines - 1][j][0].1, line_coeffs[num_lines - 1][j][0].2) + // [ | f(12)] + // -- [c3(2),c4(2)|f(12)] + // -- drop c3,c4 + { Fq2::drop() }//[c3(2)|f(12)] + { Fq2::drop() }//[|f(12)] + // -- [|f(12)] + { Fq12::fromaltstack() } + // [f(12)] + } + } + }; (script, hints) } } @@ -707,13 +702,13 @@ mod test { use crate::bn254::fq2::Fq2; use crate::bn254::pairing::Pairing; use crate::bn254::g1::hinted_from_eval_point; + use crate::groth16::constants::LAMBDA; use crate::{execute_script_without_stack_limit, treepp::*}; use ark_bn254::Bn254; use ark_ec::pairing::Pairing as _; use ark_ff::Field; use ark_std::UniformRand; use num_bigint::BigUint; - use num_traits::Num; use rand::SeedableRng; use rand_chacha::ChaCha20Rng; use std::str::FromStr; @@ -722,16 +717,6 @@ mod test { fn test_hinted_quad_miller_loop_with_c_wi() { let mut prng = ChaCha20Rng::seed_from_u64(0); - // exp = 6x + 2 + p - p^2 = lambda - p^3 - let p_pow3 = BigUint::from_str_radix(Fq::MODULUS, 16).unwrap().pow(3_u32); - let lambda = BigUint::from_str( - "10486551571378427818905133077457505975146652579011797175399169355881771981095211883813744499745558409789005132135496770941292989421431235276221147148858384772096778432243207188878598198850276842458913349817007302752534892127325269" - ).unwrap(); - let (exp, sign) = if lambda > p_pow3 { - (lambda - p_pow3, true) - } else { - (p_pow3 - lambda, false) - }; // random c and wi let c = ark_bn254::Fq12::rand(&mut prng); let c_inv = c.inverse().unwrap(); @@ -785,11 +770,7 @@ mod test { let f = Bn254::multi_miller_loop_affine([p1, p2, p3, p4], [q1, q2, q3, q4]).0; println!("Bn254::multi_miller_loop_affine done!"); - let hint = if sign { - f * wi * (c_inv.pow(exp.to_u64_digits())) - } else { - f * wi * (c_inv.pow(exp.to_u64_digits()).inverse().unwrap()) - }; + let result = f * wi * (c_inv.pow(LAMBDA.to_u64_digits())); // [beta_12, beta_13, beta_22, P1, P2, P3, P4, Q4, c, c_inv, wi, T4]: p1-p4: (-p.x / p.y, 1 / p.y) let script = script! { @@ -840,7 +821,7 @@ mod test { { quad_miller_loop_affine_script } - { Fq12::push(ark_bn254::Fq12::ONE) } + { Fq12::push(result) } { Fq12::equalverify() } @@ -857,4 +838,4 @@ mod test { } assert!(exec_result.success); } -} +} \ No newline at end of file diff --git a/bitvm/src/chunker/chunk_evaluate_line.rs b/bitvm/src/chunker/chunk_evaluate_line.rs index 8f6d24cbc..064de0b5f 100644 --- a/bitvm/src/chunker/chunk_evaluate_line.rs +++ b/bitvm/src/chunker/chunk_evaluate_line.rs @@ -64,69 +64,65 @@ pub fn chunk_evaluate_line( let mut c2 = constant.2; c2.mul_assign_by_fp(&y); - let script_lines_0 = if constant_4.is_some() { - vec![ + let script_0 = if constant_4.is_some() { + script! { // [c0.0,c0.1, c1.0, c1.1, c2.0, c2.1, x, y] - Fq::roll(7), + { Fq::roll(7) } // [c0.1, c1.0, c1.1, c2.0, c2.1, x, y,c0.0] - Fq::roll(7), + { Fq::roll(7) } // [ c1.0, c1.1, c2.0, c2.1, x, y,c0.0,c0.1] - Fq::drop(), - Fq::drop(), + { Fq::drop() } + { Fq::drop() } // [c1.0, c1.1, c2.0, c2.1, x, y] - Fq::copy(1), + { Fq::copy(1) } // [c1.0, c1.1, c2.0, c2.1, x, y, x] - Fq::roll(6), + { Fq::roll(6) } // [c1.1, c2.0, c2.1, x, y, x, c1.0] - hinted_script1, + { hinted_script1 } // [c1.1, c2.0, c2.1, x, y, x*c1.0] - Fq::roll(2), + { Fq::roll(2) } // [c1.1, c2.0, c2.1, y, x*c1.0, x] - Fq::roll(5), + { Fq::roll(5) } // [ c2.0, c2.1, y, x*c1.0, x, c1.1] - hinted_script2, + { hinted_script2 } // [ c2.0, c2.1, y, x*c1.0, x*c1.1] - Fq::copy(2), + { Fq::copy(2) } // [ c2.0, c2.1, y, x*c1.0, x*c1.1, y] - Fq::roll(5), + { Fq::roll(5) } // [ c2.1, y, x*c1.0, x*c1.1, y, c2.0] - hinted_script3, + { hinted_script3 } // [ c2.1, y, x*c1.0, x*c1.1, y*c2.0] - Fq::roll(3), + { Fq::roll(3) } // [ c2.1, x*c1.0, x*c1.1, y*c2.0, y] - Fq::roll(4), + { Fq::roll(4) } // [ x*c1.0, x*c1.1, y*c2.0, y, c2.1] - hinted_script4, + { hinted_script4 } // [ x*c1.0, x*c1.1, y*c2.0, y*c2.1] - ] + } } else { - vec![ - // [x', y'] - // update c1, c1' = x' * c1 - Fq::copy(1), - hinted_script1, - // [ x', y', x' * c1.0] - Fq::roll(2), - hinted_script2, - // [y', x' * c1.0, x' * c1.1] - // [y', x' * c1] - - // update c2, c2' = -y' * c2 - Fq::copy(2), - hinted_script3, // Fq::mul_by_constant(&constant.2.c0), - // [y', x' * c1, y' * c2.0] - Fq::roll(3), - hinted_script4, - // [x' * c1, y' * c2.0, y' * c2.1] - // [x' * c1, y' * c2] - // [c1', c2'] - ] + script! { + // [x', y'] + // update c1, c1' = x' * c1 + { Fq::copy(1) } + { hinted_script1 } + // [ x', y', x' * c1.0] + { Fq::roll(2) } + { hinted_script2 } + // [y', x' * c1.0, x' * c1.1] + // [y', x' * c1] + + // update c2, c2' = -y' * c2 + { Fq::copy(2) } + { hinted_script3 } // Fq::mul_by_constant(&constant.2.c0), + // [y', x' * c1, y' * c2.0] + { Fq::roll(3) } + { hinted_script4 } + // [x' * c1, y' * c2.0, y' * c2.1] + // [x' * c1, y' * c2] + // [c1', c2'] + } }; - let mut script_0 = script! {}; - for script_line_0 in script_lines_0 { - script_0 = script_0.push_script(script_line_0.compile()); - } let mut hints_0 = Vec::new(); hints_0.extend(hint1); hints_0.extend(hint2); @@ -176,8 +172,6 @@ pub fn chunk_evaluate_line( (vec![segment0, segment1], tc) } - - #[cfg(test)] mod test { use super::chunk_evaluate_line_wrapper; diff --git a/bitvm/src/chunker/chunk_groth16_verifier.rs b/bitvm/src/chunker/chunk_groth16_verifier.rs index f15373df0..36fa925af 100644 --- a/bitvm/src/chunker/chunk_groth16_verifier.rs +++ b/bitvm/src/chunker/chunk_groth16_verifier.rs @@ -5,9 +5,7 @@ use crate::chunker::chunk_msm::chunk_hinted_msm_with_constant_bases_affine; use crate::chunker::chunk_non_fixed_point::chunk_q4; use crate::chunker::elements::{ElementTrait, DataType::Fq6Data,Fq6Type, FrType, G2PointType}; use crate::chunker::{chunk_accumulator, chunk_hinted_accumulator}; -use crate::groth16::constants::{LAMBDA, P_POW3}; use crate::groth16::offchain_checker::compute_c_wi; -use crate::log_assert_eq; use ark_bn254::{Bn254, G1Projective}; use ark_ec::pairing::Pairing as ark_Pairing; use ark_ec::{AffineRepr, CurveGroup, VariableBaseMSM}; @@ -34,12 +32,6 @@ pub fn groth16_verify_to_segments( .concat(); let msm_g1 = G1Projective::msm(&vk.gamma_abc_g1, &scalars).expect("failed to calculate msm"); - let (exp, sign) = if LAMBDA.gt(&P_POW3) { - (&*LAMBDA - &*P_POW3, true) - } else { - (&*P_POW3 - &*LAMBDA, false) - }; - // G1/G2 points for pairings let (p1, p2, p3, p4) = (msm_g1.into_affine(), proof.c, vk.alpha_g1, proof.a); let (q1, q2, q3, q4) = ( @@ -53,13 +45,6 @@ pub fn groth16_verify_to_segments( let f = Bn254::multi_miller_loop_affine([p1, p2, p3, p4], [q1, q2, q3, q4]).0; let (c, wi) = compute_c_wi(f); let c_inv = c.inverse().unwrap(); - let hint = if sign { - f * wi * (c_inv.pow((exp).to_u64_digits())) - } else { - f * wi * (c_inv.pow((exp).to_u64_digits()).inverse().unwrap()) - }; - - log_assert_eq!(hint, c.pow(P_POW3.to_u64_digits()), "hint isn't correct!"); let q_prepared = [ G2Prepared::from_affine(q1), diff --git a/bitvm/src/chunker/chunk_hinted_accumulator.rs b/bitvm/src/chunker/chunk_hinted_accumulator.rs index e4cb56477..0665787ba 100644 --- a/bitvm/src/chunker/chunk_hinted_accumulator.rs +++ b/bitvm/src/chunker/chunk_hinted_accumulator.rs @@ -33,7 +33,7 @@ mod test { use crate::chunker::elements::Fq6Type; use crate::chunker::elements::{DataType::Fq6Data,DataType::Fq12Data, ElementTrait, G1PointType}; use crate::execute_script_with_inputs; - use crate::groth16::constants::{LAMBDA, P_POW3}; + use crate::groth16::constants::LAMBDA; use crate::groth16::offchain_checker::compute_c_wi; use ark_bn254::Bn254; @@ -145,12 +145,6 @@ mod test { let msm_g1 = G1Projective::msm(&vk.gamma_abc_g1, &scalars).expect("failed to calculate msm"); - let (_, _) = if LAMBDA.gt(&P_POW3) { - (&*LAMBDA - &*P_POW3, true) - } else { - (&*P_POW3 - &*LAMBDA, false) - }; - // G1/G2 points for pairings let (p1, p2, p3, p4) = (msm_g1.into_affine(), proof.c, vk.alpha_g1, proof.a); let (q1, q2, q3, q4) = ( @@ -186,11 +180,6 @@ mod test { .concat(); let msm_g1 = G1Projective::msm(&vk.gamma_abc_g1, &scalars).expect("failed to calculate msm"); - let (exp, sign) = if LAMBDA.gt(&P_POW3) { - (&*LAMBDA - &*P_POW3, true) - } else { - (&*P_POW3 - &*LAMBDA, false) - }; // G1/G2 points for pairings let (p1, p2, p3, p4) = (msm_g1.into_affine(), proof.c, vk.alpha_g1, proof.a); let (q1, q2, q3, q4) = ( @@ -203,13 +192,7 @@ mod test { let f = Bn254::multi_miller_loop_affine([p1, p2, p3, p4], [q1, q2, q3, q4]).0; let (c, wi) = compute_c_wi(f); let c_inv = c.inverse().unwrap(); - let hint = if sign { - f * wi * (c_inv.pow((exp).to_u64_digits())) - } else { - f * wi * (c_inv.pow((exp).to_u64_digits()).inverse().unwrap()) - }; - assert_eq!(hint, c.pow(P_POW3.to_u64_digits()), "hint isn't correct!"); - hint + f * wi * c_inv.pow(LAMBDA.to_u64_digits()) } #[allow(unused)] diff --git a/bitvm/src/chunker/chunk_scalar_mul.rs b/bitvm/src/chunker/chunk_scalar_mul.rs index 72b6ec918..e4f7cb02a 100644 --- a/bitvm/src/chunker/chunk_scalar_mul.rs +++ b/bitvm/src/chunker/chunk_scalar_mul.rs @@ -376,12 +376,12 @@ mod tests { let q = bases[0].mul(scalars[0]).into_affine(); println!("debug: expected res:{:?}", q); let (inner_coeffs, _) = prepare_msm_input(&bases, &scalars, 12); - let mut scalar_type = FrType::new(&mut assigner, "init"); + let mut scalar_type = FrType::new(&mut assigner, "init_run1"); scalar_type.fill_with_data(crate::chunker::elements::DataType::FrData(scalars[0])); let (segments1, _) = chunk_hinted_scalar_mul_by_constant( &mut assigner, - "g1_mul", + "g1_mul_run1", scalars[0], scalar_type, &mut bases1[0], @@ -396,12 +396,12 @@ mod tests { let q = bases[0].mul(scalars[0]).into_affine(); println!("debug: expected res:{:?}", q); let (inner_coeffs, _) = prepare_msm_input(&bases, &scalars, 12); - let mut scalar_type = FrType::new(&mut assigner, "init"); + let mut scalar_type = FrType::new(&mut assigner, "init_run2"); scalar_type.fill_with_data(crate::chunker::elements::DataType::FrData(scalars[0])); let (segments2, _) = chunk_hinted_scalar_mul_by_constant( &mut assigner, - "g1_mul", + "g1_mul_run2", scalars[0], scalar_type, &mut bases2[0], diff --git a/bitvm/src/groth16/constants.rs b/bitvm/src/groth16/constants.rs index 36e304e34..1dfe95744 100644 --- a/bitvm/src/groth16/constants.rs +++ b/bitvm/src/groth16/constants.rs @@ -1,15 +1,50 @@ use std::str::FromStr; - -use crate::bn254::{fp254impl::Fp254Impl, fq::Fq}; +use std::sync::LazyLock; +use ark_ff::{Field, UniformRand}; use num_bigint::BigUint; use num_traits::Num; -use std::sync::LazyLock; +use rand::SeedableRng; +use rand_chacha::ChaCha20Rng; -pub static P_POW3: LazyLock = - LazyLock::new(|| BigUint::from_str_radix(Fq::MODULUS, 16).unwrap().pow(3_u32)); +use crate::{bn254::{fp254impl::Fp254Impl, fq::Fq}, log_assert_eq, log_assert_ne}; pub static LAMBDA: LazyLock = LazyLock::new(|| { BigUint::from_str( "10486551571378427818905133077457505975146652579011797175399169355881771981095211883813744499745558409789005132135496770941292989421431235276221147148858384772096778432243207188878598198850276842458913349817007302752534892127325269" ).unwrap() }); + +pub static P: LazyLock = LazyLock::new(|| { BigUint::from_str_radix(Fq::MODULUS, 16).unwrap() }); +pub static R: LazyLock = LazyLock::new(|| { BigUint::from_str("21888242871839275222246405745257275088548364400416034343698204186575808495617").unwrap() }); +pub const S: u32 = 3; +pub static EXP: LazyLock = LazyLock::new(|| { P.pow(12_u32) - 1_u32 }); +pub static H: LazyLock = LazyLock::new(|| { &*EXP / &*R }); +pub static T: LazyLock = LazyLock::new(|| { &*EXP / 3_u32.pow(S) }); +pub static K: LazyLock = LazyLock::new(|| { (&*T + 1_u32) / 3_u32 }); +pub static M: LazyLock = LazyLock::new(|| { &*LAMBDA / &*R }); +pub const D: u32 = 3; +pub static MM: LazyLock = LazyLock::new(|| { &*M / D }); +pub static COFACTOR_CUBIC: LazyLock = LazyLock::new(|| { 3_u32.pow(S - 1) * &*T }); + +pub static W: LazyLock = LazyLock::new(|| { + let mut prng = ChaCha20Rng::seed_from_u64(0); + // sample a proper scalar w which is cubic non-residue + let w = { + let (mut w, mut z) = (ark_bn254::Fq12::ONE, ark_bn254::Fq12::ONE); + while w == ark_bn254::Fq12::ONE { + // choose z which is 3-th non-residue + let mut legendre = ark_bn254::Fq12::ONE; + while legendre == ark_bn254::Fq12::ONE { + z = ark_bn254::Fq12::rand(&mut prng); + legendre = z.pow(&*COFACTOR_CUBIC.to_u64_digits()); + } + // obtain w which is t-th power of z + w = z.pow(&*T.to_u64_digits()); + } + w + }; + // make sure 27-th root w, is 3-th non-residue and r-th residue + log_assert_ne!(w.pow(&*COFACTOR_CUBIC.to_u64_digits()), ark_bn254::Fq12::ONE); + log_assert_eq!(w.pow(&*H.to_u64_digits()), ark_bn254::Fq12::ONE); + w +}); diff --git a/bitvm/src/groth16/offchain_checker.rs b/bitvm/src/groth16/offchain_checker.rs index fd288a486..859096fc3 100644 --- a/bitvm/src/groth16/offchain_checker.rs +++ b/bitvm/src/groth16/offchain_checker.rs @@ -1,15 +1,8 @@ #![allow(non_snake_case)] -use crate::bn254::fp254impl::Fp254Impl; -use crate::bn254::fq::Fq; - -use crate::groth16::constants::LAMBDA; -use ark_ff::UniformRand; +use crate::groth16::constants::{COFACTOR_CUBIC, H, K, LAMBDA, MM, R, S, T, W}; use ark_ff::{Field, One}; use num_bigint::BigUint; -use num_traits::{Num, ToPrimitive}; -use rand::SeedableRng; -use rand_chacha::ChaCha20Rng; -use std::str::FromStr; +use num_traits::ToPrimitive; #[macro_export] macro_rules! log_assert_eq { @@ -99,78 +92,43 @@ fn tonelli_shanks_cubic( // Finding C // refer from Algorithm 5 of "On Proving Pairings"(https://eprint.iacr.org/2024/640.pdf) pub fn compute_c_wi(f: ark_bn254::Fq12) -> (ark_bn254::Fq12, ark_bn254::Fq12) { - let p = BigUint::from_str_radix(Fq::MODULUS, 16).unwrap(); - let r = BigUint::from_str( - "21888242871839275222246405745257275088548364400416034343698204186575808495617", - ) - .unwrap(); - let s = 3_u32; - let exp = p.pow(12_u32) - 1_u32; - let h = &exp / &r; - let t = &exp / 3_u32.pow(s); - let k = (&t + 1_u32) / 3_u32; - let m = &*LAMBDA / &r; - let d = 3_u32; - let mm = &m / d; - - let mut prng = ChaCha20Rng::seed_from_u64(0); - let cofactor_cubic = 3_u32.pow(s - 1) * &t; - // make sure f is r-th residue - log_assert_eq!(f.pow(h.to_u64_digits()), ark_bn254::Fq12::ONE); + log_assert_eq!(f.pow(&*H.to_u64_digits()), ark_bn254::Fq12::ONE); - // sample a proper scalar w which is cubic non-residue - let w = { - let (mut w, mut z) = (ark_bn254::Fq12::ONE, ark_bn254::Fq12::ONE); - while w == ark_bn254::Fq12::ONE { - // choose z which is 3-th non-residue - let mut legendre = ark_bn254::Fq12::ONE; - while legendre == ark_bn254::Fq12::ONE { - z = ark_bn254::Fq12::rand(&mut prng); - legendre = z.pow(cofactor_cubic.to_u64_digits()); - } - // obtain w which is t-th power of z - w = z.pow(t.to_u64_digits()); - } - w - }; - // make sure 27-th root w, is 3-th non-residue and r-th residue - log_assert_ne!(w.pow(cofactor_cubic.to_u64_digits()), ark_bn254::Fq12::ONE); - log_assert_eq!(w.pow(h.to_u64_digits()), ark_bn254::Fq12::ONE); + let w = *W; // options for wi are 1, w, w^2 let mut wi = ark_bn254::Fq12::ONE; - if (f * wi).pow(cofactor_cubic.to_u64_digits()) != ark_bn254::Fq12::ONE { + if (f * wi).pow(&*COFACTOR_CUBIC.to_u64_digits()) != ark_bn254::Fq12::ONE { wi *= w; - if (f * wi).pow(cofactor_cubic.to_u64_digits()) != ark_bn254::Fq12::ONE { + if (f * wi).pow(&*COFACTOR_CUBIC.to_u64_digits()) != ark_bn254::Fq12::ONE { wi *= w; log_assert_eq!( - (f * wi).pow(cofactor_cubic.to_u64_digits()), + (f * wi).pow(&*COFACTOR_CUBIC.to_u64_digits()), ark_bn254::Fq12::ONE ); } } - log_assert_eq!(wi.pow(h.to_u64_digits()), ark_bn254::Fq12::ONE); + log_assert_eq!(wi.pow(&*H.to_u64_digits()), ark_bn254::Fq12::ONE); - log_assert_eq!(LAMBDA.clone(), d * &mm * &r); // f1 is scaled f let f1 = f * wi; // r-th root of f1, say f2 - let r_inv = r.modinv(&h).unwrap(); + let r_inv = R.modinv(&*H).unwrap(); log_assert_ne!(r_inv, BigUint::one()); let f2 = f1.pow(r_inv.to_u64_digits()); log_assert_ne!(f2, ark_bn254::Fq12::ONE); // m'-th root of f, say f3 - let mm_inv = mm.modinv(&(r * h)).unwrap(); + let mm_inv = MM.modinv(&(&*R * &*H)).unwrap(); log_assert_ne!(mm_inv, BigUint::one()); let f3 = f2.pow(mm_inv.to_u64_digits()); - log_assert_eq!(f3.pow(cofactor_cubic.to_u64_digits()), ark_bn254::Fq12::ONE); + log_assert_eq!(f3.pow(&*COFACTOR_CUBIC.to_u64_digits()), ark_bn254::Fq12::ONE); log_assert_ne!(f3, ark_bn254::Fq12::ONE); // d-th (cubic) root, say c - let c = tonelli_shanks_cubic(f3, w, s, t, k); + let c = tonelli_shanks_cubic(f3, w, S, T.clone(), K.clone()); log_assert_ne!(c, ark_bn254::Fq12::ONE); log_assert_eq!(c.pow(LAMBDA.to_u64_digits()), f * wi); diff --git a/bitvm/src/groth16/verifier.rs b/bitvm/src/groth16/verifier.rs index 9314b193b..46e0cc0ce 100644 --- a/bitvm/src/groth16/verifier.rs +++ b/bitvm/src/groth16/verifier.rs @@ -7,7 +7,6 @@ use crate::bn254::msm::hinted_msm_with_constant_bases_affine; use crate::bn254::pairing::Pairing; use crate::bn254::utils::Hint; use crate::bn254::g1::hinted_from_eval_point; -use crate::groth16::constants::{LAMBDA, P_POW3}; use crate::groth16::offchain_checker::compute_c_wi; use crate::treepp::{script, Script}; use ark_bn254::{Bn254, G1Projective}; @@ -40,12 +39,6 @@ impl Verifier { hinted_msm_with_constant_bases_affine(&vk.gamma_abc_g1, &scalars); hints.extend(hint_msm); - let (exp, sign) = if LAMBDA.gt(&P_POW3) { - (&*LAMBDA - &*P_POW3, true) - } else { - (&*P_POW3 - &*LAMBDA, false) - }; - // G1/G2 points for pairings let (p1, p2, p3, p4) = (msm_g1.into_affine(), proof.c, vk.alpha_g1, proof.a); let (q1, q2, q3, q4) = ( @@ -60,12 +53,6 @@ impl Verifier { let f = Bn254::multi_miller_loop_affine([p1, p2, p3, p4], [q1, q2, q3, q4]).0; let (c, wi) = compute_c_wi(f); let c_inv = c.inverse().unwrap(); - let hint = if sign { - f * wi * (c_inv.pow((exp).to_u64_digits())) - } else { - f * wi * (c_inv.pow((exp).to_u64_digits()).inverse().unwrap()) - }; - assert_eq!(hint, c.pow(P_POW3.to_u64_digits()), "hint isn't correct!"); let q_prepared = [G2Prepared::from_affine(q1), G2Prepared::from_affine(q2), @@ -88,55 +75,51 @@ impl Verifier { q4, ); - let script_lines = [ + let script = script! { // constants - constants(), + { constants() } // variant of p1, say -p1.x / p1.y, 1 / p1.y - hinted_msm, - hinted_script1, // Fq::inv(), - Fq::copy(0), - Fq::roll(2), - Fq::neg(0), - hinted_script2, // Fq::mul() - Fq::roll(1), + { hinted_msm } + { hinted_script1 } // Fq::inv(), + { Fq::copy(0) } + { Fq::roll(2) } + { Fq::neg(0) } + { hinted_script2 } // Fq::mul() + { Fq::roll(1) } // variants of G1 points - {Fq::push(p2.y.inverse().unwrap())}, - {Fq::push(p2.x)}, - {Fq::push(p2.y)}, - hinted_script3, // utils::from_eval_point(p2), - {Fq::push(p3.y.inverse().unwrap())}, - {Fq::push(p3.x)}, - {Fq::push(p3.y)}, - hinted_script4, // utils::from_eval_point(p3), - {Fq::push(p4.y.inverse().unwrap())}, - {Fq::push(p4.x)}, - {Fq::push(p4.y)}, - hinted_script5, // utils::from_eval_point(p4), + { Fq::push(p2.y.inverse().unwrap()) } + { Fq::push(p2.x) } + { Fq::push(p2.y) } + { hinted_script3 } // utils::from_eval_point(p2), + { Fq::push(p3.y.inverse().unwrap()) } + { Fq::push(p3.x) } + { Fq::push(p3.y) } + { hinted_script4 } // utils::from_eval_point(p3), + { Fq::push(p4.y.inverse().unwrap()) } + { Fq::push(p4.x) } + { Fq::push(p4.y) } + { hinted_script5 } // utils::from_eval_point(p4), // the only non-fixed G2 point, say q4 - Fq2::push(q4.x), - Fq2::push(q4.y), + { Fq2::push(q4.x) } + { Fq2::push(q4.y) } // proofs for verifying final exp - Fq12::push(c), - Fq12::push(c_inv), - Fq12::push(wi), + { Fq12::push(c) } + { Fq12::push(c_inv) } + { Fq12::push(wi) } // accumulator of q4, say t4 - Fq2::push(t4.x), - Fq2::push(t4.y), + { Fq2::push(t4.x) } + { Fq2::push(t4.y) } // stack: [beta_12, beta_13, beta_22, P1, P2, P3, P4, Q4, c, c_inv, wi, T4] // 3. verify pairing // Input stack: [beta_12, beta_13, beta_22, P1, P2, P3, P4, Q4, c, c_inv, wi, T4] // Output stack: [final_f] - hinted_script6, // Pairing::quad_miller_loop_with_c_wi(q_prepared.to_vec()), + { hinted_script6 } // Pairing::quad_miller_loop_with_c_wi(q_prepared.to_vec()), // check final_f == hint - Fq12::push(ark_bn254::Fq12::ONE), - Fq12::equalverify(), - script! {OP_TRUE}, - ]; - let mut script = script! {}; - for script_line in script_lines { - script = script.push_script(script_line.compile()); - } + { Fq12::push(ark_bn254::Fq12::ONE) } + { Fq12::equalverify() } + OP_TRUE + }; hints.extend(hint1); hints.extend(hint2); diff --git a/bitvm/src/signatures/winternitz.rs b/bitvm/src/signatures/winternitz.rs index fc042758a..d8da5024e 100644 --- a/bitvm/src/signatures/winternitz.rs +++ b/bitvm/src/signatures/winternitz.rs @@ -785,12 +785,14 @@ mod test { // check signature { winternitz_verifier.checksig_verify(&ps, &public_key) } - + // convert to number { digits_to_number::<8, 4>() } - - // { message } + + { message } + OP_EQUAL + }; let result = execute_script(s);