mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-03 14:23:07 +00:00
Merge remote-tracking branch 'origin/main' into codex
# Conflicts: # plonky2/src/gates/lookup.rs
This commit is contained in:
commit
d682f58af5
@ -369,7 +369,7 @@ pub trait Field:
|
||||
let mut product = Self::ONE;
|
||||
|
||||
for j in 0..bits_u64(power) {
|
||||
if (power >> j & 1) != 0 {
|
||||
if ((power >> j) & 1) != 0 {
|
||||
product *= current;
|
||||
}
|
||||
current = current.square();
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "plonky2"
|
||||
description = "Recursive SNARKs based on PLONK and FRI"
|
||||
version = "1.0.0"
|
||||
version = "1.0.1"
|
||||
authors = ["Daniel Lubarov <daniel@lubarov.com>", "William Borgeaud <williamborgeaud@gmail.com>", "Nicholas Ward <npward@berkeley.edu>"]
|
||||
readme = "README.md"
|
||||
edition.workspace = true
|
||||
|
||||
@ -16,7 +16,8 @@ use plonky2::plonk::verifier::{VerifierOptions, HashStatisticsPrintLevel};
|
||||
|
||||
use env_logger;
|
||||
|
||||
pub const N_PRIMES: usize = 512;
|
||||
pub const N_PRIMES: usize = 512;
|
||||
pub const TABLE_SIZE: usize = 512; // 19*26;
|
||||
|
||||
// table of the first 512 prime numbers
|
||||
pub const PRIMES_TABLE: [u16; N_PRIMES] = [
|
||||
@ -101,8 +102,8 @@ fn main() -> Result<()> {
|
||||
let config = CircuitConfig::standard_recursion_config();
|
||||
let mut builder = CircuitBuilder::<F, D>::new(config);
|
||||
|
||||
let indices: [u16; N_PRIMES] = core::array::from_fn( |i| i as u16 );
|
||||
let my_lut_index = builder.add_lookup_table_from_table( &PRIMES_TABLE , &indices );
|
||||
let indices: [u16; TABLE_SIZE] = core::array::from_fn( |i| i as u16 );
|
||||
let my_lut_index = builder.add_lookup_table_from_table( &PRIMES_TABLE[..TABLE_SIZE] , &indices );
|
||||
|
||||
// The arithmetic circuit.
|
||||
let the_a = builder.add_virtual_target();
|
||||
@ -147,15 +148,13 @@ fn main() -> Result<()> {
|
||||
};
|
||||
let proof = data.prove_with_options(pw, &prover_opts)?;
|
||||
|
||||
/*
|
||||
// serialize circuit into JSON
|
||||
let common_circuit_data_serialized = serde_json::to_string(&data.common ).unwrap();
|
||||
let verifier_only_circuit_data_serialized = serde_json::to_string(&data.verifier_only).unwrap();
|
||||
let proof_serialized = serde_json::to_string(&proof ).unwrap();
|
||||
fs::write("lookup_common_circuit_data.json" , common_circuit_data_serialized) .expect("Unable to write file");
|
||||
fs::write("lookup_verifier_only_circuit_data.json", verifier_only_circuit_data_serialized).expect("Unable to write file");
|
||||
fs::write("lookup_proof_with_public_inputs.json" , proof_serialized) .expect("Unable to write file");
|
||||
*/
|
||||
fs::write("lookup_common.json" , common_circuit_data_serialized) .expect("Unable to write file");
|
||||
fs::write("lookup_vkey.json" , verifier_only_circuit_data_serialized).expect("Unable to write file");
|
||||
fs::write("lookup_proof.json" , proof_serialized) .expect("Unable to write file");
|
||||
|
||||
println!("the arithmetic progression `q[i] := {}*i + {}` for 0<=i<{} are all primes!",proof.public_inputs[0],proof.public_inputs[1],nn);
|
||||
println!("sum of the indices of these primes = {}",proof.public_inputs[2]);
|
||||
|
||||
@ -470,7 +470,7 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
if j != 0 {
|
||||
current = self.square_extension(current);
|
||||
}
|
||||
if (exponent >> j & 1) != 0 {
|
||||
if ((exponent >> j) & 1) != 0 {
|
||||
product = self.mul_extension(product, current);
|
||||
}
|
||||
}
|
||||
|
||||
@ -198,9 +198,9 @@ impl<F: RichField + Extendable<D>, const B: usize, const D: usize> SimpleGenerat
|
||||
) -> Result<()> {
|
||||
let sum_value = witness
|
||||
.get_target(Target::wire(self.row, BaseSumGate::<B>::WIRE_SUM))
|
||||
.to_canonical_u64() as usize;
|
||||
.to_canonical_u64();
|
||||
debug_assert_eq!(
|
||||
(0..self.num_limbs).fold(sum_value, |acc, _| acc / B),
|
||||
(0..self.num_limbs).fold(sum_value, |acc, _| acc / (B as u64)),
|
||||
0,
|
||||
"Integer too large to fit in given number of limbs"
|
||||
);
|
||||
@ -209,9 +209,9 @@ impl<F: RichField + Extendable<D>, const B: usize, const D: usize> SimpleGenerat
|
||||
.map(|i| Target::wire(self.row, i));
|
||||
let limbs_value = (0..self.num_limbs)
|
||||
.scan(sum_value, |acc, _| {
|
||||
let tmp = *acc % B;
|
||||
*acc /= B;
|
||||
Some(F::from_canonical_usize(tmp))
|
||||
let tmp = *acc % (B as u64);
|
||||
*acc /= B as u64;
|
||||
Some(F::from_canonical_u64(tmp))
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
|
||||
@ -81,7 +81,7 @@ impl<F: RichField + Extendable<D>, const D: usize> Gate<F, D> for LookupGate {
|
||||
fn short_id(&self) -> String {
|
||||
format!("LookupGate:{}",self.num_slots)
|
||||
}
|
||||
|
||||
|
||||
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() {
|
||||
@ -201,14 +201,10 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D> for Loo
|
||||
let get_wire = |wire: usize| -> F { witness.get_target(Target::wire(self.row, wire)) };
|
||||
|
||||
let input_val = get_wire(LookupGate::wire_ith_looking_inp(self.slot_nb));
|
||||
let idx_candidate: usize = input_val.to_canonical_u64() as usize;
|
||||
let ((input, output), ok) = if idx_candidate < self.lut.len() {
|
||||
(self.lut[idx_candidate], true)
|
||||
}
|
||||
else {
|
||||
((0,0), false)
|
||||
};
|
||||
if ok && (input_val == F::from_canonical_u16(input)) {
|
||||
if (input_val.to_canonical_u64() as usize) < self.lut.len()
|
||||
&& input_val == F::from_canonical_u16(self.lut[input_val.to_canonical_u64() as usize].0)
|
||||
{
|
||||
let (_, output) = self.lut[input_val.to_canonical_u64() as usize];
|
||||
let output_val = F::from_canonical_u16(output);
|
||||
|
||||
let out_wire = Target::wire(self.row, LookupGate::wire_ith_looking_out(self.slot_nb));
|
||||
|
||||
@ -228,9 +228,11 @@ impl<F: RichField + Extendable<D>, const D: usize> SimpleGenerator<F, D> for Loo
|
||||
out_buffer.set_target(slot_input_target, F::from_canonical_usize(input as usize))?;
|
||||
out_buffer.set_target(slot_output_target, F::from_canonical_usize(output as usize))
|
||||
} else {
|
||||
// Pad with zeros.
|
||||
out_buffer.set_target(slot_input_target, F::ZERO)?;
|
||||
out_buffer.set_target(slot_output_target, F::ZERO)
|
||||
// Pad with first element in the LUT.
|
||||
assert!(!self.lut.is_empty(), "Empty LUTs are not supported.");
|
||||
let (input, output) = self.lut[0];
|
||||
out_buffer.set_target(slot_input_target, F::from_canonical_usize(input as usize))?;
|
||||
out_buffer.set_target(slot_output_target, F::from_canonical_usize(output as usize))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
#[cfg(not(feature = "std"))]
|
||||
use alloc::vec::Vec;
|
||||
use core::fmt;
|
||||
|
||||
use anyhow::ensure;
|
||||
use serde::de::{self, Visitor};
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
use crate::field::goldilocks_field::GoldilocksField;
|
||||
@ -193,19 +195,52 @@ impl<F: RichField, const N: usize> GenericHashOut<F> for BytesHash<N> {
|
||||
}
|
||||
|
||||
impl<const N: usize> Serialize for BytesHash<N> {
|
||||
fn serialize<S>(&self, _serializer: S) -> Result<S::Ok, S::Error>
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
todo!()
|
||||
serializer.serialize_bytes(&self.0)
|
||||
}
|
||||
}
|
||||
|
||||
struct ByteHashVisitor<const N: usize>;
|
||||
|
||||
impl<'de, const N: usize> Visitor<'de> for ByteHashVisitor<N> {
|
||||
type Value = BytesHash<N>;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(formatter, "an array containing exactly {} bytes", N)
|
||||
}
|
||||
|
||||
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
|
||||
where
|
||||
A: de::SeqAccess<'de>,
|
||||
{
|
||||
let mut bytes = [0u8; N];
|
||||
for i in 0..N {
|
||||
let next_element = seq.next_element()?;
|
||||
match next_element {
|
||||
Some(value) => bytes[i] = value,
|
||||
None => return Err(de::Error::invalid_length(i, &self)),
|
||||
}
|
||||
}
|
||||
Ok(BytesHash(bytes))
|
||||
}
|
||||
|
||||
fn visit_bytes<E>(self, s: &[u8]) -> Result<Self::Value, E>
|
||||
where
|
||||
E: de::Error,
|
||||
{
|
||||
let bytes = s.try_into().unwrap();
|
||||
Ok(BytesHash(bytes))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de, const N: usize> Deserialize<'de> for BytesHash<N> {
|
||||
fn deserialize<D>(_deserializer: D) -> Result<Self, D::Error>
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
todo!()
|
||||
deserializer.deserialize_seq(ByteHashVisitor::<N>)
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,10 +36,17 @@ pub(crate) fn get_lut_poly<F: RichField + Extendable<D>, const D: usize>(
|
||||
let b = deltas[LookupChallenges::ChallengeB as usize];
|
||||
let mut coeffs = Vec::with_capacity(common_data.luts[lut_index].len());
|
||||
let n = common_data.luts[lut_index].len();
|
||||
let nb_padded_elts = LookupTableGate::num_slots(&common_data.config)
|
||||
- n % LookupTableGate::num_slots(&common_data.config);
|
||||
let (padding_inp, padding_out) = common_data.luts[lut_index][0];
|
||||
for (input, output) in common_data.luts[lut_index].iter() {
|
||||
coeffs.push(F::from_canonical_u16(*input) + b * F::from_canonical_u16(*output));
|
||||
}
|
||||
coeffs.append(&mut vec![F::ZERO; degree - n]);
|
||||
// Padding with the first element of the LUT.
|
||||
for _ in 0..nb_padded_elts {
|
||||
coeffs.push(F::from_canonical_u16(padding_inp) + b * F::from_canonical_u16(padding_out));
|
||||
}
|
||||
coeffs.append(&mut vec![F::ZERO; degree - (n + nb_padded_elts)]);
|
||||
coeffs.reverse();
|
||||
PolynomialCoeffs::new(coeffs)
|
||||
}
|
||||
@ -756,6 +763,9 @@ pub(crate) fn get_lut_poly_circuit<F: RichField + Extendable<D>, const D: usize>
|
||||
let b = deltas[LookupChallenges::ChallengeB as usize];
|
||||
let delta = deltas[LookupChallenges::ChallengeDelta as usize];
|
||||
let n = common_data.luts[lut_index].len();
|
||||
let nb_padded_elts = LookupTableGate::num_slots(&common_data.config)
|
||||
- n % LookupTableGate::num_slots(&common_data.config);
|
||||
let (padding_inp, padding_out) = common_data.luts[lut_index][0];
|
||||
let mut coeffs: Vec<Target> = common_data.luts[lut_index]
|
||||
.iter()
|
||||
.map(|(input, output)| {
|
||||
@ -763,7 +773,14 @@ pub(crate) fn get_lut_poly_circuit<F: RichField + Extendable<D>, const D: usize>
|
||||
builder.add_const(temp, F::from_canonical_u16(*input))
|
||||
})
|
||||
.collect();
|
||||
for _ in n..degree {
|
||||
|
||||
// Padding with the first element of the LUT.
|
||||
for _ in 0..nb_padded_elts {
|
||||
let temp = builder.mul_const(F::from_canonical_u16(padding_out), b);
|
||||
let temp = builder.add_const(temp, F::from_canonical_u16(padding_inp));
|
||||
coeffs.push(temp);
|
||||
}
|
||||
for _ in (n + nb_padded_elts)..degree {
|
||||
coeffs.push(builder.zero());
|
||||
}
|
||||
coeffs.reverse();
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
//! A module to help with GateRef serialization
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
use alloc::vec::Vec;
|
||||
pub use alloc::vec::Vec;
|
||||
#[cfg(feature = "std")]
|
||||
use std::vec::Vec; // For macros below
|
||||
pub use std::vec::Vec; // For macros below
|
||||
|
||||
pub use log;
|
||||
use plonky2_field::extension::Extendable;
|
||||
|
||||
use crate::gates::gate::GateRef;
|
||||
@ -51,8 +52,8 @@ macro_rules! get_gate_tag_impl {
|
||||
Ok(tag)
|
||||
} else)*
|
||||
{
|
||||
log::log!(
|
||||
log::Level::Error,
|
||||
$crate::util::serialization::gate_serialization::log::log!(
|
||||
$crate::util::serialization::gate_serialization::log::Level::Error,
|
||||
"attempted to serialize gate with id `{}` which is unsupported by this gate serializer",
|
||||
$gate.0.id()
|
||||
);
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "starky"
|
||||
description = "Implementation of STARKs"
|
||||
version = "1.0.0"
|
||||
version = "1.0.1"
|
||||
authors = ["Daniel Lubarov <daniel@lubarov.com>", "William Borgeaud <williamborgeaud@gmail.com>"]
|
||||
readme = "README.md"
|
||||
edition.workspace = true
|
||||
@ -27,7 +27,7 @@ serde = { workspace = true, features = ["rc"] }
|
||||
num-bigint = { version = "0.4.3", default-features = false }
|
||||
|
||||
# Local dependencies
|
||||
plonky2 = { version = "1.0.0", path = "../plonky2", default-features = false }
|
||||
plonky2 = { version = "1.0.1", path = "../plonky2", default-features = false }
|
||||
plonky2_maybe_rayon = { version = "1.0.0", path = "../maybe_rayon", default-features = false }
|
||||
plonky2_util = { version = "1.0.0", path = "../util", default-features = false }
|
||||
|
||||
|
||||
@ -14,8 +14,8 @@
|
||||
window.onload = function() {
|
||||
console.log("onload!");
|
||||
// let fname = "json/fibonacci_witness.json";
|
||||
// let fname = "json/lookup_witness.json";
|
||||
let fname = "json/multi_lookup_witness.json";
|
||||
let fname = "json/lookup_witness.json";
|
||||
// let fname = "json/multi_lookup_witness.json";
|
||||
load_witness(fname);
|
||||
}
|
||||
</script>
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user