libsecp256k1/
lib.rs

1//! Pure Rust implementation of the secp256k1 curve and fast ECDSA
2//! signatures. The secp256k1 curve is used extensively in Bitcoin and
3//! Ethereum-alike cryptocurrencies.
4
5#![deny(
6    unused_import_braces,
7    unused_imports,
8    unused_comparisons,
9    unused_must_use,
10    unused_variables,
11    non_shorthand_field_patterns,
12    unreachable_code,
13    unused_parens
14)]
15#![cfg_attr(not(feature = "std"), no_std)]
16
17pub use libsecp256k1_core::*;
18
19use arrayref::{array_mut_ref, array_ref};
20use core::convert::TryFrom;
21use digest::{generic_array::GenericArray, Digest};
22use rand::Rng;
23
24#[cfg(feature = "std")]
25use core::fmt;
26#[cfg(feature = "hmac")]
27use hmac_drbg::HmacDRBG;
28#[cfg(feature = "std")]
29use serde::{de, ser::Serializer, Deserialize, Serialize};
30#[cfg(feature = "hmac")]
31use sha2::Sha256;
32#[cfg(feature = "hmac")]
33use typenum::U32;
34
35use crate::{
36    curve::{Affine, ECMultContext, ECMultGenContext, Field, Jacobian, Scalar},
37    util::{Decoder, SignatureArray},
38};
39
40#[cfg(feature = "lazy-static-context")]
41lazy_static::lazy_static! {
42    /// A static ECMult context.
43    pub static ref ECMULT_CONTEXT: Box<ECMultContext> = ECMultContext::new_boxed();
44
45    /// A static ECMultGen context.
46    pub static ref ECMULT_GEN_CONTEXT: Box<ECMultGenContext> = ECMultGenContext::new_boxed();
47}
48
49#[cfg(all(feature = "static-context", not(feature = "lazy-static-context")))]
50/// A static ECMult context.
51// Correct `pre_g` values are fed into `ECMultContext::new_from_raw`, generated by build script.
52pub static ECMULT_CONTEXT: ECMultContext =
53    unsafe { ECMultContext::new_from_raw(include!(concat!(env!("OUT_DIR"), "/const.rs"))) };
54
55#[cfg(all(feature = "static-context", not(feature = "lazy-static-context")))]
56/// A static ECMultGen context.
57// Correct `prec` values are fed into `ECMultGenContext::new_from_raw`, generated by build script.
58pub static ECMULT_GEN_CONTEXT: ECMultGenContext =
59    unsafe { ECMultGenContext::new_from_raw(include!(concat!(env!("OUT_DIR"), "/const_gen.rs"))) };
60
61#[derive(Debug, Clone, Copy, Eq, PartialEq)]
62/// Public key on a secp256k1 curve.
63pub struct PublicKey(Affine);
64
65#[derive(Debug, Clone, Copy, Eq, PartialEq)]
66/// Secret key (256-bit) on a secp256k1 curve.
67pub struct SecretKey(Scalar);
68
69#[derive(Debug, Clone, Copy, Eq, PartialEq)]
70/// An ECDSA signature.
71pub struct Signature {
72    pub r: Scalar,
73    pub s: Scalar,
74}
75
76#[derive(Debug, Clone, Copy, Eq, PartialEq)]
77/// Tag used for public key recovery from signatures.
78pub struct RecoveryId(u8);
79
80#[derive(Debug, Clone, Copy, Eq, PartialEq)]
81/// Hashed message input to an ECDSA signature.
82pub struct Message(pub Scalar);
83
84#[derive(Debug, Clone, Eq, PartialEq)]
85/// Shared secret using ECDH.
86pub struct SharedSecret<D: Digest>(GenericArray<u8, D::OutputSize>);
87
88impl<D> Copy for SharedSecret<D>
89where
90    D: Copy + Digest,
91    GenericArray<u8, D::OutputSize>: Copy,
92{
93}
94
95/// Format for public key parsing.
96pub enum PublicKeyFormat {
97    /// Compressed public key, 33 bytes.
98    Compressed,
99    /// Full length public key, 65 bytes.
100    Full,
101    /// Raw public key, 64 bytes.
102    Raw,
103}
104
105impl PublicKey {
106    pub fn from_secret_key_with_context(
107        seckey: &SecretKey,
108        context: &ECMultGenContext,
109    ) -> PublicKey {
110        let mut pj = Jacobian::default();
111        context.ecmult_gen(&mut pj, &seckey.0);
112        let mut p = Affine::default();
113        p.set_gej(&pj);
114        PublicKey(p)
115    }
116
117    #[cfg(any(feature = "static-context", feature = "lazy-static-context"))]
118    pub fn from_secret_key(seckey: &SecretKey) -> PublicKey {
119        Self::from_secret_key_with_context(seckey, &ECMULT_GEN_CONTEXT)
120    }
121
122    pub fn parse_slice(p: &[u8], format: Option<PublicKeyFormat>) -> Result<PublicKey, Error> {
123        let format = match (p.len(), format) {
124            (util::FULL_PUBLIC_KEY_SIZE, None)
125            | (util::FULL_PUBLIC_KEY_SIZE, Some(PublicKeyFormat::Full)) => PublicKeyFormat::Full,
126            (util::COMPRESSED_PUBLIC_KEY_SIZE, None)
127            | (util::COMPRESSED_PUBLIC_KEY_SIZE, Some(PublicKeyFormat::Compressed)) => {
128                PublicKeyFormat::Compressed
129            }
130            (util::RAW_PUBLIC_KEY_SIZE, None)
131            | (util::RAW_PUBLIC_KEY_SIZE, Some(PublicKeyFormat::Raw)) => PublicKeyFormat::Raw,
132            _ => return Err(Error::InvalidInputLength),
133        };
134
135        match format {
136            PublicKeyFormat::Full => {
137                let mut a = [0; util::FULL_PUBLIC_KEY_SIZE];
138                a.copy_from_slice(p);
139                Self::parse(&a)
140            }
141            PublicKeyFormat::Raw => {
142                use util::TAG_PUBKEY_FULL;
143
144                let mut a = [0; util::FULL_PUBLIC_KEY_SIZE];
145                a[0] = TAG_PUBKEY_FULL;
146                a[1..].copy_from_slice(p);
147                Self::parse(&a)
148            }
149            PublicKeyFormat::Compressed => {
150                let mut a = [0; util::COMPRESSED_PUBLIC_KEY_SIZE];
151                a.copy_from_slice(p);
152                Self::parse_compressed(&a)
153            }
154        }
155    }
156
157    pub fn parse(p: &[u8; util::FULL_PUBLIC_KEY_SIZE]) -> Result<PublicKey, Error> {
158        use util::{TAG_PUBKEY_FULL, TAG_PUBKEY_HYBRID_EVEN, TAG_PUBKEY_HYBRID_ODD};
159
160        if !(p[0] == TAG_PUBKEY_FULL
161            || p[0] == TAG_PUBKEY_HYBRID_EVEN
162            || p[0] == TAG_PUBKEY_HYBRID_ODD)
163        {
164            return Err(Error::InvalidPublicKey);
165        }
166        let mut x = Field::default();
167        let mut y = Field::default();
168        if !x.set_b32(array_ref!(p, 1, 32)) {
169            return Err(Error::InvalidPublicKey);
170        }
171        if !y.set_b32(array_ref!(p, 33, 32)) {
172            return Err(Error::InvalidPublicKey);
173        }
174        let mut elem = Affine::default();
175        elem.set_xy(&x, &y);
176        if (p[0] == TAG_PUBKEY_HYBRID_EVEN || p[0] == TAG_PUBKEY_HYBRID_ODD)
177            && (y.is_odd() != (p[0] == TAG_PUBKEY_HYBRID_ODD))
178        {
179            return Err(Error::InvalidPublicKey);
180        }
181        if elem.is_infinity() {
182            return Err(Error::InvalidPublicKey);
183        }
184        if elem.is_valid_var() {
185            Ok(PublicKey(elem))
186        } else {
187            Err(Error::InvalidPublicKey)
188        }
189    }
190
191    pub fn parse_compressed(
192        p: &[u8; util::COMPRESSED_PUBLIC_KEY_SIZE],
193    ) -> Result<PublicKey, Error> {
194        use util::{TAG_PUBKEY_EVEN, TAG_PUBKEY_ODD};
195
196        if !(p[0] == TAG_PUBKEY_EVEN || p[0] == TAG_PUBKEY_ODD) {
197            return Err(Error::InvalidPublicKey);
198        }
199        let mut x = Field::default();
200        if !x.set_b32(array_ref!(p, 1, 32)) {
201            return Err(Error::InvalidPublicKey);
202        }
203        let mut elem = Affine::default();
204        elem.set_xo_var(&x, p[0] == TAG_PUBKEY_ODD);
205        if elem.is_infinity() {
206            return Err(Error::InvalidPublicKey);
207        }
208        if elem.is_valid_var() {
209            Ok(PublicKey(elem))
210        } else {
211            Err(Error::InvalidPublicKey)
212        }
213    }
214
215    pub fn serialize(&self) -> [u8; util::FULL_PUBLIC_KEY_SIZE] {
216        use util::TAG_PUBKEY_FULL;
217
218        debug_assert!(!self.0.is_infinity());
219
220        let mut ret = [0u8; 65];
221        let mut elem = self.0;
222
223        elem.x.normalize_var();
224        elem.y.normalize_var();
225        elem.x.fill_b32(array_mut_ref!(ret, 1, 32));
226        elem.y.fill_b32(array_mut_ref!(ret, 33, 32));
227        ret[0] = TAG_PUBKEY_FULL;
228
229        ret
230    }
231
232    pub fn serialize_compressed(&self) -> [u8; util::COMPRESSED_PUBLIC_KEY_SIZE] {
233        use util::{TAG_PUBKEY_EVEN, TAG_PUBKEY_ODD};
234
235        debug_assert!(!self.0.is_infinity());
236
237        let mut ret = [0u8; 33];
238        let mut elem = self.0;
239
240        elem.x.normalize_var();
241        elem.y.normalize_var();
242        elem.x.fill_b32(array_mut_ref!(ret, 1, 32));
243        ret[0] = if elem.y.is_odd() {
244            TAG_PUBKEY_ODD
245        } else {
246            TAG_PUBKEY_EVEN
247        };
248
249        ret
250    }
251
252    pub fn tweak_add_assign_with_context(
253        &mut self,
254        tweak: &SecretKey,
255        context: &ECMultContext,
256    ) -> Result<(), Error> {
257        let mut r = Jacobian::default();
258        let a = Jacobian::from_ge(&self.0);
259        let one = Scalar::from_int(1);
260        context.ecmult(&mut r, &a, &one, &tweak.0);
261
262        if r.is_infinity() {
263            return Err(Error::TweakOutOfRange);
264        }
265
266        self.0.set_gej(&r);
267        Ok(())
268    }
269
270    #[cfg(any(feature = "static-context", feature = "lazy-static-context"))]
271    pub fn tweak_add_assign(&mut self, tweak: &SecretKey) -> Result<(), Error> {
272        self.tweak_add_assign_with_context(tweak, &ECMULT_CONTEXT)
273    }
274
275    pub fn tweak_mul_assign_with_context(
276        &mut self,
277        tweak: &SecretKey,
278        context: &ECMultContext,
279    ) -> Result<(), Error> {
280        if tweak.0.is_zero() {
281            return Err(Error::TweakOutOfRange);
282        }
283
284        let mut r = Jacobian::default();
285        let zero = Scalar::from_int(0);
286        let pt = Jacobian::from_ge(&self.0);
287        context.ecmult(&mut r, &pt, &tweak.0, &zero);
288
289        self.0.set_gej(&r);
290        Ok(())
291    }
292
293    #[cfg(any(feature = "static-context", feature = "lazy-static-context"))]
294    pub fn tweak_mul_assign(&mut self, tweak: &SecretKey) -> Result<(), Error> {
295        self.tweak_mul_assign_with_context(tweak, &ECMULT_CONTEXT)
296    }
297
298    pub fn combine(keys: &[PublicKey]) -> Result<Self, Error> {
299        let mut qj = Jacobian::default();
300        qj.set_infinity();
301
302        for key in keys {
303            qj = qj.add_ge(&key.0);
304        }
305
306        if qj.is_infinity() {
307            return Err(Error::InvalidPublicKey);
308        }
309
310        let q = Affine::from_gej(&qj);
311        Ok(PublicKey(q))
312    }
313}
314
315impl Into<Affine> for PublicKey {
316    fn into(self) -> Affine {
317        self.0
318    }
319}
320
321impl TryFrom<Affine> for PublicKey {
322    type Error = Error;
323
324    fn try_from(value: Affine) -> Result<Self, Self::Error> {
325        if value.is_infinity() || !value.is_valid_var() {
326            Err(Error::InvalidAffine)
327        } else {
328            Ok(PublicKey(value))
329        }
330    }
331}
332
333#[cfg(feature = "std")]
334impl Serialize for PublicKey {
335    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
336    where
337        S: Serializer,
338    {
339        if serializer.is_human_readable() {
340            serializer.serialize_str(&base64::encode(&self.serialize()[..]))
341        } else {
342            serializer.serialize_bytes(&self.serialize())
343        }
344    }
345}
346
347#[cfg(feature = "std")]
348struct PublicKeyStrVisitor;
349
350#[cfg(feature = "std")]
351impl<'de> de::Visitor<'de> for PublicKeyStrVisitor {
352    type Value = PublicKey;
353
354    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
355        formatter
356            .write_str("a bytestring of either 33 (compressed), 64 (raw), or 65 bytes in length")
357    }
358
359    fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
360    where
361        E: de::Error,
362    {
363        let value: &[u8] = &base64::decode(value).map_err(|e| E::custom(e))?;
364        let key_format = match value.len() {
365            33 => PublicKeyFormat::Compressed,
366            64 => PublicKeyFormat::Raw,
367            65 => PublicKeyFormat::Full,
368            _ => return Err(E::custom(Error::InvalidInputLength)),
369        };
370        PublicKey::parse_slice(value, Some(key_format))
371            .map_err(|_e| E::custom(Error::InvalidPublicKey))
372    }
373}
374
375#[cfg(feature = "std")]
376struct PublicKeyBytesVisitor;
377
378#[cfg(feature = "std")]
379impl<'de> de::Visitor<'de> for PublicKeyBytesVisitor {
380    type Value = PublicKey;
381
382    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
383        formatter.write_str(
384            "a byte slice that is either 33 (compressed), 64 (raw), or 65 bytes in length",
385        )
386    }
387
388    fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
389    where
390        E: de::Error,
391    {
392        PublicKey::parse_slice(value, None).map_err(|_e| E::custom(Error::InvalidPublicKey))
393    }
394}
395
396#[cfg(feature = "std")]
397impl<'de> Deserialize<'de> for PublicKey {
398    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
399    where
400        D: de::Deserializer<'de>,
401    {
402        if deserializer.is_human_readable() {
403            deserializer.deserialize_str(PublicKeyStrVisitor)
404        } else {
405            deserializer.deserialize_bytes(PublicKeyBytesVisitor)
406        }
407    }
408}
409
410impl SecretKey {
411    pub fn parse(p: &[u8; util::SECRET_KEY_SIZE]) -> Result<SecretKey, Error> {
412        let mut elem = Scalar::default();
413        if !bool::from(elem.set_b32(p)) {
414            Self::try_from(elem)
415        } else {
416            Err(Error::InvalidSecretKey)
417        }
418    }
419
420    pub fn parse_slice(p: &[u8]) -> Result<SecretKey, Error> {
421        if p.len() != util::SECRET_KEY_SIZE {
422            return Err(Error::InvalidInputLength);
423        }
424
425        let mut a = [0; 32];
426        a.copy_from_slice(p);
427        Self::parse(&a)
428    }
429
430    pub fn random<R: Rng>(rng: &mut R) -> SecretKey {
431        loop {
432            let mut ret = [0u8; util::SECRET_KEY_SIZE];
433            rng.fill_bytes(&mut ret);
434
435            if let Ok(key) = Self::parse(&ret) {
436                return key;
437            }
438        }
439    }
440
441    pub fn serialize(&self) -> [u8; util::SECRET_KEY_SIZE] {
442        self.0.b32()
443    }
444
445    pub fn tweak_add_assign(&mut self, tweak: &SecretKey) -> Result<(), Error> {
446        let v = self.0 + tweak.0;
447        if v.is_zero() {
448            return Err(Error::TweakOutOfRange);
449        }
450        self.0 = v;
451        Ok(())
452    }
453
454    pub fn tweak_mul_assign(&mut self, tweak: &SecretKey) -> Result<(), Error> {
455        if tweak.0.is_zero() {
456            return Err(Error::TweakOutOfRange);
457        }
458
459        self.0 *= &tweak.0;
460        Ok(())
461    }
462
463    pub fn inv(&self) -> Self {
464        SecretKey(self.0.inv())
465    }
466}
467
468impl Default for SecretKey {
469    fn default() -> SecretKey {
470        let mut elem = Scalar::default();
471        let overflowed = bool::from(elem.set_b32(&[
472            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
473            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
474            0x00, 0x00, 0x00, 0x01,
475        ]));
476        debug_assert!(!overflowed);
477        debug_assert!(!elem.is_zero());
478        SecretKey(elem)
479    }
480}
481
482impl Into<Scalar> for SecretKey {
483    fn into(self) -> Scalar {
484        self.0
485    }
486}
487
488impl TryFrom<Scalar> for SecretKey {
489    type Error = Error;
490
491    fn try_from(scalar: Scalar) -> Result<Self, Error> {
492        if scalar.is_zero() {
493            Err(Error::InvalidSecretKey)
494        } else {
495            Ok(Self(scalar))
496        }
497    }
498}
499
500impl core::fmt::LowerHex for SecretKey {
501    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
502        let scalar = self.0;
503
504        write!(f, "{:x}", scalar)
505    }
506}
507
508impl Signature {
509    /// Parse an possibly overflowing signature.
510    ///
511    /// A SECP256K1 signature is usually required to be within 0 and curve
512    /// order. This function, however, allows signatures larger than curve order
513    /// by taking the signature and minus curve order.
514    ///
515    /// Note that while this function is technically safe, it is non-standard,
516    /// meaning you will have compatibility issues if you also use other
517    /// SECP256K1 libraries. It's not recommended to use this function. Please
518    /// use `parse_standard` instead.
519    pub fn parse_overflowing(p: &[u8; util::SIGNATURE_SIZE]) -> Signature {
520        let mut r = Scalar::default();
521        let mut s = Scalar::default();
522
523        // Okay for signature to overflow
524        let _ = r.set_b32(array_ref!(p, 0, 32));
525        let _ = s.set_b32(array_ref!(p, 32, 32));
526
527        Signature { r, s }
528    }
529
530    /// Parse a standard SECP256K1 signature. The signature is required to be
531    /// within 0 and curve order. Returns error if it overflows.
532    pub fn parse_standard(p: &[u8; util::SIGNATURE_SIZE]) -> Result<Signature, Error> {
533        let mut r = Scalar::default();
534        let mut s = Scalar::default();
535
536        // It's okay for the signature to overflow here, it's checked below.
537        let overflowed_r = r.set_b32(array_ref!(p, 0, 32));
538        let overflowed_s = s.set_b32(array_ref!(p, 32, 32));
539
540        if bool::from(overflowed_r | overflowed_s) {
541            return Err(Error::InvalidSignature);
542        }
543
544        Ok(Signature { r, s })
545    }
546
547    /// Parse a possibly overflowing signature slice. See also
548    /// `parse_overflowing`.
549    ///
550    /// It's not recommended to use this function. Please use
551    /// `parse_standard_slice` instead.
552    pub fn parse_overflowing_slice(p: &[u8]) -> Result<Signature, Error> {
553        if p.len() != util::SIGNATURE_SIZE {
554            return Err(Error::InvalidInputLength);
555        }
556
557        let mut a = [0; util::SIGNATURE_SIZE];
558        a.copy_from_slice(p);
559        Ok(Self::parse_overflowing(&a))
560    }
561
562    /// Parse a standard signature slice. See also `parse_standard`.
563    pub fn parse_standard_slice(p: &[u8]) -> Result<Signature, Error> {
564        if p.len() != util::SIGNATURE_SIZE {
565            return Err(Error::InvalidInputLength);
566        }
567
568        let mut a = [0; util::SIGNATURE_SIZE];
569        a.copy_from_slice(p);
570        Ok(Self::parse_standard(&a)?)
571    }
572
573    /// Parse a DER-encoded byte slice to a signature.
574    pub fn parse_der(p: &[u8]) -> Result<Signature, Error> {
575        let mut decoder = Decoder::new(p);
576
577        decoder.read_constructed_sequence()?;
578        let rlen = decoder.read_len()?;
579
580        if rlen != decoder.remaining_len() {
581            return Err(Error::InvalidSignature);
582        }
583
584        let r = decoder.read_integer()?;
585        let s = decoder.read_integer()?;
586
587        if decoder.remaining_len() != 0 {
588            return Err(Error::InvalidSignature);
589        }
590
591        Ok(Signature { r, s })
592    }
593
594    /// Converts a "lax DER"-encoded byte slice to a signature. This is basically
595    /// only useful for validating signatures in the Bitcoin blockchain from before
596    /// 2016. It should never be used in new applications. This library does not
597    /// support serializing to this "format"
598    pub fn parse_der_lax(p: &[u8]) -> Result<Signature, Error> {
599        let mut decoder = Decoder::new(p);
600
601        decoder.read_constructed_sequence()?;
602        decoder.read_seq_len_lax()?;
603
604        let r = decoder.read_integer_lax()?;
605        let s = decoder.read_integer_lax()?;
606
607        Ok(Signature { r, s })
608    }
609
610    /// Normalizes a signature to a "low S" form. In ECDSA, signatures are
611    /// of the form (r, s) where r and s are numbers lying in some finite
612    /// field. The verification equation will pass for (r, s) iff it passes
613    /// for (r, -s), so it is possible to ``modify'' signatures in transit
614    /// by flipping the sign of s. This does not constitute a forgery since
615    /// the signed message still cannot be changed, but for some applications,
616    /// changing even the signature itself can be a problem. Such applications
617    /// require a "strong signature". It is believed that ECDSA is a strong
618    /// signature except for this ambiguity in the sign of s, so to accommodate
619    /// these applications libsecp256k1 will only accept signatures for which
620    /// s is in the lower half of the field range. This eliminates the
621    /// ambiguity.
622    ///
623    /// However, for some systems, signatures with high s-values are considered
624    /// valid. (For example, parsing the historic Bitcoin blockchain requires
625    /// this.) For these applications we provide this normalization function,
626    /// which ensures that the s value lies in the lower half of its range.
627    pub fn normalize_s(&mut self) {
628        if self.s.is_high() {
629            self.s = -self.s;
630        }
631    }
632
633    /// Serialize a signature to a standard byte representation. This is the
634    /// reverse of `parse_standard`.
635    pub fn serialize(&self) -> [u8; util::SIGNATURE_SIZE] {
636        let mut ret = [0u8; 64];
637        self.r.fill_b32(array_mut_ref!(ret, 0, 32));
638        self.s.fill_b32(array_mut_ref!(ret, 32, 32));
639        ret
640    }
641
642    /// Serialize a signature to a DER encoding. This is the reverse of
643    /// `parse_der`.
644    pub fn serialize_der(&self) -> SignatureArray {
645        fn fill_scalar_with_leading_zero(scalar: &Scalar) -> [u8; 33] {
646            let mut ret = [0u8; 33];
647            scalar.fill_b32(array_mut_ref!(ret, 1, 32));
648            ret
649        }
650
651        let r_full = fill_scalar_with_leading_zero(&self.r);
652        let s_full = fill_scalar_with_leading_zero(&self.s);
653
654        fn integer_slice(full: &[u8; 33]) -> &[u8] {
655            let mut len = 33;
656            while len > 1 && full[full.len() - len] == 0 && full[full.len() - len + 1] < 0x80 {
657                len -= 1;
658            }
659            &full[(full.len() - len)..]
660        }
661
662        let r = integer_slice(&r_full);
663        let s = integer_slice(&s_full);
664
665        let mut ret = SignatureArray::new(6 + r.len() + s.len());
666        {
667            let l = ret.as_mut();
668            l[0] = 0x30;
669            l[1] = 4 + r.len() as u8 + s.len() as u8;
670            l[2] = 0x02;
671            l[3] = r.len() as u8;
672            l[4..(4 + r.len())].copy_from_slice(r);
673            l[4 + r.len()] = 0x02;
674            l[5 + r.len()] = s.len() as u8;
675            l[(6 + r.len())..(6 + r.len() + s.len())].copy_from_slice(s);
676        }
677
678        ret
679    }
680}
681
682impl Message {
683    pub fn parse(p: &[u8; util::MESSAGE_SIZE]) -> Message {
684        let mut m = Scalar::default();
685
686        // Okay for message to overflow.
687        let _ = m.set_b32(p);
688
689        Message(m)
690    }
691
692    pub fn parse_slice(p: &[u8]) -> Result<Message, Error> {
693        if p.len() != util::MESSAGE_SIZE {
694            return Err(Error::InvalidInputLength);
695        }
696
697        let mut a = [0; util::MESSAGE_SIZE];
698        a.copy_from_slice(p);
699        Ok(Self::parse(&a))
700    }
701
702    pub fn serialize(&self) -> [u8; util::MESSAGE_SIZE] {
703        self.0.b32()
704    }
705}
706
707impl RecoveryId {
708    /// Parse recovery ID starting with 0.
709    pub fn parse(p: u8) -> Result<RecoveryId, Error> {
710        if p < 4 {
711            Ok(RecoveryId(p))
712        } else {
713            Err(Error::InvalidRecoveryId)
714        }
715    }
716
717    /// Parse recovery ID as Ethereum RPC format, starting with 27.
718    pub fn parse_rpc(p: u8) -> Result<RecoveryId, Error> {
719        if p >= 27 && p < 27 + 4 {
720            RecoveryId::parse(p - 27)
721        } else {
722            Err(Error::InvalidRecoveryId)
723        }
724    }
725
726    pub fn serialize(&self) -> u8 {
727        self.0
728    }
729}
730
731impl Into<u8> for RecoveryId {
732    fn into(self) -> u8 {
733        self.0
734    }
735}
736
737impl Into<i32> for RecoveryId {
738    fn into(self) -> i32 {
739        self.0 as i32
740    }
741}
742
743impl<D: Digest + Default> SharedSecret<D> {
744    pub fn new_with_context(
745        pubkey: &PublicKey,
746        seckey: &SecretKey,
747        context: &ECMultContext,
748    ) -> Result<SharedSecret<D>, Error> {
749        let inner = match context.ecdh_raw::<D>(&pubkey.0, &seckey.0) {
750            Some(val) => val,
751            None => return Err(Error::InvalidSecretKey),
752        };
753
754        Ok(SharedSecret(inner))
755    }
756
757    #[cfg(any(feature = "static-context", feature = "lazy-static-context"))]
758    pub fn new(pubkey: &PublicKey, seckey: &SecretKey) -> Result<SharedSecret<D>, Error> {
759        Self::new_with_context(pubkey, seckey, &ECMULT_CONTEXT)
760    }
761}
762
763impl<D: Digest> AsRef<[u8]> for SharedSecret<D> {
764    fn as_ref(&self) -> &[u8] {
765        &self.0.as_ref()
766    }
767}
768
769/// Check signature is a valid message signed by public key, using the given context.
770pub fn verify_with_context(
771    message: &Message,
772    signature: &Signature,
773    pubkey: &PublicKey,
774    context: &ECMultContext,
775) -> bool {
776    context.verify_raw(&signature.r, &signature.s, &pubkey.0, &message.0)
777}
778
779#[cfg(any(feature = "static-context", feature = "lazy-static-context"))]
780/// Check signature is a valid message signed by public key.
781pub fn verify(message: &Message, signature: &Signature, pubkey: &PublicKey) -> bool {
782    verify_with_context(message, signature, pubkey, &ECMULT_CONTEXT)
783}
784
785/// Recover public key from a signed message, using the given context.
786pub fn recover_with_context(
787    message: &Message,
788    signature: &Signature,
789    recovery_id: &RecoveryId,
790    context: &ECMultContext,
791) -> Result<PublicKey, Error> {
792    context
793        .recover_raw(&signature.r, &signature.s, recovery_id.0, &message.0)
794        .map(PublicKey)
795}
796
797#[cfg(any(feature = "static-context", feature = "lazy-static-context"))]
798/// Recover public key from a signed message.
799pub fn recover(
800    message: &Message,
801    signature: &Signature,
802    recovery_id: &RecoveryId,
803) -> Result<PublicKey, Error> {
804    recover_with_context(message, signature, recovery_id, &ECMULT_CONTEXT)
805}
806
807#[cfg(feature = "hmac")]
808/// Sign a message using the secret key, with the given context.
809pub fn sign_with_context(
810    message: &Message,
811    seckey: &SecretKey,
812    context: &ECMultGenContext,
813) -> (Signature, RecoveryId) {
814    let seckey_b32 = seckey.0.b32();
815    let message_b32 = message.0.b32();
816
817    let mut drbg = HmacDRBG::<Sha256>::new(&seckey_b32, &message_b32, &[]);
818    let mut nonce = Scalar::default();
819    let mut overflow;
820
821    let result;
822    loop {
823        let generated = drbg.generate::<U32>(None);
824        overflow = bool::from(nonce.set_b32(array_ref!(generated, 0, 32)));
825
826        if !overflow && !nonce.is_zero() {
827            if let Ok(val) = context.sign_raw(&seckey.0, &message.0, &nonce) {
828                result = val;
829                break;
830            }
831        }
832    }
833
834    #[allow(unused_assignments)]
835    {
836        nonce = Scalar::default();
837    }
838    let (sigr, sigs, recid) = result;
839
840    (Signature { r: sigr, s: sigs }, RecoveryId(recid))
841}
842
843#[cfg(all(
844    feature = "hmac",
845    any(feature = "static-context", feature = "lazy-static-context")
846))]
847/// Sign a message using the secret key.
848pub fn sign(message: &Message, seckey: &SecretKey) -> (Signature, RecoveryId) {
849    sign_with_context(message, seckey, &ECMULT_GEN_CONTEXT)
850}
851
852#[cfg(test)]
853mod tests {
854    use crate::SecretKey;
855    use hex_literal::hex;
856
857    #[test]
858    fn secret_key_inverse_is_sane() {
859        let sk = SecretKey::parse(&[1; 32]).unwrap();
860        let inv = sk.inv();
861        let invinv = inv.inv();
862        assert_eq!(sk, invinv);
863        // Check that the inverse of `[1; 32]` is same as rust-secp256k1
864        assert_eq!(
865            inv,
866            SecretKey::parse(&hex!(
867                "1536f1d756d1abf83aaf173bc5ee3fc487c93010f18624d80bd6d4038fadd59e"
868            ))
869            .unwrap()
870        )
871    }
872}