mirror of https://github.com/zcash/orchard.git
primitives::sinsemilla: Use hard-coded generators in sinsemilla_s.
This commit is contained in:
parent
506b6a6dcd
commit
995728caa6
|
@ -25,7 +25,6 @@ use halo2::{
|
||||||
use pasta_curves::pallas;
|
use pasta_curves::pallas;
|
||||||
|
|
||||||
mod generator_table;
|
mod generator_table;
|
||||||
pub use generator_table::get_s_by_idx;
|
|
||||||
use generator_table::GeneratorTableConfig;
|
use generator_table::GeneratorTableConfig;
|
||||||
|
|
||||||
mod hash_to_point;
|
mod hash_to_point;
|
||||||
|
|
|
@ -1,16 +1,11 @@
|
||||||
use crate::primitives::sinsemilla::{self, sinsemilla_s_generators, S_PERSONALIZATION};
|
use crate::primitives::sinsemilla::{self, SINSEMILLA_S};
|
||||||
use halo2::{
|
use halo2::{
|
||||||
circuit::Layouter,
|
circuit::Layouter,
|
||||||
plonk::{ConstraintSystem, Error, Expression, TableColumn},
|
plonk::{ConstraintSystem, Error, Expression, TableColumn},
|
||||||
poly::Rotation,
|
poly::Rotation,
|
||||||
};
|
};
|
||||||
|
|
||||||
use pasta_curves::{
|
use pasta_curves::{arithmetic::FieldExt, pallas};
|
||||||
arithmetic::{CurveAffine, CurveExt, FieldExt},
|
|
||||||
pallas,
|
|
||||||
};
|
|
||||||
|
|
||||||
use group::Curve;
|
|
||||||
|
|
||||||
/// Table containing independent generators S[0..2^k]
|
/// Table containing independent generators S[0..2^k]
|
||||||
#[derive(Eq, PartialEq, Copy, Clone, Debug)]
|
#[derive(Eq, PartialEq, Copy, Clone, Debug)]
|
||||||
|
@ -69,10 +64,7 @@ impl GeneratorTableConfig {
|
||||||
|
|
||||||
// Lookup expressions default to the first entry when `q_s1`
|
// Lookup expressions default to the first entry when `q_s1`
|
||||||
// is not enabled.
|
// is not enabled.
|
||||||
let (init_x, init_y) = {
|
let (init_x, init_y) = SINSEMILLA_S[0];
|
||||||
let init_p = get_s_by_idx(0).to_affine().coordinates().unwrap();
|
|
||||||
(*init_p.x(), *init_p.y())
|
|
||||||
};
|
|
||||||
let not_q_s1 = Expression::Constant(pallas::Base::one()) - q_s1.clone();
|
let not_q_s1 = Expression::Constant(pallas::Base::one()) - q_s1.clone();
|
||||||
|
|
||||||
let m = q_s1.clone() * word; // The first table index is 0.
|
let m = q_s1.clone() * word; // The first table index is 0.
|
||||||
|
@ -87,41 +79,18 @@ impl GeneratorTableConfig {
|
||||||
layouter.assign_table(
|
layouter.assign_table(
|
||||||
|| "generator_table",
|
|| "generator_table",
|
||||||
|mut table| {
|
|mut table| {
|
||||||
// We generate the row values lazily (we only need them during keygen).
|
for (index, (x, y)) in SINSEMILLA_S.iter().enumerate() {
|
||||||
let mut rows = sinsemilla_s_generators();
|
|
||||||
|
|
||||||
for index in 0..(1 << sinsemilla::K) {
|
|
||||||
let mut row = None;
|
|
||||||
table.assign_cell(
|
table.assign_cell(
|
||||||
|| "table_idx",
|
|| "table_idx",
|
||||||
self.table_idx,
|
self.table_idx,
|
||||||
index,
|
index,
|
||||||
|| {
|
|| Ok(pallas::Base::from_u64(index as u64)),
|
||||||
row = rows.next();
|
|
||||||
Ok(pallas::Base::from_u64(index as u64))
|
|
||||||
},
|
|
||||||
)?;
|
|
||||||
table.assign_cell(
|
|
||||||
|| "table_x",
|
|
||||||
self.table_x,
|
|
||||||
index,
|
|
||||||
|| row.map(|(x, _)| x).ok_or(Error::SynthesisError),
|
|
||||||
)?;
|
|
||||||
table.assign_cell(
|
|
||||||
|| "table_y",
|
|
||||||
self.table_y,
|
|
||||||
index,
|
|
||||||
|| row.map(|(_, y)| y).ok_or(Error::SynthesisError),
|
|
||||||
)?;
|
)?;
|
||||||
|
table.assign_cell(|| "table_x", self.table_x, index, || Ok(*x))?;
|
||||||
|
table.assign_cell(|| "table_y", self.table_y, index, || Ok(*y))?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get generator S by index
|
|
||||||
pub fn get_s_by_idx(idx: u32) -> pallas::Point {
|
|
||||||
let hash = pallas::Point::hash_to_curve(S_PERSONALIZATION);
|
|
||||||
hash(&idx.to_le_bytes())
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
use super::super::SinsemillaInstructions;
|
use super::super::SinsemillaInstructions;
|
||||||
use super::{get_s_by_idx, CellValue, EccPoint, SinsemillaChip, Var};
|
use super::{CellValue, EccPoint, SinsemillaChip, Var};
|
||||||
use crate::primitives::sinsemilla::{self, lebs2ip_k, INV_TWO_POW_K};
|
use crate::primitives::sinsemilla::{self, lebs2ip_k, INV_TWO_POW_K, SINSEMILLA_S};
|
||||||
use halo2::{
|
use halo2::{
|
||||||
circuit::{Chip, Region},
|
circuit::{Chip, Region},
|
||||||
plonk::Error,
|
plonk::Error,
|
||||||
};
|
};
|
||||||
|
|
||||||
use ff::{Field, PrimeFieldBits};
|
use ff::{Field, PrimeFieldBits};
|
||||||
use group::Curve;
|
|
||||||
use pasta_curves::{
|
use pasta_curves::{
|
||||||
arithmetic::{CurveAffine, FieldExt},
|
arithmetic::{CurveAffine, FieldExt},
|
||||||
pallas,
|
pallas,
|
||||||
|
@ -112,7 +111,7 @@ impl SinsemillaChip {
|
||||||
{
|
{
|
||||||
use crate::circuit::gadget::sinsemilla::message::MessagePiece;
|
use crate::circuit::gadget::sinsemilla::message::MessagePiece;
|
||||||
use crate::primitives::sinsemilla::{K, S_PERSONALIZATION};
|
use crate::primitives::sinsemilla::{K, S_PERSONALIZATION};
|
||||||
use group::prime::PrimeCurveAffine;
|
use group::{prime::PrimeCurveAffine, Curve};
|
||||||
use pasta_curves::arithmetic::CurveExt;
|
use pasta_curves::arithmetic::CurveExt;
|
||||||
|
|
||||||
let field_elems: Option<Vec<pallas::Base>> =
|
let field_elems: Option<Vec<pallas::Base>> =
|
||||||
|
@ -235,20 +234,11 @@ impl SinsemillaChip {
|
||||||
.collect()
|
.collect()
|
||||||
});
|
});
|
||||||
|
|
||||||
// Get (x_p, y_p) for each word. We precompute this here so that we can use `batch_normalize()`.
|
// Get (x_p, y_p) for each word.
|
||||||
let generators_projective: Option<Vec<pallas::Point>> = words
|
let generators: Option<Vec<(pallas::Base, pallas::Base)>> = words.clone().map(|words| {
|
||||||
.clone()
|
words
|
||||||
.map(|words| words.iter().map(|word| get_s_by_idx(*word)).collect());
|
|
||||||
let generators: Option<Vec<(pallas::Base, pallas::Base)>> =
|
|
||||||
generators_projective.map(|generators_projective| {
|
|
||||||
let mut generators = vec![pallas::Affine::default(); generators_projective.len()];
|
|
||||||
pallas::Point::batch_normalize(&generators_projective, &mut generators);
|
|
||||||
generators
|
|
||||||
.iter()
|
.iter()
|
||||||
.map(|gen| {
|
.map(|word| SINSEMILLA_S[*word as usize])
|
||||||
let point = gen.coordinates().unwrap();
|
|
||||||
(*point.x(), *point.y())
|
|
||||||
})
|
|
||||||
.collect()
|
.collect()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
//! The Sinsemilla hash function and commitment scheme.
|
//! The Sinsemilla hash function and commitment scheme.
|
||||||
|
|
||||||
use halo2::arithmetic::CurveExt;
|
use group::prime::PrimeCurveAffine;
|
||||||
|
use halo2::arithmetic::{CurveAffine, CurveExt};
|
||||||
use pasta_curves::pallas;
|
use pasta_curves::pallas;
|
||||||
use subtle::CtOption;
|
use subtle::CtOption;
|
||||||
|
|
||||||
|
@ -12,6 +13,7 @@ use self::addition::IncompletePoint;
|
||||||
mod constants;
|
mod constants;
|
||||||
mod sinsemilla_s;
|
mod sinsemilla_s;
|
||||||
pub use constants::*;
|
pub use constants::*;
|
||||||
|
pub use sinsemilla_s::*;
|
||||||
|
|
||||||
pub(crate) fn lebs2ip_k(bits: &[bool]) -> u32 {
|
pub(crate) fn lebs2ip_k(bits: &[bool]) -> u32 {
|
||||||
assert!(bits.len() == K);
|
assert!(bits.len() == K);
|
||||||
|
@ -114,13 +116,11 @@ impl HashDomain {
|
||||||
fn hash_to_point_inner(&self, msg: impl Iterator<Item = bool>) -> IncompletePoint {
|
fn hash_to_point_inner(&self, msg: impl Iterator<Item = bool>) -> IncompletePoint {
|
||||||
let padded: Vec<_> = Pad::new(msg).collect();
|
let padded: Vec<_> = Pad::new(msg).collect();
|
||||||
|
|
||||||
let hasher_S = pallas::Point::hash_to_curve(S_PERSONALIZATION);
|
|
||||||
let S = |chunk: &[bool]| hasher_S(&lebs2ip_k(chunk).to_le_bytes());
|
|
||||||
|
|
||||||
padded
|
padded
|
||||||
.chunks(K)
|
.chunks(K)
|
||||||
.fold(IncompletePoint::from(self.Q), |acc, chunk| {
|
.fold(IncompletePoint::from(self.Q), |acc, chunk| {
|
||||||
(acc + S(chunk)) + acc
|
let (S_x, S_y) = SINSEMILLA_S[lebs2ip_k(chunk) as usize];
|
||||||
|
acc + pallas::Affine::from_xy(S_x, S_y).unwrap().to_curve() + acc
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue