Skip to content

Instantly share code, notes, and snippets.

@niooss-ledger
Last active April 17, 2024 09:56
Show Gist options
  • Save niooss-ledger/1208f9209b7e1d0c2b7805bb2c160d0c to your computer and use it in GitHub Desktop.
Save niooss-ledger/1208f9209b7e1d0c2b7805bb2c160d0c to your computer and use it in GitHub Desktop.
Short write-up for RWPQC CTF 2024

Short write-up for RWPQC CTF 2024

Subject: https://github.com/sandbox-quantum/CTF-RWPQC2024/tree/ea398c3e934cdb35198c4efa180fa6bd6e2f9670

Challenge 1

As the secret key $s$ is only 32-bit long, it is possible to brute-force it. As $t_1 = A_1 * s_1 + A_2 * s_2 + e$ with $e$ some error polynomials, we can speed things up by splitting the brute-force in two 16-bit enumerations with $s_1$ and $s_2$ and comparing $A_1 * s_1$ with $t_1 - A_2 * s_2$. If these two polynomials have coefficients which only differ by one, $(s_1, s_2)$ is likely to be the secret key.

chall1_main.rs implements this brute-force in Rust code with no dependency:

$ rustc -O chall1_main.rs && ./chall1_main
Computing 2 tables
Comparing 2 tables
Brute split 0xc8df 0xe9d1
s = [1x^{15}+1x^{14}+1x^{11}+1x^{7}+1x^{6}+1x^{4}+1x^{3}+1x^{2}+1x+1, 1x^{15}+1x^{14}+1x^{13}+1x^{11}+1x^{8}+1x^{7}+1x^{6}+1x^{4}+1]
(As-t)_1 = 1x^{14}+250x^{11}+1x^{10}+1x^{9}+1x^{8}+250x^{7}+250x^{6}+250x^{4}+250x^{2}
(As-t)_2 = 250x^{15}+1x^{14}+250x^{12}+1x^{11}+1x^{8}+250x^{7}+250x^{6}+250x^{3}+250x^{2}+250x+250
e = [250x^{14}+1x^{11}+250x^{10}+250x^{9}+250x^{8}+1x^{7}+1x^{6}+1x^{4}+1x^{2}, 1x^{15}+250x^{14}+1x^{12}+250x^{11}+250x^{8}+1x^{7}+1x^{6}+1x^{3}+1x^{2}+1x+1]
m_n = 128x^{15}+245x^{13}+1x^{12}+125x^{11}+128x^{10}+120x^{9}+1x^{7}+125x^{6}+122x^{5}+249x^{4}+120x^{3}+248x^{2}+123
m = [1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1]
flag = 1000111001101001

Challenge 2

The challenge consists in brute-forcing a missing row in a training data-set. As the training function is continuous, a brute-force by small variations on the 16-dimensional parameters can be implemented.

In practice, the training was implemented using scikit-learn's LogisticRegression with some parameters to make it more precise than the default: LogisticRegression(penalty="l2", C=1.0, solver="lbfgs", max_iter=10000, tol=1e-6)

$ pip install pandas scikit-learn
$ ./chall2_bruteforce.py
Using new best<0> (425): [4, 12, 5, -3, -12, 9, -5, -15, 15, 16, -12, 0, 10, 0, -11, -13, 0]
Using new best<0> (404): [2, 14, 4, -3, -13, 13, -3, -16, 16, 14, -12, 1, 7, 1, -10, -14, 0]
Using new best<0> (305): [4, 14, 4, -2, -13, 11, -5, -16, 16, 16, -13, 0, 11, 1, -10, -14, 0]
Using new best<0> (267): [3, 14, 4, -2, -13, 11, -6, -16, 16, 16, -12, 0, 10, 2, -10, -14, 0]
Using new best<0> (250): [3, 14, 4, -2, -12, 12, -5, -16, 16, 16, -12, 0, 10, 1, -10, -13, 0]
Using new best<0> (2): [3, 14, 4, -3, -13, 11, -5, -16, 16, 16, -12, 0, 9, 1, -11, -14, 0]
Using new best<1> (5070): [16, -16, -5, -16, 16, -2, 16, 13, -2, 3, 16, 9, -6, -16, 16, 5, 1]
Using new best<1> (4981): [16, -16, -5, -16, 16, -2, 16, 13, -1, 4, 16, 7, -5, -16, 16, 6, 1]
Using new best<1> (4934): [16, -16, -5, -15, 16, -2, 16, 14, -2, 4, 16, 8, -4, -16, 16, 6, 1]
Using new best<1> (4774): [16, -16, -5, -16, 16, -3, 16, 14, -1, 4, 16, 8, -4, -16, 16, 6, 1]
Using new best<1> (3785): [7, -16, -14, -16, 16, -4, 15, 16, 5, 15, 15, -4, -1, -5, 12, 11, 1]
Using new best<1> (3780): [7, -16, -14, -16, 16, -4, 15, 16, 6, 15, 15, -4, -1, -5, 13, 13, 1]
Current best[y=0]: [3, 14, 4, -3, -13, 11, -5, -16, 16, 16, -12, 0, 9, 1, -11, -14, 0] # 2
Current best[y=1]: [7, -16, -14, -16, 16, -4, 15, 16, 6, 15, 15, -4, -1, -5, 13, 13, 1] # 3780

idx   target   coeff(y=0) (delta)   coeff(y=1) (delta)
 0  -1.812210  -1.812204 (    0.6)  -1.812200 (    1.0)
 1  -0.177120  -0.177117 (    0.3)  -0.177017 (   10.3)
 2   0.016450   0.016451 (    0.1)   0.016789 (   33.9)
 3   0.123640   0.123634 (   -0.6)   0.123625 (   -1.5)
 4   0.508700   0.508700 (    0.0)   0.508654 (   -4.6)
 5   0.119510   0.119508 (   -0.2)   0.119002 (  -50.8)
 6  -0.308540  -0.308541 (   -0.1)  -0.308333 (   20.7)
 7   0.191310   0.191314 (    0.4)   0.197588 (  627.8)
 8  -0.041010  -0.041013 (   -0.3)  -0.044106 ( -309.6)
 9   0.333260   0.333261 (    0.1)   0.343092 (  983.2)
10   0.326930   0.326928 (   -0.2)   0.340926 ( 1399.6)
11   0.010800   0.010803 (    0.3)   0.012468 (  166.8)
12   0.117170   0.117172 (    0.2)   0.117492 (   32.2)
13  -0.229780  -0.229780 (    0.0)  -0.229683 (    9.7)
14  -0.191400  -0.191399 (    0.1)  -0.191444 (   -4.4)
15   0.139090   0.139094 (    0.4)   0.139435 (   34.5)
16  -0.220880  -0.220884 (   -0.4)  -0.221773 (  -89.3)

This output means that the closest data was [3, 14, 4, -3, -13, 11, -5, -16, 16, 16, -12, 0, 9, 1, -11, -14, 0], with coefficients really near the target.

Challenge 3

ctf_server generates a Kyber key using a specific random number generator, called NIST-KAT, and a random seed generated with this pseudo-code written in C:

uint8_t orig_seed[48];
OQS_randombytes(orig_seed, 48);
for (int i = 0; i < 24; i++)
    orig_seed[i] = 0;
for (int i = 24; i < 48; i++)
    orig_seed[i] = orig_seed[i] & 0x01;

OQS_randombytes_switch_algorithm("NIST-KAT");
OQS_randombytes_nist_kat_init_256bit(orig_seed, NULL);
OQS_KEM_keypair(kem, public_key_srv, secret_key_srv);

This seed generation is very biaised: instead of using 48*8 = 384 random bits, the masking makes it only use 24 bits! When running ctf_server several times, it clearly displays such biaised seeds:

orig seed = 000000000000000000000000000000000000000000000000000000010101010100000100010100010100000001010001

To brute-force the seeds, liboqs needs to be built with a small patch provided in chall3a_liboqs.patch (this is because a recent Pull Request removed the ability to call OQS_randombytes_switch_algorithm("NIST-KAT") directly ; instead of patching, an older version of the library could probably have been used):

git clone https://github.com/open-quantum-safe/liboqs
cd liboqs
git checkout 890a6aa448598a019e72b5431d8ba8e0a5dbcc85
patch -Np1 < ../chall3a_liboqs.patch
mkdir build && cd build
cmake -GNinja ..
ninja
cd ../..
gcc -Wall -Wextra -Iliboqs/build/include/ -DCURRENT=1 chall3b_bf_seeds.c liboqs/build/lib/liboqs.a liboqs/build/lib/liboqs-internal.a -lcrypto -o chall3b_bf_seeds
./chall3b_bf_seeds

file.pcap contains 4 connections with different public keys, copied in chall3b_data.h. This file also contains the Kyber ciphertext. This brute-force gives for each connection the seed and the shared secret:

orig seed 000000000000000000000000000000000000000000000000010000000101010101010000010101010101000001000101
shared secret 83198c77f7128da58d3b33854635776fd50f82a858e6538a3993c6df21e61b67

orig seed 000000000000000000000000000000000000000000000000010100010001000101010000010100000000010101010000
shared secret 2fe79b0608478cfb6f8707aacb263a8ed0959ef56cf669c9690eac170010eb19

orig seed 000000000000000000000000000000000000000000000000010101010100000001000000000000000100010001000000
shared secret 6a3382f0de1c02e73166bca50e6252492b73462c789075341a1dbb36051756ba

orig seed 000000000000000000000000000000000000000000000000000000010001010101000100010101000000010100010001
shared secret 13b48bcb7cddcd56a63b0439dc76323b7c40e78c623a993cff501684d16b0d5e

The shared secret is used as a AES-128-ECB key to decryt the data.

chall3c_decrypt_pcap.py is a Python script using scapy to decrypt the messages from file.pcap. It displays:

[0 127.0.0.1:47826 > 127.0.0.1:1337]     b'NS1'
[3 127.0.0.1:47826 > 127.0.0.1:1337 enc] b'DIR'
[3 127.0.0.1:47826 > 127.0.0.1:1337 enc] b'.'
[3 127.0.0.1:47826 > 127.0.0.1:1337 enc] b'END'
[4 127.0.0.1:47826 < 127.0.0.1:1337 enc] b'b.txt'
[5 127.0.0.1:47826 < 127.0.0.1:1337 enc] b'\n'
[5 127.0.0.1:47826 < 127.0.0.1:1337 enc] b'.'
[5 127.0.0.1:47826 < 127.0.0.1:1337 enc] b'\n'
[5 127.0.0.1:47826 < 127.0.0.1:1337 enc] b'd.txt'
[5 127.0.0.1:47826 < 127.0.0.1:1337 enc] b'\n'
[5 127.0.0.1:47826 < 127.0.0.1:1337 enc] b'c.txt'
[5 127.0.0.1:47826 < 127.0.0.1:1337 enc] b'\n'
[5 127.0.0.1:47826 < 127.0.0.1:1337 enc] b'ctf_server'
[5 127.0.0.1:47826 < 127.0.0.1:1337 enc] b'\n'
[5 127.0.0.1:47826 < 127.0.0.1:1337 enc] b'abc'
[5 127.0.0.1:47826 < 127.0.0.1:1337 enc] b'\n'
[5 127.0.0.1:47826 < 127.0.0.1:1337 enc] b'bfg'
[5 127.0.0.1:47826 < 127.0.0.1:1337 enc] b'\n'
[5 127.0.0.1:47826 < 127.0.0.1:1337 enc] b'..'
[5 127.0.0.1:47826 < 127.0.0.1:1337 enc] b'\n'
[5 127.0.0.1:47826 < 127.0.0.1:1337 enc] b'server_secret.tx'
[5 127.0.0.1:47826 < 127.0.0.1:1337 enc] b't'
[5 127.0.0.1:47826 < 127.0.0.1:1337 enc] b'\n'
[5 127.0.0.1:47826 < 127.0.0.1:1337 enc] b'a.txt'
[5 127.0.0.1:47826 < 127.0.0.1:1337 enc] b'\n'
[5 127.0.0.1:47826 < 127.0.0.1:1337 enc] b'abc.txt'
[5 127.0.0.1:47826 < 127.0.0.1:1337 enc] b'\n'
[5 127.0.0.1:47826 < 127.0.0.1:1337 enc] b'END'
[0 127.0.0.1:44424 > 127.0.0.1:1337]     b'NS3'
[3 127.0.0.1:44424 > 127.0.0.1:1337 enc] b'PUT'
[3 127.0.0.1:44424 > 127.0.0.1:1337 enc] b'client_secret.tx'
[3 127.0.0.1:44424 > 127.0.0.1:1337 enc] b't'
[3 127.0.0.1:44424 > 127.0.0.1:1337 enc] b'END'
[3 127.0.0.1:44424 > 127.0.0.1:1337 enc] b'1337h@x0r\n'
[3 127.0.0.1:44424 > 127.0.0.1:1337 enc] b'END'
[0 127.0.0.1:45466 > 127.0.0.1:1337]     b'NS5'
[3 127.0.0.1:45466 > 127.0.0.1:1337 enc] b'DIR'
[3 127.0.0.1:45466 > 127.0.0.1:1337 enc] b'.'
[3 127.0.0.1:45466 > 127.0.0.1:1337 enc] b'END'
[4 127.0.0.1:45466 < 127.0.0.1:1337 enc] b'b.txt'
[5 127.0.0.1:45466 < 127.0.0.1:1337 enc] b'\n'
[5 127.0.0.1:45466 < 127.0.0.1:1337 enc] b'.'
[5 127.0.0.1:45466 < 127.0.0.1:1337 enc] b'\n'
[5 127.0.0.1:45466 < 127.0.0.1:1337 enc] b'd.txt'
[5 127.0.0.1:45466 < 127.0.0.1:1337 enc] b'\n'
[5 127.0.0.1:45466 < 127.0.0.1:1337 enc] b'c.txt'
[5 127.0.0.1:45466 < 127.0.0.1:1337 enc] b'\n'
[5 127.0.0.1:45466 < 127.0.0.1:1337 enc] b'ctf_server'
[5 127.0.0.1:45466 < 127.0.0.1:1337 enc] b'\n'
[5 127.0.0.1:45466 < 127.0.0.1:1337 enc] b'client_secret.tx'
[5 127.0.0.1:45466 < 127.0.0.1:1337 enc] b't'
[5 127.0.0.1:45466 < 127.0.0.1:1337 enc] b'\n'
[5 127.0.0.1:45466 < 127.0.0.1:1337 enc] b'abc'
[5 127.0.0.1:45466 < 127.0.0.1:1337 enc] b'\n'
[5 127.0.0.1:45466 < 127.0.0.1:1337 enc] b'bfg'
[5 127.0.0.1:45466 < 127.0.0.1:1337 enc] b'\n'
[5 127.0.0.1:45466 < 127.0.0.1:1337 enc] b'..'
[5 127.0.0.1:45466 < 127.0.0.1:1337 enc] b'\n'
[5 127.0.0.1:45466 < 127.0.0.1:1337 enc] b'server_secret.tx'
[5 127.0.0.1:45466 < 127.0.0.1:1337 enc] b't'
[5 127.0.0.1:45466 < 127.0.0.1:1337 enc] b'\n'
[5 127.0.0.1:45466 < 127.0.0.1:1337 enc] b'a.txt'
[5 127.0.0.1:45466 < 127.0.0.1:1337 enc] b'\n'
[5 127.0.0.1:45466 < 127.0.0.1:1337 enc] b'abc.txt'
[5 127.0.0.1:45466 < 127.0.0.1:1337 enc] b'\n'
[5 127.0.0.1:45466 < 127.0.0.1:1337 enc] b'END'
[0 127.0.0.1:37546 > 127.0.0.1:1337]     b'NS5'
[3 127.0.0.1:37546 > 127.0.0.1:1337 enc] b'GET'
[3 127.0.0.1:37546 > 127.0.0.1:1337 enc] b'server_secret.tx'
[3 127.0.0.1:37546 > 127.0.0.1:1337 enc] b't'
[3 127.0.0.1:37546 > 127.0.0.1:1337 enc] b'END'
[4 127.0.0.1:37546 < 127.0.0.1:1337 enc] b'My v0ice is my p'
[5 127.0.0.1:37546 < 127.0.0.1:1337 enc] b'@ssport.\n'
[5 127.0.0.1:37546 < 127.0.0.1:1337 enc] b'END'

In short, the client put client_secret.txt with 1337h@x0r and got server_secret.txt with My v0ice is my p@ssport..

Challenge 4

The challenge provides a fork of tlslite from https://github.com/tlsfuzzer/tlslite-ng/releases/tag/v0.8.0-beta1 where a directory kyber was added and the constant x25519kyber768draft00 was defined and use in some places. But the implementation of x25519kyber768draft00 was incomplete: it only implemented the x25519 part. Following https://www.ietf.org/archive/id/draft-tls-westerbaan-xyber768d00-03.html is quite straightforward. It is mainly a matter of calling Kyber768.keygen and Kyber768.dec in the right functions, which is implemented in chall4_tlslite.patch.

With it, running client.py displays:

Kyber will work perfectly fine with system randomness
Generating Kyber private key
Handshake success
Received data:  HTTP/1.1 200 OK
Date: Fri, 01 Mar 2024 22:09:29 GMT
Content-Length: 78
Content-Type: text/plain; charset=utf-8

The flag is: 5443184089537ac26d77f5605e1d0c8271597ca097ef1b40be77c7a7bbd62d90

#![allow(non_snake_case, unused)]
use std::fmt;
use std::ops::{Add, AddAssign, Mul, Sub, SubAssign};
use std::str::FromStr;
// Parameters
const BABY_KYBER_K: u32 = 2;
const BABY_KYBER_N: usize = 16;
const BABY_KYBER_Q: u8 = 251;
/// Field element modulo BABY_KYBER_Q
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
struct Field(pub u8);
impl Field {
pub fn zero() -> Self {
Field(0)
}
}
impl Field {
pub fn is_off_by_one(&self, other: &Field) -> bool {
self.0 == other.0 || self.0 == other.0 + 1 || self.0 + 1 == other.0
}
}
impl AsRef<Field> for Field {
fn as_ref(&self) -> &Field {
self
}
}
impl From<u8> for Field {
fn from(value: u8) -> Field {
assert!(value < BABY_KYBER_Q);
Field(value)
}
}
impl fmt::Display for Field {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl<T1> AddAssign<T1> for Field
where
T1: AsRef<Field>,
{
fn add_assign(&mut self, rhs: T1) {
let result: u16 = (self.0 as u16 + rhs.as_ref().0 as u16) % (BABY_KYBER_Q as u16);
self.0 = result as u8;
}
}
impl<'a> SubAssign<&'a Field> for Field {
fn sub_assign(&mut self, rhs: &'a Field) {
let result: u16 =
(self.0 as u16 + BABY_KYBER_Q as u16 - rhs.0 as u16) % (BABY_KYBER_Q as u16);
self.0 = result as u8;
}
}
impl SubAssign for Field {
#[inline]
fn sub_assign(&mut self, rhs: Field) {
*self -= &rhs;
}
}
impl<T> Mul<T> for &Field
where
T: AsRef<Field>,
{
type Output = Field;
fn mul(self, rhs: T) -> Self::Output {
let result: u16 = (self.as_ref().0 as u16 * rhs.as_ref().0 as u16) % (BABY_KYBER_Q as u16);
Field(result as u8)
}
}
impl<T> Mul<T> for Field
where
T: AsRef<Field>,
{
type Output = Field;
fn mul(self, rhs: T) -> Self::Output {
&self * rhs
}
}
/// polynomial of degree BABY_KYBER_N using field elements modulo BABY_KYBER_Q
#[derive(Debug, Default, Clone, PartialEq, Eq)]
struct Poly {
pub coeffs: [Field; BABY_KYBER_N],
}
impl Poly {
pub fn from_str(s: &str) -> Self {
let mut coeffs = [Field::zero(); BABY_KYBER_N];
for term in s.split("+") {
let coeff_str: &str;
let exp: usize;
if term.ends_with("}") {
let parts: Vec<&str> = term[..term.len() - 1].split("x^{").collect();
coeff_str = parts[0];
exp = usize::from_str(parts[1]).expect("usize::from_str");
} else if term.ends_with("x") {
coeff_str = &term[..term.len() - 1];
exp = 1;
} else {
coeff_str = term;
exp = 0;
}
assert!(exp < 16);
assert_eq!(coeffs[exp].0, 0);
let coeff: u8 = u8::from_str(coeff_str).expect("u8::from_str");
coeffs[exp] = coeff.into();
}
Poly { coeffs }
}
pub fn from_canonical_str(s: &str) -> Self {
let poly = Poly::from_str(s);
assert_eq!(poly.to_string(), s);
poly
}
pub fn scale(&self, factor: Field) -> Poly {
Poly {
coeffs: self.coeffs.map(|c| c * factor),
}
}
pub fn is_off_by_one(&self, other: &Poly) -> bool {
for exp in 0..BABY_KYBER_N {
if !self.coeffs[exp].is_off_by_one(&other.coeffs[exp]) {
return false;
}
}
true
}
}
impl AsRef<Poly> for Poly {
fn as_ref(&self) -> &Poly {
self
}
}
impl fmt::Display for Poly {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut is_first: bool = true;
for exp in (0..BABY_KYBER_N).rev() {
let coeff = self.coeffs[exp];
if coeff.0 != 0 {
if is_first {
is_first = false;
} else {
write!(f, "+")?;
}
write!(f, "{coeff}")?;
if exp >= 2 {
write!(f, "x^{{{exp}}}")?;
} else if exp == 1 {
write!(f, "x")?;
}
}
}
if is_first {
write!(f, "0")?;
}
Ok(())
}
}
impl<T> AddAssign<T> for Poly
where
T: AsRef<Poly>,
{
fn add_assign(&mut self, rhs: T) {
for exp in 0..BABY_KYBER_N {
self.coeffs[exp] += rhs.as_ref().coeffs[exp];
}
}
}
impl<T> Add<T> for &Poly
where
T: AsRef<Poly>,
{
type Output = Poly;
#[inline]
fn add(self, rhs: T) -> Self::Output {
let mut result = self.clone();
result += rhs;
result
}
}
impl<T> Add<T> for Poly
where
T: AsRef<Poly>,
{
type Output = Poly;
#[inline]
fn add(self, rhs: T) -> Self::Output {
&self + rhs
}
}
impl<T> SubAssign<T> for Poly
where
T: AsRef<Poly>,
{
fn sub_assign(&mut self, rhs: T) {
for exp in 0..BABY_KYBER_N {
self.coeffs[exp] -= rhs.as_ref().coeffs[exp];
}
}
}
impl<T> Sub<T> for &Poly
where
T: AsRef<Poly>,
{
type Output = Poly;
#[inline]
fn sub(self, rhs: T) -> Self::Output {
let mut result = self.clone();
result -= rhs;
result
}
}
impl<T> Sub<T> for Poly
where
T: AsRef<Poly>,
{
type Output = Poly;
#[inline]
fn sub(self, rhs: T) -> Self::Output {
&self - rhs
}
}
impl<T> Mul<T> for &Poly
where
T: AsRef<Poly>,
{
type Output = Poly;
fn mul(self, rhs: T) -> Self::Output {
// Polynomials are modulo x^N + 1
let mut result = Poly::default();
for (exp1, coeff1) in self.coeffs.iter().enumerate() {
for (exp2, coeff2) in rhs.as_ref().coeffs.iter().enumerate() {
let c = coeff1 * coeff2;
let exp = exp1 + exp2;
if exp < BABY_KYBER_N {
result.coeffs[exp] += c;
} else {
result.coeffs[exp - BABY_KYBER_N] -= c;
}
}
}
result
}
}
impl<T> Mul<T> for Poly
where
T: AsRef<Poly>,
{
type Output = Poly;
#[inline]
fn mul(self, rhs: T) -> Self::Output {
&self * rhs
}
}
#[derive(Debug, Default, Clone)]
struct PolyVec2(pub [Poly; 2]);
impl PolyVec2 {
pub fn is_off_by_one(&self, other: &PolyVec2) -> bool {
self.0[0].is_off_by_one(&other.0[0]) && self.0[1].is_off_by_one(&other.0[1])
}
}
impl AsRef<PolyVec2> for PolyVec2 {
fn as_ref(&self) -> &PolyVec2 {
self
}
}
impl fmt::Display for PolyVec2 {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "[{}, {}]", self.0[0], self.0[1])
}
}
impl<T> Add<T> for &PolyVec2
where
T: AsRef<PolyVec2>,
{
type Output = PolyVec2;
fn add(self, rhs: T) -> Self::Output {
PolyVec2([
&self.0[0] + &rhs.as_ref().0[0],
&self.0[1] + &rhs.as_ref().0[1],
])
}
}
impl<T> Sub<T> for &PolyVec2
where
T: AsRef<PolyVec2>,
{
type Output = PolyVec2;
fn sub(self, rhs: T) -> Self::Output {
PolyVec2([
&self.0[0] - &rhs.as_ref().0[0],
&self.0[1] - &rhs.as_ref().0[1],
])
}
}
/// 2x2 Matrix:
/// [m0 m1]
/// [m2 m3]
#[derive(Debug, Default, Clone)]
struct PolyMat2x2(pub [Poly; 4]);
impl AsRef<PolyMat2x2> for PolyMat2x2 {
fn as_ref(&self) -> &PolyMat2x2 {
self
}
}
impl<T> Mul<T> for &PolyMat2x2
where
T: AsRef<PolyVec2>,
{
type Output = PolyVec2;
fn mul(self, rhs: T) -> Self::Output {
PolyVec2([
&self.0[0] * &rhs.as_ref().0[0] + &self.0[1] * &rhs.as_ref().0[1],
&self.0[2] * &rhs.as_ref().0[0] + &self.0[3] * &rhs.as_ref().0[1],
])
}
}
fn main() {
let A1 = Poly::from_canonical_str("195x^{15}+229x^{14}+25x^{13}+88x^{12}+5x^{11}+209x^{10}+91x^{9}+209x^{8}+189x^{7}+122x^{6}+34x^{5}+39x^{4}+194x^{3}+3x^{2}+198x+180");
let A2 = Poly::from_canonical_str("187x^{15}+83x^{14}+58x^{13}+30x^{12}+77x^{11}+138x^{10}+71x^{9}+212x^{8}+11x^{7}+73x^{6}+24x^{5}+222x^{4}+8x^{3}+105x^{2}+246x+229");
let A3 = Poly::from_canonical_str("84x^{15}+95x^{14}+224x^{13}+177x^{12}+43x^{11}+155x^{10}+63x^{9}+246x^{8}+232x^{7}+177x^{6}+53x^{5}+243x^{4}+41x^{3}+111x^{2}+73x+234");
let A4 = Poly::from_canonical_str("3x^{15}+85x^{14}+143x^{13}+51x^{12}+177x^{11}+116x^{10}+247x^{9}+222x^{8}+181x^{7}+33x^{6}+78x^{5}+196x^{4}+188x^{3}+216x^{2}+170x+64");
let A = PolyMat2x2([A1.clone(), A2.clone(), A3.clone(), A4.clone()]);
let t1 = Poly::from_canonical_str("109x^{15}+188x^{14}+107x^{13}+177x^{12}+240x^{11}+205x^{10}+22x^{9}+134x^{8}+174x^{7}+243x^{6}+36x^{5}+215x^{4}+114x^{3}+210x^{2}+145x+9");
let t2 = Poly::from_canonical_str("198x^{15}+159x^{14}+120x^{13}+184x^{12}+217x^{11}+224x^{10}+96x^{9}+124x^{8}+30x^{7}+155x^{6}+247x^{5}+34x^{4}+224x^{3}+154x^{2}+240x+235");
let t = PolyVec2([t1.clone(), t2.clone()]);
let u1 = Poly::from_canonical_str("49x^{15}+118x^{14}+243x^{13}+19x^{12}+124x^{11}+37x^{10}+121x^{9}+30x^{8}+86x^{7}+34x^{6}+218x^{5}+5x^{4}+198x^{3}+248x^{2}+227x+49");
let u2 = Poly::from_canonical_str("41x^{15}+70x^{14}+147x^{13}+28x^{12}+218x^{11}+224x^{10}+82x^{9}+128x^{8}+141x^{7}+85x^{6}+141x^{5}+70x^{4}+199x^{3}+242x^{2}+190x+112");
let u = PolyVec2([u1.clone(), u2.clone()]);
let v = Poly::from_canonical_str(&"78x^{15} +206 x^{14} +72 x^{13} +81 x^{12} +165 x^{11} +80 x^{10} +86 x^{9} +16 x^{8} +34 x^{7} +96 x^{6} +189 x^{5} +232 x^{4} +121 x^{3} +77 x^{2} +156 x +29".replace(" ", ""));
// Self-check for the custom implementation
let test1 = Poly::from_canonical_str("10x^{2}");
let test2 = Poly::from_canonical_str("5x^{3}");
assert_eq!((&test1 + &test2).to_string(), "5x^{3}+10x^{2}");
assert_eq!((&test1 * &test2).to_string(), "50x^{5}");
assert_eq!(
(&Poly::from_canonical_str("1x^{15}") * &Poly::from_canonical_str("1x")).to_string(),
"250"
);
let test3 = Poly::from_canonical_str("2x^{15}");
assert_eq!((&test1 * &test3).to_string(), "231x");
// Brute-force by splitting s in two 16-bit parts
let mut s_poly = Poly::default();
let mut A1_s = vec![Poly::default(); 0x10000];
let mut t1_sub_A2_s = vec![Poly::default(); 0x10000];
println!("Computing 2 tables");
for test_s in 0..=0xffffu16 {
for exp in 0..16 {
s_poly.coeffs[exp].0 = ((test_s >> exp) & 1) as u8;
}
A1_s[test_s as usize] = &A1 * &s_poly;
t1_sub_A2_s[test_s as usize] = &t1 - &(&A2 * &s_poly);
}
println!("Comparing 2 tables");
let mut test_s1 = 0;
let mut test_s2 = 0;
for idx1 in 0..=0xffffusize {
for idx2 in 0..=0xffffusize {
if A1_s[idx1].is_off_by_one(&t1_sub_A2_s[idx2]) {
println!("Brute split {:#x} {:#x}", idx1, idx2);
// => FOUND : Brute split 0xc8df 0xe9d1
test_s1 = idx1;
test_s2 = idx2;
}
}
}
let mut s = PolyVec2::default();
for exp in 0..16 {
s.0[0].coeffs[exp].0 = ((test_s1 >> exp) & 1) as u8;
s.0[1].coeffs[exp].0 = ((test_s2 >> exp) & 1) as u8;
}
println!("s = {}", s);
// Display error too
let As = &A * &s;
println!("(As-t)_1 = {}", &As.0[0] - &t1);
println!("(As-t)_2 = {}", &As.0[1] - &t2);
assert!(As.is_off_by_one(&t));
/*
* u= A^{T}r + e1 is a Vector
* v= t^{T}r + e2 + \frac{q-1}{2}m is a polynom
* t = As + e so t^{T} = s^{T}A^{T} + e^{T}
* v = (s^{T}A^{T} + e^{T})r + e2 + \frac{q-1}{2}m
* v = s^{T}(u - e1) + e^{T}r + e2 + \frac{q-1}{2}m
* \frac{q-1}{2}m = v - s^{T}u + s^{T}e1 - e^{T}r - e2 -> this is m_n
*/
let e = &t - &As;
println!("e = {}", e);
let m_n = &v - &(&s.0[0] * &u1 + &s.0[1] * &u2);
println!("m_n = {}", m_n);
let m = m_n.coeffs.map(|c| {
if c.0 <= BABY_KYBER_Q / 4 || c.0 >= BABY_KYBER_Q - BABY_KYBER_Q / 4 {
0u8
} else {
1
}
});
println!("m = {:?}", m); // m = [1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1]
let flag = m
.iter()
.rev()
.map(u8::to_string)
.collect::<Vec<String>>()
.join("");
println!("flag = {}", flag); // flag = 1000111001101001
}
#!/usr/bin/env python3
import itertools
import random
import pandas as pd
from sklearn.linear_model import LogisticRegression
# Documentation: https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html
data = pd.read_csv('CTF-RWPQC2024/challenges/challenge2_CSVs/attacker_knowledge.csv')
# This comes from trained_LR_model.csv
target = [-1.81221, -0.17712, 0.01645, 0.12364, 0.5087, 0.11951, -0.30854, 0.19131, -0.04101, 0.33326, 0.32693, 0.0108, 0.11717, -0.22978, -0.1914, 0.13909, -0.22088]
# Use a scaled target to compare integers
scaled_target = [round(t * 1e5) for t in target]
assert all(("%.07f" % t) == ("%.07f" % (st * 1e-5)) for t, st in zip(target, scaled_target))
def try_values(values):
"""Try adding the given line to the data set and train with it"""
values = values.copy()
X = data.iloc[:,:16].copy()
X.loc[499] = values[:16]
assert X.iloc[499, 0] == values[0]
assert X.iloc[499, 8] == values[8]
y = data.iloc[:,16].copy()
y[499] = values[16]
assert len(y) == 500
classifier = LogisticRegression(penalty="l2", C=1.0, solver="lbfgs", max_iter=10000, tol=1e-6)
classifier.fit(X, y)
return [classifier.intercept_[0], *[classifier.coef_[0, i] for i in range(16)]]
# Record best values for a given target
best_for_y = {0: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0], 1: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1]}
delta_for_best = {0: 1e20, 1: 1e20}
verbose_count = 0
def dist_coeffs(result):
"""Compute the distance between the result and the target"""
# Norm 2, but keeps low digits
#return sum((r*1000. - t*1000.)**2 for r, t in zip(result, target))
# Norm 1 between integer values
return sum(abs(round(r * 1e5) - st) for r, st in zip(result, scaled_target))
def try_values_dist(values):
"""Try adding the given line to the data set and train with it and compare with target"""
result = try_values(values)
delta = dist_coeffs(result)
y = values[16]
if delta < delta_for_best[y]:
print(f"Using new best<{y}> ({delta}): {values}")
best_for_y[y] = values.copy()
delta_for_best[y] = delta
else:
global verbose_count
verbose_count += 1
if verbose_count >= 2000:
print(f"Tried<{y}> ({delta}): {values}", end=" \r")
verbose_count = 0
return delta
def iter_approx():
for y in (0, 1):
values = best_for_y[y]
print(f"iter_approx {y}...")
for col in list(itertools.chain(range(15, -1, -1), range(16))) * 2:
min_delta = None
val_min = None
for val in range(-16, 17):
values[col] = val
delta = try_values_dist(values.copy())
# print(col, val, values, delta)
if min_delta is None or delta < min_delta:
min_delta = delta
val_min = val
values[col] = val_min
def random_approx(y):
assert y in {0, 1}
while True:
col1 = random.randint(0, 15)
col2 = random.randint(0, 15)
val1 = random.randint(-16, 16)
val2 = random.randint(-16, 16)
values = best_for_y[y].copy()
values[col1] = val1
values[col2] = val2
try_values_dist(values)
def random_walk():
print("Start random walking")
while True:
y = random.randint(0, 1)
col1 = random.randint(0, 15)
col2 = random.randint(0, 15)
col3 = random.randint(0, 15)
col4 = random.randint(0, 15)
col5 = random.randint(0, 15)
d1 = random.randint(-1, 1)
d2 = random.randint(-1, 1)
d3 = random.randint(-1, 1)
d4 = random.randint(-1, 1)
d5 = random.randint(-1, 1)
values = best_for_y[y].copy()
values[col1] = max(-16, min(16, values[col1] + d1))
values[col2] = max(-16, min(16, values[col2] + d2))
values[col3] = max(-16, min(16, values[col3] + d3))
values[col4] = max(-16, min(16, values[col4] + d4))
values[col5] = max(-16, min(16, values[col5] + d5))
try_values_dist(values)
def walk_plusmintwo():
for y in (0, 1):
print(f"Start walking +-2 for y={y} ")
for col1 in range(16):
for col2 in range(col1 + 1, 16):
for col3 in range(col2 + 1, 16):
for d1 in range(-2, 3):
for d2 in range(-2, 3):
for d3 in range(-2, 3):
values = best_for_y[y].copy()
values[col1] = max(-16, min(16, values[col1] + d1))
values[col2] = max(-16, min(16, values[col2] + d2))
values[col3] = max(-16, min(16, values[col3] + d3))
try_values_dist(values)
def walk_plusminone():
for y in (0, 1):
print(f"Start walking +-1 for y={y} ")
for col1 in range(16):
for col2 in range(col1 + 1, 16):
for col3 in range(col2 + 1, 16):
for col4 in range(col3 + 1, 16):
for col5 in range(col4 + 1, 16):
for col6 in range(col5 + 1, 16):
for d1 in (-1, 0, 1):
for d2 in (-1, 0, 1):
for d3 in (-1, 0, 1):
for d4 in (-1, 0, 1):
for d5 in (-1, 0, 1):
for d6 in (-1, 0, 1):
values = best_for_y[y].copy()
values[col1] = max(-16, min(16, values[col1] + d1))
values[col2] = max(-16, min(16, values[col2] + d2))
values[col3] = max(-16, min(16, values[col3] + d3))
values[col4] = max(-16, min(16, values[col4] + d4))
values[col5] = max(-16, min(16, values[col5] + d5))
values[col6] = max(-16, min(16, values[col6] + d6))
#print(col1, col2, col3, col4, col5, col6, d1, d2, d3, d4, d5, d6)
#print(values)
try_values_dist(values)
# Some values obtained by iterative bruteforcing
try_values_dist([4, 12, 5, -3, -12, 9, -5, -15, 15, 16, -12, 0, 10, 0, -11, -13, 0])
try_values_dist([2, 14, 4, -3, -13, 13, -3, -16, 16, 14, -12, 1, 7, 1, -10, -14, 0])
try_values_dist([3, 12, 4, -3, -12, 10, -5, -16, 16, 16, -13, 0, 10, 1, -10, -13, 0])
try_values_dist([4, 14, 4, -2, -13, 11, -5, -16, 16, 16, -13, 0, 11, 1, -10, -14, 0])
try_values_dist([3, 14, 4, -2, -13, 11, -6, -16, 16, 16, -12, 0, 10, 2, -10, -14, 0])
try_values_dist([3, 14, 4, -2, -12, 11, -5, -16, 15, 16, -12, 0, 10, 2, -10, -14, 0])
try_values_dist([3, 14, 4, -2, -12, 12, -5, -16, 16, 16, -12, 0, 10, 1, -10, -13, 0])
try_values_dist([3, 14, 4, -3, -13, 11, -5, -16, 16, 16, -12, 0, 9, 1, -11, -14, 0])
try_values_dist([16, -16, -5, -16, 16, -2, 16, 13, -2, 3, 16, 9, -6, -16, 16, 5, 1])
try_values_dist([16, -16, -5, -16, 16, -2, 16, 13, -1, 4, 16, 7, -5, -16, 16, 6, 1])
try_values_dist([16, -16, -5, -16, 16, -2, 16, 13, -1, 3, 16, 8, -5, -16, 16, 5, 1])
try_values_dist([16, -16, -5, -15, 16, -2, 16, 14, -2, 4, 16, 8, -4, -16, 16, 6, 1])
try_values_dist([16, -16, -5, -16, 16, -3, 16, 14, -1, 4, 16, 8, -4, -16, 16, 6, 1])
try_values_dist([7, -16, -14, -16, 16, -4, 15, 16, 5, 15, 15, -4, -1, -5, 12, 11, 1])
try_values_dist([7, -16, -14, -16, 16, -4, 15, 16, 6, 15, 15, -4, -1, -5, 13, 13, 1])
def show_best():
result0 = try_values(best_for_y[0])
result1 = try_values(best_for_y[1])
d_result0 = dist_coeffs(result0)
d_result1 = dist_coeffs(result1)
print(f"Current best[y=0]: {best_for_y[0]} # {d_result0}")
print(f"Current best[y=1]: {best_for_y[1]} # {d_result1}")
print("")
print("idx target coeff(y=0) (delta) coeff(y=1) (delta)")
for idx in range(17):
t = target[idx]
r0 = result0[idx]
r1 = result1[idx]
st = scaled_target[idx]
assert st == round(t * 1e5)
d0 = round(r0 * 1e6) / 10. - st
d1 = round(r1 * 1e6) / 10. - st
print(f"{idx:2d} {target[idx]:10.6f} {result0[idx]:10.6f} ({d0:7.1f}) {result1[idx]:10.6f} ({d1:7.1f})")
print("")
show_best()
# Brute-force things
# random_approx(0)
# iter_approx()
# walk_plusminone()
# walk_plusmintwo()
#random_walk()
diff --git a/src/common/rand/rand.c b/src/common/rand/rand.c
index b48d8030d3ed..f11e0ebb3c49 100644
--- a/src/common/rand/rand.c
+++ b/src/common/rand/rand.c
@@ -25,11 +25,19 @@ void OQS_randombytes_openssl(uint8_t *random_array, size_t bytes_to_read);
#ifdef OQS_USE_OPENSSL
#include <openssl/rand.h>
// Use OpenSSL's RAND_bytes as the default PRNG
-static void (*oqs_randombytes_algorithm)(uint8_t *, size_t) = &OQS_randombytes_openssl;
+//static void (*oqs_randombytes_algorithm)(uint8_t *, size_t) = &OQS_randombytes_openssl;
#else
-static void (*oqs_randombytes_algorithm)(uint8_t *, size_t) = &OQS_randombytes_system;
+//static void (*oqs_randombytes_algorithm)(uint8_t *, size_t) = &OQS_randombytes_system;
#endif
+
+void OQS_randombytes_nist_kat(unsigned char *x, size_t xlen);
+static void (*oqs_randombytes_algorithm)(uint8_t *, size_t) = &OQS_randombytes_nist_kat;
+
OQS_API OQS_STATUS OQS_randombytes_switch_algorithm(const char *algorithm) {
+ if (0 == strcasecmp("NIST-KAT", algorithm)) {
+ oqs_randombytes_algorithm = &OQS_randombytes_nist_kat;
+ return OQS_SUCCESS;
+ }
if (0 == strcasecmp(OQS_RAND_alg_system, algorithm)) {
oqs_randombytes_algorithm = &OQS_randombytes_system;
return OQS_SUCCESS;
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <oqs/oqs.h>
#include <oqs/rand_nist.h>
#include <string.h>
static OQS_KEM *kem;
static uint8_t public_key_srv[5000];
static uint8_t secret_key_srv[5000];
#include "chall3b_data.h"
// Change this to choose which seed to brute-force
#ifndef CURRENT
#define CURRENT 1
#endif
#define concat_(a, b) a##b
#define concat(a, b) concat_(a, b)
#define PUBKEY concat(PUBKEY_, CURRENT)
#define CT concat(CT_, CURRENT)
static void bf_seed(uint8_t *orig_seed, unsigned int position) {
unsigned int i;
if (position == 0x20) {
printf("Testing...");
for (i = 0; i < 0x20; i++) {
printf("%02x", orig_seed[i]);
}
}
printf("\r");
if (position < 0x30) {
orig_seed[position] = 0;
bf_seed(orig_seed, position + 1);
orig_seed[position] = 1;
bf_seed(orig_seed, position + 1);
return;
}
// liboqs has been patched
int res = OQS_randombytes_switch_algorithm("NIST-KAT");
if (res != 0) {
printf("\nOQS_randombytes_switch_algorithm failed\n");
exit(1);
}
OQS_randombytes_nist_kat_init_256bit(orig_seed, 0);
OQS_KEM_keypair(kem, public_key_srv, secret_key_srv);
if (!memcmp(PUBKEY, public_key_srv, sizeof(PUBKEY))) {
printf("\nFOUND pubkey: ");
for (i = 0; i < 0x30; i++) {
printf("%02x", orig_seed[i]);
}
printf("\n");
uint8_t shared_secret[50] = {};
OQS_KEM_decaps(kem, shared_secret, CT, secret_key_srv);
printf("\nFOUND shared_secret = ");
for (i = 0; i < 0x30; i++) {
if (i >= 0x20) {
assert(shared_secret[i] == 0);
continue;
}
printf("%02x", shared_secret[i]);
}
printf("\n");
}
}
int main(void) {
if (sizeof(PUBKEY) == sizeof(PUBKEY_1)) {
kem = OQS_KEM_kyber_512_new();
} else if (sizeof(PUBKEY) == sizeof(PUBKEY_2)) {
kem = OQS_KEM_kyber_768_new();
} else if (sizeof(PUBKEY) == sizeof(PUBKEY_3)) {
kem = OQS_KEM_kyber_1024_new();
}
assert(kem->length_public_key == sizeof(PUBKEY));
assert(kem->length_public_key < sizeof(public_key_srv));
assert(kem->length_secret_key < sizeof(secret_key_srv));
uint8_t orig_seed[0x30] = {};
bf_seed(orig_seed, 0x18);
return 0;
}
static const uint8_t PUBKEY_1[800] = {0x4f, 0xa6, 0x1e, 0x20, 0x97, 0x84, 0x18, 0x14, 0xc1, 0x3f, 0xd3, 0x90, 0xb1, 0xa7, 0xb0, 0xdc, 0x67, 0xce, 0x68, 0x52, 0x41, 0x9c, 0x78, 0xc5, 0x81, 0x6a, 0x8e, 0xe4, 0xd6, 0xaa, 0x16, 0xdc, 0x52, 0x50, 0x98, 0x12, 0xb5, 0x33, 0x58, 0x84, 0x33, 0x71, 0xac, 0x5c, 0x5e, 0x44, 0x0a, 0x43, 0xc4, 0x88, 0x57, 0xf8, 0xe4, 0x71, 0x85, 0xaa, 0x8d, 0xca, 0x69, 0xc8, 0xce, 0x22, 0xae, 0xa1, 0x02, 0xb1, 0x80, 0xc4, 0x25, 0x06, 0x0c, 0x8a, 0x07, 0x8b, 0x35, 0xa5, 0x7c, 0x8c, 0xb5, 0x33, 0x16, 0x7a, 0x5a, 0x57, 0x68, 0x5c, 0x4e, 0x79, 0x1b, 0x78, 0xac, 0x5a, 0x88, 0x5b, 0x5b, 0x18, 0x8b, 0xa5, 0x4a, 0x83, 0x5b, 0x97, 0xed, 0xa0, 0x15, 0xe7, 0x8b, 0xbe, 0xe7, 0x31, 0x02, 0x77, 0xfc, 0x86, 0x51, 0xa5, 0x18, 0x81, 0xdb, 0x85, 0x07, 0xe6, 0xb9, 0xdc, 0xe2, 0x44, 0xc9, 0x45, 0x41, 0xe6, 0xe9, 0xbf, 0xd3, 0x37, 0xb2, 0x30, 0xba, 0x94, 0x3c, 0x8b, 0x6c, 0xd3, 0xc9, 0x50, 0x3a, 0xf5, 0x40, 0x12, 0x41, 0x50, 0xe5, 0xb8, 0x2c, 0x36, 0x5c, 0x99, 0xdb, 0xb3, 0x0f, 0xe8, 0x18, 0x43, 0x9f, 0x3b, 0x45, 0x3b, 0x99, 0xa4, 0x18, 0xb2, 0x76, 0x05, 0xb6, 0xc4, 0x59, 0x9b, 0x98, 0xfa, 0x30, 0x67, 0xf3, 0x63, 0x31, 0xd3, 0x5a, 0x1c, 0x80, 0x87, 0x63, 0xca, 0xc8, 0x4f, 0x47, 0x30, 0xa4, 0x88, 0x21, 0x02, 0x9c, 0x78, 0x3e, 0x09, 0xc2, 0xb9, 0x3a, 0x7c, 0x67, 0xcf, 0xdc, 0xcc, 0xed, 0x1c, 0x6d, 0x3d, 0x1a, 0x91, 0x90, 0xfb, 0x91, 0xe3, 0x17, 0x86, 0x5c, 0xfb, 0xb1, 0xaa, 0x57, 0x37, 0x8a, 0x71, 0x55, 0x23, 0x9a, 0xcf, 0xca, 0x48, 0x8d, 0x3c, 0x62, 0x93, 0x3d, 0xf8, 0x02, 0x08, 0xc0, 0x00, 0x21, 0x28, 0x0c, 0x3f, 0xa4, 0xc9, 0x3d, 0x05, 0x5f, 0x7f, 0x4c, 0xbc, 0xae, 0x46, 0x4b, 0x45, 0xe2, 0x3c, 0x1e, 0x73, 0xba, 0x5b, 0x90, 0xb3, 0x87, 0x13, 0x59, 0x3d, 0xa9, 0x12, 0x79, 0x12, 0x9a, 0x4e, 0xec, 0xba, 0x40, 0x64, 0x9d, 0x35, 0xa7, 0x15, 0x7e, 0x92, 0x5f, 0x40, 0xa5, 0x5a, 0x64, 0x96, 0x10, 0x2d, 0xcc, 0xc4, 0x07, 0x46, 0x90, 0xe5, 0x08, 0xad, 0x0a, 0x89, 0x50, 0x4b, 0x08, 0x2c, 0x8b, 0x2b, 0x3d, 0xcf, 0xdc, 0x29, 0xa3, 0x73, 0x03, 0x15, 0x7a, 0x7d, 0x35, 0xcb, 0x02, 0xb8, 0x8c, 0x4a, 0xfb, 0x24, 0x24, 0x75, 0xeb, 0x62, 0x39, 0xf7, 0x8c, 0x0e, 0x12, 0x8f, 0x65, 0xc9, 0x08, 0x97, 0x8b, 0x28, 0x97, 0x06, 0x69, 0xb5, 0xb1, 0xcb, 0xf7, 0xfc, 0x40, 0xe7, 0x75, 0x67, 0x64, 0x46, 0x08, 0x8c, 0x58, 0x17, 0xfd, 0xc4, 0x0a, 0xf3, 0xc5, 0x9e, 0x02, 0x45, 0x06, 0x7f, 0x77, 0x5a, 0xef, 0x63, 0x31, 0x67, 0x80, 0x2a, 0x3f, 0xdb, 0x08, 0x8b, 0x45, 0x0b, 0xa7, 0x2b, 0x05, 0x92, 0x0a, 0x70, 0x91, 0xe2, 0x18, 0xd6, 0x71, 0x7d, 0x52, 0x46, 0x07, 0x4f, 0x5c, 0xcd, 0x73, 0x98, 0x63, 0xf3, 0xe4, 0x9c, 0x0b, 0x10, 0xbc, 0xe8, 0xc4, 0x7b, 0xf2, 0x03, 0x28, 0xfe, 0xd6, 0xb6, 0x41, 0x75, 0xaf, 0x7b, 0x0a, 0xcc, 0x1c, 0xac, 0xa9, 0x7d, 0xf6, 0x07, 0x49, 0x40, 0x8c, 0xa1, 0x62, 0x37, 0x2f, 0x3b, 0xb0, 0x89, 0x57, 0x94, 0x61, 0x79, 0x37, 0x2f, 0x26, 0x8e, 0xd2, 0x4a, 0x65, 0xf1, 0x19, 0x1c, 0x6e, 0xe8, 0xb6, 0x2f, 0x9c, 0xc2, 0xe7, 0xcb, 0x37, 0xb2, 0x11, 0xc7, 0x24, 0x20, 0x3f, 0x04, 0x36, 0xb2, 0x52, 0x90, 0x6d, 0x14, 0x67, 0xbb, 0x95, 0x37, 0xcf, 0x0a, 0x36, 0x6e, 0x8a, 0x4a, 0x26, 0x41, 0x19, 0x87, 0xcc, 0x30, 0x23, 0xef, 0x71, 0x92, 0x5c, 0x46, 0x01, 0x64, 0xe7, 0x29, 0x72, 0x07, 0x93, 0xad, 0x77, 0xca, 0x23, 0x41, 0x4f, 0xe5, 0xd6, 0x54, 0xe8, 0x02, 0x06, 0x1b, 0x04, 0x58, 0x22, 0x04, 0x40, 0xb4, 0x25, 0x97, 0xab, 0x60, 0x0b, 0x19, 0x6a, 0x77, 0x62, 0xc8, 0xb4, 0xa1, 0xc1, 0x49, 0xb4, 0x13, 0x72, 0x4c, 0x48, 0x78, 0x47, 0x38, 0x4d, 0xa9, 0x83, 0xa0, 0xa3, 0xb8, 0x5c, 0x81, 0x8c, 0x31, 0x5c, 0xf4, 0x05, 0xef, 0x87, 0x08, 0x1f, 0x37, 0x17, 0x4e, 0x92, 0x01, 0x1f, 0x62, 0x29, 0x7b, 0x36, 0x26, 0xb5, 0x52, 0xb2, 0x1a, 0x7b, 0x66, 0xa6, 0xc6, 0x65, 0x60, 0x81, 0x98, 0x19, 0xf1, 0x8c, 0x3f, 0x31, 0x8c, 0x0e, 0xe0, 0x83, 0x8f, 0x35, 0x19, 0x92, 0x8c, 0xb7, 0x03, 0x6b, 0xbd, 0x11, 0x33, 0x66, 0xb9, 0xac, 0x8f, 0xc0, 0xa9, 0x35, 0x72, 0x28, 0x62, 0x27, 0xb4, 0x1f, 0xc3, 0x37, 0xcd, 0xf8, 0x89, 0x39, 0xe4, 0xcb, 0x5c, 0x5d, 0x60, 0x10, 0x3b, 0xd9, 0x30, 0xd8, 0xa2, 0x40, 0x60, 0x35, 0x7d, 0xc6, 0xf5, 0xae, 0xab, 0x3a, 0xbb, 0x7a, 0xf6, 0x0c, 0x8f, 0x85, 0xab, 0x21, 0xac, 0x99, 0x99, 0xf6, 0x5d, 0x71, 0x89, 0x22, 0x95, 0xa0, 0x81, 0x8c, 0x5c, 0x3c, 0x64, 0xd0, 0xb6, 0xcc, 0x59, 0x7b, 0xcb, 0x10, 0x96, 0xc4, 0xcc, 0xc7, 0xf2, 0xa2, 0xba, 0xb3, 0xf0, 0x4f, 0x7a, 0xf6, 0x6c, 0xbf, 0x45, 0x85, 0x12, 0x49, 0xbe, 0x9e, 0xd4, 0x01, 0x78, 0x79, 0x86, 0x87, 0xfc, 0x05, 0xa1, 0xf2, 0x25, 0xab, 0x58, 0x02, 0x88, 0x32, 0x07, 0x14, 0x14, 0xbc, 0xf2, 0xf8, 0x43, 0x37, 0x2b, 0x88, 0x1b, 0xca, 0xb3, 0x49, 0x23, 0x42, 0x92, 0xe0, 0x1d, 0x82, 0xd6, 0xc0, 0xb2, 0xcc, 0x69, 0x47, 0x66, 0x5c, 0xea, 0xb2, 0xcc, 0xb6, 0xd8, 0x84, 0x83, 0x56, 0x21, 0x9b, 0xe0, 0x02, 0xf4, 0xb9, 0x54, 0x45, 0x57, 0x53, 0x5f, 0x11, 0x48, 0x3e, 0x00, 0x4d, 0x72, 0x12, 0x99, 0xec, 0x84, 0x2a, 0x81, 0xef, 0x3a, 0x90, 0x10, 0x75, 0x8d, 0x61, 0xf8, 0xd4, 0xca, 0xeb, 0xa1, 0x7c, 0xcc, 0xdb, 0xb3, 0xa2, 0x45, 0x98, 0xcb, 0x5b, 0x78};
static const uint8_t PUBKEY_2[1184] = {0x0a, 0x39, 0x2e, 0x98, 0xb9, 0x8d, 0x2e, 0x82, 0x91, 0x7d, 0x2c, 0x8c, 0x97, 0x38, 0xce, 0xba, 0xc3, 0x50, 0x3a, 0x64, 0xaf, 0xc9, 0xf7, 0x84, 0x47, 0x03, 0x9b, 0xa6, 0xa4, 0xb2, 0x95, 0x93, 0x1c, 0x74, 0x09, 0xb4, 0x08, 0x21, 0x09, 0x2b, 0x02, 0xb1, 0x3d, 0x40, 0x6e, 0xf7, 0x7b, 0x18, 0x28, 0xfb, 0xaf, 0x5b, 0x61, 0xa0, 0x5d, 0x43, 0xa3, 0x0d, 0x65, 0x9f, 0xcb, 0x44, 0x67, 0x03, 0x0a, 0xd0, 0x1a, 0x04, 0x3f, 0xa1, 0x56, 0x59, 0xff, 0x8c, 0x90, 0x0c, 0x70, 0x45, 0xae, 0x5c, 0x3d, 0xb2, 0x44, 0xaf, 0x81, 0x55, 0xa0, 0x6c, 0x99, 0x60, 0xd7, 0xb5, 0x23, 0x74, 0xb9, 0x61, 0x63, 0xac, 0x4d, 0x6a, 0xb4, 0x05, 0x00, 0xe6, 0x9f, 0x80, 0x00, 0x98, 0x3f, 0x7a, 0x1f, 0xa0, 0xc2, 0x0a, 0x7d, 0x69, 0x96, 0x12, 0xa4, 0x93, 0x12, 0xd3, 0x69, 0x73, 0xb4, 0x1c, 0xa5, 0x95, 0xc0, 0xa8, 0xa6, 0xc0, 0x6e, 0x0b, 0x43, 0x09, 0xb0, 0x87, 0xa7, 0xa8, 0x3c, 0x1b, 0x32, 0x38, 0x60, 0x33, 0x7c, 0x24, 0xf1, 0x19, 0x8c, 0xb6, 0x65, 0xaf, 0x37, 0x2f, 0xae, 0x75, 0x47, 0x38, 0x6b, 0x8d, 0x32, 0xd8, 0x66, 0x49, 0xd5, 0x33, 0x42, 0x73, 0x7c, 0x9b, 0xf2, 0x87, 0x63, 0xe3, 0x2c, 0x4f, 0xa7, 0xbb, 0x50, 0xd8, 0x59, 0x05, 0xb4, 0x1d, 0x9f, 0x92, 0xc3, 0x19, 0xa3, 0x0b, 0xa4, 0x2a, 0x03, 0xa9, 0xd4, 0x2f, 0x50, 0x54, 0xc6, 0x6c, 0x55, 0xba, 0x9e, 0x67, 0x6b, 0xbd, 0x27, 0x55, 0xac, 0x3c, 0x35, 0x69, 0x26, 0x8c, 0x82, 0x32, 0x68, 0x37, 0xd3, 0x56, 0xb6, 0xc7, 0x02, 0x01, 0xc1, 0x60, 0x1a, 0x83, 0xae, 0xed, 0x7c, 0xcf, 0xed, 0x97, 0x97, 0x09, 0xca, 0x03, 0x5b, 0xb6, 0x4e, 0xab, 0xb7, 0x0c, 0xb2, 0xe9, 0x24, 0x91, 0x38, 0x95, 0x0d, 0xd0, 0xa4, 0x04, 0x18, 0x03, 0xa5, 0x4a, 0xa8, 0xcd, 0xac, 0x48, 0xe9, 0xdc, 0x26, 0x68, 0x09, 0x17, 0xfc, 0x5c, 0x9c, 0x61, 0xcc, 0x94, 0x8a, 0x00, 0x09, 0x75, 0xc6, 0x7a, 0x04, 0x55, 0x01, 0xc8, 0xd4, 0x62, 0x62, 0xfa, 0x4f, 0x2a, 0x44, 0x5f, 0xd3, 0xd7, 0x5e, 0xc2, 0x76, 0xc4, 0x1a, 0x67, 0x4b, 0x71, 0x6b, 0xba, 0x16, 0x7c, 0x8c, 0x4d, 0x12, 0x25, 0x5b, 0xe0, 0x9a, 0x37, 0x08, 0xad, 0x7b, 0xf2, 0xac, 0xf6, 0x4c, 0x15, 0x23, 0x77, 0x17, 0x51, 0xea, 0x16, 0x1f, 0xb7, 0xbe, 0xd7, 0xa5, 0x30, 0x9b, 0x00, 0x9a, 0xcb, 0x96, 0x16, 0x87, 0x4c, 0xb1, 0xeb, 0x12, 0x81, 0x7f, 0x29, 0x49, 0x5b, 0xf4, 0x2a, 0x6a, 0x19, 0x10, 0x27, 0x0b, 0x6e, 0x61, 0xa6, 0x9e, 0xfc, 0xc0, 0x63, 0x73, 0x45, 0x11, 0x8b, 0x03, 0x55, 0xca, 0x7c, 0x60, 0x94, 0x3b, 0x04, 0xe6, 0x0b, 0x29, 0x85, 0x90, 0x2d, 0xb1, 0x43, 0xc2, 0x18, 0xb5, 0x1d, 0x3f, 0xa2, 0x2f, 0x33, 0xf8, 0x12, 0x1f, 0xb0, 0x7e, 0xf8, 0x7a, 0xcf, 0xf2, 0x54, 0x43, 0xa1, 0x4a, 0xb1, 0xdf, 0xe1, 0xaa, 0x8a, 0xa0, 0xab, 0xcf, 0x31, 0x75, 0xbe, 0xd0, 0xa1, 0xc6, 0xd1, 0x91, 0xa8, 0x70, 0x01, 0xa6, 0xca, 0x09, 0xcc, 0x84, 0x4f, 0x1b, 0x63, 0x25, 0x30, 0xc8, 0xbb, 0x20, 0x84, 0x3f, 0xff, 0x78, 0xb5, 0xd4, 0x93, 0x73, 0x41, 0x0c, 0x1e, 0x0e, 0x31, 0x20, 0xa2, 0xd8, 0x44, 0xa8, 0x66, 0x57, 0xb5, 0x46, 0x73, 0x12, 0x22, 0x23, 0xe9, 0x41, 0x86, 0xd7, 0xa9, 0x8a, 0x68, 0xea, 0x4a, 0x45, 0xd8, 0x80, 0x87, 0x19, 0x9e, 0x8b, 0x10, 0x72, 0x20, 0xbb, 0xad, 0xf9, 0xf3, 0xc3, 0xa9, 0x0a, 0xaa, 0xa6, 0x3a, 0x33, 0x16, 0xe4, 0x0e, 0x1e, 0xa6, 0x72, 0x59, 0x04, 0xb1, 0xf4, 0x27, 0x47, 0x28, 0x7a, 0x4c, 0x6e, 0x41, 0x8d, 0x91, 0x37, 0xcc, 0xa2, 0x09, 0x33, 0xc5, 0x50, 0xa3, 0xf4, 0x93, 0x62, 0x14, 0xf2, 0x04, 0x1d, 0x15, 0x03, 0xc3, 0x6a, 0x20, 0x7e, 0x3c, 0xb1, 0x26, 0x4a, 0x79, 0xa1, 0xba, 0x1f, 0xaa, 0x14, 0x95, 0xd4, 0x19, 0x6c, 0x6c, 0x07, 0x47, 0x09, 0xa8, 0x5f, 0xea, 0x78, 0x6e, 0x64, 0x90, 0x7b, 0x64, 0x50, 0xb6, 0xc1, 0xd5, 0xbf, 0x0d, 0xf4, 0x6b, 0xac, 0xb2, 0x92, 0xdb, 0xd8, 0x24, 0xe7, 0x15, 0xad, 0xf4, 0x37, 0xbc, 0xdc, 0x18, 0x61, 0x97, 0xd1, 0x89, 0x3b, 0xf6, 0x3a, 0xab, 0xc1, 0x28, 0xc8, 0x87, 0x0b, 0x70, 0xda, 0x55, 0x74, 0xaa, 0x2e, 0x37, 0x0a, 0x07, 0x2f, 0xc1, 0x90, 0xda, 0xa6, 0x16, 0x48, 0x7c, 0xca, 0xfd, 0xe3, 0x3b, 0xe4, 0x49, 0x8a, 0x02, 0x00, 0x95, 0x59, 0xfc, 0x49, 0x4d, 0x88, 0x7f, 0xa8, 0xac, 0x5f, 0x4e, 0xfb, 0x8e, 0x7c, 0x7a, 0x12, 0x41, 0x01, 0x1a, 0xb5, 0x6c, 0x92, 0xb4, 0xf2, 0xb8, 0xa8, 0x29, 0xcc, 0x42, 0xe5, 0x86, 0xc1, 0x72, 0x1b, 0x7c, 0xf2, 0xc4, 0xa7, 0xe8, 0x5c, 0x6f, 0xf2, 0x22, 0x6b, 0x0a, 0x07, 0x7a, 0x57, 0x49, 0x05, 0x12, 0xae, 0x1c, 0x51, 0xbc, 0x32, 0x90, 0xbc, 0x7d, 0x80, 0xa4, 0x36, 0x53, 0x38, 0x12, 0x31, 0x0a, 0x39, 0xba, 0x4b, 0xb2, 0xb0, 0x3e, 0x99, 0xc5, 0x20, 0xc9, 0x76, 0xce, 0xee, 0xb0, 0x07, 0x10, 0x2b, 0x5a, 0xba, 0xd1, 0x4a, 0xf9, 0x57, 0x34, 0xba, 0xc0, 0x72, 0x02, 0xfc, 0xb7, 0x5a, 0x56, 0x51, 0xff, 0x34, 0x0f, 0x63, 0x65, 0x4b, 0x6f, 0x0c, 0x70, 0x9e, 0x96, 0x6a, 0x89, 0x71, 0x92, 0x99, 0x07, 0xa6, 0x8e, 0x79, 0x98, 0x79, 0x53, 0x1e, 0x8a, 0x75, 0x51, 0x70, 0x14, 0x13, 0x3e, 0x65, 0xaf, 0xc0, 0xdb, 0x9d, 0x1a, 0xf7, 0xcb, 0xfd, 0x08, 0x5a, 0xa5, 0xf6, 0x02, 0x5f, 0x08, 0x8c, 0xe3, 0x02, 0xb8, 0x5d, 0x30, 0x46, 0xd8, 0x46, 0x08, 0xa0, 0x80, 0x0e, 0x58, 0xb6, 0xa6, 0x69, 0x48, 0x46, 0x29, 0x2b, 0x14, 0xe5, 0x88, 0x83, 0x62, 0x59, 0x86, 0xb8, 0x2c, 0xc5, 0x04, 0xda, 0x59, 0x0e, 0x53, 0x80, 0xf0, 0x85, 0x4d, 0xfe, 0x27, 0x50, 0x45, 0xc0, 0x4e, 0xfb, 0xa3, 0x0b, 0x24, 0xb6, 0x4f, 0x73, 0x15, 0x14, 0x1e, 0xd8, 0xa8, 0x93, 0xc9, 0x31, 0xc8, 0xf2, 0x4f, 0x61, 0xd8, 0x00, 0x90, 0x0a, 0xc8, 0xbe, 0x22, 0x8f, 0x7e, 0x14, 0xcc, 0xaa, 0x0a, 0x8b, 0x1c, 0x50, 0xac, 0x2b, 0xc6, 0x6d, 0x17, 0xe1, 0x1c, 0x70, 0xfa, 0x37, 0xea, 0xfa, 0x98, 0x01, 0xcb, 0xad, 0xd6, 0xa0, 0x74, 0x62, 0x30, 0x4a, 0x45, 0x34, 0x50, 0x55, 0x12, 0xc8, 0xab, 0x51, 0x09, 0xcb, 0xf6, 0x89, 0xc6, 0x99, 0x4d, 0xd1, 0x28, 0x73, 0x81, 0x95, 0xb0, 0x48, 0x98, 0x5f, 0x28, 0xec, 0x2a, 0x22, 0x83, 0x38, 0xf4, 0x08, 0x72, 0xae, 0x53, 0x19, 0xda, 0x96, 0xc7, 0x16, 0xb0, 0x2b, 0x3d, 0x84, 0x7e, 0x42, 0x56, 0xcd, 0x94, 0x81, 0x9c, 0x1f, 0xc1, 0x99, 0x98, 0x3b, 0x34, 0x39, 0xda, 0x16, 0x1a, 0x67, 0x0a, 0x35, 0xf1, 0x2e, 0xef, 0x18, 0x93, 0xcc, 0x29, 0xa0, 0x7a, 0x25, 0xb6, 0x2e, 0x29, 0xb0, 0x90, 0xca, 0x81, 0x75, 0x91, 0x8c, 0x74, 0x75, 0xbd, 0xaa, 0x41, 0x87, 0xdb, 0x7a, 0x57, 0xfc, 0x50, 0x35, 0x96, 0xfa, 0x5d, 0x7d, 0xc7, 0x97, 0x59, 0x18, 0x7d, 0x9e, 0xda, 0x5b, 0xd9, 0x55, 0x6f, 0x92, 0x06, 0x98, 0xcc, 0xfb, 0x45, 0xc3, 0x05, 0x21, 0xb8, 0xf4, 0x84, 0xaf, 0x65, 0x30, 0x4a, 0xb3, 0x5f, 0x4c, 0x1a, 0xc5, 0xfd, 0xe9, 0x6a, 0x06, 0x06, 0x49, 0xc2, 0x10, 0x80, 0x23, 0x57, 0x1e, 0x28, 0xa3, 0x06, 0x71, 0xb6, 0x80, 0x52, 0x88, 0xb7, 0xe2, 0x59, 0xa5, 0xf6, 0x37, 0xc7, 0xa7, 0x16, 0x06, 0x3b, 0xf4, 0x03, 0x6f, 0x14, 0xc3, 0xa6, 0x19, 0xbb, 0xca, 0x17, 0xb3, 0xc8, 0xc3, 0xbe, 0x56, 0xb0, 0x74, 0x35, 0x99, 0x1f, 0x1b, 0x51, 0x9d, 0x75, 0x8a, 0x48, 0x33, 0x90, 0x55, 0x6c, 0xe3, 0xc1, 0xf5, 0x73, 0xb6, 0x83, 0x64, 0x64, 0xc5, 0x76, 0xac, 0xdb, 0x80, 0x5f, 0xc0, 0x8c, 0x7b, 0x41, 0x17, 0x49, 0x5f, 0x46, 0x93, 0xfe, 0x96, 0xc8, 0x23, 0xc6, 0x61, 0x96, 0xda, 0x84, 0xf8, 0x90, 0xad, 0x1b, 0x4c, 0xa0, 0x54, 0x33, 0x88, 0xcb, 0x86, 0x7d, 0x3d, 0xc5, 0x79, 0x09, 0x8b, 0x9b, 0x7c, 0x1c, 0x9b, 0x4e, 0x91, 0x8f, 0xbb, 0xb0, 0x21, 0x06, 0x23, 0x76, 0xdf, 0x6c, 0xbf, 0xf5, 0x17, 0x39, 0xe1, 0x6a, 0x57, 0x89, 0xc7, 0x9b, 0xa1, 0x77, 0x8f, 0x3f, 0x3b, 0x59, 0xa5, 0x8a, 0x2c, 0xd2, 0xcb, 0x6c, 0xed, 0x6b, 0xb2, 0x3f, 0x12, 0xd3, 0x7c, 0x22, 0xd8, 0x16, 0x97, 0x2c, 0xc9, 0xa1, 0xca, 0xa2, 0x20, 0xfd, 0xac, 0x33, 0xbc, 0x13, 0xb1, 0x42, 0x19, 0x86, 0x1c, 0x8f, 0x93, 0xe3, 0xe2, 0x07};
static const uint8_t PUBKEY_3[1568] = {0x09, 0x33, 0xb4, 0x63, 0x51, 0x4f, 0x1b, 0x39, 0x91, 0xc8, 0xb5, 0x79, 0x49, 0x63, 0x39, 0x8a, 0xc3, 0x21, 0x18, 0x7b, 0x9e, 0x05, 0x24, 0x1e, 0xe8, 0x35, 0x13, 0x71, 0x72, 0x30, 0x84, 0x94, 0xc9, 0x5e, 0xc6, 0xc7, 0xd0, 0x61, 0xad, 0x49, 0x2a, 0x70, 0xe3, 0xd5, 0x03, 0xee, 0x19, 0x9c, 0x62, 0x43, 0x0a, 0x6c, 0x7a, 0x12, 0xd2, 0xd8, 0xa9, 0x5d, 0x4b, 0x27, 0x04, 0x6c, 0x1a, 0xc0, 0x28, 0x36, 0x9c, 0x18, 0x31, 0x43, 0x54, 0xb3, 0x24, 0xa9, 0x76, 0x86, 0xc6, 0x3d, 0xfd, 0x30, 0xc4, 0xde, 0xa1, 0x1b, 0xee, 0xb0, 0x80, 0xb0, 0x69, 0x8a, 0xf3, 0xd1, 0x81, 0x3b, 0xac, 0x0d, 0xc9, 0x8b, 0x2f, 0x9a, 0xaa, 0xc6, 0xfc, 0x40, 0x15, 0x7b, 0xbb, 0x3e, 0x38, 0x93, 0x3b, 0x6e, 0x25, 0x26, 0x35, 0xb1, 0x52, 0xdd, 0x72, 0x6d, 0x78, 0x78, 0x86, 0x73, 0x67, 0x95, 0x12, 0xd4, 0x7e, 0x85, 0x9b, 0x3d, 0xa4, 0x8b, 0x82, 0xab, 0x08, 0x39, 0x78, 0xb6, 0x7a, 0x88, 0x7a, 0xa6, 0xd6, 0x43, 0x93, 0xf5, 0x09, 0xa7, 0x50, 0x79, 0x85, 0x85, 0xb0, 0xb0, 0xc8, 0xa0, 0xa9, 0x9b, 0x37, 0x97, 0x49, 0xd9, 0x60, 0x90, 0xb8, 0x91, 0x59, 0x77, 0xb0, 0x36, 0xd2, 0xa5, 0x73, 0x29, 0x54, 0xe1, 0x60, 0x9d, 0xd1, 0x99, 0x7d, 0x3e, 0xd3, 0x13, 0x34, 0xb9, 0x87, 0x86, 0xc4, 0x6c, 0x25, 0xc8, 0xb6, 0xc8, 0x49, 0x15, 0xaf, 0xbb, 0xaf, 0x31, 0x09, 0x9f, 0x60, 0x2b, 0x09, 0xe8, 0xf5, 0x9b, 0xc1, 0x13, 0x02, 0x36, 0xe6, 0xb0, 0x73, 0x66, 0x8f, 0xb2, 0xcc, 0x23, 0x95, 0x7b, 0x98, 0xc9, 0xa4, 0x65, 0xcb, 0x05, 0x40, 0xbe, 0x23, 0x97, 0x36, 0xd0, 0xcb, 0x11, 0xc9, 0x21, 0x71, 0x41, 0x1a, 0xf2, 0x24, 0xb9, 0xb9, 0x96, 0x0c, 0xe0, 0x01, 0xa5, 0x8e, 0x22, 0x17, 0xcd, 0x52, 0x7d, 0x81, 0x74, 0x4b, 0xe0, 0x13, 0x2a, 0x66, 0x10, 0x24, 0xeb, 0x1a, 0x83, 0x24, 0xf7, 0x15, 0x9d, 0x85, 0x81, 0x80, 0xd1, 0x7f, 0x56, 0x13, 0x21, 0x70, 0x52, 0x4d, 0xc3, 0x83, 0xc9, 0x3f, 0x76, 0x00, 0x0b, 0xf9, 0xcf, 0xb1, 0xa5, 0x0e, 0x52, 0xc9, 0x04, 0xac, 0x5a, 0x5e, 0xc6, 0xcb, 0x75, 0x3e, 0x43, 0x23, 0xc2, 0xf7, 0x1b, 0x03, 0x0a, 0x45, 0xef, 0x55, 0x21, 0x6e, 0x1c, 0x56, 0x52, 0x0c, 0x0c, 0x41, 0x98, 0x0a, 0x51, 0x07, 0x34, 0x56, 0x7b, 0xb5, 0x93, 0xf8, 0xb8, 0xae, 0x83, 0x3c, 0xda, 0x75, 0x10, 0x62, 0x54, 0xca, 0xe8, 0x98, 0x24, 0xda, 0xeb, 0x14, 0xaa, 0x17, 0x4d, 0x33, 0xfc, 0x7b, 0x64, 0x71, 0x05, 0xe7, 0xb6, 0x96, 0x16, 0xe3, 0x89, 0x34, 0xbb, 0x4c, 0xf2, 0x85, 0x85, 0xd7, 0x45, 0xc6, 0x33, 0xc2, 0x7e, 0x7c, 0x04, 0x3d, 0x4d, 0x42, 0xb6, 0x28, 0x6c, 0xa8, 0x88, 0x3a, 0xb2, 0x03, 0x32, 0xa9, 0x08, 0x61, 0x90, 0x49, 0x24, 0x64, 0x16, 0xd8, 0x19, 0x81, 0xc6, 0xbd, 0xf2, 0x37, 0x09, 0x1f, 0x1b, 0x99, 0xbe, 0x21, 0x72, 0x07, 0xcb, 0xbc, 0x24, 0x3a, 0xb0, 0x67, 0x66, 0x2e, 0x99, 0x88, 0x3b, 0x07, 0x61, 0x31, 0xc8, 0x77, 0x72, 0x8e, 0xe5, 0xc8, 0x2e, 0xa2, 0x85, 0x6a, 0x56, 0x40, 0x0c, 0x88, 0x6b, 0x44, 0x3b, 0x1b, 0x72, 0x30, 0x60, 0x0f, 0x33, 0x76, 0x4a, 0x4c, 0x37, 0xf9, 0xac, 0x06, 0xe2, 0xd2, 0x1d, 0xbb, 0x8c, 0xb4, 0x54, 0x62, 0x5c, 0xe1, 0x08, 0x71, 0x15, 0x63, 0xa7, 0x4a, 0x10, 0xbb, 0x00, 0x32, 0x64, 0x1e, 0x96, 0x11, 0xfa, 0x3a, 0x91, 0x37, 0x42, 0xbe, 0xc1, 0x55, 0x41, 0xd2, 0x90, 0x39, 0x59, 0x61, 0x12, 0x3b, 0x60, 0x72, 0x70, 0x09, 0x1c, 0xde, 0x12, 0x2e, 0x57, 0xfb, 0xc4, 0xdf, 0xbb, 0x56, 0xb9, 0x02, 0xb5, 0x78, 0x56, 0x46, 0x44, 0xd7, 0x50, 0x67, 0xd2, 0x8d, 0x3c, 0x1a, 0x2b, 0xad, 0xea, 0xb4, 0x85, 0xc7, 0xc5, 0x60, 0x0c, 0x36, 0x5a, 0x01, 0xa2, 0x16, 0xc0, 0x08, 0x97, 0xc6, 0x86, 0x02, 0xf5, 0x8d, 0x7a, 0x77, 0x46, 0x8a, 0x3a, 0x2a, 0xa5, 0x5a, 0xc8, 0x1d, 0xc3, 0x40, 0xc9, 0xf6, 0x25, 0x2d, 0x89, 0xbc, 0x26, 0x24, 0x21, 0xfa, 0xc7, 0x34, 0x48, 0xe5, 0xc5, 0x2a, 0x1b, 0x1a, 0xcd, 0x89, 0x3f, 0x9d, 0x43, 0x0f, 0x95, 0x64, 0x72, 0xe9, 0x84, 0x53, 0xa7, 0x43, 0x58, 0xd4, 0x22, 0xac, 0x65, 0x81, 0x72, 0x09, 0xea, 0x66, 0x01, 0x0a, 0xbc, 0xba, 0xc2, 0xc8, 0x84, 0x36, 0x98, 0x00, 0xd5, 0x76, 0x07, 0x16, 0x4f, 0x39, 0xc3, 0x78, 0xa2, 0x18, 0x53, 0x5f, 0xaa, 0xb0, 0x0c, 0xc3, 0x02, 0xb1, 0x51, 0x87, 0x30, 0x50, 0x66, 0x33, 0x2c, 0x27, 0xe6, 0x58, 0x7c, 0x20, 0x39, 0x62, 0xfa, 0xd5, 0x41, 0xe1, 0xe4, 0xcd, 0x99, 0xe7, 0x6d, 0x6c, 0x04, 0x94, 0x60, 0x61, 0x45, 0x12, 0x36, 0x93, 0x34, 0xfa, 0x38, 0x98, 0x58, 0xba, 0xd4, 0x04, 0x11, 0x8b, 0x5a, 0x22, 0xcc, 0x51, 0x4d, 0xce, 0x34, 0x9b, 0xa6, 0x99, 0x3a, 0xdc, 0x68, 0x9b, 0x05, 0x7b, 0x86, 0x1c, 0x5a, 0x74, 0x70, 0x38, 0x39, 0xbf, 0x9a, 0x20, 0x7e, 0xcc, 0x00, 0xa1, 0xaa, 0xbb, 0xc7, 0xa0, 0x59, 0x0b, 0x36, 0xbf, 0xb5, 0x49, 0x76, 0x02, 0xe2, 0x17, 0x25, 0x02, 0x99, 0x55, 0x25, 0xb7, 0x1f, 0x78, 0x69, 0x76, 0x42, 0x49, 0xe7, 0x97, 0xcb, 0xe3, 0xb7, 0x0b, 0x5f, 0x68, 0x0b, 0x9a, 0x64, 0x9a, 0x62, 0x64, 0xa9, 0x36, 0xf6, 0xb6, 0xe5, 0x01, 0x49, 0x8b, 0x04, 0x64, 0x97, 0xfc, 0xce, 0x85, 0x29, 0x90, 0xd4, 0x97, 0x45, 0x2f, 0x67, 0x9d, 0x63, 0x39, 0xa9, 0x82, 0xa5, 0x78, 0x42, 0x29, 0x54, 0x8b, 0xb4, 0x1d, 0x0e, 0xfb, 0x79, 0xf3, 0xdb, 0x01, 0xec, 0x18, 0xa7, 0x2d, 0xdb, 0x7b, 0xd7, 0x42, 0x51, 0x8f, 0xa0, 0xcf, 0xc4, 0xf3, 0x55, 0x83, 0xdb, 0x55, 0x54, 0x5b, 0x13, 0x4c, 0x40, 0x23, 0x6f, 0x0b, 0xba, 0x40, 0x05, 0x56, 0xa2, 0x32, 0x09, 0xe7, 0x21, 0x90, 0x4f, 0xc1, 0x02, 0x56, 0xa2, 0xc1, 0x08, 0x55, 0x0d, 0x9f, 0x66, 0x07, 0x5b, 0x05, 0x2c, 0xb4, 0xf8, 0x22, 0x2b, 0xb0, 0x5d, 0x4d, 0x53, 0x22, 0x7f, 0xa6, 0x8d, 0x8e, 0xb5, 0x43, 0xf5, 0x19, 0x94, 0x05, 0x46, 0x7e, 0x64, 0x09, 0x3a, 0x8b, 0x3a, 0x60, 0x83, 0x44, 0x12, 0x60, 0xf0, 0x63, 0xc3, 0xa8, 0xb3, 0x05, 0xea, 0x8b, 0xe0, 0x58, 0x80, 0x0f, 0x16, 0xc2, 0xfe, 0xdb, 0xc9, 0xb6, 0xdc, 0x82, 0xc5, 0x5a, 0x4b, 0x92, 0xc4, 0x83, 0x76, 0xc2, 0x4b, 0x51, 0xb4, 0xc9, 0x92, 0xe3, 0xc8, 0x12, 0x3c, 0x37, 0xda, 0x1b, 0x32, 0x17, 0xa4, 0x2c, 0x96, 0x95, 0x8f, 0x23, 0x51, 0x18, 0xd3, 0x81, 0x33, 0x30, 0xf4, 0x2e, 0x5b, 0xa6, 0xa4, 0x80, 0x8a, 0x59, 0x60, 0x84, 0x8f, 0x4b, 0x7a, 0x2c, 0xa9, 0x98, 0xa0, 0x59, 0xdc, 0x47, 0xa0, 0x77, 0x66, 0xf2, 0x82, 0x43, 0xf2, 0x7b, 0xa3, 0xa5, 0x19, 0x83, 0x2d, 0xd5, 0xca, 0x03, 0x51, 0x78, 0xc6, 0xea, 0x68, 0xce, 0x2a, 0x94, 0x47, 0x35, 0x00, 0x68, 0x84, 0x5e, 0x26, 0x7b, 0x7d, 0x56, 0xb4, 0x15, 0xc7, 0x4a, 0x76, 0x08, 0x71, 0x27, 0x50, 0x22, 0x5a, 0x1a, 0x5c, 0x07, 0xf5, 0x06, 0x19, 0x44, 0x75, 0xba, 0xbc, 0xba, 0x09, 0x64, 0xb2, 0x08, 0x7d, 0x61, 0x77, 0xce, 0x80, 0xbf, 0xe7, 0xf5, 0x22, 0xd1, 0x46, 0x10, 0xe7, 0xfb, 0x2a, 0x6a, 0xe6, 0x9e, 0xd5, 0x47, 0x8c, 0x63, 0x7c, 0xb8, 0xf7, 0xe1, 0x5e, 0x15, 0x49, 0x8e, 0xe5, 0x44, 0x7e, 0x00, 0x2d, 0x62, 0x97, 0xf3, 0x33, 0x7f, 0xd5, 0x56, 0xb4, 0x23, 0x68, 0xfd, 0x45, 0x3b, 0xa7, 0x28, 0xbd, 0xbe, 0xc9, 0x8a, 0x5d, 0xf4, 0x7e, 0x61, 0xc7, 0x8c, 0x23, 0x9a, 0x5c, 0xcb, 0xf8, 0x27, 0x0b, 0x36, 0x05, 0xb7, 0xd8, 0xb1, 0xf8, 0x97, 0x89, 0xd0, 0xb8, 0x3d, 0x71, 0x9a, 0xcb, 0x16, 0x84, 0x9a, 0x45, 0xb2, 0x80, 0xb8, 0x36, 0x37, 0x8b, 0xc4, 0xbd, 0xba, 0x41, 0x81, 0xe8, 0x23, 0xcb, 0xf3, 0x00, 0x41, 0x4a, 0xa3, 0xa9, 0xf0, 0xf7, 0x34, 0xf1, 0xa4, 0x25, 0xa6, 0x23, 0x4c, 0xca, 0x47, 0x5d, 0x9f, 0xab, 0x63, 0xe6, 0x45, 0x8e, 0xc0, 0x16, 0xa0, 0x45, 0xa4, 0x11, 0x28, 0x47, 0x83, 0xf1, 0x9a, 0x70, 0x9d, 0xf8, 0x1d, 0x13, 0x33, 0x48, 0xf8, 0xe3, 0x27, 0x43, 0xc3, 0x35, 0x2e, 0x3b, 0x1d, 0x24, 0x45, 0x77, 0xe2, 0xa9, 0x3a, 0x79, 0x85, 0xc6, 0xc6, 0x87, 0xce, 0x50, 0xc9, 0x04, 0xa4, 0xec, 0xc3, 0x8d, 0xd4, 0x13, 0x7e, 0x1b, 0x1b, 0x30, 0x36, 0x90, 0x69, 0x76, 0xb9, 0xdb, 0xa4, 0x0c, 0x5f, 0x35, 0x04, 0xb7, 0xc5, 0x99, 0x37, 0xc8, 0x00, 0x3d, 0xd9, 0x59, 0x26, 0x57, 0x05, 0xdb, 0x69, 0x6d, 0x83, 0xc9, 0x0c, 0x7f, 0x50, 0xad, 0xff, 0x2a, 0x58, 0xee, 0x8c, 0xad, 0x46, 0xf7, 0x5d, 0xe4, 0xd4, 0x22, 0x19, 0xc4, 0xc4, 0x16, 0x0b, 0x6d, 0x24, 0xc3, 0x73, 0xe3, 0xca, 0x2b, 0x1c, 0xa7, 0x22, 0xac, 0x8b, 0x74, 0xaa, 0x30, 0x8d, 0xe9, 0xb0, 0x23, 0x28, 0xd3, 0x68, 0xee, 0x12, 0x61, 0x1d, 0xe7, 0x98, 0x06, 0x44, 0x00, 0xd4, 0xd2, 0xcc, 0xb9, 0x73, 0x89, 0x0b, 0x5a, 0x44, 0x2b, 0x85, 0x5b, 0x63, 0x99, 0x60, 0xe8, 0x3b, 0x1e, 0x75, 0xf3, 0x8d, 0xea, 0xa3, 0x90, 0x52, 0xb5, 0x6a, 0x0d, 0xb1, 0xa4, 0xdb, 0xd0, 0x85, 0xfb, 0x56, 0xae, 0x77, 0x74, 0x00, 0xb9, 0xd9, 0xa9, 0x32, 0x28, 0x12, 0xb5, 0x5a, 0x77, 0xfb, 0x36, 0x57, 0xe7, 0x21, 0x56, 0xd5, 0x8b, 0x63, 0x74, 0x96, 0x72, 0xc2, 0x42, 0xcb, 0x1e, 0xc1, 0x51, 0x6c, 0xd6, 0x42, 0x97, 0x26, 0xb7, 0xe6, 0xf0, 0xb5, 0x3e, 0xe3, 0xbf, 0xf8, 0x43, 0x10, 0x8c, 0xdb, 0x89, 0x6d, 0x13, 0x89, 0xf8, 0x3c, 0x7b, 0xe4, 0x24, 0x27, 0xd5, 0x57, 0x83, 0xdf, 0xab, 0x4b, 0xbe, 0xec, 0x07, 0xf1, 0x45, 0xcd, 0x23, 0xc2, 0x05, 0xf6, 0xd2, 0x4f, 0x61, 0x17, 0x29, 0xe3, 0x72, 0x86, 0xb7, 0xa0, 0x34, 0x59, 0xd1, 0x51, 0x19, 0xe7, 0xa1, 0xa2, 0xd4, 0xad, 0x7b, 0x17, 0x25, 0xcc, 0x8b, 0x54, 0x29, 0x3a, 0xb2, 0xfc, 0xd8, 0x28, 0x5c, 0xf9, 0x75, 0x21, 0x89, 0x40, 0x33, 0xf3, 0x93, 0x61, 0x73, 0xab, 0x8d, 0x33, 0xaa, 0x0f, 0x20, 0x95, 0xa8, 0xc4, 0x57, 0xa7, 0x34, 0xc6, 0x37, 0xd3, 0x91, 0x84, 0x70, 0x89, 0x55, 0x05, 0x8d, 0xfe, 0xb3, 0x9f, 0xcd, 0x68, 0x9c, 0x70, 0xd6, 0xc1, 0x11, 0xc7, 0x1a, 0x0c, 0xbc, 0x43, 0x1b, 0x84, 0x3c, 0x7c, 0x12, 0x57, 0xb5, 0x58, 0x27, 0x6c, 0xdc, 0xbf, 0xf7, 0x01, 0xbe, 0xd0, 0x65, 0x20, 0x33, 0x45, 0x07, 0xfe, 0x24, 0x81, 0xca, 0xba, 0x19, 0x5f, 0xcb, 0x86, 0xda, 0xa5, 0x10, 0xec, 0xea, 0x20, 0xef, 0xa0, 0x32, 0xdb, 0x46, 0xc8, 0xb5, 0xb9, 0x90, 0xf9, 0x6b, 0x4d, 0xbb, 0x9c, 0x99, 0x39, 0x77, 0x97, 0x4a, 0xf8, 0xae, 0xe8, 0x97, 0x43, 0x92, 0x05, 0xbb, 0xf6, 0x21, 0x06, 0x81, 0x0a, 0x3c, 0x84, 0xb1, 0x79, 0x98, 0x99, 0x77, 0xee, 0xb9, 0x5b, 0x79, 0x56, 0x98, 0x31, 0x34, 0xaf, 0x6b, 0xd2, 0x20, 0x28, 0x26, 0xa3, 0x2e, 0x9a, 0x99, 0xb4, 0xc4, 0xdc, 0x2e, 0x40, 0x51, 0x5c, 0x57, 0x11, 0xc2, 0xdf, 0x2f, 0xa5, 0x06, 0x65, 0x51, 0xbc, 0xbb, 0xa9, 0xcf, 0x5d, 0x0e, 0x94, 0x5e, 0x9d, 0x29, 0x3f, 0x95, 0xb7, 0x99, 0xf4, 0x64};
static const uint8_t PUBKEY_4[1568] = {0x0f, 0x87, 0x24, 0xcf, 0xc1, 0x23, 0x22, 0x30, 0xaa, 0x3c, 0xaa, 0xbf, 0x22, 0x47, 0xa3, 0x79, 0xf3, 0xa3, 0x79, 0xb4, 0x5a, 0x01, 0x72, 0x4c, 0xd4, 0x00, 0x73, 0x47, 0x96, 0x12, 0x77, 0xe9, 0xc7, 0x71, 0x23, 0x13, 0x4b, 0x26, 0xa2, 0xaa, 0xd6, 0x80, 0xb0, 0x03, 0x30, 0x37, 0x19, 0x30, 0xb3, 0x68, 0x84, 0xb8, 0x3b, 0x28, 0xaf, 0x30, 0xb6, 0x21, 0x69, 0x79, 0x17, 0xf6, 0x0f, 0xf6, 0x30, 0x4c, 0xfc, 0x27, 0xc9, 0xef, 0x56, 0xaf, 0xff, 0xea, 0x27, 0x55, 0x76, 0x08, 0x53, 0xb9, 0x08, 0x8a, 0x50, 0x37, 0xd1, 0xd3, 0x02, 0x6c, 0xb9, 0x28, 0xe3, 0xec, 0x53, 0x8f, 0x52, 0x6a, 0x81, 0xf9, 0x44, 0x7e, 0xaa, 0x49, 0x75, 0xd5, 0xbd, 0x38, 0x98, 0x98, 0x78, 0x2c, 0x36, 0x5f, 0x66, 0x8a, 0xf4, 0x64, 0x64, 0xf9, 0x1a, 0xae, 0x22, 0x6b, 0xa8, 0x4a, 0x5c, 0x24, 0x03, 0xf5, 0x8b, 0x07, 0xea, 0x7b, 0x65, 0x08, 0x9c, 0x06, 0x82, 0x40, 0x09, 0xeb, 0xce, 0x39, 0xd8, 0x8c, 0x9b, 0x13, 0x1e, 0xd8, 0xbb, 0xc4, 0x22, 0x19, 0x4b, 0xed, 0x22, 0x3b, 0x12, 0xb2, 0xb5, 0xc1, 0x84, 0x97, 0x71, 0xb2, 0x1d, 0x27, 0x55, 0x37, 0x2c, 0x71, 0x02, 0xf5, 0x4b, 0x00, 0x21, 0x0c, 0x87, 0x7e, 0xa5, 0x9d, 0xfb, 0xd1, 0xa6, 0x78, 0x49, 0xcb, 0x34, 0x98, 0x5f, 0x6e, 0xfc, 0xad, 0x73, 0xe8, 0x6b, 0x1f, 0x52, 0x3a, 0x7a, 0x63, 0x96, 0xc9, 0xc8, 0x1a, 0x43, 0xbb, 0xa6, 0xbe, 0x96, 0x95, 0xc4, 0xb7, 0x5d, 0xdb, 0x41, 0x0a, 0x7b, 0xb9, 0x3d, 0x07, 0x88, 0x18, 0xa2, 0xf9, 0x17, 0x45, 0xa0, 0x1f, 0x6c, 0x91, 0xcf, 0x19, 0x71, 0x85, 0xc4, 0x0a, 0xa0, 0x13, 0xd0, 0x82, 0xcb, 0xcb, 0xbf, 0x4d, 0x00, 0xbe, 0x20, 0x04, 0x8d, 0x1a, 0x50, 0x59, 0x33, 0x0b, 0x67, 0x56, 0xc7, 0x17, 0x01, 0x7c, 0x97, 0xd7, 0xe8, 0x51, 0xa6, 0x3c, 0x16, 0x2d, 0x0b, 0xb2, 0x03, 0x2a, 0x58, 0x9a, 0xf9, 0x79, 0xb3, 0x1a, 0x3e, 0x95, 0xd2, 0x42, 0x2e, 0xfa, 0x3e, 0x86, 0x22, 0x61, 0x72, 0xf7, 0x9d, 0x95, 0x01, 0x5c, 0x33, 0xb8, 0x16, 0x1e, 0x07, 0xc3, 0xed, 0x59, 0x35, 0xb2, 0xbb, 0x40, 0x34, 0xb8, 0x86, 0xce, 0xe3, 0x73, 0xd6, 0xf5, 0xb4, 0xf0, 0x84, 0x4b, 0x34, 0xe1, 0x92, 0x87, 0x52, 0xaf, 0x76, 0x34, 0xb7, 0x32, 0x85, 0x4b, 0xe8, 0x59, 0x3e, 0x4b, 0x14, 0xa9, 0xd1, 0xfc, 0x56, 0x25, 0x00, 0x8c, 0xf3, 0x14, 0x55, 0xa2, 0xfc, 0xc9, 0xd3, 0xc2, 0x27, 0xb1, 0xe9, 0x9c, 0x10, 0x56, 0xcb, 0xcd, 0xca, 0x0e, 0xa5, 0x36, 0x07, 0x05, 0x04, 0x3e, 0x59, 0xe6, 0x12, 0x18, 0xdc, 0x2a, 0xc2, 0x10, 0x96, 0xb7, 0x78, 0x4d, 0xef, 0xbc, 0x56, 0x17, 0x23, 0xb1, 0x92, 0x1b, 0x14, 0xbc, 0x6a, 0xc6, 0xf4, 0x12, 0x60, 0xa1, 0xe0, 0x2c, 0x5a, 0xd3, 0xaf, 0x1e, 0x9b, 0x14, 0x05, 0x31, 0x07, 0xa7, 0x5b, 0x8a, 0xbb, 0x68, 0x01, 0xdc, 0x47, 0x26, 0xa8, 0x89, 0xb9, 0x4e, 0xe6, 0x64, 0xf7, 0xa5, 0xa0, 0xa1, 0x79, 0x5c, 0x3c, 0x52, 0x24, 0x8f, 0x4a, 0x5f, 0x89, 0x17, 0x2f, 0xb2, 0x8a, 0x09, 0xbd, 0x59, 0x7d, 0x9e, 0xb2, 0x09, 0x70, 0x32, 0x51, 0x3f, 0xca, 0x3c, 0xab, 0x73, 0x1f, 0xae, 0x49, 0x6e, 0x10, 0x52, 0x6d, 0xfe, 0x74, 0xa2, 0xf9, 0x1b, 0x4b, 0x8e, 0x72, 0x00, 0xac, 0x03, 0xb0, 0xa4, 0x88, 0x02, 0xdc, 0x72, 0x2e, 0xfc, 0x33, 0x72, 0x8d, 0x08, 0x56, 0x20, 0x39, 0x32, 0x7d, 0xb8, 0x99, 0x51, 0x4b, 0x27, 0xef, 0x74, 0x91, 0xa7, 0x96, 0x1c, 0x04, 0xa7, 0x9a, 0x4a, 0xb1, 0x20, 0x9f, 0x20, 0x95, 0xb3, 0xc3, 0x59, 0x6d, 0x24, 0x41, 0xbb, 0xcc, 0x08, 0x3e, 0x92, 0x46, 0xc1, 0xb2, 0xaa, 0x93, 0x8a, 0x9d, 0xe4, 0xe4, 0xbd, 0xa3, 0x8a, 0xab, 0x6a, 0xe7, 0x2e, 0x7c, 0x7c, 0x9f, 0xad, 0x77, 0x25, 0xcd, 0xa8, 0x73, 0xd2, 0x65, 0x70, 0x9d, 0xd7, 0xbb, 0x8a, 0xc9, 0x57, 0xa6, 0xe2, 0x8b, 0x47, 0x31, 0x16, 0xdf, 0x1b, 0x54, 0x5a, 0x09, 0x57, 0x63, 0x30, 0x7b, 0x34, 0xb5, 0xbe, 0x67, 0xa5, 0x49, 0xfb, 0xb6, 0x03, 0xf7, 0x66, 0x1f, 0xf1, 0xab, 0xa1, 0xe9, 0x60, 0x4a, 0xf0, 0x6a, 0x92, 0x2f, 0x46, 0x80, 0xf5, 0x9b, 0x5b, 0x4b, 0x73, 0x5c, 0x85, 0x28, 0xb9, 0xd0, 0x08, 0x40, 0x8f, 0xd8, 0xae, 0x33, 0x75, 0xa6, 0xfd, 0x34, 0x57, 0x25, 0x47, 0x10, 0x5e, 0x01, 0x4d, 0xb7, 0xe0, 0x21, 0x55, 0xe1, 0xb0, 0xbb, 0xb2, 0x19, 0x31, 0xe7, 0x6e, 0xf4, 0xb8, 0x76, 0xda, 0x60, 0x61, 0x48, 0x5c, 0x0e, 0xfc, 0xcb, 0x4a, 0x12, 0x35, 0x79, 0x25, 0x15, 0x73, 0xbe, 0x14, 0xca, 0x9c, 0xe6, 0x36, 0xd6, 0xf9, 0x82, 0x9c, 0xc5, 0x08, 0xca, 0x58, 0xae, 0xd2, 0xf9, 0x8d, 0x70, 0x51, 0x9c, 0x85, 0xab, 0x25, 0x5e, 0x2a, 0x65, 0xc1, 0xe0, 0x78, 0xfc, 0xf9, 0x54, 0xed, 0xe7, 0x52, 0x20, 0x63, 0x8c, 0x76, 0xf8, 0xca, 0x1a, 0xf2, 0x2e, 0x35, 0x58, 0x90, 0xf7, 0x39, 0x6d, 0xf9, 0x51, 0x82, 0xad, 0xd0, 0xbc, 0x9f, 0xc9, 0x5a, 0xb9, 0xe6, 0x2f, 0x5f, 0xc7, 0x11, 0x72, 0x33, 0x7e, 0x93, 0x48, 0x1f, 0x7d, 0x70, 0x2e, 0x50, 0xba, 0x10, 0x8f, 0x09, 0x1b, 0x45, 0x05, 0x6d, 0x50, 0x20, 0xc8, 0x2f, 0x50, 0x08, 0xca, 0x36, 0xce, 0x15, 0x00, 0x67, 0x60, 0x60, 0x8f, 0x67, 0x4b, 0x4b, 0x84, 0x82, 0x8f, 0xfb, 0x89, 0x41, 0x60, 0x18, 0x08, 0x18, 0x79, 0x14, 0xba, 0x9b, 0x31, 0x13, 0x2b, 0x80, 0x61, 0x9b, 0xa6, 0xc5, 0xd8, 0xc0, 0xd0, 0xf5, 0x68, 0x75, 0xd1, 0xa9, 0x00, 0xf1, 0x96, 0x72, 0x36, 0x6d, 0xde, 0xe6, 0x58, 0x07, 0xfa, 0x87, 0x55, 0x31, 0x56, 0x47, 0xd2, 0x8c, 0x8c, 0x10, 0x63, 0x28, 0xe3, 0x2c, 0xc8, 0xf1, 0x69, 0xca, 0x83, 0x04, 0x70, 0x67, 0xab, 0xd9, 0x92, 0x21, 0x8f, 0xb3, 0xb8, 0x33, 0x3b, 0x30, 0xd0, 0xb9, 0x72, 0x86, 0x8a, 0x96, 0x52, 0x31, 0x3c, 0x52, 0x8c, 0xa1, 0x15, 0xc3, 0x3c, 0xaf, 0x37, 0xb1, 0xe7, 0x92, 0x4f, 0x27, 0x56, 0x10, 0x84, 0xd8, 0x78, 0x58, 0x67, 0xae, 0xdc, 0x10, 0x89, 0xac, 0xc8, 0x58, 0x44, 0x78, 0xb0, 0x0a, 0xcb, 0xb2, 0x2a, 0x67, 0x78, 0x84, 0x1b, 0x27, 0x19, 0x22, 0x8b, 0x39, 0x2b, 0xa1, 0xd7, 0x91, 0x97, 0xeb, 0x75, 0xaf, 0xf1, 0xf8, 0x12, 0x95, 0x34, 0x87, 0x7a, 0xf0, 0x68, 0xbe, 0x03, 0x4c, 0xe4, 0x57, 0x8b, 0xbf, 0xd8, 0x6a, 0xff, 0xe7, 0x0a, 0x51, 0x55, 0x6c, 0x06, 0xac, 0x95, 0xc9, 0x14, 0x98, 0x92, 0x38, 0x11, 0xc8, 0x01, 0x64, 0x12, 0x3c, 0x37, 0xd5, 0x1c, 0x7f, 0xfd, 0x68, 0xa1, 0xd8, 0x86, 0x28, 0xff, 0x36, 0x30, 0xeb, 0x82, 0x4a, 0xe8, 0x33, 0x36, 0x69, 0xda, 0x2b, 0x57, 0xe2, 0x66, 0xeb, 0x20, 0x6e, 0xc7, 0x98, 0x63, 0x13, 0x83, 0x25, 0xa3, 0xd8, 0xb9, 0xeb, 0x1a, 0xae, 0x04, 0x0c, 0x01, 0x69, 0x6c, 0x08, 0x72, 0xdc, 0xc1, 0x4e, 0x6c, 0x9c, 0x77, 0xd3, 0x08, 0xeb, 0x42, 0x23, 0xa5, 0xaa, 0xbb, 0x8f, 0x20, 0x6a, 0x6d, 0x71, 0x51, 0x0a, 0x94, 0x1d, 0x3a, 0x46, 0x73, 0x57, 0x03, 0x7a, 0x2e, 0xe3, 0x98, 0xfd, 0x09, 0x67, 0x76, 0x05, 0x63, 0x30, 0x8b, 0xa5, 0x8c, 0xfc, 0x2e, 0x65, 0x9c, 0x04, 0xfb, 0xda, 0x84, 0x95, 0x20, 0x04, 0xa4, 0x6c, 0x1b, 0x6e, 0xcb, 0x81, 0xc1, 0xfb, 0x96, 0x71, 0xe5, 0xc3, 0x33, 0x53, 0x26, 0x89, 0x61, 0x27, 0xaa, 0x37, 0xa6, 0xc8, 0x2b, 0x78, 0x2a, 0x60, 0xac, 0xbe, 0xf2, 0xaf, 0x2d, 0xfb, 0x07, 0xd2, 0x31, 0x4e, 0x5f, 0x69, 0x53, 0xea, 0x52, 0xca, 0x2b, 0xaa, 0x09, 0x00, 0x79, 0x7f, 0xd3, 0x01, 0xa5, 0x1c, 0xd4, 0xca, 0x84, 0xd4, 0x5b, 0x2d, 0x5b, 0xc7, 0xed, 0x3b, 0x4a, 0x43, 0x18, 0x85, 0xdf, 0xa3, 0x1f, 0xf7, 0xdc, 0x9b, 0xe5, 0x69, 0x64, 0x2e, 0xb7, 0x14, 0x4b, 0x49, 0xc7, 0x15, 0x04, 0x6c, 0x5b, 0xc6, 0x28, 0xe8, 0x15, 0x83, 0x5e, 0xa6, 0x6e, 0xa4, 0x45, 0xcf, 0xa0, 0x21, 0x94, 0x87, 0xb3, 0x1d, 0xf3, 0xeb, 0x80, 0xc7, 0x9b, 0xa9, 0xd3, 0xab, 0x44, 0xfb, 0xaa, 0x0f, 0x09, 0xcc, 0x03, 0xd2, 0x23, 0x5f, 0xcb, 0x32, 0xbf, 0x8d, 0x19, 0x20, 0x88, 0xb2, 0xaa, 0x71, 0xc0, 0xcf, 0xa6, 0x68, 0x1e, 0xf9, 0x05, 0x71, 0xe9, 0x7a, 0x18, 0xdc, 0xc2, 0x97, 0x37, 0xc4, 0x1b, 0xa3, 0xc4, 0x13, 0x82, 0xab, 0x78, 0x7e, 0x1c, 0xa7, 0x8a, 0xf9, 0xc7, 0x67, 0x0b, 0x68, 0x5f, 0x72, 0x99, 0xde, 0x05, 0x5f, 0x69, 0x26, 0x85, 0x71, 0xd7, 0x53, 0xe2, 0x30, 0x94, 0xdd, 0x1b, 0x20, 0x86, 0x18, 0x87, 0x04, 0x97, 0x7f, 0x1c, 0x34, 0xc7, 0xbf, 0xc2, 0x35, 0xcb, 0xec, 0x83, 0x28, 0xf9, 0x3a, 0x92, 0x29, 0x26, 0x1f, 0xd0, 0x1d, 0x3e, 0x12, 0x43, 0xcd, 0xb7, 0x95, 0x3c, 0x07, 0x06, 0x39, 0x9b, 0x55, 0x28, 0xb1, 0x2e, 0x25, 0x98, 0x8e, 0x53, 0xb2, 0x2c, 0x83, 0xa3, 0x38, 0xe9, 0x21, 0x47, 0x5b, 0xe1, 0x3f, 0x2e, 0x0a, 0x4f, 0xc9, 0xd9, 0x1e, 0x5a, 0xf2, 0x78, 0x7d, 0x43, 0x4d, 0x01, 0xf6, 0x37, 0xfc, 0x42, 0x69, 0x8e, 0x2a, 0x8d, 0x3b, 0x96, 0x84, 0x89, 0x4a, 0xcc, 0x4f, 0x28, 0x6e, 0x75, 0x5c, 0x1e, 0xf5, 0x90, 0x57, 0x1e, 0x03, 0x86, 0x26, 0xc4, 0x71, 0x3f, 0x29, 0xce, 0xbe, 0xf5, 0x71, 0xc4, 0x25, 0x3b, 0xd8, 0x45, 0xca, 0x02, 0x08, 0xbf, 0xeb, 0x06, 0x7b, 0xa4, 0x41, 0x7f, 0x08, 0xb2, 0xb5, 0xb4, 0x03, 0x4d, 0x42, 0xcc, 0x9c, 0xad, 0x9b, 0x9b, 0xac, 0xc1, 0xa4, 0x76, 0x9a, 0x48, 0x24, 0xb6, 0x6c, 0xff, 0x32, 0x0f, 0xf1, 0x70, 0x18, 0xca, 0x78, 0xc8, 0x52, 0xb2, 0x66, 0x98, 0xb0, 0x39, 0xac, 0x48, 0x82, 0x83, 0x20, 0xb5, 0x2d, 0x53, 0x00, 0xaf, 0x24, 0x71, 0x87, 0x10, 0x5c, 0x44, 0xfb, 0x4e, 0x18, 0x22, 0x12, 0x88, 0x28, 0x4b, 0xfd, 0x25, 0xb1, 0x02, 0x96, 0x5b, 0xc2, 0x74, 0x7b, 0x9d, 0xb3, 0x07, 0x09, 0x3b, 0x81, 0xf5, 0x18, 0x61, 0xfc, 0xf5, 0x01, 0x00, 0x92, 0xc6, 0x17, 0x44, 0xc5, 0xe1, 0xb7, 0x91, 0xda, 0xca, 0x70, 0x7c, 0x24, 0x7f, 0xf1, 0x1b, 0x11, 0x5b, 0x4a, 0x1f, 0x95, 0x64, 0x32, 0x8d, 0xf7, 0x5c, 0x2d, 0xe6, 0x17, 0xc8, 0x1a, 0x6a, 0x01, 0x17, 0x17, 0x4c, 0x65, 0x0c, 0x4c, 0x2a, 0x68, 0x47, 0x90, 0x2f, 0x46, 0x66, 0x15, 0xdc, 0x80, 0x9d, 0xfd, 0xc9, 0x41, 0x65, 0x36, 0x98, 0x94, 0x51, 0x00, 0x4c, 0x19, 0x54, 0xdc, 0x97, 0xb9, 0xbf, 0xf1, 0x0e, 0x74, 0x59, 0x7b, 0xf5, 0x50, 0x73, 0xd9, 0x02, 0xc2, 0x11, 0x0c, 0x00, 0x75, 0x45, 0xc6, 0x6f, 0xb7, 0x70, 0x27, 0xc4, 0x3a, 0xdc, 0x36, 0x8e, 0xcf, 0xe1, 0x82, 0x7e, 0xda, 0x78, 0xb0, 0x00, 0x96, 0x5b, 0xb9, 0x69, 0x8f, 0x56, 0x6f, 0xeb, 0xe0, 0xc8, 0xfd, 0x60, 0x06, 0xb1, 0xdb, 0x70, 0x15, 0x63, 0x96, 0x0b, 0x83, 0x10, 0x42, 0x90, 0x36, 0xfd, 0xea, 0x1a, 0xaf, 0x12, 0x9e, 0x65, 0x59, 0x96, 0x0c, 0xa8, 0x54, 0xc0, 0xce, 0x0c, 0x83, 0x79, 0x06, 0x2b, 0x15, 0x22, 0xd2, 0x80, 0x26, 0x28, 0x9e, 0x67, 0xb7, 0x6f, 0x89, 0xfe, 0x9e, 0x46, 0x86, 0x6e, 0x61, 0xb1, 0xfa, 0x5c, 0x3c, 0xde, 0xb1, 0xd3, 0x69};
static const uint8_t CT_1[768] = {0xaf, 0x38, 0x0d, 0x94, 0xfa, 0x86, 0x23, 0xbc, 0xce, 0x15, 0x96, 0x67, 0x52, 0x58, 0x9b, 0xcf, 0xc3, 0xb9, 0x13, 0x89, 0x96, 0xef, 0x31, 0x4f, 0xc6, 0xbe, 0x08, 0x45, 0xc7, 0xde, 0x36, 0x0c, 0x2c, 0xfe, 0xa9, 0x24, 0x3b, 0x47, 0xa8, 0xee, 0xb8, 0x01, 0x8d, 0x6f, 0x19, 0xa7, 0x0a, 0x0e, 0x39, 0xfa, 0x3f, 0x92, 0xd3, 0xe5, 0x2d, 0x18, 0xa8, 0xa7, 0xce, 0xb3, 0xf0, 0x8d, 0xe5, 0x85, 0x81, 0x6a, 0x08, 0x1d, 0xa5, 0x78, 0xc7, 0xfa, 0xd8, 0x22, 0xfa, 0x06, 0x25, 0x50, 0x5c, 0x48, 0x81, 0xd9, 0x9b, 0xc8, 0xee, 0x44, 0x82, 0x44, 0x35, 0xb2, 0xdc, 0xb2, 0x1a, 0x33, 0xa8, 0x2d, 0x4a, 0xd2, 0x36, 0xd6, 0xe0, 0xa9, 0xda, 0x0d, 0x39, 0x20, 0x92, 0x12, 0xe9, 0x8e, 0xa0, 0x2e, 0xd1, 0x41, 0xc5, 0xe7, 0xc3, 0xcb, 0x64, 0xb5, 0xfc, 0x38, 0x2d, 0x93, 0x2a, 0x00, 0xc1, 0x12, 0x02, 0xdc, 0xfe, 0xc9, 0xd5, 0xf4, 0x5a, 0x04, 0x2e, 0x0c, 0x49, 0xd4, 0x6a, 0x39, 0xef, 0x56, 0x2d, 0xd4, 0x3e, 0x2e, 0x01, 0xbb, 0xd5, 0x37, 0x01, 0xa3, 0xb5, 0xbc, 0xbb, 0xc4, 0xbd, 0x2d, 0x80, 0xe3, 0xc9, 0xa6, 0x7d, 0x3a, 0x41, 0xee, 0xeb, 0xd5, 0x6b, 0x62, 0x97, 0xd2, 0x17, 0x9b, 0x07, 0x3b, 0x9d, 0xb8, 0xa9, 0x3b, 0xc6, 0x0d, 0x29, 0x24, 0xc0, 0x92, 0x12, 0x8c, 0x5f, 0x80, 0xeb, 0xed, 0x25, 0x2b, 0x26, 0xe2, 0x46, 0x3d, 0x01, 0xc3, 0x56, 0x6f, 0x4d, 0x41, 0xa6, 0x6f, 0x73, 0x9e, 0xad, 0xe0, 0x1b, 0x88, 0xa7, 0xba, 0xc8, 0xd9, 0x3e, 0x2c, 0xa1, 0xc3, 0x91, 0xe4, 0x01, 0xa7, 0x48, 0x8f, 0xdb, 0xe8, 0xca, 0xae, 0x7f, 0xd8, 0x6c, 0x9f, 0x80, 0x70, 0x5c, 0xe5, 0x16, 0x34, 0xf1, 0xeb, 0xb1, 0xcd, 0xa8, 0x26, 0xdf, 0x34, 0xa3, 0x86, 0xa8, 0xa3, 0x22, 0xfb, 0x37, 0x39, 0xdc, 0x45, 0xb2, 0xdf, 0xfa, 0x1d, 0x5c, 0xe3, 0xe8, 0x4c, 0x58, 0xd1, 0x03, 0xf3, 0x04, 0xe9, 0xb9, 0x62, 0xf0, 0x9c, 0x63, 0xe5, 0x2f, 0xe6, 0x88, 0x74, 0xad, 0x11, 0x7d, 0xf3, 0x1f, 0xb5, 0x9e, 0x88, 0x9e, 0x80, 0x1f, 0x3c, 0xa9, 0x93, 0x1f, 0xac, 0x72, 0xea, 0x20, 0x81, 0x9e, 0x4f, 0x97, 0xff, 0xfd, 0x56, 0x3a, 0xaa, 0x4e, 0xf8, 0x8b, 0x36, 0x9c, 0x30, 0x82, 0x45, 0x30, 0xa1, 0xe2, 0x97, 0xfe, 0xeb, 0xbf, 0xef, 0x3f, 0x6f, 0xd7, 0x45, 0xed, 0x64, 0x2c, 0x9e, 0x74, 0x5e, 0x44, 0x31, 0x13, 0x9c, 0xa4, 0xfd, 0xe2, 0x5b, 0x41, 0x53, 0xb0, 0x89, 0xf1, 0xcc, 0x3d, 0x51, 0xa4, 0xba, 0x74, 0x4e, 0xeb, 0x1a, 0xfd, 0xe7, 0x96, 0x4f, 0x58, 0xfb, 0x7e, 0x4f, 0x52, 0x4b, 0x92, 0xc2, 0xe9, 0x40, 0xdd, 0x58, 0x3f, 0x6d, 0x3e, 0x36, 0x94, 0x99, 0x22, 0xfa, 0x70, 0xb7, 0x81, 0x3b, 0x35, 0xeb, 0x84, 0x53, 0x1a, 0x58, 0x12, 0xc9, 0x5c, 0x5b, 0xf0, 0xaf, 0x8a, 0x5c, 0x30, 0xa5, 0x5b, 0xa6, 0x4f, 0x79, 0xb2, 0xee, 0xee, 0x8f, 0x8c, 0xa0, 0x28, 0x18, 0xe4, 0x23, 0x98, 0x51, 0x91, 0x39, 0xea, 0xc5, 0x1f, 0x62, 0x40, 0x32, 0x06, 0x23, 0x48, 0x27, 0x42, 0xac, 0x1b, 0x4e, 0xf6, 0x51, 0xe6, 0xc1, 0x77, 0x1b, 0x84, 0x28, 0xe2, 0x5f, 0x61, 0xc2, 0x30, 0x6a, 0x60, 0x20, 0xd3, 0x5d, 0x02, 0x6b, 0x36, 0x90, 0xd1, 0xff, 0xa2, 0x85, 0xe9, 0x4e, 0x66, 0x5f, 0x2a, 0xb4, 0xb4, 0x50, 0x3e, 0xb8, 0xcf, 0x01, 0xb9, 0x6d, 0xeb, 0xfe, 0xd2, 0xfa, 0x7a, 0x5c, 0x58, 0xfa, 0x47, 0xaf, 0xff, 0x3c, 0x43, 0xcf, 0x87, 0x00, 0xdb, 0x15, 0x61, 0xb6, 0x69, 0x87, 0xf0, 0xaa, 0x54, 0x36, 0xe3, 0x7d, 0xd6, 0x69, 0x7d, 0x51, 0x66, 0xa0, 0x52, 0x52, 0xd0, 0x99, 0x69, 0x37, 0x80, 0xf0, 0x38, 0xa2, 0x85, 0x9b, 0xfc, 0xe8, 0xdf, 0x54, 0xb6, 0x82, 0x67, 0xf2, 0x27, 0x9b, 0xbe, 0x43, 0xbc, 0x73, 0x0e, 0x17, 0xdc, 0x1a, 0xc0, 0x0e, 0x4a, 0xa7, 0x25, 0x48, 0x89, 0x78, 0xe6, 0xd8, 0x5a, 0x86, 0x6e, 0xe1, 0xd2, 0x3e, 0xec, 0xc9, 0x87, 0xd5, 0xc7, 0x7b, 0xcc, 0xbd, 0x7b, 0xf7, 0x52, 0x3a, 0xd9, 0x44, 0x39, 0x32, 0xe2, 0x80, 0x15, 0x5c, 0x4e, 0x64, 0x7d, 0x8c, 0xcd, 0x7e, 0xe6, 0xdd, 0x2b, 0xec, 0x03, 0x7f, 0x00, 0x75, 0x2b, 0xd4, 0x67, 0xc2, 0x04, 0x6b, 0xde, 0x4e, 0x75, 0x3c, 0x62, 0x78, 0x38, 0x56, 0x71, 0xa2, 0x2f, 0xad, 0x20, 0xfe, 0xbc, 0xfc, 0x4d, 0x1a, 0x10, 0xf2, 0xa8, 0xaf, 0xa7, 0x01, 0x5e, 0xac, 0x3c, 0xfc, 0x3e, 0xa5, 0xe2, 0x6a, 0x32, 0x36, 0x76, 0x06, 0x49, 0xe9, 0x2c, 0x0f, 0x6f, 0x80, 0xbd, 0x55, 0xb2, 0x49, 0xb3, 0x50, 0x24, 0x8e, 0x5e, 0x26, 0xd2, 0x71, 0x00, 0xbf, 0x71, 0x2e, 0x52, 0xe8, 0x7e, 0xc0, 0xd5, 0xd2, 0xae, 0x90, 0xfb, 0x9d, 0xb7, 0x66, 0x45, 0x48, 0x3b, 0x3a, 0x0d, 0x1a, 0x09, 0x55, 0x74, 0x99, 0x54, 0xaa, 0x48, 0xaf, 0xbe, 0x9d, 0xa7, 0xe0, 0xe0, 0x46, 0x96, 0x5e, 0x51, 0x38, 0xd1, 0x70, 0x3b, 0xaf, 0x8f, 0x74, 0xc7, 0x37, 0xa4, 0xe1, 0x63, 0x9b, 0x12, 0xd0, 0xb9, 0xa6, 0xff, 0x2f, 0xee, 0x58, 0x85, 0xfd, 0x5e, 0xdc, 0xb3, 0xdb, 0x2b, 0xbe, 0xa9, 0x37, 0x03, 0xe1, 0xe2, 0x4b, 0x7a, 0xcf, 0xf2, 0x5e, 0x43, 0x96, 0x2d, 0xa5, 0xae, 0x43, 0x74, 0xde, 0xea, 0x3c, 0x91, 0xa6, 0x2a, 0xc5, 0xe2, 0x35, 0x04, 0xc0, 0x3b, 0x17, 0xa0, 0xf0, 0x5d, 0x8d, 0xc7, 0xc0, 0x37, 0x75, 0xdc, 0xef, 0x65, 0xb9, 0x8e, 0x83, 0xd0, 0x8f, 0xf9, 0x49, 0x65, 0x74};
static const uint8_t CT_2[1088] = {0xba, 0x0f, 0xcd, 0xe5, 0x74, 0x21, 0x49, 0x32, 0x3a, 0xf3, 0x3c, 0xd2, 0x96, 0x0f, 0x76, 0x28, 0x4d, 0x39, 0x70, 0x23, 0x74, 0xc3, 0x13, 0x7f, 0x18, 0x0e, 0xef, 0xdd, 0xcf, 0xf3, 0xce, 0x43, 0x29, 0x92, 0x4e, 0x75, 0x0c, 0xc8, 0xc8, 0x89, 0xfc, 0x42, 0x00, 0xbd, 0x27, 0x58, 0x51, 0x44, 0x82, 0x99, 0x20, 0x32, 0xab, 0xec, 0xfd, 0x43, 0xe0, 0x20, 0xc8, 0xaf, 0xc9, 0x1d, 0x9d, 0xaa, 0x4a, 0x61, 0x5b, 0x49, 0xa6, 0x37, 0x56, 0x1e, 0x84, 0xc1, 0x2e, 0xa3, 0xc0, 0x0f, 0x1b, 0x27, 0xba, 0x0b, 0x66, 0x92, 0x4a, 0x52, 0x1d, 0xa7, 0x58, 0xbc, 0xe2, 0x2b, 0x42, 0x60, 0x1b, 0x90, 0x19, 0x99, 0x73, 0xc9, 0x21, 0x27, 0x01, 0x46, 0x51, 0xf2, 0x14, 0xb2, 0x26, 0x94, 0xac, 0x01, 0xc8, 0x53, 0x9d, 0x43, 0x5f, 0x77, 0x35, 0x7a, 0x22, 0x1f, 0x64, 0x7e, 0x86, 0x37, 0x89, 0x9a, 0x5d, 0xe3, 0xcf, 0x06, 0x04, 0x16, 0x0b, 0x0a, 0x6c, 0x87, 0xa5, 0xe1, 0x39, 0xac, 0x1d, 0x78, 0x1f, 0x94, 0xb8, 0x2c, 0x89, 0x70, 0xda, 0xd4, 0xd8, 0xf5, 0x41, 0xe9, 0xea, 0x74, 0xd0, 0x8c, 0x31, 0x33, 0xf8, 0x6d, 0xa9, 0x68, 0xbe, 0xd4, 0xd9, 0xc5, 0xb4, 0x35, 0x4c, 0x15, 0x9f, 0x6b, 0xb3, 0xba, 0x5d, 0x3b, 0x21, 0x3f, 0x2a, 0x22, 0x6e, 0xec, 0xe3, 0x2b, 0x85, 0x5e, 0xcc, 0x11, 0x05, 0x90, 0x98, 0xc6, 0x4e, 0x21, 0xbd, 0xc3, 0x04, 0xd6, 0x6e, 0xb2, 0x20, 0x5e, 0xa8, 0xf6, 0x8e, 0xb5, 0x2d, 0x81, 0xbf, 0xa2, 0x16, 0xc9, 0x35, 0x4a, 0xc4, 0x46, 0x36, 0xbb, 0x21, 0x3e, 0xce, 0x6f, 0x4f, 0x8e, 0x51, 0x98, 0xdb, 0x5b, 0xd3, 0xc3, 0x30, 0xc2, 0x17, 0x42, 0xbf, 0xe8, 0x58, 0x9f, 0x22, 0x57, 0xc0, 0xdc, 0x12, 0xaf, 0x0e, 0x8f, 0x19, 0xd0, 0xa8, 0x61, 0x0a, 0x6a, 0xf2, 0xaf, 0x01, 0xfb, 0x84, 0xdf, 0x75, 0x66, 0xa9, 0xed, 0xfc, 0x7a, 0x4b, 0xf5, 0xc0, 0xbb, 0x5c, 0xe1, 0x4c, 0xe4, 0x11, 0xfb, 0x4f, 0x73, 0x9c, 0x5a, 0x22, 0xc3, 0x8f, 0xf7, 0x36, 0xe0, 0xc0, 0xcd, 0xd9, 0xe3, 0x11, 0x49, 0xe6, 0xfd, 0x34, 0xca, 0xa5, 0x24, 0xd8, 0x93, 0x52, 0xef, 0xeb, 0xb4, 0xa5, 0xb6, 0x9e, 0xf7, 0x26, 0xab, 0xf5, 0xc8, 0x93, 0xe6, 0x29, 0xeb, 0xb8, 0x12, 0x08, 0xac, 0xec, 0xc7, 0xa5, 0x52, 0x13, 0xb8, 0x5c, 0x10, 0xc2, 0x95, 0xf9, 0x9b, 0x44, 0xe6, 0xca, 0x6d, 0x3a, 0x6d, 0x06, 0xae, 0x2c, 0xd4, 0x0f, 0x95, 0x2b, 0xfb, 0xa1, 0xc8, 0x03, 0x5d, 0xce, 0xaf, 0x6c, 0xab, 0x02, 0x38, 0xe0, 0xbd, 0xff, 0x39, 0xe1, 0xf7, 0xdb, 0x58, 0xa2, 0x05, 0x2c, 0xf8, 0x57, 0x40, 0x43, 0x63, 0x9a, 0x08, 0x70, 0x4f, 0x14, 0xa6, 0xa2, 0x0a, 0xe2, 0xa4, 0x14, 0x95, 0x08, 0x6e, 0x68, 0xc2, 0x6f, 0xc3, 0xa1, 0xa0, 0xe9, 0xc3, 0x34, 0x18, 0xaa, 0xd4, 0x50, 0x79, 0x50, 0xad, 0x2c, 0x29, 0x3b, 0x6a, 0xa6, 0x48, 0xb0, 0x2b, 0x72, 0x73, 0x97, 0x0e, 0xd9, 0x67, 0x71, 0xd0, 0x39, 0x31, 0xf6, 0xf2, 0xd5, 0x72, 0x23, 0x49, 0xd6, 0xce, 0x92, 0x7e, 0xb0, 0x89, 0x1a, 0xb9, 0x3a, 0xb6, 0xea, 0xe6, 0xb0, 0x6c, 0x6e, 0x63, 0x9d, 0xab, 0xfd, 0xe8, 0x30, 0x12, 0x00, 0xfe, 0xbd, 0x53, 0xd0, 0xfa, 0x45, 0xb5, 0x24, 0x9a, 0x60, 0x97, 0x54, 0xfc, 0x51, 0x76, 0x10, 0x57, 0x8b, 0x18, 0x1d, 0xac, 0xde, 0x30, 0x9d, 0xcd, 0xa8, 0x5f, 0x9b, 0x34, 0x0e, 0x81, 0x01, 0x61, 0x3b, 0xb7, 0xa9, 0x76, 0xd3, 0xf4, 0x73, 0x79, 0x49, 0xbd, 0x54, 0x71, 0x13, 0x79, 0x5c, 0x34, 0x29, 0x3f, 0x5d, 0xae, 0x06, 0xaf, 0x9c, 0x81, 0x91, 0x41, 0x60, 0x96, 0xe6, 0xf7, 0xc8, 0xf9, 0xc4, 0x2c, 0xcf, 0x37, 0x06, 0x30, 0xce, 0x7b, 0x48, 0x21, 0x40, 0xdd, 0x10, 0x78, 0xe7, 0xe6, 0x21, 0xb4, 0x58, 0xad, 0x76, 0xb2, 0x07, 0x28, 0xda, 0xf4, 0x5e, 0xec, 0x86, 0xe9, 0x6e, 0x79, 0x04, 0x85, 0x62, 0x6f, 0x02, 0x2a, 0x6f, 0x02, 0x58, 0xd6, 0x75, 0x2f, 0x0d, 0xe6, 0x15, 0x0a, 0x61, 0x9f, 0x36, 0xa6, 0x18, 0x9b, 0x40, 0x96, 0x2b, 0x2f, 0xc8, 0xb3, 0x92, 0x9a, 0x26, 0xf8, 0xb9, 0xcf, 0x56, 0x19, 0x92, 0x86, 0xba, 0xce, 0xce, 0x5f, 0x64, 0xb4, 0x52, 0xb9, 0x65, 0x5b, 0x82, 0x71, 0x3c, 0x7c, 0x4a, 0xc3, 0xd6, 0x18, 0xf5, 0x05, 0xc9, 0xbb, 0xbf, 0x3f, 0xef, 0x93, 0x8c, 0xd8, 0x86, 0x4b, 0x31, 0x63, 0xb9, 0x32, 0x4f, 0x28, 0x09, 0x21, 0x6b, 0x89, 0xe5, 0x4d, 0xde, 0xa4, 0x58, 0xc5, 0x14, 0xe5, 0xe8, 0xcc, 0x8f, 0x80, 0x9e, 0x28, 0x0c, 0xb5, 0x87, 0x49, 0x89, 0x12, 0x4f, 0xad, 0x53, 0x7e, 0x5b, 0x5c, 0x27, 0xc1, 0x56, 0xdd, 0x7b, 0xc7, 0xab, 0x40, 0x5f, 0x93, 0x18, 0x60, 0x4b, 0x14, 0x12, 0x61, 0x25, 0x66, 0xbd, 0x3d, 0xfc, 0x16, 0x94, 0x4c, 0x18, 0x6e, 0x0e, 0x21, 0xad, 0xb7, 0x6c, 0xe1, 0x73, 0x4f, 0xc6, 0xe0, 0x01, 0xa7, 0xc9, 0x4d, 0xb3, 0x4f, 0x53, 0xca, 0x07, 0xef, 0x2a, 0x2b, 0x6a, 0xca, 0x61, 0x3b, 0x3b, 0x8a, 0x4b, 0xb3, 0x2a, 0xb3, 0x05, 0x0a, 0x61, 0xb2, 0x64, 0xd8, 0xd7, 0x4c, 0x21, 0x2e, 0x0e, 0x26, 0xe8, 0xda, 0xb2, 0x1c, 0xe2, 0x56, 0x9f, 0xc2, 0x57, 0x12, 0xd1, 0xae, 0x25, 0x3a, 0x80, 0xbe, 0x12, 0x08, 0x3b, 0xb7, 0x7a, 0xf3, 0x11, 0xf8, 0x06, 0xa9, 0x67, 0x97, 0xb5, 0x64, 0x10, 0x6a, 0x5d, 0x17, 0xb8, 0x63, 0xbf, 0xea, 0x0b, 0xa2, 0xb8, 0xa6, 0xbb, 0xb8, 0x81, 0xdf, 0x2a, 0x01, 0xe2, 0x72, 0x63, 0xc1, 0x2d, 0x5d, 0x39, 0xb0, 0xa6, 0xf6, 0x39, 0xb7, 0x05, 0x99, 0xaa, 0xfd, 0xd3, 0x54, 0xf2, 0xe5, 0x41, 0x13, 0x52, 0xc8, 0x9f, 0xc9, 0x98, 0xc3, 0x93, 0x17, 0xd0, 0xef, 0xdd, 0xe6, 0xc1, 0x97, 0x75, 0xa3, 0xd0, 0x66, 0x11, 0x69, 0x6f, 0x9c, 0xe4, 0xc2, 0x5d, 0x7c, 0xc1, 0x35, 0x89, 0xd8, 0xb0, 0x64, 0x8a, 0x9f, 0xbf, 0x74, 0x90, 0xf9, 0x13, 0x78, 0xb1, 0xd2, 0xeb, 0x70, 0x2a, 0x37, 0xf4, 0x5e, 0xce, 0x78, 0x14, 0x18, 0x00, 0x43, 0xf3, 0x43, 0xdf, 0xbe, 0x9f, 0x56, 0xa3, 0xdd, 0x27, 0xb2, 0x5f, 0x4d, 0xa6, 0xf6, 0x6e, 0x2f, 0xd0, 0x41, 0x4c, 0x58, 0x61, 0xc8, 0xa8, 0x4b, 0x60, 0xbe, 0xdc, 0xe2, 0x73, 0x6b, 0x0f, 0x47, 0x21, 0xc9, 0x0b, 0xf8, 0x40, 0xd1, 0xd8, 0x16, 0x98, 0x8b, 0xc0, 0x6f, 0x0d, 0xef, 0xd3, 0xbe, 0x0e, 0xdc, 0x9c, 0xa8, 0xf0, 0x0b, 0x57, 0xd0, 0x7e, 0x27, 0x7c, 0x0b, 0x9f, 0x41, 0xc4, 0xaa, 0xf1, 0xe2, 0x0b, 0xef, 0x14, 0x9a, 0x52, 0xca, 0x5d, 0xcc, 0x4a, 0xbc, 0x5a, 0xad, 0x70, 0xa2, 0xb2, 0x07, 0xf8, 0x85, 0x63, 0xbf, 0xc5, 0x5b, 0xa7, 0xc7, 0xa9, 0x17, 0x86, 0xa6, 0xb3, 0x65, 0x77, 0xdb, 0xef, 0x80, 0x09, 0x79, 0xcc, 0x1c, 0x64, 0x64, 0x7d, 0x2c, 0xe6, 0xec, 0x89, 0x2b, 0xab, 0x70, 0x77, 0x26, 0x0b, 0x1b, 0xd8, 0xa6, 0xb2, 0xff, 0x17, 0xbf, 0x68, 0x93, 0xcb, 0x7e, 0x24, 0x39, 0x4f, 0x29, 0x1b, 0xb0, 0xa1, 0xba, 0xd6, 0xde, 0xb5, 0x4f, 0x65, 0x09, 0x1f, 0x6f, 0x10, 0x54, 0xb1, 0xc4, 0xfc, 0x3e, 0x2c, 0xdd, 0x9c, 0xb3, 0xba, 0x53, 0x4b, 0x3a, 0x13, 0x85, 0x83, 0x1c, 0x85, 0x6e, 0x51, 0xf4, 0x99, 0xb8, 0x40, 0x31, 0x1f, 0x12, 0x05, 0x13, 0x8b, 0x63, 0xde, 0xbf, 0x57, 0x19, 0x45, 0xa6, 0x1b, 0x01, 0x51, 0x38, 0x1f, 0xc7, 0x85, 0x53, 0x7d, 0xa0, 0x6a, 0x0a, 0x15, 0x24, 0xb0, 0x8b, 0xda, 0x65, 0x60, 0xf2, 0x35, 0x2e, 0xa5, 0xe2, 0xa5, 0x2c, 0x9c, 0x36, 0x30, 0xc4, 0xc3, 0xcf, 0xd7, 0xbd, 0xb5, 0xa0, 0x7e, 0x3d, 0x62, 0x71, 0x0e, 0x7f, 0x15, 0xe4, 0xfd, 0x7e, 0x49, 0xbe, 0x8d, 0x16, 0x09, 0x1f, 0xb8, 0x0e, 0x72, 0xfa, 0x51, 0xae, 0xdb, 0x1f};
static const uint8_t CT_3[1568] = {0x13, 0xab, 0x88, 0x8b, 0x76, 0x0e, 0xac, 0x15, 0x26, 0xdb, 0x0f, 0x4c, 0x9e, 0x69, 0x91, 0x14, 0x5d, 0xc0, 0x43, 0x1d, 0x84, 0xf7, 0x2c, 0x67, 0x77, 0xd6, 0x56, 0x5e, 0x6f, 0x01, 0xca, 0x65, 0xd3, 0x1b, 0x41, 0x70, 0x7c, 0xd9, 0xfe, 0x09, 0x4e, 0x5d, 0x87, 0xfd, 0x2c, 0xf2, 0xca, 0xf9, 0x8a, 0x29, 0x19, 0xc2, 0x66, 0x39, 0xb1, 0xf6, 0xa0, 0xe5, 0x7a, 0x65, 0x93, 0x69, 0xfd, 0x91, 0xc6, 0x7f, 0x26, 0x61, 0x18, 0xf3, 0xbb, 0x27, 0xba, 0x1d, 0xec, 0x62, 0xec, 0x1c, 0x57, 0xee, 0xfe, 0xc0, 0x6b, 0x58, 0x1b, 0xfb, 0x2a, 0xfe, 0x16, 0x48, 0x22, 0xd5, 0x96, 0x58, 0x2f, 0x03, 0xdb, 0x12, 0xbc, 0xcf, 0x7e, 0x79, 0xf5, 0x6c, 0x53, 0x95, 0x75, 0x95, 0xed, 0x4f, 0x71, 0x84, 0x46, 0x11, 0xff, 0x6d, 0xe2, 0xd5, 0x65, 0x6c, 0xa8, 0x24, 0x8a, 0x2d, 0x51, 0xda, 0x64, 0xdb, 0x83, 0xb7, 0x25, 0xbb, 0xf2, 0x8f, 0xfb, 0xc6, 0x1f, 0x13, 0x12, 0xec, 0xa2, 0xca, 0x58, 0x17, 0xd6, 0xc2, 0x33, 0x97, 0x8a, 0x32, 0x35, 0xce, 0x3c, 0x62, 0xac, 0x46, 0x4e, 0x5c, 0xe9, 0xae, 0x46, 0x92, 0x49, 0x45, 0x59, 0x52, 0xb6, 0x77, 0x60, 0x7a, 0xc6, 0x87, 0x28, 0x24, 0xda, 0x90, 0x2e, 0xbe, 0xd6, 0x53, 0x84, 0x3f, 0x69, 0x2a, 0xe4, 0xa0, 0x95, 0x4e, 0x61, 0xf8, 0xcd, 0xb6, 0xb1, 0x95, 0x4c, 0x36, 0x98, 0xf3, 0x82, 0xbb, 0x00, 0x66, 0xa9, 0x5b, 0xc7, 0xbc, 0x16, 0xee, 0xcb, 0xd3, 0xcb, 0xca, 0x5c, 0x6d, 0x06, 0x5b, 0x55, 0x14, 0x3c, 0xe9, 0x58, 0x9d, 0x5d, 0x3b, 0x6a, 0xec, 0xc4, 0x4c, 0x67, 0xe9, 0xaf, 0xa4, 0xf4, 0x04, 0xc0, 0xa2, 0x07, 0x28, 0x96, 0x7f, 0xb3, 0x9d, 0x07, 0x60, 0xcf, 0xd1, 0xdc, 0x69, 0xa0, 0x91, 0x4a, 0xd4, 0x6a, 0x1a, 0x64, 0xb8, 0x40, 0xe0, 0xe5, 0xeb, 0xd0, 0xc5, 0x54, 0xcb, 0x0e, 0x47, 0xb9, 0xee, 0x35, 0x29, 0x1f, 0x9a, 0xaf, 0xb3, 0x9e, 0xdb, 0xdb, 0x0d, 0x85, 0xbc, 0xf4, 0x5e, 0x78, 0x44, 0xc0, 0x03, 0x04, 0xc1, 0x9f, 0xa4, 0x35, 0x1a, 0x25, 0xe8, 0x86, 0xd6, 0xa1, 0xc7, 0x42, 0x5e, 0x38, 0xb9, 0x33, 0x84, 0xed, 0xee, 0x6d, 0xa6, 0xeb, 0x33, 0xb3, 0x8e, 0x82, 0x8c, 0xa4, 0x98, 0xb0, 0xe9, 0x7c, 0xf6, 0x23, 0x41, 0xb6, 0xf2, 0xcc, 0xe1, 0x95, 0x50, 0xc9, 0xe8, 0x45, 0x14, 0xba, 0x52, 0xd0, 0x86, 0x2c, 0xc3, 0x01, 0xaa, 0x4d, 0xf2, 0x66, 0xa4, 0x88, 0xa8, 0xb3, 0x33, 0xb0, 0x9e, 0x87, 0xda, 0xad, 0x81, 0x79, 0xbb, 0x7c, 0x46, 0x69, 0xc9, 0xe7, 0x57, 0x79, 0x8e, 0x9a, 0xfb, 0x74, 0x35, 0x93, 0x87, 0x12, 0xf2, 0x76, 0x97, 0xcb, 0x94, 0xa3, 0xe6, 0xbc, 0x2e, 0xc7, 0x4b, 0x61, 0x93, 0x6d, 0x2d, 0x4a, 0xb3, 0xfc, 0x38, 0xa1, 0xd6, 0xa7, 0xf6, 0xd1, 0xba, 0x31, 0xa7, 0x6d, 0x30, 0xa8, 0x86, 0x46, 0x5e, 0xf7, 0x3a, 0x2a, 0xa4, 0xc8, 0x49, 0xe9, 0x52, 0x9d, 0x17, 0xfe, 0x74, 0x20, 0x57, 0x81, 0xa0, 0x59, 0xf2, 0x9c, 0x01, 0x72, 0xfd, 0x9f, 0xbf, 0x97, 0x39, 0xcd, 0x48, 0x27, 0xad, 0x40, 0xe0, 0x90, 0x70, 0xc0, 0x00, 0x5b, 0x16, 0x22, 0xe8, 0xd2, 0xae, 0x3f, 0xd9, 0x33, 0x56, 0xda, 0xe2, 0x4a, 0x77, 0xc7, 0xa0, 0xc4, 0xa5, 0x42, 0xd2, 0x1f, 0x68, 0x8f, 0x06, 0xd4, 0x6c, 0xc2, 0xb1, 0xbb, 0x1a, 0x68, 0x18, 0x7c, 0x3b, 0xc3, 0xd7, 0xdc, 0xc6, 0x5a, 0x3b, 0x7c, 0x81, 0x71, 0x69, 0xf2, 0x50, 0x97, 0x96, 0xd8, 0x2e, 0x7a, 0x9e, 0x51, 0xc9, 0xf2, 0x8d, 0x1f, 0x1f, 0xb0, 0x8a, 0xc7, 0x2c, 0x1e, 0x06, 0x1f, 0x72, 0x8d, 0x94, 0x4d, 0x70, 0xeb, 0xa7, 0x29, 0x5d, 0x78, 0x14, 0x0d, 0x5e, 0xef, 0x27, 0x6a, 0x41, 0x79, 0x12, 0x7f, 0x09, 0x25, 0xa8, 0xe2, 0xf9, 0xc0, 0xae, 0x06, 0xa9, 0xc0, 0xb7, 0xfb, 0x87, 0x09, 0x88, 0x5a, 0xef, 0x14, 0xa0, 0x69, 0x45, 0xe0, 0xf3, 0x19, 0x7a, 0x49, 0x2f, 0xad, 0x97, 0xe6, 0x77, 0xeb, 0x9f, 0x5b, 0xfd, 0x9f, 0x99, 0x95, 0x18, 0xf7, 0x36, 0x8d, 0xe7, 0xde, 0x0c, 0x41, 0x00, 0x8f, 0xbe, 0x71, 0x09, 0xf6, 0xc5, 0x04, 0x4e, 0x24, 0x5b, 0xff, 0xba, 0xdf, 0xa7, 0x6b, 0x4f, 0xc2, 0x58, 0x5f, 0x9f, 0xdc, 0xe4, 0xf7, 0x4f, 0xeb, 0x54, 0xd3, 0x9b, 0x2d, 0x7a, 0x24, 0xb5, 0x84, 0x3e, 0x2f, 0xdd, 0xb7, 0xf4, 0xe7, 0x5a, 0x34, 0x79, 0x04, 0x7a, 0x72, 0x1a, 0xe4, 0xf7, 0x6d, 0x68, 0xb0, 0xfd, 0x8c, 0x54, 0x23, 0xc0, 0x5a, 0x66, 0xeb, 0x64, 0xc4, 0x02, 0x82, 0x6e, 0x5a, 0x47, 0x29, 0x7a, 0x3f, 0x82, 0x05, 0x14, 0x02, 0x1c, 0xb9, 0x33, 0x2a, 0x54, 0x27, 0xf2, 0x1f, 0x28, 0xd2, 0x09, 0x0f, 0x21, 0x58, 0x7e, 0x77, 0xec, 0x0a, 0xe7, 0xfd, 0x6a, 0x55, 0x02, 0x0c, 0x0c, 0xf3, 0x80, 0xd9, 0xec, 0xc2, 0xeb, 0x09, 0x50, 0xdd, 0x81, 0xfb, 0x54, 0x96, 0x21, 0x7d, 0xf7, 0xbb, 0x9d, 0xd1, 0xd5, 0x5e, 0x02, 0x5f, 0x75, 0x0c, 0xb5, 0x63, 0xa5, 0x36, 0xc9, 0x76, 0x58, 0xc8, 0xab, 0x84, 0x80, 0xa0, 0x1e, 0x4a, 0x03, 0x23, 0x38, 0x9d, 0x03, 0x71, 0x43, 0x93, 0xe6, 0xe2, 0xfc, 0xea, 0xe0, 0xe7, 0xa7, 0xb7, 0x59, 0x54, 0x6a, 0x3b, 0xa4, 0x1c, 0xef, 0x5a, 0x8d, 0xe8, 0x8d, 0x19, 0x6c, 0x76, 0x37, 0x13, 0x9a, 0x90, 0x20, 0xfd, 0x23, 0x19, 0x35, 0x7f, 0x35, 0x9c, 0xd6, 0x04, 0xf8, 0xe4, 0x90, 0x10, 0xe9, 0x43, 0x34, 0x94, 0x43, 0xb7, 0x64, 0xb3, 0x98, 0x4a, 0xf6, 0x74, 0x85, 0x72, 0x4f, 0xe5, 0xfa, 0x40, 0x81, 0xe4, 0x2d, 0x1b, 0x86, 0x21, 0x30, 0x16, 0xfe, 0xdd, 0x52, 0x62, 0x26, 0xb0, 0xc2, 0xee, 0xa1, 0x35, 0x8a, 0xc3, 0x49, 0x01, 0x31, 0xcf, 0xbb, 0x9b, 0xb3, 0x1b, 0xb1, 0x66, 0x03, 0xb9, 0x49, 0xb4, 0xac, 0x6b, 0x57, 0x03, 0x40, 0xc7, 0x49, 0x17, 0xae, 0x2b, 0xd4, 0x30, 0x8c, 0x11, 0x6b, 0xbf, 0x93, 0xcf, 0x08, 0xe2, 0x30, 0xbe, 0x50, 0x30, 0xf5, 0xa1, 0x5d, 0x86, 0x80, 0xcd, 0xd9, 0x96, 0x49, 0x7d, 0x18, 0xab, 0x36, 0xa3, 0x1d, 0x05, 0x58, 0x5f, 0xbc, 0xe5, 0x3e, 0xfc, 0xe1, 0xd3, 0x48, 0x1e, 0x38, 0xc4, 0x03, 0x10, 0x89, 0xf2, 0x50, 0x04, 0xdb, 0xdc, 0x15, 0x1c, 0x5d, 0x4b, 0xc3, 0xe1, 0x02, 0x43, 0x00, 0x3c, 0xf8, 0x18, 0x6c, 0x0e, 0xf3, 0x29, 0x5d, 0x78, 0xd9, 0x10, 0x1c, 0x61, 0x5b, 0x3a, 0x7b, 0xaa, 0x60, 0x18, 0xb9, 0x20, 0xf4, 0xf2, 0x7d, 0x4f, 0xbc, 0x35, 0x69, 0xe5, 0xdd, 0x25, 0xc9, 0x53, 0xd7, 0xc1, 0x11, 0x7a, 0x22, 0xc6, 0xb7, 0x66, 0xcf, 0x58, 0x22, 0x9f, 0x89, 0xe0, 0x64, 0xb2, 0x89, 0xc9, 0xfd, 0x87, 0x06, 0xf6, 0x58, 0x27, 0x1f, 0x39, 0xc2, 0xbf, 0x88, 0x33, 0x0d, 0x37, 0xe6, 0x75, 0xf2, 0x33, 0xc4, 0x21, 0x49, 0xec, 0xd7, 0x9f, 0x6c, 0xe0, 0x8e, 0xbd, 0xa2, 0x31, 0x6e, 0x17, 0xf9, 0xa2, 0x1a, 0xa1, 0x30, 0xf7, 0xe6, 0xb3, 0x13, 0xcc, 0x28, 0xe1, 0x67, 0x16, 0x7e, 0x9a, 0x17, 0x8d, 0x47, 0x9a, 0xfb, 0xe6, 0xb7, 0x0e, 0x46, 0x13, 0x4a, 0x26, 0xe4, 0xca, 0x51, 0x1f, 0x5f, 0xb9, 0x5c, 0xda, 0x9e, 0x2a, 0x0c, 0xda, 0x94, 0x86, 0x2c, 0x84, 0x03, 0x90, 0xf7, 0x2b, 0xdd, 0x28, 0xc3, 0xa3, 0x3f, 0xe7, 0x28, 0x2a, 0x53, 0x59, 0xd4, 0x1e, 0x5c, 0x89, 0x74, 0x8d, 0x24, 0x70, 0xe2, 0xa0, 0x5c, 0xc3, 0x49, 0x66, 0x09, 0x99, 0x10, 0xb4, 0x0c, 0x9d, 0x4c, 0x88, 0x12, 0x9a, 0x96, 0x60, 0x0b, 0xcb, 0x2e, 0xfb, 0xd8, 0x24, 0x9b, 0x7b, 0x9c, 0x55, 0x02, 0x03, 0x2e, 0xa9, 0x40, 0x0f, 0x75, 0x01, 0xcd, 0x75, 0xc4, 0xfc, 0x14, 0xdf, 0x68, 0x66, 0xd3, 0x45, 0x1f, 0x00, 0xb7, 0x88, 0xb2, 0x82, 0x92, 0x49, 0x52, 0xce, 0x03, 0xd7, 0xbf, 0x70, 0x28, 0xfa, 0xb3, 0x3d, 0xc4, 0xb0, 0x70, 0xf6, 0x36, 0x22, 0xb8, 0xa2, 0xfa, 0x8b, 0x03, 0x9f, 0x35, 0xed, 0x5d, 0x15, 0xeb, 0xfc, 0x83, 0x18, 0x52, 0x60, 0x7c, 0x98, 0x8c, 0xcc, 0x64, 0xaf, 0x45, 0x5c, 0x61, 0x6b, 0x87, 0x29, 0x97, 0x0f, 0x8d, 0x30, 0xea, 0x0b, 0x74, 0x49, 0x6a, 0x18, 0x94, 0xd8, 0x98, 0xdd, 0x1c, 0x78, 0x5a, 0x94, 0x55, 0xd2, 0x3b, 0x33, 0xa6, 0x42, 0xb9, 0x51, 0x3a, 0x79, 0xc9, 0xb9, 0x58, 0x9e, 0x49, 0x30, 0x53, 0x72, 0x02, 0xe3, 0x2a, 0x23, 0xb5, 0x51, 0xba, 0x8a, 0xf7, 0x74, 0xd2, 0xce, 0xaa, 0x5c, 0xd0, 0xda, 0xdf, 0xa2, 0x78, 0xfa, 0x31, 0xef, 0x81, 0xa7, 0xb1, 0x55, 0x1f, 0xe7, 0x38, 0x88, 0xf2, 0x60, 0xfb, 0x61, 0xb7, 0x4b, 0xc7, 0xb0, 0x4e, 0x7f, 0x98, 0x1d, 0xd2, 0x1a, 0x66, 0x1b, 0x64, 0xa0, 0x4a, 0x69, 0x2e, 0x80, 0x00, 0x20, 0x31, 0xa4, 0xa5, 0xeb, 0x43, 0x84, 0xbe, 0xec, 0xcd, 0x6a, 0x7b, 0x3d, 0xf4, 0xbd, 0x95, 0xe0, 0x33, 0xd4, 0x44, 0x99, 0xdc, 0x50, 0x3b, 0xc7, 0xf8, 0x77, 0x45, 0xee, 0xab, 0x5e, 0x9a, 0x9e, 0x26, 0x57, 0x52, 0xc7, 0x7d, 0xdd, 0xf3, 0x32, 0x3b, 0x33, 0xe1, 0xdd, 0x80, 0xbd, 0x94, 0x68, 0x0b, 0x2a, 0xe5, 0xb3, 0xaf, 0x8f, 0xbf, 0x4f, 0xe9, 0x40, 0xeb, 0x49, 0x7a, 0x0e, 0xed, 0xa1, 0x46, 0xdf, 0x83, 0x89, 0xf2, 0xc9, 0x62, 0xee, 0xda, 0x95, 0x75, 0x31, 0x8d, 0xf8, 0x7f, 0xa8, 0x82, 0x78, 0x88, 0xdb, 0x6a, 0x6f, 0x2b, 0x2e, 0x0e, 0x7b, 0x67, 0xe9, 0x6b, 0x71, 0x60, 0xbc, 0x30, 0x53, 0xdc, 0x50, 0xa9, 0x13, 0x50, 0x0e, 0xc3, 0xdc, 0xa3, 0x28, 0x60, 0x84, 0x83, 0x9b, 0x17, 0x27, 0xc5, 0xde, 0x5b, 0xd4, 0x12, 0x8d, 0x7e, 0x88, 0xa7, 0x8a, 0xa3, 0xd3, 0xe6, 0x33, 0xa2, 0x52, 0xdb, 0x04, 0xf1, 0xb2, 0x95, 0xa9, 0xee, 0x3d, 0x49, 0xf0, 0x6a, 0x0e, 0x7b, 0x00, 0xca, 0xfb, 0x01, 0x0d, 0x7e, 0x61, 0x90, 0x26, 0xfe, 0xd9, 0xd6, 0xda, 0x44, 0x2f, 0xb2, 0x99, 0x97, 0x63, 0xf5, 0x26, 0x77, 0x45, 0x1a, 0xf9, 0xe8, 0x00, 0x3e, 0x56, 0x1d, 0xbb, 0xc4, 0x7c, 0x9f, 0x90, 0x79, 0x47, 0x62, 0x8e, 0xb5, 0x00, 0xa9, 0xcb, 0xaf, 0xa5, 0xb8, 0x5c, 0x82, 0xea, 0xb4, 0x4b, 0x24, 0x76, 0x44, 0x16, 0xed, 0xd5, 0x3b, 0xf5, 0x2e, 0xe0, 0xa4, 0xec, 0x00, 0x81, 0x98, 0x3e, 0x7c, 0xa7, 0xd7, 0x26, 0x1c, 0x95, 0xf5, 0x03, 0x27, 0xbe, 0x8a, 0xb8, 0xb3, 0x4e, 0x26, 0x42, 0x9d, 0xde, 0x25, 0xf0, 0x71, 0x89, 0x34, 0x2a, 0x32, 0x6e, 0xee, 0x9a, 0x9b, 0x1e, 0x41, 0xed, 0x71, 0xa9, 0x87, 0x8f, 0x4b, 0x6f, 0x33, 0xce, 0xe3, 0xf1, 0x94, 0xa8, 0x5e, 0xdf, 0xab, 0x0e, 0x26, 0x11, 0xe4, 0x0b, 0x56, 0x72, 0x9f, 0x07, 0x70, 0x12, 0x75, 0x03, 0xb1, 0xd1, 0x7c, 0xee, 0x77, 0x04, 0xe1, 0xcf, 0x83, 0x85, 0x31, 0x97, 0xf2, 0xf7, 0xb3, 0x8a, 0xd6, 0x96, 0x38, 0x03, 0x8a, 0x60, 0x26, 0x8a, 0xbc, 0xc7, 0x17, 0x35, 0x0c, 0x20, 0x37, 0x80, 0x2d, 0x47, 0x4c, 0x6c, 0x33, 0x36, 0x63, 0x48, 0xac, 0x87, 0x59, 0x3a, 0x18, 0x7b, 0x34, 0xf4, 0x8b, 0xd6, 0x38, 0x1f, 0xc8, 0x00, 0xe6, 0x2b, 0x6d, 0xde, 0x1f, 0x45, 0x2e, 0x08, 0x3a, 0xcc, 0x5b, 0x77, 0xc4, 0x3d, 0xee, 0x0b, 0xca, 0x3e, 0x8d, 0x7e, 0xa8, 0x6f, 0x6f, 0x67, 0xb3, 0xbe, 0xf1, 0x03, 0xc4};
static const uint8_t CT_4[1568] = {0x11, 0x06, 0x67, 0x4b, 0x8f, 0xb7, 0x8c, 0xf6, 0x40, 0x70, 0xc4, 0x66, 0x0d, 0x42, 0xe9, 0x17, 0xcc, 0x3b, 0xc3, 0xf5, 0x5d, 0xab, 0xda, 0xd0, 0xd6, 0x01, 0x4c, 0xa2, 0x14, 0xf2, 0xd2, 0xb8, 0xda, 0x0f, 0x38, 0xaf, 0x96, 0x22, 0x9d, 0xd9, 0xdf, 0xce, 0x50, 0x48, 0x1a, 0xc4, 0xf9, 0x7c, 0x7d, 0xbd, 0xe6, 0xd1, 0xd1, 0xfb, 0x04, 0x40, 0x6b, 0x5d, 0x2a, 0x1d, 0x98, 0xfa, 0x81, 0xd4, 0x4d, 0xf4, 0xe0, 0x7a, 0xd5, 0x32, 0x02, 0xa4, 0x7d, 0x54, 0xe3, 0x5c, 0x9c, 0xf5, 0x0f, 0x04, 0xb3, 0x20, 0x73, 0x85, 0x2b, 0xb5, 0xb2, 0xc9, 0x0f, 0xbc, 0x8d, 0xa4, 0xd0, 0xe6, 0x52, 0xfc, 0x6f, 0x46, 0x3a, 0xa8, 0xeb, 0xc7, 0x89, 0xe1, 0xb5, 0x9c, 0x1e, 0xde, 0x0c, 0x6d, 0xd5, 0xc2, 0xd1, 0xd7, 0x23, 0x22, 0x20, 0x7b, 0x31, 0xd7, 0x6c, 0xf5, 0xe1, 0x29, 0x3f, 0xc6, 0xbe, 0x3d, 0x4b, 0x3b, 0x51, 0x94, 0xd6, 0xa3, 0xeb, 0xd4, 0xed, 0x9a, 0x2a, 0xf5, 0x97, 0x0e, 0x4f, 0x20, 0x34, 0x52, 0x0c, 0x90, 0x50, 0xde, 0x06, 0xa4, 0x01, 0x1f, 0x5b, 0xeb, 0xe9, 0x6e, 0x6e, 0x6d, 0xd2, 0xae, 0x3d, 0x54, 0xb1, 0xb6, 0x90, 0x10, 0xdf, 0x63, 0xa2, 0x41, 0x23, 0x1f, 0x71, 0xaa, 0x2a, 0x04, 0x67, 0x16, 0x48, 0x0c, 0xc8, 0xac, 0x2f, 0xfb, 0xdd, 0xfd, 0x94, 0x9b, 0xc2, 0x1d, 0x2d, 0xd0, 0x6c, 0x0b, 0x59, 0x4b, 0xaa, 0x5f, 0xfa, 0xbf, 0x9f, 0x9d, 0x38, 0xfb, 0x0d, 0xb5, 0xf7, 0x8d, 0x3b, 0x34, 0xb5, 0x9f, 0xdf, 0x1e, 0x39, 0x10, 0xe8, 0x7e, 0xa9, 0xdd, 0xe6, 0x5b, 0xb9, 0x33, 0xdc, 0x45, 0xcb, 0xf0, 0x93, 0x30, 0x31, 0xe2, 0xc5, 0x6c, 0x7d, 0x93, 0xa5, 0x64, 0xea, 0x1e, 0x30, 0x40, 0x6e, 0x2b, 0xb4, 0xe4, 0x2c, 0x86, 0x28, 0xf8, 0x32, 0xfc, 0x10, 0x43, 0x1d, 0xd3, 0xa4, 0x64, 0xb0, 0xa1, 0xd1, 0x46, 0x1c, 0x55, 0xc3, 0x7e, 0x93, 0x48, 0xf1, 0xf7, 0x35, 0x59, 0x5a, 0x46, 0x9f, 0x97, 0x05, 0xf1, 0x6e, 0x35, 0x1a, 0x43, 0x02, 0x2c, 0x5c, 0x84, 0xe1, 0x56, 0x99, 0x91, 0x58, 0xdd, 0x28, 0x05, 0xd7, 0x51, 0xd7, 0xc0, 0xfe, 0xe2, 0x7d, 0xcf, 0xba, 0x75, 0x6f, 0x4f, 0x8a, 0xa7, 0x75, 0xe6, 0x4c, 0xbb, 0xfc, 0x91, 0xb3, 0xa5, 0x45, 0x64, 0x8d, 0x40, 0x8e, 0x3f, 0xd3, 0xc4, 0x31, 0x9b, 0x19, 0xfe, 0xfc, 0xcd, 0x53, 0x32, 0x8c, 0xe0, 0x56, 0x2e, 0x8b, 0xcc, 0xa6, 0x4c, 0x54, 0xe0, 0x6a, 0x45, 0x12, 0x04, 0x41, 0x14, 0x61, 0x66, 0x68, 0x7e, 0xa7, 0xa7, 0x15, 0x26, 0x1d, 0xcc, 0xab, 0x2a, 0x74, 0x73, 0x04, 0xb0, 0x59, 0x5f, 0xb9, 0xab, 0x55, 0x4d, 0x19, 0x6f, 0xd1, 0x17, 0x22, 0xba, 0x93, 0x23, 0x58, 0x6f, 0xa7, 0x19, 0x2b, 0x97, 0x69, 0xd1, 0x44, 0x17, 0x36, 0x57, 0x03, 0xdc, 0xb1, 0x4d, 0xa0, 0x6f, 0x49, 0x4b, 0x3c, 0x60, 0xa7, 0x8b, 0x72, 0xa3, 0x1a, 0xd3, 0x89, 0x89, 0x19, 0xbe, 0x02, 0x25, 0x2d, 0x61, 0x8f, 0xc6, 0xbf, 0xb9, 0x0e, 0x0e, 0x6d, 0x07, 0xe7, 0xa8, 0x26, 0x74, 0x78, 0x97, 0xdc, 0x2d, 0x02, 0x59, 0x37, 0x13, 0xa5, 0x4c, 0xf5, 0x90, 0x58, 0xc6, 0xdb, 0xbe, 0x4c, 0x08, 0x16, 0x60, 0x4e, 0x59, 0x52, 0x07, 0xe1, 0x24, 0x20, 0x07, 0x22, 0x9d, 0xc3, 0xbf, 0xa5, 0xa3, 0xb6, 0xd5, 0x5d, 0x29, 0x5d, 0x47, 0x40, 0x84, 0x3f, 0x7c, 0x57, 0xa4, 0x49, 0x71, 0xf9, 0x1a, 0x78, 0xc2, 0x72, 0xfd, 0xbf, 0xed, 0x07, 0x65, 0x16, 0xf9, 0xd7, 0x69, 0x36, 0x9c, 0x07, 0x5f, 0x36, 0x47, 0x6d, 0x47, 0x49, 0x5a, 0x3a, 0xc8, 0x97, 0x39, 0xd1, 0x73, 0xf8, 0xf6, 0x7b, 0x22, 0x41, 0x34, 0xbd, 0x4b, 0x50, 0x7f, 0xfe, 0x1e, 0x05, 0x9a, 0xca, 0xbd, 0x9e, 0x03, 0x40, 0x0d, 0x37, 0xad, 0xd2, 0x9c, 0x77, 0x99, 0x80, 0x62, 0x62, 0x6b, 0xce, 0x11, 0xbc, 0x84, 0x29, 0x66, 0x53, 0x41, 0x35, 0x31, 0xc3, 0x64, 0x8e, 0xe0, 0xd4, 0x01, 0x73, 0xa0, 0xca, 0x1d, 0x1d, 0x3a, 0x26, 0x57, 0x19, 0xb0, 0x34, 0x7c, 0x59, 0xa7, 0x5b, 0xfa, 0xd6, 0x4e, 0xeb, 0x98, 0x7b, 0x7f, 0x49, 0xc3, 0xfe, 0x95, 0x6b, 0x18, 0xef, 0x3d, 0x1a, 0xed, 0x5b, 0x99, 0x1a, 0x1f, 0x7f, 0x26, 0x62, 0xb8, 0xce, 0xd4, 0x33, 0x85, 0xf0, 0xc5, 0x29, 0x50, 0x9d, 0xdf, 0x7b, 0xbf, 0x75, 0x4e, 0xb4, 0xa1, 0xc6, 0xa5, 0x86, 0xc3, 0xe9, 0x5a, 0x0f, 0xc3, 0x2e, 0xba, 0x8a, 0x91, 0xee, 0x05, 0x36, 0x09, 0xf4, 0x29, 0xc8, 0x4f, 0x80, 0x68, 0x27, 0x98, 0x7b, 0x84, 0x28, 0xae, 0x9b, 0x00, 0xd8, 0xc9, 0x8d, 0x13, 0x98, 0xe1, 0xc7, 0x41, 0x49, 0x20, 0xb9, 0x35, 0x05, 0x83, 0x0f, 0x90, 0x08, 0x65, 0x40, 0xcd, 0xb6, 0x45, 0xf0, 0xd4, 0x2c, 0xd6, 0x87, 0x21, 0x2a, 0x02, 0xc5, 0xea, 0x8b, 0x1d, 0xe4, 0x13, 0x96, 0x12, 0x5e, 0x37, 0x6c, 0xc5, 0x2e, 0x07, 0xfd, 0xd5, 0x2c, 0x2f, 0x60, 0xdf, 0x80, 0x92, 0xb0, 0x01, 0x10, 0x60, 0x1e, 0x7c, 0x0c, 0x75, 0x27, 0x45, 0xf7, 0x8e, 0x17, 0xb3, 0x93, 0xe6, 0xfb, 0xbf, 0x3e, 0x7d, 0x21, 0x52, 0x33, 0x84, 0xbb, 0x4c, 0xb2, 0x39, 0x5f, 0xcb, 0x92, 0xb0, 0xa2, 0x77, 0xf1, 0x57, 0x82, 0x8c, 0x6c, 0x23, 0xfa, 0xc3, 0x6c, 0xa1, 0x01, 0xe3, 0x04, 0x5b, 0x6e, 0xe6, 0xbf, 0x78, 0xee, 0x40, 0x10, 0x95, 0x45, 0x1c, 0xe9, 0xd7, 0xc6, 0x9f, 0x50, 0x70, 0xac, 0x47, 0xef, 0x5a, 0xe1, 0x9a, 0x14, 0x0d, 0x51, 0x38, 0x19, 0xb7, 0xf3, 0x43, 0x7a, 0x27, 0xe5, 0xa3, 0x90, 0x22, 0x06, 0x88, 0x65, 0x5d, 0x60, 0x70, 0x81, 0x8a, 0x18, 0x74, 0xa8, 0x2a, 0xcc, 0xb6, 0xd2, 0x36, 0xce, 0xf0, 0x92, 0x75, 0xb2, 0x90, 0x1c, 0xe6, 0xe6, 0xe4, 0xce, 0xa2, 0x29, 0x65, 0x77, 0x22, 0xc9, 0x61, 0x55, 0x55, 0x2b, 0x5a, 0x78, 0x4c, 0xeb, 0x25, 0x75, 0xb3, 0x89, 0xa1, 0x96, 0x41, 0x19, 0x7a, 0x6b, 0x44, 0xa8, 0x65, 0x20, 0x38, 0x8b, 0xa4, 0x37, 0x19, 0xc8, 0x6f, 0x02, 0x1c, 0xd7, 0x7d, 0x32, 0x71, 0x23, 0x7a, 0xdb, 0x10, 0xb7, 0xd6, 0xeb, 0xa6, 0xaf, 0x3f, 0xfe, 0x0d, 0xe3, 0x78, 0x06, 0xaf, 0xf2, 0xff, 0x5f, 0x2c, 0xac, 0x4f, 0xd4, 0x30, 0x77, 0xce, 0x8b, 0xde, 0x64, 0xdc, 0x08, 0x97, 0xbb, 0x2e, 0xee, 0xa5, 0xfd, 0x04, 0x44, 0xd6, 0x0a, 0x90, 0x13, 0x29, 0x94, 0xc5, 0x12, 0x52, 0xc4, 0x73, 0x63, 0x48, 0x1b, 0xd3, 0xe3, 0x42, 0x29, 0x0c, 0xb9, 0x17, 0xdf, 0x0b, 0xc2, 0x41, 0x17, 0x49, 0x26, 0x6f, 0xc6, 0xf4, 0x23, 0xcd, 0x54, 0xcf, 0x9e, 0x13, 0x23, 0x90, 0x55, 0x49, 0x79, 0x51, 0x2a, 0x2e, 0x8e, 0xb0, 0x0e, 0x0a, 0x42, 0x49, 0xa5, 0xdf, 0x39, 0xa0, 0xc5, 0x09, 0x7e, 0xf3, 0x8e, 0x10, 0x25, 0x3b, 0xb0, 0x63, 0xdb, 0x74, 0xde, 0x5b, 0xca, 0x64, 0x68, 0x7d, 0xa3, 0x67, 0xb9, 0x6b, 0xc6, 0xa8, 0x5b, 0x22, 0xbd, 0xf2, 0x1f, 0x85, 0x5b, 0xdf, 0xde, 0x0e, 0x35, 0xce, 0x97, 0xad, 0x75, 0xc0, 0x99, 0xd7, 0xcf, 0xaf, 0x6b, 0x47, 0xbc, 0xa4, 0x40, 0x14, 0xec, 0x87, 0x68, 0xd6, 0x86, 0xfd, 0xb5, 0x63, 0x11, 0xd7, 0x90, 0xd5, 0x76, 0x62, 0x3f, 0xa1, 0x22, 0x53, 0x85, 0xf2, 0x80, 0xbe, 0x75, 0xc3, 0x6d, 0xd8, 0x09, 0xc0, 0xf3, 0xd8, 0x04, 0xc4, 0x80, 0x73, 0x04, 0xb8, 0x73, 0x01, 0x9f, 0xff, 0xba, 0x2a, 0x4e, 0xec, 0x5a, 0x2b, 0xc9, 0x5b, 0xa8, 0x64, 0x96, 0x58, 0x31, 0x9a, 0x14, 0xac, 0xb8, 0x9a, 0xec, 0x6b, 0x75, 0xa3, 0x11, 0x7f, 0x02, 0x89, 0xf3, 0x53, 0x21, 0xe9, 0xba, 0xf8, 0x2a, 0x65, 0x33, 0xcd, 0x83, 0x28, 0xcf, 0xfd, 0x6a, 0x9e, 0xce, 0xa5, 0x31, 0x49, 0x45, 0x10, 0x35, 0x2e, 0xf1, 0x24, 0xf1, 0xdd, 0x2f, 0xb1, 0x01, 0x8b, 0x5d, 0xc9, 0x64, 0x1f, 0xae, 0xd2, 0x95, 0xa2, 0xc2, 0x4e, 0x3d, 0x3b, 0xc4, 0x50, 0x3d, 0x17, 0xaf, 0xc7, 0xf6, 0x59, 0xc8, 0x65, 0x40, 0x9e, 0x40, 0xf3, 0x5c, 0xb2, 0xd8, 0xdc, 0x69, 0x26, 0xd6, 0xd5, 0x52, 0x04, 0x90, 0xf7, 0xb0, 0xcc, 0x30, 0x8a, 0x4c, 0x20, 0x5c, 0xd9, 0xcd, 0x31, 0x24, 0xb8, 0x81, 0xdb, 0x41, 0x4e, 0x61, 0xf0, 0x65, 0x02, 0x33, 0x1b, 0xef, 0x11, 0x01, 0x87, 0x2b, 0x15, 0xee, 0x59, 0x6c, 0xf4, 0xfb, 0xca, 0xf7, 0x3f, 0xaf, 0x73, 0x0c, 0xff, 0x5d, 0x0f, 0x47, 0x78, 0xfe, 0x24, 0x78, 0x29, 0x6d, 0x4e, 0xf2, 0x1d, 0xf9, 0x1a, 0x0f, 0x8f, 0x69, 0xa6, 0xbf, 0xcc, 0xf3, 0x5e, 0x2f, 0x23, 0x0f, 0x59, 0x10, 0xe4, 0xa6, 0x33, 0xdd, 0xef, 0xe1, 0x5f, 0xfd, 0x44, 0x3e, 0x5a, 0xee, 0x28, 0x98, 0xe8, 0xdd, 0x19, 0xe3, 0x66, 0x0c, 0x57, 0xf5, 0xb1, 0x8a, 0xf1, 0xcf, 0x56, 0xc2, 0xa8, 0x7b, 0x24, 0xf2, 0xcb, 0x52, 0x60, 0xb1, 0xd3, 0xbd, 0x11, 0x5b, 0x06, 0xa4, 0xf2, 0x35, 0x51, 0x96, 0xab, 0xfb, 0xf3, 0xf8, 0x63, 0x11, 0xa9, 0x8c, 0x4b, 0x70, 0x1f, 0x4b, 0x07, 0x3c, 0x99, 0x92, 0x6e, 0xfb, 0x75, 0x20, 0x3a, 0x37, 0x3f, 0x64, 0x8c, 0x37, 0x19, 0xe3, 0x09, 0x8a, 0x28, 0xf3, 0x72, 0x61, 0xec, 0xf6, 0x66, 0xd3, 0xb8, 0x52, 0xb4, 0x24, 0xd1, 0x08, 0x80, 0xe1, 0x1b, 0x6e, 0x64, 0xf9, 0x44, 0xb0, 0x94, 0xb1, 0xe2, 0x8d, 0xa2, 0xea, 0x02, 0x3f, 0x40, 0x14, 0x53, 0x4a, 0xb9, 0x74, 0xb7, 0x83, 0xf2, 0xc9, 0xbb, 0x98, 0xd8, 0x65, 0x87, 0x77, 0x77, 0xb5, 0x2b, 0x52, 0xec, 0x32, 0x5a, 0x37, 0x6f, 0x89, 0x3b, 0x08, 0x65, 0x0a, 0xee, 0x5c, 0x07, 0x62, 0x0a, 0x6b, 0x72, 0x58, 0x97, 0x33, 0xe5, 0x50, 0x25, 0x8d, 0x4e, 0x3d, 0x73, 0x79, 0xff, 0xb8, 0x8e, 0xf6, 0x60, 0xf3, 0xdf, 0x3b, 0x8e, 0x00, 0xc5, 0xd8, 0xe3, 0xa9, 0xc5, 0xf8, 0x14, 0x88, 0xb0, 0xa9, 0x87, 0x94, 0x51, 0x34, 0x9c, 0xfc, 0x4f, 0x64, 0x91, 0x84, 0xe0, 0x10, 0x41, 0xc5, 0x90, 0xc7, 0x26, 0x6d, 0x59, 0xe7, 0x96, 0x09, 0x1c, 0xa7, 0x4c, 0xd0, 0x3f, 0x31, 0x5c, 0xe0, 0x9b, 0x1c, 0xdf, 0x7a, 0x09, 0xb0, 0x7d, 0x88, 0xee, 0xf6, 0xdb, 0x1f, 0x54, 0x91, 0xc3, 0xd3, 0x22, 0x3a, 0x1c, 0x11, 0x28, 0x71, 0x95, 0x20, 0x64, 0xe7, 0x6a, 0x59, 0x2e, 0x20, 0x1f, 0x03, 0x69, 0x5e, 0x0f, 0xc8, 0x21, 0x70, 0xa6, 0xca, 0xdd, 0x0a, 0x92, 0x37, 0x87, 0x2a, 0xb6, 0xf3, 0xb7, 0x16, 0xff, 0x4c, 0x2c, 0xcf, 0xb8, 0x73, 0xca, 0xa7, 0x43, 0xc2, 0xe3, 0x2a, 0xfe, 0x4f, 0x7a, 0x95, 0x7a, 0x47, 0xd2, 0xd6, 0xc7, 0xa8, 0x4a, 0x51, 0xcb, 0x00, 0xe6, 0x1f, 0x45, 0x4c, 0x54, 0xad, 0x20, 0x92, 0xcd, 0x5e, 0x7f, 0x38, 0xd7, 0xa8, 0x48, 0xad, 0xd8, 0x7d, 0xed, 0x30, 0xc3, 0x4b, 0x8d, 0xae, 0xdd, 0x49, 0xd3, 0xbe, 0xca, 0x1d, 0xff, 0xf8, 0xc7, 0x89, 0x25, 0x95, 0xc7, 0x55, 0xb0, 0x16, 0x36, 0xb1, 0xc6, 0x58, 0xfd, 0x23, 0xec, 0x18, 0xe8, 0xdb, 0x4c, 0xc0, 0x71, 0x37, 0xb4, 0x4c, 0x8e, 0x60, 0x1e, 0x55, 0xfa, 0x6c, 0x8e, 0x6f, 0xaa, 0x32, 0x4d, 0xe1, 0x7d, 0x47, 0xb5, 0xfc, 0x10, 0x67, 0xbb, 0x52, 0xdc, 0xbf, 0xd1, 0x71, 0x92, 0x6f, 0xb1, 0x65, 0xb8, 0xad, 0xf9, 0x65, 0x61, 0x01, 0xc7, 0xa8, 0x53, 0x94, 0xc7, 0xc8, 0x07, 0x78, 0xf2};
#!/usr/bin/env python3
from contextlib import suppress
import logging
from scapy.all import PcapReader, Padding
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
# pylint: disable=invalid-name
logger = logging.getLogger(__name__)
AES_KEYS = [
bytes.fromhex("83198c77f7128da58d3b33854635776fd50f82a858e6538a3993c6df21e61b67"),
bytes.fromhex("2fe79b0608478cfb6f8707aacb263a8ed0959ef56cf669c9690eac170010eb19"),
bytes.fromhex("6a3382f0de1c02e73166bca50e6252492b73462c789075341a1dbb36051756ba"),
bytes.fromhex("13b48bcb7cddcd56a63b0439dc76323b7c40e78c623a993cff501684d16b0d5e"),
]
pkt_global_count = -1
def repr_0(value, basecolor=''):
"""Represent binary data by replacing \0 with a colored underscore"""
return basecolor + repr(value).replace('\\x00', '\033[36m_\033[m' + basecolor) + '\033[m'
class TcpStream:
"""Hold information about a TCP stream"""
def __init__(self, ipsrc, ipdst, tcpsrc, tcpdst):
self.ipsrc = ipsrc
self.ipdst = ipdst
self.tcpsrc = tcpsrc
self.tcpdst = tcpdst
self.last_tcpseq_c2s = None
self.last_tcpseq_s2c = None
self.current_data_c2s = b''
self.current_data_s2c = b''
self.expected_tcpseq_c2s = None
self.expected_tcpseq_s2c = None # Server2Client may be fragmented
self.future_paquets_s2c = []
self.pkt_idx = 0
logger.info("Initiating TCP conn to %s:%s", ipdst, tcpdst)
def got_synack(self, seq_s2c, ack_c2s):
"""Got sequence numbers from a SYN+ACK packet"""
if self.last_tcpseq_s2c is not None:
logger.warning("Got a duplicated TCP SYN+ACK for %s:%d > %s:%d",
self.ipsrc, self.tcpsrc, self.ipdst, self.tcpdst)
elif self.last_tcpseq_c2s is not None:
# TCP Fast open
if self.last_tcpseq_c2s + 1 == ack_c2s:
logger.warning("Rejected TCP SYN+ACK with TCP Fast Open for %s:%d > %s:%d",
self.ipsrc, self.tcpsrc, self.ipdst, self.tcpdst)
else:
logger.warning(
"Got an unexpected TCP SYN+ACK with TCP Fast Open for %s:%d > %s:%d: %d + 1 != %d",
self.ipsrc, self.tcpsrc, self.ipdst, self.tcpdst, self.last_tcpseq_c2s, ack_c2s)
self.last_tcpseq_c2s = ack_c2s
self.last_tcpseq_s2c = seq_s2c
self.expected_tcpseq_c2s = ack_c2s
self.expected_tcpseq_s2c = seq_s2c + 1
def add_payload(self, data, client_to_server, seq):
"""Got a new TCP packet, adding it to the internal buffers"""
if client_to_server:
if self.last_tcpseq_c2s == seq and self.expected_tcpseq_c2s != seq:
# Ignore repeated packets
return
if self.current_data_s2c: # Drop recv bytes when sending
logger.warning("Ignoring %d recv bytes", len(self.current_data_s2c))
self.current_data_s2c = b''
self.last_tcpseq_c2s = seq
# print("[>] %d + %d = %d" % (seq, len(data), seq + len(data))); data = b''
data = self.process_packets(self.current_data_c2s + data, client_to_server)
self.current_data_c2s = data
else:
if self.last_tcpseq_s2c == seq and self.expected_tcpseq_s2c != seq:
# Ignore repeated packets
return
if self.current_data_c2s: # Drop sent bytes when receiving
logger.warning("Ignoring %d sent bytes", len(self.current_data_s2c))
self.current_data_c2s = b''
if self.expected_tcpseq_s2c != seq:
logger.warning("Bad order of packets: %#x vs. %#x", self.expected_tcpseq_s2c, seq)
if self.expected_tcpseq_s2c < seq:
# The packet is a future one... keep it
self.future_paquets_s2c.append((seq, data))
return
self.last_tcpseq_s2c = seq
self.expected_tcpseq_s2c = seq + len(data)
# print("[TCP<] %#x + %d = %#x" % (seq, len(data), seq + len(data)))
data = self.process_packets(self.current_data_s2c + data, client_to_server)
self.current_data_s2c = data
# Unstack stashed packets
if self.future_paquets_s2c:
unstashed_packet_idx = None
for idx, pkt in enumerate(self.future_paquets_s2c):
if pkt[0] == self.expected_tcpseq_s2c:
unstashed_packet_idx = idx
break
if unstashed_packet_idx is not None:
seq, new_data = self.future_paquets_s2c.pop(unstashed_packet_idx)
logger.warning("Found out-of-order now :) %#x, sending %d+%d=%d=%#x bytes",
seq, len(data), len(new_data),
len(data) + len(new_data),
len(data) + len(new_data))
# The data is already in self.current_data_s2c
self.add_payload(new_data, client_to_server, seq)
return
def process_packets(self, data, client_to_server):
"""Process parts of a packet and return the remaining (unparsed data)"""
# By default, display the packet and return nothing
if self.pkt_idx == 0:
global pkt_global_count
pkt_global_count += 1
print("[{} {}:{} {} {}:{}] {}".format(
self.pkt_idx,
self.ipsrc, self.tcpsrc,
'<>'[client_to_server],
self.ipdst, self.tcpdst,
repr_0(data.rstrip(b"\0"))))
self.pkt_idx += 1
return b""
if self.pkt_idx == 1:
# print("... pubkey [" + ", ".join(f"0x{x:02x}" for x in data) + "]")
self.pkt_idx += 1
return b""
if self.pkt_idx == 2:
# print("... ciphertext {" + ", ".join(f"0x{x:02x}" for x in data) + "}")
self.pkt_idx += 1
return b""
if self.pkt_idx >= 3:
key = AES_KEYS[pkt_global_count]
if key is not None:
cipher = Cipher(algorithms.AES(key[:16]), modes.ECB())
decryptor = cipher.decryptor()
plain = decryptor.update(data) + decryptor.finalize()
#print("... decrypted: " + repr_0(plain))
while plain:
print("[{} {}:{} {} {}:{} enc] {}".format(
self.pkt_idx,
self.ipsrc, self.tcpsrc,
'<>'[client_to_server],
self.ipdst, self.tcpdst,
repr_0(plain[:16].rstrip(b"\0"))))
plain = plain[16:]
self.pkt_idx += 1
return b""
print("[{} {}:{} {} {}:{}] [{}] {}".format(
self.pkt_idx,
self.ipsrc, self.tcpsrc,
'<>'[client_to_server],
self.ipdst, self.tcpdst,
len(data),
repr_0(data[:32])))
self.pkt_idx += 1
return b''
def get_ip_layer(packet):
"""Return the IPv4 or IPv6 layer of a packet, if it exists. Otherwise None"""
with suppress(IndexError):
return packet['IP']
with suppress(IndexError):
return packet['IPv6']
return None
def analyze_pcap_for_tcp(pcap_file):
"""Analyze a PCAP file with TCP communications"""
tcp_streams = {}
for packet in PcapReader(pcap_file):
ippkt = get_ip_layer(packet)
if ippkt is None or ippkt.proto != 6: # TCP protocol is 6
continue
tcppkt = ippkt['TCP']
# Gather packet metadata
ipsrc = ippkt.src
ipdst = ippkt.dst
tcpsrc = tcppkt.sport
tcpdst = tcppkt.dport
# Match the packet with existing streams in tcp_streams
client_to_server = None
tcpip_tuple = (ipdst, ipsrc, tcpdst, tcpsrc)
if tcpip_tuple in tcp_streams:
client_to_server = False
if tcppkt.flags.SA: # SYN=2 + ACK=0x10
tcp_streams[tcpip_tuple].got_synack(tcppkt.seq, tcppkt.ack)
else:
tcpip_tuple = (ipsrc, ipdst, tcpsrc, tcpdst)
if tcpip_tuple in tcp_streams:
client_to_server = True
elif tcppkt.flags.S: # SYN
tcp_streams[tcpip_tuple] = TcpStream(ipsrc, ipdst, tcpsrc, tcpdst)
client_to_server = True
else:
logger.debug("Ignoring non-SYN first TCP packet %r", tcpip_tuple)
continue
assert client_to_server is not None # Ensure that the direction has been found
# Ignore Ethernet padding that might slips into the TCP packet
if isinstance(tcppkt.payload, Padding):
continue
payload_bytes = bytes(tcppkt.payload)
if payload_bytes:
tcp_streams[tcpip_tuple].add_payload(payload_bytes, client_to_server, tcppkt.seq)
logger.debug("Analyzed %d TCP streams", len(tcp_streams))
analyze_pcap_for_tcp("CTF-RWPQC2024/challenges/challenge3/file.pcap")
diff --git a/challenges/challenge4/tlslite/keyexchange.py b/challenges/challenge4/tlslite/keyexchange.py
index 58b71c709aaf..4921d049e988 100644
--- a/challenges/challenge4/tlslite/keyexchange.py
+++ b/challenges/challenge4/tlslite/keyexchange.py
@@ -999,7 +999,13 @@ class ECDHKeyExchange(RawDHKeyExchange):
else:
return getRandomBytes(X448_ORDER_SIZE)
elif self.group == GroupName.x25519kyber768draft00:
- return getRandomBytes(X25519_ORDER_SIZE)
+ print(f"Generating Kyber private key")
+ x25519_priv = getRandomBytes(X25519_ORDER_SIZE)
+ pk, sk = Kyber768.keygen()
+ assert len(x25519_priv) == 32, len(x25519_priv)
+ assert len(pk) == 1184, len(pk)
+ assert len(sk) == 2400, len(sk)
+ return x25519_priv + pk + sk
else:
curve = getCurveByName(GroupName.toStr(self.group))
return ecdsa.util.randrange(curve.generator.order())
@@ -1017,7 +1023,12 @@ class ECDHKeyExchange(RawDHKeyExchange):
fun, generator, _ = self._get_fun_gen_size()
return fun(private, generator)
elif self.group == GroupName.x25519kyber768draft00:
- return x25519(private, bytearray(X25519_G))
+ assert len(private) == 32 + 1184 + 2400, len(private)
+ x25519_pub = x25519(private[:32], bytearray(X25519_G))
+ pk = private[32:32 + 1184]
+ assert len(x25519_pub) == 32
+ assert len(pk) == 1184
+ return x25519_pub + pk
else:
curve = getCurveByName(GroupName.toStr(self.group))
return encodeX962Point(curve.generator * private)
@@ -1032,9 +1043,14 @@ class ECDHKeyExchange(RawDHKeyExchange):
self._non_zero_check(S)
return S
elif self.group == GroupName.x25519kyber768draft00:
- S = x25519(private, peer_share)
- self._non_zero_check(s)
- return S
+ assert len(private) == 32 + 1184 + 2400, len(private)
+ assert len(peer_share) == 32 + 1088, len(peer_share)
+ S = x25519(private[:32], peer_share[:32])
+ self._non_zero_check(S)
+ kyber_s = Kyber768.dec(peer_share[32:], private[-2400:])
+ assert len(S) == 32, len(S)
+ assert len(kyber_s) == 32, len(kyber_s)
+ return S + kyber_s
else:
curve = getCurveByName(GroupName.toRepr(self.group))
try:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment