Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: Params and pihash bug #3

Merged
merged 7 commits into from
Mar 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 9 additions & 9 deletions bus-mapping/src/circuit_input_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -715,6 +715,15 @@ impl CircuitInputBuilder {
/// block.
pub fn keccak_inputs(block: &Block, code_db: &CodeDB) -> Result<Vec<Vec<u8>>, Error> {
let mut keccak_inputs = Vec::new();
// PI circuit
keccak_inputs.extend(keccak_inputs_pi_circuit(
block.chain_id,
block.start_l1_queue_index,
block.prev_state_root,
block.withdraw_root,
&block.headers,
block.txs(),
));
// Tx Circuit
let txs: Vec<geth_types::Transaction> = block.txs.iter().map(|tx| tx.into()).collect();
keccak_inputs.extend_from_slice(&keccak_inputs_tx_circuit(&txs)?);
Expand All @@ -730,15 +739,6 @@ pub fn keccak_inputs(block: &Block, code_db: &CodeDB) -> Result<Vec<Vec<u8>>, Er
"keccak total len after ecrecover: {}",
keccak_inputs.iter().map(|i| i.len()).sum::<usize>()
);
// PI circuit
keccak_inputs.extend(keccak_inputs_pi_circuit(
block.chain_id,
block.start_l1_queue_index,
block.prev_state_root,
block.withdraw_root,
&block.headers,
block.txs(),
));
// Bytecode Circuit
for _bytecode in code_db.0.values() {
// keccak_inputs.push(bytecode.clone());
Expand Down
1 change: 1 addition & 0 deletions prover/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ zkevm-circuits = { path = "../zkevm-circuits", default-features = false }

snark-verifier = { git = "https://github.com/scroll-tech/snark-verifier", tag = "v0.1.5" }
snark-verifier-sdk = { git = "https://github.com/scroll-tech/snark-verifier", tag = "v0.1.5", default-features=false, features = ["loader_halo2", "loader_evm", "halo2-pse"] }
bls12_381 = { git = "https://github.com/morph-l2/bls12_381.git", branch = "eip4844" }

anyhow = "1.0"
base64 = "0.13.0"
Expand Down
2 changes: 1 addition & 1 deletion prover/src/common/prover/inner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ impl Prover {

Self::assert_if_mock_prover(id, degree, &circuit);

let (params, pk) = self.params_and_pk(id, degree, &circuit)?;
let (params, pk) = self.params_and_pk(id, degree, &C::dummy_inner_circuit())?;
let snark = gen_snark_shplonk(params, pk, circuit, &mut rng, None::<String>);

Ok(snark)
Expand Down
2 changes: 1 addition & 1 deletion prover/src/common/prover/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use halo2_proofs::{dev::MockProver, halo2curves::bn256::Fr};
use once_cell::sync::Lazy;
use snark_verifier_sdk::CircuitExt;

pub static MOCK_PROVE: Lazy<bool> = Lazy::new(|| read_env_var("MOCK_PROVE", false));
pub static MOCK_PROVE: Lazy<bool> = Lazy::new(|| read_env_var("MOCK_PROVE", true));

impl Prover {
pub fn assert_if_mock_prover<C: CircuitExt<Fr>>(id: &str, degree: u32, circuit: &C) {
Expand Down
15 changes: 14 additions & 1 deletion prover/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::{
};
use anyhow::{bail, Result};
use chrono::Utc;
use eth_types::{l2_types::BlockTrace, Address, U256};
use eth_types::{l2_types::BlockTrace, Address, U256, ToLittleEndian};
use git_version::git_version;
use halo2_proofs::{
halo2curves::bn256::{Bn256, Fr}, plonk::Challenge, poly::kzg::commitment::ParamsKZG, SerdeFormat
Expand All @@ -27,6 +27,8 @@ use std::{
sync::Once,
};
use zkevm_circuits::evm_circuit::witness::Block;
use bls12_381::{Scalar as Fp};
use snark_verifier::loader::halo2::halo2_ecc::halo2_base::utils::{decompose_biguint, fe_to_biguint};

pub static LOGGER: Once = Once::new();

Expand Down Expand Up @@ -177,6 +179,17 @@ pub fn chunk_trace_to_witness_block_with_index(mut chunk_trace: Vec<BlockTrace>,
}
}

pub fn decompose_cp_result(block: &Block<Fr>) -> Vec<[u8; 32]>{
let cp_fe = Fp::from_bytes(&block.challenge_point.clone().to_le_bytes()).unwrap();
let cp = decompose_biguint::<Fr>(&fe_to_biguint(&cp_fe), 3, 88);
let mut preimage = cp.iter().map(|x| {let mut be_bytes = x.to_bytes(); be_bytes.reverse(); be_bytes}).collect::<Vec<_>>();
let pr_fe = Fp::from_bytes(&block.partial_result.clone().to_le_bytes()).unwrap();
let re = decompose_biguint::<Fr>(&fe_to_biguint(&pr_fe), 3, 88);
let mut re_preimage = re.iter().map(|x| {let mut be_bytes = x.to_bytes(); be_bytes.reverse(); be_bytes}).collect::<Vec<_>>();
preimage.append(&mut re_preimage);
preimage
}

// Return the output dir.
pub fn init_env_and_log(id: &str) -> String {
dotenvy::dotenv().ok();
Expand Down
2 changes: 1 addition & 1 deletion prover/src/zkevm/circuit/super_circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,6 @@ impl TargetCircuit for SuperCircuit {
}

fn public_input_len() -> usize {
2
1
}
}
18 changes: 16 additions & 2 deletions prover/src/zkevm/prover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::{
config::{LayerId, ZKEVM_DEGREES},
consts::CHUNK_VK_FILENAME,
io::try_to_read,
utils::{chunk_trace_to_witness_block, chunk_trace_to_witness_block_with_index},
utils::{chunk_trace_to_witness_block, chunk_trace_to_witness_block_with_index, decompose_cp_result},
ChunkProof,
};
use aggregator::ChunkHash;
Expand Down Expand Up @@ -103,13 +103,27 @@ impl Prover {
) -> Result<ChunkProof> {
assert!(!chunk_trace.is_empty());

let witness_block = chunk_trace_to_witness_block_with_index(
let mut witness_block = chunk_trace_to_witness_block_with_index(
chunk_trace,
batch_commit,
challenge_point,
index,
partial_result,
)?;

//add pihash preimage
let blob_cp_result = decompose_cp_result(&witness_block);

//index 0: data_bytes index 1: pi_bytes
witness_block.keccak_inputs[1].extend_from_slice(&blob_cp_result[0]);
witness_block.keccak_inputs[1].extend_from_slice(&blob_cp_result[1]);
witness_block.keccak_inputs[1].extend_from_slice(&blob_cp_result[2]);
witness_block.keccak_inputs[1].extend_from_slice(&blob_cp_result[3]);
witness_block.keccak_inputs[1].extend_from_slice(&blob_cp_result[4]);
witness_block.keccak_inputs[1].extend_from_slice(&blob_cp_result[5]);

log::trace!("kecck_inputs for pi:{:?}", witness_block.keccak_inputs[1]);

log::info!("Got witness block");

let name = name.map_or_else(
Expand Down
65 changes: 40 additions & 25 deletions zkevm-circuits/src/blob_circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,14 +224,26 @@ impl<F: Field> BlobCircuit<F>{
//load challenge_point to fp_chip
let challenge_point_fp = load_private(fp_chip, ctx, Value::known(self.challenge_point));

let blob = self

let mut blob = (0..self.index)
.map(|_| load_private(fp_chip, ctx, Value::known(Fp::from(0))))
.collect::<Vec<_>>();


let real_blob = self
.partial_blob
.iter()
.map(|x| load_private(fp_chip, ctx, Value::known(*x)))
.collect::<Vec<_>>();

blob.extend_from_slice(&real_blob);

while blob.len() < 4096 {
blob.push(load_private(fp_chip, ctx, Value::known(Fp::from(0))));
}

let partial_blob_len = blob.len();
log::trace!("partial blob len{}", partial_blob_len);
log::trace!("partial blob len {}", partial_blob_len);
// === STEP 2: compute the barycentric formula ===
// spec reference:
// https://github.com/ethereum/consensus-specs/blob/dev/specs/deneb/polynomial-commitments.md
Expand Down Expand Up @@ -280,12 +292,12 @@ impl<F: Field> BlobCircuit<F>{


for i in 0..partial_blob_len as usize {
let numinator_i = fp_chip.mul(ctx, &roots_of_unity_brp[i + self.index].clone(), &blob[i].clone());
let numinator_i = fp_chip.mul(ctx, &roots_of_unity_brp[i].clone(), &blob[i].clone());

let denominator_i_no_carry = fp_chip.sub_no_carry(
ctx,
&challenge_point_fp.clone(),
&roots_of_unity_brp[i + self.index].clone(),
&roots_of_unity_brp[i].clone(),
);
let denominator_i = fp_chip.carry_mod(ctx, &denominator_i_no_carry);
// avoid division by zero
Expand Down Expand Up @@ -328,26 +340,26 @@ impl<F: Field> BlobCircuit<F>{
// if challenge_point is a root of unity((0..self.index)or((self.index + partial_blob_len)..BLOB_WIDTH), then result = 0
// else result = barycentric_evaluation
// (0..self.index).chain((self.index + partial_blob_len)..BLOB_WIDTH)
for i in (0..self.index).chain((self.index + partial_blob_len)..BLOB_WIDTH) {
let denominator_i_no_carry = fp_chip.sub_no_carry(
ctx,
&challenge_point_fp.clone(),
&roots_of_unity_brp[i].clone(),
);
let denominator_i = fp_chip.carry_mod(ctx, &denominator_i_no_carry);
// avoid division by zero
// safe_denominator_i = denominator_i (denominator_i != 0)
// safe_denominator_i = 1 (denominator_i == 0)
let is_zero_denominator_i = fp_is_zero(ctx, &gate, &denominator_i);
let is_zero_denominator_i =
cross_field_load_private(ctx, &fp_chip, &fp_chip.range, &is_zero_denominator_i, &zero);
// update `cp_is_not_root_of_unity`
// cp_is_not_root_of_unity = 1 (initialize)
// cp_is_not_root_of_unity = 0 (denominator_i == 0)
let non_zero_denominator_i =
fp_chip.sub_no_carry(ctx, &one_fp.clone(), &is_zero_denominator_i.clone());
cp_is_not_root_of_unity = fp_chip.mul(ctx, &cp_is_not_root_of_unity, &non_zero_denominator_i);
}
// for i in (0..self.index).chain((self.index + partial_blob_len)..BLOB_WIDTH) {
// let denominator_i_no_carry = fp_chip.sub_no_carry(
// ctx,
// &challenge_point_fp.clone(),
// &roots_of_unity_brp[i].clone(),
// );
// let denominator_i = fp_chip.carry_mod(ctx, &denominator_i_no_carry);
// // avoid division by zero
// // safe_denominator_i = denominator_i (denominator_i != 0)
// // safe_denominator_i = 1 (denominator_i == 0)
// let is_zero_denominator_i = fp_is_zero(ctx, &gate, &denominator_i);
// let is_zero_denominator_i =
// cross_field_load_private(ctx, &fp_chip, &fp_chip.range, &is_zero_denominator_i, &zero);
// // update `cp_is_not_root_of_unity`
// // cp_is_not_root_of_unity = 1 (initialize)
// // cp_is_not_root_of_unity = 0 (denominator_i == 0)
// let non_zero_denominator_i =
// fp_chip.sub_no_carry(ctx, &one_fp.clone(), &is_zero_denominator_i.clone());
// cp_is_not_root_of_unity = fp_chip.mul(ctx, &cp_is_not_root_of_unity, &non_zero_denominator_i);
// }

let select_evaluation = fp_chip.mul(ctx, &barycentric_evaluation, &cp_is_not_root_of_unity);
let tmp_result = fp_chip.add_no_carry(ctx, &result, &select_evaluation);
Expand Down Expand Up @@ -440,7 +452,6 @@ impl<F: Field> SubCircuit<F> for BlobCircuit<F>{
result
},
)?;
let randomness = _challenges.evm_word();

self.exports.borrow_mut().replace(export);

Expand All @@ -455,6 +466,10 @@ impl<F: Field> SubCircuit<F> for BlobCircuit<F>{
const MAX_BLOB_DATA_SIZE: usize = 4096 * 31 - 4;

pub fn block_to_blob<F: Field>(block: &Block<F>) -> Result<Vec<u8>, String> {
if block.txs.len() == 0 {
let zero_blob: Vec<u8> = vec![0; 32 * 4096];
return Ok(zero_blob);
}
// get data from block.txs.rlp_signed
let data: Vec<u8> = block
.txs
Expand Down
18 changes: 15 additions & 3 deletions zkevm-circuits/src/blob_circuit/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,16 +69,16 @@ fn test_partial_blob_consistency(){

log::trace!("blob:{:?}", blob);

let index = 0;
let index = 50;
let omega = Fp::from(123).pow(&[(FP_S - 12) as u64, 0, 0, 0]);
let roots_of_unity: Vec<_> = (0..4096)
.map(|i| omega.pow(&[i as u64, 0, 0, 0]))
.collect();
let roots_of_unity_brp = bit_reversal_permutation(roots_of_unity);

//let challenge_point = roots_of_unity_brp[0];
let challenge_point = roots_of_unity_brp[0];
//let challenge_point = Fp::random(OsRng);
let challenge_point = Fp::from(128);
// let challenge_point = Fp::from(128);

let result = poly_eval_partial(blob.clone(), challenge_point, omega, index);

Expand All @@ -105,5 +105,17 @@ fn test_partial_blob_consistency(){
assert_eq!(prover.verify(), Ok(()));
}

#[test]
fn test_zero_blob(){
let blob: Vec<u8> = vec![0; 32 * 4096];
let mut result: Vec<Fp> = Vec::new();
for chunk in blob.chunks(32) {
let reverse: Vec<u8> = chunk.iter().rev().cloned().collect();
result.push(Fp::from_bytes(reverse.as_slice().try_into().unwrap()).unwrap());
}


log::trace!("partial blob: {:?} len: {:?}", result, result.len());
}


11 changes: 11 additions & 0 deletions zkevm-circuits/src/pi_circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,8 +240,13 @@ impl PublicData {
);

let pi_bytes = self.pi_bytes(data_hash);

log::trace!("pi bytes:{:?}", pi_bytes);

let pi_hash = keccak256(pi_bytes);

log::trace!("pi hash:{:?}", pi_hash);

H256(pi_hash)
}

Expand Down Expand Up @@ -1020,6 +1025,12 @@ impl<F: Field> PiCircuitConfig<F> {
y_limb2: blob_cells[4].clone(),
y_limb3: blob_cells[5].clone(),
};
log::trace!("[pi circuit rlc]connect blob:{:?}", connections.x_limb1.value());
log::trace!("[pi circuit rlc]connect blob:{:?}", connections.x_limb2.value());
log::trace!("[pi circuit rlc]connect blob:{:?}", connections.x_limb3.value());
log::trace!("[pi circuit rlc]connect blob:{:?}", connections.y_limb1.value());
log::trace!("[pi circuit rlc]connect blob:{:?}", connections.y_limb2.value());
log::trace!("[pi circuit rlc]connect blob:{:?}", connections.y_limb3.value());

for i in pi_bytes_start_row..pi_bytes_end_row {
self.q_not_end.enable(region, i)?;
Expand Down
1 change: 1 addition & 0 deletions zkevm-circuits/src/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1361,6 +1361,7 @@ impl KeccakTable {
challenge,
)
});
log::trace!("input_rlc:{:?} output_rlc:{:?}", input_rlc, output_rlc);
vec![[
Value::known(F::one()),
input_rlc,
Expand Down
Loading