@@ -28,14 +28,15 @@ use crate::crypto::{
28
28
} ;
29
29
#[ cfg( feature = "full_crypto" ) ]
30
30
use crate :: crypto:: { DeriveError , DeriveJunction , Pair as TraitPair , SecretStringError } ;
31
- #[ cfg( all( feature = "full_crypto" , not( feature = "std" ) ) ) ]
32
- use secp256k1:: Secp256k1 ;
33
- #[ cfg( feature = "std" ) ]
34
- use secp256k1:: SECP256K1 ;
35
- #[ cfg( feature = "full_crypto" ) ]
31
+
32
+ #[ cfg( all( not( feature = "std" ) , feature = "full_crypto" ) ) ]
33
+ use k256:: ecdsa:: SigningKey as SecretKey ;
34
+ #[ cfg( not( feature = "std" ) ) ]
35
+ use k256:: ecdsa:: VerifyingKey ;
36
+ #[ cfg( all( feature = "std" , feature = "full_crypto" ) ) ]
36
37
use secp256k1:: {
37
38
ecdsa:: { RecoverableSignature , RecoveryId } ,
38
- Message , PublicKey , SecretKey ,
39
+ Message , PublicKey , SecretKey , SECP256K1 ,
39
40
} ;
40
41
#[ cfg( feature = "serde" ) ]
41
42
use serde:: { de, Deserialize , Deserializer , Serialize , Serializer } ;
@@ -53,9 +54,9 @@ pub const PUBLIC_KEY_SERIALIZED_SIZE: usize = 33;
53
54
/// The byte length of signature
54
55
pub const SIGNATURE_SERIALIZED_SIZE : usize = 65 ;
55
56
56
- /// A secret seed (which is bytewise essentially equivalent to a SecretKey) .
57
+ /// The secret seed.
57
58
///
58
- /// We need it as a different type because `Seed` is expected to be AsRef<[u8]> .
59
+ /// The raw secret seed, which can be used to create the `Pair` .
59
60
#[ cfg( feature = "full_crypto" ) ]
60
61
type Seed = [ u8 ; 32 ] ;
61
62
@@ -96,18 +97,21 @@ impl Public {
96
97
/// Create a new instance from the given full public key.
97
98
///
98
99
/// This will convert the full public key into the compressed format.
99
- #[ cfg( feature = "std" ) ]
100
100
pub fn from_full ( full : & [ u8 ] ) -> Result < Self , ( ) > {
101
- let pubkey = if full. len ( ) == 64 {
101
+ let mut tagged_full = [ 0u8 ; 65 ] ;
102
+ let full = if full. len ( ) == 64 {
102
103
// Tag it as uncompressed public key.
103
- let mut tagged_full = [ 0u8 ; 65 ] ;
104
104
tagged_full[ 0 ] = 0x04 ;
105
105
tagged_full[ 1 ..] . copy_from_slice ( full) ;
106
- secp256k1 :: PublicKey :: from_slice ( & tagged_full)
106
+ & tagged_full
107
107
} else {
108
- secp256k1 :: PublicKey :: from_slice ( full)
108
+ full
109
109
} ;
110
- pubkey. map ( |k| Self ( k. serialize ( ) ) ) . map_err ( |_| ( ) )
110
+ #[ cfg( feature = "std" ) ]
111
+ let pubkey = PublicKey :: from_slice ( & full) ;
112
+ #[ cfg( not( feature = "std" ) ) ]
113
+ let pubkey = VerifyingKey :: from_sec1_bytes ( & full) ;
114
+ pubkey. map ( |k| k. into ( ) ) . map_err ( |_| ( ) )
111
115
}
112
116
}
113
117
@@ -131,6 +135,24 @@ impl AsMut<[u8]> for Public {
131
135
}
132
136
}
133
137
138
+ #[ cfg( feature = "std" ) ]
139
+ impl From < PublicKey > for Public {
140
+ fn from ( pubkey : PublicKey ) -> Self {
141
+ Self ( pubkey. serialize ( ) )
142
+ }
143
+ }
144
+
145
+ #[ cfg( not( feature = "std" ) ) ]
146
+ impl From < VerifyingKey > for Public {
147
+ fn from ( pubkey : VerifyingKey ) -> Self {
148
+ Self :: unchecked_from (
149
+ pubkey. to_sec1_bytes ( ) [ ..]
150
+ . try_into ( )
151
+ . expect ( "valid key is serializable to [u8,33]. qed." ) ,
152
+ )
153
+ }
154
+ }
155
+
134
156
impl TryFrom < & [ u8 ] > for Public {
135
157
type Error = ( ) ;
136
158
@@ -331,23 +353,34 @@ impl Signature {
331
353
/// Recover the public key from this signature and a pre-hashed message.
332
354
#[ cfg( feature = "full_crypto" ) ]
333
355
pub fn recover_prehashed ( & self , message : & [ u8 ; 32 ] ) -> Option < Public > {
334
- let rid = RecoveryId :: from_i32 ( self . 0 [ 64 ] as i32 ) . ok ( ) ?;
335
- let sig = RecoverableSignature :: from_compact ( & self . 0 [ ..64 ] , rid) . ok ( ) ?;
336
- let message = Message :: from_digest_slice ( message) . expect ( "Message is 32 bytes; qed" ) ;
337
-
338
356
#[ cfg( feature = "std" ) ]
339
- let context = SECP256K1 ;
357
+ {
358
+ let rid = RecoveryId :: from_i32 ( self . 0 [ 64 ] as i32 ) . ok ( ) ?;
359
+ let sig = RecoverableSignature :: from_compact ( & self . 0 [ ..64 ] , rid) . ok ( ) ?;
360
+ let message = Message :: from_digest_slice ( message) . expect ( "Message is 32 bytes; qed" ) ;
361
+ SECP256K1 . recover_ecdsa ( & message, & sig) . ok ( ) . map ( Public :: from)
362
+ }
363
+
340
364
#[ cfg( not( feature = "std" ) ) ]
341
- let context = Secp256k1 :: verification_only ( ) ;
365
+ {
366
+ let rid = k256:: ecdsa:: RecoveryId :: from_byte ( self . 0 [ 64 ] ) ?;
367
+ let sig = k256:: ecdsa:: Signature :: from_bytes ( ( & self . 0 [ ..64 ] ) . into ( ) ) . ok ( ) ?;
368
+ VerifyingKey :: recover_from_prehash ( message, & sig, rid) . map ( Public :: from) . ok ( )
369
+ }
370
+ }
371
+ }
342
372
343
- context
344
- . recover_ecdsa ( & message, & sig)
345
- . ok ( )
346
- . map ( |pubkey| Public ( pubkey. serialize ( ) ) )
373
+ #[ cfg( not( feature = "std" ) ) ]
374
+ impl From < ( k256:: ecdsa:: Signature , k256:: ecdsa:: RecoveryId ) > for Signature {
375
+ fn from ( recsig : ( k256:: ecdsa:: Signature , k256:: ecdsa:: RecoveryId ) ) -> Signature {
376
+ let mut r = Self :: default ( ) ;
377
+ r. 0 [ ..64 ] . copy_from_slice ( & recsig. 0 . to_bytes ( ) ) ;
378
+ r. 0 [ 64 ] = recsig. 1 . to_byte ( ) ;
379
+ r
347
380
}
348
381
}
349
382
350
- #[ cfg( feature = "full_crypto" ) ]
383
+ #[ cfg( all ( feature = "std" , feature = " full_crypto") ) ]
351
384
impl From < RecoverableSignature > for Signature {
352
385
fn from ( recsig : RecoverableSignature ) -> Signature {
353
386
let mut r = Self :: default ( ) ;
@@ -384,17 +417,19 @@ impl TraitPair for Pair {
384
417
///
385
418
/// You should never need to use this; generate(), generate_with_phrase
386
419
fn from_seed_slice ( seed_slice : & [ u8 ] ) -> Result < Pair , SecretStringError > {
387
- let secret =
388
- SecretKey :: from_slice ( seed_slice) . map_err ( |_| SecretStringError :: InvalidSeedLength ) ?;
389
-
390
420
#[ cfg( feature = "std" ) ]
391
- let context = SECP256K1 ;
392
- #[ cfg( not( feature = "std" ) ) ]
393
- let context = Secp256k1 :: signing_only ( ) ;
421
+ {
422
+ let secret = SecretKey :: from_slice ( seed_slice)
423
+ . map_err ( |_| SecretStringError :: InvalidSeedLength ) ?;
424
+ Ok ( Pair { public : PublicKey :: from_secret_key ( & SECP256K1 , & secret) . into ( ) , secret } )
425
+ }
394
426
395
- let public = PublicKey :: from_secret_key ( & context, & secret) ;
396
- let public = Public ( public. serialize ( ) ) ;
397
- Ok ( Pair { public, secret } )
427
+ #[ cfg( not( feature = "std" ) ) ]
428
+ {
429
+ let secret = SecretKey :: from_slice ( seed_slice)
430
+ . map_err ( |_| SecretStringError :: InvalidSeedLength ) ?;
431
+ Ok ( Pair { public : VerifyingKey :: from ( & secret) . into ( ) , secret } )
432
+ }
398
433
}
399
434
400
435
/// Derive a child key from a series of given junctions.
@@ -438,7 +473,14 @@ impl TraitPair for Pair {
438
473
impl Pair {
439
474
/// Get the seed for this key.
440
475
pub fn seed ( & self ) -> Seed {
441
- self . secret . secret_bytes ( )
476
+ #[ cfg( feature = "std" ) ]
477
+ {
478
+ self . secret . secret_bytes ( )
479
+ }
480
+ #[ cfg( not( feature = "std" ) ) ]
481
+ {
482
+ self . secret . to_bytes ( ) . into ( )
483
+ }
442
484
}
443
485
444
486
/// Exactly as `from_string` except that if no matches are found then, the the first 32
@@ -455,14 +497,19 @@ impl Pair {
455
497
456
498
/// Sign a pre-hashed message
457
499
pub fn sign_prehashed ( & self , message : & [ u8 ; 32 ] ) -> Signature {
458
- let message = Message :: from_digest_slice ( message) . expect ( "Message is 32 bytes; qed" ) ;
459
-
460
500
#[ cfg( feature = "std" ) ]
461
- let context = SECP256K1 ;
462
- #[ cfg( not( feature = "std" ) ) ]
463
- let context = Secp256k1 :: signing_only ( ) ;
501
+ {
502
+ let message = Message :: from_digest_slice ( message) . expect ( "Message is 32 bytes; qed" ) ;
503
+ SECP256K1 . sign_ecdsa_recoverable ( & message, & self . secret ) . into ( )
504
+ }
464
505
465
- context. sign_ecdsa_recoverable ( & message, & self . secret ) . into ( )
506
+ #[ cfg( not( feature = "std" ) ) ]
507
+ {
508
+ self . secret
509
+ . sign_prehash_recoverable ( message)
510
+ . expect ( "signing may not fail (???). qed." )
511
+ . into ( )
512
+ }
466
513
}
467
514
468
515
/// Verify a signature on a pre-hashed message. Return `true` if the signature is valid
@@ -503,7 +550,7 @@ impl Pair {
503
550
// NOTE: this solution is not effective when `Pair` is moved around memory.
504
551
// The very same problem affects other cryptographic backends that are just using
505
552
// `zeroize`for their secrets.
506
- #[ cfg( feature = "full_crypto" ) ]
553
+ #[ cfg( all ( feature = "std" , feature = " full_crypto") ) ]
507
554
impl Drop for Pair {
508
555
fn drop ( & mut self ) {
509
556
self . secret . non_secure_erase ( )
@@ -770,8 +817,18 @@ mod test {
770
817
let msg = [ 0u8 ; 32 ] ;
771
818
let sig1 = pair. sign_prehashed ( & msg) ;
772
819
let sig2: Signature = {
773
- let message = Message :: from_digest_slice ( & msg) . unwrap ( ) ;
774
- SECP256K1 . sign_ecdsa_recoverable ( & message, & pair. secret ) . into ( )
820
+ #[ cfg( feature = "std" ) ]
821
+ {
822
+ let message = Message :: from_digest_slice ( & msg) . unwrap ( ) ;
823
+ SECP256K1 . sign_ecdsa_recoverable ( & message, & pair. secret ) . into ( )
824
+ }
825
+ #[ cfg( not( feature = "std" ) ) ]
826
+ {
827
+ pair. secret
828
+ . sign_prehash_recoverable ( & msg)
829
+ . expect ( "signing may not fail (???). qed." )
830
+ . into ( )
831
+ }
775
832
} ;
776
833
assert_eq ! ( sig1, sig2) ;
777
834
0 commit comments