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
112
113
114
115
116
117
use std::fmt;
use super::*;
use crate::multicipher::MKeyId;
pub const KEY_ID_SIZE: usize = 20 + VERSION_SIZE;
pub const KEY_ID_VERSION1: u8 = b'\x01';
#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct SecpKeyId(Vec<u8>);
impl SecpKeyId {
pub fn to_bytes(&self) -> Vec<u8> {
self.0.clone()
}
pub fn from_bytes<D: AsRef<[u8]>>(bytes: D) -> Result<Self> {
let bytes = bytes.as_ref();
ensure!(bytes.len() == KEY_ID_SIZE, "Identifier length is not {}", KEY_ID_SIZE);
ensure!(
bytes[0] == KEY_ID_VERSION1,
"Only identifier version {:x} is supported",
KEY_ID_VERSION1
);
Ok(Self(bytes.to_owned()))
}
pub fn to_p2pkh_addr(&self, prefix: &[u8; ADDR_PREFIX_SIZE]) -> String {
assert_eq!(self.0[0], KEY_ID_VERSION1);
assert_eq!(self.0.len(), KEY_ID_SIZE);
debug_assert_eq!(prefix.len(), ADDR_PREFIX_SIZE);
let mut address = Vec::with_capacity(ADDR_PREFIX_SIZE + KEY_ID_SIZE - VERSION_SIZE);
address.extend_from_slice(prefix);
address.extend_from_slice(&self.0[VERSION_SIZE..]);
to_base58check(address)
}
pub fn from_p2pkh_addr(addr: &str, network: &dyn Network<Suite = Secp256k1>) -> Result<Self> {
let expected_prefix = network.p2pkh_addr();
debug_assert_eq!(expected_prefix.len(), ADDR_PREFIX_SIZE);
debug_assert_eq!(ADDR_PREFIX_SIZE, 1);
let data = from_base58check(addr)?;
ensure!(
data.len() == ADDR_PREFIX_SIZE + KEY_ID_SIZE - VERSION_SIZE,
"Invalid length of address"
);
let actual_prefix = &data[0..1];
ensure!(
actual_prefix == expected_prefix,
"Invalid network prefix found: {}",
hex::encode(actual_prefix)
);
let mut id = Vec::with_capacity(KEY_ID_SIZE);
id.push(KEY_ID_VERSION1);
id.extend_from_slice(&data[1..]);
Ok(Self(id))
}
pub fn from_ark_pk(pk: &SecpPublicKey) -> Self {
let mut hasher = Ripemd160::default();
hasher.update(&pk.to_bytes());
let hash = hasher.finalize_fixed();
Self::from_v1_bytes(&*hash)
}
fn from_v1_bytes(hash: &[u8]) -> Self {
let mut id = Vec::with_capacity(KEY_ID_SIZE);
id.push(KEY_ID_VERSION1);
id.extend_from_slice(hash);
SecpKeyId(id)
}
}
impl From<&SecpPublicKey> for SecpKeyId {
fn from(pk: &SecpPublicKey) -> Self {
let hash = hash160(&pk.to_bytes()[..]);
Self::from_v1_bytes(&*hash)
}
}
impl fmt::Debug for SecpKeyId {
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> Result<(), fmt::Error> {
let id = MKeyId::from(self.clone());
id.fmt(formatter)
}
}