Hash domain and cs into transcript

This commit is contained in:
therealyingtong 2021-02-11 22:30:26 +08:00 committed by Sean Bowe
parent 437782e902
commit 4aa4b4463a
No known key found for this signature in database
GPG Key ID: 95684257D8F8B031
4 changed files with 134 additions and 3 deletions

View File

@ -5,11 +5,14 @@
//! [halo]: https://eprint.iacr.org/2019/1021
//! [plonk]: https://eprint.iacr.org/2019/953
use crate::arithmetic::CurveAffine;
use blake2b_simd::Params as Blake2bParams;
use crate::arithmetic::{CurveAffine, FieldExt};
use crate::poly::{
commitment::Params, Coeff, EvaluationDomain, ExtendedLagrangeCoeff, LagrangeCoeff, Polynomial,
};
use crate::transcript::{ChallengeScalar, Transcript};
use std::convert::TryInto;
mod circuit;
mod keygen;
@ -77,13 +80,38 @@ impl<C: CurveAffine> VerifyingKey<C> {
/// Hashes a verification key into a transcript.
pub fn hash<T: Transcript<C>>(&self, transcript: &mut T) -> io::Result<()> {
let mut hasher = Blake2bParams::new()
.hash_length(64)
.personal(C::BLAKE2B_PERSONALIZATION)
.to_state();
// Hash in constants in the domain which influence the proof
let domain_hash = &self.domain.hash(&mut hasher);
transcript.common_scalar(C::Scalar::from_bytes_wide(domain_hash))?;
// Hash in `ConstraintSystem`
let cs_hash = &self.cs.hash(&mut hasher);
transcript.common_scalar(C::Scalar::from_bytes_wide(cs_hash))?;
// Hash in vector of fixed commitments
hasher.update(b"num_fixed_commitments");
hasher.update(&self.fixed_commitments.len().to_le_bytes());
for commitment in &self.fixed_commitments {
transcript.common_point(*commitment)?;
}
// Hash in vector of permutation arguments
hasher.update(b"num_permutations");
hasher.update(&self.permutations.len().to_le_bytes());
for permutation in &self.permutations {
permutation.hash(transcript)?;
}
// Hash in final Blake2bState
transcript.common_scalar(C::Scalar::from_bytes_wide(
hasher.finalize().as_bytes().try_into().unwrap(),
))?;
Ok(())
}
}

View File

@ -1,8 +1,9 @@
use blake2b_simd::State as Blake2bState;
use core::cmp::max;
use core::ops::{Add, Mul};
use ff::Field;
use std::{
convert::TryFrom,
convert::{TryFrom, TryInto},
ops::{Neg, Sub},
};
@ -10,7 +11,7 @@ use super::{lookup, permutation, Error};
use crate::poly::Rotation;
/// A column type
pub trait ColumnType: 'static + Sized {}
pub trait ColumnType: 'static + Sized + std::fmt::Debug {}
/// A column with an index and type
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
@ -27,6 +28,11 @@ impl<C: ColumnType> Column<C> {
pub(crate) fn column_type(&self) -> &C {
&self.column_type
}
pub(crate) fn hash(&self, hasher: &mut Blake2bState) -> [u8; 64] {
hasher.update(&format!("{:?}", self).as_bytes());
hasher.finalize().as_bytes().try_into().unwrap()
}
}
/// An advice column
@ -317,6 +323,12 @@ impl<F: Field> Expression<F> {
Expression::Scaled(poly, _) => poly.degree(),
}
}
/// Hash an Expression into a Blake2bState
pub fn hash(&self, hasher: &mut Blake2bState) -> [u8; 64] {
hasher.update(&format!("{:?}", self).as_bytes());
hasher.finalize().as_bytes().try_into().unwrap()
}
}
impl<F: Field> Neg for Expression<F> {
@ -598,4 +610,70 @@ impl<F: Field> ConstraintSystem<F> {
self.num_instance_columns += 1;
tmp
}
/// Hashes the `ConstraintSystem` into a `u64`.
pub fn hash(&self, mut hasher: &mut Blake2bState) -> [u8; 64] {
hasher.update(b"num_fixed_columns");
hasher.update(&self.num_fixed_columns.to_le_bytes());
hasher.update(b"num_advice_columns");
hasher.update(&self.num_advice_columns.to_le_bytes());
hasher.update(b"num_aux_columns");
hasher.update(&self.num_aux_columns.to_le_bytes());
hasher.update(b"num_gates");
hasher.update(&self.gates.len().to_le_bytes());
for gate in self.gates.iter() {
hasher.update(gate.0.to_owned().as_bytes());
gate.1.hash(&mut hasher);
}
hasher.update(b"num_advice_queries");
hasher.update(&self.advice_queries.len().to_le_bytes());
for query in self.advice_queries.iter() {
query.0.hash(&mut hasher);
query.1.hash(&mut hasher);
}
hasher.update(b"num_aux_queries");
hasher.update(&self.aux_queries.len().to_le_bytes());
for query in self.aux_queries.iter() {
query.0.hash(&mut hasher);
query.1.hash(&mut hasher);
}
hasher.update(b"num_fixed_queries");
hasher.update(&self.fixed_queries.len().to_le_bytes());
for query in self.fixed_queries.iter() {
query.0.hash(&mut hasher);
query.1.hash(&mut hasher);
}
hasher.update(b"num_permutations");
hasher.update(&self.permutations.len().to_le_bytes());
for argument in self.permutations.iter() {
hasher.update(&argument.get_columns().len().to_le_bytes());
for column in argument.get_columns().iter() {
column.hash(&mut hasher);
}
}
hasher.update(b"num_lookups");
hasher.update(&self.lookups.len().to_le_bytes());
for argument in self.lookups.iter() {
hasher.update(&argument.input_columns.len().to_le_bytes());
hasher.update(&argument.table_columns.len().to_le_bytes());
for (input, table) in argument
.input_columns
.iter()
.zip(argument.table_columns.iter())
{
input.hash(&mut hasher);
table.hash(&mut hasher);
}
}
hasher.finalize().as_bytes().try_into().unwrap()
}
}

View File

@ -4,7 +4,9 @@
use crate::arithmetic::parallelize;
use blake2b_simd::State as Blake2bState;
use ff::Field;
use std::convert::TryInto;
use std::fmt::Debug;
use std::marker::PhantomData;
use std::ops::{Add, Deref, DerefMut, Index, IndexMut, Mul, RangeFrom, RangeFull, Sub};
@ -228,4 +230,10 @@ impl Rotation {
pub fn next() -> Rotation {
Rotation(1)
}
/// Hash Rotation into a Blake2bState
pub fn hash(&self, hasher: &mut Blake2bState) -> [u8; 64] {
hasher.update(&format!("{:?}", self).as_bytes());
hasher.finalize().as_bytes().try_into().unwrap()
}
}

View File

@ -8,6 +8,9 @@ use super::{Coeff, ExtendedLagrangeCoeff, LagrangeCoeff, Polynomial, Rotation};
use ff::{Field, PrimeField};
use std::marker::PhantomData;
use blake2b_simd::State as Blake2bState;
use std::convert::TryInto;
/// This structure contains precomputed constants and other details needed for
/// performing operations on an evaluation domain of size $2^k$ and an extended
/// domain of size $2^{k} * j$ with $j \neq 0$.
@ -376,4 +379,18 @@ impl<G: Group> EvaluationDomain<G> {
pub fn get_quotient_poly_degree(&self) -> usize {
self.quotient_poly_degree as usize
}
/// Hashes the constants in the domain which influence the proof into a u64
pub fn hash(&self, hasher: &mut Blake2bState) -> [u8; 64] {
hasher.update(b"k");
hasher.update(&self.k.to_le_bytes());
hasher.update(b"extended_k");
hasher.update(&self.extended_k.to_le_bytes());
hasher.update(b"omega");
hasher.update(&self.omega.to_bytes());
hasher.finalize().as_bytes().try_into().unwrap()
}
}