From bd08808566b5fbeae9b89f0ae00157afee01e617 Mon Sep 17 00:00:00 2001 From: therealyingtong Date: Sun, 20 Jun 2021 20:54:33 +0800 Subject: [PATCH] SinsemillaChip::configure(): Merge "Initial y_q" gate with main gate This allows the MockProver to see the fixed_y_q query as semantically connected to q_sinsemilla1. Co-authored-by: Jack Grigg --- src/circuit/gadget/sinsemilla/chip.rs | 17 ++++++----------- .../gadget/sinsemilla/chip/hash_to_point.rs | 18 +++++++++++++++--- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/circuit/gadget/sinsemilla/chip.rs b/src/circuit/gadget/sinsemilla/chip.rs index 2612bfe4..2549a384 100644 --- a/src/circuit/gadget/sinsemilla/chip.rs +++ b/src/circuit/gadget/sinsemilla/chip.rs @@ -150,17 +150,6 @@ impl SinsemillaChip { (lambda_1 + lambda_2) * (x_a - x_r(meta, rotation)) }; - // Check that the initial x_A, x_P, lambda_1, lambda_2 are consistent with y_Q. - meta.create_gate("Initial y_Q", |meta| { - let fixed_y_q = meta.query_fixed(config.fixed_y_q, Rotation::cur()); - - // Y_A = (lambda_1 + lambda_2) * (x_a - x_r) - let Y_A = Y_A(meta, Rotation::cur()); - - // fixed_y_q * (2 * fixed_y_q - Y_{A,0}) = 0 - vec![fixed_y_q.clone() * (two.clone() * fixed_y_q - Y_A)] - }); - meta.create_gate("Sinsemilla gate", |meta| { let q_s1 = meta.query_selector(config.q_sinsemilla1); let q_s2 = meta.query_fixed(config.q_sinsemilla2, Rotation::cur()); @@ -168,6 +157,7 @@ impl SinsemillaChip { let one = Expression::Constant(pallas::Base::one()); q_s2.clone() * (q_s2 - one) }; + let fixed_y_q = meta.query_fixed(config.fixed_y_q, Rotation::cur()); let lambda_1_next = meta.query_advice(config.lambda_1, Rotation::next()); let lambda_2_cur = meta.query_advice(config.lambda_2, Rotation::cur()); @@ -183,6 +173,10 @@ impl SinsemillaChip { // Y_A = (lambda_1 + lambda_2) * (x_a - x_r) let Y_A_next = Y_A(meta, Rotation::next()); + // Check that the initial x_A, x_P, lambda_1, lambda_2 are consistent with y_Q. + // fixed_y_q * (2 * fixed_y_q - Y_{A,0}) = 0 + let init_y_q_check = fixed_y_q.clone() * (two.clone() * fixed_y_q - Y_A_cur.clone()); + // lambda2^2 - (x_a_next + x_r + x_a_cur) = 0 let secant_line = lambda_2_cur.clone().square() - (x_a_next.clone() + x_r + x_a_cur.clone()); @@ -207,6 +201,7 @@ impl SinsemillaChip { }; vec![ + ("Initial y_q", init_y_q_check), ("Secant line", q_s1.clone() * secant_line), ("Sinsemilla gate", q_s1 * expr), ] diff --git a/src/circuit/gadget/sinsemilla/chip/hash_to_point.rs b/src/circuit/gadget/sinsemilla/chip/hash_to_point.rs index 7bc24031..c72e503e 100644 --- a/src/circuit/gadget/sinsemilla/chip/hash_to_point.rs +++ b/src/circuit/gadget/sinsemilla/chip/hash_to_point.rs @@ -57,8 +57,20 @@ impl SinsemillaChip { )?; // Constrain the initial x_a, lambda_1, lambda_2, x_p using the fixed y_q - // initializer. - region.assign_fixed(|| "fixed y_q", config.fixed_y_q, offset, || Ok(y_q))?; + // initializer. Assign `fixed_y_q` to be zero on every other row. + { + region.assign_fixed(|| "fixed y_q", config.fixed_y_q, offset, || Ok(y_q))?; + + let total_num_words = message.iter().map(|piece| piece.num_words()).sum(); + for row in 1..total_num_words { + region.assign_fixed( + || "fixed y_q", + config.fixed_y_q, + offset + row, + || Ok(pallas::Base::zero()), + )?; + } + } let y_a = Some(y_q); @@ -68,7 +80,7 @@ impl SinsemillaChip { let mut zs_sum: Vec>> = Vec::new(); // Hash each piece in the message. - for (idx, piece) in message[0..message.len()].iter().enumerate() { + for (idx, piece) in message.iter().enumerate() { let final_piece = idx == message.len() - 1; // The value of the accumulator after this piece is processed.