use std::str::FromStr;
use std::sync::Arc;
use assert_matches::assert_matches;
use expect_test::expect;
use hex_literal::hex;
use pkcs8::AssociatedOid;
use super::{
PrivateKey,
PrivateKeyDataWrapper,
};
use crate::Error;
#[test]
fn ed25519_from_str() {
const S: &str = "302e020100300506032b65700422042098aa82d6125b5efa04bf8372be7931d05cd77f5ef3330b97d6ee7c006eaaf312";
let pk = PrivateKey::from_str(S).unwrap();
assert_eq!(pk.to_string(), S);
}
#[test]
fn ecdsa_from_str() {
const S: &str = "3030020100300706052b8104000a042204208776c6b831a1b61ac10dac0304a2843de4716f54b1919bb91a2685d0fe3f3048";
let pk = PrivateKey::from_str(S).unwrap();
assert_eq!(pk.algorithm().oid, k256::Secp256k1::OID);
assert_eq!(pk.to_string(), S);
}
#[test]
fn ed25519_sign() {
let private_key = PrivateKey::from_str(
"302e020100300506032b657004220420db484b828e64b2d8f12ce3c0a0e93a0b8cce7af1bb8f39c97732394482538e10",
)
.unwrap();
let signature = private_key.sign(b"hello, world");
expect![[r#"
"9d04bfed7baa97c80d29a6ae48c0d896ce8463a7ea0c16197d55a563c73996ef062b2adf507f416c108422c0310fc6fb21886e11ce3de3e951d7a56049743f07"
"#]]
.assert_debug_eq(&hex::encode(signature));
}
#[test]
fn ecdsa_sign() {
let private_key = PrivateKey::from_str(
"3030020100300706052b8104000a042204208776c6b831a1b61ac10dac0304a2843de4716f54b1919bb91a2685d0fe3f3048"
)
.unwrap();
let signature = private_key.sign(b"hello world");
expect![[r#"
"f3a13a555f1f8cd6532716b8f388bd4e9d8ed0b252743e923114c0c6cbfe414c086e3717a6502c3edff6130d34df252fb94b6f662d0cd27e2110903320563851"
"#]]
.assert_debug_eq(&hex::encode(signature));
}
#[test]
fn ed25519_legacy_derive() {
let private_key = PrivateKey::from_str(
"302e020100300506032b65700422042098aa82d6125b5efa04bf8372be7931d05cd77f5ef3330b97d6ee7c006eaaf312",
)
.unwrap();
let private_key_0 = private_key.legacy_derive(0).unwrap();
assert_eq!(private_key_0.to_string(), "302e020100300506032b6570042204202b7345f302a10c2a6d55bf8b7af40f125ec41d780957826006d30776f0c441fb");
let private_key_neg_1 = private_key.legacy_derive(-1).unwrap();
assert_eq!(private_key_neg_1.to_string(), "302e020100300506032b657004220420caffc03fdb9853e6a91a5b3c57a5c0031d164ce1c464dea88f3114786b5199e5");
}
#[test]
fn ed25519_legacy_derive_2() {
let private_key = PrivateKey::from_str(
"302e020100300506032b65700422042000c2f59212cb3417f0ee0d38e7bd876810d04f2dd2cb5c2d8f26ff406573f2bd",
)
.unwrap();
let private_key_mhw = private_key.legacy_derive(0xffffffffff).unwrap();
assert_eq!(private_key_mhw.to_string(), "302e020100300506032b6570042204206890dc311754ce9d3fc36bdf83301aa1c8f2556e035a6d0d13c2cccdbbab1242")
}
fn key_with_chain(data: &str, chain_code: [u8; 32]) -> PrivateKey {
let key_without_chain = PrivateKey::from_str(data).unwrap();
let data = match Arc::try_unwrap(key_without_chain.0) {
Ok(it) => it.data,
Err(_) => unreachable!(),
};
PrivateKey(Arc::new(PrivateKeyDataWrapper::new_derivable(data, chain_code)))
}
#[test]
fn ed25519_derive_1() {
let key = key_with_chain(
"302e020100300506032b657004220420a6b9548d7e123ad4c8bc6fee58301e9b96360000df9d03785c07b620569e7728",
hex!("cde7f535264f1db4e2ded409396f8c72f8075cc43757bd5a205c97699ea40271"),
);
let child_key = key.derive(0).unwrap();
expect![[r#"
PrivateKeyData {
algorithm: Ed25519,
key: "5f66a51931e8c99089472e0d70516b6272b94dd772b967f8221e1077f966dbda",
chain_code: Some(
"0e5c869c1cf9daecd03edb2d49cf2621412578a352578a4bb7ef4eef2942b7c9",
),
}
"#]]
.assert_debug_eq(&*child_key.0);
}
#[test]
fn ed25519_derive_2() {
let key = key_with_chain(
"302e020100300506032b65700422042097dbce1988ef8caf5cf0fd13a5374969e2be5f50650abd19314db6b32f96f18e",
hex!("b7b406314eb2224f172c1907fe39f807e306655e81f2b3bc4766486f42ef1433")
);
let child_key = key.derive(0).unwrap();
expect![[r#"
PrivateKeyData {
algorithm: Ed25519,
key: "c284c25b3a1458b59423bc289e83703b125c8eefec4d5aa1b393c2beb9f2bae6",
chain_code: Some(
"a7a1c2d115a988e51efc12c23692188a4796b312a4a700d6c703e4de4cf1a7f6",
),
}
"#]]
.assert_debug_eq(&child_key.0);
}
#[test]
fn ed25519_from_pem() {
const PEM: &[u8] = br#"-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VwBCIEINtIS4KOZLLY8SzjwKDpOguMznrxu485yXcyOUSCU44Q
-----END PRIVATE KEY-----"#;
let pk = PrivateKey::from_pem(PEM).unwrap();
assert_eq!(pk.to_string(), "302e020100300506032b657004220420db484b828e64b2d8f12ce3c0a0e93a0b8cce7af1bb8f39c97732394482538e10");
}
#[test]
fn ecdsa_from_pem() {
const PEM: &[u8] = br#"-----BEGIN PRIVATE KEY-----
MDACAQAwBwYFK4EEAAoEIgQgh3bGuDGhthrBDawDBKKEPeRxb1SxkZu5GiaF0P4/
MEg=
-----END PRIVATE KEY-----"#;
let pk = PrivateKey::from_pem(PEM).unwrap();
assert_eq!(pk.to_string(), "3030020100300706052b8104000a042204208776c6b831a1b61ac10dac0304a2843de4716f54b1919bb91a2685d0fe3f3048");
}
#[test]
fn ed25519_from_pem_invalid_type_label() {
const PEM: &[u8] = br#"-----BEGIN PRIVATE KEYS-----
MC4CAQAwBQYDK2VwBCIEINtIS4KOZLLY8SzjwKDpOguMznrxu485yXcyOUSCU44Q
-----END PRIVATE KEYS-----"#;
assert_matches!(PrivateKey::from_pem(PEM), Err(Error::KeyParse(_)));
}