mirror of
https://github.com/mimblewimble/grin-wallet.git
synced 2025-01-22 03:51:08 +03:00
133 lines
3.9 KiB
Rust
133 lines
3.9 KiB
Rust
|
// Copyright 2019 The Grin Developers
|
||
|
//
|
||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
// you may not use this file except in compliance with the License.
|
||
|
// You may obtain a copy of the License at
|
||
|
//
|
||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||
|
//
|
||
|
// Unless required by applicable law or agreed to in writing, software
|
||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
// See the License for the specific language governing permissions and
|
||
|
// limitations under the License.
|
||
|
|
||
|
//! Sane serialization & deserialization of cryptographic structs into hex
|
||
|
|
||
|
/// Serializes an ed25519 PublicKey to and from hex
|
||
|
pub mod dalek_pubkey_serde {
|
||
|
use crate::grin_util::{from_hex, to_hex};
|
||
|
use ed25519_dalek::PublicKey as DalekPublicKey;
|
||
|
use serde::{Deserialize, Deserializer, Serializer};
|
||
|
|
||
|
///
|
||
|
pub fn serialize<S>(key: &DalekPublicKey, serializer: S) -> Result<S::Ok, S::Error>
|
||
|
where
|
||
|
S: Serializer,
|
||
|
{
|
||
|
serializer.serialize_str(&to_hex(key.to_bytes().to_vec()))
|
||
|
}
|
||
|
|
||
|
///
|
||
|
pub fn deserialize<'de, D>(deserializer: D) -> Result<DalekPublicKey, D::Error>
|
||
|
where
|
||
|
D: Deserializer<'de>,
|
||
|
{
|
||
|
use serde::de::Error;
|
||
|
String::deserialize(deserializer)
|
||
|
.and_then(|string| from_hex(string).map_err(|err| Error::custom(err.to_string())))
|
||
|
.and_then(|bytes: Vec<u8>| {
|
||
|
DalekPublicKey::from_bytes(&bytes).map_err(|err| Error::custom(err.to_string()))
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// Serializes an Option<ed25519_dalek::PublicKey> to and from hex
|
||
|
pub mod option_dalek_pubkey_serde {
|
||
|
use ed25519_dalek::PublicKey as DalekPublicKey;
|
||
|
use serde::de::Error;
|
||
|
use serde::{Deserialize, Deserializer, Serializer};
|
||
|
|
||
|
use crate::grin_util::{from_hex, to_hex};
|
||
|
|
||
|
///
|
||
|
pub fn serialize<S>(key: &Option<DalekPublicKey>, serializer: S) -> Result<S::Ok, S::Error>
|
||
|
where
|
||
|
S: Serializer,
|
||
|
{
|
||
|
match key {
|
||
|
Some(key) => serializer.serialize_str(&to_hex(key.to_bytes().to_vec())),
|
||
|
None => serializer.serialize_none(),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
///
|
||
|
pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<DalekPublicKey>, D::Error>
|
||
|
where
|
||
|
D: Deserializer<'de>,
|
||
|
{
|
||
|
Option::<String>::deserialize(deserializer).and_then(|res| match res {
|
||
|
Some(string) => from_hex(string.to_string())
|
||
|
.map_err(|err| Error::custom(err.to_string()))
|
||
|
.and_then(|bytes: Vec<u8>| {
|
||
|
let mut b = [0u8; 32];
|
||
|
b.copy_from_slice(&bytes[0..32]);
|
||
|
DalekPublicKey::from_bytes(&b)
|
||
|
.map(|val| Some(val))
|
||
|
.map_err(|err| Error::custom(err.to_string()))
|
||
|
}),
|
||
|
None => Ok(None),
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
// Test serialization methods of components that are being used
|
||
|
#[cfg(test)]
|
||
|
mod test {
|
||
|
use super::*;
|
||
|
use rand::rngs::mock::StepRng;
|
||
|
|
||
|
use crate::grin_util::{secp, static_secp_instance};
|
||
|
use ed25519_dalek::PublicKey as DalekPublicKey;
|
||
|
use ed25519_dalek::SecretKey as DalekSecretKey;
|
||
|
use serde::Deserialize;
|
||
|
|
||
|
use serde_json;
|
||
|
|
||
|
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)]
|
||
|
struct SerTest {
|
||
|
#[serde(with = "dalek_pubkey_serde")]
|
||
|
pub pub_key: DalekPublicKey,
|
||
|
#[serde(with = "option_dalek_pubkey_serde")]
|
||
|
pub pub_key_opt: Option<DalekPublicKey>,
|
||
|
}
|
||
|
|
||
|
impl SerTest {
|
||
|
pub fn random() -> SerTest {
|
||
|
let secp_inst = static_secp_instance();
|
||
|
let secp = secp_inst.lock();
|
||
|
let mut test_rng = StepRng::new(1234567890u64, 1);
|
||
|
let sec_key = secp::key::SecretKey::new(&secp, &mut test_rng);
|
||
|
let d_skey = DalekSecretKey::from_bytes(&sec_key.0).unwrap();
|
||
|
let d_pub_key: DalekPublicKey = (&d_skey).into();
|
||
|
SerTest {
|
||
|
pub_key: d_pub_key.clone(),
|
||
|
pub_key_opt: Some(d_pub_key),
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#[test]
|
||
|
fn ser_dalek_primitives() {
|
||
|
for _ in 0..10 {
|
||
|
let s = SerTest::random();
|
||
|
println!("Before Serialization: {:?}", s);
|
||
|
let serialized = serde_json::to_string_pretty(&s).unwrap();
|
||
|
println!("JSON: {}", serialized);
|
||
|
let deserialized: SerTest = serde_json::from_str(&serialized).unwrap();
|
||
|
println!("After Serialization: {:?}", deserialized);
|
||
|
println!();
|
||
|
assert_eq!(s, deserialized);
|
||
|
}
|
||
|
}
|
||
|
}
|