Skip to content

Commit

Permalink
Merge branch 'main' of github.com:manojkgorle/brainfuckvm
Browse files Browse the repository at this point in the history
  • Loading branch information
m-pandey5 committed Dec 7, 2024
2 parents d6b1030 + c840142 commit 3cdef6a
Show file tree
Hide file tree
Showing 7 changed files with 185 additions and 24 deletions.
8 changes: 5 additions & 3 deletions src/fri/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ use crate::univariate_polynomial::*;

//@todo pass difference quotient polynomial as a parameter too if using random secret initials
//challenges = [alpha, beta], given by fiat shamir

//@todo this has to be inside prover/main?, check once
//boundary_q includes boundary constraints for all tables together, similarly for others

pub fn combination_polynomial(
boundary_q: Vec<Polynomial>,
transition_q: Vec<Polynomial>,
Expand All @@ -25,7 +25,9 @@ pub fn combination_polynomial(
FieldElement::zero(field),
FieldElement::one(field),
]);
let degree = height;
let degree = height-1;
//@todo what should be degree here since processor and instruction table can have different heights
//@todo we can also pass a single vector of all quotient

for i in 0..boundary_q.clone().len() {
let d = degree - boundary_q[i].clone().degree();
Expand Down Expand Up @@ -200,7 +202,7 @@ pub fn decommit_fri_layers(
/// sends
pub fn decommit_on_query(
idx: usize,
blow_up_factor: usize,
blow_up_factor: usize,//expansion_f
f_eval: Vec<&[FieldElement]>, //this contains basecodewords zipped, and extension codewords zipped
f_merkle: Vec<&MerkleTree>, //this contains MerkleTree of base codewords zipped, and extension codewords zipped
fri_layers: &[Vec<FieldElement>],
Expand Down
125 changes: 124 additions & 1 deletion src/stark/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,20 @@
#![allow(unused_variables)]
use io::IOTable;
use memory::MemoryTable;
use processor::ProcessorTable;
use instruction::InstructionTable;

use crate::merkle::*;
use crate::channel::*;
use crate::fri::*;
use crate::fields::Field;
use crate::fields::FieldElement;
use crate::tables::*;
use crate::univariate_polynomial::*;


//@todo boundary, transition and terminal constraints: in all tables: should we be adding them? does that ensure they are individually zero if the sum is zero? check once
//@todo Tipa, Tmpa, Tiea, Toea, Tpea, Tppai, Tppam, Tea, Tea' -> have to write equality amongst them, not written in terminal constraints
pub struct Stark<'a> {
pub running_time: i32,
pub memory_length: usize,
Expand All @@ -12,11 +26,110 @@ pub struct Stark<'a> {
num_collinearity_checks: u32,
}

// prove:
// prove parameter - matrices, inputs
// matrices -> processor, memory, instruction, i, o -> in this order
pub fn prove(matrices: Vec<Vec<Vec<FieldElement>>>, inputs: Vec<FieldElement>, field: Field, offset: FieldElement, expansion_f: usize){
let generator = field.generator().pow((1<<32)-1);
let order = 1<<32;

let mut processor_table = ProcessorTable::new(field, matrices[0].clone().len() as u128, generator, order, matrices[0].clone());
let mut memory_table = MemoryTable::new(field, matrices[1].len() as u128, generator, order, matrices[1].clone());
let mut instruction_table = InstructionTable::new(field, matrices[2].len() as u128, generator, order, matrices[2].clone());
let mut input_table = IOTable::new(field, matrices[3].len() as u128, generator, order, matrices[3].clone());
let mut output_table = IOTable::new(field, matrices[4].len() as u128, generator, order, matrices[4].clone());

processor_table.pad();
memory_table.pad();
instruction_table.pad();
input_table.pad();
output_table.pad();

let processor_interpol_columns = processor_table.table.clone().interpolate_columns(vec![0,1,2,3,4,5,6]);
let memory_interpol_columns = memory_table.table.clone().interpolate_columns(vec![0,1,2]);
let instruction_interpol_columns = instruction_table.table.clone().interpolate_columns(vec![0,1,2]);

let initial_length = instruction_table.table.clone().height;
//all codewords are evaluated on this expanded domain that has length expanded_length
let expanded_length = initial_length*(expansion_f as u128);

let domain = FriDomain::new(offset, derive_omicron(generator, order, expanded_length), expanded_length);

let mut basecodewords: Vec<Vec<FieldElement>> = Vec::new();

// basecodewords vector order:
// processor: clk, ip, ci, ni, mp, mv, inv
// memory: clk, mp, mv
// instruction: ip, ci, ni
// input and output tables are public, we dont commit to those, we only check their termnal extensions after extending

for i in 0..processor_interpol_columns.clone().len(){
basecodewords.push(domain.evaluate(processor_interpol_columns[i].clone()));
}

for i in 0..memory_interpol_columns.clone().len(){
basecodewords.push(domain.evaluate(memory_interpol_columns[i].clone()));
}

for i in 0..instruction_interpol_columns.clone().len(){
basecodewords.push(domain.evaluate(instruction_interpol_columns[i].clone()));
}

//we are zipping all the base codewords (for each index in order) using concatenation
//@todo to_bytes function of field element is not working properly? check once

let mut basecodeword: Vec<Vec<u8>> = Vec::new();

// for i in 0..expanded_length as usize{
// let mut x: Vec<Vec<u8>> = vec![];
// for j in 0..basecodewords.len(){
// x.push(basecodewords[j][i].to_bytes().iter().map(y:));
// }
// }

//@todo could not find a function in channel for fiat shamir, ie sending data as string and then getting random element
//@todo make extend columns function return Terminal value , eg. Tipa, for every table and store it, use it to compare

}

// commit this codeword in merkle tree -> send to verifier, and use the merkle root in fiat shamir
// get 11 challenges array from fiat shamir
// use extend column function on tables -> extends the base columns to extension columns
// interpolate extension columns of all matrices
// evaluate these polynomials on expanded evaluation domains to give extension codewords
// zip/concatenate the extension codewords to give one extension codeword
// commit this codeword in merkle tree -> send to verifier, and use the merkle root in fiat shamir
// get 2 challenges array from fiat shamir
// use generate AIR -> generate zerofier -> generate quotient: on all tables
// form combination polynomial from quotient polynomials and challenges array
// evaluate combination polynomials on expanded evaluation domains to get combination codeword
// perform fri :D, send commitments of fri functions (written in fri module)
// lessgooo

//@todo IMP - we have interpolated columns of processor table already for commitment and fiat shamir, no need to do it again in AIR

// verifier
// verifier knows -
// constraints (therefore AIR)
// zerofiers (instruction zerofiers //@todo discuss once)
// combination polynomial equation
// challenges of extension columns
// challenges of composition polynomial
//
// prover sends to verifier -
// height (whose correctness is indirectly verified through fri and degree bound)
// base codewords merkle root, extension codewords merkle root
// for each query (index) of verifier, prover sends respective evaluation and merkle authentication path of evaluation
// written in fri decommit_on_query
//
//verifier will perform IOTable computations like extension of columns, will then send those values to prover via channel


impl Stark<'_> {}

#[cfg(test)]
mod stark_test {
use crate::fields::Field;
use crate::fields::{Field, FieldElement};
use crate::vm::VirtualMachine;
#[test]
fn test_proving() {
Expand All @@ -29,4 +142,14 @@ mod stark_test {
vm.simulate(&program, "".to_string());
assert_eq!(running_time as usize, processor_matrix.len());
}
#[test]
fn helper_tests() {
let x = FieldElement::new(318, Field::new(421));
println!("{}", x);
let y = x.to_bytes();
for i in 0..y.len(){
print!("{}, ", y[i]);
}
}
}

25 changes: 18 additions & 7 deletions src/tables/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,24 @@ impl InstructionTable {
}

pub fn extend_column(&mut self, rand_field_elem: u128, challenges: Vec<FieldElement>) {
let mut ppa = FieldElement::new(rand_field_elem, self.table.field);
//take randFieldElement = 1 when not implementing random secret diff constraint
let pea = FieldElement::zero(self.table.field);
let mut ppa = self.table.matrix[0 as usize][Indices::Address as usize]
* challenges[ChallengeIndices::A as usize]
+ self.table.matrix[0 as usize][Indices::CurrentInstruction as usize]
* challenges[ChallengeIndices::B as usize]
+ self.table.matrix[0 as usize][Indices::NextInstruction as usize]
* challenges[ChallengeIndices::C as usize]
- challenges[ChallengeIndices::Alpha as usize];

let pea = self.table.matrix[0 as usize][Indices::Address as usize]
* challenges[ChallengeIndices::A as usize]
+ self.table.matrix[0 as usize][Indices::CurrentInstruction as usize]
* challenges[ChallengeIndices::B as usize]
+ self.table.matrix[0 as usize][Indices::NextInstruction as usize]
* challenges[ChallengeIndices::C as usize];

self.table.matrix[0_usize][Indices::PermutationArg as usize] = ppa;
self.table.matrix[0_usize][Indices::EvaluationArg as usize] = pea;
//@todo set initial value of first row of ppa and pea


for i in 0..self.table.length - 1 {
let weighted_sum = self.table.matrix[(i + 1) as usize][Indices::Address as usize]
* challenges[ChallengeIndices::A as usize]
Expand Down Expand Up @@ -144,8 +154,9 @@ impl InstructionTable {
let one = Polynomial::new_from_coefficients(vec![FieldElement::one(self.table.field)]);
let mut air = vec![];

//Boundary constraint: ip=0
//@todo ppa and pea initial value from extended fn, see once
//Boundary constraint:
//ip=0
//@todo ci ni, ppa, pea ka bhi boundary constraint dalna hai?

let boundaryair = ip.clone() + ppa.clone()
- Polynomial::new_from_coefficients(vec![FieldElement::one(self.table.field)])
Expand Down
10 changes: 5 additions & 5 deletions src/tables/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use super::{derive_omicron, roundup_npow2};
use crate::fields::{Field, FieldElement};
use crate::univariate_polynomial::interpolate_lagrange_polynomials;
use crate::univariate_polynomial::Polynomial;
pub struct Memory {
pub struct MemoryTable {
pub table: Table,
}

Expand Down Expand Up @@ -37,7 +37,7 @@ pub enum ChallengeIndices {
Eta,
}

impl Memory {
impl MemoryTable {
pub fn new(
field: Field,
length: u128,
Expand Down Expand Up @@ -239,7 +239,7 @@ impl Memory {
#[cfg(test)]
mod test_memory_table {
#![allow(unused_variables)]
use super::Memory;
use super::MemoryTable;
use crate::fields::{Field, FieldElement};
use crate::tables::memory::{ChallengeIndices, Indices};
use crate::tables::Table;
Expand All @@ -256,7 +256,7 @@ mod test_memory_table {
let (processor_matrix, memory_matrix, instruction_matrix, input_matrix, output_matrix) =
vm.simulate(&program, "a".to_string());
let mlen = memory_matrix.len();
let mut memory_table = Memory::new(
let mut memory_table = MemoryTable::new(
field,
memory_matrix.len() as u128,
generator,
Expand All @@ -283,7 +283,7 @@ mod test_memory_table {
let generator = field.generator();
let order = 1 << 32;
let zero = FieldElement::zero(field);
let mut mem = Memory::new(
let mut mem = MemoryTable::new(
field,
memory_matrix.len() as u128,
generator,
Expand Down
31 changes: 28 additions & 3 deletions src/tables/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ pub struct Table {
base_width: u128, //number of base columns in the table.
full_width: u128, //total no. of coloumn using extension and all
length: u128, //Number of rows in the table.
height: u128, //Represents the rounded-up next power of two of the table length
pub height: u128, //Represents the rounded-up next power of two of the table length
omicron: FieldElement, //represent the generator eval_domain depends on the generator and the order of the subgroup
generator: FieldElement, // A generator for the multiplicative group of the field
order: u128, //order of the generator.
matrix: Vec<Vec<FieldElement>>,
pub matrix: Vec<Vec<FieldElement>>,
}

impl Table {
Expand Down Expand Up @@ -48,7 +48,7 @@ impl Table {
matrix,
}
}
fn new_2(
pub fn new_2(
field: Field,
base_width: u128,
full_width: u128,
Expand All @@ -70,6 +70,30 @@ impl Table {
matrix: Vec::new(), // Initialize as empty
}
}

pub fn new_3(
field: Field,
base_width: u128,
full_width: u128,
length: u128,
generator: FieldElement,
order: u128,
matrix: Vec<Vec<FieldElement>>
) -> Self {
let height = roundup_npow2(length);
let omicron = derive_omicron(generator, order, height);
Table {
field,
base_width,
full_width,
length,
height,
omicron,
generator,
order,
matrix: matrix,
}
}
// dont know how to implement this method
pub fn unit_distance(&self, omega_order: u128) -> u128 {
if self.height == 0 {
Expand Down Expand Up @@ -187,6 +211,7 @@ pub fn derive_omicron(
generator_order: u128,
target_order: u128,
) -> FieldElement {

let mut t_generator = generator;
let mut t_order = generator_order;
while t_order != target_order {
Expand Down
6 changes: 3 additions & 3 deletions src/tables/processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::fri::*;
use crate::univariate_polynomial::*;

pub struct ProcessorTable {
table: Table,
pub table: Table,
}

pub enum Indices {
Expand Down Expand Up @@ -634,7 +634,7 @@ mod test_processor {
use crate::fields::{Field, FieldElement};
use crate::tables::instruction::InstructionTable;
use crate::tables::io::IOTable;
use crate::tables::memory::Memory;
use crate::tables::memory::MemoryTable;
use crate::tables::processor::Indices;
use crate::vm::VirtualMachine;

Expand Down Expand Up @@ -690,7 +690,7 @@ mod test_processor {
order,
processor_matrix,
);
let mut memory_table = Memory::new(
let mut memory_table = MemoryTable::new(
field,
memory_matrix.len() as u128,
generator,
Expand Down
4 changes: 2 additions & 2 deletions src/vm/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use core::panic;
use std::{collections::HashMap, mem};

use crate::tables::memory::Memory;
use crate::tables::memory::MemoryTable;
use crate::{
fields::{Field, FieldElement},
tables::memory,
Expand Down Expand Up @@ -310,7 +310,7 @@ impl VirtualMachine {
// sort instruction matrix
instruction_matrix.sort();
// build memory matrix
let memory_matrix = Memory::derive_matrix(&processor_materix);
let memory_matrix = MemoryTable::derive_matrix(&processor_materix);
(
processor_materix,
memory_matrix,
Expand Down

0 comments on commit 3cdef6a

Please sign in to comment.