use crate::error::Error;
pub use rand_core::{CryptoRng, CryptoRngCore, RngCore};
pub use canon::*;
pub use rand::*;
pub mod backend;
mod canon;
mod rand;
pub trait Crypto {
type Rand<'a>: CryptoRngCore + Copy
where
Self: 'a;
type WeakRand<'a>: RngCore + Copy
where
Self: 'a;
type Hash<'a>: Digest<HASH_LEN>
where
Self: 'a;
type Hash1<'a>: Digest<SHA1_HASH_LEN>
where
Self: 'a;
type Hmac<'a>: Digest<HASH_LEN>
where
Self: 'a;
type Kdf<'a>: Kdf
where
Self: 'a;
type PbKdf<'a>: PbKdf
where
Self: 'a;
type Aead<'a>: Aead<AEAD_CANON_KEY_LEN, AEAD_NONCE_LEN>
where
Self: 'a;
type PublicKey<'a>: PublicKey<'a, PKC_CANON_PUBLIC_KEY_LEN, PKC_SIGNATURE_LEN>
where
Self: 'a;
type SigningSecretKey<'a>: SigningSecretKey<
'a,
PKC_CANON_PUBLIC_KEY_LEN,
PKC_SIGNATURE_LEN,
PublicKey<'a> = Self::PublicKey<'a>,
>
where
Self: 'a;
type SecretKey<'a>: SecretKey<
'a,
PKC_CANON_SECRET_KEY_LEN,
PKC_CANON_PUBLIC_KEY_LEN,
PKC_SIGNATURE_LEN,
PKC_SHARED_SECRET_LEN,
PublicKey<'a> = Self::PublicKey<'a>,
>
where
Self: 'a;
type EcScalar<'a>: EcScalar<'a, EC_CANON_SCALAR_LEN>
where
Self: 'a;
type EcPoint<'a>: EcPoint<
'a,
EC_CANON_POINT_LEN,
EC_CANON_SCALAR_LEN,
Scalar<'a> = Self::EcScalar<'a>,
>
where
Self: 'a;
fn rand(&self) -> Result<Self::Rand<'_>, Error>;
fn weak_rand(&self) -> Result<Self::WeakRand<'_>, Error>;
fn hash(&self) -> Result<Self::Hash<'_>, Error>;
fn hash1(&self) -> Result<Self::Hash1<'_>, Error>;
fn hmac<const KEY_LEN: usize>(
&self,
key: CryptoSensitiveRef<'_, KEY_LEN>,
) -> Result<Self::Hmac<'_>, Error>;
fn kdf(&self) -> Result<Self::Kdf<'_>, Error>;
fn pbkdf(&self) -> Result<Self::PbKdf<'_>, Error>;
fn aead(&self) -> Result<Self::Aead<'_>, Error>;
fn pub_key(&self, key: CanonPkcPublicKeyRef<'_>) -> Result<Self::PublicKey<'_>, Error>;
fn secret_key(&self, key: CanonPkcSecretKeyRef<'_>) -> Result<Self::SecretKey<'_>, Error>;
fn generate_secret_key(&self) -> Result<Self::SecretKey<'_>, Error>;
fn singleton_singing_secret_key(&self) -> Result<Self::SigningSecretKey<'_>, Error>;
fn ec_scalar(&self, scalar: CanonEcScalarRef<'_>) -> Result<Self::EcScalar<'_>, Error>;
fn ec_scalar_mod_p(&self, uint: CanonUint320Ref<'_>) -> Result<Self::EcScalar<'_>, Error>;
fn generate_ec_scalar(&self) -> Result<Self::EcScalar<'_>, Error>;
fn ec_point(&self, point: CanonEcPointRef<'_>) -> Result<Self::EcPoint<'_>, Error>;
fn ec_generator_point(&self) -> Result<Self::EcPoint<'_>, Error>;
}
impl<T> Crypto for &T
where
T: Crypto,
{
type Rand<'a>
= T::Rand<'a>
where
Self: 'a;
type WeakRand<'a>
= T::WeakRand<'a>
where
Self: 'a;
type Hash<'a>
= T::Hash<'a>
where
Self: 'a;
type Hash1<'a>
= T::Hash1<'a>
where
Self: 'a;
type Hmac<'a>
= T::Hmac<'a>
where
Self: 'a;
type Kdf<'a>
= T::Kdf<'a>
where
Self: 'a;
type PbKdf<'a>
= T::PbKdf<'a>
where
Self: 'a;
type Aead<'a>
= T::Aead<'a>
where
Self: 'a;
type PublicKey<'a>
= T::PublicKey<'a>
where
Self: 'a;
type SecretKey<'a>
= T::SecretKey<'a>
where
Self: 'a;
type SigningSecretKey<'a>
= T::SigningSecretKey<'a>
where
Self: 'a;
type EcScalar<'a>
= T::EcScalar<'a>
where
Self: 'a;
type EcPoint<'a>
= T::EcPoint<'a>
where
Self: 'a;
fn rand(&self) -> Result<Self::Rand<'_>, Error> {
(*self).rand()
}
fn weak_rand(&self) -> Result<Self::WeakRand<'_>, Error> {
(*self).weak_rand()
}
fn hash(&self) -> Result<Self::Hash<'_>, Error> {
(*self).hash()
}
fn hash1(&self) -> Result<Self::Hash1<'_>, Error> {
(*self).hash1()
}
fn hmac<const KEY_LEN: usize>(
&self,
key: CryptoSensitiveRef<'_, KEY_LEN>,
) -> Result<Self::Hmac<'_>, Error> {
(*self).hmac(key)
}
fn kdf(&self) -> Result<Self::Kdf<'_>, Error> {
(*self).kdf()
}
fn pbkdf(&self) -> Result<Self::PbKdf<'_>, Error> {
(*self).pbkdf()
}
fn aead(&self) -> Result<Self::Aead<'_>, Error> {
(*self).aead()
}
fn pub_key(&self, key: CanonPkcPublicKeyRef<'_>) -> Result<Self::PublicKey<'_>, Error> {
(*self).pub_key(key)
}
fn generate_secret_key(&self) -> Result<Self::SecretKey<'_>, Error> {
(*self).generate_secret_key()
}
fn secret_key(&self, key: CanonPkcSecretKeyRef<'_>) -> Result<Self::SecretKey<'_>, Error> {
(*self).secret_key(key)
}
fn singleton_singing_secret_key(&self) -> Result<Self::SigningSecretKey<'_>, Error> {
(*self).singleton_singing_secret_key()
}
fn ec_scalar(&self, scalar: CanonEcScalarRef<'_>) -> Result<Self::EcScalar<'_>, Error> {
(*self).ec_scalar(scalar)
}
fn ec_scalar_mod_p(&self, uint: CanonUint320Ref<'_>) -> Result<Self::EcScalar<'_>, Error> {
(*self).ec_scalar_mod_p(uint)
}
fn generate_ec_scalar(&self) -> Result<Self::EcScalar<'_>, Error> {
(*self).generate_ec_scalar()
}
fn ec_point(&self, point: CanonEcPointRef<'_>) -> Result<Self::EcPoint<'_>, Error> {
(*self).ec_point(point)
}
fn ec_generator_point(&self) -> Result<Self::EcPoint<'_>, Error> {
(*self).ec_generator_point()
}
}
pub trait Digest<const HASH_LEN: usize> {
fn update(&mut self, data: &[u8]) -> Result<(), Error>;
fn finish_current(&mut self, hash: &mut CryptoSensitive<HASH_LEN>) -> Result<(), Error>;
fn finish(self, hash: &mut CryptoSensitive<HASH_LEN>) -> Result<(), Error>;
}
pub trait Kdf {
fn expand<const IKM_LEN: usize, const KEY_LEN: usize>(
self,
salt: &[u8],
ikm: CryptoSensitiveRef<'_, IKM_LEN>,
info: &[u8],
key: &mut CryptoSensitive<KEY_LEN>,
) -> Result<(), Error>;
}
pub trait PbKdf {
fn derive<const PASS_LEN: usize, const KEY_LEN: usize>(
self,
pass: CryptoSensitiveRef<'_, PASS_LEN>,
iter: usize,
salt: &[u8],
key: &mut CryptoSensitive<KEY_LEN>,
) -> Result<(), Error>;
}
pub trait Aead<const KEY_LEN: usize, const NONCE_LEN: usize> {
fn encrypt_in_place<'a>(
&mut self,
key: CryptoSensitiveRef<'_, KEY_LEN>,
nonce: CryptoSensitiveRef<'_, NONCE_LEN>,
aad: &[u8],
data: &'a mut [u8],
data_len: usize,
) -> Result<&'a [u8], Error>;
fn decrypt_in_place<'a>(
&mut self,
key: CryptoSensitiveRef<'_, KEY_LEN>,
nonce: CryptoSensitiveRef<'_, NONCE_LEN>,
aad: &[u8],
data: &'a mut [u8],
) -> Result<&'a [u8], Error>;
}
impl<const KEY_LEN: usize, const NONCE_LEN: usize, T> Aead<KEY_LEN, NONCE_LEN> for &mut T
where
T: Aead<KEY_LEN, NONCE_LEN>,
{
fn encrypt_in_place<'a>(
&mut self,
key: CryptoSensitiveRef<'_, KEY_LEN>,
nonce: CryptoSensitiveRef<'_, NONCE_LEN>,
aad: &[u8],
data: &'a mut [u8],
data_len: usize,
) -> Result<&'a [u8], Error> {
(*self).encrypt_in_place(key, nonce, aad, data, data_len)
}
fn decrypt_in_place<'a>(
&mut self,
key: CryptoSensitiveRef<'_, KEY_LEN>,
nonce: CryptoSensitiveRef<'_, NONCE_LEN>,
aad: &[u8],
data: &'a mut [u8],
) -> Result<&'a [u8], Error> {
(*self).decrypt_in_place(key, nonce, aad, data)
}
}
pub trait SigningSecretKey<'a, const PUB_KEY_LEN: usize, const SIGNATURE_LEN: usize> {
type PublicKey<'s>: PublicKey<'s, PUB_KEY_LEN, SIGNATURE_LEN>
where
Self: 's;
fn pub_key(&self) -> Result<Self::PublicKey<'a>, Error>;
fn csr<'s>(&self, buf: &'s mut [u8]) -> Result<&'s [u8], Error>;
fn sign(
&self,
data: &[u8],
signature: &mut CryptoSensitive<SIGNATURE_LEN>,
) -> Result<(), Error>;
}
pub trait SecretKey<
'a,
const KEY_LEN: usize,
const PUB_KEY_LEN: usize,
const SIGNATURE_LEN: usize,
const SHARED_SECRET_LEN: usize,
>: SigningSecretKey<'a, PUB_KEY_LEN, SIGNATURE_LEN>
{
fn derive_shared_secret(
&self,
peer_pub_key: &Self::PublicKey<'a>,
shared_secret: &mut CryptoSensitive<SHARED_SECRET_LEN>,
) -> Result<(), Error>;
fn write_canon(&self, key: &mut CryptoSensitive<KEY_LEN>) -> Result<(), Error>;
}
pub trait PublicKey<'a, const KEY_LEN: usize, const SIGNATURE_LEN: usize> {
fn verify(
&self,
data: &[u8],
signature: CryptoSensitiveRef<SIGNATURE_LEN>,
) -> Result<bool, Error>;
fn write_canon(&self, key: &mut CryptoSensitive<KEY_LEN>) -> Result<(), Error>;
}
impl<'a, const KEY_LEN: usize, const SIGNATURE_LEN: usize, T> PublicKey<'a, KEY_LEN, SIGNATURE_LEN>
for &T
where
T: PublicKey<'a, KEY_LEN, SIGNATURE_LEN>,
{
fn verify(
&self,
data: &[u8],
signature: CryptoSensitiveRef<SIGNATURE_LEN>,
) -> Result<bool, Error> {
(*self).verify(data, signature)
}
fn write_canon(&self, key: &mut CryptoSensitive<KEY_LEN>) -> Result<(), Error> {
(*self).write_canon(key)
}
}
pub trait EcScalar<'a, const LEN: usize> {
fn mul(&self, other: &Self) -> Result<Self, Error>
where
Self: Sized;
fn write_canon(&self, scalar: &mut CryptoSensitive<LEN>) -> Result<(), Error>;
}
pub trait EcPoint<'a, const LEN: usize, const SCALAR_LEN: usize> {
type Scalar<'s>: EcScalar<'s, SCALAR_LEN>
where
Self: 'a + 's;
fn is_valid_pubkey(&self) -> Result<bool, Error>;
fn neg(&self) -> Result<Self, Error>
where
Self: Sized;
fn mul(&self, scalar: &Self::Scalar<'a>) -> Result<Self, Error>
where
Self: Sized;
fn add_mul(
&self,
s1: &Self::Scalar<'a>,
p2: &Self,
s2: &Self::Scalar<'a>,
) -> Result<Self, Error>
where
Self: Sized;
fn write_canon(&self, point: &mut CryptoSensitive<LEN>) -> Result<(), Error>;
}
#[allow(unused)]
pub fn default_crypto<'s, R>(
rand: R,
singleton_secret_key: CanonPkcSecretKeyRef<'s>,
) -> impl Crypto + 's
where
R: CryptoRngCore + 's,
{
#[cfg(feature = "openssl")]
let crypto = backend::openssl::OpenSslCrypto::new(singleton_secret_key);
#[cfg(all(feature = "mbedtls", not(feature = "openssl")))]
let crypto = backend::mbedtls::MbedtlsCrypto::new(rand, singleton_secret_key);
#[cfg(all(
feature = "rustcrypto",
not(any(feature = "openssl", feature = "mbedtls"))
))]
let crypto = backend::rustcrypto::RustCrypto::new(rand, singleton_secret_key);
#[cfg(not(any(feature = "openssl", feature = "mbedtls", feature = "rustcrypto")))]
let crypto = backend::dummy::DummyCrypto;
crypto
}
pub fn test_only_crypto() -> impl Crypto {
default_crypto(
WeakTestOnlyRand::new_default(),
crate::dm::devices::test::DAC_PRIVKEY,
)
}
#[cfg(test)]
mod tests {
use crate::crypto::{
test_only_crypto, CanonPkcPublicKeyRef, CanonPkcSignatureRef, Crypto, PublicKey,
};
#[test]
fn test_verify_msg_success() {
let crypto = test_only_crypto();
let key = unwrap!(crypto.pub_key(PUB_KEY1));
assert_eq!(unwrap!(key.verify(MSG1_SUCCESS, SIGNATURE1)), true);
}
#[test]
fn test_verify_msg_fail() {
let crypto = test_only_crypto();
let key = unwrap!(crypto.pub_key(PUB_KEY1));
assert_eq!(unwrap!(key.verify(MSG1_FAIL, SIGNATURE1)), false);
}
const PUB_KEY1: CanonPkcPublicKeyRef = CanonPkcPublicKeyRef::new(&[
0x4, 0x56, 0x19, 0x77, 0x18, 0x3f, 0xd4, 0xff, 0x2b, 0x58, 0x3d, 0xe9, 0x79, 0x34, 0x66,
0xdf, 0xe9, 0x0, 0xfb, 0x6d, 0xa1, 0xef, 0xe0, 0xcc, 0xdc, 0x77, 0x30, 0xc0, 0x6f, 0xb6,
0x2d, 0xff, 0xbe, 0x54, 0xa0, 0x95, 0x75, 0xb, 0x8b, 0x7, 0xbc, 0x55, 0xdb, 0x9c, 0xb6,
0x55, 0x13, 0x8, 0xb8, 0xdf, 0x2, 0xe3, 0x40, 0x6b, 0xae, 0x34, 0xf5, 0xc, 0xba, 0xc9,
0xf2, 0xbf, 0xf1, 0xe7, 0x50,
]);
const MSG1_SUCCESS: &[u8] = &[
0x30, 0x82, 0x1, 0xa1, 0xa0, 0x3, 0x2, 0x1, 0x2, 0x2, 0x1, 0x1, 0x30, 0xa, 0x6, 0x8, 0x2a,
0x86, 0x48, 0xce, 0x3d, 0x4, 0x3, 0x2, 0x30, 0x44, 0x31, 0x20, 0x30, 0x1e, 0x6, 0xa, 0x2b,
0x6, 0x1, 0x4, 0x1, 0x82, 0xa2, 0x7c, 0x1, 0x3, 0xc, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30,
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x31, 0x20, 0x30, 0x1e,
0x6, 0xa, 0x2b, 0x6, 0x1, 0x4, 0x1, 0x82, 0xa2, 0x7c, 0x1, 0x5, 0xc, 0x10, 0x30, 0x30,
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30,
0x1e, 0x17, 0xd, 0x32, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0x5a, 0x17, 0xd, 0x33, 0x30, 0x31, 0x32, 0x33, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0x5a, 0x30, 0x44, 0x31, 0x20, 0x30, 0x1e, 0x6, 0xa, 0x2b, 0x6, 0x1, 0x4, 0x1, 0x82, 0xa2,
0x7c, 0x1, 0x1, 0xc, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0x42, 0x43, 0x35, 0x43, 0x30, 0x32, 0x31, 0x20, 0x30, 0x1e, 0x6, 0xa, 0x2b, 0x6, 0x1, 0x4,
0x1, 0x82, 0xa2, 0x7c, 0x1, 0x5, 0xc, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x59, 0x30, 0x13, 0x6, 0x7, 0x2a,
0x86, 0x48, 0xce, 0x3d, 0x2, 0x1, 0x6, 0x8, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x3, 0x1, 0x7,
0x3, 0x42, 0x0, 0x4, 0x6, 0x47, 0xf2, 0x86, 0x4d, 0x27, 0x25, 0xdc, 0x1, 0xa, 0x87, 0xde,
0x8d, 0xca, 0x88, 0x37, 0xcb, 0x3b, 0xd0, 0xea, 0x93, 0xa6, 0x24, 0x65, 0x8, 0x8f, 0xa1,
0x75, 0xc2, 0xd4, 0x41, 0xfa, 0xca, 0x96, 0x54, 0xa3, 0xd8, 0x10, 0x85, 0x73, 0xce, 0x15,
0xa5, 0x38, 0xc1, 0xe3, 0xb5, 0x6b, 0x61, 0x1, 0xd3, 0xc4, 0xb7, 0x6b, 0x61, 0x16, 0xc3,
0x77, 0x8d, 0xe9, 0xb5, 0x44, 0xac, 0x14, 0xa3, 0x81, 0x83, 0x30, 0x81, 0x80, 0x30, 0xc,
0x6, 0x3, 0x55, 0x1d, 0x13, 0x1, 0x1, 0xff, 0x4, 0x2, 0x30, 0x0, 0x30, 0xe, 0x6, 0x3, 0x55,
0x1d, 0xf, 0x1, 0x1, 0xff, 0x4, 0x4, 0x3, 0x2, 0x7, 0x80, 0x30, 0x20, 0x6, 0x3, 0x55, 0x1d,
0x25, 0x1, 0x1, 0xff, 0x4, 0x16, 0x30, 0x14, 0x6, 0x8, 0x2b, 0x6, 0x1, 0x5, 0x5, 0x7, 0x3,
0x2, 0x6, 0x8, 0x2b, 0x6, 0x1, 0x5, 0x5, 0x7, 0x3, 0x1, 0x30, 0x1d, 0x6, 0x3, 0x55, 0x1d,
0xe, 0x4, 0x16, 0x4, 0x14, 0xbd, 0xfd, 0x11, 0xac, 0x89, 0xb6, 0xe0, 0x90, 0x7a, 0xf6,
0x12, 0x61, 0x78, 0x4d, 0x3d, 0x79, 0x56, 0xeb, 0xc2, 0xdc, 0x30, 0x1f, 0x6, 0x3, 0x55,
0x1d, 0x23, 0x4, 0x18, 0x30, 0x16, 0x80, 0x14, 0xce, 0x60, 0xb4, 0x28, 0x96, 0x72, 0x27,
0x64, 0x81, 0xbc, 0x4f, 0x0, 0x78, 0xa3, 0x30, 0x48, 0xfe, 0x6e, 0x65, 0x86,
];
const MSG1_FAIL: &[u8] = &[
0x30, 0x82, 0x1, 0xa1, 0xa0, 0x3, 0x2, 0x1, 0x2, 0x2, 0x1, 0x1, 0x30, 0xa, 0x6, 0x8, 0x2a,
0x86, 0x48, 0xce, 0x3d, 0x4, 0x3, 0x2, 0x30, 0x44, 0x31, 0x20, 0x30, 0x1e, 0x6, 0xa, 0x2b,
0x6, 0x1, 0x4, 0x1, 0x82, 0xa2, 0x7c, 0x1, 0x3, 0xc, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30,
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x31, 0x20, 0x30, 0x1e,
0x6, 0xa, 0x2b, 0x6, 0x1, 0x4, 0x1, 0x82, 0xa2, 0x7c, 0x1, 0x5, 0xc, 0x10, 0x30, 0x30,
0x30, 0x31, 0x32, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30,
0x1e, 0x17, 0xd, 0x32, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0x5a, 0x17, 0xd, 0x33, 0x30, 0x31, 0x32, 0x33, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0x5a, 0x30, 0x44, 0x31, 0x20, 0x30, 0x1e, 0x6, 0xa, 0x2b, 0x6, 0x1, 0x4, 0x1, 0x82, 0xa2,
0x7c, 0x1, 0x1, 0xc, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0x42, 0x43, 0x35, 0x43, 0x30, 0x32, 0x31, 0x20, 0x30, 0x1e, 0x6, 0xa, 0x2b, 0x6, 0x1, 0x4,
0x1, 0x82, 0xa2, 0x7c, 0x1, 0x5, 0xc, 0x10, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x59, 0x30, 0x13, 0x6, 0x7, 0x2a,
0x86, 0x48, 0xce, 0x3d, 0x2, 0x1, 0x6, 0x8, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x3, 0x1, 0x7,
0x3, 0x42, 0x0, 0x4, 0x6, 0x47, 0xf2, 0x86, 0x4d, 0x27, 0x25, 0xdc, 0x1, 0xa, 0x87, 0xde,
0x8d, 0xca, 0x88, 0x37, 0xcb, 0x3b, 0xd0, 0xea, 0x93, 0xa6, 0x24, 0x65, 0x8, 0x8f, 0xa1,
0x75, 0xc2, 0xd4, 0x41, 0xfa, 0xca, 0x96, 0x54, 0xa3, 0xd8, 0x10, 0x85, 0x73, 0xce, 0x15,
0xa5, 0x38, 0xc1, 0xe3, 0xb5, 0x6b, 0x61, 0x1, 0xd3, 0xc4, 0xb7, 0x6b, 0x61, 0x16, 0xc3,
0x77, 0x8d, 0xe9, 0xb5, 0x44, 0xac, 0x14, 0xa3, 0x81, 0x83, 0x30, 0x81, 0x80, 0x30, 0xc,
0x6, 0x3, 0x55, 0x1d, 0x13, 0x1, 0x1, 0xff, 0x4, 0x2, 0x30, 0x0, 0x30, 0xe, 0x6, 0x3, 0x55,
0x1d, 0xf, 0x1, 0x1, 0xff, 0x4, 0x4, 0x3, 0x2, 0x7, 0x80, 0x30, 0x20, 0x6, 0x3, 0x55, 0x1d,
0x25, 0x1, 0x1, 0xff, 0x4, 0x16, 0x30, 0x14, 0x6, 0x8, 0x2b, 0x6, 0x1, 0x5, 0x5, 0x7, 0x3,
0x2, 0x6, 0x8, 0x2b, 0x6, 0x1, 0x5, 0x5, 0x7, 0x3, 0x1, 0x30, 0x1d, 0x6, 0x3, 0x55, 0x1d,
0xe, 0x4, 0x16, 0x4, 0x14, 0xbd, 0xfd, 0x11, 0xac, 0x89, 0xb6, 0xe0, 0x90, 0x7a, 0xf6,
0x12, 0x61, 0x78, 0x4d, 0x3d, 0x79, 0x56, 0xeb, 0xc2, 0xdc, 0x30, 0x1f, 0x6, 0x3, 0x55,
0x1d, 0x23, 0x4, 0x18, 0x30, 0x16, 0x80, 0x14, 0xce, 0x60, 0xb4, 0x28, 0x96, 0x72, 0x27,
0x64, 0x81, 0xbc, 0x4f, 0x0, 0x78, 0xa3, 0x30, 0x48, 0xfe, 0x6e, 0x65, 0x86,
];
const SIGNATURE1: CanonPkcSignatureRef = CanonPkcSignatureRef::new(&[
0x20, 0x16, 0xd0, 0x13, 0x1e, 0xd0, 0xb3, 0x9d, 0x44, 0x25, 0x16, 0xea, 0x9c, 0xf2, 0x72,
0x44, 0xd7, 0xb0, 0xf4, 0xae, 0x4a, 0xa4, 0x37, 0x32, 0xcd, 0x6a, 0x79, 0x7a, 0x4c, 0x48,
0x3, 0x6d, 0xef, 0xe6, 0x26, 0x82, 0x39, 0x28, 0x9, 0x22, 0xc8, 0x9a, 0xde, 0xd5, 0x13,
0x9f, 0xc5, 0x40, 0x25, 0x85, 0x2c, 0x69, 0xe0, 0xdb, 0x6a, 0x79, 0x5b, 0x21, 0x82, 0x13,
0xb0, 0x20, 0xb9, 0x69,
]);
}