mina_signer/
keypair.rs

1//! Keypair structures and algorithms
2//!
3//! Definition of secret key, keypairs and related helpers
4
5extern crate alloc;
6
7use crate::{pubkey::PubKeyError, seckey::SecKeyError, CurvePoint, PubKey, ScalarField, SecKey};
8use alloc::{string::String, vec::Vec};
9use core::fmt;
10use rand::{self, CryptoRng, RngCore};
11use thiserror::Error;
12
13/// Keypair error
14#[derive(Error, Debug, Clone, PartialEq, Eq)]
15pub enum KeypairError {
16    /// Invalid secret key
17    #[error(transparent)]
18    SecretKey(#[from] SecKeyError),
19    /// Public key error
20    #[error(transparent)]
21    PublicKey(#[from] PubKeyError),
22    /// point not on curve
23    #[error("point not on curve")]
24    NonCurvePoint,
25}
26/// Keypair result
27pub type Result<T> = core::result::Result<T, KeypairError>;
28
29/// Keypair structure
30#[derive(Clone, PartialEq, Eq)]
31pub struct Keypair {
32    /// Secret key
33    pub secret: SecKey,
34    /// Public key
35    pub public: PubKey,
36}
37
38impl Keypair {
39    /// Create keypair from scalar field `secret` element and curve point `public`
40    /// Note: Does not check point `public` is on curve
41    pub fn from_parts_unsafe(secret: ScalarField, public: CurvePoint) -> Self {
42        Self {
43            secret: SecKey::new(secret),
44            public: PubKey::from_point_unsafe(public),
45        }
46    }
47
48    /// Create keypair from secret key
49    pub fn from_secret_key(secret_key: SecKey) -> Result<Self> {
50        let public = PubKey::from_secret_key(secret_key.clone())?;
51
52        // Safe now because PubKey::from_secret_key() checked point is on the curve
53        Ok(Self::from_parts_unsafe(
54            secret_key.into_scalar(),
55            public.into_point(),
56        ))
57    }
58
59    /// Generate random keypair
60    pub fn rand(rng: &mut (impl RngCore + CryptoRng)) -> Result<Self> {
61        let sec_key: SecKey = SecKey::rand(rng);
62        Keypair::from_secret_key(sec_key)
63    }
64
65    /// Deserialize keypair from secret key bytes
66    ///
67    /// # Errors
68    ///
69    /// Will give error if `bytes` do not match certain requirements.
70    pub fn from_bytes(secret_bytes: &[u8]) -> Result<Self> {
71        let secret = SecKey::from_bytes(secret_bytes)?;
72        Keypair::from_secret_key(secret)
73    }
74
75    /// Deserialize keypair from secret key hex
76    ///
77    /// # Errors
78    ///
79    /// Will give error if `hex` string does not match certain requirements.
80    pub fn from_hex(secret_hex: &str) -> Result<Self> {
81        let secret = SecKey::from_hex(secret_hex)?;
82        Keypair::from_secret_key(secret)
83    }
84
85    /// Obtain the Mina address corresponding to the keypair's public key
86    pub fn get_address(self) -> String {
87        self.public.into_address()
88    }
89
90    /// Deserialize keypair into bytes
91    pub fn to_bytes(&self) -> Vec<u8> {
92        self.secret.to_bytes()
93    }
94
95    /// Deserialize keypair into hex
96    pub fn to_hex(&self) -> String {
97        hex::encode(self.to_bytes())
98    }
99}
100
101impl fmt::Debug for Keypair {
102    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
103        // Omit the secret key for security
104        write!(f, "{:?}", self.public)
105    }
106}
107
108impl fmt::Display for Keypair {
109    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
110        // Omit the secret key for security
111        write!(f, "{}", self.public)
112    }
113}