Skip to content
This repository was archived by the owner on Oct 17, 2022. It is now read-only.

Commit e54611e

Browse files
authored
crypto: fix Ed25519AggregateSignature serialization (#800)
1 parent 050049c commit e54611e

File tree

2 files changed

+42
-3
lines changed

2 files changed

+42
-3
lines changed

crypto/src/ed25519.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use serde::{
1010
Deserialize, Serialize,
1111
};
1212
use serde_bytes::{ByteBuf, Bytes};
13+
use serde_with::serde_as;
1314
use signature::{rand_core::OsRng, Signature, Signer, Verifier};
1415
use std::{
1516
fmt::{self, Display},
@@ -18,7 +19,7 @@ use std::{
1819

1920
use crate::{
2021
pubkey_bytes::PublicKeyBytes,
21-
serde_helpers::keypair_decode_base64,
22+
serde_helpers::{keypair_decode_base64, Ed25519Signature as Ed25519Sig},
2223
traits::{
2324
AggregateAuthenticator, Authenticator, EncodeDecodeBase64, KeyPair, SigningKey,
2425
ToFromBytes, VerifyingKey,
@@ -59,9 +60,11 @@ pub struct Ed25519Signature {
5960
pub bytes: OnceCell<[u8; ED25519_SIGNATURE_LENGTH]>,
6061
}
6162

63+
#[serde_as]
6264
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
63-
pub struct Ed25519AggregateSignature(pub Vec<ed25519_consensus::Signature>);
64-
65+
pub struct Ed25519AggregateSignature(
66+
#[serde_as(as = "Vec<Ed25519Sig>")] pub Vec<ed25519_consensus::Signature>,
67+
);
6568
///
6669
/// Implement VerifyingKey
6770
///

crypto/src/serde_helpers.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,39 @@ pub fn keypair_decode_base64<T: KeyPair>(value: &str) -> Result<T, eyre::Report>
6767
}
6868
Ok(kp)
6969
}
70+
71+
pub struct Ed25519Signature;
72+
73+
impl SerializeAs<ed25519_consensus::Signature> for Ed25519Signature {
74+
fn serialize_as<S>(
75+
source: &ed25519_consensus::Signature,
76+
serializer: S,
77+
) -> Result<S::Ok, S::Error>
78+
where
79+
S: Serializer,
80+
{
81+
if serializer.is_human_readable() {
82+
// Serialise to Base64 encoded String
83+
base64ct::Base64::encode_string(source.to_bytes().as_ref()).serialize(serializer)
84+
} else {
85+
// Serialise to Bytes
86+
Bytes::serialize_as(&source.to_bytes(), serializer)
87+
}
88+
}
89+
}
90+
91+
impl<'de> DeserializeAs<'de, ed25519_consensus::Signature> for Ed25519Signature {
92+
fn deserialize_as<D>(deserializer: D) -> Result<ed25519_consensus::Signature, D::Error>
93+
where
94+
D: Deserializer<'de>,
95+
{
96+
let bytes = if deserializer.is_human_readable() {
97+
let s = String::deserialize(deserializer)?;
98+
base64ct::Base64::decode_vec(&s).map_err(to_custom_error::<'de, D, _>)?
99+
} else {
100+
Bytes::deserialize_as(deserializer)?
101+
};
102+
ed25519_consensus::Signature::try_from(bytes.as_slice())
103+
.map_err(to_custom_error::<'de, D, _>)
104+
}
105+
}

0 commit comments

Comments
 (0)