NOT stark (#565)

* NOT operation stark

* Daniel PR comment
This commit is contained in:
Jacqueline Nabaglo 2022-06-14 16:55:08 -07:00 committed by GitHub
parent 732002691b
commit 49219a2b11
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 109 additions and 3 deletions

View File

@ -144,4 +144,8 @@ pub const KECCAK_INPUT_LIMBS: Range<usize> = START_KECCAK_INPUT..START_KECCAK_IN
pub const START_KECCAK_OUTPUT: usize = KECCAK_INPUT_LIMBS.end;
pub const KECCAK_OUTPUT_LIMBS: Range<usize> = START_KECCAK_OUTPUT..START_KECCAK_OUTPUT + 50;
pub const NUM_CPU_COLUMNS: usize = KECCAK_OUTPUT_LIMBS.end;
// Assuming a limb size of 16 bits.
pub const SIMPLE_LOGIC_INPUT0: Range<usize> = KECCAK_OUTPUT_LIMBS.end..KECCAK_OUTPUT_LIMBS.end + 16;
pub const SIMPLE_LOGIC_OUTPUT: Range<usize> = SIMPLE_LOGIC_INPUT0.end..SIMPLE_LOGIC_INPUT0.end + 16;
pub const NUM_CPU_COLUMNS: usize = SIMPLE_LOGIC_OUTPUT.end;

View File

@ -5,8 +5,7 @@ use plonky2::field::packed_field::PackedField;
use plonky2::hash::hash_types::RichField;
use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer};
use crate::cpu::columns;
use crate::cpu::decode;
use crate::cpu::{columns, decode, simple_logic};
use crate::permutation::PermutationPair;
use crate::stark::Stark;
use crate::vars::{StarkEvaluationTargets, StarkEvaluationVars};
@ -19,6 +18,7 @@ pub struct CpuStark<F, const D: usize> {
impl<F: RichField, const D: usize> CpuStark<F, D> {
pub fn generate(&self, local_values: &mut [F; columns::NUM_CPU_COLUMNS]) {
decode::generate(local_values);
simple_logic::generate(local_values);
}
}
@ -35,6 +35,7 @@ impl<F: RichField + Extendable<D>, const D: usize> Stark<F, D> for CpuStark<F, D
P: PackedField<Scalar = FE>,
{
decode::eval_packed_generic(vars.local_values, yield_constr);
simple_logic::eval_packed(vars.local_values, yield_constr);
}
fn eval_ext_circuit(
@ -44,6 +45,7 @@ impl<F: RichField + Extendable<D>, const D: usize> Stark<F, D> for CpuStark<F, D
yield_constr: &mut RecursiveConstraintConsumer<F, D>,
) {
decode::eval_ext_circuit(builder, vars.local_values, yield_constr);
simple_logic::eval_ext_circuit(builder, vars.local_values, yield_constr);
}
fn constraint_degree(&self) -> usize {

View File

@ -1,3 +1,4 @@
pub(crate) mod columns;
pub mod cpu_stark;
pub(crate) mod decode;
mod simple_logic;

View File

@ -0,0 +1,34 @@
mod not;
use plonky2::field::extension_field::Extendable;
use plonky2::field::packed_field::PackedField;
use plonky2::hash::hash_types::RichField;
use plonky2::iop::ext_target::ExtensionTarget;
use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer};
use crate::cpu::columns;
pub fn generate<F: RichField>(lv: &mut [F; columns::NUM_CPU_COLUMNS]) {
let cycle_filter = lv[columns::IS_CPU_CYCLE].to_canonical_u64();
if cycle_filter == 0 {
return;
}
assert_eq!(cycle_filter, 1);
not::generate(lv);
}
pub fn eval_packed<P: PackedField>(
lv: &[P; columns::NUM_CPU_COLUMNS],
yield_constr: &mut ConstraintConsumer<P>,
) {
not::eval_packed(lv, yield_constr);
}
pub fn eval_ext_circuit<F: RichField + Extendable<D>, const D: usize>(
builder: &mut plonky2::plonk::circuit_builder::CircuitBuilder<F, D>,
lv: &[ExtensionTarget<D>; columns::NUM_CPU_COLUMNS],
yield_constr: &mut RecursiveConstraintConsumer<F, D>,
) {
not::eval_ext_circuit(builder, lv, yield_constr);
}

View File

@ -0,0 +1,65 @@
use plonky2::field::extension_field::Extendable;
use plonky2::field::field_types::Field;
use plonky2::field::packed_field::PackedField;
use plonky2::hash::hash_types::RichField;
use plonky2::iop::ext_target::ExtensionTarget;
use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer};
use crate::cpu::columns;
const LIMB_SIZE: usize = 16;
const ALL_1_LIMB: u64 = (1 << LIMB_SIZE) - 1;
pub fn generate<F: RichField>(lv: &mut [F; columns::NUM_CPU_COLUMNS]) {
let is_not_filter = lv[columns::IS_NOT].to_canonical_u64();
if is_not_filter == 0 {
return;
}
assert_eq!(is_not_filter, 1);
for (input_col, output_col) in columns::SIMPLE_LOGIC_INPUT0.zip(columns::SIMPLE_LOGIC_OUTPUT) {
let input = lv[input_col].to_canonical_u64();
assert_eq!(input >> LIMB_SIZE, 0);
let output = input ^ ALL_1_LIMB;
lv[output_col] = F::from_canonical_u64(output);
}
}
pub fn eval_packed<P: PackedField>(
lv: &[P; columns::NUM_CPU_COLUMNS],
yield_constr: &mut ConstraintConsumer<P>,
) {
// This is simple: just do output = 0xffff - input.
let cycle_filter = lv[columns::IS_CPU_CYCLE];
let is_not_filter = lv[columns::IS_NOT];
let filter = cycle_filter * is_not_filter;
for (input_col, output_col) in columns::SIMPLE_LOGIC_INPUT0.zip(columns::SIMPLE_LOGIC_OUTPUT) {
let input = lv[input_col];
let output = lv[output_col];
yield_constr
.constraint(filter * (output + input - P::Scalar::from_canonical_u64(ALL_1_LIMB)));
}
}
pub fn eval_ext_circuit<F: RichField + Extendable<D>, const D: usize>(
builder: &mut plonky2::plonk::circuit_builder::CircuitBuilder<F, D>,
lv: &[ExtensionTarget<D>; columns::NUM_CPU_COLUMNS],
yield_constr: &mut RecursiveConstraintConsumer<F, D>,
) {
let cycle_filter = lv[columns::IS_CPU_CYCLE];
let is_not_filter = lv[columns::IS_NOT];
let filter = builder.mul_extension(cycle_filter, is_not_filter);
for (input_col, output_col) in columns::SIMPLE_LOGIC_INPUT0.zip(columns::SIMPLE_LOGIC_OUTPUT) {
let input = lv[input_col];
let output = lv[output_col];
let constr = builder.add_extension(output, input);
let constr = builder.arithmetic_extension(
F::ONE,
-F::from_canonical_u64(ALL_1_LIMB),
filter,
constr,
filter,
);
yield_constr.constraint(builder, constr);
}
}