1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
use std::ops::Add;
use super::*;
use crate::PrivateKey;
pub const PRIVATE_KEY_SIZE: usize = secp::util::SECRET_KEY_SIZE;
#[derive(Clone, Eq, PartialEq)]
pub struct SecpPrivateKey(secp::SecretKey);
impl SecpPrivateKey {
pub fn to_bytes(&self) -> Vec<u8> {
self.0.serialize().to_vec()
}
pub fn from_bytes<D: AsRef<[u8]>>(bytes: D) -> Result<Self> {
let sk = secp::SecretKey::parse_slice(bytes.as_ref())?;
Ok(Self(sk))
}
pub fn from_ark_passphrase(phrase: impl AsRef<str>) -> Result<Self> {
let hash = sha2::Sha256::digest(phrase.as_ref().as_bytes());
Self::from_bytes(hash)
}
pub fn to_wif(&self, version: &[u8; ADDR_PREFIX_SIZE], usage: Bip178) -> String {
let mut res = Vec::with_capacity(1 + 1 + PRIVATE_KEY_SIZE);
res.extend_from_slice(version);
res.extend_from_slice(&self.to_bytes());
res.extend_from_slice(usage.to_wif_suffix());
to_base58check(res)
}
pub fn from_wif(wif: &str, network: &dyn Network<Suite = Secp256k1>) -> Result<(Self, Bip178)> {
let data = from_base58check(wif)?;
ensure!(data.len() > PRIVATE_KEY_SIZE, "WIF data is too short");
let expected_prefix = network.wif();
debug_assert_eq!(expected_prefix.len(), ADDR_PREFIX_SIZE);
debug_assert_eq!(ADDR_PREFIX_SIZE, 1);
let (actual_prefix, data) = data.split_at(ADDR_PREFIX_SIZE);
ensure!(
actual_prefix == expected_prefix,
"Invalid network prefix found: {}",
hex::encode(actual_prefix)
);
let (sk_bytes, usage_bytes) = data.split_at(PRIVATE_KEY_SIZE);
let sk = Self::from_bytes(sk_bytes)?;
let usage = Bip178::from_wif_suffix(usage_bytes)?;
Ok((sk, usage))
}
}
impl Add<&[u8]> for &SecpPrivateKey {
type Output = Result<SecpPrivateKey>;
fn add(self, rhs: &[u8]) -> Self::Output {
let mut sum = secp::SecretKey::parse_slice(rhs)?;
sum.tweak_add_assign(&self.0)?;
Ok(SecpPrivateKey(sum))
}
}
impl PrivateKey<Secp256k1> for SecpPrivateKey {
fn public_key(&self) -> SecpPublicKey {
let pk = secp::PublicKey::from_secret_key(&self.0);
SecpPublicKey(pk)
}
fn sign<D: AsRef<[u8]>>(&self, data: D) -> SecpSignature {
let msg = Secp256k1::hash_message(data);
let (sig, _recovery) = secp::sign(&msg, &self.0);
SecpSignature(sig)
}
}
impl From<secp::SecretKey> for SecpPrivateKey {
fn from(sk: secp::SecretKey) -> Self {
Self(sk)
}
}
impl From<SecpPrivateKey> for secp::SecretKey {
fn from(sk: SecpPrivateKey) -> secp::SecretKey {
sk.0
}
}