Update sha256 example to work with new API

This commit is contained in:
therealyingtong 2021-07-16 23:33:22 +08:00
parent 61c431edc7
commit 66268cf192
15 changed files with 355 additions and 633 deletions

View File

@ -1,10 +1,10 @@
use halo2::{
arithmetic::FieldExt,
circuit::{layouter::SingleChipLayouter, Layouter},
circuit::{Layouter, SimpleFloorPlanner},
pasta::EqAffine,
plonk::{
create_proof, keygen_pk, keygen_vk, verify_proof, Assignment, Circuit, ConstraintSystem,
Error, VerifyingKey,
create_proof, keygen_pk, keygen_vk, verify_proof, Circuit, ConstraintSystem, Error,
VerifyingKey,
},
poly::commitment::Params,
transcript::{Blake2bRead, Blake2bWrite, Challenge255},
@ -22,10 +22,16 @@ use crate::{BlockWord, Sha256, Table16Chip, Table16Config, BLOCK_SIZE};
#[allow(dead_code)]
fn bench(name: &str, k: u32, c: &mut Criterion) {
#[derive(Default)]
struct MyCircuit {}
impl<F: FieldExt> Circuit<F> for MyCircuit {
type Config = Table16Config;
type FloorPlanner = SimpleFloorPlanner;
fn without_witnesses(&self) -> Self {
Self::default()
}
fn configure(meta: &mut ConstraintSystem<F>) -> Self::Config {
Table16Chip::configure(meta)
@ -33,10 +39,9 @@ fn bench(name: &str, k: u32, c: &mut Criterion) {
fn synthesize(
&self,
cs: &mut impl Assignment<F>,
config: Self::Config,
mut layouter: impl Layouter<F>,
) -> Result<(), Error> {
let mut layouter = SingleChipLayouter::new(cs)?;
Table16Chip::<F>::load(config.clone(), &mut layouter)?;
let table16_chip = Table16Chip::<F>::construct(config);
@ -155,7 +160,7 @@ fn bench(name: &str, k: u32, c: &mut Criterion) {
#[allow(dead_code)]
fn criterion_benchmark(c: &mut Criterion) {
bench("sha256", 16, c);
bench("sha256", 17, c);
// bench("sha256", 20, c);
}

View File

@ -2,7 +2,6 @@
//!
//! [SHA-256]: https://tools.ietf.org/html/rfc6234
/*
use std::cmp::min;
use std::convert::TryInto;
use std::fmt;
@ -169,6 +168,5 @@ impl<F: FieldExt, Sha256Chip: Sha256Instructions<F>> Sha256<F, Sha256Chip> {
hasher.finalize(layouter.namespace(|| "finalize"))
}
}
*/
fn main() {}

View File

@ -4,7 +4,7 @@ use super::Sha256Instructions;
use halo2::{
arithmetic::FieldExt,
circuit::{Cell, Chip, Layouter, Region},
plonk::{Advice, Column, ConstraintSystem, Error, Permutation},
plonk::{Advice, Column, ConstraintSystem, Error},
};
mod compression;
@ -91,6 +91,7 @@ impl CellValue32 {
}
}
#[allow(clippy::from_over_into)]
impl Into<CellValue32> for CellValue16 {
fn into(self) -> CellValue32 {
CellValue32::new(self.var, self.value.unwrap() as u32)
@ -165,30 +166,16 @@ impl<F: FieldExt> Table16Chip<F> {
let a_8 = extras[4];
let _a_9 = extras[5];
let perm = Permutation::new(
meta,
&[
a_1.into(),
a_2.into(),
a_3.into(),
a_4.into(),
a_5.into(),
a_6.into(),
a_7.into(),
a_8.into(),
],
);
// Add all advice columns to permutation
for column in [a_1, a_2, a_3, a_4, a_5, a_6, a_7, a_8].iter() {
meta.enable_equality((*column).into());
}
let compression = CompressionConfig::configure(
meta,
lookup_inputs.clone(),
message_schedule,
extras,
perm.clone(),
);
let compression =
CompressionConfig::configure(meta, lookup_inputs.clone(), message_schedule, extras);
let message_schedule =
MessageScheduleConfig::configure(meta, lookup_inputs, message_schedule, extras, perm);
MessageScheduleConfig::configure(meta, lookup_inputs, message_schedule, extras);
Table16Config {
lookup,
@ -260,7 +247,6 @@ trait Table16Assignment<F: FieldExt> {
region: &mut Region<'_, F>,
lookup: &SpreadInputs,
a_3: Column<Advice>,
perm: &Permutation,
row: usize,
r_0_even: u16,
r_0_odd: u16,
@ -280,7 +266,7 @@ trait Table16Assignment<F: FieldExt> {
row,
|| Ok(F::from_u64(r_1_odd.spread.value.unwrap().into())),
)?;
region.constrain_equal(perm, r_1_odd.spread.var, r_1_odd_spread)?;
region.constrain_equal(r_1_odd.spread.var, r_1_odd_spread)?;
Ok((
(
@ -301,7 +287,6 @@ trait Table16Assignment<F: FieldExt> {
region: &mut Region<'_, F>,
lookup: &SpreadInputs,
a_3: Column<Advice>,
perm: &Permutation,
row: usize,
r_0_even: u16,
r_0_odd: u16,
@ -309,7 +294,7 @@ trait Table16Assignment<F: FieldExt> {
r_1_odd: u16,
) -> Result<(CellValue16, CellValue16), Error> {
let (even, _odd) = self.assign_spread_outputs(
region, lookup, a_3, perm, row, r_0_even, r_0_odd, r_1_even, r_1_odd,
region, lookup, a_3, row, r_0_even, r_0_odd, r_1_even, r_1_odd,
)?;
Ok(even)
@ -323,7 +308,6 @@ trait Table16Assignment<F: FieldExt> {
column: Column<Advice>,
row: usize,
copy: &CellValue32,
perm: &Permutation,
) -> Result<Cell, Error>
where
A: Fn() -> AR,
@ -332,7 +316,7 @@ trait Table16Assignment<F: FieldExt> {
let cell = region.assign_advice(annotation, column, row, || {
Ok(F::from_u64(copy.value.unwrap() as u64))
})?;
region.constrain_equal(perm, cell, copy.var)?;
region.constrain_equal(cell, copy.var)?;
Ok(cell)
}
}
@ -343,9 +327,9 @@ mod tests {
use super::{Table16Chip, Table16Config};
use halo2::{
arithmetic::FieldExt,
circuit::{layouter::SingleChipLayouter, Layouter},
circuit::{Layouter, SimpleFloorPlanner},
pasta::Fq,
plonk::{Assignment, Circuit, ConstraintSystem, Error},
plonk::{Circuit, ConstraintSystem, Error},
};
#[cfg(feature = "dev-graph")]
@ -355,6 +339,11 @@ mod tests {
impl<F: FieldExt> Circuit<F> for MyCircuit {
type Config = Table16Config;
type FloorPlanner = SimpleFloorPlanner;
fn without_witnesses(&self) -> Self {
MyCircuit {}
}
fn configure(meta: &mut ConstraintSystem<F>) -> Self::Config {
Table16Chip::configure(meta)
@ -362,10 +351,9 @@ mod tests {
fn synthesize(
&self,
cs: &mut impl Assignment<F>,
config: Self::Config,
mut layouter: impl Layouter<F>,
) -> Result<(), Error> {
let mut layouter = SingleChipLayouter::new(cs)?;
let table16_chip = Table16Chip::<F>::construct(config.clone());
Table16Chip::<F>::load(config, &mut layouter)?;
@ -412,6 +400,11 @@ mod tests {
impl<F: FieldExt> Circuit<F> for MyCircuit {
type Config = Table16Config;
type FloorPlanner = SimpleFloorPlanner;
fn without_witnesses(&self) -> Self {
MyCircuit {}
}
fn configure(meta: &mut ConstraintSystem<F>) -> Self::Config {
Table16Chip::configure(meta)
@ -419,10 +412,9 @@ mod tests {
fn synthesize(
&self,
cs: &mut impl Assignment<F>,
config: Self::Config,
mut layouter: impl Layouter<F>,
) -> Result<(), Error> {
let mut layouter = SingleChipLayouter::new(cs)?;
let table16_chip = Table16Chip::<F>::construct(config.clone());
Table16Chip::<F>::load(config, &mut layouter)?;
@ -465,6 +457,8 @@ mod tests {
.unwrap();
let circuit = MyCircuit {};
halo2::dev::circuit_layout::<Fq, _, _>(&circuit, &root).unwrap();
halo2::dev::CircuitLayout::default()
.render::<Fq, _, _>(&circuit, &root)
.unwrap();
}
}

View File

@ -5,7 +5,7 @@ use super::{
use halo2::{
arithmetic::FieldExt,
circuit::Layouter,
plonk::{Advice, Column, ConstraintSystem, Error, Fixed, Permutation},
plonk::{Advice, Column, ConstraintSystem, Error, Fixed},
poly::Rotation,
};
@ -90,6 +90,7 @@ impl RoundWordSpread {
}
}
#[allow(clippy::from_over_into)]
impl Into<RoundWordDense> for RoundWordSpread {
fn into(self) -> RoundWordDense {
RoundWordDense::new(self.dense_halves)
@ -125,6 +126,7 @@ impl RoundWordA {
}
}
#[allow(clippy::from_over_into)]
impl Into<RoundWordSpread> for RoundWordA {
fn into(self) -> RoundWordSpread {
RoundWordSpread::new(self.dense_halves, self.spread_halves.unwrap())
@ -160,6 +162,7 @@ impl RoundWordE {
}
}
#[allow(clippy::from_over_into)]
impl Into<RoundWordSpread> for RoundWordE {
fn into(self) -> RoundWordSpread {
RoundWordSpread::new(self.dense_halves, self.spread_halves.unwrap())
@ -252,8 +255,6 @@ pub(super) struct CompressionConfig {
s_decompose_efgh: Column<Fixed>,
s_digest: Column<Fixed>,
perm: Permutation,
}
impl<F: FieldExt> Table16Assignment<F> for CompressionConfig {}
@ -264,7 +265,6 @@ impl CompressionConfig {
lookup: SpreadInputs,
message_schedule: Column<Advice>,
extras: [Column<Advice>; 6],
perm: Permutation,
) -> Self {
let s_ch = meta.fixed_column();
let s_ch_neg = meta.fixed_column();
@ -339,7 +339,6 @@ impl CompressionConfig {
word_hi,
spread_word_hi,
)
.0
});
// Decompose `E,F,G,H` words into (6, 5, 14, 7)-bit chunks.
@ -387,7 +386,6 @@ impl CompressionConfig {
word_hi,
spread_word_hi,
)
.0
});
// s_upper_sigma_0 on abcd words
@ -419,7 +417,6 @@ impl CompressionConfig {
spread_c_hi,
spread_d,
)
.0
});
// s_upper_sigma_1 on efgh words
@ -450,7 +447,6 @@ impl CompressionConfig {
spread_c,
spread_d,
)
.0
});
// s_ch on efgh words
@ -477,7 +473,6 @@ impl CompressionConfig {
spread_f_lo,
spread_f_hi,
)
.0
});
// s_ch_neg on efgh words
@ -508,7 +503,6 @@ impl CompressionConfig {
spread_g_lo,
spread_g_hi,
)
.0
});
// s_maj on abcd words
@ -538,7 +532,6 @@ impl CompressionConfig {
spread_c_lo,
spread_c_hi,
)
.0
});
// s_h_prime to compute H' = H + Ch(E, F, G) + s_upper_sigma_1(E) + K + W
@ -578,7 +571,6 @@ impl CompressionConfig {
w_lo,
w_hi,
)
.0
});
// s_a_new
@ -606,7 +598,6 @@ impl CompressionConfig {
h_prime_lo,
h_prime_hi,
)
.0
});
// s_e_new
@ -630,7 +621,6 @@ impl CompressionConfig {
h_prime_lo,
h_prime_hi,
)
.0
});
// s_digest for final round
@ -653,7 +643,6 @@ impl CompressionConfig {
s_digest, lo_0, hi_0, word_0, lo_1, hi_1, word_1, lo_2, hi_2, word_2, lo_3, hi_3,
word_3,
)
.0
});
CompressionConfig {
@ -671,7 +660,6 @@ impl CompressionConfig {
s_decompose_abcd,
s_decompose_efgh,
s_digest,
perm,
}
}
@ -759,10 +747,10 @@ mod tests {
};
use halo2::{
arithmetic::FieldExt,
circuit::layouter::SingleChipLayouter,
circuit::{Layouter, SimpleFloorPlanner},
dev::MockProver,
pasta::Fp,
plonk::{Assignment, Circuit, ConstraintSystem, Error},
plonk::{Circuit, ConstraintSystem, Error},
};
#[test]
@ -771,6 +759,11 @@ mod tests {
impl<F: FieldExt> Circuit<F> for MyCircuit {
type Config = Table16Config;
type FloorPlanner = SimpleFloorPlanner;
fn without_witnesses(&self) -> Self {
MyCircuit {}
}
fn configure(meta: &mut ConstraintSystem<F>) -> Self::Config {
Table16Chip::configure(meta)
@ -778,10 +771,9 @@ mod tests {
fn synthesize(
&self,
cs: &mut impl Assignment<F>,
config: Self::Config,
mut layouter: impl Layouter<F>,
) -> Result<(), Error> {
let mut layouter = SingleChipLayouter::new(cs)?;
Table16Chip::<F>::load(config.clone(), &mut layouter)?;
// Test vector: "abc"
@ -811,7 +803,7 @@ mod tests {
let circuit: MyCircuit = MyCircuit {};
let prover = match MockProver::<Fp>::run(16, &circuit, vec![]) {
let prover = match MockProver::<Fp>::run(17, &circuit, vec![]) {
Ok(prover) => prover,
Err(e) => panic!("{:?}", e),
};

View File

@ -1,7 +1,8 @@
use super::super::{util::*, Gate};
use halo2::{arithmetic::FieldExt, plonk::Expression};
use std::{array, marker::PhantomData};
pub struct CompressionGate<F: FieldExt>(pub Expression<F>);
pub struct CompressionGate<F: FieldExt>(PhantomData<F>);
impl<F: FieldExt> CompressionGate<F> {
fn ones() -> Expression<F> {
@ -31,12 +32,18 @@ impl<F: FieldExt> CompressionGate<F> {
spread_word_lo: Expression<F>,
word_hi: Expression<F>,
spread_word_hi: Expression<F>,
) -> Self {
) -> impl Iterator<Item = (&'static str, Expression<F>)> {
let check_spread_and_range =
Gate::three_bit_spread_and_range(c_lo.clone(), spread_c_lo.clone())
+ Gate::three_bit_spread_and_range(c_mid.clone(), spread_c_mid.clone())
+ Gate::three_bit_spread_and_range(c_hi.clone(), spread_c_hi.clone())
+ Gate::two_bit_spread_and_range(a.clone(), spread_a.clone());
.chain(Gate::three_bit_spread_and_range(
c_mid.clone(),
spread_c_mid.clone(),
))
.chain(Gate::three_bit_spread_and_range(
c_hi.clone(),
spread_c_hi.clone(),
))
.chain(Gate::two_bit_spread_and_range(a.clone(), spread_a.clone()));
let range_check_tag_b = Gate::range_check(tag_b, 0, 2);
let range_check_tag_d = Gate::range_check(tag_d, 0, 1);
let dense_check = a
@ -56,14 +63,12 @@ impl<F: FieldExt> CompressionGate<F> {
+ spread_word_lo * (-F::one())
+ spread_word_hi * F::from_u64(1 << 32) * (-F::one());
CompressionGate(
s_decompose_abcd
* (range_check_tag_b
+ range_check_tag_d
+ dense_check
+ spread_check
+ check_spread_and_range),
)
check_spread_and_range
.chain(Some(("range_check_tag_b", range_check_tag_b)))
.chain(Some(("range_check_tag_d", range_check_tag_d)))
.chain(Some(("dense_check", dense_check)))
.chain(Some(("spread_check", spread_check)))
.map(move |(name, poly)| (name, s_decompose_abcd.clone() * poly))
}
// Decompose `E,F,G,H` words
@ -89,12 +94,21 @@ impl<F: FieldExt> CompressionGate<F> {
spread_word_lo: Expression<F>,
word_hi: Expression<F>,
spread_word_hi: Expression<F>,
) -> Self {
) -> impl Iterator<Item = (&'static str, Expression<F>)> {
let check_spread_and_range =
Gate::three_bit_spread_and_range(a_lo.clone(), spread_a_lo.clone())
+ Gate::three_bit_spread_and_range(a_hi.clone(), spread_a_hi.clone())
+ Gate::three_bit_spread_and_range(b_hi.clone(), spread_b_hi.clone())
+ Gate::two_bit_spread_and_range(b_lo.clone(), spread_b_lo.clone());
.chain(Gate::three_bit_spread_and_range(
a_hi.clone(),
spread_a_hi.clone(),
))
.chain(Gate::three_bit_spread_and_range(
b_hi.clone(),
spread_b_hi.clone(),
))
.chain(Gate::two_bit_spread_and_range(
b_lo.clone(),
spread_b_lo.clone(),
));
let range_check_tag_c = Gate::range_check(tag_c, 0, 4);
let range_check_tag_d = Gate::range_check(tag_d, 0, 0);
let dense_check = a_lo
@ -114,14 +128,12 @@ impl<F: FieldExt> CompressionGate<F> {
+ spread_word_lo * (-F::one())
+ spread_word_hi * F::from_u64(1 << 32) * (-F::one());
CompressionGate(
s_decompose_efgh
* (range_check_tag_c
+ range_check_tag_d
+ dense_check
+ spread_check
+ check_spread_and_range),
)
check_spread_and_range
.chain(Some(("range_check_tag_c", range_check_tag_c)))
.chain(Some(("range_check_tag_d", range_check_tag_d)))
.chain(Some(("dense_check", dense_check)))
.chain(Some(("spread_check", spread_check)))
.map(move |(name, poly)| (name, s_decompose_efgh.clone() * poly))
}
// s_upper_sigma_0 on abcd words
@ -139,7 +151,7 @@ impl<F: FieldExt> CompressionGate<F> {
spread_c_mid: Expression<F>,
spread_c_hi: Expression<F>,
spread_d: Expression<F>,
) -> Self {
) -> impl Iterator<Item = (&'static str, Expression<F>)> {
let spread_witness = spread_r0_even
+ spread_r0_odd * F::from_u64(2)
+ (spread_r1_even + spread_r1_odd * F::from_u64(2)) * F::from_u64(1 << 32);
@ -162,8 +174,9 @@ impl<F: FieldExt> CompressionGate<F> {
+ spread_c_mid * F::from_u64(1 << 52)
+ spread_c_hi * F::from_u64(1 << 58);
let xor = xor_0 + xor_1 + xor_2;
let check = spread_witness + (xor * -F::one());
CompressionGate(s_upper_sigma_0 * (spread_witness + (xor * -F::one())))
std::iter::empty().chain(Some(("s_upper_sigma_0", s_upper_sigma_0 * check)))
}
// s_upper_sigma_1 on efgh words
@ -181,7 +194,7 @@ impl<F: FieldExt> CompressionGate<F> {
spread_b_hi: Expression<F>,
spread_c: Expression<F>,
spread_d: Expression<F>,
) -> Self {
) -> impl Iterator<Item = (&'static str, Expression<F>)> {
let spread_witness = spread_r0_even
+ spread_r0_odd * F::from_u64(2)
+ (spread_r1_even + spread_r1_odd * F::from_u64(2)) * F::from_u64(1 << 32);
@ -205,8 +218,9 @@ impl<F: FieldExt> CompressionGate<F> {
+ spread_b_hi * F::from_u64(1 << 30)
+ spread_c * F::from_u64(1 << 36);
let xor = xor_0 + xor_1 + xor_2;
let check = spread_witness + (xor * -F::one());
CompressionGate(s_upper_sigma_1 * (spread_witness + (xor * -F::one())))
std::iter::empty().chain(Some(("s_upper_sigma_1", s_upper_sigma_1 * check)))
}
// First part of choice gate on (E, F, G), E ∧ F
@ -221,7 +235,7 @@ impl<F: FieldExt> CompressionGate<F> {
spread_e_hi: Expression<F>,
spread_f_lo: Expression<F>,
spread_f_hi: Expression<F>,
) -> Self {
) -> impl Iterator<Item = (&'static str, Expression<F>)> {
let lhs_lo = spread_e_lo + spread_f_lo;
let lhs_hi = spread_e_hi + spread_f_hi;
let lhs = lhs_lo + lhs_hi * F::from_u64(1 << 32);
@ -230,7 +244,9 @@ impl<F: FieldExt> CompressionGate<F> {
let rhs_odd = spread_p0_odd + spread_p1_odd * F::from_u64(1 << 32);
let rhs = rhs_even + rhs_odd * F::from_u64(2);
CompressionGate(s_ch * (lhs + rhs * -F::one()))
let check = lhs + rhs * -F::one();
std::iter::empty().chain(Some(("s_ch", s_ch * check)))
}
// Second part of Choice gate on (E, F, G), ¬E ∧ G
@ -247,13 +263,19 @@ impl<F: FieldExt> CompressionGate<F> {
spread_e_neg_hi: Expression<F>,
spread_g_lo: Expression<F>,
spread_g_hi: Expression<F>,
) -> Self {
let neg_check = Self::neg_check(
spread_e_lo,
spread_e_hi,
spread_e_neg_lo.clone(),
spread_e_neg_hi.clone(),
);
) -> impl Iterator<Item = (&'static str, Expression<F>)> {
let neg_check = {
let evens = Self::ones() * F::from_u64(MASK_EVEN_32 as u64);
// evens - spread_e_lo = spread_e_neg_lo
let lo_check = spread_e_neg_lo.clone() + spread_e_lo + (evens.clone() * (-F::one()));
// evens - spread_e_hi = spread_e_neg_hi
let hi_check = spread_e_neg_hi.clone() + spread_e_hi + (evens * (-F::one()));
std::iter::empty()
.chain(Some(("lo_check", lo_check)))
.chain(Some(("hi_check", hi_check)))
};
let lhs_lo = spread_e_neg_lo + spread_g_lo;
let lhs_hi = spread_e_neg_hi + spread_g_hi;
let lhs = lhs_lo + lhs_hi * F::from_u64(1 << 32);
@ -262,7 +284,9 @@ impl<F: FieldExt> CompressionGate<F> {
let rhs_odd = spread_q0_odd + spread_q1_odd * F::from_u64(1 << 32);
let rhs = rhs_even + rhs_odd * F::from_u64(2);
CompressionGate(s_ch_neg * (neg_check + lhs + rhs * -F::one()))
neg_check
.chain(Some(("s_ch_neg", lhs - rhs)))
.map(move |(name, poly)| (name, s_ch_neg.clone() * poly))
}
// Majority gate on (A, B, C)
@ -279,7 +303,7 @@ impl<F: FieldExt> CompressionGate<F> {
spread_b_hi: Expression<F>,
spread_c_lo: Expression<F>,
spread_c_hi: Expression<F>,
) -> Self {
) -> impl Iterator<Item = (&'static str, Expression<F>)> {
let maj_even = spread_m_0_even + spread_m_1_even * F::from_u64(1 << 32);
let maj_odd = spread_m_0_odd + spread_m_1_odd * F::from_u64(1 << 32);
let maj = maj_even + maj_odd * F::from_u64(2);
@ -289,23 +313,7 @@ impl<F: FieldExt> CompressionGate<F> {
let c = spread_c_lo + spread_c_hi * F::from_u64(1 << 32);
let sum = a + b + c;
CompressionGate(s_maj * (sum + maj * -F::one()))
}
// Negation gate, used in second part of Choice gate
fn neg_check(
word_lo: Expression<F>,
word_hi: Expression<F>,
neg_word_lo: Expression<F>,
neg_word_hi: Expression<F>,
) -> Expression<F> {
let evens = Self::ones() * F::from_u64(MASK_EVEN_32 as u64);
// evens - word_lo = neg_word_lo
let lo_check = neg_word_lo + word_lo + (evens.clone() * (-F::one()));
// evens - word_hi = neg_word_hi
let hi_check = neg_word_hi + word_hi + (evens * (-F::one()));
lo_check + hi_check
std::iter::empty().chain(Some(("maj", s_maj * (sum - maj))))
}
// s_h_prime to get H' = H + Ch(E, F, G) + s_upper_sigma_1(E) + K + W
@ -327,19 +335,16 @@ impl<F: FieldExt> CompressionGate<F> {
k_hi: Expression<F>,
w_lo: Expression<F>,
w_hi: Expression<F>,
) -> Self {
) -> impl Iterator<Item = (&'static str, Expression<F>)> {
let lo = h_lo + ch_lo + ch_neg_lo + sigma_e_lo + k_lo + w_lo;
let hi = h_hi + ch_hi + ch_neg_hi + sigma_e_hi + k_hi + w_hi;
let sum = lo + hi * F::from_u64(1 << 16);
let h_prime = h_prime_lo + h_prime_hi * F::from_u64(1 << 16);
CompressionGate(
s_h_prime
* (sum
+ h_prime_carry * F::from_u64(1 << 32) * (-F::one())
+ h_prime * (-F::one())),
)
let check = sum - (h_prime_carry * F::from_u64(1 << 32)) - h_prime;
std::iter::empty().chain(Some(("s_h_prime", s_h_prime * check)))
}
// s_a_new to get A_new = H' + Maj(A, B, C) + s_upper_sigma_0(A)
@ -355,16 +360,15 @@ impl<F: FieldExt> CompressionGate<F> {
maj_abc_hi: Expression<F>,
h_prime_lo: Expression<F>,
h_prime_hi: Expression<F>,
) -> Self {
) -> impl Iterator<Item = (&'static str, Expression<F>)> {
let lo = sigma_a_lo + maj_abc_lo + h_prime_lo;
let hi = sigma_a_hi + maj_abc_hi + h_prime_hi;
let sum = lo + hi * F::from_u64(1 << 16);
let a_new = a_new_lo + a_new_hi * F::from_u64(1 << 16);
CompressionGate(
s_a_new
* (sum + a_new_carry * F::from_u64(1 << 32) * (-F::one()) + a_new * (-F::one())),
)
let check = sum - (a_new_carry * F::from_u64(1 << 32)) - a_new;
std::iter::empty().chain(Some(("s_a_new", s_a_new * check)))
}
// s_e_new to get E_new = H' + D
@ -378,20 +382,15 @@ impl<F: FieldExt> CompressionGate<F> {
d_hi: Expression<F>,
h_prime_lo: Expression<F>,
h_prime_hi: Expression<F>,
) -> Self {
) -> impl Iterator<Item = (&'static str, Expression<F>)> {
let lo = h_prime_lo + d_lo;
let hi = h_prime_hi + d_hi;
let sum = lo + hi * F::from_u64(1 << 16);
let e_new = e_new_lo + e_new_hi * F::from_u64(1 << 16);
CompressionGate(
s_e_new
* (sum + e_new_carry * F::from_u64(1 << 32) * (-F::one()) + e_new * (-F::one())),
)
}
let check = sum - (e_new_carry * F::from_u64(1 << 32)) - e_new;
fn check_lo_hi(lo: Expression<F>, hi: Expression<F>, word: Expression<F>) -> Expression<F> {
lo + hi * F::from_u64(1 << 16) + (word * (-F::one()))
std::iter::empty().chain(Some(("s_e_new", s_e_new * check)))
}
// s_digest on final round
@ -410,13 +409,17 @@ impl<F: FieldExt> CompressionGate<F> {
lo_3: Expression<F>,
hi_3: Expression<F>,
word_3: Expression<F>,
) -> Self {
CompressionGate(
s_digest
* (Self::check_lo_hi(lo_0, hi_0, word_0)
+ Self::check_lo_hi(lo_1, hi_1, word_1)
+ Self::check_lo_hi(lo_2, hi_2, word_2)
+ Self::check_lo_hi(lo_3, hi_3, word_3)),
)
) -> impl Iterator<Item = (&'static str, Expression<F>)> {
let check_lo_hi = |lo: Expression<F>, hi: Expression<F>, word: Expression<F>| {
lo + hi * F::from_u64(1 << 16) - word
};
array::IntoIter::new([
("check_lo_hi_0", check_lo_hi(lo_0, hi_0, word_0)),
("check_lo_hi_1", check_lo_hi(lo_1, hi_1, word_1)),
("check_lo_hi_2", check_lo_hi(lo_2, hi_2, word_2)),
("check_lo_hi_3", check_lo_hi(lo_3, hi_3, word_3)),
])
.map(move |(name, poly)| (name, s_digest.clone() * poly))
}
}

View File

@ -299,45 +299,17 @@ impl CompressionConfig {
)?;
// Assign `spread_a` and copy constraint
self.assign_and_constrain(
region,
|| "spread_a",
a_3,
row + 1,
&word.a.spread,
&self.perm,
)?;
self.assign_and_constrain(region, || "spread_a", a_3, row + 1, &word.a.spread)?;
// Assign `spread_b` and copy constraint
self.assign_and_constrain(region, || "spread_b", a_5, row, &word.b.spread, &self.perm)?;
self.assign_and_constrain(region, || "spread_b", a_5, row, &word.b.spread)?;
// Assign `spread_c_lo` and copy constraint
self.assign_and_constrain(
region,
|| "spread_c_lo",
a_3,
row - 1,
&word.c_lo.spread,
&self.perm,
)?;
self.assign_and_constrain(region, || "spread_c_lo", a_3, row - 1, &word.c_lo.spread)?;
// Assign `spread_c_mid` and copy constraint
self.assign_and_constrain(
region,
|| "spread_c_mid",
a_4,
row - 1,
&word.c_mid.spread,
&self.perm,
)?;
self.assign_and_constrain(region, || "spread_c_mid", a_4, row - 1, &word.c_mid.spread)?;
// Assign `spread_c_hi` and copy constraint
self.assign_and_constrain(
region,
|| "spread_c_hi",
a_4,
row + 1,
&word.c_hi.spread,
&self.perm,
)?;
self.assign_and_constrain(region, || "spread_c_hi", a_4, row + 1, &word.c_hi.spread)?;
// Assign `spread_d` and copy constraint
self.assign_and_constrain(region, || "spread_d", a_4, row, &word.d.spread, &self.perm)?;
self.assign_and_constrain(region, || "spread_d", a_4, row, &word.d.spread)?;
// Calculate R_0^{even}, R_0^{odd}, R_1^{even}, R_1^{odd}
let spread_a = word.a.spread.value.unwrap() as u64;
@ -374,7 +346,6 @@ impl CompressionConfig {
region,
&self.lookup,
a_3,
&self.perm,
row,
r_0_even,
r_0_odd,
@ -404,45 +375,17 @@ impl CompressionConfig {
)?;
// Assign `spread_a_lo` and copy constraint
self.assign_and_constrain(
region,
|| "spread_a_lo",
a_3,
row + 1,
&word.a_lo.spread,
&self.perm,
)?;
self.assign_and_constrain(region, || "spread_a_lo", a_3, row + 1, &word.a_lo.spread)?;
// Assign `spread_a_hi` and copy constraint
self.assign_and_constrain(
region,
|| "spread_a_hi",
a_4,
row + 1,
&word.a_hi.spread,
&self.perm,
)?;
self.assign_and_constrain(region, || "spread_a_hi", a_4, row + 1, &word.a_hi.spread)?;
// Assign `spread_b_lo` and copy constraint
self.assign_and_constrain(
region,
|| "spread_b_lo",
a_3,
row - 1,
&word.b_lo.spread,
&self.perm,
)?;
self.assign_and_constrain(region, || "spread_b_lo", a_3, row - 1, &word.b_lo.spread)?;
// Assign `spread_b_hi` and copy constraint
self.assign_and_constrain(
region,
|| "spread_b_hi",
a_4,
row - 1,
&word.b_hi.spread,
&self.perm,
)?;
self.assign_and_constrain(region, || "spread_b_hi", a_4, row - 1, &word.b_hi.spread)?;
// Assign `spread_c` and copy constraint
self.assign_and_constrain(region, || "spread_c", a_5, row, &word.c.spread, &self.perm)?;
self.assign_and_constrain(region, || "spread_c", a_5, row, &word.c.spread)?;
// Assign `spread_d` and copy constraint
self.assign_and_constrain(region, || "spread_d", a_4, row, &word.d.spread, &self.perm)?;
self.assign_and_constrain(region, || "spread_d", a_4, row, &word.d.spread)?;
// Calculate R_0^{even}, R_0^{odd}, R_1^{even}, R_1^{odd}
let spread_a_lo = word.a_lo.spread.value.unwrap() as u64;
@ -479,7 +422,6 @@ impl CompressionConfig {
region,
&self.lookup,
a_3,
&self.perm,
row,
r_0_even,
r_0_odd,
@ -503,7 +445,6 @@ impl CompressionConfig {
region,
&self.lookup,
a_3,
&self.perm,
row,
r_0_even,
r_0_odd,
@ -529,40 +470,12 @@ impl CompressionConfig {
region.assign_fixed(|| "s_ch", self.s_ch, row, || Ok(F::one()))?;
// Assign and copy spread_e_lo, spread_e_hi
self.assign_and_constrain(
region,
|| "spread_e_lo",
a_3,
row - 1,
&spread_halves_e.0,
&self.perm,
)?;
self.assign_and_constrain(
region,
|| "spread_e_hi",
a_4,
row - 1,
&spread_halves_e.1,
&self.perm,
)?;
self.assign_and_constrain(region, || "spread_e_lo", a_3, row - 1, &spread_halves_e.0)?;
self.assign_and_constrain(region, || "spread_e_hi", a_4, row - 1, &spread_halves_e.1)?;
// Assign and copy spread_f_lo, spread_f_hi
self.assign_and_constrain(
region,
|| "spread_f_lo",
a_3,
row + 1,
&spread_halves_f.0,
&self.perm,
)?;
self.assign_and_constrain(
region,
|| "spread_f_hi",
a_4,
row + 1,
&spread_halves_f.1,
&self.perm,
)?;
self.assign_and_constrain(region, || "spread_f_lo", a_3, row + 1, &spread_halves_f.0)?;
self.assign_and_constrain(region, || "spread_f_hi", a_4, row + 1, &spread_halves_f.1)?;
let p: u64 = spread_halves_e.0.value.unwrap() as u64
+ spread_halves_f.0.value.unwrap() as u64
@ -592,40 +505,12 @@ impl CompressionConfig {
let a_5 = self.message_schedule;
// Assign and copy spread_e_lo, spread_e_hi
self.assign_and_constrain(
region,
|| "spread_e_lo",
a_5,
row - 1,
&spread_halves_e.0,
&self.perm,
)?;
self.assign_and_constrain(
region,
|| "spread_e_hi",
a_5,
row,
&spread_halves_e.1,
&self.perm,
)?;
self.assign_and_constrain(region, || "spread_e_lo", a_5, row - 1, &spread_halves_e.0)?;
self.assign_and_constrain(region, || "spread_e_hi", a_5, row, &spread_halves_e.1)?;
// Assign and copy spread_g_lo, spread_g_hi
self.assign_and_constrain(
region,
|| "spread_g_lo",
a_3,
row + 1,
&spread_halves_g.0,
&self.perm,
)?;
self.assign_and_constrain(
region,
|| "spread_g_hi",
a_4,
row + 1,
&spread_halves_g.1,
&self.perm,
)?;
self.assign_and_constrain(region, || "spread_g_lo", a_3, row + 1, &spread_halves_g.0)?;
self.assign_and_constrain(region, || "spread_g_hi", a_4, row + 1, &spread_halves_g.1)?;
// Calculate neg_e_lo, neg_e_hi
let spread_e_lo = spread_halves_e.0.value.unwrap();
@ -673,7 +558,6 @@ impl CompressionConfig {
region,
&self.lookup,
a_3,
&self.perm,
row,
r_0_even,
r_0_odd,
@ -700,58 +584,16 @@ impl CompressionConfig {
region.assign_fixed(|| "s_maj", self.s_maj, row, || Ok(F::one()))?;
// Assign and copy spread_a_lo, spread_a_hi
self.assign_and_constrain(
region,
|| "spread_a_lo",
a_4,
row - 1,
&spread_halves_a.0,
&self.perm,
)?;
self.assign_and_constrain(
region,
|| "spread_a_hi",
a_5,
row - 1,
&spread_halves_a.1,
&self.perm,
)?;
self.assign_and_constrain(region, || "spread_a_lo", a_4, row - 1, &spread_halves_a.0)?;
self.assign_and_constrain(region, || "spread_a_hi", a_5, row - 1, &spread_halves_a.1)?;
// Assign and copy spread_b_lo, spread_b_hi
self.assign_and_constrain(
region,
|| "spread_b_lo",
a_4,
row,
&spread_halves_b.0,
&self.perm,
)?;
self.assign_and_constrain(
region,
|| "spread_b_hi",
a_5,
row,
&spread_halves_b.1,
&self.perm,
)?;
self.assign_and_constrain(region, || "spread_b_lo", a_4, row, &spread_halves_b.0)?;
self.assign_and_constrain(region, || "spread_b_hi", a_5, row, &spread_halves_b.1)?;
// Assign and copy spread_c_lo, spread_c_hi
self.assign_and_constrain(
region,
|| "spread_c_lo",
a_4,
row + 1,
&spread_halves_c.0,
&self.perm,
)?;
self.assign_and_constrain(
region,
|| "spread_c_hi",
a_5,
row + 1,
&spread_halves_c.1,
&self.perm,
)?;
self.assign_and_constrain(region, || "spread_c_lo", a_4, row + 1, &spread_halves_c.0)?;
self.assign_and_constrain(region, || "spread_c_hi", a_5, row + 1, &spread_halves_c.1)?;
let m: u64 = spread_halves_a.0.value.unwrap() as u64
+ spread_halves_b.0.value.unwrap() as u64
@ -791,26 +633,12 @@ impl CompressionConfig {
let a_9 = self.extras[5];
// Assign and copy h
self.assign_and_constrain(region, || "h_lo", a_7, row - 1, &h.0.into(), &self.perm)?;
self.assign_and_constrain(region, || "h_hi", a_7, row, &h.1.into(), &self.perm)?;
self.assign_and_constrain(region, || "h_lo", a_7, row - 1, &h.0.into())?;
self.assign_and_constrain(region, || "h_hi", a_7, row, &h.1.into())?;
// Assign and copy sigma_1
self.assign_and_constrain(
region,
|| "sigma_1_lo",
a_4,
row,
&sigma_1.0.into(),
&self.perm,
)?;
self.assign_and_constrain(
region,
|| "sigma_1_hi",
a_5,
row,
&sigma_1.1.into(),
&self.perm,
)?;
self.assign_and_constrain(region, || "sigma_1_lo", a_4, row, &sigma_1.0.into())?;
self.assign_and_constrain(region, || "sigma_1_hi", a_5, row, &sigma_1.1.into())?;
// Assign k
let k_pieces = chop_u32(k, &[16, 16]);
@ -823,36 +651,15 @@ impl CompressionConfig {
region.assign_advice(|| "k_hi", a_6, row, || Ok(F::from_u64(k_pieces[1] as u64)))?;
// Assign and copy w
self.assign_and_constrain(region, || "w_lo", a_8, row - 1, &w.0.into(), &self.perm)?;
self.assign_and_constrain(region, || "w_hi", a_8, row, &w.1.into(), &self.perm)?;
self.assign_and_constrain(region, || "w_lo", a_8, row - 1, &w.0.into())?;
self.assign_and_constrain(region, || "w_hi", a_8, row, &w.1.into())?;
// Assign and copy ch
self.assign_and_constrain(
region,
|| "ch_neg_hi",
a_6,
row + 1,
&ch.1.into(),
&self.perm,
)?;
self.assign_and_constrain(region, || "ch_neg_hi", a_6, row + 1, &ch.1.into())?;
// Assign and copy ch_neg
self.assign_and_constrain(
region,
|| "ch_neg_lo",
a_5,
row - 1,
&ch_neg.0.into(),
&self.perm,
)?;
self.assign_and_constrain(
region,
|| "ch_neg_hi",
a_5,
row + 1,
&ch_neg.1.into(),
&self.perm,
)?;
self.assign_and_constrain(region, || "ch_neg_lo", a_5, row - 1, &ch_neg.0.into())?;
self.assign_and_constrain(region, || "ch_neg_hi", a_5, row + 1, &ch_neg.1.into())?;
// Assign h_prime, h_prime_carry
let h_prime_lo = h.0.value.unwrap() as u32
@ -914,8 +721,8 @@ impl CompressionConfig {
let a_9 = self.extras[5];
// Assign and copy d_lo, d_hi
self.assign_and_constrain(region, || "d_lo", a_7, row, &d.0.into(), &self.perm)?;
self.assign_and_constrain(region, || "d_hi", a_7, row + 1, &d.1.into(), &self.perm)?;
self.assign_and_constrain(region, || "d_lo", a_7, row, &d.0.into())?;
self.assign_and_constrain(region, || "d_hi", a_7, row + 1, &d.1.into())?;
// Assign e_new, e_new_carry
let e_new_lo = h_prime.0.value.unwrap() as u32 + d.0.value.unwrap() as u32;
@ -956,50 +763,15 @@ impl CompressionConfig {
let a_9 = self.extras[5];
// Assign and copy maj_1
self.assign_and_constrain(
region,
|| "maj_1_hi",
a_3,
row - 1,
&maj.1.into(),
&self.perm,
)?;
self.assign_and_constrain(region, || "maj_1_hi", a_3, row - 1, &maj.1.into())?;
// Assign and copy sigma_0
self.assign_and_constrain(
region,
|| "sigma_0_lo",
a_6,
row,
&sigma_0.0.into(),
&self.perm,
)?;
self.assign_and_constrain(
region,
|| "sigma_0_hi",
a_6,
row + 1,
&sigma_0.1.into(),
&self.perm,
)?;
self.assign_and_constrain(region, || "sigma_0_lo", a_6, row, &sigma_0.0.into())?;
self.assign_and_constrain(region, || "sigma_0_hi", a_6, row + 1, &sigma_0.1.into())?;
// Assign and copy h_prime
self.assign_and_constrain(
region,
|| "h_prime_lo",
a_7,
row - 1,
&h_prime.0.into(),
&self.perm,
)?;
self.assign_and_constrain(
region,
|| "h_prime_hi",
a_8,
row - 1,
&h_prime.1.into(),
&self.perm,
)?;
self.assign_and_constrain(region, || "h_prime_lo", a_7, row - 1, &h_prime.0.into())?;
self.assign_and_constrain(region, || "h_prime_hi", a_8, row - 1, &h_prime.1.into())?;
// Assign a_new, a_new_carry
let a_new_lo = h_prime.0.value.unwrap() as u32

View File

@ -28,22 +28,8 @@ impl CompressionConfig {
region.assign_fixed(|| "s_digest", self.s_digest, efgh_row, || Ok(F::one()))?;
// Assign digest for A, B, C, D
self.assign_and_constrain(
region,
|| "a_lo",
a_3,
abcd_row,
&a.dense_halves.0.into(),
&self.perm,
)?;
self.assign_and_constrain(
region,
|| "a_hi",
a_4,
abcd_row,
&a.dense_halves.1.into(),
&self.perm,
)?;
self.assign_and_constrain(region, || "a_lo", a_3, abcd_row, &a.dense_halves.0.into())?;
self.assign_and_constrain(region, || "a_hi", a_4, abcd_row, &a.dense_halves.1.into())?;
let a = a.dense_halves.0.value.unwrap() as u32
+ (1 << 16) * (a.dense_halves.1.value.unwrap() as u32);
region.assign_advice(|| "a", a_5, abcd_row, || Ok(F::from_u64(a as u64)))?;
@ -53,22 +39,8 @@ impl CompressionConfig {
let d = self.assign_digest_word(region, abcd_row + 1, a_6, a_7, a_8, d.dense_halves)?;
// Assign digest for E, F, G, H
self.assign_and_constrain(
region,
|| "e_lo",
a_3,
efgh_row,
&e.dense_halves.0.into(),
&self.perm,
)?;
self.assign_and_constrain(
region,
|| "e_hi",
a_4,
efgh_row,
&e.dense_halves.1.into(),
&self.perm,
)?;
self.assign_and_constrain(region, || "e_lo", a_3, efgh_row, &e.dense_halves.0.into())?;
self.assign_and_constrain(region, || "e_hi", a_4, efgh_row, &e.dense_halves.1.into())?;
let e = e.dense_halves.0.value.unwrap() as u32
+ (1 << 16) * (e.dense_halves.1.value.unwrap() as u32);
region.assign_advice(|| "e", a_5, efgh_row, || Ok(F::from_u64(e as u64)))?;
@ -98,22 +70,8 @@ impl CompressionConfig {
word_col: Column<Advice>,
dense_halves: (CellValue16, CellValue16),
) -> Result<u32, Error> {
self.assign_and_constrain(
region,
|| "lo",
lo_col,
row,
&dense_halves.0.into(),
&self.perm,
)?;
self.assign_and_constrain(
region,
|| "hi",
hi_col,
row,
&dense_halves.1.into(),
&self.perm,
)?;
self.assign_and_constrain(region, || "lo", lo_col, row, &dense_halves.0.into())?;
self.assign_and_constrain(region, || "hi", hi_col, row, &dense_halves.1.into())?;
let val = dense_halves.0.value.unwrap() as u32
+ (1 << 16) * (dense_halves.1.value.unwrap() as u32);
region.assign_advice(|| "word", word_col, row, || Ok(F::from_u64(val as u64)))?;

View File

@ -67,7 +67,6 @@ impl CompressionConfig {
a_7,
a_new_row,
&a_new_dense.0.into(),
&self.perm,
)?;
self.assign_and_constrain(
region,
@ -75,7 +74,6 @@ impl CompressionConfig {
a_7,
a_new_row + 1,
&a_new_dense.1.into(),
&self.perm,
)?;
// Assign and copy E_new
@ -86,7 +84,6 @@ impl CompressionConfig {
a_7,
e_new_row,
&e_new_dense.0.into(),
&self.perm,
)?;
self.assign_and_constrain(
region,
@ -94,7 +91,6 @@ impl CompressionConfig {
a_7,
e_new_row + 1,
&e_new_dense.1.into(),
&self.perm,
)?;
// Decompose A into (2, 11, 9, 10)-bit chunks

View File

@ -68,50 +68,57 @@ impl<F: FieldExt> Gate<F> {
expr
}
// 2-bit range check
fn two_bit_range_check(value: Expression<F>) -> Expression<F> {
Self::range_check(value, 0, (1 << 2) - 1)
}
// 2-bit spread interpolation
fn two_bit_spread(dense: Expression<F>, spread: Expression<F>) -> Expression<F> {
let (factor, lagrange_poly) = Self::lagrange_interpolate(
dense,
vec![0b00, 0b01, 0b10, 0b11],
vec![0b0000, 0b0001, 0b0100, 0b0101],
);
lagrange_poly + (spread * factor * (-F::one()))
}
// 3-bit range check
fn three_bit_range_check(value: Expression<F>) -> Expression<F> {
Self::range_check(value, 0, (1 << 3) - 1)
}
// 3-bit spread
fn three_bit_spread(dense: Expression<F>, spread: Expression<F>) -> Expression<F> {
let (factor, lagrange_poly) = Self::lagrange_interpolate(
dense,
vec![0b000, 0b001, 0b010, 0b011, 0b100, 0b101, 0b110, 0b111],
vec![
0b000000, 0b000001, 0b000100, 0b000101, 0b010000, 0b010001, 0b010100, 0b010101,
],
);
lagrange_poly + (spread * factor * (-F::one()))
}
/// Spread and range check on 2-bit word
pub fn two_bit_spread_and_range(dense: Expression<F>, spread: Expression<F>) -> Expression<F> {
Self::two_bit_range_check(dense.clone()) + Self::two_bit_spread(dense, spread)
pub fn two_bit_spread_and_range(
dense: Expression<F>,
spread: Expression<F>,
) -> impl Iterator<Item = (&'static str, Expression<F>)> {
let two_bit_spread = |dense: Expression<F>, spread: Expression<F>| {
let (factor, lagrange_poly) = Self::lagrange_interpolate(
dense,
vec![0b00, 0b01, 0b10, 0b11],
vec![0b0000, 0b0001, 0b0100, 0b0101],
);
lagrange_poly - spread * factor
};
std::iter::empty()
.chain(Some((
"two_bit_range_check",
Self::range_check(dense.clone(), 0, (1 << 2) - 1),
)))
.chain(Some((
"two_bit_spread_check",
two_bit_spread(dense, spread),
)))
}
/// Spread and range check on 3-bit word
pub fn three_bit_spread_and_range(
dense: Expression<F>,
spread: Expression<F>,
) -> Expression<F> {
Self::three_bit_range_check(dense.clone()) + Self::three_bit_spread(dense, spread)
) -> impl Iterator<Item = (&'static str, Expression<F>)> {
let three_bit_spread = |dense: Expression<F>, spread: Expression<F>| {
let (factor, lagrange_poly) = Self::lagrange_interpolate(
dense,
vec![0b000, 0b001, 0b010, 0b011, 0b100, 0b101, 0b110, 0b111],
vec![
0b000000, 0b000001, 0b000100, 0b000101, 0b010000, 0b010001, 0b010100, 0b010101,
],
);
lagrange_poly - spread * factor
};
std::iter::empty()
.chain(Some((
"three_bit_range_check",
Self::range_check(dense.clone(), 0, (1 << 3) - 1),
)))
.chain(Some((
"three_bit_spread_check",
three_bit_spread(dense, spread),
)))
}
}

View File

@ -4,7 +4,7 @@ use super::{super::BLOCK_SIZE, BlockWord, CellValue16, SpreadInputs, Table16Assi
use halo2::{
arithmetic::FieldExt,
circuit::{Cell, Layouter},
plonk::{Advice, Column, ConstraintSystem, Error, Fixed, Permutation},
plonk::{Advice, Column, ConstraintSystem, Error, Fixed},
poly::Rotation,
};
@ -50,7 +50,6 @@ pub(super) struct MessageScheduleConfig {
s_lower_sigma_0_v2: Column<Fixed>,
/// sigma_1_v2 gate for W_[14..49]
s_lower_sigma_1_v2: Column<Fixed>,
perm: Permutation,
}
impl<F: FieldExt> Table16Assignment<F> for MessageScheduleConfig {}
@ -71,7 +70,6 @@ impl MessageScheduleConfig {
lookup: SpreadInputs,
message_schedule: Column<Advice>,
extras: [Column<Advice>; 6],
perm: Permutation,
) -> Self {
// Create fixed columns for the selectors we will require.
let s_word = meta.fixed_column();
@ -128,7 +126,6 @@ impl MessageScheduleConfig {
word,
carry,
)
.0
});
// s_decompose_0 for all words
@ -138,7 +135,7 @@ impl MessageScheduleConfig {
let hi = meta.query_advice(a_4, Rotation::cur());
let word = meta.query_advice(a_5, Rotation::cur());
ScheduleGate::s_decompose_0(s_decompose_0, lo, hi, word).0
ScheduleGate::s_decompose_0(s_decompose_0, lo, hi, word)
});
// s_decompose_1 for W_[1..14]
@ -153,7 +150,7 @@ impl MessageScheduleConfig {
let tag_d = meta.query_advice(a_0, Rotation::cur());
let word = meta.query_advice(a_5, Rotation::cur());
ScheduleGate::s_decompose_1(s_decompose_1, a, b, c, tag_c, d, tag_d, word).0
ScheduleGate::s_decompose_1(s_decompose_1, a, b, c, tag_c, d, tag_d, word)
});
// s_decompose_2 for W_[14..49]
@ -171,7 +168,7 @@ impl MessageScheduleConfig {
let tag_g = meta.query_advice(a_0, Rotation::prev());
let word = meta.query_advice(a_5, Rotation::cur());
ScheduleGate::s_decompose_2(s_decompose_2, a, b, c, d, tag_d, e, f, g, tag_g, word).0
ScheduleGate::s_decompose_2(s_decompose_2, a, b, c, d, tag_d, e, f, g, tag_g, word)
});
// s_decompose_3 for W_49 to W_61
@ -186,7 +183,7 @@ impl MessageScheduleConfig {
let tag_d = meta.query_advice(a_0, Rotation::cur());
let word = meta.query_advice(a_5, Rotation::cur());
ScheduleGate::s_decompose_3(s_decompose_3, a, tag_a, b, c, d, tag_d, word).0
ScheduleGate::s_decompose_3(s_decompose_3, a, tag_a, b, c, d, tag_d, word)
});
// sigma_0 v1 on W_[1..14]
@ -208,7 +205,6 @@ impl MessageScheduleConfig {
meta.query_advice(a_4, Rotation::cur()), // spread_c
meta.query_advice(a_5, Rotation::cur()), // spread_d
)
.0
});
// sigma_0 v2 on W_[14..49]
@ -234,7 +230,6 @@ impl MessageScheduleConfig {
meta.query_advice(a_7, Rotation::next()), // spread_f
meta.query_advice(a_5, Rotation::cur()), // spread_g
)
.0
});
// sigma_1 v2 on W_14 to W_48
@ -260,7 +255,6 @@ impl MessageScheduleConfig {
meta.query_advice(a_7, Rotation::next()), // spread_f
meta.query_advice(a_5, Rotation::cur()), // spread_g
)
.0
});
// sigma_1 v1 on W_49 to W_61
@ -284,7 +278,6 @@ impl MessageScheduleConfig {
meta.query_advice(a_4, Rotation::next()), // spread_c
meta.query_advice(a_5, Rotation::cur()), // spread_d
)
.0
});
MessageScheduleConfig {
@ -300,7 +293,6 @@ impl MessageScheduleConfig {
s_lower_sigma_1,
s_lower_sigma_0_v2,
s_lower_sigma_1_v2,
perm,
}
}
@ -445,10 +437,10 @@ mod tests {
use super::schedule_util::*;
use halo2::{
arithmetic::FieldExt,
circuit::layouter::SingleChipLayouter,
circuit::{Layouter, SimpleFloorPlanner},
dev::MockProver,
pasta::Fp,
plonk::{Assignment, Circuit, ConstraintSystem, Error},
plonk::{Circuit, ConstraintSystem, Error},
};
#[test]
@ -457,6 +449,11 @@ mod tests {
impl<F: FieldExt> Circuit<F> for MyCircuit {
type Config = Table16Config;
type FloorPlanner = SimpleFloorPlanner;
fn without_witnesses(&self) -> Self {
MyCircuit {}
}
fn configure(meta: &mut ConstraintSystem<F>) -> Self::Config {
Table16Chip::configure(meta)
@ -464,11 +461,9 @@ mod tests {
fn synthesize(
&self,
cs: &mut impl Assignment<F>,
config: Self::Config,
mut layouter: impl Layouter<F>,
) -> Result<(), Error> {
let mut layouter = SingleChipLayouter::new(cs)?;
// Load lookup table
SpreadTableChip::load(config.lookup.clone(), &mut layouter)?;
@ -488,7 +483,7 @@ mod tests {
let circuit: MyCircuit = MyCircuit {};
let prover = match MockProver::<Fp>::run(16, &circuit, vec![]) {
let prover = match MockProver::<Fp>::run(17, &circuit, vec![]) {
Ok(prover) => prover,
Err(e) => panic!("{:?}", e),
};

View File

@ -1,7 +1,8 @@
use super::super::Gate;
use halo2::{arithmetic::FieldExt, plonk::Expression};
use std::{array, marker::PhantomData};
pub struct ScheduleGate<F: FieldExt>(pub Expression<F>);
pub struct ScheduleGate<F: FieldExt>(PhantomData<F>);
impl<F: FieldExt> ScheduleGate<F> {
/// s_word for W_16 to W_63
@ -18,7 +19,7 @@ impl<F: FieldExt> ScheduleGate<F> {
w_minus_16_hi: Expression<F>,
word: Expression<F>,
carry: Expression<F>,
) -> Self {
) -> impl Iterator<Item = (&'static str, Expression<F>)> {
let lo = sigma_0_lo + sigma_1_lo + w_minus_9_lo + w_minus_16_lo;
let hi = sigma_0_hi + sigma_1_hi + w_minus_9_hi + w_minus_16_hi;
@ -28,7 +29,8 @@ impl<F: FieldExt> ScheduleGate<F> {
+ (word * (-F::one()));
let carry_check = Gate::range_check(carry, 0, 3);
ScheduleGate(s_word * (word_check + carry_check))
array::IntoIter::new([("word_check", word_check), ("carry_check", carry_check)])
.map(move |(name, poly)| (name, s_word.clone() * poly))
}
/// s_decompose_0 for all words
@ -37,8 +39,9 @@ impl<F: FieldExt> ScheduleGate<F> {
lo: Expression<F>,
hi: Expression<F>,
word: Expression<F>,
) -> Self {
ScheduleGate(s_decompose_0 * (lo + hi * F::from_u64(1 << 16) + word * (-F::one())))
) -> impl Iterator<Item = (&'static str, Expression<F>)> {
let check = lo + hi * F::from_u64(1 << 16) - word;
std::iter::empty().chain(Some(("s_decompose_0", s_decompose_0 * check)))
}
/// s_decompose_1 for W_1 to W_13
@ -53,7 +56,7 @@ impl<F: FieldExt> ScheduleGate<F> {
d: Expression<F>,
tag_d: Expression<F>,
word: Expression<F>,
) -> Self {
) -> impl Iterator<Item = (&'static str, Expression<F>)> {
let decompose_check = a
+ b * F::from_u64(1 << 3)
+ c * F::from_u64(1 << 7)
@ -61,7 +64,13 @@ impl<F: FieldExt> ScheduleGate<F> {
+ word * (-F::one());
let range_check_tag_c = Gate::range_check(tag_c, 0, 2);
let range_check_tag_d = Gate::range_check(tag_d, 0, 4);
ScheduleGate(s_decompose_1 * (decompose_check + range_check_tag_c + range_check_tag_d))
array::IntoIter::new([
("decompose_check", decompose_check),
("range_check_tag_c", range_check_tag_c),
("range_check_tag_d", range_check_tag_d),
])
.map(move |(name, poly)| (name, s_decompose_1.clone() * poly))
}
/// s_decompose_2 for W_14 to W_48
@ -80,7 +89,7 @@ impl<F: FieldExt> ScheduleGate<F> {
g: Expression<F>,
tag_g: Expression<F>,
word: Expression<F>,
) -> Self {
) -> impl Iterator<Item = (&'static str, Expression<F>)> {
let decompose_check = a
+ b * F::from_u64(1 << 3)
+ c * F::from_u64(1 << 7)
@ -91,7 +100,13 @@ impl<F: FieldExt> ScheduleGate<F> {
+ word * (-F::one());
let range_check_tag_d = Gate::range_check(tag_d, 0, 0);
let range_check_tag_g = Gate::range_check(tag_g, 0, 3);
ScheduleGate(s_decompose_2 * (decompose_check + range_check_tag_g + range_check_tag_d))
array::IntoIter::new([
("decompose_check", decompose_check),
("range_check_tag_g", range_check_tag_g),
("range_check_tag_d", range_check_tag_d),
])
.map(move |(name, poly)| (name, s_decompose_2.clone() * poly))
}
/// s_decompose_3 for W_49 to W_61
@ -106,7 +121,7 @@ impl<F: FieldExt> ScheduleGate<F> {
d: Expression<F>,
tag_d: Expression<F>,
word: Expression<F>,
) -> Self {
) -> impl Iterator<Item = (&'static str, Expression<F>)> {
let decompose_check = a
+ b * F::from_u64(1 << 10)
+ c * F::from_u64(1 << 17)
@ -115,24 +130,18 @@ impl<F: FieldExt> ScheduleGate<F> {
let range_check_tag_a = Gate::range_check(tag_a, 0, 1);
let range_check_tag_d = Gate::range_check(tag_d, 0, 3);
ScheduleGate(s_decompose_3 * (decompose_check + range_check_tag_a + range_check_tag_d))
array::IntoIter::new([
("decompose_check", decompose_check),
("range_check_tag_a", range_check_tag_a),
("range_check_tag_d", range_check_tag_d),
])
.map(move |(name, poly)| (name, s_decompose_3.clone() * poly))
}
/// b_lo + 2^2 * b_mid = b, on W_[1..49]
fn check_b(b: Expression<F>, b_lo: Expression<F>, b_hi: Expression<F>) -> Expression<F> {
let expected_b = b_lo + b_hi * F::from_u64(1 << 2);
expected_b + (b * -F::one())
}
/// b_lo + 2^2 * b_mid + 2^4 * b_hi = b, on W_[49..62]
fn check_b1(
b: Expression<F>,
b_lo: Expression<F>,
b_mid: Expression<F>,
b_hi: Expression<F>,
) -> Expression<F> {
let expected_b = b_lo + b_mid * F::from_u64(1 << 2) + b_hi * F::from_u64(1 << 4);
expected_b + (b * -F::one())
expected_b - b
}
/// sigma_0 v1 on W_1 to W_13
@ -153,11 +162,14 @@ impl<F: FieldExt> ScheduleGate<F> {
spread_b_hi: Expression<F>,
spread_c: Expression<F>,
spread_d: Expression<F>,
) -> Self {
) -> impl Iterator<Item = (&'static str, Expression<F>)> {
let check_spread_and_range =
Gate::two_bit_spread_and_range(b_lo.clone(), spread_b_lo.clone())
+ Gate::two_bit_spread_and_range(b_hi.clone(), spread_b_hi.clone())
+ Gate::three_bit_spread_and_range(a, spread_a.clone());
.chain(Gate::two_bit_spread_and_range(
b_hi.clone(),
spread_b_hi.clone(),
))
.chain(Gate::three_bit_spread_and_range(a, spread_a.clone()));
let check_b = Self::check_b(b, b_lo, b_hi);
let spread_witness = spread_r0_even
+ spread_r0_odd * F::from_u64(2)
@ -178,10 +190,10 @@ impl<F: FieldExt> ScheduleGate<F> {
+ spread_c * F::from_u64(1 << 42);
let xor = xor_0 + xor_1 + xor_2;
ScheduleGate(
s_lower_sigma_0
* (check_spread_and_range + check_b + spread_witness + (xor * -F::one())),
)
check_spread_and_range
.chain(Some(("check_b", check_b)))
.chain(Some(("lower_sigma_0", spread_witness - xor)))
.map(move |(name, poly)| (name, s_lower_sigma_0.clone() * poly))
}
/// sigma_1 v1 on W_49 to W_61
@ -204,13 +216,23 @@ impl<F: FieldExt> ScheduleGate<F> {
c: Expression<F>,
spread_c: Expression<F>,
spread_d: Expression<F>,
) -> Self {
) -> impl Iterator<Item = (&'static str, Expression<F>)> {
let check_spread_and_range =
Gate::two_bit_spread_and_range(b_lo.clone(), spread_b_lo.clone())
+ Gate::two_bit_spread_and_range(b_mid.clone(), spread_b_mid.clone())
+ Gate::two_bit_spread_and_range(c, spread_c.clone())
+ Gate::three_bit_spread_and_range(b_hi.clone(), spread_b_hi.clone());
let check_b1 = Self::check_b1(b, b_lo, b_mid, b_hi);
.chain(Gate::two_bit_spread_and_range(
b_mid.clone(),
spread_b_mid.clone(),
))
.chain(Gate::two_bit_spread_and_range(c, spread_c.clone()))
.chain(Gate::three_bit_spread_and_range(
b_hi.clone(),
spread_b_hi.clone(),
));
// b_lo + 2^2 * b_mid + 2^4 * b_hi = b, on W_[49..62]
let check_b1 = {
let expected_b = b_lo + b_mid * F::from_u64(1 << 2) + b_hi * F::from_u64(1 << 4);
expected_b - b
};
let spread_witness = spread_r0_even
+ spread_r0_odd * F::from_u64(2)
+ (spread_r1_even + spread_r1_odd * F::from_u64(2)) * F::from_u64(1 << 32);
@ -233,10 +255,10 @@ impl<F: FieldExt> ScheduleGate<F> {
+ spread_c * F::from_u64(1 << 60);
let xor = xor_0 + xor_1 + xor_2;
ScheduleGate(
s_lower_sigma_1
* (check_spread_and_range + check_b1 + spread_witness + (xor * -F::one())),
)
check_spread_and_range
.chain(Some(("check_b1", check_b1)))
.chain(Some(("lower_sigma_1", spread_witness - xor)))
.map(move |(name, poly)| (name, s_lower_sigma_1.clone() * poly))
}
/// sigma_0 v2 on W_14 to W_48
@ -261,12 +283,15 @@ impl<F: FieldExt> ScheduleGate<F> {
spread_e: Expression<F>,
spread_f: Expression<F>,
spread_g: Expression<F>,
) -> Self {
) -> impl Iterator<Item = (&'static str, Expression<F>)> {
let check_spread_and_range =
Gate::two_bit_spread_and_range(b_lo.clone(), spread_b_lo.clone())
+ Gate::two_bit_spread_and_range(b_hi.clone(), spread_b_hi.clone())
+ Gate::three_bit_spread_and_range(a, spread_a.clone())
+ Gate::three_bit_spread_and_range(c, spread_c.clone());
.chain(Gate::two_bit_spread_and_range(
b_hi.clone(),
spread_b_hi.clone(),
))
.chain(Gate::three_bit_spread_and_range(a, spread_a.clone()))
.chain(Gate::three_bit_spread_and_range(c, spread_c.clone()));
let check_b = Self::check_b(b, b_lo, b_hi);
let spread_witness = spread_r0_even
+ spread_r0_odd * F::from_u64(2)
@ -296,10 +321,10 @@ impl<F: FieldExt> ScheduleGate<F> {
+ spread_e * F::from_u64(1 << 62);
let xor = xor_0 + xor_1 + xor_2;
ScheduleGate(
s_lower_sigma_0_v2
* (check_spread_and_range + check_b + spread_witness + (xor * -F::one())),
)
check_spread_and_range
.chain(Some(("check_b", check_b)))
.chain(Some(("lower_sigma_0_v2", spread_witness - xor)))
.map(move |(name, poly)| (name, s_lower_sigma_0_v2.clone() * poly))
}
/// sigma_1 v2 on W_14 to W_48
@ -324,12 +349,15 @@ impl<F: FieldExt> ScheduleGate<F> {
spread_e: Expression<F>,
spread_f: Expression<F>,
spread_g: Expression<F>,
) -> Self {
) -> impl Iterator<Item = (&'static str, Expression<F>)> {
let check_spread_and_range =
Gate::two_bit_spread_and_range(b_lo.clone(), spread_b_lo.clone())
+ Gate::two_bit_spread_and_range(b_hi.clone(), spread_b_hi.clone())
+ Gate::three_bit_spread_and_range(a, spread_a.clone())
+ Gate::three_bit_spread_and_range(c, spread_c.clone());
.chain(Gate::two_bit_spread_and_range(
b_hi.clone(),
spread_b_hi.clone(),
))
.chain(Gate::three_bit_spread_and_range(a, spread_a.clone()))
.chain(Gate::three_bit_spread_and_range(c, spread_c.clone()));
let check_b = Self::check_b(b, b_lo, b_hi);
let spread_witness = spread_r0_even
+ spread_r0_odd * F::from_u64(2)
@ -356,9 +384,9 @@ impl<F: FieldExt> ScheduleGate<F> {
+ spread_f * F::from_u64(1 << 62);
let xor = xor_0 + xor_1 + xor_2;
ScheduleGate(
s_lower_sigma_1_v2
* (check_spread_and_range + check_b + spread_witness + (xor * -F::one())),
)
check_spread_and_range
.chain(Some(("check_b", check_b)))
.chain(Some(("lower_sigma_1_v2", spread_witness - xor)))
.map(move |(name, poly)| (name, s_lower_sigma_1_v2.clone() * poly))
}
}

View File

@ -102,7 +102,7 @@ impl MessageScheduleConfig {
let row = get_word_row(word.index) + 3;
// Assign `a` and copy constraint
self.assign_and_constrain(region, || "a", a_5, row + 1, &word.a, &self.perm)?;
self.assign_and_constrain(region, || "a", a_5, row + 1, &word.a)?;
// Witness `spread_a`
let spread_a = interleave_u16_with_zeros(word.a.value.unwrap() as u16);
@ -136,13 +136,13 @@ impl MessageScheduleConfig {
)?;
// Assign `b` and copy constraint
self.assign_and_constrain(region, || "b", a_6, row, &word.b, &self.perm)?;
self.assign_and_constrain(region, || "b", a_6, row, &word.b)?;
// Assign `spread_c` and copy constraint
self.assign_and_constrain(region, || "spread_c", a_4, row, &word.spread_c, &self.perm)?;
self.assign_and_constrain(region, || "spread_c", a_4, row, &word.spread_c)?;
// Assign `spread_d` and copy constraint
self.assign_and_constrain(region, || "spread_d", a_5, row, &word.spread_d, &self.perm)?;
self.assign_and_constrain(region, || "spread_d", a_5, row, &word.spread_d)?;
// Calculate R_0^{even}, R_0^{odd}, R_1^{even}, R_1^{odd}
let spread_a = spread_a as u64;
@ -171,7 +171,6 @@ impl MessageScheduleConfig {
region,
&self.lookup,
a_3,
&self.perm,
row,
r_0_even,
r_0_odd,

View File

@ -66,7 +66,6 @@ impl MessageScheduleConfig {
a_6,
get_word_row(new_word_idx - 16),
&sigma_0_output.0.into(),
&self.perm,
)?;
self.assign_and_constrain(
region,
@ -74,7 +73,6 @@ impl MessageScheduleConfig {
a_6,
get_word_row(new_word_idx - 16) + 1,
&sigma_0_output.1.into(),
&self.perm,
)?;
// Copy sigma_1(W_{i - 2})
@ -84,7 +82,6 @@ impl MessageScheduleConfig {
a_7,
get_word_row(new_word_idx - 16),
&lower_sigma_1_v2_results[new_word_idx - 16].0.into(),
&self.perm,
)?;
self.assign_and_constrain(
region,
@ -92,7 +89,6 @@ impl MessageScheduleConfig {
a_7,
get_word_row(new_word_idx - 16) + 1,
&lower_sigma_1_v2_results[new_word_idx - 16].1.into(),
&self.perm,
)?;
// Copy W_{i - 7}
@ -102,7 +98,6 @@ impl MessageScheduleConfig {
a_8,
get_word_row(new_word_idx - 16),
&w_halves[new_word_idx - 7].0.into(),
&self.perm,
)?;
self.assign_and_constrain(
region,
@ -110,7 +105,6 @@ impl MessageScheduleConfig {
a_8,
get_word_row(new_word_idx - 16) + 1,
&w_halves[new_word_idx - 7].1.into(),
&self.perm,
)?;
// Calculate W_i, carry_i
@ -233,7 +227,7 @@ impl MessageScheduleConfig {
let a_7 = self.extras[3];
// Assign `a` and copy constraint
self.assign_and_constrain(region, || "a", a_3, row + 1, &subregion2_word.a, &self.perm)?;
self.assign_and_constrain(region, || "a", a_3, row + 1, &subregion2_word.a)?;
// Witness `spread_a`
let spread_a = interleave_u16_with_zeros(subregion2_word.a.value.unwrap() as u16);
@ -267,10 +261,10 @@ impl MessageScheduleConfig {
)?;
// Assign `b` and copy constraint
self.assign_and_constrain(region, || "b", a_6, row, &subregion2_word.b, &self.perm)?;
self.assign_and_constrain(region, || "b", a_6, row, &subregion2_word.b)?;
// Assign `c` and copy constraint
self.assign_and_constrain(region, || "c", a_5, row + 1, &subregion2_word.c, &self.perm)?;
self.assign_and_constrain(region, || "c", a_5, row + 1, &subregion2_word.c)?;
// Witness `spread_c`
let spread_c = interleave_u16_with_zeros(subregion2_word.c.value.unwrap() as u16);
@ -282,30 +276,16 @@ impl MessageScheduleConfig {
)?;
// Assign `spread_d` and copy constraint
self.assign_and_constrain(
region,
|| "spread_d",
a_4,
row,
&subregion2_word.spread_d,
&self.perm,
)?;
self.assign_and_constrain(region, || "spread_d", a_4, row, &subregion2_word.spread_d)?;
// Assign `e` and copy constraint
self.assign_and_constrain(region, || "e", a_7, row, &subregion2_word.e, &self.perm)?;
self.assign_and_constrain(region, || "e", a_7, row, &subregion2_word.e)?;
// Assign `f` and copy constraint
self.assign_and_constrain(region, || "f", a_7, row + 1, &subregion2_word.f, &self.perm)?;
self.assign_and_constrain(region, || "f", a_7, row + 1, &subregion2_word.f)?;
// Assign `spread_g` and copy constraint
self.assign_and_constrain(
region,
|| "spread_g",
a_5,
row,
&subregion2_word.spread_g,
&self.perm,
)?;
self.assign_and_constrain(region, || "spread_g", a_5, row, &subregion2_word.spread_g)?;
Ok((
spread_a as u64,
@ -365,7 +345,6 @@ impl MessageScheduleConfig {
region,
&self.lookup,
a_3,
&self.perm,
row,
r_0_even,
r_0_odd,
@ -415,7 +394,6 @@ impl MessageScheduleConfig {
region,
&self.lookup,
a_3,
&self.perm,
row,
r_0_even,
r_0_odd,

View File

@ -55,7 +55,6 @@ impl MessageScheduleConfig {
a_6,
get_word_row(new_word_idx - 16),
&lower_sigma_0_v2_output[idx - 49].0.into(),
&self.perm,
)?;
self.assign_and_constrain(
region,
@ -63,7 +62,6 @@ impl MessageScheduleConfig {
a_6,
get_word_row(new_word_idx - 16) + 1,
&lower_sigma_0_v2_output[idx - 49].1.into(),
&self.perm,
)?;
// Copy sigma_1(W_{i - 2})
@ -73,7 +71,6 @@ impl MessageScheduleConfig {
a_7,
get_word_row(new_word_idx - 16),
&r_0_even.into(),
&self.perm,
)?;
self.assign_and_constrain(
region,
@ -81,7 +78,6 @@ impl MessageScheduleConfig {
a_7,
get_word_row(new_word_idx - 16) + 1,
&r_1_even.into(),
&self.perm,
)?;
// Copy W_{i - 7}
@ -91,7 +87,6 @@ impl MessageScheduleConfig {
a_8,
get_word_row(new_word_idx - 16),
&w_halves[new_word_idx - 7].0.into(),
&self.perm,
)?;
self.assign_and_constrain(
region,
@ -99,7 +94,6 @@ impl MessageScheduleConfig {
a_8,
get_word_row(new_word_idx - 16) + 1,
&w_halves[new_word_idx - 7].1.into(),
&self.perm,
)?;
// Calculate W_i, carry_i
@ -198,7 +192,7 @@ impl MessageScheduleConfig {
let row = get_word_row(word.index) + 3;
// Assign `spread_a` and copy constraint
self.assign_and_constrain(region, || "spread_a", a_4, row, &word.spread_a, &self.perm)?;
self.assign_and_constrain(region, || "spread_a", a_4, row, &word.spread_a)?;
// Split `b` (7-bit chunk) into (2,2,3)-bit `b_lo`, `b_mid` and `b_hi`
let b = word.b.value.unwrap();
@ -232,10 +226,10 @@ impl MessageScheduleConfig {
)?;
// Assign `b` and copy constraint
self.assign_and_constrain(region, || "b", a_6, row, &word.b, &self.perm)?;
self.assign_and_constrain(region, || "b", a_6, row, &word.b)?;
// Assign `c` and copy constraint
self.assign_and_constrain(region, || "c", a_3, row + 1, &word.c, &self.perm)?;
self.assign_and_constrain(region, || "c", a_3, row + 1, &word.c)?;
// Witness `spread_c`
let spread_c = interleave_u16_with_zeros(word.c.value.unwrap() as u16);
@ -247,7 +241,7 @@ impl MessageScheduleConfig {
)?;
// Assign `spread_d` and copy constraint
self.assign_and_constrain(region, || "spread_d", a_5, row, &word.spread_d, &self.perm)?;
self.assign_and_constrain(region, || "spread_d", a_5, row, &word.spread_d)?;
// (10, 7, 2, 13)
// Calculate R_0^{even}, R_0^{odd}, R_1^{even}, R_1^{odd}
@ -283,7 +277,6 @@ impl MessageScheduleConfig {
region,
&self.lookup,
a_3,
&self.perm,
row,
r_0_even,
r_0_odd,

View File

@ -275,10 +275,10 @@ mod tests {
use crate::table16::util::{get_tag, interleave_u16_with_zeros};
use halo2::{
arithmetic::FieldExt,
circuit::{layouter::SingleChipLayouter, Layouter},
circuit::{Layouter, SimpleFloorPlanner},
dev::MockProver,
pasta::Fp,
plonk::{Advice, Assignment, Circuit, Column, ConstraintSystem, Error},
plonk::{Advice, Circuit, Column, ConstraintSystem, Error},
};
#[test]
@ -291,6 +291,11 @@ mod tests {
impl<F: FieldExt> Circuit<F> for MyCircuit {
type Config = SpreadTableConfig;
type FloorPlanner = SimpleFloorPlanner;
fn without_witnesses(&self) -> Self {
MyCircuit {}
}
fn configure(meta: &mut ConstraintSystem<F>) -> Self::Config {
let input_tag = meta.advice_column();
@ -302,10 +307,9 @@ mod tests {
fn synthesize(
&self,
cs: &mut impl Assignment<F>,
config: Self::Config,
mut layouter: impl Layouter<F>,
) -> Result<(), Error> {
let mut layouter = SingleChipLayouter::new(cs)?;
SpreadTableChip::load(config.clone(), &mut layouter)?;
layouter.assign_region(
@ -410,7 +414,7 @@ mod tests {
let circuit: MyCircuit = MyCircuit {};
let prover = match MockProver::<Fp>::run(16, &circuit, vec![]) {
let prover = match MockProver::<Fp>::run(17, &circuit, vec![]) {
Ok(prover) => prover,
Err(e) => panic!("{:?}", e),
};