ckb_crypto/secp/
pubkey.rs

1use super::error::Error;
2use super::signature::Signature;
3use super::Message;
4use super::SECP256K1;
5use ckb_fixed_hash::H512;
6use secp256k1::Message as SecpMessage;
7use secp256k1::PublicKey;
8use std::{fmt, ops};
9
10/// A Secp256k1 512-bit public key, used for verification of signatures
11#[derive(Debug, Eq, PartialEq, Hash, Clone)]
12pub struct Pubkey {
13    inner: H512,
14}
15
16impl Pubkey {
17    /// Checks that `signature` is a valid ECDSA signature for `message` using the public
18    /// key `pubkey`
19    pub fn verify(&self, message: &Message, signature: &Signature) -> Result<(), Error> {
20        let context = &SECP256K1;
21
22        // non-compressed key prefix 4
23        let prefix_key: [u8; 65] = {
24            let mut temp = [4u8; 65];
25            temp[1..65].copy_from_slice(self.inner.as_bytes());
26            temp
27        };
28
29        let pubkey = PublicKey::from_slice(&prefix_key)?;
30        let recoverable_signature = signature.to_recoverable()?;
31        let signature = recoverable_signature.to_standard();
32
33        let message = SecpMessage::from_digest_slice(message.as_bytes())?;
34        context.verify_ecdsa(&message, &signature, &pubkey)?;
35        Ok(())
36    }
37
38    /// Serialize the key as a byte-encoded pair of values.
39    /// In compressed form the y-coordinate is represented by only a single bit,
40    /// as x determines it up to one bit.
41    pub fn serialize(&self) -> Vec<u8> {
42        // non-compressed key prefix 4
43        let prefix_key: [u8; 65] = {
44            let mut temp = [4u8; 65];
45            temp[1..65].copy_from_slice(self.inner.as_bytes());
46            temp
47        };
48        let pubkey = PublicKey::from_slice(&prefix_key).unwrap();
49        Vec::from(&pubkey.serialize()[..])
50    }
51
52    /// Creates a new Pubkey from a slice
53    pub fn from_slice(data: &[u8]) -> Result<Self, Error> {
54        Ok(PublicKey::from_slice(data)?.into())
55    }
56}
57
58impl From<[u8; 64]> for Pubkey {
59    fn from(key: [u8; 64]) -> Self {
60        Pubkey { inner: key.into() }
61    }
62}
63
64impl From<H512> for Pubkey {
65    fn from(key: H512) -> Self {
66        Pubkey { inner: key }
67    }
68}
69
70impl ops::Deref for Pubkey {
71    type Target = H512;
72
73    fn deref(&self) -> &Self::Target {
74        &self.inner
75    }
76}
77
78impl From<PublicKey> for Pubkey {
79    fn from(key: PublicKey) -> Self {
80        let serialized = key.serialize_uncompressed();
81        let mut pubkey = [0u8; 64];
82        pubkey.copy_from_slice(&serialized[1..65]);
83        Pubkey {
84            inner: pubkey.into(),
85        }
86    }
87}
88
89impl fmt::Display for Pubkey {
90    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
91        write!(f, "{:x}", self.inner)
92    }
93}