mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-10 17:53:06 +00:00
Add LUT hash to remove CircuitBuilder overhead
This commit is contained in:
parent
8b35fefb3b
commit
1d6ca5894f
@ -3,6 +3,9 @@ use alloc::string::String;
|
||||
use alloc::vec::Vec;
|
||||
use core::usize;
|
||||
|
||||
use itertools::Itertools;
|
||||
use keccak_hash::keccak;
|
||||
|
||||
use super::lookup_table::LookupTable;
|
||||
use crate::field::extension::Extendable;
|
||||
use crate::field::packed::PackedField;
|
||||
@ -31,13 +34,21 @@ pub struct LookupGate {
|
||||
pub num_slots: usize,
|
||||
/// LUT associated to the gate.
|
||||
lut: LookupTable,
|
||||
/// The Keccak hash of the lookup table.
|
||||
lut_hash: [u8; 32],
|
||||
}
|
||||
|
||||
impl LookupGate {
|
||||
pub fn new_from_table(config: &CircuitConfig, lut: LookupTable) -> Self {
|
||||
let table_bytes = lut
|
||||
.iter()
|
||||
.flat_map(|(input, output)| [input.to_le_bytes(), output.to_le_bytes()].concat())
|
||||
.collect_vec();
|
||||
|
||||
Self {
|
||||
num_slots: Self::num_slots(config),
|
||||
lut,
|
||||
lut_hash: keccak(table_bytes).0,
|
||||
}
|
||||
}
|
||||
pub(crate) fn num_slots(config: &CircuitConfig) -> usize {
|
||||
@ -56,14 +67,19 @@ impl LookupGate {
|
||||
|
||||
impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for LookupGate {
|
||||
fn id(&self) -> String {
|
||||
format!("{self:?}")
|
||||
// Custom implementation to not have the entire lookup table
|
||||
format!(
|
||||
"LookupGate {{num_slots: {}, lut_hash: {:?}}}",
|
||||
self.num_slots, self.lut_hash
|
||||
)
|
||||
}
|
||||
|
||||
fn serialize(&self, dst: &mut Vec<u8>, common_data: &CommonCircuitData<F, D>) -> IoResult<()> {
|
||||
dst.write_usize(self.num_slots)?;
|
||||
for (i, lut) in common_data.luts.iter().enumerate() {
|
||||
if lut == &self.lut {
|
||||
return dst.write_usize(i);
|
||||
dst.write_usize(i)?;
|
||||
return dst.write_all(&self.lut_hash);
|
||||
}
|
||||
}
|
||||
|
||||
@ -73,10 +89,13 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for LookupGate {
|
||||
fn deserialize(src: &mut Buffer, common_data: &CommonCircuitData<F, D>) -> IoResult<Self> {
|
||||
let num_slots = src.read_usize()?;
|
||||
let lut_index = src.read_usize()?;
|
||||
let mut lut_hash = [0u8; 32];
|
||||
src.read_exact(&mut lut_hash)?;
|
||||
|
||||
Ok(Self {
|
||||
num_slots,
|
||||
lut: common_data.luts[lut_index].clone(),
|
||||
lut_hash,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@ -4,6 +4,8 @@ use alloc::sync::Arc;
|
||||
use alloc::vec::Vec;
|
||||
use core::usize;
|
||||
|
||||
use itertools::Itertools;
|
||||
use keccak_hash::keccak;
|
||||
use plonky2_util::ceil_div_usize;
|
||||
|
||||
use crate::field::extension::Extendable;
|
||||
@ -33,15 +35,23 @@ pub struct LookupTableGate {
|
||||
pub num_slots: usize,
|
||||
/// Lookup table associated to the gate.
|
||||
pub lut: LookupTable,
|
||||
/// The Keccak hash of the lookup table.
|
||||
lut_hash: [u8; 32],
|
||||
/// First row of the lookup table.
|
||||
last_lut_row: usize,
|
||||
}
|
||||
|
||||
impl LookupTableGate {
|
||||
pub fn new_from_table(config: &CircuitConfig, lut: LookupTable, last_lut_row: usize) -> Self {
|
||||
let table_bytes = lut
|
||||
.iter()
|
||||
.flat_map(|(input, output)| [input.to_le_bytes(), output.to_le_bytes()].concat())
|
||||
.collect_vec();
|
||||
|
||||
Self {
|
||||
num_slots: Self::num_slots(config),
|
||||
lut,
|
||||
lut_hash: keccak(table_bytes).0,
|
||||
last_lut_row,
|
||||
}
|
||||
}
|
||||
@ -69,7 +79,11 @@ impl LookupTableGate {
|
||||
|
||||
impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for LookupTableGate {
|
||||
fn id(&self) -> String {
|
||||
format!("{self:?}")
|
||||
// Custom implementation to not have the entire lookup table
|
||||
format!(
|
||||
"LookupGate {{num_slots: {}, lut_hash: {:?}, last_lut_row: {}}}",
|
||||
self.num_slots, self.lut_hash, self.last_lut_row
|
||||
)
|
||||
}
|
||||
|
||||
fn serialize(&self, dst: &mut Vec<u8>, common_data: &CommonCircuitData<F, D>) -> IoResult<()> {
|
||||
@ -77,7 +91,8 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for LookupTableGat
|
||||
dst.write_usize(self.last_lut_row)?;
|
||||
for (i, lut) in common_data.luts.iter().enumerate() {
|
||||
if lut == &self.lut {
|
||||
return dst.write_usize(i);
|
||||
dst.write_usize(i)?;
|
||||
return dst.write_all(&self.lut_hash);
|
||||
}
|
||||
}
|
||||
|
||||
@ -88,10 +103,13 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for LookupTableGat
|
||||
let num_slots = src.read_usize()?;
|
||||
let last_lut_row = src.read_usize()?;
|
||||
let lut_index = src.read_usize()?;
|
||||
let mut lut_hash = [0u8; 32];
|
||||
src.read_exact(&mut lut_hash)?;
|
||||
|
||||
Ok(Self {
|
||||
num_slots,
|
||||
lut: common_data.luts[lut_index].clone(),
|
||||
lut_hash,
|
||||
last_lut_row,
|
||||
})
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user