From 20cbf894846daaf44f5de580438accc4244ecb07 Mon Sep 17 00:00:00 2001 From: soumyathakur44 Date: Sat, 14 Dec 2024 19:21:14 +0530 Subject: [PATCH 1/3] proc --- src/fields/mod.rs | 3 +- src/fri/mod.rs | 14 +- src/stark/mod.rs | 209 +++++++++++++++------- src/tables/instruction.rs | 96 +++++++---- src/tables/io.rs | 20 ++- src/tables/memory.rs | 355 +++++++++++++++++++++----------------- src/tables/mod.rs | 5 +- src/tables/processor.rs | 200 ++++++++++++--------- 8 files changed, 544 insertions(+), 358 deletions(-) diff --git a/src/fields/mod.rs b/src/fields/mod.rs index 5314774..9bdaf53 100644 --- a/src/fields/mod.rs +++ b/src/fields/mod.rs @@ -25,7 +25,6 @@ pub enum ChallengeIndices { Eta, } - impl Field { pub fn new(x: u128) -> Field { Field(x) @@ -37,7 +36,7 @@ impl Field { "Field does not have nth root of unity where n > 2^32 or not power of two." ); let mut root = FieldElement::new(1753635133440165772, self); - + let mut order = 1 << 32; while order != n { diff --git a/src/fri/mod.rs b/src/fri/mod.rs index 8e9089b..113ed2f 100644 --- a/src/fri/mod.rs +++ b/src/fri/mod.rs @@ -25,9 +25,9 @@ pub fn combination_polynomial( FieldElement::zero(field), FieldElement::one(field), ]); - let degree = height-1; + 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 + //@todo we can also pass a single vector of all quotient for i in 0..processor_q.clone().len() { let d = degree - processor_q[i].clone().degree(); @@ -202,7 +202,7 @@ pub fn decommit_fri_layers( /// sends pub fn decommit_on_query( idx: usize, - blow_up_factor: usize,//expansion_f + 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], @@ -391,10 +391,10 @@ mod test_fri_layer { assert_eq!(next_poly.coefficients.len(), 2); assert_eq!(next_poly.coefficients[0].0, 11); - assert_eq!(next_poly.coefficients[1].0, 3); - assert_eq!(next_eval_domain.length, 2); - assert_eq!(next_eval_domain.omega, FieldElement::new(16, field)); - assert_eq!(next_evaluations.len(), 2); + assert_eq!(next_poly.coefficients[1].0, 3); + assert_eq!(next_eval_domain.length, 2); + assert_eq!(next_eval_domain.omega, FieldElement::new(16, field)); + assert_eq!(next_evaluations.len(), 2); assert_eq!(next_evaluations[0].0, 14); assert_eq!(next_evaluations[1].0, 8); } diff --git a/src/stark/mod.rs b/src/stark/mod.rs index 33c9e7c..05c68b1 100644 --- a/src/stark/mod.rs +++ b/src/stark/mod.rs @@ -2,23 +2,22 @@ use std::io::Read; use instruction::Indices; +use instruction::InstructionTable; use io::IOTable; use memory::MemoryTable; use processor::ProcessorTable; -use instruction::InstructionTable; use crate::channel; -use crate::merkle::*; use crate::channel::*; -use crate::fri::*; use crate::fields::Field; use crate::fields::FieldElement; +use crate::fri::*; +use crate::merkle::*; 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 +//@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, @@ -47,15 +46,51 @@ pub enum ChallengeIndices { // prove: // prove parameter - matrices, inputs // matrices -> processor, memory, instruction, i, o -> in this order -pub fn prove(matrices: Vec>>, inputs: Vec, 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()); +pub fn prove( + matrices: Vec>>, + inputs: Vec, + 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(), + ); //@todo instruction table height passed as parameter processor_table.pad(); @@ -64,16 +99,29 @@ pub fn prove(matrices: Vec>>, inputs: Vec, f 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 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 expanded_length = initial_length * (expansion_f as u128); + + let domain = FriDomain::new( + offset, + derive_omicron(generator, order, expanded_length), + expanded_length, + ); - let domain = FriDomain::new(offset, derive_omicron(generator, order, expanded_length), expanded_length); - let mut basecodewords: Vec> = Vec::new(); // basecodewords vector order: @@ -82,15 +130,15 @@ pub fn prove(matrices: Vec>>, inputs: Vec, f // 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(){ + 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(){ + 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(){ + for i in 0..instruction_interpol_columns.clone().len() { basecodewords.push(domain.evaluate(instruction_interpol_columns[i].clone())); } @@ -98,9 +146,9 @@ pub fn prove(matrices: Vec>>, inputs: Vec, f let mut basecodeword: Vec> = Vec::new(); - for i in 0..expanded_length as usize{ + for i in 0..expanded_length as usize { let mut x: Vec = vec![]; - for j in 0..basecodewords.len(){ + for j in 0..basecodewords.len() { x.extend(basecodewords[j][i].to_bytes().iter().map(|&x| x)); } basecodeword.push(x); @@ -109,14 +157,14 @@ pub fn prove(matrices: Vec>>, inputs: Vec, f //@todo make extend columns function return Terminal value , eg. Tipa, for every table and store it, use it to compare let mut data1 = vec![]; - for i in 0..basecodeword.len(){ - // difficulty in implementing -> let n = basecodewords[0].len(); + for i in 0..basecodeword.len() { + // difficulty in implementing -> let n = basecodewords[0].len(); // so hardcoded the value to 32*13 = 416 -> where 13 => clk, ip, ci, ni, mp, mv, inv, clk, mp, mv, ip, ci, ni let array: &[u8] = &basecodeword[i].to_vec(); data1.push(FieldElement::from_bytes(array)); } - + // get 11 challenges array from fiat shamir let mut channel = Channel::new(); let merkle1 = MerkleTree::new(&data1); @@ -124,7 +172,7 @@ pub fn prove(matrices: Vec>>, inputs: Vec, f let mut challenges_extension = vec![]; - for i in 0..10{ + for i in 0..10 { let x = channel.receive_random_field_element(field); challenges_extension.push(x); channel.send(x.to_bytes()); @@ -135,13 +183,23 @@ pub fn prove(matrices: Vec>>, inputs: Vec, f let Terminal_processor = processor_table.extend_columns(challenges_extension.clone()); let Terminal_memory = memory_table.extend_column_ppa(1, challenges_extension.clone()); let Terminal_instruction = instruction_table.extend_column(1, challenges_extension.clone()); - let Terminal_input = input_table.extend_column_ea(1, challenges_extension[ChallengeIndices::Gamma as usize]).clone(); - let Terminal_output = output_table.extend_column_ea(1, challenges_extension[ChallengeIndices::Delta as usize]).clone(); - - //These contain polynomials for interpolation of extension columns - let processor_interpol_columns_2 = processor_table.table.clone().interpolate_columns(vec![7, 8, 9, 10]); + let Terminal_input = input_table + .extend_column_ea(1, challenges_extension[ChallengeIndices::Gamma as usize]) + .clone(); + let Terminal_output = output_table + .extend_column_ea(1, challenges_extension[ChallengeIndices::Delta as usize]) + .clone(); + + //These contain polynomials for interpolation of extension columns + let processor_interpol_columns_2 = processor_table + .table + .clone() + .interpolate_columns(vec![7, 8, 9, 10]); let memory_interpol_columns_2 = memory_table.table.clone().interpolate_columns(vec![3]); - let instruction_interpol_columns_2 = instruction_table.table.clone().interpolate_columns(vec![3, 4]); + let instruction_interpol_columns_2 = instruction_table + .table + .clone() + .interpolate_columns(vec![3, 4]); let mut extension_codewords: Vec> = Vec::new(); @@ -151,23 +209,23 @@ pub fn prove(matrices: Vec>>, inputs: Vec, f // instruction: ppa, pea // 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_2.clone().len(){ + for i in 0..processor_interpol_columns_2.clone().len() { extension_codewords.push(domain.evaluate(processor_interpol_columns_2[i].clone())); } - for i in 0..memory_interpol_columns_2.clone().len(){ + for i in 0..memory_interpol_columns_2.clone().len() { extension_codewords.push(domain.evaluate(memory_interpol_columns_2[i].clone())); } - for i in 0..instruction_interpol_columns_2.clone().len(){ + for i in 0..instruction_interpol_columns_2.clone().len() { extension_codewords.push(domain.evaluate(instruction_interpol_columns_2[i].clone())); } let mut extension_codeword: Vec> = Vec::new(); - for i in 0..expanded_length as usize{ + for i in 0..expanded_length as usize { let mut x: Vec = vec![]; - for j in 0..extension_codewords.len(){ + for j in 0..extension_codewords.len() { x.extend(extension_codewords[j][i].to_bytes().iter().map(|&x| x)); } extension_codeword.push(x); @@ -175,7 +233,7 @@ pub fn prove(matrices: Vec>>, inputs: Vec, f let mut data2 = vec![]; - for i in 0..extension_codeword.len(){ + for i in 0..extension_codeword.len() { let array: &[u8] = &extension_codeword[i].to_vec(); data2.push(FieldElement::from_bytes(array)); @@ -192,51 +250,74 @@ pub fn prove(matrices: Vec>>, inputs: Vec, f let eval = FieldElement::zero(field); - - let processor_quotients = processor_table.generate_quotients(challenges_extension.clone(), Terminal_processor[0], Terminal_processor[1], Terminal_processor[2], Terminal_processor[3]); - let memory_quotients = memory_table.generate_quotients(challenges_extension.clone(), Terminal_memory[0]); - let instruction_quotients = instruction_table.generate_quotients(challenges_extension, Terminal_instruction[0], Terminal_instruction[1]); + let processor_quotients = processor_table.generate_quotients( + challenges_extension.clone(), + Terminal_processor[0], + Terminal_processor[1], + Terminal_processor[2], + Terminal_processor[3], + ); + let memory_quotients = + memory_table.generate_quotients(challenges_extension.clone(), Terminal_memory[0]); + let instruction_quotients = instruction_table.generate_quotients( + challenges_extension, + Terminal_instruction[0], + Terminal_instruction[1], + ); //for inter table arguments constraints assert_eq!(Terminal_processor[0], Terminal_instruction[0]); //Tipa = Tppa assert_eq!(Terminal_processor[1], Terminal_memory[0]); //Tmpa = Tppa assert_eq!(Terminal_processor[2], Terminal_input[0]); //Tipa = Tea input assert_eq!(Terminal_processor[3], Terminal_output[0]); //Tipa = Tea output - //let this be for now:- assert_eq!(Terminal_instruction[1], Tpea); //Tpea = program evaluation + //let this be for now:- assert_eq!(Terminal_instruction[1], Tpea); //Tpea = program evaluation //form combination polynomial - let combination= combination_polynomial(processor_quotients, memory_quotients, instruction_quotients, challenges_combination, instruction_table.table.height as usize, field); + let combination = combination_polynomial( + processor_quotients, + memory_quotients, + instruction_quotients, + challenges_combination, + instruction_table.table.height as usize, + field, + ); let combination_codeword = domain.evaluate(combination.clone()); - + let merkle_combination = MerkleTree::new(&combination_codeword); channel.send(merkle_combination.inner.root().unwrap().to_vec()); - let (fri_polys, fri_domains, fri_layers, fri_merkles) = fri_commit(combination.clone(), domain, combination_codeword, merkle_combination, &mut channel); + let (fri_polys, fri_domains, fri_layers, fri_merkles) = fri_commit( + combination.clone(), + domain, + combination_codeword, + merkle_combination, + &mut channel, + ); let no_of_queries = 5; - decommit_fri(no_of_queries, expansion_f, 1<<64-1<<32+1, vec![&data1, &data2], vec![&merkle1, &merkle2], &fri_layers, &fri_merkles, &mut channel); + decommit_fri( + no_of_queries, + expansion_f, + 1 << 64 - 1 << 32 + 1, + vec![&data1, &data2], + vec![&merkle1, &merkle2], + &fri_layers, + &fri_merkles, + &mut channel, + ); //print channel proof, proofsize, time taken for running prover, space taken etc etc. - } -// 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 - +// 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 - +// +// 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 @@ -244,7 +325,6 @@ pub fn prove(matrices: Vec>>, inputs: Vec, f // //verifier will perform IOTable computations like extension of columns, will then send those values to prover via channel - impl Stark<'_> {} #[cfg(test)] @@ -267,9 +347,8 @@ mod stark_test { let x = FieldElement::new(318, Field::new(421)); println!("{}", x); let y = x.to_bytes(); - for i in 0..y.len(){ + for i in 0..y.len() { print!("{}, ", y[i]); } } } - diff --git a/src/tables/instruction.rs b/src/tables/instruction.rs index c4d2a70..b8e655c 100644 --- a/src/tables/instruction.rs +++ b/src/tables/instruction.rs @@ -1,7 +1,7 @@ use super::{derive_omicron, roundup_npow2, Table}; use crate::fields::{Field, FieldElement}; use crate::univariate_polynomial::*; -pub struct InstructionTable { +pub struct InstructionTable { pub table: Table, } @@ -83,28 +83,32 @@ impl InstructionTable { } } #[warn(unused_variables)] - pub fn extend_column(&mut self, rand_field_elem: u128, challenges: Vec) ->Vec{ - let mut terminal:Vec=Vec::new(); + pub fn extend_column( + &mut self, + rand_field_elem: u128, + challenges: Vec, + ) -> Vec { + let mut terminal: Vec = Vec::new(); let field = self.table.field; let mut ppa = FieldElement::one(field); let mut 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]; + * 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) as usize][Indices::PermutationArg as usize] = ppa; self.table.matrix[(0) as usize][Indices::EvaluationArg as usize] = pea; - - for i in 0..self.table.length-1 { - let weighted_sum = self.table.matrix[(i+1) as usize][Indices::Address as usize] + + 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] - + self.table.matrix[(i+1) as usize][Indices::CurrentInstruction as usize] + + self.table.matrix[(i + 1) as usize][Indices::CurrentInstruction as usize] * challenges[ChallengeIndices::B as usize] - + self.table.matrix[(i+1) as usize][Indices::NextInstruction as usize] + + self.table.matrix[(i + 1) as usize][Indices::NextInstruction as usize] * challenges[ChallengeIndices::C as usize]; - if self.table.matrix[(i+1) as usize][Indices::Address as usize] + if self.table.matrix[(i + 1) as usize][Indices::Address as usize] == self.table.matrix[i as usize][Indices::Address as usize] { ppa *= weighted_sum - challenges[ChallengeIndices::Alpha as usize]; @@ -115,14 +119,18 @@ impl InstructionTable { pea = pea * challenges[ChallengeIndices::Eta as usize] + weighted_sum; self.table.matrix[(i + 1) as usize][Indices::EvaluationArg as usize] = pea; } - } terminal.push(ppa); terminal.push(pea); terminal } - pub fn generate_air(&self, challenges: Vec,tppa:FieldElement,tpea:FieldElement) -> Vec { + pub fn generate_air( + &self, + challenges: Vec, + tppa: FieldElement, + tpea: FieldElement, + ) -> Vec { let interpolated = self.table.clone().interpolate_columns(vec![ Indices::Address as u128, Indices::CurrentInstruction as u128, @@ -153,19 +161,21 @@ impl InstructionTable { let one = Polynomial::new_from_coefficients(vec![FieldElement::one(self.table.field)]); let mut air = vec![]; - //Boundary constraint: + //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)]) + pea.clone() - - Polynomial::constant((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])); + - Polynomial::constant( + (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]), + ); //@todo check this once!! initial value is not zero and one, set it to req value air.push(boundaryair); @@ -218,14 +228,14 @@ impl InstructionTable { air.push(transitionair); //Terminal constraints: - + //ppa - Tppa //pea - tpea //@todo Tppa and tipa given by prover, for now just taking it as empty polynomials to write constraint without error //@todo tpea is computed locally by verifier, taking empty polynomial for now let terminalair = - ppa.clone() -Polynomial::constant(tppa) + pea.clone() - Polynomial::constant(tpea) ; + ppa.clone() - Polynomial::constant(tppa) + pea.clone() - Polynomial::constant(tpea); //@todo separate Tppa - tipa term as it will cancel out air.push(terminalair); @@ -257,9 +267,14 @@ impl InstructionTable { zerofiers } - pub fn generate_quotients(&self, challenges: Vec,tppa:FieldElement,tpea:FieldElement) -> Vec { + pub fn generate_quotients( + &self, + challenges: Vec, + tppa: FieldElement, + tpea: FieldElement, + ) -> Vec { let mut quotients = vec![]; - let air = self.generate_air(challenges,tppa,tpea); + let air = self.generate_air(challenges, tppa, tpea); let zerofiers = self.generate_zerofier(); for i in 0..air.len() { @@ -275,12 +290,11 @@ mod test_instruction { use super::Indices; use crate::fields::Field; use crate::fields::FieldElement; - use crate::vm::VirtualMachine; - use crate::tables::processor::ProcessorTable; use crate::tables::instruction::InstructionTable; use crate::tables::io::IOTable; use crate::tables::memory::MemoryTable; - + use crate::tables::processor::ProcessorTable; + use crate::vm::VirtualMachine; #[test] fn test_padding() { @@ -328,11 +342,11 @@ mod test_instruction { let one = FieldElement::one(field); let two = one + one; let vm = VirtualMachine::new(field); - let generator = field.generator().pow((1<<32)-1); + let generator = field.generator().pow((1 << 32) - 1); let omicron = generator.clone(); let order = 1 << 32; // let code = "++>+++++[<+>-]++++++++[<++++++>-]<.".to_string(); - let code2 = ">>[++-]+".to_string(); + let code2 = ">>+.[++-]+.".to_string(); let program = vm.compile(code2); println!("{:?}", program.clone()); let (rt, _, _) = vm.run(&program, "".to_string()); @@ -405,7 +419,7 @@ mod test_instruction { for i in 0..instruction_table.table.height { omicron_domain.push(instruction_table.table.omicron.pow(i)); if i == 4 { - println!("omicron_domain: {:?}", omicron_domain); + println!("omicron_domain: {:?}", omicron_domain); } } let air = instruction_table.generate_air(challenges, terminal[0], terminal[1]); @@ -417,15 +431,25 @@ mod test_instruction { let b = air[0].evaluate(omicron_domain[0]); assert_eq!(b, zero); - for v in 0..instruction_table.table.length-1 { + for v in 0..instruction_table.table.length - 1 { let transition = air[1].evaluate(omicron_domain[v as usize]); //println!("{:?}: {}", transition, v); assert_eq!(transition, zero); } - let terminal = air[2].evaluate(omicron_domain[(instruction_table.table.length-1) as usize]); + let terminal = + air[2].evaluate(omicron_domain[(instruction_table.table.length - 1) as usize]); assert_eq!(terminal, zero); - } + println!("Input table after extending columns"); + for row in input_table.table.matrix.clone() { + println!("{:?}", row); + } + println!("Output table after extending columns"); + for row in output_table.table.matrix.clone() { + println!("{:?}", row); + } + //@todo check input output bt + } } diff --git a/src/tables/io.rs b/src/tables/io.rs index 5519b54..ff9a950 100644 --- a/src/tables/io.rs +++ b/src/tables/io.rs @@ -38,7 +38,11 @@ impl IOTable { pub fn pad(&mut self) {} - pub fn extend_column_ea(&mut self, rand_field_elem: u128, challenge: FieldElement)->Vec { + pub fn extend_column_ea( + &mut self, + rand_field_elem: u128, + challenge: FieldElement, + ) -> Vec { let mut ea = FieldElement::new(rand_field_elem, self.table.field); // take rand_field_elem as zero if no random secret implementation self.table.matrix[0][1] = ea; for i in 0..self.table.length - 1 { @@ -47,12 +51,10 @@ impl IOTable { self.table.matrix[(i + 1) as usize][1] = ea; //Tea = IOTable.matrix[length-1][1] } - let mut terminal: Vec=Vec::new(); + let mut terminal: Vec = Vec::new(); terminal.push(ea); terminal - } - } #[cfg(test)] @@ -88,9 +90,13 @@ mod test_io { ); input_table.pad(); output_table.pad(); - - for row in input_table.table.matrix.clone(){ println!("{:?}",row)} - for row in output_table.table.matrix.clone(){println!("{:?}",row)} + + for row in input_table.table.matrix.clone() { + println!("{:?}", row) + } + for row in output_table.table.matrix.clone() { + println!("{:?}", row) + } assert_eq!(input_table.table.matrix.len(), 2); assert_eq!(output_table.table.matrix.len(), 2); } diff --git a/src/tables/memory.rs b/src/tables/memory.rs index 7c60f03..e6009a7 100644 --- a/src/tables/memory.rs +++ b/src/tables/memory.rs @@ -49,7 +49,7 @@ impl MemoryTable { let full_width = base_width + 1; let height = roundup_npow2(length); let omicron = derive_omicron(generator, order, height); - + let mut gmatrix = vec![vec![FieldElement::zero(field); full_width as usize]; height as usize]; for i in 0..matrix.len() { @@ -106,8 +106,11 @@ impl MemoryTable { #[warn(non_snake_case)] //the matrix taken here is padded - pub fn extend_column_ppa(&mut self, rand_field_elem: u128, challenges: Vec)->Vec { - + pub fn extend_column_ppa( + &mut self, + rand_field_elem: u128, + challenges: Vec, + ) -> Vec { let mut ppa = FieldElement::new(rand_field_elem, self.table.field); self.table.matrix[0][Indices::PermutationArg as usize] = ppa; for i in 0..self.table.length - 1 { @@ -120,23 +123,29 @@ impl MemoryTable { - challenges[ChallengeIndices::Beta as usize]; ppa *= weighted_sum; self.table.matrix[(i + 1) as usize][Indices::PermutationArg as usize] = ppa; - } - let tppa=ppa*(self.table.matrix[(self.table.length-1 )as usize][Indices::Cycle as usize] - * challenges[ChallengeIndices::D as usize] - + self.table.matrix[(self.table.length-1) as usize][Indices::MemoryPointer as usize] - * challenges[ChallengeIndices::E as usize] - + self.table.matrix[(self.table.length-1)as usize][Indices::MemoryValue as usize] - * challenges[ChallengeIndices::F as usize] - - challenges[ChallengeIndices::Beta as usize]); - let mut Tppa:Vec=Vec::new(); - Tppa.push(tppa); - Tppa + let tppa = ppa + * (self.table.matrix[(self.table.length - 1) as usize][Indices::Cycle as usize] + * challenges[ChallengeIndices::D as usize] + + self.table.matrix[(self.table.length - 1) as usize] + [Indices::MemoryPointer as usize] + * challenges[ChallengeIndices::E as usize] + + self.table.matrix[(self.table.length - 1) as usize] + [Indices::MemoryValue as usize] + * challenges[ChallengeIndices::F as usize] + - challenges[ChallengeIndices::Beta as usize]); + let mut Tppa: Vec = Vec::new(); + Tppa.push(tppa); + Tppa } //this is after padding and extension - pub fn generate_air(&self, challenges: Vec,tppa:FieldElement) -> Vec { - let interpolated = self.table.clone().interpolate_columns(vec![ + pub fn generate_air( + &self, + challenges: Vec, + tppa: FieldElement, + ) -> Vec { + let interpolated = self.table.clone().interpolate_columns(vec![ Indices::Cycle as u128, Indices::MemoryPointer as u128, Indices::MemoryValue as u128, @@ -146,7 +155,7 @@ impl MemoryTable { let mp = interpolated[Indices::MemoryPointer as usize].clone(); let mv = interpolated[Indices::MemoryValue as usize].clone(); let ppa = interpolated[Indices::PermutationArg as usize].clone(); - + let next_interpolated = self.table.clone().next_interpolate_columns(vec![ Indices::Cycle as u128, Indices::MemoryPointer as u128, @@ -165,7 +174,7 @@ impl MemoryTable { let boundaryair = clk.clone() + mp.clone() + mv.clone() + ppa.clone() - Polynomial::new_from_coefficients(vec![FieldElement::one(self.table.field)]); air.push(boundaryair); - println!("{:?}",air); + println!("{:?}", air); //Transition constraints: * == next //1. (mp+1-mp*).(mp-mp*) @@ -192,7 +201,7 @@ impl MemoryTable { //ppa.(d.clk+e.mp+f.mv-beta)-Tppa // Tppa given by prover, for now just taking it as empty polynomials to write constraint without error - let terminalair = ppa + let terminalair = ppa * (clk.scalar_mul(challenges[ChallengeIndices::D as usize]) + mp.scalar_mul(challenges[ChallengeIndices::E as usize]) + mv.scalar_mul(challenges[ChallengeIndices::F as usize]) @@ -200,12 +209,10 @@ impl MemoryTable { challenges[ChallengeIndices::Beta as usize], ])) - Polynomial::constant(tppa); - + air.push(terminalair); - - air - + air } pub fn generate_zerofier(&self) -> Vec { @@ -234,9 +241,13 @@ impl MemoryTable { zerofiers } - pub fn generate_quotients(&self, challenges: Vec,tppa:FieldElement) -> Vec { + pub fn generate_quotients( + &self, + challenges: Vec, + tppa: FieldElement, + ) -> Vec { let mut quotients = vec![]; - let air = self.generate_air(challenges,tppa); + let air = self.generate_air(challenges, tppa); let zerofiers = self.generate_zerofier(); for i in 0..air.len() { @@ -257,14 +268,12 @@ mod test_memory_table { #![allow(unused_variables)] use super::MemoryTable; use crate::fields::{Field, FieldElement}; - use crate::tables::memory::{ChallengeIndices, Indices}; - use crate::tables::Table; - use crate::vm::VirtualMachine; use crate::tables::instruction::InstructionTable; use crate::tables::io::IOTable; + use crate::tables::memory::{ChallengeIndices, Indices}; use crate::tables::processor::ProcessorTable; - - + use crate::tables::Table; + use crate::vm::VirtualMachine; #[test] fn test_padding() { @@ -324,40 +333,77 @@ mod test_memory_table { // Mock field and FieldElement implementation (use actual implementation if available) let field = Field::new(101); let zero = FieldElement::zero(field); - let one= FieldElement::one(field); + let one = FieldElement::one(field); // Create a mock table structure let mut matrix = vec![ - vec![FieldElement::new(1, field), FieldElement::new(2, field), FieldElement::new(3, field), zero.clone()], - vec![FieldElement::new(4, field), FieldElement::new(5, field), FieldElement::new(6, field), zero.clone()], - vec![FieldElement::new(7, field), FieldElement::new(8, field), FieldElement::new(9, field), zero.clone()], - vec![FieldElement::new(1, field), FieldElement::new(2, field), FieldElement::new(3, field), zero.clone()], - vec![FieldElement::new(10, field), FieldElement::new(12, field), FieldElement::new(13, field), zero.clone()], - vec![FieldElement::new(1, field), FieldElement::new(2, field), FieldElement::new(3, field), zero.clone()], + vec![ + FieldElement::new(1, field), + FieldElement::new(2, field), + FieldElement::new(3, field), + zero.clone(), + ], + vec![ + FieldElement::new(4, field), + FieldElement::new(5, field), + FieldElement::new(6, field), + zero.clone(), + ], + vec![ + FieldElement::new(7, field), + FieldElement::new(8, field), + FieldElement::new(9, field), + zero.clone(), + ], + vec![ + FieldElement::new(1, field), + FieldElement::new(2, field), + FieldElement::new(3, field), + zero.clone(), + ], + vec![ + FieldElement::new(10, field), + FieldElement::new(12, field), + FieldElement::new(13, field), + zero.clone(), + ], + vec![ + FieldElement::new(1, field), + FieldElement::new(2, field), + FieldElement::new(3, field), + zero.clone(), + ], ]; // Create the challenges let challenges = vec![ - FieldElement::new(3, field), // D - FieldElement::new(4, field), // E - FieldElement::new(5, field), // F - FieldElement::new(2, field), // Beta + FieldElement::new(3, field), // D + FieldElement::new(4, field), // E + FieldElement::new(5, field), // F + FieldElement::new(2, field), // Beta ]; let mut ppa = FieldElement::new(1, field); println!("{}:0", ppa.0); matrix[0].push(FieldElement::one(field)); - for i in 0..matrix.len()-1 { + for i in 0..matrix.len() - 1 { let weighted_sum = (matrix[i as usize][0] * challenges[0] + matrix[i as usize][1] * challenges[1] - + matrix[i as usize][2] * challenges[2] - challenges[3]); - matrix[(i+1) as usize].push(ppa*weighted_sum); + + matrix[i as usize][2] * challenges[2] + - challenges[3]); + matrix[(i + 1) as usize].push(ppa * weighted_sum); ppa *= weighted_sum; - println!("{} + {} + {} - {}", (matrix[i as usize][0]*challenges[0]).0, (matrix[i as usize][1]*challenges[1]).0, (matrix[i as usize][2]*challenges[2]).0, challenges[3].0); - println!("{}:{}", ppa.0, i+1); + println!( + "{} + {} + {} - {}", + (matrix[i as usize][0] * challenges[0]).0, + (matrix[i as usize][1] * challenges[1]).0, + (matrix[i as usize][2] * challenges[2]).0, + challenges[3].0 + ); + println!("{}:{}", ppa.0, i + 1); } } #[test] - fn test_generate_air(){ - let field = Field::new((1<<64)-(1<<32)+1); + fn test_generate_air() { + let field = Field::new((1 << 64) - (1 << 32) + 1); let zero = FieldElement::zero(field); let one = FieldElement::one(field); let two = one + one; @@ -416,7 +462,7 @@ mod test_memory_table { instruction_table.pad(); input_table.pad(); output_table.pad(); - let terminal = memory_table.extend_column_ppa(1,challenges.clone()); + let terminal = memory_table.extend_column_ppa(1, challenges.clone()); let terminal2 = processor_table.extend_columns(challenges.clone()); println!("memory_table after extending columns"); for row in memory_table.table.matrix.clone() { @@ -428,118 +474,117 @@ mod test_memory_table { for i in 0..memory_table.table.height { omicron_domain.push(memory_table.table.omicron.pow(i)); if i == 4 { - println!("omicron_domain: {:?}", omicron_domain); + println!("omicron_domain: {:?}", omicron_domain); } } - + let air = memory_table.generate_air(challenges, terminal[0]); - + let b = air[0].evaluate(omicron_domain[0]); - + assert_eq!(b, zero); - for v in 0..rt-1 { + for v in 0..rt - 1 { let t_all = air[1].evaluate(omicron_domain[v as usize]); - assert_eq!(t_all, zero); + assert_eq!(t_all, zero); } - - let v =omicron_domain[4]; - - let t_air1 = air[2].evaluate(v); - - assert_eq!(t_air1, zero); } - - #[test] - fn test_not_generate_air(){ - let field = Field::new((1<<64)-(1<<32)+1); - let zero = FieldElement::zero(field); - let one = FieldElement::one(field); - let two = one + one; - let vm = VirtualMachine::new(field); - let generator = FieldElement::new(1753635133440165772, field); - // let omicron = generator.clone(); - let order = 1 << 32; - // let code = "++>+++++[<+>-]++++++++[<++++++>-]<.".to_string(); - let code2 = ">>[++-]<".to_string(); - let program = vm.compile(code2); - println!("{:?}", program.clone()); - let (rt, _, _) = vm.run(&program, "".to_string()); - println!("{:?}", rt); - // assert_eq!(program.len(), 2); - let (processor_matrix, memory_matrix, instruction_matrix, input_matrix, output_matrix) = - vm.simulate(&program, "".to_string()); - let challenges = vec![two; 11]; - let mut processor_table = ProcessorTable::new( - field, - processor_matrix.len() as u128, - generator, - order, - processor_matrix, - ); - let mut memory_table = MemoryTable::new( - field, - memory_matrix.len() as u128, - generator, - order, - memory_matrix, - ); - let mut instruction_table = InstructionTable::new( - field, - instruction_matrix.len() as u128, - generator, - order, - instruction_matrix, - ); - let mut input_table = IOTable::new( - field, - input_matrix.len() as u128, - generator, - order, - input_matrix, - ); - let mut output_table = IOTable::new( - field, - output_matrix.len() as u128, - generator, - order, - output_matrix, - ); - - processor_table.pad(); - memory_table.pad(); - instruction_table.pad(); - input_table.pad(); - output_table.pad(); - let terminal = memory_table.extend_column_ppa(1,challenges.clone()); - println!("memory_table after extending columns"); - for row in memory_table.table.matrix.clone() { - println!("{:?}", row); - } - println!("tppa: {:?}", terminal[0]); - let mut omicron_domain: Vec = Vec::new(); - for i in 0..memory_table.table.height { - omicron_domain.push(memory_table.table.omicron.pow(i)); - if i == 4 { - println!("omicron_domain: {:?}", omicron_domain); - } - } - - let air = memory_table.generate_air(challenges, terminal[0]); - - let b = air[0].evaluate(omicron_domain[1]); - - assert_ne!(b, zero); - for v in 0..rt-1 { - let t_all = air[1].evaluate(omicron_domain[v as usize]); - // println!("{:?}", t_all); - assert_eq!(t_all, zero); - } - - let v =omicron_domain[3]; - - let t_air1 = air[2].evaluate(v); - - assert_ne!(t_air1, zero); } - - + let v = omicron_domain[4]; + + let t_air1 = air[2].evaluate(v); + + assert_eq!(t_air1, zero); + } + + #[test] + fn test_not_generate_air() { + let field = Field::new((1 << 64) - (1 << 32) + 1); + let zero = FieldElement::zero(field); + let one = FieldElement::one(field); + let two = one + one; + let vm = VirtualMachine::new(field); + let generator = FieldElement::new(1753635133440165772, field); + // let omicron = generator.clone(); + let order = 1 << 32; + // let code = "++>+++++[<+>-]++++++++[<++++++>-]<.".to_string(); + let code2 = ">>[++-]<".to_string(); + let program = vm.compile(code2); + println!("{:?}", program.clone()); + let (rt, _, _) = vm.run(&program, "".to_string()); + println!("{:?}", rt); + // assert_eq!(program.len(), 2); + let (processor_matrix, memory_matrix, instruction_matrix, input_matrix, output_matrix) = + vm.simulate(&program, "".to_string()); + let challenges = vec![two; 11]; + let mut processor_table = ProcessorTable::new( + field, + processor_matrix.len() as u128, + generator, + order, + processor_matrix, + ); + let mut memory_table = MemoryTable::new( + field, + memory_matrix.len() as u128, + generator, + order, + memory_matrix, + ); + let mut instruction_table = InstructionTable::new( + field, + instruction_matrix.len() as u128, + generator, + order, + instruction_matrix, + ); + let mut input_table = IOTable::new( + field, + input_matrix.len() as u128, + generator, + order, + input_matrix, + ); + let mut output_table = IOTable::new( + field, + output_matrix.len() as u128, + generator, + order, + output_matrix, + ); + + processor_table.pad(); + memory_table.pad(); + instruction_table.pad(); + input_table.pad(); + output_table.pad(); + let terminal = memory_table.extend_column_ppa(1, challenges.clone()); + println!("memory_table after extending columns"); + for row in memory_table.table.matrix.clone() { + println!("{:?}", row); + } + println!("tppa: {:?}", terminal[0]); + let mut omicron_domain: Vec = Vec::new(); + for i in 0..memory_table.table.height { + omicron_domain.push(memory_table.table.omicron.pow(i)); + if i == 4 { + println!("omicron_domain: {:?}", omicron_domain); + } + } + + let air = memory_table.generate_air(challenges, terminal[0]); + + let b = air[0].evaluate(omicron_domain[1]); + + assert_ne!(b, zero); + for v in 0..rt - 1 { + let t_all = air[1].evaluate(omicron_domain[v as usize]); + // println!("{:?}", t_all); + assert_eq!(t_all, zero); + } + + let v = omicron_domain[3]; + + let t_air1 = air[2].evaluate(v); + + assert_ne!(t_air1, zero); + } } diff --git a/src/tables/mod.rs b/src/tables/mod.rs index 777875d..589606f 100644 --- a/src/tables/mod.rs +++ b/src/tables/mod.rs @@ -15,7 +15,7 @@ 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. - pub 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. @@ -78,7 +78,7 @@ impl Table { length: u128, generator: FieldElement, order: u128, - matrix: Vec> + matrix: Vec>, ) -> Self { let height = roundup_npow2(length); let omicron = derive_omicron(generator, order, height); @@ -211,7 +211,6 @@ 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 { diff --git a/src/tables/processor.rs b/src/tables/processor.rs index 2237783..c1c9bdf 100644 --- a/src/tables/processor.rs +++ b/src/tables/processor.rs @@ -129,7 +129,7 @@ impl ProcessorTable { } //the matrix taken here is padded - pub fn extend_columns(&mut self, challenges: Vec)->Vec { + pub fn extend_columns(&mut self, challenges: Vec) -> Vec { //@todo Note: Taking init 1 for now, change to random secret initial value which we check by difference constraint of tmpa = Tppa let mut ipa = FieldElement::one(self.table.field); let mut mpa = FieldElement::one(self.table.field); @@ -174,13 +174,16 @@ impl ProcessorTable { self.table.matrix[(i + 1) as usize][Indices::MemoryPermuation as usize] = mpa; } - let tmpa=mpa*(self.table.matrix[(self.table.length-1) as usize][Indices::Cycle as usize] - * challenges[ChallengeIndices::D as usize] - + self.table.matrix[(self.table.length-1) as usize][Indices::MemoryPointer as usize] - * challenges[ChallengeIndices::E as usize] - + self.table.matrix[(self.table.length -1)as usize][Indices::MemoryValue as usize] - * challenges[ChallengeIndices::F as usize] - - challenges[ChallengeIndices::Beta as usize]); + let tmpa = mpa + * (self.table.matrix[(self.table.length - 1) as usize][Indices::Cycle as usize] + * challenges[ChallengeIndices::D as usize] + + self.table.matrix[(self.table.length - 1) as usize] + [Indices::MemoryPointer as usize] + * challenges[ChallengeIndices::E as usize] + + self.table.matrix[(self.table.length - 1) as usize] + [Indices::MemoryValue as usize] + * challenges[ChallengeIndices::F as usize] + - challenges[ChallengeIndices::Beta as usize]); let f = |x: char| -> FieldElement { FieldElement::new((x as u32) as u128, self.table.field) }; @@ -205,9 +208,9 @@ impl ProcessorTable { self.table.matrix[(i + 1) as usize][Indices::OutputEvaluation as usize] = oea; } } - let tiea=iea; - let toea =oea; - let mut terminal:Vec=Vec::new(); + let tiea = iea; + let toea = oea; + let mut terminal: Vec = Vec::new(); terminal.push(tipa); terminal.push(tmpa); terminal.push(tiea); @@ -334,9 +337,23 @@ impl ProcessorTable { zerofiers } - pub fn generate_quotients(&self, challenges: Vec,tipa:FieldElement,tmpa:FieldElement,tiea:FieldElement,toea:FieldElement) -> Vec { + pub fn generate_quotients( + &self, + challenges: Vec, + tipa: FieldElement, + tmpa: FieldElement, + tiea: FieldElement, + toea: FieldElement, + ) -> Vec { let mut quotients = vec![]; - let air = self.generate_air(challenges,tipa,tmpa,tiea,toea, FieldElement::zero(self.table.field)); + let air = self.generate_air( + challenges, + tipa, + tmpa, + tiea, + toea, + FieldElement::zero(self.table.field), + ); let zerofiers = self.generate_zerofier(); for i in 0..air.len() { @@ -359,25 +376,32 @@ impl ProcessorTable { } //@ I am not using this function because it because universal selector is redundant // define a selector polynomial for a valid set if instruction from this set then it should be zero - pub fn universal_selector(ci: Polynomial, field: Field) ->Polynomial{ - let f = |x: char| -> FieldElement { FieldElement::new((x as u32) as u128, field) }; - // let mut deselectors = Vec::new(); - let mut acc = Polynomial::constant(FieldElement::new(1, field)); + pub fn universal_selector(ci: Polynomial, field: Field) -> Polynomial { + let f = |x: char| -> FieldElement { FieldElement::new((x as u32) as u128, field) }; + // let mut deselectors = Vec::new(); + let mut acc = Polynomial::constant(FieldElement::new(1, field)); - // for target_char in "[]<>,.+-".chars() { - let target_char = ['[',']','<','>',',','.','+','-']; + // for target_char in "[]<>,.+-".chars() { + let target_char = ['[', ']', '<', '>', ',', '.', '+', '-']; - for c in target_char.iter() { - - acc *= ci.clone() - Polynomial::constant(FieldElement::new(f(*c).0, field)); - - } acc - } + for c in target_char.iter() { + acc *= ci.clone() - Polynomial::constant(FieldElement::new(f(*c).0, field)); + } + acc + } // boundary constraints for the base coloumns // the values of instructionpermutaion ipa and mpa I am taking as 1 // @todo pa, ea are obtained when the table is extended. - pub fn generate_air(&self, challenges: Vec,tipa:FieldElement,tmpa:FieldElement,tiea:FieldElement,toea:FieldElement, eval: FieldElement) -> Vec { + pub fn generate_air( + &self, + challenges: Vec, + tipa: FieldElement, + tmpa: FieldElement, + tiea: FieldElement, + toea: FieldElement, + eval: FieldElement, + ) -> Vec { let f = |x: char| -> FieldElement { FieldElement::new((x as u32) as u128, self.table.field) }; let indices_vec = vec![ @@ -405,7 +429,7 @@ impl ProcessorTable { let mpa = interpolated[Indices::MemoryPermuation as usize].clone(); let iea = interpolated[Indices::InputEvaluation as usize].clone(); let oea = interpolated[Indices::OutputEvaluation as usize].clone(); - + let next_interpolated = self.table.clone().next_interpolate_columns(indices_vec); let clk_next = next_interpolated[Indices::Cycle as usize].clone(); let ip_next = next_interpolated[Indices::InstructionPointer as usize].clone(); @@ -415,7 +439,7 @@ impl ProcessorTable { let mpa_next = next_interpolated[Indices::MemoryPermuation as usize].clone(); let iea_next = next_interpolated[Indices::InputEvaluation as usize].clone(); let oea_next = next_interpolated[Indices::OutputEvaluation as usize].clone(); - + let mut air = vec![]; //Boundary contsraints :clk=mp=mv=inv=ip=0 //iea=oea=1 (we are using 1 instead of any random number) @@ -550,7 +574,7 @@ impl ProcessorTable { - oea_next.clone()) + (ci.clone() - Polynomial::constant(f('.'))) * (oea.clone() - oea_next.clone()); air.push(trasition_all); - //@todo have to seperate the terminal + //@todo have to seperate the terminal // Terminal constraints // tipa, tmpa- last row not accumulated so: // 1.ipa.(a.ip+ b.ci+c.ni-alpha)-tipa @@ -558,29 +582,30 @@ impl ProcessorTable { // tiea, toea- last element identical to terminal // 3.iea-tiea 4. oea-toea let terminal_air1 = ipa.clone() - * (ip - .clone() - .scalar_mul(challenges[ChallengeIndices::A as usize]) - + ci.clone() - .scalar_mul(challenges[ChallengeIndices::B as usize]) - + ni.clone() - .scalar_mul(challenges[ChallengeIndices::C as usize]) - - Polynomial::constant(challenges[ChallengeIndices::Alpha as usize])) + // * (ip + // .clone() + // .scalar_mul(challenges[ChallengeIndices::A as usize]) + // + ci.clone() + // .scalar_mul(challenges[ChallengeIndices::B as usize]) + // + ni.clone() + // .scalar_mul(challenges[ChallengeIndices::C as usize]) + // - Polynomial::constant(challenges[ChallengeIndices::Alpha as usize])) - Polynomial::constant(tipa); - + let terminal_air2 = mpa.clone() - * (clk.scalar_mul(challenges[ChallengeIndices::D as usize]) - + mp.clone() - .scalar_mul(challenges[ChallengeIndices::E as usize]) - + mv.clone() - .scalar_mul(challenges[ChallengeIndices::F as usize]) - - Polynomial::constant(challenges[ChallengeIndices::Beta as usize])) + * (clk.scalar_mul(challenges[ChallengeIndices::D as usize]) + + mp.clone() + .scalar_mul(challenges[ChallengeIndices::E as usize]) + + mv.clone() + .scalar_mul(challenges[ChallengeIndices::F as usize]) + - Polynomial::constant(challenges[ChallengeIndices::Beta as usize])) - Polynomial::constant(tmpa); - let terminal_air3 = iea - - Polynomial::constant(tiea); - let terminal_air4 = oea - - Polynomial::constant(toea); - let terminal = terminal_air1.clone()+terminal_air2.clone()+terminal_air3.clone()+terminal_air4.clone(); + let terminal_air3 = iea - Polynomial::constant(tiea); + let terminal_air4 = oea - Polynomial::constant(toea); + let terminal = terminal_air1.clone() + + terminal_air2.clone() + + terminal_air3.clone() + + terminal_air4.clone(); air.push(terminal); air } @@ -617,7 +642,7 @@ mod tests_processor_operations { } } #[test] - fn test_universal_selector(){ + fn test_universal_selector() { let field = Field::new((1 << 64) - (1 << 32) + 1); let f = |x: char| -> FieldElement { FieldElement::new((x as u32) as u128, field) }; let ci_array = vec!['[', ']', '<', '>', '-', '.', '+', ',']; @@ -635,17 +660,14 @@ mod tests_processor_operations { let domain = FriDomain::new(FieldElement::new(1, field), omicron, target_order); let ci = domain.interpolate(values_array); let poly = ProcessorTable::universal_selector(ci, field); - let values=poly.evaluate(omicron.pow(1)); - assert_eq!(values,FieldElement::zero(field)); - - - + let values = poly.evaluate(omicron.pow(1)); + assert_eq!(values, FieldElement::zero(field)); } } #[cfg(test)] mod test_processor { - use std::time::Instant; + use std::time::Instant; use super::ProcessorTable; use crate::fields::{Field, FieldElement}; @@ -686,7 +708,7 @@ mod test_processor { #[test] fn test_air() { - let field = Field::new((1<<64)-(1<<32)+1); + let field = Field::new((1 << 64) - (1 << 32) + 1); let zero = FieldElement::zero(field); let one = FieldElement::one(field); let two = one + one; @@ -745,7 +767,7 @@ mod test_processor { instruction_table.pad(); input_table.pad(); output_table.pad(); - let terminal = processor_table.extend_columns(challenges.clone()); + let terminal = processor_table.extend_columns(challenges.clone()); println!("processor table after extending columns"); for row in processor_table.table.matrix.clone() { println!("{:?}", row); @@ -755,32 +777,38 @@ mod test_processor { for i in 0..processor_table.table.height { omicron_domain.push(processor_table.table.omicron.pow(i)); if i == 4 { - println!("omicron_domain: {:?}", omicron_domain); + println!("omicron_domain: {:?}", omicron_domain); } } - let air = processor_table.generate_air(challenges, terminal[0], terminal[1], terminal[2], terminal[3], omicron_domain[4]); - let b = air[0].evaluate(omicron_domain[0]); + let air = processor_table.generate_air( + challenges, + terminal[0], + terminal[1], + terminal[2], + terminal[3], + omicron_domain[4], + ); + let b = air[0].evaluate(omicron_domain[0]); assert_eq!(b, zero); - - for v in 0..rt-1 { + + for v in 0..rt - 1 { let t_all = air[9].evaluate(omicron_domain[v as usize]); - + assert_eq!(t_all, zero); } - - let v =omicron_domain[4]; - - let t_air1 = air[10].evaluate(v); - assert_eq!(t_air1, zero); - + let v = omicron_domain[4]; + + let t_air1 = air[10].evaluate(v); + assert_eq!(t_air1, zero); + assert_eq!(air[5].evaluate(omicron_domain[1]), zero); assert_eq!(air[5].evaluate(omicron_domain[0]), zero); assert!(air[5].evaluate(omicron_domain[2]) != zero); } - #[test]//@todo the transition constraint on particular ci + #[test] //@todo the transition constraint on particular ci fn test_not_air() { - let field = Field::new((1<<64)-(1<<32)+1); + let field = Field::new((1 << 64) - (1 << 32) + 1); let zero = FieldElement::zero(field); let one = FieldElement::one(field); let two = one + one; @@ -849,25 +877,31 @@ mod test_processor { for i in 0..processor_table.table.height { omicron_domain.push(processor_table.table.omicron.pow(i)); if i == 4 { - println!("omicron_domain: {:?}", omicron_domain); + println!("omicron_domain: {:?}", omicron_domain); } } - let air = processor_table.generate_air(challenges, terminal[0], terminal[1], terminal[2], terminal[3], omicron_domain[4]); - + let air = processor_table.generate_air( + challenges, + terminal[0], + terminal[1], + terminal[2], + terminal[3], + omicron_domain[4], + ); + let b = air[0].evaluate(omicron_domain[1]); assert_ne!(b, zero); - - for v in 0..rt-1 { + + for v in 0..rt - 1 { let t_all = air[9].evaluate(omicron_domain[v as usize]); assert_eq!(t_all, zero); } - - let v =omicron_domain[3]; - - let t_air1 = air[10].evaluate(v); - assert_ne!(t_air1, zero); - + let v = omicron_domain[3]; + + let t_air1 = air[10].evaluate(v); + assert_ne!(t_air1, zero); + assert_eq!(air[5].evaluate(omicron_domain[1]), zero); assert_eq!(air[5].evaluate(omicron_domain[0]), zero); assert!(air[5].evaluate(omicron_domain[2]) != zero); From 032cb56ae792e0f72ddafd0f3649fece1a09b497 Mon Sep 17 00:00:00 2001 From: soumyathakur44 Date: Sat, 14 Dec 2024 20:49:01 +0530 Subject: [PATCH 2/3] constraints --- src/stark/mod.rs | 2 ++ src/tables/instruction.rs | 5 ++- src/tables/memory.rs | 10 +++++- src/tables/processor.rs | 74 +++++++++++++++++++++++++-------------- 4 files changed, 62 insertions(+), 29 deletions(-) diff --git a/src/stark/mod.rs b/src/stark/mod.rs index bf9552f..355f6c0 100644 --- a/src/stark/mod.rs +++ b/src/stark/mod.rs @@ -87,6 +87,7 @@ pub fn prove( let mut processor_table = ProcessorTable::new( field, matrices[0].clone().len() as u128, + roundup_npow2(matrices[2].len() as u128), generator, order, matrices[0].clone(), @@ -94,6 +95,7 @@ pub fn prove( let mut memory_table = MemoryTable::new( field, matrices[1].len() as u128, + roundup_npow2(matrices[2].len() as u128), generator, order, matrices[1].clone(), diff --git a/src/tables/instruction.rs b/src/tables/instruction.rs index b8e655c..f862193 100644 --- a/src/tables/instruction.rs +++ b/src/tables/instruction.rs @@ -295,6 +295,7 @@ mod test_instruction { use crate::tables::memory::MemoryTable; use crate::tables::processor::ProcessorTable; use crate::vm::VirtualMachine; + use crate::tables::roundup_npow2; #[test] fn test_padding() { @@ -346,7 +347,7 @@ mod test_instruction { let omicron = generator.clone(); let order = 1 << 32; // let code = "++>+++++[<+>-]++++++++[<++++++>-]<.".to_string(); - let code2 = ">>+.[++-]+.".to_string(); + let code2 = ">>[++-]+-".to_string(); let program = vm.compile(code2); println!("{:?}", program.clone()); let (rt, _, _) = vm.run(&program, "".to_string()); @@ -358,6 +359,7 @@ mod test_instruction { let mut processor_table = ProcessorTable::new( field, processor_matrix.len() as u128, + roundup_npow2(instruction_matrix.len() as u128), generator, order, processor_matrix, @@ -365,6 +367,7 @@ mod test_instruction { let mut memory_table = MemoryTable::new( field, memory_matrix.len() as u128, + roundup_npow2(instruction_matrix.len() as u128), generator, order, memory_matrix, diff --git a/src/tables/memory.rs b/src/tables/memory.rs index e6009a7..9cb6f4e 100644 --- a/src/tables/memory.rs +++ b/src/tables/memory.rs @@ -41,13 +41,14 @@ impl MemoryTable { pub fn new( field: Field, length: u128, + height: u128, generator: FieldElement, order: u128, matrix: Vec>, ) -> Self { let base_width = 3; let full_width = base_width + 1; - let height = roundup_npow2(length); + let height = height; let omicron = derive_omicron(generator, order, height); let mut gmatrix = @@ -274,6 +275,7 @@ mod test_memory_table { use crate::tables::processor::ProcessorTable; use crate::tables::Table; use crate::vm::VirtualMachine; + use crate::tables::roundup_npow2; #[test] fn test_padding() { @@ -289,6 +291,7 @@ mod test_memory_table { let mut memory_table = MemoryTable::new( field, memory_matrix.len() as u128, + roundup_npow2(instruction_matrix.len() as u128), generator, order, memory_matrix.clone(), @@ -316,6 +319,7 @@ mod test_memory_table { let mut mem = MemoryTable::new( field, memory_matrix.len() as u128, + roundup_npow2(instruction_matrix.len() as u128), generator, order, memory_matrix, @@ -424,6 +428,7 @@ mod test_memory_table { let mut processor_table = ProcessorTable::new( field, processor_matrix.len() as u128, + roundup_npow2(instruction_matrix.len() as u128), generator, order, processor_matrix, @@ -431,6 +436,7 @@ mod test_memory_table { let mut memory_table = MemoryTable::new( field, memory_matrix.len() as u128, + roundup_npow2(instruction_matrix.len() as u128), generator, order, memory_matrix, @@ -518,6 +524,7 @@ mod test_memory_table { let mut processor_table = ProcessorTable::new( field, processor_matrix.len() as u128, + roundup_npow2(instruction_matrix.len() as u128), generator, order, processor_matrix, @@ -525,6 +532,7 @@ mod test_memory_table { let mut memory_table = MemoryTable::new( field, memory_matrix.len() as u128, + roundup_npow2(instruction_matrix.len() as u128), generator, order, memory_matrix, diff --git a/src/tables/processor.rs b/src/tables/processor.rs index 7b570e6..c280566 100644 --- a/src/tables/processor.rs +++ b/src/tables/processor.rs @@ -70,13 +70,14 @@ impl ProcessorTable { pub fn new( field: Field, length: u128, + height: u128, generator: FieldElement, order: u128, matrix: Vec>, ) -> Self { let base_width = 7; let full_width = base_width + 4; - let height = roundup_npow2(length); + let height = height; let omicron = derive_omicron(generator, order, height); let mut gmatrix = vec![vec![FieldElement::zero(field); full_width as usize]; height as usize]; @@ -489,7 +490,7 @@ impl ProcessorTable { //ci =< // ip⋆−ip−1 // mp⋆−mp+1 - let trasition_i2 = (ip_next.clone() - ip.clone() - poly_one.clone()) + let trasition_i2 = (ip_next.clone() - ip.clone() - poly_one.clone())*poly_two.clone() + (mp_next.clone() - mp.clone() + poly_one.clone()); air.push(trasition_i2); //ci=> @@ -512,7 +513,7 @@ impl ProcessorTable { // mp⋆−mp // mv⋆−mv+1 // ci = - - let trasition_i5 = (ip_next.clone() - ip.clone() - poly_one.clone()) + let trasition_i5 = (ip_next.clone() - ip.clone() - poly_one.clone())*poly_two.clone() + (mp_next.clone() - mp.clone()) + (mv_next.clone() - mv.clone() + poly_one.clone()); air.push(trasition_i5); @@ -677,6 +678,7 @@ mod test_processor { use crate::tables::io::IOTable; use crate::tables::memory::MemoryTable; use crate::tables::processor::Indices; + use crate::tables::roundup_npow2; use crate::vm::VirtualMachine; #[test] @@ -694,6 +696,7 @@ mod test_processor { let mut processor_table = ProcessorTable::new( field, processor_matrix.len() as u128, + roundup_npow2(processor_matrix.len() as u128), generator, order, processor_matrix, @@ -731,6 +734,7 @@ mod test_processor { let mut processor_table = ProcessorTable::new( field, processor_matrix.len() as u128, + roundup_npow2(instruction_matrix.len() as u128), generator, order, processor_matrix, @@ -738,6 +742,7 @@ mod test_processor { let mut memory_table = MemoryTable::new( field, memory_matrix.len() as u128, + roundup_npow2(instruction_matrix.len() as u128), generator, order, memory_matrix, @@ -769,12 +774,21 @@ mod test_processor { instruction_table.pad(); input_table.pad(); output_table.pad(); + let terminal = processor_table.extend_columns(challenges.clone()); + let terminal2 = memory_table.extend_column_ppa(1, challenges.clone()); + println!("processor table after extending columns"); for row in processor_table.table.matrix.clone() { println!("{:?}", row); } + println!("memory table after extending columns"); + for row in memory_table.table.matrix.clone() { + println!("{:?}", row); + } + println!("tmpa: {:?}", terminal[1]); + println!("tppa: {:?}", terminal2[0]); let mut omicron_domain: Vec = Vec::new(); for i in 0..processor_table.table.height { omicron_domain.push(processor_table.table.omicron.pow(i)); @@ -819,7 +833,7 @@ mod test_processor { // let omicron = generator.clone(); let order = 1 << 32; // let code = "++>+++++[<+>-]++++++++[<++++++>-]<.".to_string(); - let code2 = ">>[++-]<".to_string(); + let code2 = ">>[++-]<+-".to_string(); let program = vm.compile(code2); println!("{:?}", program.clone()); let (rt, _, _) = vm.run(&program, "".to_string()); @@ -831,6 +845,7 @@ mod test_processor { let mut processor_table = ProcessorTable::new( field, processor_matrix.len() as u128, + roundup_npow2(instruction_matrix.len() as u128), generator, order, processor_matrix, @@ -838,6 +853,7 @@ mod test_processor { let mut memory_table = MemoryTable::new( field, memory_matrix.len() as u128, + roundup_npow2(instruction_matrix.len() as u128), generator, order, memory_matrix, @@ -899,29 +915,33 @@ mod test_processor { assert_eq!(t_all, zero); } - let v =omicron_domain[3]; - - let t_air1 = air[10].evaluate(v); - assert_ne!(t_air1, zero); - for v in omicron_domain.clone(){ - println!("{:?}",air[3].evaluate(v)) - } - for v in omicron_domain.clone(){ - println!("{:?}",air[4].evaluate(v)) - } - for v in omicron_domain.clone(){ - println!("{:?}",air[5].evaluate(v)) - } - for v in omicron_domain.clone(){ - println!("{:?}",air[6].evaluate(v)) - } - - - - + //let v =omicron_domain[1]; + // let t_air1 = air[10].evaluate(v); + // println!("{:?}",air[0].evaluate(v)); + //assert_ne!(t_air1, zero); + + + for v in omicron_domain.clone(){ + println!("{:?}", air[3].evaluate(v)) + } + println!("this was <"); + for v in omicron_domain.clone(){ + println!("{:?}",air[4].evaluate(v)) + } + println!("this was >"); + for v in omicron_domain.clone(){ + println!("{:?}",air[5].evaluate(v)) + } + println!("this was +"); + for v in omicron_domain.clone(){ + println!("{:?}",air[6].evaluate(v)) + } + println!("this was -"); - assert_eq!(air[4].evaluate(omicron_domain[1]), zero); - assert_eq!(air[4].evaluate(omicron_domain[0]), zero); - assert!(air[4].evaluate(omicron_domain[2]) != zero); + assert_eq!(air[4].evaluate(omicron_domain[1]), zero); + assert_eq!(air[4].evaluate(omicron_domain[0]), zero); + assert!(air[4].evaluate(omicron_domain[2]) != zero); + } + } From 17b99df6124ba4485a01ac5c50203414a500fb43 Mon Sep 17 00:00:00 2001 From: soumyathakur44 Date: Sun, 15 Dec 2024 19:21:30 +0530 Subject: [PATCH 3/3] io --- src/stark/mod.rs | 4 +- src/tables/processor.rs | 133 +++++++++++++++++++++++++++++++++++----- 2 files changed, 122 insertions(+), 15 deletions(-) diff --git a/src/stark/mod.rs b/src/stark/mod.rs index 355f6c0..462f029 100644 --- a/src/stark/mod.rs +++ b/src/stark/mod.rs @@ -43,7 +43,9 @@ impl log::Log for ConsoleLogger { //@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 +//transition has this bt +//input ouput giving lots of bt, run hone me excess time, input string bt, ask manoj + pub struct Stark<'a> { pub running_time: i32, pub memory_length: usize, diff --git a/src/tables/processor.rs b/src/tables/processor.rs index c280566..1df4248 100644 --- a/src/tables/processor.rs +++ b/src/tables/processor.rs @@ -721,8 +721,9 @@ mod test_processor { let generator = FieldElement::new(1753635133440165772, field); // let omicron = generator.clone(); let order = 1 << 32; - // let code = "++>+++++[<+>-]++++++++[<++++++>-]<.".to_string(); - let code2 = ">>[++-]<".to_string(); + let code2 = "++>+++++[<+>-]++++++++[<++++++>-]<.".to_string(); + // let code2 = ">>[++-]<".to_string(); + let program = vm.compile(code2); println!("{:?}", program.clone()); let (rt, _, _) = vm.run(&program, "".to_string()); @@ -782,13 +783,13 @@ mod test_processor { for row in processor_table.table.matrix.clone() { println!("{:?}", row); } - println!("memory table after extending columns"); - for row in memory_table.table.matrix.clone() { + println!("output table after extending columns"); + for row in output_table.table.matrix.clone() { println!("{:?}", row); } - println!("tmpa: {:?}", terminal[1]); - println!("tppa: {:?}", terminal2[0]); + // println!("tmpa: {:?}", terminal[1]); + // println!("tppa: {:?}", terminal2[0]); let mut omicron_domain: Vec = Vec::new(); for i in 0..processor_table.table.height { omicron_domain.push(processor_table.table.omicron.pow(i)); @@ -813,14 +814,9 @@ mod test_processor { assert_eq!(t_all, zero); } - let v = omicron_domain[4]; - - let t_air1 = air[10].evaluate(v); - assert_eq!(t_air1, zero); - - assert_eq!(air[5].evaluate(omicron_domain[1]), zero); - assert_eq!(air[5].evaluate(omicron_domain[0]), zero); - assert!(air[5].evaluate(omicron_domain[2]) != zero); + // assert_eq!(air[5].evaluate(omicron_domain[1]), zero); + // assert_eq!(air[5].evaluate(omicron_domain[0]), zero); + // assert!(air[5].evaluate(omicron_domain[2]) != zero); } #[test] //@todo the transition constraint on particular ci fn test_not_air() { @@ -941,7 +937,116 @@ mod test_processor { assert_eq!(air[4].evaluate(omicron_domain[1]), zero); assert_eq!(air[4].evaluate(omicron_domain[0]), zero); assert!(air[4].evaluate(omicron_domain[2]) != zero); + } + + #[test] + fn IO_program() { + let field = Field::new((1 << 64) - (1 << 32) + 1); + let zero = FieldElement::zero(field); + let one = FieldElement::one(field); + let two = one + one; + let vm = VirtualMachine::new(field); + let generator = FieldElement::new(1753635133440165772, field); + // let omicron = generator.clone(); + let order = 1 << 32; + let code2 = "++.>,++,.".to_string(); + + let program = vm.compile(code2); + println!("{:?}", program.clone()); + let (rt, _, _) = vm.run(&program, "15".to_string()); + println!("{:?}", rt); + + let (processor_matrix, memory_matrix, instruction_matrix, input_matrix, output_matrix) = + vm.simulate(&program, "15".to_string()); + let challenges = vec![two; 11]; + let mut processor_table = ProcessorTable::new( + field, + processor_matrix.len() as u128, + roundup_npow2(instruction_matrix.len() as u128), + generator, + order, + processor_matrix, + ); + let mut memory_table = MemoryTable::new( + field, + memory_matrix.len() as u128, + roundup_npow2(instruction_matrix.len() as u128), + generator, + order, + memory_matrix, + ); + let mut instruction_table = InstructionTable::new( + field, + instruction_matrix.len() as u128, + generator, + order, + instruction_matrix, + ); + let mut input_table = IOTable::new( + field, + input_matrix.len() as u128, + generator, + order, + input_matrix, + ); + let mut output_table = IOTable::new( + field, + output_matrix.len() as u128, + generator, + order, + output_matrix, + ); + + processor_table.pad(); + memory_table.pad(); + instruction_table.pad(); + input_table.pad(); + output_table.pad(); + + let terminal = processor_table.extend_columns(challenges.clone()); + let terminal2 = input_table.extend_column_ea(1, two); + let terminal3 = output_table.extend_column_ea(1, two); + + println!("processor table after extending columns"); + for row in processor_table.table.matrix.clone() { + println!("{:?}", row); + } + println!("input table after extending columns"); + for row in input_table.table.matrix.clone() { + println!("{:?}", row); + } + println!("output table after extending columns"); + for row in output_table.table.matrix.clone() { + println!("{:?}", row); + } + + let mut omicron_domain: Vec = Vec::new(); + for i in 0..processor_table.table.height { + omicron_domain.push(processor_table.table.omicron.pow(i)); + if i == 4 { + println!("omicron_domain: {:?}", omicron_domain); + } + } + let air = processor_table.generate_air( + challenges, + terminal[0], + terminal[1], + terminal[2], + terminal[3], + omicron_domain[4], + ); + let f = |x: char| -> FieldElement { FieldElement::new((x as u32) as u128, field) }; + + println!("{} {}", f('1'), f('5')) + + // let b = air[0].evaluate(omicron_domain[0]); + // assert_eq!(b, zero); + + // for v in 0..rt - 1 { + // let t_all = air[9].evaluate(omicron_domain[v as usize]); + // assert_eq!(t_all, zero); + // } } }