secp256k1/
key.rs

1// Bitcoin secp256k1 bindings
2// Written in 2014 by
3//   Dawid Ciężarkiewicz
4//   Andrew Poelstra
5//
6// To the extent possible under law, the author(s) have dedicated all
7// copyright and related and neighboring rights to this software to
8// the public domain worldwide. This software is distributed without
9// any warranty.
10//
11// You should have received a copy of the CC0 Public Domain Dedication
12// along with this software.
13// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
14//
15
16//! # Public and secret keys
17
18use std::intrinsics::copy_nonoverlapping;
19use arrayvec::ArrayVec;
20use rand::Rng;
21
22use super::{Secp256k1, ContextFlag};
23use super::Error::{self, IncapableContext, InvalidPublicKey, InvalidSecretKey};
24use constants;
25use ffi;
26
27/// Secret 256-bit key used as `x` in an ECDSA signature
28#[repr(C)]
29pub struct SecretKey([u8; constants::SECRET_KEY_SIZE]);
30impl_array_newtype!(SecretKey, u8, constants::SECRET_KEY_SIZE);
31impl_pretty_debug!(SecretKey);
32
33impl From<[u8; constants::SECRET_KEY_SIZE]> for SecretKey {
34	fn from(raw: [u8; constants::SECRET_KEY_SIZE]) -> Self {
35		SecretKey(raw)
36	}
37}
38
39/// The number 1 encoded as a secret key
40/// Deprecated; `static` is not what I want; use `ONE_KEY` instead
41pub static ONE: SecretKey = SecretKey([0, 0, 0, 0, 0, 0, 0, 0,
42                                       0, 0, 0, 0, 0, 0, 0, 0,
43                                       0, 0, 0, 0, 0, 0, 0, 0,
44                                       0, 0, 0, 0, 0, 0, 0, 1]);
45
46/// The number 0 encoded as a secret key
47pub const ZERO_KEY: SecretKey = SecretKey([0, 0, 0, 0, 0, 0, 0, 0,
48                                           0, 0, 0, 0, 0, 0, 0, 0,
49                                           0, 0, 0, 0, 0, 0, 0, 0,
50                                           0, 0, 0, 0, 0, 0, 0, 0]);
51
52/// The number 1 encoded as a secret key
53pub const ONE_KEY: SecretKey = SecretKey([0, 0, 0, 0, 0, 0, 0, 0,
54                                          0, 0, 0, 0, 0, 0, 0, 0,
55                                          0, 0, 0, 0, 0, 0, 0, 0,
56                                          0, 0, 0, 0, 0, 0, 0, 1]);
57
58/// The number -1 encoded as a secret key
59pub const MINUS_ONE_KEY: SecretKey = SecretKey([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
60                                                0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
61                                                0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b,
62                                                0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x40]);
63
64/// A Secp256k1 public key, used for verification of signatures
65#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
66pub struct PublicKey(ffi::PublicKey);
67
68fn random_32_bytes<R: Rng>(rng: &mut R) -> [u8; 32] {
69    let mut ret = [0u8; 32];
70    rng.fill_bytes(&mut ret);
71    ret
72}
73
74impl SecretKey {
75    /// Creates a new random secret key
76    #[inline]
77    pub fn new<R: Rng>(secp: &Secp256k1, rng: &mut R) -> SecretKey {
78        let mut data = random_32_bytes(rng);
79        unsafe {
80            while ffi::secp256k1_ec_seckey_verify(secp.ctx, data.as_ptr()) == 0 {
81                data = random_32_bytes(rng);
82            }
83        }
84        SecretKey(data)
85    }
86
87    /// Converts a `SECRET_KEY_SIZE`-byte slice to a secret key
88    #[inline]
89    pub fn from_slice(secp: &Secp256k1, data: &[u8])
90                        -> Result<SecretKey, Error> {
91        match data.len() {
92            constants::SECRET_KEY_SIZE => {
93                let mut ret = [0; constants::SECRET_KEY_SIZE];
94                unsafe {
95                    if ffi::secp256k1_ec_seckey_verify(secp.ctx, data.as_ptr()) == 0 {
96                        return Err(InvalidSecretKey);
97                    }
98                    copy_nonoverlapping(data.as_ptr(),
99                                        ret.as_mut_ptr(),
100                                        data.len());
101                }
102                Ok(SecretKey(ret))
103            }
104            _ => Err(InvalidSecretKey)
105        }
106    }
107
108    #[inline]
109    /// Adds one secret key to another, modulo the curve order
110    pub fn add_assign(&mut self, secp: &Secp256k1, other: &SecretKey)
111                     -> Result<(), Error> {
112        unsafe {
113            if ffi::secp256k1_ec_privkey_tweak_add(secp.ctx, self.as_mut_ptr(), other.as_ptr()) != 1 {
114                Err(InvalidSecretKey)
115            } else {
116                Ok(())
117            }
118        }
119    }
120
121    #[inline]
122    /// Multiplies one secret key to another, modulo the curve order
123    pub fn mul_assign(&mut self, secp: &Secp256k1, other: &SecretKey)
124                     -> Result<(), Error> {
125        unsafe {
126            if ffi::secp256k1_ec_privkey_tweak_mul(secp.ctx, self.as_mut_ptr(), other.as_ptr()) != 1 {
127                Err(InvalidSecretKey)
128            } else {
129                Ok(())
130            }
131        }
132    }
133
134    #[inline]
135    /// Inverts (1 / self) this secret key.
136    pub fn inv_assign(&mut self, secp: &Secp256k1) -> Result<(), Error> {
137        let original = self.clone();
138        unsafe {
139            if ffi::secp256k1_ec_privkey_inverse(secp.ctx, self.as_mut_ptr(), original.as_ptr()) != 1 {
140                Err(InvalidSecretKey)
141            } else {
142                Ok(())
143            }
144        }
145    }
146}
147
148impl PublicKey {
149    /// Creates a new zeroed out public key
150    #[inline]
151    pub fn new() -> PublicKey {
152        PublicKey(ffi::PublicKey::new())
153    }
154
155    /// Determines whether a pubkey is valid
156    #[inline]
157    pub fn is_valid(&self) -> bool {
158        // The only invalid pubkey the API should be able to create is
159        // the zero one.
160        self.0[..].iter().any(|&x| x != 0)
161    }
162
163    /// Obtains a raw pointer suitable for use with FFI functions
164    #[inline]
165    pub fn as_ptr(&self) -> *const ffi::PublicKey {
166        &self.0 as *const _
167    }
168
169    /// Creates a new public key from a secret key.
170    #[inline]
171    pub fn from_secret_key(secp: &Secp256k1,
172                           sk: &SecretKey)
173                           -> Result<PublicKey, Error> {
174        if secp.caps == ContextFlag::VerifyOnly || secp.caps == ContextFlag::None {
175            return Err(IncapableContext);
176        }
177        let mut pk = unsafe { ffi::PublicKey::blank() };
178        unsafe {
179            // We can assume the return value because it's not possible to construct
180            // an invalid `SecretKey` without transmute trickery or something
181            let res = ffi::secp256k1_ec_pubkey_create(secp.ctx, &mut pk, sk.as_ptr());
182            debug_assert_eq!(res, 1);
183        }
184        Ok(PublicKey(pk))
185    }
186
187    /// Creates a public key directly from a slice
188    #[inline]
189    pub fn from_slice(secp: &Secp256k1, data: &[u8])
190                      -> Result<PublicKey, Error> {
191
192        let mut pk = unsafe { ffi::PublicKey::blank() };
193        unsafe {
194            if ffi::secp256k1_ec_pubkey_parse(secp.ctx, &mut pk, data.as_ptr(),
195                                              data.len() as ::libc::size_t) == 1 {
196                Ok(PublicKey(pk))
197            } else {
198                Err(InvalidPublicKey)
199            }
200        }
201    }
202
203    #[inline]
204    /// Serialize the key as a byte-encoded pair of values. In compressed form
205    /// the y-coordinate is represented by only a single bit, as x determines
206    /// it up to one bit.
207    pub fn serialize_vec(&self, secp: &Secp256k1, compressed: bool) -> ArrayVec<[u8; constants::PUBLIC_KEY_SIZE]> {
208        let mut ret = ArrayVec::new();
209
210        unsafe {
211            let mut ret_len = constants::PUBLIC_KEY_SIZE as ::libc::size_t;
212            let compressed = if compressed { ffi::SECP256K1_SER_COMPRESSED } else { ffi::SECP256K1_SER_UNCOMPRESSED };
213            let err = ffi::secp256k1_ec_pubkey_serialize(secp.ctx, ret.as_ptr(),
214                                                         &mut ret_len, self.as_ptr(),
215                                                         compressed);
216            debug_assert_eq!(err, 1);
217            ret.set_len(ret_len as usize);
218        }
219        ret
220    }
221
222    #[inline]
223    /// Adds the pk corresponding to `other` to the pk `self` in place
224    pub fn add_exp_assign(&mut self, secp: &Secp256k1, other: &SecretKey)
225                         -> Result<(), Error> {
226        if secp.caps == ContextFlag::SignOnly || secp.caps == ContextFlag::None {
227            return Err(IncapableContext);
228        }
229        unsafe {
230            if ffi::secp256k1_ec_pubkey_tweak_add(secp.ctx, &mut self.0 as *mut _,
231                                                  other.as_ptr()) == 1 {
232                Ok(())
233            } else {
234                Err(InvalidSecretKey)
235            }
236        }
237    }
238
239    #[inline]
240    /// Adds another point on the curve in place
241    pub fn add_assign(&mut self, secp: &Secp256k1, other: &PublicKey) -> Result<(), Error> {
242        let mut public = ffi::PublicKey::new();
243        let res = unsafe {
244            if ffi::secp256k1_ec_pubkey_combine(
245                secp.ctx,
246                &mut public as *mut _,
247                [other.as_ptr(), self.as_ptr()].as_ptr(),
248                2) == 1
249            {
250                Ok(())
251            } else {
252                Err(InvalidSecretKey)
253            }
254        };
255        if res.is_ok() { self.0 = public }
256        res
257    }
258
259    #[inline]
260    /// Multiplies this point by `secret` scalar
261    pub fn mul_assign(&mut self, secp: &Secp256k1, other: &SecretKey) -> Result<(), Error> {
262        if secp.caps == ContextFlag::SignOnly || secp.caps == ContextFlag::None {
263            return Err(IncapableContext);
264        }
265        unsafe {
266            if ffi::secp256k1_ec_pubkey_tweak_mul(secp.ctx, &mut self.0 as *mut _,
267                                                  other.as_ptr()) == 1 {
268                Ok(())
269            } else {
270                Err(InvalidSecretKey)
271            }
272        }
273    }
274}
275
276/// Creates a new public key from a FFI public key
277impl From<ffi::PublicKey> for PublicKey {
278    #[inline]
279    fn from(pk: ffi::PublicKey) -> PublicKey {
280        PublicKey(pk)
281    }
282}
283
284#[cfg(test)]
285mod test {
286    use super::super::{Secp256k1, ContextFlag};
287    use super::super::Error::{InvalidPublicKey, InvalidSecretKey, IncapableContext};
288    use super::{PublicKey, SecretKey};
289    use super::super::constants;
290
291    use rand::{Rng, thread_rng};
292
293    #[test]
294    fn skey_from_slice() {
295        let s = Secp256k1::new();
296        let sk = SecretKey::from_slice(&s, &[1; 31]);
297        assert_eq!(sk, Err(InvalidSecretKey));
298
299        let sk = SecretKey::from_slice(&s, &[1; 32]);
300        assert!(sk.is_ok());
301    }
302
303    #[test]
304    fn pubkey_from_slice() {
305        let s = Secp256k1::new();
306        assert_eq!(PublicKey::from_slice(&s, &[]), Err(InvalidPublicKey));
307        assert_eq!(PublicKey::from_slice(&s, &[1, 2, 3]), Err(InvalidPublicKey));
308
309        let uncompressed = PublicKey::from_slice(&s, &[4, 54, 57, 149, 239, 162, 148, 175, 246, 254, 239, 75, 154, 152, 10, 82, 234, 224, 85, 220, 40, 100, 57, 121, 30, 162, 94, 156, 135, 67, 74, 49, 179, 57, 236, 53, 162, 124, 149, 144, 168, 77, 74, 30, 72, 211, 229, 110, 111, 55, 96, 193, 86, 227, 183, 152, 195, 155, 51, 247, 123, 113, 60, 228, 188]);
310        assert!(uncompressed.is_ok());
311
312        let compressed = PublicKey::from_slice(&s, &[3, 23, 183, 225, 206, 31, 159, 148, 195, 42, 67, 115, 146, 41, 248, 140, 11, 3, 51, 41, 111, 180, 110, 143, 114, 134, 88, 73, 198, 174, 52, 184, 78]);
313        assert!(compressed.is_ok());
314    }
315
316    #[test]
317    fn keypair_slice_round_trip() {
318        let s = Secp256k1::new();
319
320        let (sk1, pk1) = s.generate_keypair(&mut thread_rng()).unwrap();
321        assert_eq!(SecretKey::from_slice(&s, &sk1[..]), Ok(sk1));
322        assert_eq!(PublicKey::from_slice(&s, &pk1.serialize_vec(&s, true)[..]), Ok(pk1));
323        assert_eq!(PublicKey::from_slice(&s, &pk1.serialize_vec(&s, false)[..]), Ok(pk1));
324    }
325
326    #[test]
327    fn invalid_secret_key() {
328        let s = Secp256k1::new();
329        // Zero
330        assert_eq!(SecretKey::from_slice(&s, &[0; 32]), Err(InvalidSecretKey));
331        // -1
332        assert_eq!(SecretKey::from_slice(&s, &[0xff; 32]), Err(InvalidSecretKey));
333        // Top of range
334        assert!(SecretKey::from_slice(&s,
335                                      &[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
336                                        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
337                                        0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B,
338                                        0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x40]).is_ok());
339        // One past top of range
340        assert!(SecretKey::from_slice(&s,
341                                      &[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
342                                        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
343                                        0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B,
344                                        0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41]).is_err());
345    }
346
347    #[test]
348    fn test_pubkey_from_slice_bad_context() {
349        let s = Secp256k1::without_caps();
350        let sk = SecretKey::new(&s, &mut thread_rng());
351        assert_eq!(PublicKey::from_secret_key(&s, &sk), Err(IncapableContext));
352
353        let s = Secp256k1::with_caps(ContextFlag::VerifyOnly);
354        assert_eq!(PublicKey::from_secret_key(&s, &sk), Err(IncapableContext));
355
356        let s = Secp256k1::with_caps(ContextFlag::SignOnly);
357        assert!(PublicKey::from_secret_key(&s, &sk).is_ok());
358
359        let s = Secp256k1::with_caps(ContextFlag::Full);
360        assert!(PublicKey::from_secret_key(&s, &sk).is_ok());
361    }
362
363    #[test]
364    fn test_add_exp_bad_context() {
365        let s = Secp256k1::with_caps(ContextFlag::Full);
366        let (sk, mut pk) = s.generate_keypair(&mut thread_rng()).unwrap();
367
368        assert!(pk.add_exp_assign(&s, &sk).is_ok());
369
370        let s = Secp256k1::with_caps(ContextFlag::VerifyOnly);
371        assert!(pk.add_exp_assign(&s, &sk).is_ok());
372
373        let s = Secp256k1::with_caps(ContextFlag::SignOnly);
374        assert_eq!(pk.add_exp_assign(&s, &sk), Err(IncapableContext));
375
376        let s = Secp256k1::with_caps(ContextFlag::None);
377        assert_eq!(pk.add_exp_assign(&s, &sk), Err(IncapableContext));
378    }
379
380    #[test]
381    fn test_out_of_range() {
382
383        struct BadRng(u8);
384        impl Rng for BadRng {
385            fn next_u32(&mut self) -> u32 { unimplemented!() }
386            // This will set a secret key to a little over the
387            // group order, then decrement with repeated calls
388            // until it returns a valid key
389            fn fill_bytes(&mut self, data: &mut [u8]) {
390                let group_order: [u8; 32] = [
391                    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
392                    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
393                    0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b,
394                    0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x41];
395                assert_eq!(data.len(), 32);
396                unsafe {
397                    use std::intrinsics::copy_nonoverlapping;
398                    copy_nonoverlapping(group_order.as_ptr(),
399                                        data.as_mut_ptr(),
400                                        32);
401                }
402                data[31] = self.0;
403                self.0 -= 1;
404            }
405        }
406
407        let s = Secp256k1::new();
408        s.generate_keypair(&mut BadRng(0xff)).unwrap();
409    }
410
411    #[test]
412    fn test_pubkey_from_bad_slice() {
413        let s = Secp256k1::new();
414        // Bad sizes
415        assert_eq!(PublicKey::from_slice(&s, &[0; constants::COMPRESSED_PUBLIC_KEY_SIZE - 1]),
416                   Err(InvalidPublicKey));
417        assert_eq!(PublicKey::from_slice(&s, &[0; constants::COMPRESSED_PUBLIC_KEY_SIZE + 1]),
418                   Err(InvalidPublicKey));
419        assert_eq!(PublicKey::from_slice(&s, &[0; constants::UNCOMPRESSED_PUBLIC_KEY_SIZE - 1]),
420                   Err(InvalidPublicKey));
421        assert_eq!(PublicKey::from_slice(&s, &[0; constants::UNCOMPRESSED_PUBLIC_KEY_SIZE + 1]),
422                   Err(InvalidPublicKey));
423
424        // Bad parse
425        assert_eq!(PublicKey::from_slice(&s, &[0xff; constants::UNCOMPRESSED_PUBLIC_KEY_SIZE]),
426                   Err(InvalidPublicKey));
427        assert_eq!(PublicKey::from_slice(&s, &[0x55; constants::COMPRESSED_PUBLIC_KEY_SIZE]),
428                   Err(InvalidPublicKey));
429    }
430
431    #[test]
432    fn test_debug_output() {
433        struct DumbRng(u32);
434        impl Rng for DumbRng {
435            fn next_u32(&mut self) -> u32 {
436                self.0 = self.0.wrapping_add(1);
437                self.0
438            }
439        }
440
441        let s = Secp256k1::new();
442        let (sk, _) = s.generate_keypair(&mut DumbRng(0)).unwrap();
443
444        assert_eq!(&format!("{:?}", sk),
445                   "SecretKey(0200000001000000040000000300000006000000050000000800000007000000)");
446    }
447
448    #[test]
449    fn test_pubkey_serialize() {
450        struct DumbRng(u32);
451        impl Rng for DumbRng {
452            fn next_u32(&mut self) -> u32 {
453                self.0 = self.0.wrapping_add(1);
454                self.0
455            }
456        }
457
458        let s = Secp256k1::new();
459        let (_, pk1) = s.generate_keypair(&mut DumbRng(0)).unwrap();
460        assert_eq!(&pk1.serialize_vec(&s, false)[..],
461                   &[4, 149, 16, 196, 140, 38, 92, 239, 179, 65, 59, 224, 230, 183, 91, 238, 240, 46, 186, 252, 175, 102, 52, 249, 98, 178, 123, 72, 50, 171, 196, 254, 236, 1, 189, 143, 242, 227, 16, 87, 247, 183, 162, 68, 237, 140, 92, 205, 151, 129, 166, 58, 111, 96, 123, 64, 180, 147, 51, 12, 209, 89, 236, 213, 206][..]);
462        assert_eq!(&pk1.serialize_vec(&s, true)[..],
463                   &[2, 149, 16, 196, 140, 38, 92, 239, 179, 65, 59, 224, 230, 183, 91, 238, 240, 46, 186, 252, 175, 102, 52, 249, 98, 178, 123, 72, 50, 171, 196, 254, 236][..]);
464    }
465
466    #[test]
467    fn test_addition() {
468        let s = Secp256k1::new();
469
470        let (mut sk1, mut pk1) = s.generate_keypair(&mut thread_rng()).unwrap();
471        let (mut sk2, mut pk2) = s.generate_keypair(&mut thread_rng()).unwrap();
472
473        assert_eq!(PublicKey::from_secret_key(&s, &sk1).unwrap(), pk1);
474        assert!(sk1.add_assign(&s, &sk2).is_ok());
475        assert!(pk1.add_exp_assign(&s, &sk2).is_ok());
476        assert_eq!(PublicKey::from_secret_key(&s, &sk1).unwrap(), pk1);
477
478        assert_eq!(PublicKey::from_secret_key(&s, &sk2).unwrap(), pk2);
479        assert!(sk2.add_assign(&s, &sk1).is_ok());
480        assert!(pk2.add_exp_assign(&s, &sk1).is_ok());
481        assert_eq!(PublicKey::from_secret_key(&s, &sk2).unwrap(), pk2);
482    }
483
484    #[test]
485    fn pubkey_hash() {
486        use std::hash::{Hash, SipHasher, Hasher};
487        use std::collections::HashSet;
488
489        fn hash<T: Hash>(t: &T) -> u64 {
490            let mut s = SipHasher::new();
491            t.hash(&mut s);
492            s.finish()
493        }
494
495        let s = Secp256k1::new();
496        let mut set = HashSet::new();
497        const COUNT : usize = 1024;
498        let count = (0..COUNT).map(|_| {
499            let (_, pk) = s.generate_keypair(&mut thread_rng()).unwrap();
500            let hash = hash(&pk);
501            assert!(!set.contains(&hash));
502            set.insert(hash);
503        }).count();
504        assert_eq!(count, COUNT);
505    }
506
507    #[test]
508    fn pubkey_add() {
509        let s = Secp256k1::new();
510        let (_, mut pk1) = s.generate_keypair(&mut thread_rng()).unwrap();
511        let (_, pk2) = s.generate_keypair(&mut thread_rng()).unwrap();
512
513        let result = pk1.add_assign(&s, &pk2);
514
515        assert!(result.is_ok());
516    }
517
518    #[test]
519    fn pubkey_mul() {
520        let s = Secp256k1::new();
521        let (_, mut pk1) = s.generate_keypair(&mut thread_rng()).unwrap();
522        let (sk2, _) = s.generate_keypair(&mut thread_rng()).unwrap();
523
524        let result = pk1.mul_assign(&s, &sk2);
525
526        assert!(result.is_ok());
527    }
528
529    #[test]
530    fn skey_mul() {
531        let s = Secp256k1::new();
532        let (mut sk1, _) = s.generate_keypair(&mut thread_rng()).unwrap();
533        let (sk2, _) = s.generate_keypair(&mut thread_rng()).unwrap();
534
535        let result = sk1.mul_assign(&s, &sk2);
536
537        assert!(result.is_ok());
538    }
539
540    #[test]
541    fn skey_inv() {
542        let s = Secp256k1::new();
543        let (mut sk, _) = s.generate_keypair(&mut thread_rng()).unwrap();
544
545        let result = sk.inv_assign(&s);
546
547        assert!(result.is_ok());
548    }
549}
550
551