Skip to content

Commit

Permalink
adjuct function orders for hash_message
Browse files Browse the repository at this point in the history
  • Loading branch information
YaoGalteland committed May 13, 2024
1 parent 46773e3 commit 3621e0e
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 70 deletions.
2 changes: 1 addition & 1 deletion halo2_gadgets/src/sinsemilla/chip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ where
};

// Set up lookup argument
GeneratorTableConfig::configure(meta, &config);
GeneratorTableConfig::configure(meta, config.clone());

config
}
Expand Down
2 changes: 1 addition & 1 deletion halo2_gadgets/src/sinsemilla/chip/generator_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ impl GeneratorTableConfig {
/// controlled by `q_sinsemilla`, and would likely not apply to other chips.
pub fn configure<Hash, Commit, F, Lookup>(
meta: &mut ConstraintSystem<pallas::Base>,
config: &super::SinsemillaConfig<Hash, Commit, F, Lookup>,
config: super::SinsemillaConfig<Hash, Commit, F, Lookup>,
) where
Hash: HashDomains<pallas::Affine>,
F: FixedPoints<pallas::Affine>,
Expand Down
136 changes: 68 additions & 68 deletions halo2_gadgets/src/sinsemilla/chip/hash_to_point.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ where
/// [Specification](https://p.z.cash/halo2-0.1:sinsemilla-constraints?partial).
#[allow(non_snake_case)]
#[allow(clippy::type_complexity)]
pub(crate) fn hash_message(
pub(super) fn hash_message(
&self,
region: &mut Region<'_, pallas::Base>,
Q: pallas::Affine,
Expand All @@ -56,73 +56,6 @@ where
self.check_hash_result(EccPointQ::PublicPoint(Q), message, x_a, y_a, zs_sum)
}

#[allow(non_snake_case)]
#[allow(unused_variables)]
// Check equivalence to result from primitives::sinsemilla::hash_to_point
pub(crate) fn check_hash_result(
&self,
Q: EccPointQ,
message: &<Self as SinsemillaInstructions<
pallas::Affine,
{ sinsemilla::K },
{ sinsemilla::C },
>>::Message,
x_a: X<pallas::Base>,
y_a: AssignedCell<Assigned<pallas::Base>, pallas::Base>,
zs_sum: Vec<Vec<AssignedCell<pallas::Base, pallas::Base>>>,
) -> HashResult {
#[cfg(test)]
{
use crate::sinsemilla::primitives::{K, S_PERSONALIZATION};

use group::{prime::PrimeCurveAffine, Curve};
use pasta_curves::arithmetic::CurveExt;

let field_elems: Value<Vec<_>> = message
.iter()
.map(|piece| piece.field_elem().map(|elem| (elem, piece.num_words())))
.collect();

let value_Q = match Q {
EccPointQ::PublicPoint(p) => Value::known(p),
EccPointQ::PrivatePoint(p) => p.point(),
};

field_elems
.zip(x_a.value().zip(y_a.value()))
.zip(value_Q)
.assert_if_known(|((field_elems, (x_a, y_a)), value_Q)| {
// Get message as a bitstring.
let bitstring: Vec<bool> = field_elems
.iter()
.flat_map(|(elem, num_words)| {
elem.to_le_bits().into_iter().take(K * num_words)
})
.collect();

let hasher_S = pallas::Point::hash_to_curve(S_PERSONALIZATION);
let S = |chunk: &[bool]| hasher_S(&lebs2ip_k(chunk).to_le_bytes());

// We can use complete addition here because it differs from
// incomplete addition with negligible probability.
let expected_point = bitstring
.chunks(K)
.fold(value_Q.to_curve(), |acc, chunk| (acc + S(chunk)) + acc);
let actual_point =
pallas::Affine::from_xy(x_a.evaluate(), y_a.evaluate()).unwrap();
expected_point.to_affine() == actual_point
});
}

x_a.value()
.zip(y_a.value())
.error_if_known_and(|(x_a, y_a)| x_a.is_zero_vartime() || y_a.is_zero_vartime())?;
Ok((
NonIdentityEccPoint::from_coordinates_unchecked(x_a.0, y_a),
zs_sum,
))
}

#[allow(non_snake_case)]
/// Assign the coordinates of the initial public point `Q`,
/// y_Q to a fixed column
Expand Down Expand Up @@ -244,6 +177,73 @@ where
Ok((x_a, y_a, zs_sum))
}

#[allow(non_snake_case)]
#[allow(unused_variables)]
// Check equivalence to result from primitives::sinsemilla::hash_to_point
pub(crate) fn check_hash_result(
&self,
Q: EccPointQ,
message: &<Self as SinsemillaInstructions<
pallas::Affine,
{ sinsemilla::K },
{ sinsemilla::C },
>>::Message,
x_a: X<pallas::Base>,
y_a: AssignedCell<Assigned<pallas::Base>, pallas::Base>,
zs_sum: Vec<Vec<AssignedCell<pallas::Base, pallas::Base>>>,
) -> HashResult {
#[cfg(test)]
{
use crate::sinsemilla::primitives::{K, S_PERSONALIZATION};

use group::{prime::PrimeCurveAffine, Curve};
use pasta_curves::arithmetic::CurveExt;

let field_elems: Value<Vec<_>> = message
.iter()
.map(|piece| piece.field_elem().map(|elem| (elem, piece.num_words())))
.collect();

let value_Q = match Q {
EccPointQ::PublicPoint(p) => Value::known(p),
EccPointQ::PrivatePoint(p) => p.point(),
};

field_elems
.zip(x_a.value().zip(y_a.value()))
.zip(value_Q)
.assert_if_known(|((field_elems, (x_a, y_a)), value_Q)| {
// Get message as a bitstring.
let bitstring: Vec<bool> = field_elems
.iter()
.flat_map(|(elem, num_words)| {
elem.to_le_bits().into_iter().take(K * num_words)
})
.collect();

let hasher_S = pallas::Point::hash_to_curve(S_PERSONALIZATION);
let S = |chunk: &[bool]| hasher_S(&lebs2ip_k(chunk).to_le_bytes());

// We can use complete addition here because it differs from
// incomplete addition with negligible probability.
let expected_point = bitstring
.chunks(K)
.fold(value_Q.to_curve(), |acc, chunk| (acc + S(chunk)) + acc);
let actual_point =
pallas::Affine::from_xy(x_a.evaluate(), y_a.evaluate()).unwrap();
expected_point.to_affine() == actual_point
});
}

x_a.value()
.zip(y_a.value())
.error_if_known_and(|(x_a, y_a)| x_a.is_zero_vartime() || y_a.is_zero_vartime())?;
Ok((
NonIdentityEccPoint::from_coordinates_unchecked(x_a.0, y_a),
zs_sum,
))
}

#[allow(clippy::type_complexity)]
/// Hashes a message piece containing `piece.length` number of `K`-bit words.
///
Expand Down

0 comments on commit 3621e0e

Please sign in to comment.