@@ -24,7 +24,7 @@ use super::Error::{self, InvalidPublicKey, InvalidSecretKey};
2424use Signing ;
2525use Verification ;
2626use constants;
27- use ffi;
27+ use ffi:: { self , CPtr } ;
2828
2929/// Secret 256-bit key used as `x` in an ECDSA signature
3030pub struct SecretKey ( [ u8 ; constants:: SECRET_KEY_SIZE ] ) ;
@@ -117,7 +117,7 @@ impl SecretKey {
117117 unsafe {
118118 while ffi:: secp256k1_ec_seckey_verify (
119119 ffi:: secp256k1_context_no_precomp,
120- data. as_ptr ( ) ,
120+ data. as_c_ptr ( ) ,
121121 ) == 0
122122 {
123123 data = random_32_bytes ( rng) ;
@@ -135,7 +135,7 @@ impl SecretKey {
135135 unsafe {
136136 if ffi:: secp256k1_ec_seckey_verify (
137137 ffi:: secp256k1_context_no_precomp,
138- data. as_ptr ( ) ,
138+ data. as_c_ptr ( ) ,
139139 ) == 0
140140 {
141141 return Err ( InvalidSecretKey ) ;
@@ -162,8 +162,8 @@ impl SecretKey {
162162 unsafe {
163163 if ffi:: secp256k1_ec_privkey_tweak_add (
164164 ffi:: secp256k1_context_no_precomp,
165- self . as_mut_ptr ( ) ,
166- other. as_ptr ( ) ,
165+ self . as_mut_c_ptr ( ) ,
166+ other. as_c_ptr ( ) ,
167167 ) != 1
168168 {
169169 Err ( Error :: InvalidTweak )
@@ -187,8 +187,8 @@ impl SecretKey {
187187 unsafe {
188188 if ffi:: secp256k1_ec_privkey_tweak_mul (
189189 ffi:: secp256k1_context_no_precomp,
190- self . as_mut_ptr ( ) ,
191- other. as_ptr ( ) ,
190+ self . as_mut_c_ptr ( ) ,
191+ other. as_c_ptr ( ) ,
192192 ) != 1
193193 {
194194 Err ( Error :: InvalidTweak )
@@ -223,7 +223,7 @@ impl PublicKey {
223223 unsafe {
224224 // We can assume the return value because it's not possible to construct
225225 // an invalid `SecretKey` without transmute trickery or something
226- let res = ffi:: secp256k1_ec_pubkey_create ( secp. ctx , & mut pk, sk. as_ptr ( ) ) ;
226+ let res = ffi:: secp256k1_ec_pubkey_create ( secp. ctx , & mut pk, sk. as_c_ptr ( ) ) ;
227227 debug_assert_eq ! ( res, 1 ) ;
228228 }
229229 PublicKey ( pk)
@@ -232,12 +232,14 @@ impl PublicKey {
232232 /// Creates a public key directly from a slice
233233 #[ inline]
234234 pub fn from_slice ( data : & [ u8 ] ) -> Result < PublicKey , Error > {
235+ if data. is_empty ( ) { return Err ( Error :: InvalidPublicKey ) ; }
236+
235237 let mut pk = ffi:: PublicKey :: new ( ) ;
236238 unsafe {
237239 if ffi:: secp256k1_ec_pubkey_parse (
238240 ffi:: secp256k1_context_no_precomp,
239241 & mut pk,
240- data. as_ptr ( ) ,
242+ data. as_c_ptr ( ) ,
241243 data. len ( ) as usize ,
242244 ) == 1
243245 {
@@ -259,9 +261,9 @@ impl PublicKey {
259261 let mut ret_len = constants:: PUBLIC_KEY_SIZE as usize ;
260262 let err = ffi:: secp256k1_ec_pubkey_serialize (
261263 ffi:: secp256k1_context_no_precomp,
262- ret. as_mut_ptr ( ) ,
264+ ret. as_mut_c_ptr ( ) ,
263265 & mut ret_len,
264- self . as_ptr ( ) ,
266+ self . as_c_ptr ( ) ,
265267 ffi:: SECP256K1_SER_COMPRESSED ,
266268 ) ;
267269 debug_assert_eq ! ( err, 1 ) ;
@@ -278,9 +280,9 @@ impl PublicKey {
278280 let mut ret_len = constants:: UNCOMPRESSED_PUBLIC_KEY_SIZE as usize ;
279281 let err = ffi:: secp256k1_ec_pubkey_serialize (
280282 ffi:: secp256k1_context_no_precomp,
281- ret. as_mut_ptr ( ) ,
283+ ret. as_mut_c_ptr ( ) ,
282284 & mut ret_len,
283- self . as_ptr ( ) ,
285+ self . as_c_ptr ( ) ,
284286 ffi:: SECP256K1_SER_UNCOMPRESSED ,
285287 ) ;
286288 debug_assert_eq ! ( err, 1 ) ;
@@ -303,7 +305,7 @@ impl PublicKey {
303305 }
304306 unsafe {
305307 if ffi:: secp256k1_ec_pubkey_tweak_add ( secp. ctx , & mut self . 0 as * mut _ ,
306- other. as_ptr ( ) ) == 1 {
308+ other. as_c_ptr ( ) ) == 1 {
307309 Ok ( ( ) )
308310 } else {
309311 Err ( Error :: InvalidTweak )
@@ -325,7 +327,7 @@ impl PublicKey {
325327 }
326328 unsafe {
327329 if ffi:: secp256k1_ec_pubkey_tweak_mul ( secp. ctx , & mut self . 0 as * mut _ ,
328- other. as_ptr ( ) ) == 1 {
330+ other. as_c_ptr ( ) ) == 1 {
329331 Ok ( ( ) )
330332 } else {
331333 Err ( Error :: InvalidTweak )
@@ -339,11 +341,11 @@ impl PublicKey {
339341 pub fn combine ( & self , other : & PublicKey ) -> Result < PublicKey , Error > {
340342 unsafe {
341343 let mut ret = ffi:: PublicKey :: new ( ) ;
342- let ptrs = [ self . as_ptr ( ) , other. as_ptr ( ) ] ;
344+ let ptrs = [ self . as_c_ptr ( ) , other. as_c_ptr ( ) ] ;
343345 if ffi:: secp256k1_ec_pubkey_combine (
344346 ffi:: secp256k1_context_no_precomp,
345347 & mut ret,
346- ptrs. as_ptr ( ) ,
348+ ptrs. as_c_ptr ( ) ,
347349 2
348350 ) == 1
349351 {
@@ -355,6 +357,18 @@ impl PublicKey {
355357 }
356358}
357359
360+ impl CPtr for PublicKey {
361+ type Target = ffi:: PublicKey ;
362+ fn as_c_ptr ( & self ) -> * const Self :: Target {
363+ self . as_ptr ( )
364+ }
365+
366+ fn as_mut_c_ptr ( & mut self ) -> * mut Self :: Target {
367+ self . as_mut_ptr ( )
368+ }
369+ }
370+
371+
358372/// Creates a new public key from a FFI public key
359373impl From < ffi:: PublicKey > for PublicKey {
360374 #[ inline]
@@ -562,6 +576,36 @@ mod test {
562576 PublicKey :: from_slice( & [ 0x55 ; constants:: PUBLIC_KEY_SIZE ] ) ,
563577 Err ( InvalidPublicKey )
564578 ) ;
579+ assert_eq ! (
580+ PublicKey :: from_slice( & [ ] ) ,
581+ Err ( InvalidPublicKey )
582+ ) ;
583+ }
584+
585+ #[ test]
586+ fn test_seckey_from_bad_slice ( ) {
587+ // Bad sizes
588+ assert_eq ! (
589+ SecretKey :: from_slice( & [ 0 ; constants:: SECRET_KEY_SIZE - 1 ] ) ,
590+ Err ( InvalidSecretKey )
591+ ) ;
592+ assert_eq ! (
593+ SecretKey :: from_slice( & [ 0 ; constants:: SECRET_KEY_SIZE + 1 ] ) ,
594+ Err ( InvalidSecretKey )
595+ ) ;
596+ // Bad parse
597+ assert_eq ! (
598+ SecretKey :: from_slice( & [ 0xff ; constants:: SECRET_KEY_SIZE ] ) ,
599+ Err ( InvalidSecretKey )
600+ ) ;
601+ assert_eq ! (
602+ SecretKey :: from_slice( & [ 0x00 ; constants:: SECRET_KEY_SIZE ] ) ,
603+ Err ( InvalidSecretKey )
604+ ) ;
605+ assert_eq ! (
606+ SecretKey :: from_slice( & [ ] ) ,
607+ Err ( InvalidSecretKey )
608+ ) ;
565609 }
566610
567611 #[ test]
0 commit comments