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