Merge pull request #107 from jonasnick/human-readable-sk
Add human readable serialization and deserialization to Secret Key
This commit is contained in:
commit
b843f72955
33
src/key.rs
33
src/key.rs
|
@ -187,30 +187,7 @@ impl SecretKey {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
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))
|
||||
}
|
||||
}
|
||||
serde_impl!(SecretKey, constants::SECRET_KEY_SIZE);
|
||||
|
||||
impl PublicKey {
|
||||
/// Obtains a raw const pointer suitable for use with FFI functions
|
||||
|
@ -739,13 +716,16 @@ mod test {
|
|||
#[cfg(feature = "serde")]
|
||||
#[test]
|
||||
fn test_signature_serde() {
|
||||
use serde_test::{Token, assert_tokens};
|
||||
use serde_test::{Configure, Token, assert_tokens};
|
||||
static SK_BYTES: [u8; 32] = [
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
0, 1, 2, 3, 4, 5, 6, 7,
|
||||
0xff, 0xff, 0, 0, 0xff, 0xff, 0, 0,
|
||||
99, 99, 99, 99, 99, 99, 99, 99
|
||||
];
|
||||
static SK_STR: &'static str = "\
|
||||
01010101010101010001020304050607ffff0000ffff00006363636363636363\
|
||||
";
|
||||
static PK_BYTES: [u8; 33] = [
|
||||
0x02,
|
||||
0x18, 0x84, 0x57, 0x81, 0xf6, 0x31, 0xc4, 0x8f,
|
||||
|
@ -759,7 +739,8 @@ mod test {
|
|||
let sk = SecretKey::from_slice(&SK_BYTES).unwrap();
|
||||
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[..])]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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