@@ -25,6 +25,9 @@ use crate::Error::{self, InvalidPublicKey, InvalidPublicKeySum, InvalidSecretKey
25
25
use crate :: ffi:: { self , CPtr , impl_array_newtype} ;
26
26
use crate :: ffi:: types:: c_uint;
27
27
28
+ #[ cfg( feature = "serde" ) ]
29
+ use serde:: ser:: SerializeTuple ;
30
+
28
31
#[ cfg( feature = "global-context" ) ]
29
32
use crate :: { Message , ecdsa, SECP256K1 } ;
30
33
#[ cfg( all( feature = "global-context" , feature = "rand-std" ) ) ]
@@ -33,6 +36,12 @@ use crate::Scalar;
33
36
34
37
/// Secret 256-bit key used as `x` in an ECDSA signature.
35
38
///
39
+ /// # Serde support
40
+ ///
41
+ /// Implements de/serialization with the `serde` feature enabled. We treat the byte value as a tuple
42
+ /// of 32 `u8`s for non-human-readable formats. This representation is optimal for for some formats
43
+ /// (e.g. [`bincode`]) however other formats may be less optimal (e.g. [`cbor`]).
44
+ ///
36
45
/// # Examples
37
46
///
38
47
/// Basic usage:
@@ -45,6 +54,8 @@ use crate::Scalar;
45
54
/// let secret_key = SecretKey::new(&mut rand::thread_rng());
46
55
/// # }
47
56
/// ```
57
+ /// [`bincode`]: https://docs.rs/bincode
58
+ /// [`cbor`]: https://docs.rs/cbor
48
59
pub struct SecretKey ( [ u8 ; constants:: SECRET_KEY_SIZE ] ) ;
49
60
impl_array_newtype ! ( SecretKey , u8 , constants:: SECRET_KEY_SIZE ) ;
50
61
impl_display_secret ! ( SecretKey ) ;
@@ -68,6 +79,12 @@ pub const ONE_KEY: SecretKey = SecretKey([0, 0, 0, 0, 0, 0, 0, 0,
68
79
69
80
/// A Secp256k1 public key, used for verification of signatures.
70
81
///
82
+ /// # Serde support
83
+ ///
84
+ /// Implements de/serialization with the `serde` feature enabled. We treat the byte value as a tuple
85
+ /// of 33 `u8`s for non-human-readable formats. This representation is optimal for for some formats
86
+ /// (e.g. [`bincode`]) however other formats may be less optimal (e.g. [`cbor`]).
87
+ ///
71
88
/// # Examples
72
89
///
73
90
/// Basic usage:
@@ -81,6 +98,8 @@ pub const ONE_KEY: SecretKey = SecretKey([0, 0, 0, 0, 0, 0, 0, 0,
81
98
/// let public_key = PublicKey::from_secret_key(&secp, &secret_key);
82
99
/// # }
83
100
/// ```
101
+ /// [`bincode`]: https://docs.rs/bincode
102
+ /// [`cbor`]: https://docs.rs/cbor
84
103
#[ derive( Copy , Clone , PartialEq , Eq , Debug , Hash ) ]
85
104
#[ repr( transparent) ]
86
105
pub struct PublicKey ( ffi:: PublicKey ) ;
@@ -315,7 +334,11 @@ impl serde::Serialize for SecretKey {
315
334
let mut buf = [ 0u8 ; constants:: SECRET_KEY_SIZE * 2 ] ;
316
335
s. serialize_str ( crate :: to_hex ( & self . 0 , & mut buf) . expect ( "fixed-size hex serialization" ) )
317
336
} else {
318
- s. serialize_bytes ( & self [ ..] )
337
+ let mut tuple = s. serialize_tuple ( constants:: SECRET_KEY_SIZE ) ?;
338
+ for byte in self . 0 . iter ( ) {
339
+ tuple. serialize_element ( byte) ?;
340
+ }
341
+ tuple. end ( )
319
342
}
320
343
}
321
344
}
@@ -329,10 +352,11 @@ impl<'de> serde::Deserialize<'de> for SecretKey {
329
352
"a hex string representing 32 byte SecretKey"
330
353
) )
331
354
} else {
332
- d . deserialize_bytes ( super :: serde_util:: BytesVisitor :: new (
355
+ let visitor = super :: serde_util:: Tuple32Visitor :: new (
333
356
"raw 32 bytes SecretKey" ,
334
357
SecretKey :: from_slice
335
- ) )
358
+ ) ;
359
+ d. deserialize_tuple ( constants:: SECRET_KEY_SIZE , visitor)
336
360
}
337
361
}
338
362
}
@@ -649,7 +673,11 @@ impl serde::Serialize for PublicKey {
649
673
if s. is_human_readable ( ) {
650
674
s. collect_str ( self )
651
675
} else {
652
- s. serialize_bytes ( & self . serialize ( ) )
676
+ let mut tuple = s. serialize_tuple ( constants:: PUBLIC_KEY_SIZE ) ?;
677
+ for byte in self . serialize ( ) . iter ( ) { // Serialize in compressed form.
678
+ tuple. serialize_element ( & byte) ?;
679
+ }
680
+ tuple. end ( )
653
681
}
654
682
}
655
683
}
@@ -663,10 +691,11 @@ impl<'de> serde::Deserialize<'de> for PublicKey {
663
691
"an ASCII hex string representing a public key"
664
692
) )
665
693
} else {
666
- d . deserialize_bytes ( super :: serde_util:: BytesVisitor :: new (
667
- "a bytestring representing a public key" ,
694
+ let visitor = super :: serde_util:: Tuple33Visitor :: new (
695
+ "33 bytes compressed public key" ,
668
696
PublicKey :: from_slice
669
- ) )
697
+ ) ;
698
+ d. deserialize_tuple ( constants:: PUBLIC_KEY_SIZE , visitor)
670
699
}
671
700
}
672
701
}
@@ -687,13 +716,10 @@ impl Ord for PublicKey {
687
716
///
688
717
/// # Serde support
689
718
///
690
- /// [`Serialize`] and [`Deserialize`] are not implemented for this type, even with the `serde`
691
- /// feature active. This is due to security considerations, see the [`serde_keypair`] documentation
692
- /// for details.
693
- ///
694
- /// If the `serde` and `global-context` features are active `KeyPair`s can be serialized and
695
- /// deserialized by annotating them with `#[serde(with = "secp256k1::serde_keypair")]`
696
- /// inside structs or enums for which [`Serialize`] and [`Deserialize`] are being derived.
719
+ /// Implements de/serialization with the `serde` and_`global-context` features enabled. Serializes
720
+ /// the secret bytes only. We treat the byte value as a tuple of 32 `u8`s for non-human-readable
721
+ /// formats. This representation is optimal for for some formats (e.g. [`bincode`]) however other
722
+ /// formats may be less optimal (e.g. [`cbor`]). For human-readable formats we use a hex string.
697
723
///
698
724
/// # Examples
699
725
///
@@ -708,8 +734,8 @@ impl Ord for PublicKey {
708
734
/// let key_pair = KeyPair::from_secret_key(&secp, &secret_key);
709
735
/// # }
710
736
/// ```
711
- /// [`Deserialize `]: serde::Deserialize
712
- /// [`Serialize `]: serde::Serialize
737
+ /// [`bincode `]: https://docs.rs/bincode
738
+ /// [`cbor `]: https://docs.rs/cbor
713
739
#[ derive( Copy , Clone , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
714
740
pub struct KeyPair ( ffi:: KeyPair ) ;
715
741
impl_display_secret ! ( KeyPair ) ;
@@ -966,7 +992,11 @@ impl serde::Serialize for KeyPair {
966
992
s. serialize_str ( crate :: to_hex ( & self . secret_bytes ( ) , & mut buf)
967
993
. expect ( "fixed-size hex serialization" ) )
968
994
} else {
969
- s. serialize_bytes ( & self . 0 [ ..] )
995
+ let mut tuple = s. serialize_tuple ( constants:: SECRET_KEY_SIZE ) ?;
996
+ for byte in self . secret_bytes ( ) . iter ( ) {
997
+ tuple. serialize_element ( & byte) ?;
998
+ }
999
+ tuple. end ( )
970
1000
}
971
1001
}
972
1002
}
@@ -980,19 +1010,26 @@ impl<'de> serde::Deserialize<'de> for KeyPair {
980
1010
"a hex string representing 32 byte KeyPair"
981
1011
) )
982
1012
} else {
983
- d . deserialize_bytes ( super :: serde_util:: BytesVisitor :: new (
1013
+ let visitor = super :: serde_util:: Tuple32Visitor :: new (
984
1014
"raw 32 bytes KeyPair" ,
985
1015
|data| unsafe {
986
1016
let ctx = Secp256k1 :: from_raw_all ( ffi:: secp256k1_context_no_precomp as * mut ffi:: Context ) ;
987
1017
KeyPair :: from_seckey_slice ( & ctx, data)
988
1018
}
989
- ) )
1019
+ ) ;
1020
+ d. deserialize_tuple ( constants:: SECRET_KEY_SIZE , visitor)
990
1021
}
991
1022
}
992
1023
}
993
1024
994
1025
/// An x-only public key, used for verification of Schnorr signatures and serialized according to BIP-340.
995
1026
///
1027
+ /// # Serde support
1028
+ ///
1029
+ /// Implements de/serialization with the `serde` feature enabled. We treat the byte value as a tuple
1030
+ /// of 32 `u8`s for non-human-readable formats. This representation is optimal for for some formats
1031
+ /// (e.g. [`bincode`]) however other formats may be less optimal (e.g. [`cbor`]).
1032
+ ///
996
1033
/// # Examples
997
1034
///
998
1035
/// Basic usage:
@@ -1006,6 +1043,8 @@ impl<'de> serde::Deserialize<'de> for KeyPair {
1006
1043
/// let xonly = XOnlyPublicKey::from_keypair(&key_pair);
1007
1044
/// # }
1008
1045
/// ```
1046
+ /// [`bincode`]: https://docs.rs/bincode
1047
+ /// [`cbor`]: https://docs.rs/cbor
1009
1048
#[ derive( Copy , Clone , PartialEq , Eq , Debug , PartialOrd , Ord , Hash ) ]
1010
1049
pub struct XOnlyPublicKey ( ffi:: XOnlyPublicKey ) ;
1011
1050
@@ -1429,7 +1468,11 @@ impl serde::Serialize for XOnlyPublicKey {
1429
1468
if s. is_human_readable ( ) {
1430
1469
s. collect_str ( self )
1431
1470
} else {
1432
- s. serialize_bytes ( & self . serialize ( ) )
1471
+ let mut tuple = s. serialize_tuple ( constants:: SCHNORR_PUBLIC_KEY_SIZE ) ?;
1472
+ for byte in self . serialize ( ) . iter ( ) {
1473
+ tuple. serialize_element ( & byte) ?;
1474
+ }
1475
+ tuple. end ( )
1433
1476
}
1434
1477
}
1435
1478
}
@@ -1443,10 +1486,11 @@ impl<'de> serde::Deserialize<'de> for XOnlyPublicKey {
1443
1486
"a hex string representing 32 byte schnorr public key"
1444
1487
) )
1445
1488
} else {
1446
- d . deserialize_bytes ( super :: serde_util:: BytesVisitor :: new (
1489
+ let visitor = super :: serde_util:: Tuple32Visitor :: new (
1447
1490
"raw 32 bytes schnorr public key" ,
1448
1491
XOnlyPublicKey :: from_slice
1449
- ) )
1492
+ ) ;
1493
+ d. deserialize_tuple ( constants:: SCHNORR_PUBLIC_KEY_SIZE , visitor)
1450
1494
}
1451
1495
}
1452
1496
}
@@ -1492,6 +1536,8 @@ pub mod serde_keypair {
1492
1536
#[ cfg( test) ]
1493
1537
#[ allow( unused_imports) ]
1494
1538
mod test {
1539
+ use super :: * ;
1540
+
1495
1541
use core:: str:: FromStr ;
1496
1542
1497
1543
#[ cfg( any( feature = "alloc" , feature = "std" ) ) ]
@@ -1949,6 +1995,7 @@ mod test {
1949
1995
static SK_STR : & ' static str = "\
1950
1996
01010101010101010001020304050607ffff0000ffff00006363636363636363\
1951
1997
";
1998
+ #[ cfg( fuzzing) ]
1952
1999
static PK_BYTES : [ u8 ; 33 ] = [
1953
2000
0x02 ,
1954
2001
0x18 , 0x84 , 0x57 , 0x81 , 0xf6 , 0x31 , 0xc4 , 0x8f ,
@@ -1971,22 +2018,32 @@ mod test {
1971
2018
#[ cfg( fuzzing) ]
1972
2019
let pk = PublicKey :: from_slice ( & PK_BYTES ) . expect ( "pk" ) ;
1973
2020
1974
- assert_tokens ( & sk. compact ( ) , & [ Token :: BorrowedBytes ( & SK_BYTES [ ..] ) ] ) ;
1975
- assert_tokens ( & sk. compact ( ) , & [ Token :: Bytes ( & SK_BYTES ) ] ) ;
1976
- assert_tokens ( & sk. compact ( ) , & [ Token :: ByteBuf ( & SK_BYTES ) ] ) ;
2021
+ assert_tokens ( & sk. compact ( ) , & [
2022
+ Token :: Tuple { len : 32 } ,
2023
+ Token :: U8 ( 1 ) , Token :: U8 ( 1 ) , Token :: U8 ( 1 ) , Token :: U8 ( 1 ) , Token :: U8 ( 1 ) , Token :: U8 ( 1 ) , Token :: U8 ( 1 ) , Token :: U8 ( 1 ) ,
2024
+ Token :: U8 ( 0 ) , Token :: U8 ( 1 ) , Token :: U8 ( 2 ) , Token :: U8 ( 3 ) , Token :: U8 ( 4 ) , Token :: U8 ( 5 ) , Token :: U8 ( 6 ) , Token :: U8 ( 7 ) ,
2025
+ Token :: U8 ( 0xff ) , Token :: U8 ( 0xff ) , Token :: U8 ( 0 ) , Token :: U8 ( 0 ) , Token :: U8 ( 0xff ) , Token :: U8 ( 0xff ) , Token :: U8 ( 0 ) , Token :: U8 ( 0 ) ,
2026
+ Token :: U8 ( 99 ) , Token :: U8 ( 99 ) , Token :: U8 ( 99 ) , Token :: U8 ( 99 ) , Token :: U8 ( 99 ) , Token :: U8 ( 99 ) , Token :: U8 ( 99 ) , Token :: U8 ( 99 ) ,
2027
+ Token :: TupleEnd
2028
+ ] ) ;
1977
2029
1978
2030
assert_tokens ( & sk. readable ( ) , & [ Token :: BorrowedStr ( SK_STR ) ] ) ;
1979
2031
assert_tokens ( & sk. readable ( ) , & [ Token :: Str ( SK_STR ) ] ) ;
1980
2032
assert_tokens ( & sk. readable ( ) , & [ Token :: String ( SK_STR ) ] ) ;
1981
2033
1982
- assert_tokens ( & pk. compact ( ) , & [ Token :: BorrowedBytes ( & PK_BYTES [ ..] ) ] ) ;
1983
- assert_tokens ( & pk. compact ( ) , & [ Token :: Bytes ( & PK_BYTES ) ] ) ;
1984
- assert_tokens ( & pk. compact ( ) , & [ Token :: ByteBuf ( & PK_BYTES ) ] ) ;
2034
+ assert_tokens ( & pk. compact ( ) , & [
2035
+ Token :: Tuple { len : 33 } ,
2036
+ Token :: U8 ( 0x02 ) ,
2037
+ Token :: U8 ( 0x18 ) , Token :: U8 ( 0x84 ) , Token :: U8 ( 0x57 ) , Token :: U8 ( 0x81 ) , Token :: U8 ( 0xf6 ) , Token :: U8 ( 0x31 ) , Token :: U8 ( 0xc4 ) , Token :: U8 ( 0x8f ) ,
2038
+ Token :: U8 ( 0x1c ) , Token :: U8 ( 0x97 ) , Token :: U8 ( 0x09 ) , Token :: U8 ( 0xe2 ) , Token :: U8 ( 0x30 ) , Token :: U8 ( 0x92 ) , Token :: U8 ( 0x06 ) , Token :: U8 ( 0x7d ) ,
2039
+ Token :: U8 ( 0x06 ) , Token :: U8 ( 0x83 ) , Token :: U8 ( 0x7f ) , Token :: U8 ( 0x30 ) , Token :: U8 ( 0xaa ) , Token :: U8 ( 0x0c ) , Token :: U8 ( 0xd0 ) , Token :: U8 ( 0x54 ) ,
2040
+ Token :: U8 ( 0x4a ) , Token :: U8 ( 0xc8 ) , Token :: U8 ( 0x87 ) , Token :: U8 ( 0xfe ) , Token :: U8 ( 0x91 ) , Token :: U8 ( 0xdd ) , Token :: U8 ( 0xd1 ) , Token :: U8 ( 0x66 ) ,
2041
+ Token :: TupleEnd
2042
+ ] ) ;
1985
2043
1986
2044
assert_tokens ( & pk. readable ( ) , & [ Token :: BorrowedStr ( PK_STR ) ] ) ;
1987
2045
assert_tokens ( & pk. readable ( ) , & [ Token :: Str ( PK_STR ) ] ) ;
1988
2046
assert_tokens ( & pk. readable ( ) , & [ Token :: String ( PK_STR ) ] ) ;
1989
-
1990
2047
}
1991
2048
1992
2049
#[ test]
@@ -2066,10 +2123,14 @@ mod test {
2066
2123
";
2067
2124
2068
2125
let sk = KeyPairWrapper ( KeyPair :: from_seckey_slice ( & crate :: SECP256K1 , & SK_BYTES ) . unwrap ( ) ) ;
2069
-
2070
- assert_tokens ( & sk. compact ( ) , & [ Token :: BorrowedBytes ( & SK_BYTES [ ..] ) ] ) ;
2071
- assert_tokens ( & sk. compact ( ) , & [ Token :: Bytes ( & SK_BYTES ) ] ) ;
2072
- assert_tokens ( & sk. compact ( ) , & [ Token :: ByteBuf ( & SK_BYTES ) ] ) ;
2126
+ assert_tokens ( & sk. compact ( ) , & [
2127
+ Token :: Tuple { len : 32 } ,
2128
+ Token :: U8 ( 1 ) , Token :: U8 ( 1 ) , Token :: U8 ( 1 ) , Token :: U8 ( 1 ) , Token :: U8 ( 1 ) , Token :: U8 ( 1 ) , Token :: U8 ( 1 ) , Token :: U8 ( 1 ) ,
2129
+ Token :: U8 ( 0 ) , Token :: U8 ( 1 ) , Token :: U8 ( 2 ) , Token :: U8 ( 3 ) , Token :: U8 ( 4 ) , Token :: U8 ( 5 ) , Token :: U8 ( 6 ) , Token :: U8 ( 7 ) ,
2130
+ Token :: U8 ( 0xff ) , Token :: U8 ( 0xff ) , Token :: U8 ( 0 ) , Token :: U8 ( 0 ) , Token :: U8 ( 0xff ) , Token :: U8 ( 0xff ) , Token :: U8 ( 0 ) , Token :: U8 ( 0 ) ,
2131
+ Token :: U8 ( 99 ) , Token :: U8 ( 99 ) , Token :: U8 ( 99 ) , Token :: U8 ( 99 ) , Token :: U8 ( 99 ) , Token :: U8 ( 99 ) , Token :: U8 ( 99 ) , Token :: U8 ( 99 ) ,
2132
+ Token :: TupleEnd
2133
+ ] ) ;
2073
2134
2074
2135
assert_tokens ( & sk. readable ( ) , & [ Token :: BorrowedStr ( SK_STR ) ] ) ;
2075
2136
assert_tokens ( & sk. readable ( ) , & [ Token :: Str ( SK_STR ) ] ) ;
@@ -2221,4 +2282,38 @@ mod test {
2221
2282
2222
2283
assert_eq ! ( got, want)
2223
2284
}
2285
+
2286
+ #[ test]
2287
+ #[ cfg( not( fuzzing) ) ]
2288
+ #[ cfg( all( feature = "global-context" , feature = "serde" ) ) ]
2289
+ fn test_serde_x_only_pubkey ( ) {
2290
+ use serde_test:: { Configure , Token , assert_tokens} ;
2291
+
2292
+ static SK_BYTES : [ u8 ; 32 ] = [
2293
+ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ,
2294
+ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ,
2295
+ 0xff , 0xff , 0 , 0 , 0xff , 0xff , 0 , 0 ,
2296
+ 99 , 99 , 99 , 99 , 99 , 99 , 99 , 99
2297
+ ] ;
2298
+
2299
+ static PK_STR : & ' static str = "\
2300
+ 18845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166\
2301
+ ";
2302
+
2303
+ let kp = KeyPair :: from_seckey_slice ( & crate :: SECP256K1 , & SK_BYTES ) . unwrap ( ) ;
2304
+ let ( pk, _parity) = XOnlyPublicKey :: from_keypair ( & kp) ;
2305
+
2306
+ assert_tokens ( & pk. compact ( ) , & [
2307
+ Token :: Tuple { len : 32 } ,
2308
+ Token :: U8 ( 0x18 ) , Token :: U8 ( 0x84 ) , Token :: U8 ( 0x57 ) , Token :: U8 ( 0x81 ) , Token :: U8 ( 0xf6 ) , Token :: U8 ( 0x31 ) , Token :: U8 ( 0xc4 ) , Token :: U8 ( 0x8f ) ,
2309
+ Token :: U8 ( 0x1c ) , Token :: U8 ( 0x97 ) , Token :: U8 ( 0x09 ) , Token :: U8 ( 0xe2 ) , Token :: U8 ( 0x30 ) , Token :: U8 ( 0x92 ) , Token :: U8 ( 0x06 ) , Token :: U8 ( 0x7d ) ,
2310
+ Token :: U8 ( 0x06 ) , Token :: U8 ( 0x83 ) , Token :: U8 ( 0x7f ) , Token :: U8 ( 0x30 ) , Token :: U8 ( 0xaa ) , Token :: U8 ( 0x0c ) , Token :: U8 ( 0xd0 ) , Token :: U8 ( 0x54 ) ,
2311
+ Token :: U8 ( 0x4a ) , Token :: U8 ( 0xc8 ) , Token :: U8 ( 0x87 ) , Token :: U8 ( 0xfe ) , Token :: U8 ( 0x91 ) , Token :: U8 ( 0xdd ) , Token :: U8 ( 0xd1 ) , Token :: U8 ( 0x66 ) ,
2312
+ Token :: TupleEnd
2313
+ ] ) ;
2314
+
2315
+ assert_tokens ( & pk. readable ( ) , & [ Token :: BorrowedStr ( PK_STR ) ] ) ;
2316
+ assert_tokens ( & pk. readable ( ) , & [ Token :: Str ( PK_STR ) ] ) ;
2317
+ assert_tokens ( & pk. readable ( ) , & [ Token :: String ( PK_STR ) ] ) ;
2318
+ }
2224
2319
}
0 commit comments