Skip to content

Commit 0dba4c0

Browse files
committed
Merge #34: Implement serde for EcdsaAdaptorSignature
f089aea Implement serde for EcdsaAdaptorSignature (Lucas Soriano del Pino) 5a4f874 Define deserialization from string and bytes generically (Lucas Soriano del Pino) Pull request description: ACKs for top commit: thomaseizinger: ACK f089aea jonasnick: ACK f089aea Tree-SHA512: c1cbfda5b2b1e54973140cda8e6a1a4aa5b12730e78ded37a4686b16cb4f337bd4bda6fcceba308965cef7c191a37667c25b23732bc0a21e6582fa70f56f3c6f
2 parents 0601fad + f089aea commit 0dba4c0

8 files changed

+199
-218
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
- Rename `secp256k1_zkp::bitcoin_hashes` module to `secp256k1_zkp::hashes`.
44
- Rename feature `hashes` to `bitcoin_hashes` to align with `rust-secp256k1`.
5+
- Implement `serde::{Serialize, Deserialize}` for `EcdsaAdaptorSignature`.
56

67
# 0.4.0 - 2021-05-04
78

src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ pub use key::{PublicKey, SecretKey};
7474

7575
pub use secp256k1::*;
7676

77+
#[cfg(feature = "serde")]
78+
mod serde_util;
7779
mod zkp;
7880
pub use zkp::*;
7981

src/serde_util.rs

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
use core::fmt;
2+
use core::marker::PhantomData;
3+
use core::str::{self, FromStr};
4+
use serde::de;
5+
6+
/// A serde visitor that works for `T`s implementing `FromStr`.
7+
pub struct FromStrVisitor<T> {
8+
expectation: &'static str,
9+
_pd: PhantomData<T>,
10+
}
11+
12+
impl<T> FromStrVisitor<T> {
13+
pub fn new(expectation: &'static str) -> Self {
14+
FromStrVisitor {
15+
expectation,
16+
_pd: PhantomData,
17+
}
18+
}
19+
}
20+
21+
impl<'de, T> de::Visitor<'de> for FromStrVisitor<T>
22+
where
23+
T: FromStr,
24+
<T as FromStr>::Err: fmt::Display,
25+
{
26+
type Value = T;
27+
28+
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
29+
formatter.write_str(self.expectation)
30+
}
31+
32+
fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
33+
FromStr::from_str(v).map_err(E::custom)
34+
}
35+
}
36+
37+
pub struct BytesVisitor<F> {
38+
expectation: &'static str,
39+
parse_fn: F,
40+
}
41+
42+
impl<F, T, Err> BytesVisitor<F>
43+
where
44+
F: FnOnce(&[u8]) -> Result<T, Err>,
45+
Err: fmt::Display,
46+
{
47+
pub fn new(expectation: &'static str, parse_fn: F) -> Self {
48+
BytesVisitor {
49+
expectation,
50+
parse_fn,
51+
}
52+
}
53+
}
54+
55+
impl<'de, F, T, Err> de::Visitor<'de> for BytesVisitor<F>
56+
where
57+
F: FnOnce(&[u8]) -> Result<T, Err>,
58+
Err: fmt::Display,
59+
{
60+
type Value = T;
61+
62+
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
63+
formatter.write_str(self.expectation)
64+
}
65+
66+
fn visit_bytes<E: de::Error>(self, v: &[u8]) -> Result<Self::Value, E> {
67+
(self.parse_fn)(v).map_err(E::custom)
68+
}
69+
}

src/zkp/ecdsa_adaptor.rs

+70
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,33 @@ impl str::FromStr for EcdsaAdaptorSignature {
5050
}
5151
}
5252

53+
#[cfg(feature = "serde")]
54+
impl ::serde::Serialize for EcdsaAdaptorSignature {
55+
fn serialize<S: ::serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
56+
if s.is_human_readable() {
57+
s.collect_str(self)
58+
} else {
59+
s.serialize_bytes(self.0.as_bytes())
60+
}
61+
}
62+
}
63+
64+
#[cfg(feature = "serde")]
65+
impl<'de> ::serde::Deserialize<'de> for EcdsaAdaptorSignature {
66+
fn deserialize<D: ::serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
67+
use serde_util;
68+
69+
if d.is_human_readable() {
70+
d.deserialize_str(serde_util::FromStrVisitor::new("an ASCII hex string"))
71+
} else {
72+
d.deserialize_bytes(serde_util::BytesVisitor::new(
73+
"a bytestring",
74+
EcdsaAdaptorSignature::from_slice,
75+
))
76+
}
77+
}
78+
}
79+
5380
impl CPtr for EcdsaAdaptorSignature {
5481
type Target = ffi::EcdsaAdaptorSignature;
5582
fn as_c_ptr(&self) -> *const Self::Target {
@@ -409,6 +436,49 @@ mod tests {
409436
assert_eq!(expected_decryption_key, recovered);
410437
}
411438

439+
#[cfg(feature = "serde")]
440+
#[test]
441+
fn test_ecdsa_adaptor_sig_de_serialization() {
442+
use serde_test::Configure;
443+
use serde_test::{assert_tokens, Token};
444+
445+
let sig = EcdsaAdaptorSignature::from_slice(&[
446+
3, 44, 99, 124, 215, 151, 221, 140, 44, 226, 97, 144, 126, 212, 62, 130, 214, 209, 164,
447+
140, 186, 187, 190, 206, 128, 17, 51, 221, 141, 112, 160, 27, 20, 3, 235, 97, 90, 62,
448+
89, 177, 203, 191, 79, 135, 172, 175, 100, 91, 225, 237, 163, 42, 6, 102, 17, 243, 93,
449+
213, 85, 120, 2, 128, 43, 20, 177, 156, 129, 192, 76, 63, 239, 172, 87, 131, 178, 7,
450+
123, 212, 63, 160, 163, 154, 184, 166, 77, 77, 120, 51, 42, 93, 98, 30, 162, 62, 202,
451+
70, 188, 1, 16, 17, 171, 130, 221, 166, 222, 184, 86, 153, 245, 8, 116, 77, 112, 212,
452+
19, 75, 234, 3, 247, 132, 210, 133, 181, 198, 193, 90, 86, 228, 225, 250, 180, 188, 53,
453+
106, 187, 222, 187, 59, 143, 225, 229, 94, 109, 214, 210, 169, 234, 69, 126, 145, 178,
454+
230, 100, 47, 174, 105, 249, 219, 181, 37, 136, 84,
455+
])
456+
.unwrap();
457+
458+
assert_tokens(
459+
&sig.readable(),
460+
&[Token::Str(
461+
"032c637cd797dd8c2ce261907ed43e82d6d1a48cbabbbece801133dd8d70a01b1403eb615a3e59b1cbbf4f87acaf645be1eda32a066611f35dd5557802802b14b19c81c04c3fefac5783b2077bd43fa0a39ab8a64d4d78332a5d621ea23eca46bc011011ab82dda6deb85699f508744d70d4134bea03f784d285b5c6c15a56e4e1fab4bc356abbdebb3b8fe1e55e6dd6d2a9ea457e91b2e6642fae69f9dbb5258854",
462+
)],
463+
);
464+
465+
assert_tokens(
466+
&sig.compact(),
467+
&[Token::Bytes(&[
468+
3, 44, 99, 124, 215, 151, 221, 140, 44, 226, 97, 144, 126, 212, 62, 130, 214, 209,
469+
164, 140, 186, 187, 190, 206, 128, 17, 51, 221, 141, 112, 160, 27, 20, 3, 235, 97,
470+
90, 62, 89, 177, 203, 191, 79, 135, 172, 175, 100, 91, 225, 237, 163, 42, 6, 102,
471+
17, 243, 93, 213, 85, 120, 2, 128, 43, 20, 177, 156, 129, 192, 76, 63, 239, 172,
472+
87, 131, 178, 7, 123, 212, 63, 160, 163, 154, 184, 166, 77, 77, 120, 51, 42, 93,
473+
98, 30, 162, 62, 202, 70, 188, 1, 16, 17, 171, 130, 221, 166, 222, 184, 86, 153,
474+
245, 8, 116, 77, 112, 212, 19, 75, 234, 3, 247, 132, 210, 133, 181, 198, 193, 90,
475+
86, 228, 225, 250, 180, 188, 53, 106, 187, 222, 187, 59, 143, 225, 229, 94, 109,
476+
214, 210, 169, 234, 69, 126, 145, 178, 230, 100, 47, 174, 105, 249, 219, 181, 37,
477+
136, 84,
478+
])],
479+
);
480+
}
481+
412482
fn msg_from_str(input: &str) -> Message {
413483
let mut buf = [0u8; 32];
414484
from_hex(input, &mut buf).unwrap();

src/zkp/generator.rs

+14-92
Original file line numberDiff line numberDiff line change
@@ -223,54 +223,15 @@ impl ::serde::Serialize for Generator {
223223
#[cfg(feature = "serde")]
224224
impl<'de> ::serde::Deserialize<'de> for Generator {
225225
fn deserialize<D: ::serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
226-
if d.is_human_readable() {
227-
struct HexVisitor;
228-
229-
impl<'de> ::serde::de::Visitor<'de> for HexVisitor {
230-
type Value = Generator;
226+
use serde_util;
231227

232-
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
233-
formatter.write_str("an ASCII hex string")
234-
}
235-
236-
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
237-
where
238-
E: ::serde::de::Error,
239-
{
240-
if let Ok(hex) = str::from_utf8(v) {
241-
str::FromStr::from_str(hex).map_err(E::custom)
242-
} else {
243-
Err(E::invalid_value(::serde::de::Unexpected::Bytes(v), &self))
244-
}
245-
}
246-
247-
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
248-
where
249-
E: ::serde::de::Error,
250-
{
251-
str::FromStr::from_str(v).map_err(E::custom)
252-
}
253-
}
254-
d.deserialize_str(HexVisitor)
228+
if d.is_human_readable() {
229+
d.deserialize_str(serde_util::FromStrVisitor::new("an ASCII hex string"))
255230
} else {
256-
struct BytesVisitor;
257-
258-
impl<'de> ::serde::de::Visitor<'de> for BytesVisitor {
259-
type Value = Generator;
260-
261-
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
262-
formatter.write_str("a bytestring")
263-
}
264-
265-
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
266-
where
267-
E: ::serde::de::Error,
268-
{
269-
Generator::from_slice(v).map_err(E::custom)
270-
}
271-
}
272-
273-
d.deserialize_bytes(BytesVisitor)
231+
d.deserialize_bytes(serde_util::BytesVisitor::new(
232+
"a bytestring",
233+
Generator::from_slice,
234+
))
274235
}
275236
}
276237
}
@@ -289,54 +250,15 @@ impl ::serde::Serialize for Tweak {
289250
#[cfg(feature = "serde")]
290251
impl<'de> ::serde::Deserialize<'de> for Tweak {
291252
fn deserialize<D: ::serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
292-
if d.is_human_readable() {
293-
struct HexVisitor;
294-
295-
impl<'de> ::serde::de::Visitor<'de> for HexVisitor {
296-
type Value = Tweak;
253+
use serde_util;
297254

298-
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
299-
formatter.write_str("an ASCII hex string")
300-
}
301-
302-
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
303-
where
304-
E: ::serde::de::Error,
305-
{
306-
if let Ok(hex) = str::from_utf8(v) {
307-
str::FromStr::from_str(hex).map_err(E::custom)
308-
} else {
309-
Err(E::invalid_value(::serde::de::Unexpected::Bytes(v), &self))
310-
}
311-
}
312-
313-
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
314-
where
315-
E: ::serde::de::Error,
316-
{
317-
str::FromStr::from_str(v).map_err(E::custom)
318-
}
319-
}
320-
d.deserialize_str(HexVisitor)
255+
if d.is_human_readable() {
256+
d.deserialize_str(serde_util::FromStrVisitor::new("an ASCII hex string"))
321257
} else {
322-
struct BytesVisitor;
323-
324-
impl<'de> ::serde::de::Visitor<'de> for BytesVisitor {
325-
type Value = Tweak;
326-
327-
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
328-
formatter.write_str("a bytestring")
329-
}
330-
331-
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
332-
where
333-
E: ::serde::de::Error,
334-
{
335-
Tweak::from_slice(v).map_err(E::custom)
336-
}
337-
}
338-
339-
d.deserialize_bytes(BytesVisitor)
258+
d.deserialize_bytes(serde_util::BytesVisitor::new(
259+
"a bytestring",
260+
Tweak::from_slice,
261+
))
340262
}
341263
}
342264
}

src/zkp/pedersen.rs

+7-46
Original file line numberDiff line numberDiff line change
@@ -219,54 +219,15 @@ impl ::serde::Serialize for PedersenCommitment {
219219
#[cfg(feature = "serde")]
220220
impl<'de> ::serde::Deserialize<'de> for PedersenCommitment {
221221
fn deserialize<D: ::serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
222+
use serde_util;
223+
222224
if d.is_human_readable() {
223-
struct HexVisitor;
224-
225-
impl<'de> ::serde::de::Visitor<'de> for HexVisitor {
226-
type Value = PedersenCommitment;
227-
228-
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
229-
formatter.write_str("an ASCII hex string")
230-
}
231-
232-
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
233-
where
234-
E: ::serde::de::Error,
235-
{
236-
if let Ok(hex) = str::from_utf8(v) {
237-
str::FromStr::from_str(hex).map_err(E::custom)
238-
} else {
239-
Err(E::invalid_value(::serde::de::Unexpected::Bytes(v), &self))
240-
}
241-
}
242-
243-
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
244-
where
245-
E: ::serde::de::Error,
246-
{
247-
str::FromStr::from_str(v).map_err(E::custom)
248-
}
249-
}
250-
d.deserialize_str(HexVisitor)
225+
d.deserialize_str(serde_util::FromStrVisitor::new("an ASCII hex string"))
251226
} else {
252-
struct BytesVisitor;
253-
254-
impl<'de> ::serde::de::Visitor<'de> for BytesVisitor {
255-
type Value = PedersenCommitment;
256-
257-
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
258-
formatter.write_str("a bytestring")
259-
}
260-
261-
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
262-
where
263-
E: ::serde::de::Error,
264-
{
265-
PedersenCommitment::from_slice(v).map_err(E::custom)
266-
}
267-
}
268-
269-
d.deserialize_bytes(BytesVisitor)
227+
d.deserialize_bytes(serde_util::BytesVisitor::new(
228+
"a bytestring",
229+
PedersenCommitment::from_slice,
230+
))
270231
}
271232
}
272233
}

0 commit comments

Comments
 (0)