Add human readable serialization and deserialization to Secret Key
This commit is contained in:
parent
ab4320f8cc
commit
3825ed35a7
33
src/key.rs
33
src/key.rs
|
@ -187,30 +187,7 @@ impl SecretKey {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "serde")]
|
serde_impl!(SecretKey, constants::SECRET_KEY_SIZE);
|
||||||
impl ::serde::Serialize for SecretKey {
|
|
||||||
fn serialize<S: ::serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
|
|
||||||
s.serialize_bytes(&self.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "serde")]
|
|
||||||
impl<'de> ::serde::Deserialize<'de> for SecretKey {
|
|
||||||
fn deserialize<D: ::serde::Deserializer<'de>>(d: D) -> Result<SecretKey, D::Error> {
|
|
||||||
use ::serde::de::Error;
|
|
||||||
|
|
||||||
// serde can actually deserialize a 32-byte array directly rather than deserializing
|
|
||||||
// a byte slice and copying, but it has special code for byte-slices and no special
|
|
||||||
// code for byte-arrays, meaning this is actually simpler and more efficient
|
|
||||||
let mut arr = [0; 32];
|
|
||||||
let sl: &[u8] = ::serde::Deserialize::deserialize(d)?;
|
|
||||||
if sl.len() != constants::SECRET_KEY_SIZE {
|
|
||||||
return Err(D::Error::invalid_length(sl.len(), &"32"));
|
|
||||||
}
|
|
||||||
arr.copy_from_slice(sl);
|
|
||||||
Ok(SecretKey(arr))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PublicKey {
|
impl PublicKey {
|
||||||
/// Obtains a raw const pointer suitable for use with FFI functions
|
/// Obtains a raw const pointer suitable for use with FFI functions
|
||||||
|
@ -739,13 +716,16 @@ mod test {
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
#[test]
|
#[test]
|
||||||
fn test_signature_serde() {
|
fn test_signature_serde() {
|
||||||
use serde_test::{Token, assert_tokens};
|
use serde_test::{Configure, Token, assert_tokens};
|
||||||
static SK_BYTES: [u8; 32] = [
|
static SK_BYTES: [u8; 32] = [
|
||||||
1, 1, 1, 1, 1, 1, 1, 1,
|
1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
0, 1, 2, 3, 4, 5, 6, 7,
|
0, 1, 2, 3, 4, 5, 6, 7,
|
||||||
0xff, 0xff, 0, 0, 0xff, 0xff, 0, 0,
|
0xff, 0xff, 0, 0, 0xff, 0xff, 0, 0,
|
||||||
99, 99, 99, 99, 99, 99, 99, 99
|
99, 99, 99, 99, 99, 99, 99, 99
|
||||||
];
|
];
|
||||||
|
static SK_STR: &'static str = "\
|
||||||
|
01010101010101010001020304050607ffff0000ffff00006363636363636363\
|
||||||
|
";
|
||||||
static PK_BYTES: [u8; 33] = [
|
static PK_BYTES: [u8; 33] = [
|
||||||
0x02,
|
0x02,
|
||||||
0x18, 0x84, 0x57, 0x81, 0xf6, 0x31, 0xc4, 0x8f,
|
0x18, 0x84, 0x57, 0x81, 0xf6, 0x31, 0xc4, 0x8f,
|
||||||
|
@ -759,7 +739,8 @@ mod test {
|
||||||
let sk = SecretKey::from_slice(&SK_BYTES).unwrap();
|
let sk = SecretKey::from_slice(&SK_BYTES).unwrap();
|
||||||
let pk = PublicKey::from_secret_key(&s, &sk);
|
let pk = PublicKey::from_secret_key(&s, &sk);
|
||||||
|
|
||||||
assert_tokens(&sk, &[Token::BorrowedBytes(&SK_BYTES[..])]);
|
assert_tokens(&sk.compact(), &[Token::BorrowedBytes(&SK_BYTES[..])]);
|
||||||
|
assert_tokens(&sk.readable(), &[Token::BorrowedStr(SK_STR)]);
|
||||||
assert_tokens(&pk, &[Token::BorrowedBytes(&PK_BYTES[..])]);
|
assert_tokens(&pk, &[Token::BorrowedBytes(&PK_BYTES[..])]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -158,3 +158,47 @@ macro_rules! impl_raw_debug {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature="serde")]
|
||||||
|
/// Implements `Serialize` and `Deserialize` for a type `$t` which represents
|
||||||
|
/// a newtype over a byte-slice over length `$len`. Type `$t` must implement
|
||||||
|
/// the `FromStr` and `Display` trait.
|
||||||
|
macro_rules! serde_impl(
|
||||||
|
($t:ident, $len:expr) => (
|
||||||
|
impl ::serde::Serialize for $t {
|
||||||
|
fn serialize<S: ::serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
|
||||||
|
if s.is_human_readable() {
|
||||||
|
s.collect_str(self)
|
||||||
|
} else {
|
||||||
|
s.serialize_bytes(&self[..])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de> ::serde::Deserialize<'de> for $t {
|
||||||
|
fn deserialize<D: ::serde::Deserializer<'de>>(d: D) -> Result<$t, D::Error> {
|
||||||
|
use ::serde::de::Error;
|
||||||
|
use core::str::FromStr;
|
||||||
|
|
||||||
|
if d.is_human_readable() {
|
||||||
|
let sl: &str = ::serde::Deserialize::deserialize(d)?;
|
||||||
|
SecretKey::from_str(sl).map_err(D::Error::custom)
|
||||||
|
} else {
|
||||||
|
let sl: &[u8] = ::serde::Deserialize::deserialize(d)?;
|
||||||
|
if sl.len() != $len {
|
||||||
|
Err(D::Error::invalid_length(sl.len(), &stringify!($len)))
|
||||||
|
} else {
|
||||||
|
let mut ret = [0; $len];
|
||||||
|
ret.copy_from_slice(sl);
|
||||||
|
Ok($t(ret))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
#[cfg(not(feature="serde"))]
|
||||||
|
macro_rules! serde_impl(
|
||||||
|
($t:ident, $len:expr) => ()
|
||||||
|
);
|
||||||
|
|
Loading…
Reference in New Issue