diff --git a/src/circuit/gadget.rs b/src/circuit/gadget.rs index 45224f5d2..3b1461d79 100644 --- a/src/circuit/gadget.rs +++ b/src/circuit/gadget.rs @@ -5,8 +5,8 @@ use pasta_curves::pallas; use super::{commit_ivk::CommitIvkChip, note_commit::NoteCommitChip}; use crate::constants::{ - NullifierK, OrchardCommitDomains, OrchardFixedBases, OrchardFixedBasesFull, OrchardHashDomains, - ValueCommitV, + NullifierK, OrchardCommitDomains, OrchardFixedBases, OrchardFixedBasesFull, + OrchardHashDomains, ValueCommitV, }; use halo2_gadgets::{ ecc::{ @@ -137,7 +137,7 @@ pub(in crate::circuit) fn value_commit_orchard< // commitment = [v] ValueCommitV let (commitment, _) = { let value_commit_v = ValueCommitV; - let value_commit_v = FixedPointShort::from_inner(ecc_chip.clone(), value_commit_v); + let value_commit_v = FixedPointShort::from_inner(ecc_chip.clone(), value_commit_v.into()); value_commit_v.mul(layouter.namespace(|| "[v] ValueCommitV"), v)? }; @@ -199,7 +199,8 @@ pub fn derive_nullifier< // `product` = [poseidon_hash(nk, rho) + psi] NullifierK. // let product = { - let nullifier_k = FixedPointBaseField::from_inner(ecc_chip, NullifierK); + let nullifier_k = NullifierK; + let nullifier_k = FixedPointBaseField::from_inner(ecc_chip, nullifier_k.into()); nullifier_k.mul( layouter.namespace(|| "[poseidon_output + psi] NullifierK"), scalar, diff --git a/src/constants.rs b/src/constants.rs index 06a345162..7fd7fc09f 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -6,7 +6,10 @@ pub mod util; #[cfg(feature = "circuit")] pub use self::sinsemilla::{OrchardCommitDomains, OrchardHashDomains}; #[cfg(feature = "circuit")] -pub use fixed_bases::{NullifierK, OrchardFixedBases, OrchardFixedBasesFull, ValueCommitV}; +pub use fixed_bases::{ + NullifierK, OrchardBaseFieldBases, OrchardFixedBases, OrchardFixedBasesFull, + OrchardShortScalarBases, ValueCommitV, +}; /// $\mathsf{MerkleDepth^{Orchard}}$ pub const MERKLE_DEPTH_ORCHARD: usize = 32; diff --git a/src/constants/fixed_bases.rs b/src/constants/fixed_bases.rs index 0e3a73906..8079e6a5a 100644 --- a/src/constants/fixed_bases.rs +++ b/src/constants/fixed_bases.rs @@ -54,13 +54,42 @@ pub const NUM_WINDOWS: usize = pub const NUM_WINDOWS_SHORT: usize = (L_VALUE + FIXED_BASE_WINDOW_SIZE - 1) / FIXED_BASE_WINDOW_SIZE; +/// Fixed bases used in scalar mul where the scalar is a base field element. +/// +/// The ECC chip's `FixedPoints::Base` associated type must be a single type, +/// so both `NullifierK` and `SpendAuthGBase` are wrapped in this enum. +/// `SpendAuthGBase` reuses the same generator and U/Z tables as +/// `OrchardFixedBasesFull::SpendAuthG` (same 85-window structure over the +/// 255-bit pallas base field), allowing `FixedPointBaseField::mul` to accept +/// an `AssignedCell` directly — no variable-base NonIdentityPoint witness needed. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub enum OrchardBaseFieldBases { + NullifierK, + SpendAuthGBase, +} + +/// Fixed bases used in scalar mul where the scalar is a short (64-bit) signed value. +/// +/// `FixedPoints::ShortScalar` must be a single type, so both `ValueCommitV` +/// and `SpendAuthGShort` are wrapped in this enum. `SpendAuthGShort` uses the +/// same generator as `SpendAuthG` but with 22-window precomputed tables, enabling +/// `FixedPointShort::mul` for vote-share values bounded to 30 bits by condition 9. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub enum OrchardShortScalarBases { + /// Value commitment generator for Orchard (original short base). + ValueCommitV, + /// SpendAuthG with short (22-window) tables, used for `[v_i]*G` in ElGamal + /// encryption where `v_i` is range-checked to 30 bits by condition 9. + SpendAuthGShort, +} + #[derive(Copy, Clone, Debug, Eq, PartialEq)] // A sum type for both full-width and short bases. This enables us to use the // shared functionality of full-width and short fixed-base scalar multiplication. pub enum OrchardFixedBases { Full(OrchardFixedBasesFull), - NullifierK, - ValueCommitV, + Base(OrchardBaseFieldBases), + Short(OrchardShortScalarBases), } impl From for OrchardFixedBases { @@ -70,17 +99,41 @@ impl From for OrchardFixedBases { } impl From for OrchardFixedBases { - fn from(_value_commit_v: ValueCommitV) -> Self { - Self::ValueCommitV + fn from(value_commit_v: ValueCommitV) -> Self { + Self::Short(value_commit_v.into()) } } impl From for OrchardFixedBases { + fn from(nullifier_k: NullifierK) -> Self { + Self::Base(nullifier_k.into()) + } +} + +impl From for OrchardFixedBases { + fn from(b: OrchardBaseFieldBases) -> Self { + Self::Base(b) + } +} + +impl From for OrchardFixedBases { + fn from(b: OrchardShortScalarBases) -> Self { + Self::Short(b) + } +} + +impl From for OrchardBaseFieldBases { fn from(_nullifier_k: NullifierK) -> Self { Self::NullifierK } } +impl From for OrchardShortScalarBases { + fn from(_value_commit_v: ValueCommitV) -> Self { + Self::ValueCommitV + } +} + /// The Orchard fixed bases used in scalar mul with full-width scalars. #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum OrchardFixedBasesFull { @@ -101,8 +154,8 @@ pub struct ValueCommitV; #[cfg(feature = "circuit")] impl FixedPoints for OrchardFixedBases { type FullScalar = OrchardFixedBasesFull; - type Base = NullifierK; - type ShortScalar = ValueCommitV; + type Base = OrchardBaseFieldBases; + type ShortScalar = OrchardShortScalarBases; } #[cfg(feature = "circuit")] @@ -154,6 +207,36 @@ impl FixedPoint for NullifierK { } } +#[cfg(feature = "circuit")] +impl FixedPoint for OrchardBaseFieldBases { + type FixedScalarKind = BaseFieldElem; + + fn generator(&self) -> pallas::Affine { + match self { + Self::NullifierK => nullifier_k::generator(), + Self::SpendAuthGBase => spend_auth_g::generator(), + } + } + + fn u(&self) -> Vec<[[u8; 32]; H]> { + match self { + Self::NullifierK => nullifier_k::U.to_vec(), + // SpendAuthG's full-scalar U/Z tables have the same 85-window + // structure as the base-field-element variant (pallas::Base and + // pallas::Scalar are both 255-bit); the precomputed values depend + // only on the generator and window layout, not the scalar kind. + Self::SpendAuthGBase => spend_auth_g::U.to_vec(), + } + } + + fn z(&self) -> Vec { + match self { + Self::NullifierK => nullifier_k::Z.to_vec(), + Self::SpendAuthGBase => spend_auth_g::Z.to_vec(), + } + } +} + #[cfg(feature = "circuit")] impl FixedPoint for ValueCommitV { type FixedScalarKind = ShortScalar; @@ -170,3 +253,138 @@ impl FixedPoint for ValueCommitV { value_commit_v::Z_SHORT.to_vec() } } + +#[cfg(feature = "circuit")] +impl FixedPoint for OrchardShortScalarBases { + type FixedScalarKind = ShortScalar; + + fn generator(&self) -> pallas::Affine { + match self { + Self::ValueCommitV => value_commit_v::generator(), + Self::SpendAuthGShort => spend_auth_g::generator(), + } + } + + fn u(&self) -> Vec<[[u8; 32]; H]> { + match self { + Self::ValueCommitV => value_commit_v::U_SHORT.to_vec(), + Self::SpendAuthGShort => spend_auth_g::U_SHORT.to_vec(), + } + } + + fn z(&self) -> Vec { + match self { + Self::ValueCommitV => value_commit_v::Z_SHORT.to_vec(), + Self::SpendAuthGShort => spend_auth_g::Z_SHORT.to_vec(), + } + } +} + +#[cfg(all(test, feature = "circuit"))] +mod tests { + use super::*; + + /// Ensures that `OrchardBaseFieldBases::SpendAuthGBase` routes to the + /// correct generator and tables via the `FixedPoint` trait. The U/Z data + /// is identical to `OrchardFixedBasesFull::SpendAuthG` (same generator, + /// same 85-window structure); this test makes the dispatch wiring explicit. + #[test] + fn spend_auth_g_base_field_routes_correctly() { + let full = OrchardFixedBasesFull::SpendAuthG; + let base = OrchardBaseFieldBases::SpendAuthGBase; + + assert_eq!( + full.generator(), + base.generator(), + "SpendAuthGBase must share the SpendAuthG generator" + ); + assert_eq!( + full.u(), + base.u(), + "SpendAuthGBase U tables must match SpendAuthG full-scalar U tables" + ); + assert_eq!( + full.z(), + base.z(), + "SpendAuthGBase Z tables must match SpendAuthG full-scalar Z tables" + ); + } + + /// Ensures that `OrchardBaseFieldBases::NullifierK` still routes to the + /// NullifierK generator and tables (regression guard for the enum refactor). + #[test] + fn nullifier_k_base_field_routes_correctly() { + let base = OrchardBaseFieldBases::NullifierK; + + assert_eq!( + base.generator(), + nullifier_k::generator(), + "OrchardBaseFieldBases::NullifierK must use the NullifierK generator" + ); + assert_eq!( + base.u(), + nullifier_k::U.to_vec(), + "OrchardBaseFieldBases::NullifierK U tables must match" + ); + assert_eq!( + base.z(), + nullifier_k::Z.to_vec(), + "OrchardBaseFieldBases::NullifierK Z tables must match" + ); + } + + #[test] + fn nullifier_k_converts_to_base_field_enum() { + assert_eq!(OrchardBaseFieldBases::from(NullifierK), OrchardBaseFieldBases::NullifierK); + } + + /// Ensures that `OrchardShortScalarBases::SpendAuthGShort` routes to the + /// SpendAuthG generator and the 22-window short tables. + #[test] + fn spend_auth_g_short_routes_correctly() { + let short = OrchardShortScalarBases::SpendAuthGShort; + let full = OrchardFixedBasesFull::SpendAuthG; + + assert_eq!( + short.generator(), + full.generator(), + "SpendAuthGShort must share the SpendAuthG generator" + ); + assert_eq!( + short.u().len(), + NUM_WINDOWS_SHORT, + "SpendAuthGShort U table must have NUM_WINDOWS_SHORT entries" + ); + assert_eq!( + short.z().len(), + NUM_WINDOWS_SHORT, + "SpendAuthGShort Z table must have NUM_WINDOWS_SHORT entries" + ); + // Short tables must differ from the full 85-window tables. + assert_ne!( + short.u(), + full.u()[..NUM_WINDOWS_SHORT].to_vec(), + "SpendAuthGShort U table must use the short-scalar window structure" + ); + } + + /// Ensures that `OrchardShortScalarBases::ValueCommitV` still routes to + /// the ValueCommitV generator and tables (regression guard for the enum change). + #[test] + fn value_commit_v_short_routes_correctly() { + let short = OrchardShortScalarBases::ValueCommitV; + let legacy = ValueCommitV; + + assert_eq!(short.generator(), legacy.generator()); + assert_eq!(short.u(), legacy.u()); + assert_eq!(short.z(), legacy.z()); + } + + #[test] + fn value_commit_v_converts_to_short_scalar_enum() { + assert_eq!( + OrchardShortScalarBases::from(ValueCommitV), + OrchardShortScalarBases::ValueCommitV + ); + } +} diff --git a/src/constants/fixed_bases/spend_auth_g.rs b/src/constants/fixed_bases/spend_auth_g.rs index 0a83fc363..35ead4fc6 100644 --- a/src/constants/fixed_bases/spend_auth_g.rs +++ b/src/constants/fixed_bases/spend_auth_g.rs @@ -2928,9 +2928,769 @@ pub fn generator() -> pallas::Affine { .unwrap() } +/// Short signed z-values for GENERATOR (22 windows, for SpendAuthGShort). +/// These can be reproduced by [`halo2_gadgets::ecc::chip::constants::find_zs_and_us`]. +pub const Z_SHORT: [u64; super::NUM_WINDOWS_SHORT] = [ + 49707, 15701, 45931, 163127, 41654, 212130, 34473, 25205, 4118, 10240, 12264, 22866, 203610, + 18808, 13851, 62448, 62380, 94497, 39496, 73216, 32037, 65411, +]; + +/// Short signed u-values for GENERATOR (22 windows, for SpendAuthGShort). +/// These can be reproduced by [`halo2_gadgets::ecc::chip::constants::find_zs_and_us`]. +pub const U_SHORT: [[[u8; 32]; super::H]; super::NUM_WINDOWS_SHORT] = [ + [ + [ + 134, 139, 159, 167, 179, 203, 183, 86, 54, 69, 108, 127, 183, 40, 226, 188, 34, 72, + 235, 174, 120, 30, 214, 202, 46, 166, 177, 78, 133, 80, 221, 35, + ], + [ + 128, 147, 194, 62, 34, 230, 94, 209, 44, 242, 88, 94, 91, 252, 184, 217, 72, 173, 32, + 128, 118, 158, 176, 67, 255, 192, 227, 150, 189, 56, 205, 10, + ], + [ + 89, 235, 150, 72, 148, 202, 175, 172, 88, 248, 184, 63, 149, 194, 33, 149, 187, 218, + 51, 194, 131, 184, 34, 138, 62, 112, 115, 0, 197, 109, 145, 37, + ], + [ + 55, 241, 4, 146, 234, 109, 232, 212, 90, 95, 84, 170, 84, 254, 20, 89, 80, 100, 143, 3, + 30, 229, 117, 35, 32, 249, 43, 36, 200, 74, 200, 13, + ], + [ + 194, 23, 77, 68, 227, 113, 225, 181, 201, 67, 219, 25, 234, 73, 160, 104, 12, 6, 180, + 204, 185, 16, 224, 62, 83, 132, 193, 185, 69, 90, 67, 29, + ], + [ + 156, 240, 85, 68, 24, 96, 228, 37, 250, 218, 25, 99, 51, 50, 37, 27, 23, 76, 42, 243, + 126, 23, 236, 249, 179, 94, 59, 83, 197, 193, 215, 32, + ], + [ + 73, 145, 163, 254, 185, 142, 57, 198, 25, 48, 144, 127, 17, 171, 210, 170, 164, 88, 3, + 235, 37, 45, 124, 125, 44, 113, 141, 119, 93, 91, 163, 47, + ], + [ + 144, 156, 74, 131, 227, 73, 40, 222, 73, 67, 210, 157, 154, 161, 96, 112, 61, 251, 210, + 2, 2, 199, 107, 190, 39, 133, 107, 181, 235, 217, 1, 32, + ], + ], + [ + [ + 204, 30, 193, 82, 109, 194, 174, 212, 203, 182, 251, 224, 85, 31, 240, 246, 163, 165, + 69, 160, 26, 78, 143, 50, 115, 92, 109, 71, 48, 205, 160, 15, + ], + [ + 20, 52, 64, 133, 30, 26, 4, 37, 88, 2, 107, 192, 179, 203, 130, 109, 203, 163, 224, 31, + 238, 207, 238, 0, 79, 55, 35, 8, 69, 238, 155, 60, + ], + [ + 129, 188, 56, 216, 72, 61, 212, 36, 171, 128, 228, 90, 229, 75, 126, 41, 186, 124, 100, + 62, 161, 224, 105, 69, 196, 160, 131, 35, 39, 217, 149, 40, + ], + [ + 168, 4, 93, 175, 37, 163, 30, 50, 27, 141, 194, 23, 206, 18, 65, 85, 150, 36, 51, 169, + 206, 47, 128, 65, 151, 181, 117, 50, 74, 251, 37, 14, + ], + [ + 143, 167, 209, 67, 187, 208, 101, 235, 49, 77, 89, 225, 7, 243, 50, 56, 150, 233, 186, + 94, 0, 161, 136, 54, 163, 101, 23, 180, 199, 82, 163, 32, + ], + [ + 83, 85, 245, 163, 247, 47, 226, 3, 90, 35, 254, 250, 71, 176, 18, 214, 121, 5, 11, 162, + 55, 2, 116, 46, 36, 20, 81, 19, 209, 79, 84, 53, + ], + [ + 181, 129, 189, 44, 171, 86, 12, 145, 21, 185, 255, 145, 238, 46, 220, 242, 242, 239, 5, + 39, 176, 87, 6, 205, 209, 13, 190, 26, 72, 252, 247, 47, + ], + [ + 169, 151, 215, 50, 18, 225, 124, 186, 49, 5, 84, 177, 139, 69, 189, 88, 237, 39, 196, + 111, 251, 146, 226, 12, 207, 215, 254, 0, 246, 155, 86, 31, + ], + ], + [ + [ + 178, 207, 217, 160, 25, 246, 180, 59, 161, 29, 253, 55, 84, 14, 217, 170, 120, 167, + 203, 21, 147, 2, 190, 236, 198, 41, 99, 194, 47, 97, 213, 20, + ], + [ + 45, 217, 42, 12, 249, 206, 77, 249, 191, 69, 78, 30, 201, 54, 60, 175, 218, 187, 222, + 73, 28, 240, 105, 118, 228, 192, 184, 161, 65, 230, 115, 35, + ], + [ + 145, 233, 255, 221, 141, 221, 216, 67, 77, 53, 229, 49, 167, 130, 235, 235, 55, 39, 88, + 70, 146, 70, 243, 31, 156, 138, 246, 251, 13, 41, 2, 16, + ], + [ + 44, 14, 167, 217, 244, 57, 222, 12, 243, 116, 172, 17, 218, 246, 161, 124, 209, 248, + 240, 97, 59, 176, 138, 242, 76, 23, 207, 179, 136, 243, 79, 12, + ], + [ + 120, 239, 19, 236, 60, 149, 184, 181, 237, 83, 242, 22, 122, 53, 211, 43, 195, 217, + 208, 185, 53, 156, 105, 158, 161, 156, 47, 90, 67, 139, 159, 60, + ], + [ + 249, 224, 188, 87, 191, 134, 192, 15, 207, 29, 167, 27, 149, 161, 44, 61, 81, 55, 15, + 30, 78, 203, 150, 136, 55, 222, 237, 245, 39, 227, 177, 29, + ], + [ + 91, 228, 118, 231, 230, 113, 246, 243, 112, 73, 19, 146, 105, 173, 81, 28, 27, 59, 168, + 92, 82, 198, 192, 111, 208, 156, 210, 129, 148, 194, 13, 14, + ], + [ + 224, 185, 193, 29, 240, 177, 244, 134, 56, 252, 24, 119, 213, 110, 191, 221, 105, 122, + 89, 30, 114, 196, 53, 33, 168, 48, 77, 85, 241, 128, 168, 51, + ], + ], + [ + [ + 79, 58, 209, 170, 171, 147, 19, 156, 23, 243, 181, 231, 92, 215, 234, 118, 17, 151, + 212, 115, 164, 220, 114, 178, 18, 147, 101, 201, 228, 162, 126, 54, + ], + [ + 235, 245, 230, 232, 32, 231, 43, 206, 119, 97, 30, 131, 10, 3, 195, 93, 78, 158, 42, + 62, 53, 26, 42, 26, 123, 39, 164, 39, 149, 119, 79, 39, + ], + [ + 78, 161, 190, 242, 222, 143, 16, 193, 35, 198, 206, 67, 37, 101, 231, 6, 62, 205, 36, + 2, 146, 11, 191, 111, 78, 107, 222, 19, 32, 194, 31, 28, + ], + [ + 189, 36, 36, 147, 50, 162, 17, 179, 250, 219, 167, 100, 114, 56, 90, 184, 42, 49, 101, + 155, 213, 179, 140, 62, 245, 55, 81, 218, 11, 116, 203, 32, + ], + [ + 170, 122, 46, 42, 82, 84, 63, 207, 174, 176, 7, 139, 74, 49, 198, 238, 243, 217, 155, + 175, 31, 22, 42, 49, 125, 6, 210, 80, 124, 138, 184, 42, + ], + [ + 30, 149, 102, 115, 26, 193, 146, 161, 139, 248, 18, 9, 55, 231, 50, 78, 236, 158, 74, + 204, 173, 228, 73, 125, 75, 127, 42, 21, 202, 128, 69, 46, + ], + [ + 33, 237, 143, 1, 212, 254, 16, 231, 202, 39, 42, 28, 134, 77, 246, 51, 31, 146, 160, + 11, 178, 194, 169, 251, 50, 131, 241, 132, 81, 122, 244, 58, + ], + [ + 197, 18, 235, 234, 189, 238, 252, 93, 244, 246, 76, 251, 21, 250, 8, 118, 38, 40, 39, + 103, 96, 147, 112, 103, 188, 219, 33, 183, 6, 139, 186, 47, + ], + ], + [ + [ + 27, 179, 1, 219, 5, 237, 22, 195, 49, 31, 125, 207, 224, 185, 249, 141, 188, 16, 209, + 225, 213, 167, 101, 63, 245, 229, 177, 242, 28, 121, 227, 4, + ], + [ + 209, 90, 156, 216, 151, 223, 46, 129, 150, 195, 74, 57, 16, 102, 32, 110, 156, 108, 48, + 128, 236, 231, 35, 169, 60, 210, 63, 240, 252, 175, 28, 22, + ], + [ + 133, 6, 154, 178, 236, 58, 163, 25, 85, 197, 169, 75, 26, 103, 112, 168, 225, 245, 103, + 211, 223, 163, 79, 47, 253, 17, 114, 233, 127, 217, 94, 51, + ], + [ + 252, 137, 21, 60, 226, 116, 238, 97, 66, 128, 128, 213, 51, 35, 35, 130, 77, 160, 200, + 226, 91, 25, 22, 133, 27, 188, 198, 159, 155, 4, 106, 4, + ], + [ + 76, 129, 23, 15, 64, 93, 179, 128, 41, 202, 40, 164, 7, 199, 172, 203, 98, 179, 243, + 28, 66, 149, 80, 177, 112, 51, 81, 231, 178, 208, 16, 54, + ], + [ + 100, 99, 114, 178, 31, 130, 16, 122, 18, 47, 103, 243, 55, 84, 112, 92, 156, 246, 119, + 91, 4, 173, 157, 48, 246, 132, 129, 162, 33, 42, 164, 38, + ], + [ + 152, 167, 13, 134, 122, 121, 84, 244, 205, 49, 40, 241, 68, 223, 97, 107, 112, 216, + 124, 98, 232, 219, 187, 158, 28, 95, 222, 129, 219, 240, 233, 13, + ], + [ + 255, 191, 150, 9, 220, 109, 94, 217, 202, 19, 194, 216, 152, 81, 167, 107, 204, 138, + 104, 200, 200, 253, 210, 14, 87, 133, 149, 93, 119, 137, 129, 45, + ], + ], + [ + [ + 162, 107, 4, 19, 49, 176, 93, 99, 15, 133, 159, 53, 191, 0, 79, 228, 236, 96, 145, 53, + 120, 10, 150, 94, 198, 49, 253, 119, 229, 116, 150, 13, + ], + [ + 205, 164, 35, 49, 168, 151, 217, 138, 164, 143, 237, 170, 140, 153, 15, 171, 74, 89, + 60, 195, 13, 20, 170, 36, 66, 199, 45, 252, 18, 47, 204, 8, + ], + [ + 95, 149, 177, 178, 217, 143, 235, 251, 203, 227, 33, 62, 147, 134, 228, 83, 84, 170, + 118, 91, 103, 94, 41, 99, 1, 95, 59, 67, 253, 146, 165, 5, + ], + [ + 19, 184, 182, 93, 1, 4, 202, 21, 119, 77, 151, 12, 98, 255, 223, 34, 54, 162, 44, 199, + 13, 217, 159, 37, 147, 185, 89, 21, 251, 128, 21, 25, + ], + [ + 190, 179, 248, 211, 188, 233, 181, 149, 178, 232, 28, 253, 234, 103, 160, 153, 252, + 188, 19, 132, 143, 227, 31, 109, 134, 85, 21, 104, 133, 39, 148, 13, + ], + [ + 149, 40, 255, 15, 159, 19, 43, 100, 31, 196, 107, 209, 83, 25, 77, 122, 211, 27, 237, + 158, 74, 188, 198, 73, 86, 171, 73, 163, 110, 176, 37, 55, + ], + [ + 25, 194, 88, 151, 108, 22, 157, 145, 11, 87, 6, 215, 227, 141, 203, 218, 34, 25, 236, + 49, 69, 170, 243, 13, 240, 210, 161, 186, 45, 32, 239, 12, + ], + [ + 100, 133, 83, 207, 52, 184, 61, 180, 226, 133, 42, 161, 249, 216, 158, 39, 5, 185, 52, + 8, 212, 185, 49, 234, 32, 200, 23, 158, 19, 111, 74, 50, + ], + ], + [ + [ + 215, 206, 249, 236, 176, 248, 217, 12, 0, 204, 155, 112, 248, 215, 200, 248, 8, 250, + 61, 104, 22, 109, 196, 54, 27, 3, 0, 203, 187, 116, 69, 45, + ], + [ + 82, 29, 122, 199, 191, 205, 105, 136, 96, 93, 249, 65, 104, 197, 48, 64, 166, 175, 144, + 96, 114, 186, 147, 65, 1, 35, 87, 134, 90, 145, 230, 24, + ], + [ + 154, 172, 87, 147, 10, 166, 129, 223, 224, 162, 95, 194, 248, 41, 234, 174, 177, 221, + 64, 244, 202, 201, 225, 138, 179, 110, 80, 104, 84, 39, 26, 43, + ], + [ + 75, 226, 94, 205, 107, 248, 174, 164, 95, 115, 20, 62, 241, 202, 80, 182, 248, 213, + 115, 216, 142, 165, 182, 8, 151, 156, 170, 110, 219, 237, 63, 3, + ], + [ + 49, 234, 64, 230, 146, 237, 191, 49, 112, 45, 60, 43, 252, 216, 195, 70, 153, 146, 225, + 144, 9, 226, 23, 158, 136, 113, 247, 108, 62, 144, 108, 9, + ], + [ + 103, 21, 127, 107, 59, 109, 133, 160, 143, 88, 92, 94, 63, 60, 176, 30, 201, 130, 24, + 59, 22, 197, 68, 223, 207, 57, 45, 122, 91, 202, 196, 35, + ], + [ + 52, 102, 244, 254, 244, 16, 81, 190, 173, 244, 154, 38, 64, 214, 63, 97, 169, 9, 167, + 51, 246, 33, 109, 247, 50, 220, 114, 64, 13, 179, 177, 30, + ], + [ + 144, 221, 225, 200, 23, 166, 32, 166, 176, 75, 198, 254, 19, 193, 245, 128, 7, 12, 208, + 85, 254, 120, 147, 143, 63, 184, 236, 60, 26, 253, 251, 35, + ], + ], + [ + [ + 75, 83, 105, 13, 6, 123, 42, 108, 212, 123, 233, 193, 139, 45, 132, 88, 44, 242, 39, + 25, 1, 235, 41, 93, 161, 218, 156, 90, 105, 43, 114, 46, + ], + [ + 113, 216, 156, 147, 163, 145, 14, 155, 250, 78, 89, 11, 16, 228, 91, 223, 129, 87, 8, + 161, 204, 28, 0, 75, 59, 172, 225, 121, 76, 165, 42, 36, + ], + [ + 195, 34, 156, 131, 184, 36, 15, 228, 23, 198, 79, 88, 138, 166, 168, 21, 16, 35, 82, + 123, 87, 247, 59, 42, 195, 113, 128, 240, 223, 247, 79, 25, + ], + [ + 197, 57, 189, 78, 132, 12, 150, 148, 108, 113, 199, 232, 67, 154, 65, 201, 151, 136, + 175, 146, 0, 126, 215, 68, 183, 100, 207, 132, 39, 238, 74, 28, + ], + [ + 213, 35, 155, 170, 77, 61, 206, 127, 232, 164, 11, 133, 55, 141, 203, 73, 112, 37, 27, + 8, 250, 18, 169, 233, 171, 174, 218, 9, 15, 227, 192, 24, + ], + [ + 134, 99, 90, 204, 109, 34, 78, 239, 97, 108, 119, 18, 165, 166, 98, 20, 155, 15, 193, + 71, 34, 134, 45, 232, 229, 4, 167, 6, 75, 99, 2, 54, + ], + [ + 4, 136, 7, 177, 132, 128, 188, 128, 221, 121, 213, 198, 133, 42, 219, 156, 145, 179, + 35, 254, 88, 233, 96, 90, 206, 150, 181, 191, 254, 218, 217, 31, + ], + [ + 183, 202, 252, 66, 36, 234, 250, 116, 96, 15, 72, 88, 124, 136, 8, 156, 204, 151, 89, + 171, 185, 139, 47, 215, 117, 207, 44, 117, 226, 84, 248, 5, + ], + ], + [ + [ + 48, 78, 243, 80, 211, 5, 172, 75, 113, 98, 154, 247, 185, 52, 36, 155, 5, 244, 149, 7, + 84, 162, 39, 0, 233, 219, 188, 229, 84, 18, 154, 34, + ], + [ + 135, 176, 3, 156, 231, 35, 196, 24, 109, 104, 169, 210, 121, 247, 72, 214, 141, 15, + 155, 221, 249, 30, 196, 117, 108, 229, 219, 116, 233, 89, 208, 61, + ], + [ + 108, 238, 126, 36, 119, 110, 54, 206, 165, 24, 218, 88, 206, 201, 226, 190, 28, 76, + 125, 62, 87, 21, 15, 158, 2, 233, 41, 18, 242, 223, 192, 6, + ], + [ + 169, 95, 111, 93, 78, 167, 161, 2, 54, 29, 206, 209, 119, 196, 7, 36, 248, 233, 68, 45, + 243, 58, 155, 147, 32, 175, 221, 168, 144, 79, 126, 18, + ], + [ + 229, 0, 65, 205, 148, 179, 229, 116, 253, 143, 119, 111, 142, 63, 235, 124, 140, 243, + 182, 164, 15, 57, 219, 23, 114, 237, 116, 213, 200, 235, 227, 55, + ], + [ + 9, 233, 193, 136, 60, 112, 74, 107, 87, 12, 113, 20, 8, 8, 94, 195, 227, 83, 178, 77, + 143, 104, 211, 169, 253, 62, 8, 196, 81, 39, 96, 13, + ], + [ + 223, 12, 147, 224, 113, 27, 48, 142, 243, 199, 244, 62, 255, 20, 63, 79, 12, 37, 159, + 81, 80, 172, 136, 23, 107, 186, 180, 33, 148, 49, 128, 10, + ], + [ + 100, 248, 42, 239, 155, 107, 80, 255, 126, 96, 195, 152, 204, 166, 14, 46, 114, 152, + 200, 111, 94, 233, 117, 247, 89, 83, 34, 2, 189, 3, 245, 4, + ], + ], + [ + [ + 26, 254, 208, 112, 167, 15, 77, 90, 124, 14, 227, 31, 204, 94, 253, 228, 223, 252, 114, + 141, 234, 26, 108, 144, 115, 131, 19, 142, 25, 148, 80, 53, + ], + [ + 95, 154, 56, 85, 66, 246, 97, 207, 254, 117, 98, 51, 204, 68, 9, 1, 157, 25, 113, 175, + 12, 172, 33, 67, 212, 17, 238, 76, 166, 43, 6, 30, + ], + [ + 48, 204, 33, 34, 141, 223, 27, 151, 244, 225, 206, 129, 54, 211, 251, 18, 168, 186, + 214, 141, 37, 229, 219, 62, 187, 87, 66, 140, 181, 233, 161, 35, + ], + [ + 143, 158, 2, 174, 102, 73, 205, 247, 110, 78, 131, 38, 192, 195, 70, 193, 14, 166, 232, + 42, 142, 222, 35, 147, 189, 77, 50, 220, 23, 56, 126, 38, + ], + [ + 10, 84, 87, 89, 169, 77, 97, 156, 0, 100, 41, 191, 232, 88, 138, 82, 220, 123, 231, 59, + 142, 115, 196, 116, 217, 80, 178, 117, 237, 250, 11, 32, + ], + [ + 152, 88, 228, 103, 64, 4, 197, 110, 204, 4, 0, 131, 250, 205, 206, 83, 180, 179, 98, + 51, 213, 11, 237, 149, 150, 226, 123, 62, 129, 198, 28, 58, + ], + [ + 188, 254, 66, 154, 178, 61, 236, 232, 27, 107, 131, 38, 104, 160, 49, 57, 3, 111, 18, + 106, 158, 91, 57, 220, 174, 59, 138, 227, 176, 49, 171, 15, + ], + [ + 92, 116, 148, 172, 212, 215, 137, 153, 48, 241, 40, 25, 45, 204, 141, 58, 235, 146, + 155, 248, 50, 112, 4, 206, 228, 70, 94, 117, 128, 150, 213, 18, + ], + ], + [ + [ + 155, 96, 199, 129, 161, 131, 9, 109, 43, 95, 79, 108, 230, 168, 172, 51, 244, 183, 203, + 211, 198, 95, 64, 184, 12, 184, 190, 250, 108, 77, 202, 61, + ], + [ + 151, 114, 132, 115, 19, 130, 213, 126, 140, 64, 58, 149, 171, 26, 245, 47, 253, 9, 212, + 80, 154, 3, 206, 254, 158, 241, 87, 90, 67, 8, 29, 59, + ], + [ + 231, 100, 245, 101, 53, 146, 235, 219, 228, 106, 101, 51, 85, 110, 51, 78, 221, 149, + 223, 78, 184, 47, 144, 234, 161, 28, 6, 48, 41, 228, 253, 57, + ], + [ + 239, 82, 160, 74, 136, 231, 198, 194, 99, 192, 170, 182, 36, 125, 149, 58, 9, 239, 91, + 146, 54, 104, 94, 42, 147, 4, 61, 79, 185, 11, 51, 1, + ], + [ + 56, 89, 137, 88, 196, 32, 115, 15, 6, 53, 123, 43, 42, 27, 226, 220, 196, 131, 211, + 126, 14, 174, 191, 229, 172, 6, 210, 189, 92, 66, 79, 26, + ], + [ + 236, 153, 243, 131, 143, 123, 164, 95, 214, 160, 21, 150, 12, 71, 118, 170, 92, 166, + 223, 162, 133, 58, 93, 2, 31, 57, 197, 190, 66, 169, 112, 18, + ], + [ + 137, 13, 132, 54, 102, 120, 119, 177, 34, 217, 123, 89, 76, 242, 218, 72, 236, 129, 33, + 42, 148, 242, 221, 33, 252, 74, 219, 142, 25, 82, 162, 62, + ], + [ + 0, 132, 243, 70, 85, 72, 216, 242, 225, 170, 56, 212, 52, 143, 154, 202, 248, 33, 148, + 236, 117, 24, 29, 63, 148, 233, 28, 74, 59, 44, 221, 6, + ], + ], + [ + [ + 122, 45, 241, 68, 72, 20, 58, 84, 181, 215, 45, 12, 74, 54, 17, 144, 144, 97, 82, 103, + 81, 123, 158, 238, 167, 173, 212, 8, 90, 63, 188, 59, + ], + [ + 190, 69, 211, 175, 56, 60, 42, 23, 208, 231, 241, 96, 205, 55, 222, 210, 178, 240, 230, + 118, 210, 253, 59, 206, 104, 165, 221, 249, 237, 74, 42, 33, + ], + [ + 69, 202, 255, 56, 181, 188, 225, 92, 19, 165, 74, 192, 67, 249, 139, 35, 87, 125, 27, + 228, 61, 78, 56, 144, 42, 255, 159, 217, 53, 99, 10, 62, + ], + [ + 17, 213, 190, 3, 139, 251, 81, 49, 133, 14, 185, 61, 240, 132, 117, 99, 240, 125, 104, + 191, 248, 27, 77, 11, 130, 122, 237, 184, 35, 100, 180, 3, + ], + [ + 236, 29, 195, 209, 34, 84, 144, 163, 206, 89, 168, 108, 27, 11, 70, 115, 204, 213, 254, + 154, 127, 24, 198, 242, 246, 223, 181, 250, 165, 119, 22, 62, + ], + [ + 60, 247, 191, 168, 239, 211, 60, 148, 241, 31, 18, 170, 16, 159, 36, 114, 42, 255, 166, + 224, 203, 137, 29, 159, 207, 121, 83, 18, 65, 177, 147, 58, + ], + [ + 142, 74, 131, 209, 60, 216, 199, 80, 41, 112, 74, 182, 191, 182, 44, 195, 255, 209, + 212, 108, 139, 121, 174, 211, 221, 158, 186, 94, 7, 171, 195, 6, + ], + [ + 198, 195, 122, 214, 128, 112, 1, 64, 196, 79, 62, 9, 3, 224, 192, 175, 23, 151, 79, + 177, 86, 124, 241, 131, 111, 212, 44, 236, 166, 31, 192, 15, + ], + ], + [ + [ + 50, 31, 67, 146, 113, 240, 176, 252, 99, 195, 220, 195, 236, 33, 235, 44, 22, 161, 130, + 84, 214, 230, 9, 201, 254, 31, 226, 194, 208, 156, 234, 31, + ], + [ + 130, 252, 165, 204, 53, 14, 76, 171, 205, 52, 8, 140, 156, 25, 1, 79, 106, 128, 120, + 230, 96, 4, 65, 143, 120, 86, 95, 116, 178, 151, 251, 21, + ], + [ + 82, 176, 110, 60, 13, 107, 15, 237, 57, 201, 226, 28, 131, 232, 139, 0, 26, 117, 17, + 21, 90, 52, 206, 160, 31, 184, 67, 211, 119, 126, 23, 2, + ], + [ + 86, 78, 25, 205, 17, 108, 177, 47, 226, 5, 14, 124, 217, 100, 164, 146, 67, 56, 65, + 155, 54, 2, 97, 66, 248, 244, 46, 71, 35, 246, 90, 35, + ], + [ + 28, 122, 89, 60, 230, 19, 230, 132, 129, 117, 243, 172, 180, 95, 210, 183, 231, 73, + 194, 50, 123, 93, 40, 116, 179, 64, 48, 127, 37, 161, 133, 1, + ], + [ + 72, 176, 170, 234, 97, 26, 154, 13, 139, 23, 69, 194, 241, 59, 143, 29, 131, 72, 236, + 123, 90, 116, 132, 207, 226, 63, 190, 11, 9, 159, 225, 18, + ], + [ + 71, 3, 178, 208, 101, 43, 142, 1, 34, 183, 67, 144, 188, 255, 243, 77, 160, 17, 3, 90, + 104, 102, 15, 237, 159, 17, 119, 223, 119, 180, 184, 11, + ], + [ + 198, 247, 138, 113, 71, 170, 58, 158, 166, 18, 216, 133, 230, 166, 87, 243, 180, 129, + 59, 227, 21, 156, 206, 171, 200, 29, 193, 191, 35, 144, 110, 35, + ], + ], + [ + [ + 143, 29, 76, 191, 243, 57, 156, 88, 188, 187, 113, 179, 47, 12, 12, 80, 210, 133, 232, + 199, 196, 174, 105, 166, 185, 201, 72, 33, 182, 107, 10, 14, + ], + [ + 164, 93, 48, 22, 226, 133, 56, 19, 13, 143, 250, 49, 96, 151, 50, 136, 186, 199, 102, + 135, 44, 77, 221, 203, 66, 145, 199, 234, 71, 151, 237, 60, + ], + [ + 40, 169, 150, 23, 171, 18, 88, 233, 196, 71, 216, 65, 86, 136, 191, 225, 157, 148, 204, + 166, 81, 32, 185, 159, 33, 211, 227, 110, 49, 200, 239, 6, + ], + [ + 177, 51, 226, 132, 191, 36, 206, 168, 107, 159, 196, 253, 111, 164, 203, 30, 229, 157, + 238, 168, 231, 1, 231, 132, 124, 170, 113, 72, 205, 71, 179, 61, + ], + [ + 173, 21, 156, 246, 171, 56, 11, 126, 227, 206, 228, 132, 13, 35, 56, 214, 167, 169, + 199, 247, 183, 237, 175, 164, 56, 38, 12, 149, 16, 165, 206, 41, + ], + [ + 128, 227, 45, 193, 60, 153, 0, 6, 8, 102, 44, 127, 61, 224, 183, 230, 212, 141, 1, 51, + 225, 100, 204, 170, 122, 148, 93, 219, 56, 143, 127, 14, + ], + [ + 70, 116, 18, 220, 241, 134, 196, 152, 34, 203, 160, 47, 133, 155, 48, 238, 3, 231, 142, + 250, 130, 80, 127, 29, 47, 30, 247, 166, 7, 84, 97, 32, + ], + [ + 198, 120, 45, 251, 227, 181, 90, 244, 88, 96, 139, 170, 238, 2, 214, 157, 142, 252, 38, + 70, 46, 231, 140, 254, 133, 163, 174, 239, 236, 31, 248, 47, + ], + ], + [ + [ + 55, 136, 210, 179, 46, 105, 249, 203, 6, 77, 242, 11, 176, 133, 40, 140, 94, 213, 221, + 116, 54, 114, 154, 208, 221, 104, 34, 129, 102, 30, 159, 58, + ], + [ + 79, 251, 68, 141, 49, 255, 119, 149, 245, 56, 33, 15, 177, 119, 71, 34, 2, 157, 154, + 100, 0, 130, 254, 89, 119, 244, 255, 136, 145, 170, 75, 22, + ], + [ + 246, 138, 15, 233, 177, 157, 214, 220, 249, 137, 175, 49, 64, 49, 163, 203, 16, 5, 156, + 137, 236, 177, 51, 237, 183, 248, 106, 64, 95, 201, 63, 60, + ], + [ + 169, 216, 126, 241, 88, 115, 61, 5, 60, 196, 46, 248, 192, 24, 133, 247, 107, 35, 176, + 62, 3, 251, 187, 51, 131, 108, 26, 58, 71, 173, 69, 50, + ], + [ + 84, 151, 140, 102, 38, 240, 56, 110, 112, 245, 122, 78, 225, 149, 139, 150, 7, 90, 124, + 202, 208, 243, 85, 76, 216, 157, 7, 245, 29, 230, 202, 57, + ], + [ + 151, 205, 82, 162, 218, 18, 210, 30, 96, 49, 203, 180, 161, 163, 135, 58, 156, 223, + 248, 97, 155, 19, 244, 20, 204, 201, 109, 159, 51, 166, 157, 53, + ], + [ + 12, 187, 38, 15, 49, 56, 192, 212, 23, 177, 153, 244, 192, 65, 217, 112, 210, 82, 187, + 254, 42, 203, 172, 84, 39, 84, 171, 8, 145, 13, 6, 50, + ], + [ + 61, 241, 209, 199, 182, 87, 14, 9, 24, 44, 194, 13, 4, 85, 186, 9, 120, 82, 120, 0, + 167, 113, 231, 252, 218, 210, 112, 246, 163, 9, 247, 30, + ], + ], + [ + [ + 196, 38, 105, 221, 18, 136, 108, 66, 223, 180, 237, 185, 161, 102, 180, 224, 164, 195, + 0, 254, 210, 238, 158, 146, 253, 119, 73, 191, 148, 17, 152, 50, + ], + [ + 76, 130, 205, 97, 172, 181, 61, 253, 66, 7, 37, 249, 147, 121, 205, 101, 67, 50, 84, + 125, 60, 49, 65, 55, 48, 130, 37, 86, 92, 89, 181, 35, + ], + [ + 206, 105, 119, 230, 215, 16, 15, 177, 186, 198, 98, 203, 210, 114, 246, 76, 112, 132, + 63, 157, 216, 253, 212, 195, 36, 11, 58, 200, 70, 165, 187, 21, + ], + [ + 95, 85, 152, 202, 120, 158, 2, 113, 140, 9, 152, 197, 28, 23, 243, 98, 30, 116, 241, + 59, 150, 179, 40, 13, 119, 61, 108, 115, 88, 216, 66, 62, + ], + [ + 108, 254, 117, 155, 108, 68, 3, 230, 25, 36, 106, 204, 158, 15, 114, 204, 134, 182, + 239, 235, 104, 144, 35, 31, 84, 246, 38, 252, 87, 60, 20, 12, + ], + [ + 14, 76, 210, 134, 98, 224, 219, 180, 88, 134, 93, 30, 34, 159, 112, 85, 114, 46, 244, + 59, 169, 188, 235, 108, 254, 236, 101, 86, 97, 132, 255, 62, + ], + [ + 23, 167, 12, 59, 95, 158, 244, 22, 231, 148, 247, 162, 226, 95, 136, 77, 62, 234, 119, + 179, 29, 62, 160, 116, 94, 240, 7, 113, 75, 241, 201, 62, + ], + [ + 233, 142, 117, 40, 158, 166, 10, 78, 255, 44, 235, 32, 185, 102, 244, 23, 251, 127, 12, + 249, 120, 18, 196, 115, 151, 251, 236, 217, 97, 244, 107, 52, + ], + ], + [ + [ + 107, 155, 149, 167, 240, 119, 46, 213, 7, 178, 44, 247, 191, 163, 247, 255, 109, 160, + 87, 134, 236, 13, 49, 223, 245, 64, 194, 243, 220, 166, 203, 59, + ], + [ + 119, 76, 9, 136, 64, 42, 217, 106, 111, 151, 245, 107, 101, 191, 56, 195, 239, 79, 134, + 239, 31, 37, 60, 160, 131, 101, 90, 38, 70, 213, 103, 5, + ], + [ + 184, 158, 152, 93, 132, 93, 66, 54, 106, 79, 134, 202, 210, 72, 74, 25, 96, 93, 178, + 109, 231, 248, 173, 100, 154, 238, 170, 161, 194, 75, 148, 35, + ], + [ + 156, 17, 84, 74, 233, 248, 203, 84, 127, 132, 30, 245, 52, 4, 27, 53, 231, 22, 75, 33, + 66, 120, 175, 149, 77, 114, 237, 18, 99, 189, 126, 31, + ], + [ + 78, 144, 141, 232, 241, 133, 132, 75, 214, 189, 122, 225, 96, 155, 59, 205, 144, 243, + 176, 140, 253, 16, 152, 59, 80, 164, 165, 153, 15, 89, 219, 50, + ], + [ + 62, 16, 233, 111, 18, 125, 232, 184, 252, 2, 110, 148, 127, 176, 119, 162, 66, 211, + 198, 136, 64, 217, 189, 197, 121, 66, 32, 71, 147, 13, 146, 8, + ], + [ + 2, 45, 226, 216, 24, 120, 51, 196, 19, 16, 152, 7, 178, 30, 88, 194, 255, 186, 231, 81, + 217, 67, 36, 199, 41, 12, 135, 142, 160, 247, 199, 34, + ], + [ + 80, 193, 196, 122, 181, 155, 245, 75, 185, 218, 222, 58, 140, 110, 234, 148, 30, 19, + 243, 175, 188, 1, 57, 85, 163, 253, 211, 210, 200, 7, 249, 43, + ], + ], + [ + [ + 187, 240, 200, 140, 119, 234, 17, 25, 208, 192, 198, 107, 40, 102, 42, 212, 229, 1, + 231, 121, 19, 35, 249, 226, 185, 185, 225, 179, 84, 18, 191, 15, + ], + [ + 249, 21, 206, 133, 57, 77, 143, 126, 192, 252, 36, 62, 173, 16, 52, 11, 7, 198, 149, + 220, 48, 193, 40, 253, 217, 235, 145, 96, 241, 215, 193, 16, + ], + [ + 203, 97, 200, 83, 165, 80, 108, 220, 108, 185, 123, 227, 143, 247, 12, 200, 9, 195, 68, + 46, 238, 32, 161, 42, 247, 167, 117, 159, 191, 89, 194, 21, + ], + [ + 200, 138, 253, 89, 202, 154, 62, 252, 110, 107, 99, 189, 49, 33, 69, 220, 211, 185, 89, + 62, 101, 231, 203, 68, 45, 5, 73, 39, 144, 230, 186, 43, + ], + [ + 31, 42, 63, 181, 31, 131, 126, 192, 52, 179, 2, 178, 71, 193, 225, 189, 52, 153, 62, + 166, 207, 192, 10, 174, 67, 228, 150, 28, 169, 63, 242, 60, + ], + [ + 228, 40, 179, 0, 71, 223, 234, 22, 20, 72, 239, 146, 142, 7, 168, 47, 102, 186, 137, + 113, 248, 114, 204, 153, 12, 22, 145, 205, 143, 109, 169, 3, + ], + [ + 232, 227, 9, 11, 117, 128, 157, 126, 209, 210, 249, 174, 93, 37, 76, 150, 114, 36, 225, + 75, 198, 10, 191, 167, 6, 2, 244, 29, 191, 7, 21, 44, + ], + [ + 86, 226, 203, 210, 152, 57, 49, 226, 171, 172, 86, 225, 126, 215, 249, 166, 100, 119, + 54, 180, 193, 199, 146, 147, 253, 16, 107, 16, 22, 21, 106, 31, + ], + ], + [ + [ + 249, 155, 151, 211, 192, 36, 207, 21, 36, 141, 169, 175, 223, 248, 235, 62, 161, 214, + 236, 25, 35, 202, 64, 158, 84, 97, 121, 1, 190, 142, 23, 56, + ], + [ + 79, 129, 15, 128, 17, 234, 8, 173, 53, 238, 129, 60, 40, 6, 33, 216, 0, 171, 82, 80, + 227, 3, 219, 184, 48, 231, 244, 213, 115, 224, 162, 49, + ], + [ + 246, 219, 42, 28, 42, 134, 38, 100, 60, 131, 51, 159, 148, 5, 219, 203, 159, 51, 175, + 176, 154, 20, 79, 168, 197, 140, 200, 98, 192, 113, 179, 48, + ], + [ + 87, 7, 235, 9, 102, 19, 100, 91, 214, 230, 74, 213, 117, 120, 7, 239, 137, 255, 158, + 243, 160, 169, 30, 105, 28, 72, 188, 245, 76, 187, 227, 46, + ], + [ + 158, 245, 74, 150, 32, 197, 25, 173, 237, 231, 201, 44, 210, 117, 134, 203, 75, 108, + 102, 63, 124, 33, 47, 100, 56, 65, 129, 102, 161, 211, 117, 22, + ], + [ + 204, 70, 46, 194, 74, 212, 80, 20, 239, 11, 98, 124, 117, 38, 63, 246, 222, 191, 44, + 185, 131, 146, 129, 92, 158, 2, 87, 240, 150, 133, 57, 19, + ], + [ + 236, 136, 27, 147, 102, 12, 170, 62, 254, 16, 6, 217, 27, 178, 115, 247, 60, 158, 45, + 219, 224, 99, 111, 154, 253, 46, 247, 200, 138, 156, 26, 26, + ], + [ + 75, 211, 65, 63, 194, 212, 191, 3, 100, 173, 100, 101, 62, 25, 72, 147, 13, 148, 111, + 14, 157, 82, 27, 241, 125, 154, 243, 137, 14, 135, 241, 26, + ], + ], + [ + [ + 218, 202, 124, 110, 86, 218, 195, 2, 64, 68, 69, 220, 16, 26, 0, 40, 224, 238, 59, 69, + 246, 226, 3, 27, 219, 85, 17, 245, 133, 220, 230, 63, + ], + [ + 212, 226, 110, 162, 36, 55, 75, 198, 129, 197, 158, 79, 126, 204, 159, 71, 33, 60, 121, + 48, 127, 147, 250, 124, 60, 87, 179, 173, 160, 204, 32, 53, + ], + [ + 137, 110, 13, 7, 108, 200, 154, 204, 18, 86, 44, 221, 40, 171, 207, 5, 25, 42, 108, 2, + 147, 18, 42, 89, 101, 50, 48, 7, 233, 123, 235, 8, + ], + [ + 206, 247, 190, 175, 201, 90, 146, 123, 203, 83, 104, 46, 243, 131, 105, 131, 39, 186, + 205, 103, 203, 204, 186, 196, 251, 101, 101, 250, 186, 160, 211, 12, + ], + [ + 237, 149, 65, 13, 108, 153, 242, 14, 61, 62, 156, 46, 128, 126, 158, 246, 226, 128, + 243, 193, 10, 165, 120, 64, 72, 91, 32, 215, 90, 235, 82, 24, + ], + [ + 185, 204, 139, 200, 5, 172, 176, 126, 105, 190, 243, 150, 126, 26, 28, 74, 143, 149, + 118, 82, 210, 254, 70, 30, 81, 23, 128, 89, 255, 171, 137, 63, + ], + [ + 169, 75, 113, 101, 245, 119, 251, 230, 244, 201, 79, 85, 164, 86, 81, 155, 57, 44, 203, + 143, 173, 62, 78, 180, 1, 48, 216, 129, 223, 34, 105, 33, + ], + [ + 71, 92, 139, 39, 87, 72, 88, 2, 1, 5, 154, 14, 244, 138, 253, 116, 113, 203, 7, 174, + 49, 216, 88, 94, 233, 251, 220, 17, 19, 62, 142, 41, + ], + ], + [ + [ + 61, 222, 98, 187, 178, 246, 136, 235, 234, 162, 29, 132, 16, 87, 58, 249, 140, 210, 62, + 204, 34, 166, 135, 164, 118, 21, 181, 46, 215, 232, 234, 41, + ], + [ + 108, 124, 187, 66, 180, 167, 233, 17, 56, 166, 172, 61, 198, 167, 53, 66, 58, 24, 86, + 29, 24, 30, 59, 213, 140, 66, 162, 145, 212, 204, 115, 25, + ], + [ + 126, 189, 246, 53, 52, 94, 147, 57, 67, 135, 51, 106, 225, 56, 234, 69, 109, 0, 84, 85, + 158, 111, 234, 117, 134, 231, 202, 117, 69, 62, 231, 62, + ], + [ + 180, 135, 221, 126, 92, 15, 183, 27, 71, 155, 203, 35, 217, 20, 196, 191, 166, 148, 12, + 90, 70, 8, 55, 187, 227, 234, 199, 6, 170, 31, 164, 35, + ], + [ + 127, 229, 190, 196, 138, 191, 99, 200, 2, 94, 33, 220, 198, 94, 247, 56, 92, 235, 5, + 231, 0, 215, 115, 237, 123, 128, 163, 62, 245, 136, 81, 22, + ], + [ + 227, 192, 203, 190, 191, 238, 65, 46, 225, 246, 98, 119, 248, 140, 53, 18, 29, 161, 15, + 186, 236, 103, 170, 73, 194, 235, 181, 196, 130, 245, 221, 13, + ], + [ + 64, 205, 137, 125, 6, 95, 1, 144, 47, 13, 117, 175, 2, 2, 233, 104, 21, 195, 159, 219, + 27, 30, 12, 229, 218, 26, 207, 101, 32, 16, 167, 2, + ], + [ + 34, 165, 74, 35, 215, 50, 17, 254, 127, 186, 142, 239, 125, 1, 238, 118, 184, 35, 133, + 15, 46, 87, 123, 153, 143, 75, 66, 12, 100, 48, 121, 48, + ], + ], + [ + [ + 81, 164, 111, 19, 41, 239, 136, 17, 225, 145, 174, 11, 52, 189, 227, 115, 144, 101, 67, + 231, 99, 255, 59, 237, 161, 214, 236, 105, 2, 233, 131, 17, + ], + [ + 85, 239, 129, 19, 40, 9, 214, 53, 195, 98, 123, 7, 238, 213, 123, 153, 53, 74, 249, + 128, 246, 153, 29, 35, 39, 132, 103, 181, 185, 104, 194, 63, + ], + [ + 178, 88, 54, 71, 151, 154, 127, 147, 108, 116, 137, 109, 201, 224, 46, 137, 77, 255, + 12, 181, 18, 68, 112, 229, 35, 34, 137, 84, 177, 248, 182, 32, + ], + [ + 220, 238, 127, 81, 74, 251, 196, 23, 229, 54, 141, 109, 147, 147, 166, 40, 17, 179, + 204, 19, 186, 96, 21, 184, 24, 21, 63, 49, 50, 38, 27, 49, + ], + [ + 64, 83, 66, 127, 41, 42, 138, 123, 192, 172, 15, 123, 110, 41, 140, 169, 211, 250, 150, + 210, 56, 168, 91, 43, 238, 51, 48, 52, 20, 184, 42, 49, + ], + [ + 245, 202, 195, 95, 230, 179, 97, 113, 66, 59, 28, 136, 218, 66, 181, 100, 209, 35, 227, + 174, 4, 15, 54, 85, 57, 122, 158, 172, 189, 44, 240, 59, + ], + [ + 142, 186, 163, 67, 100, 126, 10, 1, 147, 183, 0, 191, 19, 148, 210, 75, 126, 178, 96, + 208, 218, 203, 154, 166, 127, 94, 221, 81, 72, 53, 67, 28, + ], + [ + 84, 90, 197, 131, 87, 84, 106, 82, 153, 120, 160, 42, 252, 54, 101, 99, 251, 211, 81, + 205, 157, 113, 9, 102, 253, 69, 6, 188, 159, 66, 213, 60, + ], + ], +]; + #[cfg(test)] mod tests { - use super::super::{NUM_WINDOWS, ORCHARD_PERSONALIZATION}; + use super::super::{NUM_WINDOWS, NUM_WINDOWS_SHORT, ORCHARD_PERSONALIZATION}; use super::*; use group::Curve; use halo2_gadgets::ecc::chip::constants::{test_lagrange_coeffs, test_zs_and_us}; @@ -2960,4 +3720,16 @@ mod tests { let base = super::generator(); test_zs_and_us(base, &Z, &U, NUM_WINDOWS); } + + #[test] + fn z_short() { + let base = super::generator(); + test_zs_and_us(base, &Z_SHORT, &U_SHORT, NUM_WINDOWS_SHORT); + } + + #[test] + fn lagrange_coeffs_short() { + let base = super::generator(); + test_lagrange_coeffs(base, NUM_WINDOWS_SHORT); + } }