Skip to content
Prev Previous commit
Next Next commit
stash code
  • Loading branch information
Ubuntu
Ubuntu committed Oct 5, 2025
commit 2835c5a8fbf98681c661a404d7a3626e64b2a38c
16 changes: 16 additions & 0 deletions bitvm/src/bigint/cmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,22 @@ impl<const N_BITS: u32, const LIMB_SIZE: u32> BigIntImpl<N_BITS, LIMB_SIZE> {
}
}

pub fn equal_keep_elements(a: u32, b: u32) -> Script {
script! {
{ Self::copy_zip(a, b) }
for _ in 0..Self::N_LIMBS {
OP_EQUAL
OP_TOALTSTACK
}
for _ in 0..Self::N_LIMBS {
OP_FROMALTSTACK
}
for _ in 0..Self::N_LIMBS - 1 {
OP_BOOLAND
}
}
}

pub fn notequal(a: u32, b: u32) -> Script {
script! {
{ Self::equal(a, b) }
Expand Down
5 changes: 5 additions & 0 deletions bitvm/src/bn254/fp254impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,11 @@ pub trait Fp254Impl {
U254::equal(a, b)
}

#[inline]
fn equal_keep_elements(a: u32, b: u32) -> Script {
U254::equal_keep_elements(a, b)
}

#[inline]
fn equalverify(a: u32, b: u32) -> Script {
U254::equalverify(a, b)
Expand Down
84 changes: 60 additions & 24 deletions bitvm/src/bn254/g1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,21 +186,25 @@ impl G1Affine {
pub fn hinted_check_add(t: ark_bn254::G1Affine, q: ark_bn254::G1Affine) -> (Script, Vec<Hint>) {
let mut hints = vec![];

println!("calcating alpha and bias, {:?} {:?}", t, q);
let (alpha, bias) = if !t.is_zero() && !q.is_zero() && t != q {
let (alpha, bias) = if t == q && !t.is_zero() {
let alpha = (t.x.square() + t.x.square() + t.x.square()) / (t.y + t.y);
let bias = t.y - alpha * t.x;
(alpha, bias)
} else if t == -q {
(ark_bn254::Fq::ZERO, ark_bn254::Fq::ZERO)
} else if !t.is_zero() && !q.is_zero() {
let alpha = (t.y - q.y) / (t.x - q.x);
let bias = t.y - alpha * t.x;
(alpha, bias)
} else {
(ark_bn254::Fq::ZERO, ark_bn254::Fq::ZERO)
};

println!("calcating hinted chord_line");
let (hinted_script1, hint1) = Self::hinted_check_chord_line(t, q, alpha);
// println!("calcating hinted add: {:?}, {:?}", hinted_script1, hint1);
let (hinted_script2, hint2) = Self::hinted_add(t.x, q.x, alpha);
let (hinted_script3, hint3) = Self::hinted_check_tangent_line(t, alpha);

let script = script! { // tx ty qx qy
let script = script! { // tx ty qx qy
{ G1Affine::is_zero_keep_element() }
OP_IF
{ G1Affine::drop() }
Expand All @@ -209,29 +213,61 @@ impl G1Affine {
{ G1Affine::is_zero_keep_element() }
OP_IF
{ G1Affine::drop() }
OP_ELSE // qx qy tx ty
for _ in 0..Fq::N_LIMBS {
OP_DEPTH OP_1SUB OP_ROLL
}
for _ in 0..Fq::N_LIMBS {
OP_DEPTH OP_1SUB OP_ROLL
} // qx qy tx ty c3 c4
{ Fq::copy(1) }
{ Fq::copy(1) } // qx qy tx ty c3 c4 c3 c4
{ Fq::copy(5) }
{ Fq::roll(5) } // qx qy tx c3 c4 c3 c4 tx ty
{ Fq::copy(8) }
{ Fq::roll(8) } // qx tx c3 c4 c3 c4 tx ty qx qy
{ hinted_script1 } // qx tx c3 c4 0/1
OP_VERIFY
{ Fq::roll(2) }
{ Fq::roll(3) } // c3 c4 tx qx
{ hinted_script2 } // x' y'
OP_ELSE // qx qy tx ty
{ Fq::equal_keep_elements(3, 1) } // t == q or t == -q
OP_DUP
OP_TOALTSTACK
OP_TOALTSTACK
{ Fq::equal_keep_elements(2, 0) }
OP_NOT
OP_FROMALTSTACK
OP_BOOLAND
OP_IF // case: t == -q
OP_FROMALTSTACK OP_DROP
{ G1Affine::drop() }
{ G1Affine::drop() }
{ G1Affine::push_zero() }
OP_ELSE // case: t != -q
for _ in 0..Fq::N_LIMBS {
OP_DEPTH OP_1SUB OP_ROLL
}
// TODO: uncomment out this line after 3.4 { Fq::copy(0) } { Fq::check_validity() }
for _ in 0..Fq::N_LIMBS {
OP_DEPTH OP_1SUB OP_ROLL
} // qx qy tx ty c3 c4
// TODO: uncomment out this line after 3.4 { Fq::copy(0) } { Fq::check_validity() }
{ Fq::copy(1) } // qx qy tx ty c3 c4 c3
{ Fq::copy(1) } // qx qy tx ty c3 c4 c3 c4
{ Fq::copy(5) } // qx qy tx ty c3 c4 c3 c4 tx
{ Fq::roll(5) } // qx qy tx c3 c4 c3 c4 tx ty
OP_FROMALTSTACK
OP_IF // case: t == q
{ hinted_script3 } // qx qy tx c3 c4 is_tangent_line_correct
OP_VERIFY // qx qy tx c3 c4
{ Fq::roll(3) } // qx tx c3 c4 qy
{ Fq::drop() } // qx tx c3 c4
OP_ELSE // case: general case
{ Fq::copy(8) } // qx qy tx c3 c4 c3 c4 tx ty qx
{ Fq::roll(8) } // qx tx c3 c4 c3 c4 tx ty qx qy
{ hinted_script1 } // qx tx c3 c4 0/1
OP_VERIFY // qx tx c3 c4
OP_ENDIF
{ Fq::roll(2) } // qx c3 c4 tx
{ Fq::roll(3) } // c3 c4 tx qx
{ hinted_script2 } // x' y'
OP_ENDIF
OP_ENDIF
OP_ENDIF
};

if !t.is_zero() && !q.is_zero() {
if t == q && !t.is_zero() {
hints.push(Hint::Fq(alpha));
hints.push(Hint::Fq(-bias));
hints.extend(hint3);
hints.extend(hint2);
} else if t == -q {
// no hint
} else if !t.is_zero() && !q.is_zero() {
hints.push(Hint::Fq(alpha));
hints.push(Hint::Fq(-bias));
hints.extend(hint1);
Expand Down
8 changes: 0 additions & 8 deletions bitvm/src/chunk/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -598,7 +598,6 @@ mod test {
}

#[test]
#[ignore]
fn full_e2e_exec_invalid_proof() {
let vk_bytes = crate::chunk::api_runtime_utils::test::VK_BYTES.to_vec();
let proof_bytes: Vec<u8> = crate::chunk::api_runtime_utils::test::PROOF_BYTES.to_vec();
Expand Down Expand Up @@ -686,7 +685,6 @@ mod test {

// Step 1: Anyone can Generate Operation (mul & hash) part of tapscript: same for all vks
#[test]
#[ignore]
fn test_fn_compile() {
let vk_bytes = crate::chunk::api_runtime_utils::test::VK_BYTES.to_vec();
let mock_vk: ark_groth16::VerifyingKey<Bn254> =
Expand All @@ -707,7 +705,6 @@ mod test {
// Step 2: Operator Generates keypairs and broadcasts pubkeys for a Bitvm setup;
// Anyone can create Bitcomm part of tapscript; yields complete tapscript
#[test]
#[ignore]
fn test_fn_generate_tapscripts() {
println!("start");
let vk_bytes = crate::chunk::api_runtime_utils::test::VK_BYTES.to_vec();
Expand Down Expand Up @@ -749,7 +746,6 @@ mod test {
// Step 3: Operator Generates Assertions, Signs it and submit on chain

#[test]
#[ignore]
fn test_fn_generate_assertions() {
let vk_bytes = crate::chunk::api_runtime_utils::test::VK_BYTES.to_vec();
let proof_bytes: Vec<u8> = crate::chunk::api_runtime_utils::test::PROOF_BYTES.to_vec();
Expand All @@ -763,7 +759,6 @@ mod test {

assert!(mock_vk.gamma_abc_g1.len() == NUM_PUBS + 1);
let proof_asserts = generate_assertions(proof, public_inputs.to_vec(), &mock_vk).unwrap();
println!("signed_asserts {:?}", proof_asserts);

std::fs::create_dir_all("bridge_data/chunker_data")
.expect("Failed to create directory structure");
Expand All @@ -774,7 +769,6 @@ mod test {

// Step 3: Operator Generates Assertions, Signs it and submit on chain
#[test]
#[ignore]
fn test_fn_generate_signatures() {
let vk_bytes = crate::chunk::api_runtime_utils::test::VK_BYTES.to_vec();
let proof_bytes: Vec<u8> = crate::chunk::api_runtime_utils::test::PROOF_BYTES.to_vec();
Expand Down Expand Up @@ -802,7 +796,6 @@ mod test {
}

#[test]
#[ignore]
fn test_fn_validate_assertions() {
let vk_bytes = crate::chunk::api_runtime_utils::test::VK_BYTES.to_vec();
let proof_bytes: Vec<u8> = crate::chunk::api_runtime_utils::test::PROOF_BYTES.to_vec();
Expand Down Expand Up @@ -848,7 +841,6 @@ mod test {

// Step 4: Challenger finds fault given signatures
#[test]
#[ignore]
fn test_fn_disprove_invalid_assertions() {
let vk_bytes = crate::chunk::api_runtime_utils::test::VK_BYTES.to_vec();
let proof_bytes: Vec<u8> = crate::chunk::api_runtime_utils::test::PROOF_BYTES.to_vec();
Expand Down
10 changes: 10 additions & 0 deletions bitvm/src/chunk/g16_runner_core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,16 +98,19 @@ pub(crate) fn groth16_generate_segments(
if $seg.scr_type.is_final_script() {
if let DataType::U256Data(felem) = $seg.result.0 {
if felem != ark_ff::BigInt::<4>::one() {
println!("Final validity check failed: {:?}", felem);
return false;
}
} else {
unreachable!();
}
} else if $seg.is_valid_input == false {
println!("Input validity check failed at segment id: {:?}", $seg.id);
return false;
} else {
let matches = compare(&$seg.result.0, claimed_assertions);
if matches.is_some() && matches.unwrap() == false {
println!("Output validity check failed at segment id: {:?}", $seg.id);
return false;
}
}
Expand All @@ -129,12 +132,15 @@ pub(crate) fn groth16_generate_segments(

let pub_scalars = pub_scalars.to_vec();

println!("wrap_hints_precompute_p for p4");
let p4 = wrap_hints_precompute_p(skip_evaluation, all_output_hints.len(), &gp4y, &gp4x);
push_compare_or_return!(p4);

println!("wrap_hints_precompute_p for p2");
let p2 = wrap_hints_precompute_p(skip_evaluation, all_output_hints.len(), &gp2y, &gp2x);
push_compare_or_return!(p2);

println!("wrapping msm");
let msms = wrap_hint_msm(
skip_evaluation,
all_output_hints.len(),
Expand All @@ -145,6 +151,7 @@ pub(crate) fn groth16_generate_segments(
push_compare_or_return!(msm);
}

println!("wrapping p_vk0");
let p_vk0 = wrap_hint_hash_p(
skip_evaluation,
all_output_hints.len(),
Expand All @@ -153,15 +160,18 @@ pub(crate) fn groth16_generate_segments(
);
push_compare_or_return!(p_vk0);

println!("wrapping p3");
let p3 = wrap_hints_precompute_p_from_hash(skip_evaluation, all_output_hints.len(), &p_vk0);
push_compare_or_return!(p3);

println!("wrapping c and c_inv");
let c = wrap_hint_hash_c(skip_evaluation, all_output_hints.len(), gc.clone());
push_compare_or_return!(c);

let gcinv = wrap_hint_hash_c_inv(skip_evaluation, all_output_hints.len(), gc);
push_compare_or_return!(gcinv);

println!("wrapping t4 init");
let mut t4 = wrap_hint_init_t4(
skip_evaluation,
all_output_hints.len(),
Expand Down
26 changes: 25 additions & 1 deletion bitvm/src/chunk/g16_runner_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use super::{
chunk_point_ops_and_multiply_line_evals_step_2,
},
};
use ark_ec::AffineRepr;
use ark_ff::Field;
use bitcoin::ScriptBuf;
use bitcoin_script::script;
Expand Down Expand Up @@ -390,6 +391,7 @@ pub(crate) fn wrap_hints_precompute_p(
(in_py.id, ElementType::FieldElem),
(in_px.id, ElementType::FieldElem),
];
println!("input_segment_info: {:?}", input_segment_info);

let (mut p3d, mut is_valid_input, mut scr, mut op_hints) = (
ark_bn254::G1Affine::identity().into(),
Expand All @@ -398,11 +400,21 @@ pub(crate) fn wrap_hints_precompute_p(
vec![],
);
// let mut tap_prex = script! {};
println!("segment id: {segment_id}, skip: {skip}");
if !skip {
let in_py = in_py.result.0.try_into().unwrap();
let in_px = in_px.result.0.try_into().unwrap();
println!("in px: {:?}, in py: {:?} ", in_px, in_py);
(p3d, is_valid_input, scr, op_hints) = chunk_precompute_p(in_py, in_px);
}
println!(
"ONE: {:?}, p3d: {:?}",
G1AffineIsomorphic::from(ark_bn254::G1Affine::new_unchecked(
ark_bn254::Fq::ONE,
ark_bn254::Fq::ONE
)),
p3d
);

Segment {
id: segment_id as u32,
Expand All @@ -428,16 +440,28 @@ pub(crate) fn wrap_hints_precompute_p_from_hash(
script! {},
vec![],
);
println!("segment id: {segment_id}, skip: {skip}");
if !skip {
let in_p: G1AffineIsomorphic = in_p.result.0.try_into().unwrap();

let ttt: ark_bn254::G1Affine = in_p.into();
println!("in_p: {:?}, ttt: {:?}", in_p, ttt);
(p3d, is_valid_input, scr, op_hints) = chunk_precompute_p_from_hash(in_p.into());
}
println!(
"ONE: {:?}, p3d: {:?}",
G1AffineIsomorphic::from(ark_bn254::G1Affine::new_unchecked(
ark_bn254::Fq::ONE,
ark_bn254::Fq::ONE
)),
p3d
);

Segment {
id: segment_id as u32,
is_valid_input,
parameter_ids: input_segment_info,
result: (DataType::G1Data(p3d.into()), ElementType::G1),
result: (DataType::G1Data(p3d), ElementType::G1),
hints: op_hints,
scr_type: ScriptType::PreMillerPrecomputePFromHash,
scr: scr.compile(),
Expand Down
15 changes: 11 additions & 4 deletions bitvm/src/chunk/taps_ext_miller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ pub(crate) fn chunk_precompute_p(
hints.extend_from_slice(&eval_hints);
G1AffineIsomorphic::from(p)
} else {
//mock_pd.into()
G1AffineIsomorphic::new(ark_bn254::Fq::ONE, ark_bn254::Fq::ONE)
};

Expand Down Expand Up @@ -687,11 +686,19 @@ mod test {
let p1 = ark_bn254::G1Affine::rand(&mut prng);
let p2 = ark_bn254::G1Affine::new_unchecked(ark_bn254::Fq::ONE, ark_bn254::Fq::ZERO);
let p3 = ark_bn254::G1Affine::new_unchecked(ark_bn254::Fq::ZERO, ark_bn254::Fq::ZERO);
let p4 = ark_bn254::G1Affine::new_unchecked(p1.x, p1.x);
let dataset = vec![(p1, false), (p2, true), (p3, true), (p4, true)];
let p4 = ark_bn254::G1Affine::new_unchecked(ark_bn254::Fq::ZERO, ark_bn254::Fq::ONE);
let p5 = ark_bn254::G1Affine::new_unchecked(ark_bn254::Fq::ONE, ark_bn254::Fq::ONE);
let p6 = ark_bn254::G1Affine::new_unchecked(p1.x, p1.x);
let dataset = vec![
(p1, false),
(p2, true),
(p3, true),
(p4, true),
(p5, true),
(p6, true),
];

for (p, disprovable) in dataset {
println!("p: {:?}, disprovable: {:?} ", p, disprovable);
let (hint_out, input_is_valid, tap_prex, hint_script) = chunk_precompute_p_from_hash(p);
assert_eq!(input_is_valid, !disprovable);
let hint_out = DataType::G1Data(hint_out);
Expand Down
4 changes: 3 additions & 1 deletion bitvm/src/chunk/taps_msm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,11 +138,13 @@ pub(crate) fn chunk_hash_p(
use ark_ec::AffineRepr;
// r (gp3) = t(msm) + q(vk0)
let (tx, qx, ty, qy) = (hint_in_t.x, hint_in_q.x, hint_in_t.y, hint_in_q.y);
println!("tx: {:?}, ty: {:?} ", tx, ty);
let t = if hint_in_t.is_zero() {
ark_bn254::G1Affine::zero()
} else {
ark_bn254::G1Affine::new(tx, ty)
ark_bn254::G1Affine::new_unchecked(tx, ty)
};
println!("qx: {:?}, qy: {:?} ", qx, qy);
let q = ark_bn254::G1Affine::new(qx, qy);
let (add_scr, add_hints) = G1Affine::hinted_check_add(t, q);
let r = (hint_in_t + hint_in_q).into_affine();
Expand Down