hash_to_point(): Introduce final_piece boolean flag

This toggles the assignment of q_s2 on the last row of each piece.
We assign q_s2 = 2 on the last row of the final piece, and q_s2 = 0
on the last row of other pieces.

This allows us to process the final_piece in the main loop together
with the other pieces.

Co-authored-by: Jack Grigg <jack@electriccoin.co>
This commit is contained in:
therealyingtong 2021-06-20 10:55:26 +08:00
parent 031bb0bc87
commit 9ce29d9d4d
1 changed files with 24 additions and 28 deletions

View File

@ -60,10 +60,12 @@ impl SinsemillaChip {
let mut zs_sum: Vec<Vec<CellValue<pallas::Base>>> = Vec::new(); let mut zs_sum: Vec<Vec<CellValue<pallas::Base>>> = Vec::new();
// Hash each piece in the message except the final piece. // Hash each piece in the message.
for piece in message[0..(message.len() - 1)].iter() { for (idx, piece) in message[0..message.len()].iter().enumerate() {
let final_piece = idx == message.len() - 1;
// The value of the accumulator after this piece is processed. // The value of the accumulator after this piece is processed.
let (x, y, zs) = self.hash_piece(region, offset, piece, x_a, y_a)?; let (x, y, zs) = self.hash_piece(region, offset, piece, x_a, y_a, final_piece)?;
// Since each message word takes one row to process, we increase // Since each message word takes one row to process, we increase
// the offset by `piece.num_words` on each iteration. // the offset by `piece.num_words` on each iteration.
@ -75,29 +77,9 @@ impl SinsemillaChip {
zs_sum.push(zs); zs_sum.push(zs);
} }
// Hash the final message piece. // Assign the final y_a.
let y_a = { let y_a = {
let piece = &message[message.len() - 1]; // Assign the final y_a.
// The value of the accumulator after this piece is processed.
let (x, y, zs) = self.hash_piece(region, offset, piece, x_a, y_a)?;
// Since each message word takes one row to process, we increase
// the offset by `piece.num_words` on each iteration.
offset += piece.num_words();
// Update the accumulator to the latest value.
x_a = x;
y_a = y;
zs_sum.push(zs);
// Assign and constrain the final `y_a`.
region.assign_fixed(
|| "qs_2 = 2 on final row",
config.q_sinsemilla2,
offset - 1,
|| Ok(pallas::Base::from_u64(2)),
)?;
let y_a_cell = region.assign_advice( let y_a_cell = region.assign_advice(
|| "y_a", || "y_a",
config.lambda_1, config.lambda_1,
@ -181,6 +163,7 @@ impl SinsemillaChip {
>>::MessagePiece, >>::MessagePiece,
x_a: X<pallas::Base>, x_a: X<pallas::Base>,
y_a: Y<pallas::Base>, y_a: Y<pallas::Base>,
final_piece: bool,
) -> Result< ) -> Result<
( (
X<pallas::Base>, X<pallas::Base>,
@ -208,12 +191,25 @@ impl SinsemillaChip {
)?; )?;
} }
// Set `q_sinsemilla2` fixed column to 0 on the last row. // Set `q_sinsemilla2` fixed column to 0 on the last row if this is
// not the final piece, or to 2 on the last row of the final piece.
region.assign_fixed( region.assign_fixed(
|| "q_s2 = 1", || {
if final_piece {
"q_s2 for final piece"
} else {
"q_s2 between pieces"
}
},
config.q_sinsemilla2, config.q_sinsemilla2,
offset + piece.num_words() - 1, offset + piece.num_words() - 1,
|| Ok(pallas::Base::zero()), || {
Ok(if final_piece {
pallas::Base::from_u64(2)
} else {
pallas::Base::zero()
})
},
)?; )?;
} }