mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-15 04:03:13 +00:00
Comments and cleaning
This commit is contained in:
parent
d4c8caa208
commit
b83f29cca2
@ -1,10 +1,12 @@
|
||||
use std::convert::TryInto;
|
||||
|
||||
use rand::Rng;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
use crate::field::field_types::{Field, PrimeField};
|
||||
use crate::field::field_types::{Field, PrimeField, RichField};
|
||||
use crate::iop::target::Target;
|
||||
use crate::util::ceil_div_usize;
|
||||
use crate::util::serialization::Buffer;
|
||||
|
||||
/// Represents a ~256 bit hash output.
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)]
|
||||
@ -121,3 +123,51 @@ impl HashOutTarget {
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct MerkleCapTarget(pub Vec<HashOutTarget>);
|
||||
|
||||
/// Hash consisting of a byte array.
|
||||
#[derive(Eq, PartialEq, Copy, Clone, Debug)]
|
||||
pub struct BytesHash<const N: usize>(pub [u8; N]);
|
||||
impl<const N: usize> Serialize for BytesHash<N> {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
impl<'de, const N: usize> Deserialize<'de> for BytesHash<N> {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> From<Vec<u8>> for BytesHash<N> {
|
||||
fn from(v: Vec<u8>) -> Self {
|
||||
Self(v.try_into().unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> From<BytesHash<N>> for Vec<u8> {
|
||||
fn from(hash: BytesHash<N>) -> Self {
|
||||
hash.0.to_vec()
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> From<BytesHash<N>> for u64 {
|
||||
fn from(hash: BytesHash<N>) -> Self {
|
||||
u64::from_le_bytes(hash.0[..8].try_into().unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: RichField, const N: usize> From<BytesHash<N>> for Vec<F> {
|
||||
fn from(hash: BytesHash<N>) -> Self {
|
||||
let n = hash.0.len();
|
||||
let mut v = hash.0.to_vec();
|
||||
v.resize(ceil_div_usize(n, 8) * 8, 0);
|
||||
let mut buffer = Buffer::new(v);
|
||||
buffer.read_field_vec(buffer.len() / 8).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
@ -93,6 +93,7 @@ pub fn compress<F: RichField, P: PlonkyPermutation<F>>(x: HashOut<F>, y: HashOut
|
||||
}
|
||||
}
|
||||
|
||||
/// Permutation that can be used in the sponge construction for an algebraic hash.
|
||||
pub trait PlonkyPermutation<F: RichField> {
|
||||
fn permute(input: [F; SPONGE_WIDTH]) -> [F; SPONGE_WIDTH];
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ use crate::field::extension_field::{Extendable, FieldExtension};
|
||||
use crate::field::field_types::RichField;
|
||||
use crate::field::goldilocks_field::GoldilocksField;
|
||||
use crate::gates::poseidon::PoseidonGate;
|
||||
use crate::hash::hash_types::HashOut;
|
||||
use crate::hash::hash_types::{BytesHash, HashOut};
|
||||
use crate::hash::hashing::{
|
||||
compress, hash_n_to_hash, PlonkyPermutation, PoseidonPermutation, SPONGE_WIDTH,
|
||||
};
|
||||
@ -19,6 +19,7 @@ use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
use crate::util::ceil_div_usize;
|
||||
use crate::util::serialization::Buffer;
|
||||
|
||||
/// Trait for hash functions.
|
||||
pub trait Hasher<F: RichField>: Sized + Clone + Debug + Eq + PartialEq {
|
||||
/// Size of `Hash` in bytes.
|
||||
const HASH_SIZE: usize;
|
||||
@ -40,6 +41,25 @@ pub trait Hasher<F: RichField>: Sized + Clone + Debug + Eq + PartialEq {
|
||||
fn two_to_one(left: Self::Hash, right: Self::Hash) -> Self::Hash;
|
||||
}
|
||||
|
||||
/// Trait for algebraic hash functions, built from a permutation using the sponge construction.
|
||||
pub trait AlgebraicHasher<F: RichField>: Hasher<F, Hash = HashOut<F>> {
|
||||
// TODO: Adding a `const WIDTH: usize` here yields a compiler error down the line.
|
||||
// Maybe try again in a while.
|
||||
|
||||
/// Permutation used in the sponge construction.
|
||||
type Permutation: PlonkyPermutation<F>;
|
||||
/// Circuit to conditionally swap two chunks of the inputs (useful in verifying Merkle proofs),
|
||||
/// then apply the permutation.
|
||||
fn permute_swapped<const D: usize>(
|
||||
inputs: [Target; SPONGE_WIDTH],
|
||||
swap: BoolTarget,
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
) -> [Target; SPONGE_WIDTH]
|
||||
where
|
||||
F: Extendable<D>;
|
||||
}
|
||||
|
||||
/// Poseidon hash function.
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
pub struct PoseidonHash;
|
||||
impl<F: RichField> Hasher<F> for PoseidonHash {
|
||||
@ -139,53 +159,7 @@ impl<F: RichField> AlgebraicHasher<F> for PoseidonHash {
|
||||
// }
|
||||
// }
|
||||
|
||||
pub trait AlgebraicHasher<F: RichField>: Hasher<F, Hash = HashOut<F>> {
|
||||
// TODO: Adding a `const WIDTH: usize` here yields a compiler error down the line.
|
||||
// Maybe try again in a while.
|
||||
type Permutation: PlonkyPermutation<F>;
|
||||
fn permute_swapped<const D: usize>(
|
||||
inputs: [Target; SPONGE_WIDTH],
|
||||
swap: BoolTarget,
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
) -> [Target; SPONGE_WIDTH]
|
||||
where
|
||||
F: Extendable<D>;
|
||||
}
|
||||
|
||||
pub trait GenericConfig<const D: usize>:
|
||||
Debug + Clone + Sync + Sized + Send + Eq + PartialEq
|
||||
{
|
||||
type F: RichField + Extendable<D, Extension = Self::FE>;
|
||||
type FE: FieldExtension<D, BaseField = Self::F>;
|
||||
type Hasher: Hasher<Self::F>;
|
||||
type InnerHasher: AlgebraicHasher<Self::F>;
|
||||
}
|
||||
|
||||
pub trait AlgebraicConfig<const D: usize>:
|
||||
Debug + Clone + Sync + Sized + Send + Eq + PartialEq
|
||||
{
|
||||
type F: RichField + Extendable<D, Extension = Self::FE>;
|
||||
type FE: FieldExtension<D, BaseField = Self::F>;
|
||||
type Hasher: AlgebraicHasher<Self::F>;
|
||||
type InnerHasher: AlgebraicHasher<Self::F>;
|
||||
}
|
||||
|
||||
impl<A: AlgebraicConfig<D>, const D: usize> GenericConfig<D> for A {
|
||||
type F = <Self as AlgebraicConfig<D>>::F;
|
||||
type FE = <Self as AlgebraicConfig<D>>::FE;
|
||||
type Hasher = <Self as AlgebraicConfig<D>>::Hasher;
|
||||
type InnerHasher = <Self as AlgebraicConfig<D>>::InnerHasher;
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
pub struct PoseidonGoldilocksConfig;
|
||||
impl AlgebraicConfig<2> for PoseidonGoldilocksConfig {
|
||||
type F = GoldilocksField;
|
||||
type FE = QuadraticExtension<Self::F>;
|
||||
type Hasher = PoseidonHash;
|
||||
type InnerHasher = PoseidonHash;
|
||||
}
|
||||
|
||||
/// Keccak hash function.
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
pub struct KeccakHash<const N: usize>;
|
||||
impl<F: RichField, const N: usize> Hasher<F> for KeccakHash<N> {
|
||||
@ -210,6 +184,50 @@ impl<F: RichField, const N: usize> Hasher<F> for KeccakHash<N> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Generic configuration trait.
|
||||
pub trait GenericConfig<const D: usize>:
|
||||
Debug + Clone + Sync + Sized + Send + Eq + PartialEq
|
||||
{
|
||||
/// Main field.
|
||||
type F: RichField + Extendable<D, Extension = Self::FE>;
|
||||
/// Field extension of degree 4 of the main field.
|
||||
type FE: FieldExtension<D, BaseField = Self::F>;
|
||||
/// Hash function used for building Merkle trees.
|
||||
type Hasher: Hasher<Self::F>;
|
||||
/// Algebraic hash function used for the challenger and hashing public inputs.
|
||||
type InnerHasher: AlgebraicHasher<Self::F>;
|
||||
}
|
||||
|
||||
/// Configuration trait for "algebraic" configurations, i.e., those using an algebraic hash function
|
||||
/// in Merkle trees.
|
||||
/// Same as `GenericConfig` trait but with `InnerHasher: AlgebraicHasher<F>`.
|
||||
pub trait AlgebraicConfig<const D: usize>:
|
||||
Debug + Clone + Sync + Sized + Send + Eq + PartialEq
|
||||
{
|
||||
type F: RichField + Extendable<D, Extension = Self::FE>;
|
||||
type FE: FieldExtension<D, BaseField = Self::F>;
|
||||
type Hasher: AlgebraicHasher<Self::F>;
|
||||
type InnerHasher: AlgebraicHasher<Self::F>;
|
||||
}
|
||||
|
||||
impl<A: AlgebraicConfig<D>, const D: usize> GenericConfig<D> for A {
|
||||
type F = <Self as AlgebraicConfig<D>>::F;
|
||||
type FE = <Self as AlgebraicConfig<D>>::FE;
|
||||
type Hasher = <Self as AlgebraicConfig<D>>::Hasher;
|
||||
type InnerHasher = <Self as AlgebraicConfig<D>>::InnerHasher;
|
||||
}
|
||||
|
||||
/// Configuration using Poseidon over the Goldilocks field.
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
pub struct PoseidonGoldilocksConfig;
|
||||
impl AlgebraicConfig<2> for PoseidonGoldilocksConfig {
|
||||
type F = GoldilocksField;
|
||||
type FE = QuadraticExtension<Self::F>;
|
||||
type Hasher = PoseidonHash;
|
||||
type InnerHasher = PoseidonHash;
|
||||
}
|
||||
|
||||
/// Configuration using truncated Keccak over the Goldilocks field.
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
pub struct KeccakGoldilocksConfig;
|
||||
impl GenericConfig<2> for KeccakGoldilocksConfig {
|
||||
@ -218,50 +236,3 @@ impl GenericConfig<2> for KeccakGoldilocksConfig {
|
||||
type Hasher = KeccakHash<25>;
|
||||
type InnerHasher = PoseidonHash;
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq, Copy, Clone, Debug)]
|
||||
pub struct BytesHash<const N: usize>([u8; N]);
|
||||
impl<const N: usize> Serialize for BytesHash<N> {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
impl<'de, const N: usize> Deserialize<'de> for BytesHash<N> {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> From<Vec<u8>> for BytesHash<N> {
|
||||
fn from(v: Vec<u8>) -> Self {
|
||||
Self(v.try_into().unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> From<BytesHash<N>> for Vec<u8> {
|
||||
fn from(hash: BytesHash<N>) -> Self {
|
||||
hash.0.to_vec()
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> From<BytesHash<N>> for u64 {
|
||||
fn from(hash: BytesHash<N>) -> Self {
|
||||
u64::from_le_bytes(hash.0[..8].try_into().unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: RichField, const N: usize> From<BytesHash<N>> for Vec<F> {
|
||||
fn from(hash: BytesHash<N>) -> Self {
|
||||
let n = hash.0.len();
|
||||
let mut v = hash.0.to_vec();
|
||||
v.resize(ceil_div_usize(n, 8) * 8, 0);
|
||||
let mut buffer = Buffer::new(v);
|
||||
buffer.read_field_vec(buffer.len() / 8).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user