Skip to content

Commit

Permalink
chore: submit memory prototype
Browse files Browse the repository at this point in the history
  • Loading branch information
eigmax committed Oct 14, 2023
1 parent 3255e0b commit 660be3f
Show file tree
Hide file tree
Showing 5 changed files with 285 additions and 164 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ tiny-keccak = "2.0.2"
rand = "0.8.5"
rand_chacha = "0.3.1"
once_cell = "1.13.0"
static_assertions = "1.1.0"

[dev-dependencies]
env_logger = { version = "0.9.0", default-features = false }
Expand Down
24 changes: 12 additions & 12 deletions src/all_stark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ use plonky2::field::extension::Extendable;
use plonky2::field::types::Field;
use plonky2::hash::hash_types::RichField;

//use crate::arithmetic::arithmetic_stark;
//use crate::arithmetic::arithmetic_stark::ArithmeticStark;
use crate::arithmetic::arithmetic_stark;
use crate::arithmetic::arithmetic_stark::ArithmeticStark;
//use crate::byte_packing::byte_packing_stark::{self, BytePackingStark};
use crate::config::StarkConfig;
use crate::cpu::cpu_stark;
Expand All @@ -25,7 +25,7 @@ use crate::stark::Stark;

#[derive(Clone)]
pub struct AllStark<F: RichField + Extendable<D>, const D: usize> {
// pub arithmetic_stark: ArithmeticStark<F, D>,
pub arithmetic_stark: ArithmeticStark<F, D>,
// pub byte_packing_stark: BytePackingStark<F, D>,
pub cpu_stark: CpuStark<F, D>,
pub keccak_stark: KeccakStark<F, D>,
Expand All @@ -38,7 +38,7 @@ pub struct AllStark<F: RichField + Extendable<D>, const D: usize> {
impl<F: RichField + Extendable<D>, const D: usize> Default for AllStark<F, D> {
fn default() -> Self {
Self {
// arithmetic_stark: ArithmeticStark::default(),
arithmetic_stark: ArithmeticStark::default(),
// byte_packing_stark: BytePackingStark::default(),
cpu_stark: CpuStark::default(),
keccak_stark: KeccakStark::default(),
Expand Down Expand Up @@ -66,21 +66,21 @@ impl<F: RichField + Extendable<D>, const D: usize> AllStark<F, D> {

#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum Table {
// Arithmetic = 0,
Arithmetic = 0,
// BytePacking = 1,
Cpu = 0,
Keccak = 1,
KeccakSponge = 2,
Logic = 3,
Memory = 4,
Cpu = 1,
Keccak = 2,
KeccakSponge = 3,
Logic = 4,
Memory = 5,
}

pub(crate) const NUM_TABLES: usize = Table::Memory as usize + 1;

impl Table {
pub(crate) fn all() -> [Self; NUM_TABLES] {
[
// Self::Arithmetic,
Self::Arithmetic,
// Self::BytePacking,
Self::Cpu,
Self::Keccak,
Expand All @@ -103,14 +103,14 @@ pub(crate) fn all_cross_table_lookups<F: Field>() -> Vec<CrossTableLookup<F>> {
]
}

/*
fn ctl_arithmetic<F: Field>() -> CrossTableLookup<F> {
CrossTableLookup::new(
vec![cpu_stark::ctl_arithmetic_base_rows()],
arithmetic_stark::ctl_arithmetic_rows(),
)
}

/*
fn ctl_byte_packing<F: Field>() -> CrossTableLookup<F> {
let cpu_packing_looking = TableWithColumns::new(
Table::Cpu,
Expand Down
270 changes: 270 additions & 0 deletions src/arithmetic/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,271 @@
pub mod arithmetic_stark;
pub mod columns;
pub mod shift;
pub mod addcy;
pub mod divmod;
pub mod mul;
pub mod utils;

use num::Zero;
use plonky2::field::types::PrimeField64;
use crate::util::*;

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub(crate) enum BinaryOperator {
Add,
Mul,
Sub,
Div,
Mod,
Lt,
Gt,
//Byte,
Shl, // simulated with MUL
Shr, // simulated with DIV
}

impl BinaryOperator {
pub(crate) fn result(&self, input0: u32, input1: u32) -> u32 {
match self {
BinaryOperator::Add => input0.overflowing_add(input1).0,
BinaryOperator::Mul => input0.overflowing_mul(input1).0,
BinaryOperator::Shl => {
if input0 < 256 {
input1 << input0
} else {
u32::zero()
}
}
BinaryOperator::Sub => input0.overflowing_sub(input1).0,
BinaryOperator::Div => {
if input1.is_zero() {
u32::zero()
} else {
input0 / input1
}
}
BinaryOperator::Shr => {
if input0 < 256 {
input1 >> input0
} else {
u32::zero()
}
}
BinaryOperator::Mod => {
if input1.is_zero() {
u32::zero()
} else {
input0 % input1
}
}
BinaryOperator::Lt => u32::from((input0 < input1) as u8),
BinaryOperator::Gt => u32::from((input0 > input1) as u8),
/*
BinaryOperator::Byte => {
if input0 >= 32.into() {
u32::zero()
} else {
input1.byte(31 - input0.as_usize()).into()
}
}
*/
}
}

pub(crate) fn row_filter(&self) -> usize {
match self {
BinaryOperator::Add => columns::IS_ADD,
BinaryOperator::Mul => columns::IS_MUL,
BinaryOperator::Sub => columns::IS_SUB,
BinaryOperator::Div => columns::IS_DIV,
BinaryOperator::Mod => columns::IS_MOD,
BinaryOperator::Lt => columns::IS_LT,
BinaryOperator::Gt => columns::IS_GT,
//BinaryOperator::Byte => columns::IS_BYTE,
BinaryOperator::Shl => columns::IS_SHL,
BinaryOperator::Shr => columns::IS_SHR,
}
}
}

#[allow(clippy::enum_variant_names)]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub(crate) enum TernaryOperator {
AddMod,
MulMod,
SubMod,
}

impl TernaryOperator {
pub(crate) fn result(&self, input0: u32, input1: u32, input2: u32) -> u32 {
match self {
TernaryOperator::AddMod => ((input0 + input1) % input2),
TernaryOperator::MulMod => ((input0 * input1) % input2),
TernaryOperator::SubMod => ((input0 - input1) % input2),
}
}

pub(crate) fn row_filter(&self) -> usize {
match self {
TernaryOperator::AddMod => columns::IS_ADDMOD,
TernaryOperator::MulMod => columns::IS_MULMOD,
TernaryOperator::SubMod => columns::IS_SUBMOD,
}
}
}

/// An enum representing arithmetic operations that can be either binary or ternary.
#[derive(Debug)]
pub(crate) enum Operation {
BinaryOperation {
operator: BinaryOperator,
input0: u32,
input1: u32,
result: u32,
},
TernaryOperation {
operator: TernaryOperator,
input0: u32,
input1: u32,
input2: u32,
result: u32,
},
}

impl Operation {
/// Create a binary operator with given inputs.
///
/// NB: This works as you would expect, EXCEPT for SHL and SHR,
/// whose inputs need a small amount of preprocessing. Specifically,
/// to create `SHL(shift, value)`, call (note the reversal of
/// argument order):
///
/// `Operation::binary(BinaryOperator::Shl, value, 1 << shift)`
///
/// Similarly, to create `SHR(shift, value)`, call
///
/// `Operation::binary(BinaryOperator::Shr, value, 1 << shift)`
///
/// See witness/operation.rs::append_shift() for an example (indeed
/// the only call site for such inputs).
pub(crate) fn binary(operator: BinaryOperator, input0: u32, input1: u32) -> Self {
let result = operator.result(input0, input1);
Self::BinaryOperation {
operator,
input0,
input1,
result,
}
}

pub(crate) fn ternary(
operator: TernaryOperator,
input0: u32,
input1: u32,
input2: u32,
) -> Self {
let result = operator.result(input0, input1, input2);
Self::TernaryOperation {
operator,
input0,
input1,
input2,
result,
}
}

pub(crate) fn result(&self) -> u32 {
match self {
Operation::BinaryOperation { result, .. } => *result,
Operation::TernaryOperation { result, .. } => *result,
}
}

/// Convert operation into one or two rows of the trace.
///
/// Morally these types should be [F; NUM_ARITH_COLUMNS], but we
/// use vectors because that's what utils::transpose (who consumes
/// the result of this function as part of the range check code)
/// expects.
///
/// The `is_simulated` bool indicates whether we use a native arithmetic
/// operation or simulate one with another. This is used to distinguish
/// SHL and SHR operations that are simulated through MUL and DIV respectively.
fn to_rows<F: PrimeField64>(&self) -> (Vec<F>, Option<Vec<F>>) {
match *self {
Operation::BinaryOperation {
operator,
input0,
input1,
result,
} => binary_op_to_rows(operator, input0, input1, result),
Operation::TernaryOperation {
operator,
input0,
input1,
input2,
result,
} => ternary_op_to_rows(operator.row_filter(), input0, input1, input2, result),
}
}
}

fn ternary_op_to_rows<F: PrimeField64>(
row_filter: usize,
input0: u32,
input1: u32,
input2: u32,
_result: u32,
) -> (Vec<F>, Option<Vec<F>>) {
let mut row1 = vec![F::ZERO; columns::NUM_ARITH_COLUMNS];
let mut row2 = vec![F::ZERO; columns::NUM_ARITH_COLUMNS];

row1[row_filter] = F::ONE;

// FIXME
// modular::generate(&mut row1, &mut row2, row_filter, input0, input1, input2);

(row1, Some(row2))
}

fn binary_op_to_rows<F: PrimeField64>(
op: BinaryOperator,
input0: u32,
input1: u32,
result: u32,
) -> (Vec<F>, Option<Vec<F>>) {
let mut row = vec![F::ZERO; columns::NUM_ARITH_COLUMNS];
row[op.row_filter()] = F::ONE;

match op {
BinaryOperator::Add | BinaryOperator::Sub | BinaryOperator::Lt | BinaryOperator::Gt => {
addcy::generate(&mut row, op.row_filter(), input0, input1);
(row, None)
}
BinaryOperator::Mul => {
mul::generate(&mut row, input0, input1);
(row, None)
}
BinaryOperator::Shl => {
let mut nv = vec![F::ZERO; columns::NUM_ARITH_COLUMNS];
shift::generate(&mut row, &mut nv, true, input0, input1, result);
(row, None)
}
BinaryOperator::Div | BinaryOperator::Mod => {
let mut nv = vec![F::ZERO; columns::NUM_ARITH_COLUMNS];
divmod::generate(&mut row, &mut nv, op.row_filter(), input0, input1, result);
(row, Some(nv))
}
BinaryOperator::Shr => {
let mut nv = vec![F::ZERO; columns::NUM_ARITH_COLUMNS];
shift::generate(&mut row, &mut nv, false, input0, input1, result);
(row, Some(nv))
}
/*
BinaryOperator::Byte => {
byte::generate(&mut row, input0, input1);
(row, None)
}
*/
}
}
4 changes: 2 additions & 2 deletions src/prover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,6 @@ where
F: RichField + Extendable<D>,
C: GenericConfig<D, F = F>,
{
/*
let arithmetic_proof = timed!(
timing,
"prove Arithmetic STARK",
Expand All @@ -191,6 +190,7 @@ where
timing,
)?
);
/*
let byte_packing_proof = timed!(
timing,
"prove byte packing STARK",
Expand Down Expand Up @@ -278,7 +278,7 @@ where
);

Ok([
//arithmetic_proof,
arithmetic_proof,
//byte_packing_proof,
cpu_proof,
keccak_proof,
Expand Down
Loading

0 comments on commit 660be3f

Please sign in to comment.