Skip to content

Commit

Permalink
Fill in prove_program_code
Browse files Browse the repository at this point in the history
  • Loading branch information
moodlezoup committed Dec 4, 2023
1 parent 34aeac3 commit a2e525d
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 72 deletions.
23 changes: 16 additions & 7 deletions jolt-core/src/jolt/trace/rv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ impl RVTraceRow {
// Assert instruction correctness if arithmetic
let lookups = self.to_jolt_instructions();
assert!(lookups.len() == 1);
if (lookups.len() == 1 && self.rd.unwrap() != 0) {
if lookups.len() == 1 && self.rd.unwrap() != 0 {
assert_eq!(lookups.len(), 1, "{self:?}");
let expected_result: Fr = lookups[0].lookup_entry(C, M);
let bigint = expected_result.into_bigint();
Expand Down Expand Up @@ -760,7 +760,7 @@ impl JoltProvableTrace for RVTraceRow {
fn sum_u64_i32(a: u64, b: i32) -> u64 {
if b.is_negative() {
let abs_b = b.abs() as u64;
if (a < abs_b) {
if a < abs_b {
panic!("overflow")
}
a - abs_b
Expand All @@ -774,6 +774,7 @@ fn sum_u64_i32(a: u64, b: i32) -> u64 {
#[cfg(test)]
mod tests {
use ark_curve25519::EdwardsProjective;
use itertools::Itertools;
use merlin::Transcript;

use crate::{jolt::vm::{instruction_lookups::InstructionLookupsProof, rv32i_vm::RV32IJoltVM, Jolt, read_write_memory::ReadWriteMemory}, utils::{gen_random_point, math::Math, random::RandomTape}, poly::structured_poly::BatchablePolynomials};
Expand Down Expand Up @@ -819,7 +820,7 @@ mod tests {
}

#[test]
fn load_conversion() {
fn load_trace() {
// 1. Load common::RVTraceRow from file
// 2. Convert via RVTraceRow::from_common
// 3. Run validation
Expand All @@ -831,21 +832,29 @@ mod tests {

let trace_location = JoltPaths::trace_path("fibonacci");
let loaded_trace: Vec<common::RVTraceRow> = Vec::<common::RVTraceRow>::deserialize_from_file(&trace_location).expect("deserialization failed");

let converted_trace: Vec<RVTraceRow> = loaded_trace.into_iter().map(|common| RVTraceRow::from_common(common)).collect();
let _: Vec<ELFRow> = converted_trace.iter().map(|row| row.to_pc_trace()).collect();

let mut num_errors = 0;
for row in &converted_trace {
if let Err(e) = row.validate() {
// if row.opcode != RV32IM::SLLI {
println!("Validation error: {} \n{:#?}\n\n", e, row);
// }
println!("Validation error: {} \n{:#?}\n\n", e, row);
num_errors += 1;
}
}
println!("Total errors: {num_errors}");
}

#[test]
fn load_bytecode() {
use common::serializable::Serializable;
use common::path::JoltPaths;

let bytecode_location = JoltPaths::bytecode_path("fibonacci");
let instructions = Vec::<common::ELFInstruction>::deserialize_from_file(&bytecode_location).expect("deserialization failed");
let _: Vec<ELFRow> = instructions.iter().map(|x| ELFRow::from(x)).collect();
}

#[test]
fn fib_e2e() {
use common::serializable::Serializable;
Expand Down
77 changes: 28 additions & 49 deletions jolt-core/src/jolt/vm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use ark_ff::PrimeField;
use ark_serialize::Read;
use merlin::Transcript;
use std::any::TypeId;
use std::marker::PhantomData;
use strum::{EnumCount, IntoEnumIterator};

use crate::lasso::{
Expand All @@ -18,6 +19,7 @@ use crate::poly::structured_poly::BatchablePolynomials;
use crate::utils::{errors::ProofVerifyError, random::RandomTape};

use self::instruction_lookups::{InstructionLookups, InstructionLookupsProof};
use self::pc::{ELFRow, PCInitFinalOpenings, PCPolys, PCReadWriteOpenings};
use self::read_write_memory::{
MemoryCommitment, MemoryInitFinalOpenings, MemoryOp, MemoryReadWriteOpenings, ReadWriteMemory,
};
Expand All @@ -26,7 +28,16 @@ pub trait Jolt<F: PrimeField, G: CurveGroup<ScalarField = F>, const C: usize, co
type InstructionSet: JoltInstruction + Opcode + IntoEnumIterator + EnumCount;
type Subtables: LassoSubtable<F> + IntoEnumIterator + EnumCount + From<TypeId> + Into<usize>;

fn prove() {
fn prove(program_path: &str) {
// let trace_location = JoltPaths::trace_path(program_path);
// let loaded_trace: Vec<common::RVTraceRow> =
// Vec::<common::RVTraceRow>::deserialize_from_file(&trace_location)
// .expect("deserialization failed");

// let converted_trace: Vec<RVTraceRow> = loaded_trace
// .into_iter()
// .map(|common| RVTraceRow::from_common(common))
// .collect();
// preprocess?
// emulate
// prove_program_code
Expand Down Expand Up @@ -57,55 +68,23 @@ pub trait Jolt<F: PrimeField, G: CurveGroup<ScalarField = F>, const C: usize, co
}

fn prove_program_code(
program_code: &[u64],
access_sequence: &[usize],
code_size: usize,
contiguous_reads_per_access: usize,
r_mem_check: &(F, F),
mut program: Vec<ELFRow>,
mut trace: Vec<ELFRow>,
transcript: &mut Transcript,
) {
// let (gamma, tau) = r_mem_check;
// let hash_func = |a: &F, v: &F, t: &F| -> F { *t * gamma.square() + *v * *gamma + *a - tau };

// let m: usize = (access_sequence.len() * contiguous_reads_per_access).next_power_of_two();
// // TODO(moodlezoup): resize access_sequence?

// let mut read_addrs: Vec<usize> = Vec::with_capacity(m);
// let mut final_cts: Vec<usize> = vec![0; code_size];
// let mut read_cts: Vec<usize> = Vec::with_capacity(m);
// let mut read_values: Vec<u64> = Vec::with_capacity(m);

// for (j, code_address) in access_sequence.iter().enumerate() {
// debug_assert!(code_address + contiguous_reads_per_access <= code_size);
// debug_assert!(code_address % contiguous_reads_per_access == 0);

// for offset in 0..contiguous_reads_per_access {
// let addr = code_address + offset;
// let counter = final_cts[addr];
// read_addrs.push(addr);
// read_values.push(program_code[addr]);
// read_cts.push(counter);
// final_cts[addr] = counter + 1;
// }
// }

// let E_poly: DensePolynomial<F> = DensePolynomial::from_u64(&read_values); // v_ops
// let dim: DensePolynomial<F> = DensePolynomial::from_usize(access_sequence); // a_ops
// let read_cts: DensePolynomial<F> = DensePolynomial::from_usize(&read_cts); // t_read
// let final_cts: DensePolynomial<F> = DensePolynomial::from_usize(&final_cts); // t_final
// let init_values: DensePolynomial<F> = DensePolynomial::from_u64(program_code); // v_mem

// let polys = PCPolys::new(dim, E_poly, init_values, read_cts, final_cts, 0);
// let (gens, commitments) = polys.commit::<G>();

todo!("decide how to represent nested proofs, gens, commitments");
// MemoryCheckingProof::<G, PCFingerprintProof<G>>::prove(
// &polys,
// r_fingerprints,
// &gens,
// &mut transcript,
// &mut random_tape,
// )
random_tape: &mut RandomTape<G>,
) -> MemoryCheckingProof<G, PCPolys<F, G>, PCReadWriteOpenings<F, G>, PCInitFinalOpenings<F, G>>
{
let polys: PCPolys<F, G> = PCPolys::new_program(program, trace);
let batched_polys = polys.batch();
let commitments = PCPolys::commit(&batched_polys);

polys.prove_memory_checking(
&polys,
&batched_polys,
&commitments,
transcript,
random_tape,
)
}

fn prove_memory(
Expand Down
43 changes: 27 additions & 16 deletions jolt-core/src/jolt/vm/pc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ use crate::{
utils::{errors::ProofVerifyError, is_power_of_two, random::RandomTape},
};

use common::ELFInstruction;

const ADDRESS_INCREMENT: usize = 1;

#[derive(Debug, Clone, PartialEq)]
Expand Down Expand Up @@ -52,6 +54,20 @@ impl ELFRow {
}
}

// TODO(JOLT-74): Consolidate ELFInstruction and ELFRow
impl From<&ELFInstruction> for ELFRow {
fn from(value: &ELFInstruction) -> Self {
Self::new(
value.address as usize,
value.opcode as u64,
value.rd.unwrap_or(0),
value.rs1.unwrap_or(0),
value.rs2.unwrap_or(0),
value.imm.unwrap_or(0) as u64, // imm is always cast to its 32-bit repr, signed or unsigned
)
}
}

pub struct FiveTuplePoly<F: PrimeField> {
opcode: DensePolynomial<F>,
rd: DensePolynomial<F>,
Expand Down Expand Up @@ -286,9 +302,7 @@ where
}
}

pub struct PCProof<F: PrimeField>(PhantomData<F>);

impl<F, G> MemoryCheckingProver<F, G, PCPolys<F, G>> for PCProof<F>
impl<F, G> MemoryCheckingProver<F, G, PCPolys<F, G>> for PCPolys<F, G>
where
F: PrimeField,
G: CurveGroup<ScalarField = F>,
Expand Down Expand Up @@ -419,7 +433,7 @@ where
}
}

impl<F, G> MemoryCheckingVerifier<F, G, PCPolys<F, G>> for PCProof<F>
impl<F, G> MemoryCheckingVerifier<F, G, PCPolys<F, G>> for PCPolys<F, G>
where
F: PrimeField,
G: CurveGroup<ScalarField = F>,
Expand Down Expand Up @@ -679,11 +693,10 @@ mod tests {
let polys: PCPolys<Fr, EdwardsProjective> = PCPolys::new_program(program, trace);

let (gamma, tau) = (&Fr::from(100), &Fr::from(35));
let pc_prover: PCProof<Fr> = PCProof(PhantomData::<_>);
let init_leaves: Vec<DensePolynomial<Fr>> = pc_prover.init_leaves(&polys, gamma, tau);
let read_leaves: Vec<DensePolynomial<Fr>> = pc_prover.read_leaves(&polys, gamma, tau);
let write_leaves: Vec<DensePolynomial<Fr>> = pc_prover.write_leaves(&polys, gamma, tau);
let final_leaves: Vec<DensePolynomial<Fr>> = pc_prover.final_leaves(&polys, gamma, tau);
let init_leaves: Vec<DensePolynomial<Fr>> = polys.init_leaves(&polys, gamma, tau);
let read_leaves: Vec<DensePolynomial<Fr>> = polys.read_leaves(&polys, gamma, tau);
let write_leaves: Vec<DensePolynomial<Fr>> = polys.write_leaves(&polys, gamma, tau);
let final_leaves: Vec<DensePolynomial<Fr>> = polys.final_leaves(&polys, gamma, tau);

let init_leaves = &init_leaves[0];
let read_leaves = &read_leaves[0];
Expand All @@ -709,14 +722,13 @@ mod tests {
ELFRow::new(2, 8u64, 8u64, 8u64, 8u64, 8u64),
];
let polys: PCPolys<Fr, EdwardsProjective> = PCPolys::new_program(program, trace);
let pc_prover: PCProof<Fr> = PCProof(PhantomData::<_>);

let mut transcript = Transcript::new(b"test_transcript");
let mut random_tape = RandomTape::new(b"test_tape");

let batched_polys = polys.batch();
let commitments = PCPolys::commit(&batched_polys);
let proof = pc_prover.prove_memory_checking(
let proof = polys.prove_memory_checking(
&polys,
&batched_polys,
&commitments,
Expand All @@ -725,7 +737,7 @@ mod tests {
);

let mut transcript = Transcript::new(b"test_transcript");
PCProof::verify_memory_checking(proof, &commitments, &mut transcript)
PCPolys::verify_memory_checking(proof, &commitments, &mut transcript)
.expect("proof should verify");
}

Expand All @@ -744,24 +756,23 @@ mod tests {
ELFRow::new(4, 32u64, 32u64, 32u64, 32u64, 32u64),
];

let pc_prover: PCProof<Fr> = PCProof(PhantomData::<_>);
let polys: PCPolys<Fr, EdwardsProjective> = PCPolys::new_program(program, trace);
let batch = polys.batch();
let commitments = PCPolys::commit(&batch);

let mut transcript = Transcript::new(b"test_transcript");
let mut random_tape = RandomTape::new(b"test_tape");

let proof = pc_prover.prove_memory_checking(
let proof = polys.prove_memory_checking(
&polys,
&batch,
&commitments,
&mut transcript,
&mut random_tape
&mut random_tape,
);

let mut transcript = Transcript::new(b"test_transcript");
PCProof::verify_memory_checking(proof, &commitments, &mut transcript).expect("should verify");
PCPolys::verify_memory_checking(proof, &commitments, &mut transcript).expect("should verify");
}

#[test]
Expand Down

0 comments on commit a2e525d

Please sign in to comment.