diff --git a/Cargo.lock b/Cargo.lock index 385c1c8886..6d84f6cb2e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -466,7 +466,9 @@ dependencies = [ "caliptra-emu-types", "caliptra-hw-model-types", "caliptra-registers", + "fips204", "lazy_static", + "rand", "sha3", "smlang", "tock-registers", @@ -1358,6 +1360,17 @@ dependencies = [ "subtle", ] +[[package]] +name = "fips204" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a7a91da22e550a56b4ace2681cd344cc0c3fd1640235ac433a32561668d58b9" +dependencies = [ + "rand_core", + "sha3", + "zeroize", +] + [[package]] name = "flagset" version = "0.4.4" diff --git a/Cargo.toml b/Cargo.toml index 9058c3d313..f8f1817a76 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -146,6 +146,7 @@ dpe = { path = "dpe/dpe", default-features = false, features = ["dpe_profile_p38 crypto = { path = "dpe/crypto", default-features = false } platform = { path = "dpe/platform", default-features = false } elf = "0.7.2" +fips204 = "0.2.1" gdbstub = "0.6.3" gdbstub_arch = "0.2.4" getrandom = "0.2" diff --git a/sw-emulator/lib/periph/Cargo.toml b/sw-emulator/lib/periph/Cargo.toml index c74f6814ca..2e76b96140 100644 --- a/sw-emulator/lib/periph/Cargo.toml +++ b/sw-emulator/lib/periph/Cargo.toml @@ -18,7 +18,9 @@ caliptra-emu-derive.workspace = true caliptra-emu-types.workspace = true caliptra-hw-model-types.workspace = true caliptra-registers.workspace = true +fips204.workspace = true lazy_static.workspace = true +rand.workspace = true sha3.workspace = true smlang.workspace = true tock-registers.workspace = true diff --git a/sw-emulator/lib/periph/src/helpers.rs b/sw-emulator/lib/periph/src/helpers.rs index ca34f68b88..ac15d1ddf8 100644 --- a/sw-emulator/lib/periph/src/helpers.rs +++ b/sw-emulator/lib/periph/src/helpers.rs @@ -23,7 +23,9 @@ pub trait U32Array: AsRef<[u32]> { } pub trait U32ArrayBytes: AsRef<[u8]> { const WORD_LEN: usize; - type WordArray: AsMut<[u32]> + Default; + type WordArray: AsMut<[u32]>; + // Required because Default isn't implemented for [u32; 64 and higher] + fn default_result() -> Self::WordArray; } macro_rules! u32_array_impl { ($word_len:literal) => { @@ -37,6 +39,9 @@ macro_rules! u32_array_impl { impl U32ArrayBytes for [u8; $word_len * 4] { const WORD_LEN: usize = $word_len; type WordArray = [u32; $word_len]; + fn default_result() -> Self::WordArray { + [0u32; $word_len] + } } }; } @@ -58,9 +63,12 @@ u32_array_impl!(14); u32_array_impl!(15); u32_array_impl!(16); u32_array_impl!(32); +u32_array_impl!(648); +u32_array_impl!(1157); +u32_array_impl!(1224); pub fn words_from_bytes_le(arr: &A) -> A::WordArray { - let mut result = A::WordArray::default(); + let mut result = A::default_result(); for i in 0..result.as_mut().len() { result.as_mut()[i] = u32::from_le_bytes(arr.as_ref()[i * 4..][..4].try_into().unwrap()) } @@ -68,7 +76,7 @@ pub fn words_from_bytes_le(arr: &A) -> A::WordArray { } pub fn words_from_bytes_be(arr: &A) -> A::WordArray { - let mut result = A::WordArray::default(); + let mut result = A::default_result(); for i in 0..result.as_mut().len() { result.as_mut()[i] = u32::from_be_bytes(arr.as_ref()[i * 4..][..4].try_into().unwrap()) } diff --git a/sw-emulator/lib/periph/src/lib.rs b/sw-emulator/lib/periph/src/lib.rs index 02e7e6270b..dd82d71880 100644 --- a/sw-emulator/lib/periph/src/lib.rs +++ b/sw-emulator/lib/periph/src/lib.rs @@ -25,6 +25,7 @@ mod hmac_sha384; mod iccm; mod key_vault; mod mailbox; +mod ml_dsa87; mod root_bus; mod sha512_acc; pub mod soc_reg; diff --git a/sw-emulator/lib/periph/src/ml_dsa87.rs b/sw-emulator/lib/periph/src/ml_dsa87.rs new file mode 100644 index 0000000000..050856a605 --- /dev/null +++ b/sw-emulator/lib/periph/src/ml_dsa87.rs @@ -0,0 +1,628 @@ +/*++ + +Licensed under the Apache-2.0 license. + +File Name: + +ml_dsa87.rs + +Abstract: + +File contains Ml_Dsa87 peripheral implementation. + +--*/ + +use caliptra_emu_bus::{ActionHandle, BusError, Clock, ReadOnlyRegister, ReadWriteRegister, Timer}; +use caliptra_emu_derive::Bus; +use caliptra_emu_types::{RvData, RvSize}; +use fips204::ml_dsa_87::{try_keygen_with_rng, PrivateKey, PublicKey, PK_LEN, SIG_LEN, SK_LEN}; +use fips204::traits::{SerDes, Signer, Verifier}; +use rand::rngs::StdRng; +use rand::SeedableRng; +use tock_registers::interfaces::{ReadWriteable, Readable, Writeable}; +use tock_registers::register_bitfields; + +use crate::helpers::{bytes_from_words_le, words_from_bytes_le}; + +/// ML_DSA87 Initialization Vector size +const ML_DSA87_IV_SIZE: usize = 64; + +/// ML_DSA87 Key Generation seed +const ML_DSA87_SEED_SIZE: usize = 32; + +/// ML_DSA87 SIGN_RND size +const ML_DSA87_SIGN_RND_SIZE: usize = 32; + +/// ML_DSA87 MSG size +const ML_DSA87_MSG_SIZE: usize = 64; + +/// ML_DSA87 VERIFICATION size +const ML_DSA87_VERIFICATION_SIZE: usize = 64; + +/// The number of CPU clock cycles it takes to perform Ml_Dsa87 operation +const ML_DSA87_OP_TICKS: u64 = 1000; + +register_bitfields! [ + u32, + + /// Control Register Fields + Control [ + CTRL OFFSET(0) NUMBITS(2) [ + IDLE = 0b00, + GEN_KEY = 0b01, + SIGN = 0b10, + VERIFY = 0b11, + ], + ZEROIZE OFFSET(2) NUMBITS(1) [], +// PCR_SIGN OFFSET(3) NUMBITS(1) [] TODO remove right?? + ], + + /// Status Register Fields + Status[ + READY OFFSET(0) NUMBITS(1) [], + VALID OFFSET(1) NUMBITS(1) [], + RSVD OFFSET(2) NUMBITS(30) [], + ], +]; + +#[derive(Bus)] +#[poll_fn(poll)] +#[warm_reset_fn(warm_reset)] +#[update_reset_fn(update_reset)] +pub struct MlDsa87 { + /// Name registers + #[register_array(offset = 0x0000_0000)] + name: [u32; 2], + + /// Version registers + #[register_array(offset = 0x0000_0008)] + version: [u32; 2], + + /// Control register + #[register(offset = 0x0000_0010, write_fn = on_write_control)] + control: ReadWriteRegister, + + /// Status register + #[register(offset = 0x0000_0018)] + status: ReadOnlyRegister, + + /// Initialization vector for blinding and counter measures + #[register_array(offset = 0x0000_0080)] + iv: [u32; ML_DSA87_IV_SIZE / 4], + + /// Seed size + #[register_array(offset = 0x0000_0100)] + seed: [u32; ML_DSA87_SEED_SIZE / 4], + + /// Sign RND + #[register_array(offset = 0x0000_0180)] + sign_rnd: [u32; ML_DSA87_SIGN_RND_SIZE / 4], + + /// Message + #[register_array(offset = 0x0000_0200)] + message: [u32; ML_DSA87_MSG_SIZE / 4], + + /// Verification result + #[register_array(offset = 0x0000_0280, write_fn = write_access_fault)] + verification_result: [u32; ML_DSA87_VERIFICATION_SIZE / 4], + + /// Secret Key Out (software only?) + #[register_array(offset = 0x0000_0300, write_fn = write_access_fault)] + sk_out: [u32; SK_LEN / 4], + + /// Secret Key in + #[register_array(offset = 0x0000_1620, read_fn = read_access_fault)] + sk_in: [u32; SK_LEN / 4], + + /// Public key + #[register_array(offset = 0x0000_2940)] + pk: [u32; PK_LEN / 4], + + /// Signature + #[register_array(offset = 0x0000_3400)] + signature: [u32; SIG_LEN / 4 + 1], // Signature len is unaligned + + /// Timer + timer: Timer, + + /// Operation complete callback + op_complete_action: Option, +} + +impl MlDsa87 { + /// NAME0 Register Value TODO update when known + const NAME0_VAL: RvData = 0x73656370; //0x63737065; // secp + + /// NAME1 Register Value TODO update when known + const NAME1_VAL: RvData = 0x2D333834; // -384 + + /// VERSION0 Register Value TODO update when known + const VERSION0_VAL: RvData = 0x30302E31; // 1.0 + + /// VERSION1 Register Value TODO update when known + const VERSION1_VAL: RvData = 0x00000000; + + pub fn new(clock: &Clock) -> Self { + Self { + name: [Self::NAME0_VAL, Self::NAME1_VAL], + version: [Self::VERSION0_VAL, Self::VERSION1_VAL], + control: ReadWriteRegister::new(0), + status: ReadOnlyRegister::new(Status::READY::SET.value), + iv: Default::default(), + seed: Default::default(), + sign_rnd: Default::default(), + message: Default::default(), + verification_result: Default::default(), + sk_out: [0; 1224], + sk_in: [0; 1224], + pk: [0; 648], + signature: [0; 1157], + timer: Timer::new(clock), + op_complete_action: None, + } + } + + fn read_access_fault(&self, _size: RvSize, _index: usize) -> Result { + Err(BusError::LoadAccessFault) + } + + fn write_access_fault( + &self, + _size: RvSize, + _index: usize, + _val: RvData, + ) -> Result<(), BusError> { + Err(BusError::StoreAccessFault) + } + + // TODO Clear registers + fn zeroize(&mut self) {} + + /// On Write callback for `control` register + /// + /// # Arguments + /// + /// * `size` - Size of the write + /// * `val` - Data to write + /// + /// # Error + /// + /// * `BusError` - Exception with cause `BusError::StoreAccessFault` or `BusError::StoreAddrMisaligned` + pub fn on_write_control(&mut self, size: RvSize, val: RvData) -> Result<(), BusError> { + // Writes have to be Word aligned + if size != RvSize::Word { + Err(BusError::StoreAccessFault)? + } + + // Set the control register + self.control.reg.set(val); + + match self.control.reg.read_as_enum(Control::CTRL) { + Some(Control::CTRL::Value::GEN_KEY) + | Some(Control::CTRL::Value::SIGN) + | Some(Control::CTRL::Value::VERIFY) => { + // Reset the Ready and Valid status bits + self.status + .reg + .modify(Status::READY::CLEAR + Status::VALID::CLEAR); + + self.op_complete_action = Some(self.timer.schedule_poll_in(ML_DSA87_OP_TICKS)); + } + _ => {} + } + + if self.control.reg.is_set(Control::ZEROIZE) { + self.zeroize(); + } + + Ok(()) + } + + fn gen_key(&mut self) { + let seed_bytes = &bytes_from_words_le(&self.seed); + let mut rng = StdRng::from_seed(*seed_bytes); + let (pk, sk) = try_keygen_with_rng(&mut rng).unwrap(); + + self.pk = words_from_bytes_le(&pk.into_bytes()); + self.sk_out = words_from_bytes_le(&sk.into_bytes()); + } + + fn sign(&mut self) { + let seed_bytes = &bytes_from_words_le(&self.seed); + let mut rng = StdRng::from_seed(*seed_bytes); + + let secret_key_bytes = &bytes_from_words_le(&self.sk_in); + let secret_key = PrivateKey::try_from_bytes(*secret_key_bytes).unwrap(); + + let message = &bytes_from_words_le(&self.message); + + // The Ml_Dsa87 signature is 4595 len but the reg is one byte longer + let signature = secret_key.try_sign_with_rng(&mut rng, message).unwrap(); + let signature_extended = { + let mut sig = [0; SIG_LEN + 1]; + sig[..SIG_LEN].copy_from_slice(&signature); + sig + }; + self.signature + .copy_from_slice(&words_from_bytes_le(&signature_extended)); + } + + fn verify(&mut self) { + let message = &bytes_from_words_le(&self.message); + + let public_key = { + let key_bytes = &bytes_from_words_le(&self.pk); + PublicKey::try_from_bytes(*key_bytes).unwrap() + }; + + let signature = &bytes_from_words_le(&self.signature); + + let result = public_key.verify(message, &signature[..SIG_LEN].try_into().unwrap()); + + self.verification_result + .iter_mut() + .for_each(|e| *e = if result { 1 } else { 0 }); + } + + fn op_complete(&mut self) { + match self.control.reg.read_as_enum(Control::CTRL) { + Some(Control::CTRL::Value::GEN_KEY) => self.gen_key(), + Some(Control::CTRL::Value::SIGN) => self.sign(), + Some(Control::CTRL::Value::VERIFY) => self.verify(), + _ => {} + } + + self.status + .reg + .modify(Status::READY::SET + Status::VALID::SET); + } + + /// Called by Bus::poll() to indicate that time has passed + fn poll(&mut self) { + if self.timer.fired(&mut self.op_complete_action) { + self.op_complete(); + } + } + + /// Called by Bus::warm_reset() to indicate a warm reset + fn warm_reset(&mut self) { + // TODO: Reset registers + } + + /// Called by Bus::update_reset() to indicate an update reset + fn update_reset(&mut self) { + // TODO: Reset registers + } +} + +#[cfg(test)] +mod tests { + use caliptra_emu_bus::Bus; + use caliptra_emu_crypto::EndianessTransform; + use caliptra_emu_types::RvAddr; + use tock_registers::registers::InMemoryRegister; + + use super::*; + + const OFFSET_NAME0: RvAddr = 0x0; + const OFFSET_NAME1: RvAddr = 0x4; + const OFFSET_VERSION0: RvAddr = 0x8; + const OFFSET_VERSION1: RvAddr = 0xC; + const OFFSET_CONTROL: RvAddr = 0x10; + const OFFSET_STATUS: RvAddr = 0x18; + const OFFSET_SEED: RvAddr = 0x100; + const OFFSET_SIGN_RND: RvAddr = 0x180; + const OFFSET_MSG: RvAddr = 0x200; + const OFFSET_SK_IN: RvAddr = 0x1620; + const OFFSET_PK: RvAddr = 0x2940; + const OFFSET_SIGNATURE: RvAddr = 0x3400; + + include!("./test_data/ml_dsa87_test_data.rs"); + + const VERIFICATION_SUCCES: [u8; 64] = [ + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 1, + ]; + + fn make_word(idx: usize, arr: &[u8]) -> RvData { + let mut res: RvData = 0; + for i in 0..4 { + res |= (arr[idx + i] as RvData) << (i * 8); + } + res + } + + #[test] + fn test_name() { + let clock = Clock::new(); + + let mut ml_dsa87 = MlDsa87::new(&clock); + + let name0 = ml_dsa87.read(RvSize::Word, OFFSET_NAME0).unwrap(); + let name0 = String::from_utf8_lossy(&name0.to_be_bytes()).to_string(); + assert_eq!(name0, "secp"); + + let name1 = ml_dsa87.read(RvSize::Word, OFFSET_NAME1).unwrap(); + let name1 = String::from_utf8_lossy(&name1.to_be_bytes()).to_string(); + assert_eq!(name1, "-384"); + } + + #[test] + fn test_version() { + let clock = Clock::new(); + + let mut ml_dsa87 = MlDsa87::new(&clock); + + let version0 = ml_dsa87.read(RvSize::Word, OFFSET_VERSION0).unwrap(); + let version0 = String::from_utf8_lossy(&version0.to_le_bytes()).to_string(); + assert_eq!(version0, "1.00"); + + let version1 = ml_dsa87.read(RvSize::Word, OFFSET_VERSION1).unwrap(); + let version1 = String::from_utf8_lossy(&version1.to_le_bytes()).to_string(); + assert_eq!(version1, "\0\0\0\0"); + } + + #[test] + fn test_control() { + let clock = Clock::new(); + + let mut ml_dsa87 = MlDsa87::new(&clock); + assert_eq!(ml_dsa87.read(RvSize::Word, OFFSET_CONTROL).unwrap(), 0); + } + + #[test] + fn test_status() { + let clock = Clock::new(); + + let mut ml_dsa87 = MlDsa87::new(&clock); + assert_eq!(ml_dsa87.read(RvSize::Word, OFFSET_STATUS).unwrap(), 1); + } + + #[test] + fn test_gen_key() { + let clock = Clock::new(); + + let mut ml_dsa87 = MlDsa87::new(&clock); + + let mut seed = [0u8; 32]; + seed.to_big_endian(); // Change DWORDs to big-endian. TODO is this needed? + for i in (0..seed.len()).step_by(4) { + assert_eq!( + ml_dsa87 + .write(RvSize::Word, OFFSET_SEED + i as RvAddr, make_word(i, &seed)) + .ok(), + Some(()) + ); + } + + assert_eq!( + ml_dsa87 + .write(RvSize::Word, OFFSET_CONTROL, Control::CTRL::GEN_KEY.into()) + .ok(), + Some(()) + ); + + loop { + let status = InMemoryRegister::::new( + ml_dsa87.read(RvSize::Word, OFFSET_STATUS).unwrap(), + ); + + if status.is_set(Status::VALID) && status.is_set(Status::READY) { + break; + } + + clock.increment_and_process_timer_actions(1, &mut ml_dsa87); + } + + let mut secret_key = bytes_from_words_le(&ml_dsa87.sk_out); + secret_key.to_little_endian(); // Change DWORDs to little-endian. TODO is this needed? + + let mut public_key = bytes_from_words_le(&ml_dsa87.pk); + public_key.to_little_endian(); // Change DWORDs to little-endian. TODO is this needed? + + assert_eq!(&secret_key, &SECRET_KEY); + assert_eq!(&public_key, &PUB_KEY); + } + + #[test] + fn test_sign() { + let clock = Clock::new(); + + let mut ml_dsa87 = MlDsa87::new(&clock); + + let mut seed = [0u8; 32]; + seed.to_big_endian(); // Change DWORDs to big-endian. TODO is this needed? + for i in (0..seed.len()).step_by(4) { + assert_eq!( + ml_dsa87 + .write(RvSize::Word, OFFSET_SEED + i as RvAddr, make_word(i, &seed)) + .ok(), + Some(()) + ); + } + + let mut msg = [0u8; 64]; + msg.to_big_endian(); // Change DWORDs to big-endian. TODO is this necessary + + for i in (0..msg.len()).step_by(4) { + assert_eq!( + ml_dsa87 + .write(RvSize::Word, OFFSET_MSG + i as RvAddr, make_word(i, &msg)) + .ok(), + Some(()) + ); + } + + let mut secret_key = SECRET_KEY; + secret_key.to_big_endian(); // Change DWORDs to big-endian. + + for i in (0..SECRET_KEY.len()).step_by(4) { + assert_eq!( + ml_dsa87 + .write( + RvSize::Word, + OFFSET_SK_IN + i as RvAddr, + make_word(i, &secret_key) + ) + .ok(), + Some(()) + ); + } + + let mut sign_rnd = SIGN_RND; + sign_rnd.to_big_endian(); // Change DWORDs to big-endian. + + for i in (0..SIGN_RND.len()).step_by(4) { + assert_eq!( + ml_dsa87 + .write( + RvSize::Word, + OFFSET_SIGN_RND + i as RvAddr, + make_word(i, &sign_rnd) + ) + .ok(), + Some(()) + ); + } + + assert_eq!( + ml_dsa87 + .write(RvSize::Word, OFFSET_CONTROL, Control::CTRL::SIGN.into()) + .ok(), + Some(()) + ); + + loop { + let status = InMemoryRegister::::new( + ml_dsa87.read(RvSize::Word, OFFSET_STATUS).unwrap(), + ); + + if status.is_set(Status::VALID) && status.is_set(Status::READY) { + break; + } + + clock.increment_and_process_timer_actions(1, &mut ml_dsa87); + } + + let mut signature = bytes_from_words_le(&ml_dsa87.signature); + signature.to_little_endian(); // Change DWORDs to little-endian. + + assert_eq!(&signature, &SIGNATURE); + } + + #[test] + fn test_verify() { + let clock = Clock::new(); + + let mut ml_dsa87 = MlDsa87::new(&clock); + + let msg = [0u8; 64]; + for i in (0..msg.len()).step_by(4) { + assert_eq!( + ml_dsa87 + .write(RvSize::Word, OFFSET_MSG + i as RvAddr, make_word(i, &msg)) + .ok(), + Some(()) + ); + } + + let mut pub_key = PUB_KEY; + pub_key.to_big_endian(); + + for i in (0..pub_key.len()).step_by(4) { + assert_eq!( + ml_dsa87 + .write( + RvSize::Word, + OFFSET_PK + i as RvAddr, + make_word(i, &pub_key) + ) + .ok(), + Some(()) + ); + } + + // Good signature + let mut signature = SIGNATURE; + signature.to_big_endian(); + + for i in (0..signature.len()).step_by(4) { + assert_eq!( + ml_dsa87 + .write( + RvSize::Word, + OFFSET_SIGNATURE + i as RvAddr, + make_word(i, &signature) + ) + .ok(), + Some(()) + ); + } + + assert_eq!( + ml_dsa87 + .write(RvSize::Word, OFFSET_CONTROL, Control::CTRL::VERIFY.into()) + .ok(), + Some(()) + ); + + loop { + let status = InMemoryRegister::::new( + ml_dsa87.read(RvSize::Word, OFFSET_STATUS).unwrap(), + ); + + if status.is_set(Status::VALID) && status.is_set(Status::READY) { + break; + } + + clock.increment_and_process_timer_actions(1, &mut ml_dsa87); + } + + let mut result = bytes_from_words_le(&ml_dsa87.verification_result); + result.to_little_endian(); + + assert_eq!(&result, &VERIFICATION_SUCCES); + + // Bad signature + let mut signature = [0; SIG_LEN + 1]; + signature.to_big_endian(); + + for i in (0..signature.len()).step_by(4) { + assert_eq!( + ml_dsa87 + .write( + RvSize::Word, + OFFSET_SIGNATURE + i as RvAddr, + make_word(i, &signature) + ) + .ok(), + Some(()) + ); + } + + assert_eq!( + ml_dsa87 + .write(RvSize::Word, OFFSET_CONTROL, Control::CTRL::VERIFY.into()) + .ok(), + Some(()) + ); + + loop { + let status = InMemoryRegister::::new( + ml_dsa87.read(RvSize::Word, OFFSET_STATUS).unwrap(), + ); + + if status.is_set(Status::VALID) && status.is_set(Status::READY) { + break; + } + + clock.increment_and_process_timer_actions(1, &mut ml_dsa87); + } + + let mut result = bytes_from_words_le(&ml_dsa87.verification_result); + result.to_little_endian(); + + assert_eq!(&result, &[0; 64]); + } +} diff --git a/sw-emulator/lib/periph/src/root_bus.rs b/sw-emulator/lib/periph/src/root_bus.rs index 79f53ecff4..41451756de 100644 --- a/sw-emulator/lib/periph/src/root_bus.rs +++ b/sw-emulator/lib/periph/src/root_bus.rs @@ -15,6 +15,7 @@ Abstract: use crate::{ helpers::words_from_bytes_be, iccm::Iccm, + ml_dsa87::MlDsa87, soc_reg::{DebugManufService, SocRegistersExternal}, AsymEcc384, Csrng, Doe, EmuCtrl, HashSha256, HashSha512, HmacSha384, KeyVault, MailboxExternal, MailboxInternal, MailboxRam, Sha512Accelerator, SocRegistersInternal, Uart, @@ -265,6 +266,9 @@ pub struct CaliptraRootBus { #[peripheral(offset = 0x1002_8000, mask = 0x0000_7fff)] pub sha256: HashSha256, + #[peripheral(offset = 0x1003_0000, mask = 0x0000_7fff)] // TODO update when known + pub ml_dsa87: MlDsa87, + #[peripheral(offset = 0x4000_0000, mask = 0x0fff_ffff)] pub iccm: Iccm, @@ -326,6 +330,7 @@ impl CaliptraRootBus { key_vault: key_vault.clone(), sha512, sha256: HashSha256::new(clock), + ml_dsa87: MlDsa87::new(clock), iccm, dccm: Ram::new(vec![0; Self::DCCM_SIZE]), uart: Uart::new(), diff --git a/sw-emulator/lib/periph/src/test_data/ml_dsa87_test_data.rs b/sw-emulator/lib/periph/src/test_data/ml_dsa87_test_data.rs new file mode 100644 index 0000000000..a5ee080fd3 --- /dev/null +++ b/sw-emulator/lib/periph/src/test_data/ml_dsa87_test_data.rs @@ -0,0 +1,631 @@ +/*++ + +Licensed under the Apache-2.0 license. + +File Name: + +ml_dsa87_test_data.rs + +Abstract: + +File contains Ml_Dsa87 test data. + +--*/ + + const PUB_KEY: [u8; PK_LEN] = [ + 101, 203, 95, 47, 119, 228, 185, 195, 137, 161, 111, 222, 147, 5, 29, 43, 244, 210, 131, + 60, 239, 66, 159, 22, 79, 21, 167, 47, 12, 66, 195, 175, 234, 89, 177, 101, 191, 177, 232, + 81, 188, 193, 169, 100, 141, 71, 27, 33, 19, 227, 11, 214, 168, 227, 135, 17, 10, 165, 142, + 236, 10, 94, 251, 44, 194, 123, 226, 47, 149, 147, 78, 79, 200, 48, 197, 1, 247, 124, 174, + 145, 208, 237, 102, 140, 174, 80, 95, 34, 111, 162, 99, 35, 128, 225, 202, 67, 254, 250, + 63, 189, 205, 85, 188, 18, 180, 122, 39, 145, 228, 216, 77, 223, 121, 69, 46, 70, 74, 24, + 179, 26, 116, 5, 237, 14, 58, 146, 245, 176, 165, 123, 126, 249, 182, 13, 246, 199, 177, + 41, 30, 203, 42, 133, 227, 66, 238, 109, 236, 17, 38, 236, 139, 230, 144, 251, 250, 249, + 183, 219, 0, 47, 97, 127, 242, 224, 231, 235, 222, 102, 125, 128, 80, 226, 18, 148, 11, + 187, 108, 240, 224, 6, 116, 35, 24, 124, 71, 244, 250, 66, 172, 198, 91, 63, 35, 60, 85, + 59, 64, 255, 30, 170, 99, 192, 65, 48, 113, 143, 23, 113, 253, 94, 128, 110, 136, 99, 112, + 130, 37, 124, 90, 100, 145, 254, 164, 255, 108, 14, 181, 130, 73, 148, 92, 223, 225, 2, 84, + 123, 38, 112, 173, 76, 7, 177, 194, 98, 241, 233, 3, 92, 3, 131, 242, 58, 160, 76, 141, 74, + 110, 40, 232, 167, 99, 13, 155, 189, 248, 179, 51, 127, 152, 209, 193, 92, 143, 180, 183, + 158, 126, 51, 235, 230, 41, 65, 248, 120, 42, 55, 109, 223, 219, 149, 120, 75, 176, 206, + 67, 17, 174, 114, 122, 93, 78, 255, 141, 223, 5, 169, 105, 242, 233, 159, 208, 177, 208, + 102, 179, 60, 59, 6, 167, 227, 59, 196, 187, 36, 70, 62, 4, 220, 179, 229, 149, 10, 228, + 194, 198, 155, 16, 68, 251, 202, 23, 139, 243, 137, 131, 93, 228, 87, 60, 105, 71, 18, 242, + 114, 58, 192, 193, 212, 94, 3, 20, 34, 124, 169, 174, 85, 149, 228, 18, 112, 48, 19, 11, + 190, 20, 43, 121, 181, 219, 233, 120, 87, 184, 89, 40, 250, 126, 243, 124, 70, 214, 166, + 195, 30, 95, 231, 23, 35, 244, 187, 208, 67, 247, 249, 177, 228, 182, 246, 231, 121, 196, + 64, 86, 8, 164, 249, 142, 16, 212, 18, 179, 5, 173, 25, 238, 7, 31, 206, 253, 164, 84, 86, + 196, 191, 207, 88, 233, 167, 109, 112, 226, 173, 102, 128, 8, 211, 157, 48, 246, 129, 240, + 179, 206, 100, 162, 168, 9, 55, 215, 186, 115, 167, 90, 35, 111, 18, 177, 99, 95, 181, 43, + 218, 7, 27, 182, 62, 239, 248, 251, 30, 243, 65, 220, 172, 26, 186, 160, 46, 27, 103, 92, + 173, 154, 72, 222, 2, 199, 194, 183, 120, 244, 61, 239, 163, 218, 197, 17, 225, 134, 175, + 80, 134, 124, 124, 127, 157, 231, 214, 62, 16, 251, 197, 195, 170, 222, 106, 106, 175, 57, + 142, 148, 131, 62, 146, 85, 215, 209, 148, 22, 132, 244, 242, 116, 193, 0, 68, 208, 57, + 109, 247, 78, 124, 120, 172, 7, 30, 3, 37, 185, 121, 35, 70, 204, 66, 45, 244, 209, 127, + 128, 134, 206, 78, 211, 72, 189, 95, 252, 223, 52, 25, 4, 177, 140, 0, 149, 200, 216, 143, + 141, 89, 209, 140, 21, 57, 202, 167, 194, 133, 199, 248, 143, 91, 144, 153, 159, 64, 163, + 248, 235, 203, 21, 35, 236, 23, 248, 122, 8, 167, 36, 227, 150, 83, 10, 34, 27, 253, 63, + 223, 197, 99, 215, 223, 157, 141, 13, 241, 217, 202, 7, 50, 146, 12, 206, 31, 247, 209, 95, + 222, 195, 145, 116, 164, 173, 55, 13, 94, 215, 214, 143, 59, 29, 150, 181, 121, 234, 122, + 134, 114, 141, 4, 204, 218, 6, 40, 171, 159, 54, 195, 163, 245, 8, 170, 210, 117, 233, 113, + 238, 100, 18, 102, 157, 233, 189, 117, 224, 248, 106, 233, 89, 16, 128, 76, 183, 239, 255, + 105, 177, 10, 109, 179, 221, 139, 185, 168, 50, 110, 211, 154, 76, 243, 235, 95, 92, 150, + 39, 116, 254, 123, 25, 126, 101, 230, 30, 33, 107, 168, 186, 3, 8, 34, 19, 38, 35, 183, + 107, 247, 29, 160, 183, 28, 98, 232, 191, 122, 209, 56, 66, 108, 103, 222, 6, 252, 177, 19, + 226, 11, 162, 76, 90, 137, 49, 169, 73, 111, 244, 12, 123, 254, 247, 25, 202, 137, 133, 78, + 146, 72, 224, 5, 123, 86, 136, 198, 189, 57, 148, 196, 154, 216, 106, 202, 214, 158, 6, 82, + 51, 90, 109, 108, 3, 208, 121, 97, 81, 47, 231, 36, 65, 65, 138, 118, 76, 183, 40, 155, 92, + 55, 12, 23, 43, 195, 252, 39, 64, 102, 165, 235, 82, 22, 16, 28, 27, 156, 175, 237, 25, + 174, 238, 213, 227, 48, 35, 150, 14, 144, 148, 217, 241, 28, 67, 252, 99, 64, 64, 28, 187, + 183, 230, 243, 150, 187, 93, 25, 129, 77, 56, 19, 64, 239, 243, 163, 169, 42, 88, 145, 89, + 179, 137, 73, 219, 225, 188, 50, 39, 47, 160, 74, 205, 191, 186, 157, 196, 223, 122, 135, + 165, 28, 114, 59, 250, 177, 202, 49, 97, 96, 243, 13, 58, 81, 250, 255, 51, 77, 185, 234, + 90, 244, 202, 226, 214, 134, 134, 161, 205, 234, 123, 139, 194, 155, 205, 153, 184, 115, + 198, 118, 51, 135, 127, 232, 182, 8, 114, 69, 40, 133, 127, 148, 25, 55, 47, 69, 124, 101, + 1, 50, 203, 199, 30, 180, 81, 110, 31, 98, 1, 204, 85, 162, 111, 72, 39, 104, 53, 88, 255, + 34, 49, 139, 251, 24, 22, 69, 204, 112, 206, 133, 187, 103, 186, 163, 156, 17, 152, 54, 90, + 15, 138, 86, 39, 222, 92, 91, 191, 70, 250, 181, 57, 143, 191, 144, 37, 15, 62, 194, 176, + 25, 25, 71, 122, 9, 131, 149, 241, 54, 177, 70, 156, 246, 104, 245, 210, 196, 158, 94, 190, + 101, 208, 227, 44, 254, 158, 63, 42, 7, 243, 198, 86, 16, 201, 178, 32, 83, 255, 30, 235, + 231, 164, 196, 174, 150, 68, 59, 21, 160, 126, 173, 208, 75, 16, 156, 223, 225, 135, 125, + 139, 37, 227, 116, 30, 109, 113, 196, 143, 189, 143, 0, 38, 121, 209, 13, 112, 152, 51, + 200, 57, 156, 124, 208, 195, 99, 233, 186, 244, 41, 199, 61, 86, 226, 191, 23, 54, 129, 48, + 136, 204, 214, 188, 184, 203, 69, 230, 241, 131, 123, 251, 36, 101, 99, 152, 22, 156, 109, + 22, 107, 187, 139, 77, 197, 75, 5, 156, 38, 186, 55, 56, 219, 5, 239, 105, 188, 172, 125, + 158, 24, 93, 76, 82, 92, 44, 204, 145, 174, 241, 122, 222, 58, 26, 245, 128, 238, 91, 17, + 46, 70, 95, 231, 79, 214, 131, 68, 143, 148, 23, 74, 30, 31, 24, 192, 33, 162, 113, 233, 7, + 143, 175, 105, 232, 103, 253, 143, 140, 154, 130, 114, 210, 158, 14, 162, 64, 242, 26, 69, + 84, 20, 111, 49, 120, 147, 91, 39, 222, 39, 74, 154, 49, 234, 56, 38, 243, 13, 3, 16, 58, + 117, 102, 39, 123, 42, 242, 111, 3, 81, 118, 37, 25, 158, 76, 172, 48, 14, 254, 228, 137, + 97, 50, 41, 205, 163, 158, 193, 180, 77, 105, 198, 49, 216, 29, 254, 122, 54, 136, 201, 30, + 218, 137, 204, 184, 122, 193, 170, 102, 77, 109, 119, 250, 0, 125, 160, 151, 209, 113, 141, + 166, 195, 133, 68, 94, 106, 145, 184, 92, 40, 128, 177, 189, 113, 56, 32, 65, 122, 46, 37, + 142, 70, 226, 169, 58, 135, 237, 162, 159, 177, 102, 167, 21, 148, 8, 213, 78, 114, 206, + 189, 156, 180, 54, 17, 180, 67, 217, 250, 57, 199, 123, 173, 59, 89, 83, 88, 205, 148, 92, + 50, 128, 39, 87, 193, 85, 151, 183, 136, 125, 68, 148, 227, 51, 33, 159, 123, 23, 153, 54, + 14, 255, 74, 87, 90, 219, 137, 18, 235, 119, 49, 122, 213, 123, 119, 18, 161, 19, 167, 211, + 121, 172, 15, 96, 238, 200, 66, 102, 135, 147, 9, 186, 150, 24, 106, 243, 179, 98, 71, 74, + 119, 147, 46, 189, 199, 182, 168, 191, 222, 89, 2, 14, 13, 200, 168, 69, 19, 62, 117, 67, + 66, 33, 216, 236, 89, 128, 154, 246, 77, 147, 128, 84, 217, 178, 236, 241, 91, 236, 159, + 185, 4, 246, 145, 45, 76, 6, 110, 228, 102, 223, 155, 133, 213, 205, 77, 101, 45, 74, 227, + 94, 205, 27, 210, 215, 102, 83, 109, 245, 132, 29, 11, 212, 56, 1, 35, 222, 108, 17, 32, + 98, 157, 51, 124, 168, 221, 140, 230, 106, 57, 120, 16, 231, 170, 111, 235, 247, 146, 118, + 191, 0, 253, 44, 62, 94, 183, 3, 122, 162, 165, 51, 19, 57, 16, 246, 201, 64, 174, 200, 57, + 164, 101, 131, 65, 41, 159, 119, 134, 174, 38, 137, 151, 109, 134, 69, 170, 89, 97, 7, 219, + 54, 55, 232, 120, 129, 58, 127, 120, 112, 211, 206, 221, 120, 252, 123, 30, 171, 172, 212, + 227, 84, 240, 106, 30, 225, 142, 113, 227, 42, 140, 42, 172, 41, 239, 50, 142, 199, 216, + 222, 122, 210, 114, 121, 170, 56, 0, 248, 93, 80, 9, 218, 222, 124, 30, 155, 215, 41, 167, + 8, 65, 197, 64, 120, 171, 134, 8, 237, 189, 154, 164, 251, 90, 55, 83, 235, 240, 234, 63, + 249, 82, 115, 89, 141, 139, 138, 198, 177, 129, 154, 123, 75, 201, 180, 104, 186, 251, 222, + 16, 197, 149, 51, 168, 224, 140, 87, 103, 61, 229, 114, 40, 176, 198, 253, 57, 66, 123, + 205, 188, 36, 73, 72, 154, 144, 87, 50, 31, 105, 13, 218, 83, 122, 15, 158, 86, 48, 56, + 152, 150, 6, 231, 53, 171, 236, 176, 32, 191, 96, 223, 226, 59, 150, 40, 6, 79, 75, 140, + 175, 8, 55, 119, 233, 92, 62, 194, 57, 48, 198, 239, 15, 176, 80, 38, 22, 114, 201, 88, + 103, 186, 24, 78, 100, 86, 169, 48, 42, 126, 176, 251, 6, 5, 43, 255, 165, 50, 217, 11, + 208, 239, 215, 175, 163, 71, 81, 89, 236, 122, 189, 30, 168, 248, 232, 217, 9, 127, 7, 25, + 3, 194, 54, 24, 186, 113, 19, 111, 67, 22, 97, 161, 90, 121, 177, 31, 232, 208, 27, 231, + 245, 246, 88, 202, 186, 89, 58, 101, 22, 118, 115, 131, 105, 201, 90, 131, 30, 223, 71, 51, + 248, 103, 133, 80, 185, 55, 209, 203, 118, 52, 62, 19, 209, 136, 97, 158, 87, 198, 104, + 254, 114, 239, 21, 80, 6, 147, 213, 76, 105, 61, 20, 250, 153, 32, 32, 45, 234, 232, 4, + 234, 194, 113, 1, 92, 206, 39, 44, 113, 203, 22, 210, 159, 86, 144, 79, 6, 114, 236, 172, + 77, 36, 33, 164, 136, 99, 146, 106, 194, 12, 10, 244, 36, 123, 144, 232, 67, 204, 201, 70, + 22, 251, 183, 35, 63, 36, 84, 211, 197, 200, 187, 32, 89, 175, 84, 19, 47, 244, 230, 47, + 136, 183, 41, 184, 109, 217, 213, 93, 147, 191, 251, 245, 75, 88, 23, 190, 47, 42, 38, 216, + 44, 214, 224, 239, 16, 245, 194, 4, 40, 61, 253, 144, 109, 230, 2, 236, 60, 193, 102, 177, + 79, 212, 205, 198, 188, 244, 10, 108, 146, 76, 110, 76, 87, 20, 38, 4, 227, 247, 163, 238, + 59, 94, 170, 156, 179, 235, 171, 73, 158, 255, 56, 50, 7, 139, 111, 228, 59, 112, 206, 220, + 111, 49, 254, 144, 193, 251, 97, 13, 181, 194, 244, 124, 55, 216, 61, 24, 15, 100, 198, 29, + 217, 104, 20, 215, 91, 238, 101, 21, 224, 129, 236, 23, 206, 179, 171, 136, 31, 239, 22, + 82, 103, 156, 137, 132, 49, 70, 8, 137, 232, 243, 209, 142, 238, 73, 22, 138, 161, 250, 59, + 240, 158, 183, 238, 68, 38, 161, 145, 106, 175, 159, 167, 225, 128, 55, 133, 81, 211, 29, + 136, 97, 252, 184, 73, 104, 213, 251, 37, 248, 13, 253, 213, 163, 135, 209, 135, 25, 85, + 131, 76, 203, 46, 10, 25, 67, 149, 63, 66, 46, 246, 22, 214, 49, 12, 1, 118, 71, 230, 241, + 59, 250, 197, 67, 191, 158, 185, 23, 208, 166, 248, 159, 244, 178, 88, 56, 190, 218, 184, + 252, 206, 137, 87, 160, 249, 250, 184, 154, 83, 163, 160, 107, 69, 245, 71, 151, 242, 136, + 77, 3, 223, 201, 176, 212, 69, 186, 248, 140, 107, 128, 85, 88, 77, 132, 92, 209, 255, 5, + 203, 6, 100, 208, 127, 198, 124, 192, 194, 200, 81, 153, 175, 192, 209, 187, 196, 22, 64, + 144, 220, 141, 17, 21, 190, 241, 72, 8, 139, 107, 36, 207, 142, 218, 81, 126, 122, 185, 51, + 82, 32, 221, 246, 131, 255, 179, 122, 51, 6, 202, 212, 135, 154, 150, 67, 30, 33, 224, 255, + 70, 202, 126, 151, 36, 157, 241, 185, 103, 208, 201, 135, 26, 23, 33, 163, 230, 244, 8, 69, + 82, 92, 109, 28, 121, 236, 92, 46, 38, 23, 5, 53, 180, 204, 244, 166, 17, 63, 72, 89, 229, + 176, 10, 118, 211, 236, 81, 126, 216, 138, 47, 80, 147, 226, 132, 235, 233, 239, 186, 208, + 57, 90, 166, 45, 20, 121, 205, 87, 206, 251, 2, 101, 151, 183, 31, 124, 131, 187, 209, 92, + 213, 37, 75, 200, 163, 54, 231, 5, 46, 223, 212, 4, 4, 238, 160, 196, 53, 236, 13, 0, 29, + 125, 162, 246, 71, 255, 97, 111, 80, 253, 1, 41, 70, 169, 17, 34, 162, 25, 148, 177, 184, + 94, 50, 63, 232, 5, 217, 246, 221, 115, 238, 126, 65, 20, 42, 203, 131, 53, 172, 215, 36, + 238, 2, 82, 233, 50, 57, 23, 72, 79, 178, 78, 204, 37, 28, 53, 138, 245, 67, 72, 151, 231, + 7, 9, 118, 125, 221, 94, 186, 12, 169, 208, 219, 160, 101, 223, 176, 125, 2, 254, 124, 41, + 237, 128, 30, 98, 12, 142, 155, 250, 138, 11, 2, 13, 120, 62, 169, 232, 205, 169, 172, 125, + 41, 15, 93, 68, 220, 125, 189, 125, 236, 136, 96, 203, 50, 232, 193, 31, 59, 213, 250, 200, + 172, 213, 70, 38, 144, 39, 92, 89, 146, 12, 149, 126, 238, 80, 4, 22, 177, 121, 147, 25, + 52, 117, 58, 50, 203, 11, 98, 105, 185, 129, 215, 81, 165, 113, 26, 160, 144, 123, 57, 215, + 18, 136, 164, 28, 10, 211, 57, 116, 102, 227, 230, 126, 30, 136, 156, 30, 215, 138, 102, + 246, 113, 209, 156, 30, 31, 73, 238, 206, 82, 96, 131, 190, 121, 182, 173, 114, 174, 197, + 237, 220, 56, 99, 203, 164, 73, 2, 125, 10, 116, 162, 68, 134, 59, 169, 250, 216, 234, 215, + 88, 67, 223, 109, 76, 147, 247, 250, 178, 225, 68, 146, 47, 182, 181, 94, 199, 145, 78, + 145, 129, 54, 224, 229, 48, 207, 61, 247, 30, 186, 113, 180, 79, 138, 37, 216, 163, 113, + 179, 95, 216, 26, 134, 235, + ]; + const SECRET_KEY: [u8; SK_LEN] = [ + 101, 203, 95, 47, 119, 228, 185, 195, 137, 161, 111, 222, 147, 5, 29, 43, 244, 210, 131, + 60, 239, 66, 159, 22, 79, 21, 167, 47, 12, 66, 195, 175, 185, 166, 2, 217, 191, 70, 35, + 151, 225, 131, 139, 13, 139, 3, 99, 142, 199, 128, 182, 184, 67, 33, 214, 118, 154, 38, 31, + 14, 194, 195, 188, 202, 155, 131, 32, 199, 26, 182, 162, 56, 133, 17, 128, 27, 110, 240, + 222, 189, 250, 41, 87, 97, 25, 113, 210, 216, 155, 69, 253, 154, 106, 144, 187, 236, 36, + 178, 92, 111, 121, 196, 178, 155, 197, 104, 15, 24, 160, 172, 56, 47, 135, 141, 147, 242, + 178, 160, 133, 146, 165, 153, 61, 38, 56, 95, 139, 222, 162, 97, 135, 20, 34, 200, 112, + 182, 34, 64, 160, 145, 24, 16, 1, 26, 19, 17, 113, 134, 66, 32, 203, 72, 164, 34, 54, 88, + 4, 136, 16, 38, 109, 38, 25, 70, 139, 102, 6, 196, 131, 25, 14, 36, 49, 49, 2, 96, 100, + 140, 21, 0, 73, 19, 66, 52, 80, 52, 162, 68, 147, 97, 132, 132, 2, 18, 97, 196, 6, 39, 17, + 137, 1, 134, 72, 148, 38, 204, 73, 178, 97, 137, 18, 145, 24, 101, 177, 12, 176, 28, 9, 1, + 112, 55, 34, 36, 201, 45, 6, 26, 32, 145, 110, 8, 32, 20, 209, 130, 202, 69, 182, 208, 17, + 34, 4, 152, 4, 16, 18, 18, 3, 5, 36, 155, 4, 98, 76, 177, 69, 168, 84, 16, 136, 113, 34, + 193, 6, 203, 10, 32, 70, 50, 17, 81, 100, 46, 56, 164, 38, 91, 36, 166, 65, 72, 130, 44, + 137, 146, 34, 35, 130, 132, 36, 200, 50, 34, 155, 108, 20, 37, 194, 26, 39, 4, 5, 6, 68, + 23, 19, 66, 67, 144, 8, 66, 165, 27, 5, 196, 0, 18, 73, 4, 18, 109, 200, 138, 65, 33, 64, + 196, 17, 181, 20, 137, 81, 14, 68, 154, 183, 34, 141, 8, 96, 200, 3, 72, 35, 9, 162, 224, + 198, 211, 13, 68, 1, 200, 97, 128, 35, 49, 194, 154, 54, 11, 97, 48, 32, 192, 4, 44, 25, + 105, 53, 11, 38, 203, 42, 6, 105, 21, 27, 18, 144, 137, 32, 210, 54, 209, 105, 4, 133, 52, + 27, 4, 36, 81, 16, 192, 48, 90, 98, 17, 70, 19, 24, 78, 11, 64, 18, 32, 32, 200, 145, 181, + 144, 70, 11, 33, 144, 0, 145, 25, 162, 96, 136, 8, 41, 130, 74, 97, 19, 12, 144, 90, 70, + 100, 70, 72, 76, 168, 209, 14, 28, 142, 72, 203, 162, 129, 68, 68, 97, 36, 3, 128, 32, 113, + 69, 2, 68, 84, 16, 4, 72, 0, 65, 5, 97, 12, 38, 156, 8, 36, 141, 0, 112, 162, 162, 100, + 225, 81, 48, 162, 50, 194, 48, 192, 8, 8, 12, 45, 195, 40, 16, 224, 160, 128, 48, 32, 72, + 68, 154, 44, 9, 76, 8, 64, 67, 17, 36, 195, 110, 32, 196, 132, 0, 36, 192, 212, 193, 35, + 49, 4, 41, 137, 16, 45, 24, 101, 68, 153, 192, 139, 33, 148, 49, 4, 27, 113, 83, 96, 164, + 64, 69, 26, 68, 152, 137, 199, 26, 141, 20, 16, 192, 19, 200, 11, 16, 194, 36, 1, 27, 105, + 17, 141, 2, 203, 19, 18, 129, 176, 44, 148, 163, 80, 80, 65, 129, 18, 20, 81, 44, 52, 12, + 128, 72, 76, 27, 105, 54, 10, 128, 65, 76, 24, 129, 33, 3, 112, 218, 132, 4, 100, 7, 26, + 48, 130, 13, 162, 128, 140, 11, 145, 0, 162, 32, 216, 9, 65, 44, 164, 64, 78, 194, 49, 200, + 19, 6, 16, 145, 152, 44, 65, 19, 146, 68, 137, 6, 154, 73, 33, 102, 72, 10, 72, 32, 37, 1, + 8, 135, 35, 184, 16, 36, 20, 73, 64, 148, 145, 196, 128, 149, 24, 160, 204, 81, 194, 18, + 16, 192, 97, 19, 81, 144, 89, 6, 202, 137, 162, 13, 136, 210, 97, 136, 133, 18, 1, 68, 129, + 12, 162, 9, 8, 100, 42, 68, 18, 34, 203, 70, 153, 129, 128, 104, 176, 83, 144, 25, 68, 32, + 195, 48, 218, 100, 133, 137, 25, 8, 104, 228, 12, 73, 24, 4, 216, 98, 56, 10, 9, 35, 145, + 68, 41, 134, 20, 22, 146, 77, 36, 132, 72, 66, 8, 148, 105, 34, 66, 4, 210, 78, 52, 9, 70, + 8, 104, 35, 6, 66, 100, 162, 80, 4, 50, 77, 200, 218, 0, 25, 33, 48, 17, 39, 28, 45, 71, + 104, 48, 27, 77, 19, 104, 0, 156, 68, 211, 40, 39, 82, 48, 72, 73, 18, 105, 70, 164, 54, + 161, 133, 153, 4, 164, 136, 16, 80, 69, 129, 11, 136, 203, 12, 160, 40, 41, 18, 140, 152, + 36, 177, 24, 24, 201, 77, 168, 142, 24, 129, 0, 17, 45, 5, 36, 22, 216, 49, 147, 78, 40, + 19, 78, 201, 73, 146, 193, 160, 90, 98, 34, 129, 5, 33, 144, 16, 45, 162, 192, 2, 2, 4, 56, + 1, 52, 67, 129, 152, 145, 6, 88, 136, 140, 128, 200, 129, 9, 18, 1, 209, 41, 200, 194, 1, + 12, 5, 72, 34, 72, 8, 49, 1, 133, 182, 148, 64, 227, 9, 54, 113, 160, 219, 69, 10, 48, 182, + 193, 50, 74, 0, 198, 40, 192, 218, 45, 156, 38, 25, 12, 178, 28, 134, 56, 142, 2, 91, 137, + 28, 105, 69, 4, 23, 17, 112, 56, 104, 8, 136, 133, 27, 33, 68, 68, 36, 33, 18, 19, 81, 68, + 225, 145, 17, 16, 180, 92, 70, 130, 33, 196, 144, 192, 156, 41, 8, 78, 50, 18, 168, 26, 32, + 40, 146, 72, 16, 128, 3, 2, 38, 35, 144, 211, 76, 137, 145, 168, 4, 81, 73, 32, 57, 26, 18, + 162, 113, 6, 145, 20, 90, 113, 25, 37, 194, 156, 32, 216, 97, 51, 138, 25, 3, 46, 92, 96, + 6, 228, 197, 3, 136, 200, 48, 198, 18, 1, 139, 141, 50, 27, 22, 16, 77, 8, 102, 56, 2, 104, + 156, 129, 180, 33, 152, 66, 14, 34, 113, 128, 145, 16, 35, 136, 70, 27, 128, 131, 140, 130, + 74, 68, 225, 33, 90, 98, 66, 8, 52, 162, 12, 32, 5, 160, 152, 10, 1, 109, 34, 220, 167, 20, + 64, 33, 65, 22, 18, 44, 76, 64, 4, 19, 7, 1, 6, 34, 69, 2, 36, 96, 26, 72, 176, 145, 0, + 128, 4, 129, 17, 193, 24, 8, 154, 136, 52, 225, 128, 82, 0, 16, 104, 160, 228, 9, 209, 41, + 34, 4, 182, 98, 69, 48, 100, 7, 3, 72, 25, 114, 18, 11, 192, 3, 38, 33, 96, 164, 129, 113, + 144, 66, 0, 81, 52, 76, 77, 52, 110, 20, 200, 72, 4, 16, 180, 27, 152, 74, 46, 8, 50, 21, + 34, 81, 4, 9, 196, 161, 166, 144, 0, 199, 100, 0, 84, 105, 24, 13, 164, 24, 73, 4, 69, 185, + 17, 132, 194, 34, 33, 108, 48, 137, 24, 161, 97, 53, 40, 34, 12, 140, 11, 2, 72, 132, 147, + 34, 108, 23, 141, 181, 24, 140, 66, 42, 54, 16, 4, 161, 114, 18, 137, 196, 80, 2, 147, 74, + 40, 35, 38, 92, 141, 194, 46, 56, 80, 129, 0, 13, 136, 66, 6, 139, 114, 23, 80, 178, 82, + 46, 145, 14, 0, 64, 56, 208, 4, 38, 100, 22, 84, 44, 200, 144, 2, 144, 4, 66, 44, 16, 104, + 168, 88, 106, 1, 101, 144, 145, 134, 8, 108, 20, 9, 65, 2, 137, 33, 36, 196, 161, 24, 208, + 104, 184, 132, 2, 97, 109, 147, 100, 4, 64, 201, 10, 33, 152, 70, 24, 99, 13, 3, 72, 24, + 145, 162, 144, 72, 64, 136, 160, 193, 37, 202, 114, 72, 203, 181, 1, 113, 34, 136, 9, 26, + 101, 225, 69, 57, 11, 152, 11, 138, 32, 140, 182, 25, 73, 0, 138, 65, 32, 198, 204, 113, + 199, 146, 57, 34, 128, 91, 40, 20, 27, 40, 16, 64, 32, 132, 55, 26, 108, 11, 41, 180, 219, + 73, 10, 33, 22, 138, 4, 33, 104, 154, 73, 52, 193, 18, 0, 98, 34, 81, 70, 4, 68, 73, 0, 32, + 10, 130, 216, 110, 52, 104, 145, 20, 76, 16, 132, 52, 83, 130, 196, 33, 176, 73, 67, 27, 8, + 0, 141, 192, 204, 184, 156, 109, 54, 98, 32, 74, 113, 96, 128, 194, 90, 56, 81, 113, 198, + 36, 200, 65, 5, 16, 34, 50, 28, 200, 18, 69, 22, 69, 133, 20, 109, 160, 142, 48, 2, 136, + 194, 140, 20, 145, 162, 194, 100, 164, 9, 176, 129, 71, 25, 45, 16, 108, 164, 220, 50, 1, + 14, 34, 154, 177, 20, 48, 50, 132, 6, 163, 108, 10, 45, 195, 2, 50, 4, 80, 153, 42, 4, 228, + 76, 209, 1, 177, 12, 20, 36, 129, 144, 17, 168, 147, 8, 220, 17, 128, 1, 17, 2, 110, 40, 4, + 37, 28, 130, 24, 2, 50, 98, 50, 160, 98, 4, 76, 184, 76, 34, 148, 5, 199, 32, 144, 35, 106, + 6, 109, 54, 4, 48, 36, 64, 179, 1, 179, 19, 1, 183, 40, 64, 129, 105, 211, 10, 36, 208, 24, + 100, 48, 36, 70, 4, 20, 73, 109, 86, 139, 111, 77, 37, 199, 218, 230, 7, 43, 121, 56, 61, + 209, 137, 90, 166, 220, 43, 177, 31, 89, 235, 104, 74, 201, 209, 57, 183, 55, 173, 234, + 208, 215, 239, 232, 166, 16, 126, 179, 119, 52, 224, 41, 216, 108, 30, 80, 75, 56, 209, 12, + 135, 74, 230, 20, 224, 213, 37, 197, 33, 7, 235, 169, 175, 109, 75, 92, 165, 85, 90, 40, + 184, 197, 212, 32, 81, 5, 20, 42, 200, 207, 101, 44, 103, 49, 4, 183, 132, 155, 95, 83, + 175, 61, 175, 150, 204, 229, 80, 149, 182, 76, 97, 193, 232, 4, 221, 38, 246, 225, 86, 198, + 128, 226, 175, 74, 133, 231, 162, 150, 142, 236, 238, 19, 96, 250, 78, 63, 134, 119, 228, + 87, 125, 159, 180, 88, 150, 233, 18, 132, 195, 113, 31, 67, 241, 205, 159, 232, 255, 37, + 80, 0, 214, 221, 210, 58, 167, 37, 33, 103, 41, 140, 88, 189, 206, 113, 124, 165, 211, 222, + 153, 134, 29, 207, 95, 218, 59, 214, 81, 67, 138, 127, 229, 172, 113, 245, 249, 213, 102, + 231, 14, 24, 88, 147, 186, 234, 149, 129, 223, 13, 180, 153, 61, 166, 79, 241, 103, 190, + 222, 174, 34, 195, 209, 166, 199, 108, 94, 99, 60, 41, 208, 207, 145, 191, 90, 24, 174, 12, + 211, 51, 179, 98, 246, 191, 74, 9, 10, 51, 80, 133, 77, 247, 189, 242, 253, 194, 181, 219, + 141, 71, 34, 67, 45, 116, 190, 33, 22, 73, 104, 52, 62, 8, 141, 100, 210, 68, 142, 149, 19, + 26, 201, 117, 170, 14, 110, 145, 217, 229, 54, 84, 117, 23, 253, 87, 157, 203, 51, 138, 4, + 89, 210, 198, 241, 97, 115, 127, 68, 168, 144, 130, 129, 110, 216, 13, 154, 83, 40, 227, + 121, 92, 75, 74, 189, 208, 124, 3, 50, 235, 208, 231, 72, 173, 139, 29, 90, 61, 181, 162, + 74, 15, 54, 118, 167, 51, 18, 35, 214, 94, 19, 178, 149, 19, 23, 78, 234, 37, 61, 58, 183, + 216, 205, 106, 50, 108, 79, 25, 25, 132, 232, 181, 120, 131, 34, 143, 169, 55, 73, 92, 235, + 33, 73, 238, 74, 119, 88, 215, 133, 59, 209, 137, 72, 133, 39, 88, 252, 165, 56, 103, 17, + 9, 40, 125, 217, 253, 88, 197, 218, 18, 234, 64, 231, 32, 169, 1, 143, 13, 232, 83, 111, + 223, 205, 227, 116, 175, 199, 218, 118, 229, 148, 215, 174, 109, 169, 35, 114, 138, 181, + 146, 60, 159, 24, 174, 247, 33, 242, 1, 115, 42, 238, 155, 90, 144, 161, 93, 12, 25, 86, + 127, 83, 96, 194, 178, 135, 34, 176, 130, 195, 130, 10, 151, 138, 188, 118, 62, 238, 34, + 44, 197, 17, 145, 79, 221, 83, 242, 47, 167, 55, 176, 153, 173, 31, 39, 15, 35, 249, 97, + 210, 220, 140, 222, 211, 160, 220, 192, 209, 27, 190, 195, 30, 49, 247, 112, 251, 95, 28, + 230, 61, 90, 27, 166, 87, 59, 29, 25, 115, 179, 34, 86, 145, 86, 46, 211, 60, 227, 31, 111, + 198, 213, 15, 219, 58, 141, 88, 198, 91, 78, 2, 60, 206, 134, 21, 149, 166, 93, 43, 115, + 29, 46, 156, 241, 117, 231, 122, 73, 135, 73, 247, 73, 80, 76, 164, 58, 159, 79, 0, 189, + 73, 230, 59, 171, 120, 88, 131, 75, 29, 100, 152, 174, 197, 213, 147, 17, 166, 23, 156, 31, + 158, 13, 6, 177, 16, 233, 220, 56, 128, 172, 178, 140, 178, 47, 82, 220, 210, 92, 195, 247, + 66, 248, 125, 145, 225, 32, 149, 86, 146, 162, 51, 171, 29, 251, 39, 154, 37, 246, 8, 116, + 247, 148, 79, 226, 148, 67, 9, 40, 80, 94, 135, 38, 66, 132, 161, 146, 190, 247, 163, 93, + 162, 60, 224, 74, 27, 125, 61, 0, 147, 8, 99, 172, 155, 197, 62, 94, 6, 222, 125, 194, 135, + 244, 94, 13, 236, 171, 235, 2, 117, 81, 121, 114, 51, 24, 102, 9, 52, 84, 178, 65, 210, 69, + 118, 26, 242, 231, 189, 76, 149, 243, 186, 178, 6, 188, 56, 254, 243, 19, 157, 3, 234, 97, + 38, 121, 50, 32, 222, 134, 31, 62, 251, 200, 176, 158, 68, 231, 238, 205, 199, 109, 128, + 179, 170, 16, 3, 11, 195, 175, 199, 65, 41, 233, 68, 146, 59, 99, 73, 45, 108, 86, 121, 2, + 157, 108, 29, 101, 193, 175, 242, 68, 157, 53, 51, 137, 97, 253, 77, 151, 204, 126, 150, + 187, 104, 167, 81, 160, 87, 211, 172, 254, 159, 168, 52, 196, 10, 55, 35, 182, 30, 48, 11, + 230, 0, 40, 191, 129, 168, 205, 126, 29, 217, 90, 60, 194, 211, 165, 222, 185, 30, 74, 191, + 43, 230, 126, 220, 125, 37, 112, 10, 223, 111, 235, 46, 156, 42, 182, 105, 43, 202, 107, + 172, 39, 171, 217, 87, 163, 233, 154, 81, 75, 230, 7, 26, 68, 190, 186, 13, 238, 107, 212, + 63, 202, 64, 43, 45, 140, 26, 134, 191, 35, 9, 80, 178, 150, 202, 181, 98, 101, 127, 219, + 89, 147, 103, 111, 37, 58, 240, 119, 202, 213, 241, 255, 196, 67, 65, 214, 136, 36, 151, + 114, 183, 37, 70, 218, 43, 128, 105, 113, 57, 71, 57, 225, 142, 221, 59, 41, 42, 251, 227, + 198, 180, 217, 127, 15, 154, 162, 97, 187, 116, 225, 113, 249, 208, 6, 135, 115, 233, 135, + 211, 30, 66, 72, 184, 97, 185, 131, 62, 101, 254, 127, 100, 95, 165, 64, 113, 181, 2, 75, + 83, 184, 229, 150, 128, 30, 215, 195, 212, 100, 171, 245, 107, 208, 195, 10, 18, 215, 19, + 130, 23, 109, 192, 197, 38, 162, 223, 252, 91, 86, 137, 92, 98, 214, 109, 209, 71, 225, + 159, 188, 112, 172, 42, 47, 123, 184, 120, 5, 197, 1, 119, 175, 158, 205, 181, 87, 253, + 142, 125, 129, 52, 117, 9, 213, 138, 130, 49, 168, 15, 0, 128, 72, 101, 32, 117, 153, 151, + 21, 215, 33, 157, 80, 66, 102, 237, 78, 224, 160, 63, 178, 149, 76, 59, 197, 49, 228, 227, + 238, 112, 182, 58, 241, 28, 220, 34, 234, 156, 87, 86, 20, 85, 130, 209, 154, 76, 227, 141, + 124, 194, 15, 241, 57, 131, 240, 98, 86, 168, 139, 164, 0, 241, 239, 65, 76, 118, 95, 166, + 47, 159, 205, 35, 99, 248, 103, 57, 229, 0, 114, 200, 104, 138, 49, 59, 88, 25, 41, 158, + 59, 81, 24, 130, 188, 165, 60, 138, 93, 111, 13, 86, 252, 23, 19, 71, 69, 23, 77, 215, 113, + 237, 147, 190, 48, 215, 10, 86, 36, 49, 15, 32, 18, 239, 134, 21, 248, 112, 105, 248, 180, + 126, 68, 133, 24, 134, 39, 152, 140, 94, 170, 103, 15, 7, 10, 73, 117, 116, 204, 83, 229, + 64, 87, 142, 49, 236, 237, 27, 56, 17, 189, 106, 183, 63, 155, 84, 149, 163, 123, 252, 226, + 251, 136, 254, 68, 119, 128, 241, 239, 226, 54, 250, 14, 31, 97, 113, 70, 121, 197, 200, + 108, 93, 97, 85, 122, 19, 65, 99, 185, 123, 203, 7, 252, 105, 116, 109, 57, 22, 163, 227, + 107, 166, 42, 230, 186, 112, 34, 227, 85, 165, 38, 238, 45, 216, 105, 12, 98, 138, 70, 67, + 23, 155, 152, 181, 104, 255, 31, 91, 64, 198, 238, 179, 181, 141, 34, 15, 117, 156, 133, + 212, 71, 253, 249, 137, 254, 28, 150, 110, 186, 229, 120, 114, 237, 247, 133, 56, 127, 163, + 115, 228, 33, 183, 39, 203, 208, 230, 53, 213, 160, 108, 132, 203, 77, 70, 77, 127, 71, + 248, 29, 167, 3, 112, 157, 204, 158, 29, 224, 86, 52, 62, 156, 114, 220, 75, 35, 17, 26, + 43, 93, 112, 72, 14, 228, 54, 181, 149, 230, 168, 89, 8, 44, 161, 114, 63, 53, 203, 111, + 21, 106, 15, 67, 146, 145, 0, 85, 232, 149, 234, 87, 244, 250, 127, 110, 155, 95, 86, 220, + 252, 44, 233, 149, 47, 79, 102, 252, 19, 230, 144, 98, 100, 30, 112, 171, 21, 173, 228, + 116, 175, 76, 120, 107, 27, 98, 95, 252, 76, 63, 31, 32, 225, 110, 44, 198, 61, 190, 100, + 16, 43, 0, 19, 42, 42, 236, 110, 247, 123, 184, 94, 48, 16, 135, 48, 179, 233, 252, 58, 42, + 7, 194, 79, 109, 108, 62, 94, 85, 177, 184, 86, 195, 107, 236, 171, 150, 48, 42, 245, 88, + 114, 244, 199, 95, 71, 115, 140, 135, 37, 96, 206, 214, 70, 22, 195, 105, 208, 29, 84, 203, + 113, 97, 142, 110, 59, 183, 164, 91, 108, 98, 202, 226, 241, 13, 82, 202, 108, 242, 38, 31, + 55, 112, 85, 56, 215, 91, 150, 52, 203, 75, 6, 112, 38, 170, 211, 10, 96, 245, 29, 176, + 226, 23, 8, 15, 194, 124, 135, 119, 176, 246, 57, 135, 155, 106, 120, 235, 113, 144, 249, + 2, 30, 197, 188, 77, 131, 61, 250, 23, 60, 41, 158, 103, 40, 31, 166, 42, 251, 52, 11, 246, + 249, 175, 188, 2, 65, 146, 125, 187, 242, 148, 114, 129, 170, 149, 113, 212, 251, 24, 129, + 253, 59, 188, 110, 73, 36, 27, 51, 168, 4, 66, 6, 106, 61, 36, 90, 170, 112, 165, 61, 109, + 214, 144, 169, 147, 49, 213, 248, 8, 180, 206, 74, 91, 162, 159, 217, 115, 185, 85, 157, 9, + 101, 135, 241, 217, 127, 135, 116, 225, 164, 117, 131, 251, 232, 150, 82, 23, 150, 12, 142, + 196, 218, 214, 205, 55, 126, 180, 13, 186, 146, 48, 34, 186, 97, 106, 40, 63, 96, 137, 251, + 227, 231, 107, 132, 149, 223, 248, 178, 85, 47, 17, 155, 143, 60, 50, 34, 212, 153, 208, + 125, 129, 223, 216, 8, 200, 71, 35, 118, 228, 248, 234, 242, 33, 94, 152, 64, 84, 151, 141, + 229, 22, 78, 102, 56, 129, 198, 145, 208, 135, 42, 164, 32, 27, 162, 179, 170, 247, 185, + 122, 42, 93, 109, 20, 81, 220, 32, 254, 83, 253, 170, 236, 28, 239, 129, 106, 233, 255, + 192, 53, 209, 251, 143, 156, 4, 129, 180, 242, 146, 171, 204, 13, 65, 107, 172, 82, 165, + 192, 250, 23, 93, 106, 77, 164, 199, 15, 246, 63, 196, 158, 159, 20, 80, 205, 101, 97, 75, + 185, 100, 75, 237, 252, 217, 8, 172, 97, 54, 32, 160, 27, 35, 225, 64, 68, 150, 206, 253, + 177, 249, 47, 146, 161, 142, 85, 140, 181, 12, 198, 74, 213, 210, 90, 41, 225, 185, 79, 87, + 1, 30, 174, 207, 237, 16, 195, 67, 31, 156, 171, 97, 72, 191, 218, 63, 181, 227, 242, 130, + 132, 149, 36, 146, 3, 124, 31, 101, 219, 37, 228, 15, 39, 229, 153, 85, 22, 178, 238, 69, + 178, 78, 129, 108, 226, 187, 17, 97, 124, 93, 158, 4, 132, 62, 26, 250, 50, 227, 232, 213, + 55, 12, 236, 87, 165, 194, 143, 14, 21, 176, 157, 97, 54, 50, 242, 123, 16, 59, 132, 1, + 208, 236, 191, 201, 200, 2, 160, 118, 195, 74, 21, 149, 120, 168, 59, 236, 192, 110, 254, + 234, 167, 77, 51, 234, 182, 135, 254, 3, 183, 21, 4, 18, 31, 176, 208, 167, 76, 92, 108, + 174, 235, 171, 167, 137, 190, 245, 45, 12, 88, 68, 39, 238, 98, 12, 162, 61, 42, 217, 94, + 143, 213, 237, 244, 210, 79, 175, 197, 114, 132, 12, 203, 102, 88, 132, 169, 63, 199, 65, + 199, 255, 207, 190, 188, 188, 253, 20, 214, 71, 227, 53, 251, 211, 2, 122, 6, 213, 105, + 235, 119, 229, 13, 40, 48, 44, 169, 49, 61, 108, 172, 91, 222, 37, 100, 99, 15, 44, 148, + 119, 187, 217, 2, 201, 42, 203, 117, 103, 2, 204, 204, 103, 248, 105, 102, 15, 243, 199, + 232, 153, 207, 34, 81, 204, 59, 169, 246, 70, 102, 124, 170, 77, 129, 42, 26, 163, 180, + 211, 254, 139, 194, 231, 242, 115, 198, 63, 248, 231, 141, 141, 180, 246, 248, 38, 59, 129, + 59, 188, 249, 164, 7, 126, 117, 116, 52, 49, 249, 2, 99, 219, 204, 139, 56, 203, 216, 51, + 220, 215, 208, 155, 3, 64, 36, 45, 15, 232, 67, 199, 182, 241, 24, 181, 154, 49, 125, 66, + 225, 199, 58, 195, 10, 112, 139, 163, 30, 71, 78, 10, 112, 169, 173, 97, 15, 81, 90, 20, + 70, 41, 107, 23, 117, 55, 206, 46, 38, 50, 165, 52, 51, 172, 192, 101, 67, 113, 156, 127, + 113, 111, 228, 92, 131, 249, 96, 51, 4, 188, 29, 179, 158, 48, 24, 221, 54, 194, 174, 66, + 52, 57, 164, 36, 190, 236, 139, 242, 23, 215, 88, 59, 27, 237, 249, 180, 49, 213, 56, 235, + 137, 155, 239, 106, 40, 83, 199, 201, 0, 67, 54, 38, 179, 106, 221, 152, 161, 212, 162, + 133, 115, 204, 34, 121, 139, 79, 229, 135, 53, 132, 96, 58, 217, 134, 1, 57, 181, 166, 88, + 161, 38, 103, 138, 195, 19, 57, 168, 163, 220, 30, 63, 221, 25, 20, 64, 115, 63, 85, 186, + 150, 146, 119, 217, 252, 2, 246, 221, 36, 231, 145, 13, 62, 82, 134, 210, 221, 233, 94, + 104, 136, 74, 50, 160, 148, 76, 154, 232, 78, 41, 149, 75, 4, 27, 188, 99, 151, 218, 30, + 229, 168, 163, 7, 103, 194, 15, 164, 142, 147, 198, 250, 18, 71, 218, 6, 44, 154, 202, 45, + 101, 205, 249, 101, 186, 213, 191, 88, 248, 50, 254, 14, 188, 127, 15, 13, 209, 175, 103, + 200, 15, 144, 98, 38, 45, 50, 195, 8, 254, 133, 30, 194, 95, 246, 155, 99, 117, 243, 19, + 105, 121, 24, 28, 151, 134, 56, 207, 22, 108, 198, 247, 87, 187, 80, 27, 123, 58, 43, 169, + 112, 40, 75, 15, 29, 82, 157, 240, 146, 222, 134, 94, 120, 84, 129, 115, 199, 236, 7, 149, + 203, 147, 173, 113, 71, 202, 75, 64, 227, 4, 45, 136, 40, 2, 203, 193, 165, 81, 50, 108, + 237, 81, 195, 106, 218, 120, 130, 167, 77, 244, 127, 60, 179, 229, 105, 78, 185, 85, 55, + 196, 223, 99, 32, 237, 33, 110, 40, 194, 16, 7, 62, 44, 176, 43, 123, 23, 197, 191, 252, + 142, 205, 250, 240, 20, 165, 43, 240, 221, 253, 217, 25, 85, 156, 20, 60, 153, 204, 215, + 90, 121, 18, 110, 234, 64, 178, 83, 163, 195, 160, 54, 222, 26, 33, 111, 233, 242, 74, 37, + 143, 249, 228, 255, 142, 12, 94, 56, 104, 65, 86, 32, 33, 197, 233, 160, 199, 97, 130, 28, + 40, 99, 72, 208, 57, 94, 139, 135, 111, 239, 79, 128, 41, 233, 45, 214, 44, 98, 67, 149, + 132, 41, 26, 120, 197, 160, 163, 2, 172, 66, 56, 218, 196, 101, 77, 27, 121, 56, 109, 191, + 179, 89, 221, 47, 132, 111, 225, 151, 122, 38, 204, 249, 22, 73, 110, 29, 195, 172, 241, + 181, 122, 116, 236, 245, 71, 206, 45, 28, 101, 230, 17, 78, 66, 165, 86, 221, 174, 102, 30, + 44, 229, 20, 218, 153, 18, 97, 201, 185, 20, 17, 132, 14, 98, 218, 13, 66, 117, 107, 34, + 26, 143, 161, 180, 174, 144, 204, 83, 61, 187, 47, 74, 10, 66, 24, 111, 179, 4, 52, 248, + 119, 175, 226, 127, 71, 104, 202, 152, 96, 186, 242, 65, 192, 229, 105, 192, 242, 159, 206, + 244, 200, 169, 25, 168, 141, 28, 240, 77, 186, 193, 71, 106, 206, 68, 4, 216, 164, 67, 63, + 116, 10, 230, 24, 211, 165, 248, 0, 81, 30, 125, 36, 181, 151, 178, 124, 23, 179, 51, 33, + 140, 200, 53, 174, 229, 93, 234, 39, 136, 230, 7, 139, 49, 78, 57, 181, 117, 105, 201, 176, + 32, 24, 62, 18, 59, 25, 53, 27, 84, 165, 201, 152, 241, 156, 220, 118, 1, 222, 255, 132, + 132, 131, 102, 2, 44, 79, 9, 82, 127, 39, 152, 29, 53, 156, 178, 89, 19, 198, 7, 75, 194, + 15, 218, 70, 65, 65, 5, 2, 128, 136, 118, 216, 232, 5, 210, 65, 108, 3, 49, 240, 252, 10, + 249, 136, 18, 144, 221, 123, 39, 10, 224, 159, 31, 145, 138, 81, 227, 19, 231, 31, 114, + 128, 241, 240, 3, 93, 170, 188, 125, 123, 242, 130, 203, 104, 112, 72, 218, 196, 155, 240, + 0, 80, 220, 50, 114, 188, 73, 151, 118, 89, 218, 41, 59, 29, 165, 180, 48, 243, 163, 94, + 157, 173, 199, 62, 101, 159, 73, 9, 210, 215, 88, 250, 216, 28, 76, 61, 1, 69, 60, 145, + 254, 218, 210, 19, 161, 102, 203, 164, 159, 138, 53, 96, 212, 153, 252, 1, 249, 94, 61, 20, + 223, 204, 132, 173, 163, 216, 248, 76, 28, 229, 27, 255, 131, 249, 69, 114, 110, 54, 71, + 227, 183, 123, 103, 224, 175, 55, 180, 94, 50, 176, 150, 56, 27, 120, 40, 98, 53, 209, 152, + 15, 240, 123, 106, 211, 188, 48, 105, 199, 85, 59, 40, 72, 39, 58, 136, 76, 27, 109, 7, + 218, 58, 98, 183, 168, 138, 47, 31, 32, 26, 175, 38, 115, 175, 46, 154, 75, 17, 226, 173, + 173, 181, 188, 56, 45, 31, 101, 224, 223, 1, 104, 91, 43, 86, 191, 130, 17, 63, 237, 36, + 115, 9, 92, 202, 150, 19, 56, 18, 116, 138, 230, 253, 202, 245, 75, 144, 182, 210, 32, 230, + 167, 161, 62, 225, 73, 81, 20, 181, 213, 161, 162, 124, 96, 67, 85, 223, 234, 56, 175, 10, + 224, 186, 210, 14, 163, 165, 180, 123, 171, 170, 91, 100, 105, 196, 9, 147, 119, 123, 196, + 242, 36, 193, 28, 154, 24, 175, 50, 28, 26, 107, 200, 158, 144, 38, 89, 82, 32, 11, 103, + 37, 64, 30, 118, 82, 217, 132, 24, 148, 54, 157, 194, 161, 153, 225, 142, 209, 183, 61, + 213, 62, 123, 179, 113, 189, 241, 208, 98, 94, 147, 254, 253, 98, 19, 18, 229, 164, 191, + 140, 150, 41, 131, 123, 26, 0, 23, 209, 251, 115, 73, 178, 174, 80, 30, 72, 55, 155, 239, + 169, 159, 167, 55, 73, 68, 228, 229, 91, 84, 151, 140, 52, 189, 231, 220, 250, 74, 41, 231, + 121, 49, 115, 136, 46, 141, 137, 107, 23, 244, 167, 185, 126, 25, 188, 162, 147, 68, 75, + 153, 254, 216, 217, 221, 45, 143, 135, 113, 229, 255, 169, 34, 181, 244, 76, 94, 18, 159, + 24, 6, 249, 102, 169, 166, 116, 156, 214, 227, 140, 130, 155, 182, 18, 192, 129, 33, 57, + 243, 183, 55, 87, 212, 35, 192, 193, 230, 10, 57, 82, 10, 137, 3, 60, 30, 76, 100, 150, + 125, 232, 149, 122, 213, 239, 33, 86, 207, 180, 231, 59, 106, 198, 166, 145, 194, 41, 190, + 152, 232, 81, 130, 30, 85, 24, 149, 209, 161, 7, 20, 80, 14, 81, 36, 63, 170, 73, 173, 42, + 110, 51, 43, 13, 199, 111, 135, 224, 55, 24, 107, 106, 44, 225, 7, 233, 145, 211, 233, 48, + 194, 95, 33, 0, 149, 172, 109, 161, 167, 186, 206, 153, 60, 45, 198, 151, 139, 35, 27, 95, + 217, 213, 128, 234, 172, 39, 71, 88, 175, 43, 243, 19, 47, 152, 184, 92, 196, 202, 127, + 146, 208, 254, 178, 152, 107, 118, 124, 118, 193, 184, 216, 113, 158, 80, 14, 8, 235, 130, + 74, 141, 105, 186, 18, 218, 190, 74, 0, 224, 22, 12, 228, 84, 111, 193, 97, 253, 245, 4, + 148, 149, 237, 142, 69, 238, 46, 143, 43, 135, 117, 145, 28, 216, 143, 190, + ]; + const SIGN_RND: [u8; 32] = [0; 32]; + const SIGNATURE: [u8; SIG_LEN + 1] = [ + 236, 220, 84, 213, 181, 217, 220, 186, 205, 227, 60, 143, 106, 93, 197, 151, 22, 70, 246, + 64, 200, 9, 195, 26, 190, 87, 94, 129, 56, 103, 216, 42, 55, 75, 213, 215, 236, 218, 45, + 237, 26, 161, 107, 19, 33, 113, 230, 29, 221, 27, 29, 229, 247, 112, 214, 113, 102, 53, 24, + 233, 62, 226, 167, 115, 175, 157, 138, 19, 38, 255, 9, 230, 99, 217, 119, 174, 67, 98, 152, + 81, 185, 111, 134, 169, 56, 139, 80, 144, 209, 230, 222, 56, 58, 5, 8, 118, 47, 121, 146, + 162, 10, 183, 228, 187, 122, 159, 48, 110, 108, 16, 31, 241, 253, 207, 27, 83, 224, 142, + 104, 94, 64, 173, 225, 151, 155, 228, 2, 177, 116, 54, 115, 193, 4, 239, 4, 222, 8, 244, + 249, 112, 78, 147, 64, 13, 19, 19, 75, 156, 8, 85, 248, 116, 212, 175, 2, 188, 42, 204, 55, + 84, 147, 74, 119, 176, 157, 249, 195, 177, 108, 235, 103, 34, 129, 83, 184, 225, 241, 216, + 57, 170, 255, 229, 66, 143, 106, 46, 205, 116, 178, 144, 29, 185, 235, 31, 238, 132, 142, + 211, 108, 227, 34, 6, 216, 227, 73, 44, 5, 184, 134, 102, 121, 100, 54, 241, 92, 19, 69, + 219, 252, 109, 47, 216, 111, 50, 52, 251, 84, 128, 204, 197, 141, 7, 107, 129, 203, 191, + 225, 91, 252, 190, 74, 114, 23, 212, 153, 158, 72, 166, 19, 38, 4, 77, 255, 89, 235, 180, + 103, 61, 195, 229, 77, 137, 233, 68, 7, 221, 50, 70, 214, 98, 252, 228, 52, 73, 2, 111, + 251, 115, 118, 161, 232, 208, 93, 0, 167, 156, 162, 250, 137, 37, 149, 4, 11, 243, 196, + 124, 78, 217, 173, 28, 74, 249, 178, 191, 247, 228, 106, 236, 196, 5, 136, 194, 246, 159, + 102, 200, 241, 159, 252, 56, 220, 67, 207, 128, 74, 56, 207, 130, 175, 209, 176, 73, 152, + 46, 125, 206, 209, 187, 107, 74, 26, 102, 161, 228, 133, 25, 42, 111, 123, 69, 186, 253, + 21, 97, 6, 161, 63, 76, 169, 138, 215, 19, 26, 152, 124, 96, 143, 98, 215, 77, 238, 188, + 222, 119, 143, 190, 29, 12, 154, 87, 9, 57, 130, 72, 32, 174, 240, 103, 230, 35, 10, 123, + 104, 221, 27, 200, 97, 22, 112, 166, 67, 33, 77, 90, 157, 183, 129, 157, 201, 96, 0, 200, + 79, 176, 66, 9, 6, 126, 209, 214, 69, 180, 245, 45, 5, 5, 52, 141, 119, 9, 238, 234, 107, + 244, 192, 133, 85, 161, 253, 72, 86, 252, 176, 58, 34, 215, 57, 38, 202, 246, 157, 113, 67, + 60, 144, 138, 107, 63, 178, 62, 196, 214, 218, 128, 102, 98, 138, 202, 216, 91, 0, 106, + 108, 198, 254, 250, 225, 29, 177, 221, 25, 168, 10, 155, 61, 174, 57, 25, 245, 209, 39, 86, + 212, 166, 24, 12, 198, 161, 55, 111, 244, 55, 57, 44, 91, 214, 64, 224, 143, 165, 50, 17, + 151, 220, 163, 39, 117, 166, 64, 68, 178, 24, 190, 18, 194, 59, 79, 12, 38, 150, 215, 116, + 41, 247, 136, 218, 129, 84, 63, 239, 183, 212, 137, 108, 121, 240, 75, 109, 171, 148, 216, + 101, 224, 239, 212, 94, 4, 95, 149, 76, 11, 195, 213, 165, 171, 117, 51, 208, 102, 105, + 162, 238, 60, 47, 111, 216, 120, 205, 87, 201, 9, 36, 251, 187, 215, 61, 214, 153, 69, 43, + 238, 14, 220, 18, 148, 196, 135, 111, 173, 250, 143, 145, 228, 190, 208, 200, 155, 175, + 188, 73, 52, 152, 113, 89, 137, 106, 82, 235, 46, 50, 156, 119, 60, 139, 110, 244, 55, 211, + 113, 40, 70, 229, 33, 57, 16, 103, 244, 175, 89, 75, 211, 75, 34, 209, 214, 215, 76, 68, + 46, 173, 143, 166, 69, 192, 108, 30, 149, 221, 134, 228, 31, 26, 42, 104, 12, 98, 37, 49, + 120, 3, 115, 200, 216, 58, 0, 138, 209, 47, 52, 81, 108, 34, 237, 193, 107, 99, 158, 90, + 63, 199, 147, 96, 3, 114, 211, 213, 212, 27, 30, 191, 25, 129, 167, 38, 172, 152, 39, 58, + 153, 54, 35, 145, 206, 78, 47, 74, 251, 104, 148, 113, 70, 255, 73, 79, 143, 172, 11, 209, + 39, 53, 29, 239, 144, 9, 140, 189, 222, 87, 236, 88, 24, 56, 240, 89, 42, 193, 180, 49, + 202, 221, 171, 192, 240, 237, 202, 222, 255, 136, 5, 164, 204, 51, 178, 97, 75, 87, 81, + 105, 246, 160, 36, 60, 83, 198, 130, 151, 96, 97, 182, 219, 248, 243, 129, 195, 34, 86, + 100, 248, 243, 36, 35, 172, 204, 127, 183, 169, 73, 99, 147, 185, 135, 117, 6, 185, 249, + 64, 189, 208, 193, 210, 184, 11, 102, 171, 173, 75, 182, 121, 249, 224, 221, 242, 102, 32, + 83, 7, 156, 137, 174, 164, 50, 241, 206, 169, 200, 111, 195, 9, 214, 117, 81, 34, 71, 181, + 16, 54, 64, 141, 251, 58, 240, 253, 42, 249, 159, 40, 4, 202, 157, 76, 214, 170, 64, 131, + 105, 92, 81, 59, 92, 23, 6, 48, 162, 215, 113, 30, 130, 2, 240, 216, 79, 202, 107, 204, + 184, 139, 148, 66, 82, 21, 193, 247, 124, 195, 25, 243, 124, 252, 22, 46, 4, 7, 61, 12, 80, + 141, 31, 96, 168, 76, 9, 216, 61, 114, 27, 97, 248, 58, 190, 36, 54, 154, 150, 236, 244, + 107, 127, 105, 176, 241, 217, 89, 38, 52, 218, 107, 104, 103, 74, 16, 196, 108, 49, 133, + 175, 16, 100, 59, 56, 145, 95, 82, 219, 65, 39, 39, 142, 42, 234, 209, 55, 120, 199, 231, + 211, 66, 218, 63, 47, 169, 79, 148, 21, 237, 91, 250, 134, 220, 44, 209, 96, 154, 183, 23, + 171, 72, 204, 222, 62, 214, 236, 247, 154, 161, 194, 231, 72, 244, 93, 119, 112, 210, 186, + 71, 191, 168, 154, 89, 157, 217, 214, 61, 243, 126, 113, 94, 55, 81, 59, 139, 213, 142, + 155, 221, 4, 48, 105, 229, 201, 128, 21, 201, 222, 72, 203, 235, 64, 192, 79, 103, 130, + 201, 178, 160, 70, 151, 142, 234, 95, 212, 191, 149, 154, 229, 64, 217, 67, 243, 182, 52, + 235, 42, 52, 60, 216, 12, 101, 232, 212, 68, 210, 38, 40, 207, 5, 175, 79, 40, 80, 206, 38, + 127, 249, 92, 52, 43, 181, 183, 20, 235, 237, 191, 5, 96, 49, 239, 41, 166, 112, 253, 254, + 107, 91, 91, 156, 36, 166, 90, 108, 199, 64, 246, 168, 22, 202, 19, 130, 204, 206, 36, 251, + 189, 166, 65, 195, 241, 151, 41, 147, 171, 74, 230, 143, 63, 18, 105, 244, 25, 43, 140, 29, + 28, 38, 62, 25, 249, 185, 178, 246, 165, 237, 108, 82, 184, 139, 217, 146, 166, 188, 125, + 250, 196, 235, 218, 73, 13, 73, 173, 96, 192, 155, 183, 216, 88, 146, 101, 154, 134, 28, + 110, 45, 7, 199, 9, 162, 93, 108, 96, 176, 172, 96, 238, 239, 53, 104, 175, 126, 117, 124, + 173, 202, 222, 80, 71, 31, 89, 169, 192, 112, 30, 225, 12, 165, 152, 79, 221, 78, 83, 112, + 15, 117, 5, 14, 174, 179, 6, 189, 170, 26, 124, 250, 130, 245, 55, 190, 186, 112, 158, 149, + 58, 65, 14, 152, 245, 243, 231, 65, 48, 122, 199, 52, 36, 48, 2, 49, 104, 229, 13, 26, 228, + 108, 191, 69, 123, 168, 151, 115, 199, 19, 255, 237, 111, 229, 214, 204, 105, 237, 208, 28, + 64, 145, 250, 192, 100, 26, 68, 13, 98, 226, 117, 113, 40, 213, 205, 25, 168, 92, 121, 74, + 104, 1, 43, 192, 7, 31, 75, 209, 49, 56, 81, 154, 169, 138, 243, 72, 33, 86, 36, 61, 235, + 156, 161, 0, 209, 245, 237, 232, 61, 60, 243, 31, 206, 216, 27, 244, 116, 135, 142, 236, + 241, 26, 151, 248, 2, 62, 140, 189, 210, 123, 205, 78, 200, 130, 161, 92, 147, 19, 112, + 241, 218, 89, 14, 40, 10, 180, 167, 219, 218, 198, 44, 37, 90, 42, 181, 66, 20, 185, 72, + 240, 43, 221, 182, 222, 210, 81, 251, 81, 224, 218, 218, 160, 200, 74, 45, 75, 112, 251, + 139, 49, 196, 68, 207, 210, 184, 238, 138, 112, 106, 152, 35, 20, 216, 232, 32, 35, 84, + 116, 148, 46, 86, 160, 141, 174, 90, 113, 15, 132, 55, 69, 176, 192, 142, 102, 20, 114, + 132, 228, 158, 210, 76, 155, 164, 157, 237, 184, 142, 76, 31, 196, 26, 153, 140, 28, 195, + 73, 230, 36, 82, 88, 47, 112, 67, 221, 20, 39, 19, 133, 7, 234, 126, 131, 38, 11, 45, 190, + 151, 147, 177, 0, 216, 86, 110, 200, 194, 72, 109, 243, 8, 151, 6, 191, 192, 200, 127, 206, + 5, 87, 158, 24, 186, 172, 225, 236, 198, 34, 236, 76, 66, 117, 141, 241, 90, 123, 169, 60, + 12, 28, 221, 131, 219, 186, 242, 32, 159, 162, 170, 127, 85, 76, 145, 211, 178, 241, 209, + 118, 13, 11, 161, 65, 13, 226, 106, 128, 147, 125, 230, 230, 238, 238, 183, 150, 199, 65, + 191, 100, 210, 217, 250, 33, 31, 137, 39, 150, 160, 29, 83, 115, 59, 8, 254, 26, 183, 163, + 202, 7, 176, 73, 36, 158, 38, 5, 243, 92, 88, 249, 31, 16, 233, 13, 28, 105, 221, 3, 73, + 239, 18, 246, 239, 5, 220, 197, 170, 175, 99, 172, 139, 73, 22, 222, 150, 148, 31, 151, 14, + 95, 207, 53, 141, 243, 168, 43, 172, 50, 228, 34, 101, 135, 182, 233, 1, 184, 161, 127, 72, + 47, 247, 79, 141, 83, 21, 0, 165, 76, 101, 212, 2, 227, 77, 49, 192, 137, 96, 238, 252, + 104, 108, 219, 97, 6, 155, 155, 230, 75, 145, 159, 209, 211, 244, 55, 190, 4, 111, 33, 40, + 100, 240, 88, 127, 122, 204, 44, 200, 227, 206, 122, 207, 227, 65, 94, 224, 178, 9, 4, 174, + 55, 112, 72, 82, 88, 101, 224, 122, 86, 210, 174, 79, 30, 119, 195, 8, 75, 94, 173, 87, + 238, 159, 122, 206, 18, 83, 99, 22, 199, 51, 45, 101, 14, 123, 234, 79, 253, 98, 15, 208, + 40, 13, 12, 39, 186, 128, 224, 231, 173, 105, 231, 33, 239, 2, 68, 50, 85, 148, 42, 49, + 201, 22, 164, 53, 150, 128, 189, 201, 105, 226, 254, 85, 38, 216, 47, 211, 220, 119, 254, + 56, 88, 177, 234, 112, 213, 4, 174, 112, 123, 36, 46, 246, 8, 73, 137, 127, 197, 67, 193, + 234, 157, 234, 36, 203, 150, 85, 138, 57, 57, 59, 157, 104, 41, 202, 134, 201, 22, 19, 184, + 132, 70, 123, 246, 210, 129, 202, 143, 30, 134, 29, 94, 69, 236, 239, 237, 240, 135, 64, + 195, 113, 94, 70, 89, 103, 41, 162, 154, 36, 199, 28, 189, 10, 156, 134, 184, 173, 164, 31, + 252, 254, 181, 247, 49, 159, 181, 241, 205, 125, 146, 155, 28, 96, 155, 93, 188, 101, 214, + 72, 171, 248, 71, 65, 134, 59, 152, 25, 188, 149, 209, 144, 40, 191, 111, 93, 131, 78, 59, + 223, 247, 245, 50, 198, 77, 192, 209, 73, 117, 196, 130, 102, 254, 202, 153, 77, 35, 116, + 113, 172, 8, 45, 238, 140, 111, 1, 173, 130, 5, 146, 68, 217, 198, 38, 219, 155, 76, 1, 82, + 194, 163, 235, 197, 63, 197, 111, 98, 22, 216, 218, 79, 4, 24, 13, 251, 176, 101, 29, 198, + 135, 5, 5, 37, 54, 239, 20, 175, 131, 29, 171, 85, 188, 180, 189, 146, 156, 101, 33, 56, + 87, 65, 122, 12, 205, 130, 20, 227, 152, 207, 173, 61, 67, 109, 115, 140, 238, 231, 70, + 130, 59, 77, 201, 120, 96, 85, 170, 92, 251, 40, 224, 59, 180, 209, 101, 192, 150, 175, 84, + 78, 64, 150, 79, 181, 248, 133, 159, 11, 212, 186, 17, 133, 9, 242, 25, 117, 152, 25, 89, + 146, 177, 11, 54, 142, 58, 253, 24, 150, 191, 176, 171, 78, 140, 220, 71, 95, 83, 188, 209, + 6, 239, 0, 124, 191, 190, 58, 130, 89, 162, 9, 142, 81, 26, 106, 176, 233, 39, 72, 195, 37, + 103, 143, 232, 156, 55, 238, 207, 5, 200, 170, 23, 248, 87, 20, 42, 145, 242, 176, 66, 123, + 134, 220, 178, 38, 168, 247, 102, 130, 100, 35, 188, 147, 10, 196, 147, 252, 2, 196, 68, + 226, 199, 220, 220, 141, 46, 132, 217, 116, 45, 149, 113, 54, 28, 82, 63, 95, 234, 30, 244, + 192, 58, 50, 158, 253, 47, 194, 168, 199, 186, 140, 194, 22, 201, 177, 222, 75, 37, 107, + 225, 234, 150, 164, 104, 31, 88, 157, 89, 65, 47, 75, 190, 204, 144, 230, 74, 5, 35, 192, + 45, 146, 226, 130, 76, 112, 137, 164, 245, 37, 6, 216, 241, 252, 250, 73, 209, 246, 143, + 99, 27, 189, 145, 66, 92, 52, 127, 2, 173, 247, 158, 138, 185, 35, 41, 178, 171, 85, 147, + 78, 99, 85, 93, 39, 61, 122, 41, 124, 168, 152, 29, 41, 127, 178, 228, 42, 192, 242, 213, + 131, 102, 143, 141, 147, 233, 80, 153, 177, 168, 223, 220, 131, 215, 30, 130, 69, 66, 235, + 255, 105, 231, 98, 49, 162, 216, 40, 136, 88, 160, 81, 209, 248, 130, 59, 182, 81, 163, + 146, 169, 192, 142, 138, 156, 42, 252, 216, 10, 25, 4, 189, 241, 87, 149, 162, 253, 246, + 96, 13, 181, 180, 49, 121, 76, 194, 220, 123, 87, 149, 103, 38, 9, 166, 21, 83, 50, 218, + 70, 44, 50, 238, 131, 220, 216, 212, 203, 138, 108, 108, 97, 225, 103, 0, 176, 10, 21, 107, + 120, 177, 59, 63, 145, 159, 78, 5, 239, 203, 172, 111, 33, 36, 29, 117, 192, 235, 8, 210, + 194, 229, 225, 249, 146, 162, 160, 53, 134, 181, 197, 172, 176, 87, 5, 22, 6, 50, 6, 227, + 10, 207, 124, 36, 170, 41, 229, 202, 140, 50, 173, 99, 207, 219, 159, 10, 51, 6, 198, 39, + 5, 45, 26, 222, 202, 212, 216, 245, 210, 88, 176, 230, 34, 50, 79, 180, 137, 40, 241, 238, + 180, 189, 218, 119, 102, 163, 100, 104, 123, 88, 81, 57, 179, 133, 237, 216, 178, 85, 103, + 10, 208, 147, 3, 248, 107, 164, 250, 72, 71, 112, 108, 203, 255, 183, 234, 198, 137, 77, + 188, 107, 77, 237, 160, 54, 60, 216, 93, 107, 115, 223, 97, 201, 155, 249, 111, 253, 70, + 216, 232, 166, 85, 162, 21, 250, 51, 21, 242, 77, 204, 67, 125, 225, 117, 236, 27, 184, 92, + 205, 25, 8, 254, 168, 97, 224, 84, 60, 77, 238, 39, 67, 232, 242, 169, 32, 83, 25, 253, 71, + 135, 171, 246, 89, 22, 219, 35, 228, 114, 85, 25, 35, 180, 241, 202, 10, 34, 92, 134, 187, + 94, 86, 64, 92, 86, 8, 112, 251, 1, 80, 71, 224, 46, 241, 0, 220, 68, 44, 243, 19, 156, + 183, 72, 196, 59, 134, 92, 33, 209, 127, 228, 193, 125, 123, 37, 82, 157, 190, 216, 97, 76, + 188, 107, 181, 88, 125, 253, 51, 36, 152, 76, 252, 253, 107, 192, 120, 205, 57, 145, 224, + 229, 84, 118, 241, 100, 233, 15, 206, 194, 204, 134, 116, 153, 18, 228, 244, 13, 208, 231, + 19, 222, 157, 120, 50, 1, 207, 135, 128, 164, 7, 41, 255, 127, 84, 225, 154, 149, 18, 9, + 101, 98, 126, 140, 239, 50, 16, 85, 237, 59, 9, 203, 240, 95, 194, 120, 19, 36, 42, 244, + 24, 179, 166, 146, 165, 12, 189, 85, 99, 86, 97, 213, 102, 152, 82, 27, 124, 59, 61, 7, 82, + 2, 164, 176, 230, 191, 241, 247, 29, 237, 44, 81, 245, 245, 41, 125, 85, 57, 89, 8, 138, + 34, 93, 5, 160, 6, 114, 77, 108, 148, 198, 81, 247, 87, 138, 69, 188, 12, 124, 138, 18, 16, + 34, 64, 169, 105, 72, 59, 109, 50, 106, 190, 232, 157, 242, 209, 149, 153, 227, 98, 109, + 69, 128, 44, 98, 136, 69, 150, 107, 60, 61, 42, 91, 175, 60, 10, 100, 178, 140, 155, 23, + 188, 16, 247, 225, 235, 4, 238, 75, 186, 213, 206, 39, 241, 129, 77, 221, 221, 185, 101, + 20, 165, 152, 139, 32, 170, 245, 230, 140, 105, 202, 180, 80, 121, 95, 179, 98, 198, 175, + 70, 58, 221, 227, 133, 250, 244, 103, 44, 248, 53, 96, 220, 120, 193, 95, 247, 235, 204, + 196, 164, 86, 60, 140, 227, 49, 237, 53, 240, 234, 24, 14, 45, 184, 203, 167, 18, 108, 239, + 102, 229, 182, 158, 144, 81, 14, 229, 219, 11, 254, 253, 52, 44, 126, 221, 237, 251, 231, + 245, 1, 240, 199, 107, 233, 116, 66, 36, 182, 66, 66, 207, 249, 223, 27, 208, 201, 60, 66, + 179, 122, 19, 159, 86, 19, 134, 243, 228, 249, 191, 183, 12, 61, 18, 93, 72, 24, 56, 237, + 63, 57, 103, 171, 188, 79, 175, 110, 2, 82, 101, 137, 200, 101, 67, 39, 51, 146, 35, 36, + 221, 1, 180, 25, 219, 12, 150, 148, 226, 202, 215, 244, 94, 2, 218, 92, 95, 196, 43, 8, + 190, 170, 116, 230, 206, 191, 103, 215, 130, 18, 101, 9, 15, 88, 229, 206, 158, 129, 22, + 220, 178, 141, 115, 145, 153, 119, 149, 176, 230, 75, 218, 254, 112, 12, 107, 62, 180, 217, + 38, 156, 60, 135, 155, 228, 34, 40, 89, 55, 217, 76, 153, 199, 162, 207, 252, 181, 71, 128, + 121, 218, 122, 13, 104, 224, 177, 52, 170, 41, 127, 140, 158, 74, 195, 108, 81, 79, 202, + 22, 96, 56, 104, 75, 110, 191, 35, 53, 236, 83, 108, 240, 77, 231, 219, 12, 222, 110, 104, + 163, 199, 155, 49, 191, 18, 197, 171, 243, 78, 175, 226, 130, 72, 228, 254, 169, 249, 162, + 183, 18, 242, 72, 148, 116, 219, 88, 155, 75, 133, 100, 74, 219, 167, 137, 241, 33, 219, + 172, 28, 143, 184, 149, 251, 133, 33, 161, 116, 107, 95, 39, 224, 206, 228, 215, 205, 58, + 188, 67, 157, 194, 6, 213, 73, 27, 11, 179, 218, 1, 5, 61, 53, 171, 251, 175, 63, 96, 206, + 41, 6, 194, 237, 164, 235, 130, 0, 109, 29, 168, 32, 69, 174, 225, 157, 55, 25, 71, 105, + 131, 153, 106, 163, 175, 207, 231, 95, 196, 189, 34, 190, 228, 157, 179, 5, 166, 111, 6, + 210, 54, 147, 208, 40, 107, 8, 106, 44, 36, 175, 174, 251, 235, 47, 177, 35, 245, 67, 230, + 211, 160, 200, 206, 58, 121, 248, 163, 121, 95, 56, 47, 240, 10, 99, 7, 88, 198, 114, 204, + 76, 69, 47, 93, 93, 49, 55, 162, 96, 250, 130, 126, 94, 126, 195, 161, 42, 98, 187, 70, + 222, 151, 152, 81, 157, 150, 92, 222, 237, 45, 139, 241, 190, 23, 223, 186, 16, 103, 9, + 187, 136, 75, 232, 160, 24, 8, 230, 37, 50, 241, 5, 23, 255, 218, 214, 129, 45, 4, 173, + 246, 107, 184, 253, 226, 194, 195, 22, 245, 219, 218, 102, 35, 130, 13, 40, 110, 84, 43, + 177, 195, 14, 107, 128, 63, 13, 110, 168, 136, 71, 200, 131, 71, 159, 58, 64, 82, 85, 43, + 104, 140, 39, 221, 86, 237, 128, 232, 54, 54, 134, 25, 93, 64, 15, 171, 211, 108, 35, 83, + 42, 7, 146, 49, 151, 145, 119, 120, 162, 190, 229, 213, 255, 233, 77, 165, 218, 217, 71, + 76, 203, 150, 204, 199, 244, 38, 118, 43, 30, 146, 188, 140, 100, 110, 102, 195, 150, 144, + 146, 252, 131, 203, 91, 196, 159, 194, 137, 61, 124, 6, 105, 61, 123, 19, 247, 123, 49, 41, + 170, 34, 225, 217, 166, 234, 73, 217, 21, 94, 213, 125, 73, 165, 213, 18, 181, 41, 138, + 196, 71, 216, 147, 37, 58, 70, 173, 251, 100, 221, 172, 244, 53, 43, 102, 2, 151, 92, 137, + 93, 114, 233, 237, 119, 75, 81, 53, 70, 129, 253, 165, 35, 108, 156, 109, 11, 160, 178, 51, + 160, 61, 129, 168, 250, 73, 168, 186, 99, 22, 161, 35, 45, 116, 221, 12, 65, 222, 68, 235, + 6, 131, 125, 175, 1, 152, 105, 233, 63, 26, 143, 28, 26, 115, 68, 235, 40, 148, 94, 103, + 244, 96, 116, 113, 211, 56, 159, 118, 120, 130, 216, 209, 171, 39, 78, 130, 88, 254, 100, + 220, 15, 11, 157, 9, 24, 9, 76, 5, 46, 159, 198, 29, 208, 137, 161, 98, 123, 76, 253, 142, + 192, 201, 192, 99, 91, 170, 253, 251, 160, 252, 59, 253, 22, 9, 152, 107, 209, 81, 78, 178, + 140, 243, 26, 36, 125, 106, 67, 179, 87, 207, 95, 17, 18, 46, 180, 255, 188, 102, 230, 0, + 19, 147, 210, 30, 232, 87, 174, 107, 56, 99, 205, 103, 120, 253, 146, 118, 215, 98, 189, + 175, 105, 152, 26, 132, 84, 253, 106, 137, 238, 114, 110, 241, 152, 225, 5, 42, 161, 152, + 250, 238, 250, 156, 206, 16, 72, 127, 75, 138, 84, 16, 148, 172, 224, 108, 205, 147, 165, + 71, 138, 32, 35, 33, 166, 7, 219, 129, 156, 177, 81, 39, 99, 235, 229, 237, 248, 209, 132, + 9, 213, 11, 123, 226, 107, 230, 176, 79, 49, 250, 109, 238, 126, 49, 223, 129, 110, 75, + 167, 70, 233, 238, 158, 35, 70, 233, 230, 22, 197, 153, 227, 248, 203, 82, 200, 117, 112, + 73, 254, 185, 64, 245, 37, 102, 106, 52, 14, 136, 215, 155, 4, 70, 13, 20, 86, 75, 140, + 159, 109, 105, 163, 232, 244, 176, 164, 143, 171, 96, 94, 230, 41, 109, 138, 22, 225, 125, + 219, 126, 102, 162, 234, 250, 155, 226, 25, 125, 240, 34, 235, 54, 165, 44, 149, 125, 20, + 207, 250, 176, 249, 185, 42, 172, 132, 239, 169, 229, 53, 63, 156, 39, 247, 62, 84, 158, + 128, 227, 51, 46, 223, 252, 192, 151, 168, 35, 245, 85, 124, 33, 34, 39, 213, 70, 165, 85, + 134, 102, 30, 114, 108, 245, 72, 30, 122, 150, 235, 61, 105, 209, 197, 54, 152, 159, 188, + 42, 194, 217, 181, 174, 36, 58, 145, 27, 186, 174, 33, 2, 20, 93, 82, 64, 253, 252, 144, + 105, 25, 151, 64, 199, 2, 11, 220, 243, 171, 199, 227, 167, 121, 159, 101, 150, 48, 200, + 255, 196, 195, 31, 230, 66, 5, 106, 145, 3, 183, 154, 138, 76, 77, 244, 219, 90, 51, 190, + 163, 216, 80, 77, 198, 240, 85, 143, 158, 95, 251, 245, 250, 251, 105, 202, 248, 205, 243, + 127, 144, 1, 206, 26, 176, 151, 14, 153, 106, 194, 165, 202, 84, 157, 192, 65, 244, 161, + 156, 234, 251, 219, 87, 22, 64, 102, 55, 78, 40, 95, 165, 180, 113, 141, 5, 242, 166, 54, + 168, 210, 148, 253, 249, 204, 204, 71, 248, 108, 25, 192, 182, 255, 97, 2, 236, 134, 193, + 84, 32, 68, 227, 160, 208, 43, 157, 248, 196, 1, 53, 89, 159, 124, 232, 172, 32, 41, 59, + 250, 164, 100, 179, 204, 160, 25, 132, 214, 143, 169, 205, 217, 184, 228, 0, 154, 173, 137, + 244, 140, 232, 72, 44, 233, 4, 24, 220, 193, 30, 153, 34, 144, 1, 107, 47, 157, 132, 194, + 36, 185, 25, 23, 117, 99, 133, 48, 232, 116, 163, 50, 178, 104, 237, 15, 147, 194, 240, + 186, 139, 130, 233, 72, 43, 192, 195, 101, 229, 144, 96, 50, 184, 141, 236, 118, 82, 64, + 171, 88, 130, 1, 86, 168, 166, 127, 16, 246, 55, 181, 33, 133, 97, 209, 95, 86, 9, 235, 88, + 169, 104, 65, 88, 247, 35, 143, 89, 23, 242, 229, 79, 72, 134, 104, 135, 237, 21, 86, 163, + 146, 235, 8, 30, 130, 51, 93, 35, 131, 61, 178, 95, 212, 61, 100, 252, 111, 197, 177, 228, + 57, 141, 91, 141, 227, 143, 220, 16, 38, 242, 38, 143, 156, 31, 236, 71, 213, 231, 39, 71, + 5, 34, 244, 80, 150, 159, 249, 18, 44, 31, 92, 181, 190, 207, 56, 71, 192, 226, 124, 195, + 245, 56, 177, 13, 31, 184, 48, 245, 246, 200, 166, 222, 69, 240, 176, 51, 92, 151, 46, 22, + 145, 110, 64, 112, 205, 186, 16, 31, 56, 70, 12, 83, 191, 99, 28, 86, 53, 159, 205, 175, + 236, 49, 20, 80, 226, 210, 236, 89, 53, 44, 67, 132, 108, 29, 134, 119, 187, 40, 55, 129, + 169, 26, 15, 206, 202, 117, 117, 114, 133, 101, 101, 230, 27, 229, 230, 207, 120, 2, 25, 7, + 96, 157, 66, 71, 223, 137, 48, 10, 153, 231, 42, 161, 49, 253, 117, 53, 30, 154, 200, 164, + 43, 44, 203, 59, 51, 170, 2, 202, 31, 225, 108, 23, 117, 67, 185, 90, 177, 50, 184, 31, + 179, 205, 123, 15, 26, 253, 242, 107, 165, 185, 90, 29, 119, 83, 76, 192, 54, 162, 98, 81, + 199, 96, 175, 14, 99, 37, 77, 141, 89, 151, 232, 178, 224, 150, 234, 50, 45, 45, 156, 252, + 33, 17, 231, 96, 13, 30, 81, 249, 186, 199, 34, 106, 186, 130, 111, 247, 159, 112, 215, 34, + 243, 142, 60, 194, 236, 143, 89, 29, 173, 195, 186, 107, 92, 65, 172, 83, 247, 245, 228, + 221, 20, 174, 251, 172, 230, 156, 98, 249, 4, 186, 241, 125, 120, 65, 41, 208, 53, 140, 51, + 55, 189, 14, 162, 37, 181, 224, 93, 5, 158, 153, 97, 254, 122, 199, 100, 34, 173, 12, 59, + 185, 148, 142, 127, 37, 212, 62, 38, 157, 179, 171, 143, 228, 169, 85, 150, 41, 30, 131, + 159, 77, 229, 249, 193, 97, 62, 89, 231, 208, 233, 221, 240, 2, 172, 161, 24, 52, 32, 130, + 38, 219, 222, 132, 61, 44, 85, 145, 251, 180, 164, 132, 200, 15, 192, 123, 170, 170, 239, + 183, 106, 48, 252, 190, 80, 53, 97, 170, 216, 136, 215, 86, 222, 170, 205, 35, 208, 215, + 173, 252, 245, 2, 88, 84, 211, 132, 177, 59, 137, 194, 206, 18, 11, 167, 188, 67, 178, 7, + 44, 112, 192, 252, 110, 106, 215, 131, 87, 150, 148, 151, 147, 88, 207, 123, 224, 126, 208, + 244, 43, 254, 162, 129, 84, 141, 164, 174, 249, 43, 216, 77, 104, 32, 44, 145, 17, 130, 93, + 132, 212, 114, 4, 184, 168, 150, 165, 207, 179, 214, 33, 81, 38, 2, 238, 150, 170, 158, 16, + 67, 228, 29, 39, 252, 204, 116, 195, 154, 222, 98, 62, 24, 128, 47, 23, 41, 118, 158, 245, + 56, 226, 171, 153, 122, 243, 185, 211, 144, 220, 3, 194, 35, 107, 220, 222, 194, 75, 123, + 81, 248, 57, 83, 107, 143, 51, 198, 128, 238, 4, 238, 221, 145, 61, 58, 209, 28, 148, 69, + 67, 115, 97, 59, 51, 249, 227, 184, 121, 78, 71, 69, 7, 255, 210, 155, 148, 100, 85, 72, + 18, 238, 236, 165, 158, 99, 40, 1, 253, 235, 218, 211, 128, 111, 109, 57, 39, 25, 20, 199, + 146, 112, 85, 47, 40, 102, 64, 237, 117, 0, 0, 194, 136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3, 0, 0, 0, 36, 29, 20, 12, 0, 54, 50, 42, + ];