@@ -7,7 +7,6 @@ use rand::thread_rng;
7
7
#[ cfg( any( test, feature = "rand" ) ) ]
8
8
use rand:: { CryptoRng , Rng } ;
9
9
10
- use super :: Error :: { InvalidPublicKey , InvalidSecretKey , InvalidSignature } ;
11
10
use super :: { from_hex, Error } ;
12
11
use core:: { fmt, ptr, str} ;
13
12
use ffi:: { self , CPtr } ;
@@ -108,7 +107,7 @@ impl str::FromStr for PublicKey {
108
107
Ok ( constants:: SCHNORRSIG_PUBLIC_KEY_SIZE ) => {
109
108
PublicKey :: from_slice ( & res[ 0 ..constants:: SCHNORRSIG_PUBLIC_KEY_SIZE ] )
110
109
}
111
- _ => Err ( InvalidPublicKey ) ,
110
+ _ => Err ( Error :: InvalidPublicKey ) ,
112
111
}
113
112
}
114
113
}
@@ -123,7 +122,7 @@ impl Signature {
123
122
ret[ ..] . copy_from_slice ( data) ;
124
123
Ok ( Signature ( ret) )
125
124
}
126
- _ => Err ( InvalidSignature ) ,
125
+ _ => Err ( Error :: InvalidSignature ) ,
127
126
}
128
127
}
129
128
}
@@ -143,9 +142,11 @@ impl KeyPair {
143
142
144
143
/// Creates a Schnorr KeyPair directly from generic Secp256k1 secret key
145
144
///
146
- /// Panics if internal representation of the provided [`SecretKey`] does not
147
- /// holds correct secret key value obtained from Secp256k1 library
148
- /// previously
145
+ /// # Panic
146
+ ///
147
+ /// Panics if internal representation of the provided [`SecretKey`] does not hold correct secret
148
+ /// key value obtained from Secp256k1 library previously, specifically when secret key value is
149
+ /// out-of-range (0 or in excess of the group order).
149
150
#[ inline]
150
151
pub fn from_secret_key < C : Signing > (
151
152
secp : & Secp256k1 < C > ,
@@ -161,35 +162,44 @@ impl KeyPair {
161
162
}
162
163
}
163
164
164
- /// Creates a Schnorr KeyPair directly from a secret key slice
165
+ /// Creates a Schnorr KeyPair directly from a secret key slice.
166
+ ///
167
+ /// # Errors
168
+ ///
169
+ /// [`Error::InvalidSecretKey`] if the provided data has an incorrect length, exceeds Secp256k1
170
+ /// field `p` value or the corresponding public key is not even.
165
171
#[ inline]
166
172
pub fn from_seckey_slice < C : Signing > (
167
173
secp : & Secp256k1 < C > ,
168
174
data : & [ u8 ] ,
169
175
) -> Result < KeyPair , Error > {
170
176
if data. is_empty ( ) || data. len ( ) != constants:: SECRET_KEY_SIZE {
171
- return Err ( InvalidSecretKey ) ;
177
+ return Err ( Error :: InvalidSecretKey ) ;
172
178
}
173
179
174
180
unsafe {
175
181
let mut kp = ffi:: KeyPair :: new ( ) ;
176
182
if ffi:: secp256k1_keypair_create ( secp. ctx , & mut kp, data. as_c_ptr ( ) ) == 1 {
177
183
Ok ( KeyPair ( kp) )
178
184
} else {
179
- Err ( InvalidSecretKey )
185
+ Err ( Error :: InvalidSecretKey )
180
186
}
181
187
}
182
188
}
183
189
184
190
/// Creates a Schnorr KeyPair directly from a secret key string
191
+ ///
192
+ /// # Errors
193
+ ///
194
+ /// [`Error::InvalidSecretKey`] if corresponding public key for the provided secret key is not even.
185
195
#[ inline]
186
196
pub fn from_seckey_str < C : Signing > ( secp : & Secp256k1 < C > , s : & str ) -> Result < KeyPair , Error > {
187
197
let mut res = [ 0u8 ; constants:: SECRET_KEY_SIZE ] ;
188
198
match from_hex ( s, & mut res) {
189
199
Ok ( constants:: SECRET_KEY_SIZE ) => {
190
200
KeyPair :: from_seckey_slice ( secp, & res[ 0 ..constants:: SECRET_KEY_SIZE ] )
191
201
}
192
- _ => Err ( InvalidPublicKey ) ,
202
+ _ => Err ( Error :: InvalidPublicKey ) ,
193
203
}
194
204
}
195
205
@@ -218,10 +228,15 @@ impl KeyPair {
218
228
* SecretKey :: from_keypair ( self ) . as_ref ( )
219
229
}
220
230
221
- /// Tweak a keypair by adding the given tweak to the secret key and updating the
222
- /// public key accordingly.
223
- /// Will return an error if the resulting key would be invalid or if
224
- /// the tweak was not a 32-byte length slice.
231
+ /// Tweak a keypair by adding the given tweak to the secret key and updating the public key
232
+ /// accordingly.
233
+ ///
234
+ /// Will return an error if the resulting key would be invalid or if the tweak was not a 32-byte
235
+ /// length slice.
236
+ ///
237
+ /// NB: Will not error if the tweaked public key has an odd value and can't be used for
238
+ /// BIP 340-342 purposes.
239
+ // TODO: Add checked implementation
225
240
#[ inline]
226
241
pub fn tweak_add_assign < C : Verification > (
227
242
& mut self ,
@@ -261,7 +276,7 @@ impl PublicKey {
261
276
& mut self . 0
262
277
}
263
278
264
- /// Creates a new Schnorr public key from a Schnorr key pair
279
+ /// Creates a new Schnorr public key from a Schnorr key pair.
265
280
#[ inline]
266
281
pub fn from_keypair < C : Signing > ( secp : & Secp256k1 < C > , keypair : & KeyPair ) -> PublicKey {
267
282
let mut pk_parity = 0 ;
@@ -279,10 +294,15 @@ impl PublicKey {
279
294
}
280
295
281
296
/// Creates a Schnorr public key directly from a slice
297
+ ///
298
+ /// # Errors
299
+ ///
300
+ /// Returns [`Error::InvalidPublicKey`] if the length of the data slice is not 32 bytes or the
301
+ /// slice does not represent a valid Secp256k1 point x coordinate
282
302
#[ inline]
283
303
pub fn from_slice ( data : & [ u8 ] ) -> Result < PublicKey , Error > {
284
304
if data. is_empty ( ) || data. len ( ) != constants:: SCHNORRSIG_PUBLIC_KEY_SIZE {
285
- return Err ( InvalidPublicKey ) ;
305
+ return Err ( Error :: InvalidPublicKey ) ;
286
306
}
287
307
288
308
unsafe {
@@ -295,15 +315,13 @@ impl PublicKey {
295
315
{
296
316
Ok ( PublicKey ( pk) )
297
317
} else {
298
- Err ( InvalidPublicKey )
318
+ Err ( Error :: InvalidPublicKey )
299
319
}
300
320
}
301
321
}
302
322
303
323
#[ inline]
304
- /// Serialize the key as a byte-encoded pair of values. In compressed form
305
- /// the y-coordinate is represented by only a single bit, as x determines
306
- /// it up to one bit.
324
+ /// Serialize the key as a byte-encoded x coordinate value (32 bytes).
307
325
pub fn serialize ( & self ) -> [ u8 ; constants:: SCHNORRSIG_PUBLIC_KEY_SIZE ] {
308
326
let mut ret = [ 0u8 ; constants:: SCHNORRSIG_PUBLIC_KEY_SIZE ] ;
309
327
0 commit comments