hbpasta_rs/
lib.rs

1use std::fmt;
2
3use bs58::decode::Error;
4use pasta_curves::group::ff::Field;
5use pasta_curves::group::ff::PrimeField;
6use pasta_curves::group::Group;
7use pasta_curves::group::GroupEncoding;
8use pasta_curves::Fq;
9use pasta_curves::{pallas::Scalar, Ep};
10use rand::rngs::OsRng;
11// use rand::CryptoRng;
12// use rand::RngCore;
13
14/// Fqp is a pallas::Scalar
15pub type Fqp = Scalar;
16
17#[derive(Clone, Copy, PartialEq)]
18pub struct PrivateKey(pub Fqp);
19
20impl PrivateKey {
21    fn from_fqp(fqp: Fqp) -> Self {
22        Self(fqp)
23    }
24    /// Generate new private key
25    pub fn new() -> Self {
26        let mut rng = OsRng::default();
27        Self(Fqp::random(&mut rng))
28    }
29    pub fn to_bytes(&self) -> [u8; 32] {
30        self.0.to_repr()
31    }
32    pub fn pubkey(&self) -> PublicKey {
33        PublicKey(Ep::generator() * self.0)
34    }
35}
36/// For debugging but we need to get to the 64 bytes?
37impl fmt::Debug for PrivateKey {
38    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
39        write!(f, "{}", bs58::encode(self.0.to_repr()).into_string())?;
40        Ok(())
41    }
42}
43
44#[derive(Clone, Copy)]
45pub struct Keypair {
46    priv_key: PrivateKey,
47    public_key: PublicKey,
48}
49
50impl Keypair {
51    /// Constructs a new, random `Keypair` using a caller-proveded RNG
52    fn generate() -> Self {
53        let prv_key = PrivateKey::new();
54        Self {
55            priv_key: prv_key,
56            public_key: prv_key.pubkey(),
57        }
58    }
59
60    pub fn new() -> Self {
61        Keypair::generate()
62    }
63
64    pub fn secret(&self) -> Fqp {
65        self.priv_key.0
66    }
67
68    pub fn to_bytes(&self) -> [u8; 32] {
69        self.priv_key.to_bytes()
70    }
71
72    /// Returns this `Keypair` as a base58-encoded string
73    pub fn to_base58_string(&self) -> String {
74        bs58::encode(&self.to_bytes()).into_string()
75    }
76
77    /// Recovers a `Keypair` from a base58-encoded string
78    pub fn from_base58_string(s: &str) -> Result<Self, Error> {
79        let mut inbuf = [0u8; 32];
80        let obuf = bs58::decode(s).into_vec().unwrap();
81        if obuf.len() != 32 {
82            return Err(bs58::decode::Error::BufferTooSmall);
83        } else {
84            let mut index = 0;
85            for b in obuf {
86                inbuf[index] = b;
87                index += 1;
88            }
89        }
90        let prv_key = PrivateKey::from_fqp(Fq::from_repr(inbuf).unwrap());
91        Ok(Self {
92            priv_key: prv_key,
93            public_key: prv_key.pubkey(),
94        })
95    }
96
97    pub fn private_key(&self) -> &PrivateKey {
98        &self.priv_key
99    }
100
101    pub fn pubkey(&self) -> &PublicKey {
102        &self.public_key
103    }
104}
105
106/// For debugging but we need to get to the 64 bytes?
107impl fmt::Debug for Keypair {
108    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
109        write!(
110            f,
111            "{}",
112            bs58::encode(self.priv_key.0.to_repr()).into_string()
113        )?;
114        Ok(())
115    }
116}
117#[derive(Clone, Copy, PartialEq)]
118pub struct PublicKey(pub Ep);
119
120impl PublicKey {
121    pub fn new_random() -> Self {
122        let prv = PrivateKey::new();
123        prv.pubkey()
124    }
125
126    pub fn to_bytes(&self) -> [u8; 32] {
127        self.0.to_bytes()
128    }
129
130    pub fn to_base58_string(&self) -> String {
131        bs58::encode(self.to_bytes()).into_string()
132    }
133
134    pub fn from_base58_string(s: &str) -> Self {
135        let mut bff = [0u8; 32];
136        let _ = bs58::decode(s).into(&mut bff).unwrap();
137        Self(Ep::from_bytes(&bff).unwrap())
138    }
139}
140
141/// For debugging but we need to get to the 64 bytes?
142impl fmt::Debug for PublicKey {
143    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
144        write!(f, "{}", bs58::encode(self.to_base58_string()).into_string())?;
145        Ok(())
146    }
147}
148
149#[cfg(test)]
150mod tests {
151    use super::*;
152
153    #[test]
154    fn test_keypair_bs58() {
155        let keypair = Keypair::new();
156        let o58 = keypair.to_base58_string();
157        println!("o58 {}", o58);
158        let keypair = Keypair::from_base58_string(&o58).unwrap();
159        println!("kp from o58 {:?}", keypair);
160    }
161    #[test]
162    fn test_publickey_bs58() {
163        let keypair = Keypair::new();
164        println!("Secret 1 {:?}", keypair);
165        let pkey = keypair.pubkey();
166        println!("Pubkey 1 {}", pkey.to_base58_string());
167        let pkey = PublicKey::from_base58_string("GybzWZH3QJjAjATn5WozC1TThUZhCnea3pPMWc7KbP1X");
168        println!("Pubkey 2 {}", pkey.to_base58_string());
169    }
170}