1use crate::identity::contract_bounds::ContractBounds;
2use crate::identity::identity_public_key::v0::IdentityPublicKeyV0;
3use crate::identity::KeyType::{ECDSA_HASH160, ECDSA_SECP256K1};
4use crate::identity::Purpose::{AUTHENTICATION, OWNER, TRANSFER, VOTING};
5use crate::identity::SecurityLevel::{CRITICAL, HIGH, MASTER, MEDIUM};
6use crate::identity::{KeyCount, KeyID, KeyType, Purpose, SecurityLevel};
7use crate::version::PlatformVersion;
8use crate::ProtocolError;
9use platform_value::BinaryData;
10use rand::rngs::StdRng;
11use rand::Rng;
12use std::convert::TryFrom;
13use std::ops::{Div, Rem};
14
15pub type UsedKeyMatrix = Vec<bool>;
16
17impl IdentityPublicKeyV0 {
18 pub fn random_authentication_key_with_rng(
19 id: KeyID,
20 rng: &mut StdRng,
21 used_key_matrix: Option<(KeyCount, &mut UsedKeyMatrix)>,
22 platform_version: &PlatformVersion,
23 ) -> Result<Self, ProtocolError> {
24 let mut binding = [false; 16].to_vec();
26 let (key_count, key_matrix) = used_key_matrix.unwrap_or((0, &mut binding));
27 if key_count > 16 {
28 return Err(ProtocolError::PublicKeyGenerationError(
29 "too many keys already created".to_string(),
30 ));
31 }
32 let key_number = rng.gen_range(0..(16 - key_count as u8));
33 let mut needed_pos = None;
35 let mut counter = 0;
36 key_matrix.iter_mut().enumerate().for_each(|(pos, is_set)| {
37 if !*is_set {
38 if counter == key_number {
39 needed_pos = Some(pos as u8);
40 *is_set = true;
41 }
42 counter += 1;
43 }
44 });
45 let needed_pos = needed_pos.ok_or(ProtocolError::PublicKeyGenerationError(
46 "too many keys already created".to_string(),
47 ))?;
48 let key_type = needed_pos.div(&4);
49 let security_level = needed_pos.rem(&4);
50 let security_level = SecurityLevel::try_from(security_level).unwrap();
51 let key_type = KeyType::try_from(key_type).unwrap();
52 let read_only = false;
53 let data = BinaryData::new(key_type.random_public_key_data(rng, platform_version)?);
54 Ok(IdentityPublicKeyV0 {
55 id,
56 key_type,
57 purpose: AUTHENTICATION,
58 security_level,
59 read_only,
60 disabled_at: None,
61 data,
62 contract_bounds: None,
63 })
64 }
65
66 pub fn random_authentication_key_with_private_key_with_rng(
67 id: KeyID,
68 rng: &mut StdRng,
69 used_key_matrix: Option<(KeyCount, &mut UsedKeyMatrix)>,
70 platform_version: &PlatformVersion,
71 ) -> Result<(Self, [u8; 32]), ProtocolError> {
72 let mut binding = [false; 16].to_vec();
74 let (key_count, key_matrix) = used_key_matrix.unwrap_or((0, &mut binding));
75 if key_count > 16 {
76 return Err(ProtocolError::PublicKeyGenerationError(
77 "too many keys already created".to_string(),
78 ));
79 }
80 let key_number = rng.gen_range(0..(12 - key_count as u8));
81 let mut needed_pos = None;
83 let mut counter = 0;
84 key_matrix.iter_mut().enumerate().for_each(|(pos, is_set)| {
85 if !*is_set {
86 if counter == key_number {
87 needed_pos = Some(pos as u8);
88 *is_set = true;
89 }
90 counter += 1;
91 }
92 });
93 let needed_pos = needed_pos.ok_or(ProtocolError::PublicKeyGenerationError(
94 "too many keys already created".to_string(),
95 ))?;
96 let key_type = needed_pos.div(&4);
97 let security_level = needed_pos.rem(&4);
98 let security_level = SecurityLevel::try_from(security_level).unwrap();
99 let key_type = KeyType::try_from(key_type).unwrap();
100 let read_only = false;
101 let (public_data, private_data) =
102 key_type.random_public_and_private_key_data(rng, platform_version)?;
103 let data = BinaryData::new(public_data);
104 Ok((
105 IdentityPublicKeyV0 {
106 id,
107 key_type,
108 purpose: AUTHENTICATION,
109 security_level,
110 read_only,
111 disabled_at: None,
112 data,
113 contract_bounds: None,
114 },
115 private_data,
116 ))
117 }
118
119 pub fn random_key_with_known_attributes(
120 id: KeyID,
121 rng: &mut StdRng,
122 purpose: Purpose,
123 security_level: SecurityLevel,
124 key_type: KeyType,
125 contract_bounds: Option<ContractBounds>,
126 platform_version: &PlatformVersion,
127 ) -> Result<(Self, [u8; 32]), ProtocolError> {
128 let read_only = false;
129 let (public_data, private_data) =
130 key_type.random_public_and_private_key_data(rng, platform_version)?;
131 let data = BinaryData::new(public_data);
132 let identity_public_key = IdentityPublicKeyV0 {
133 id,
134 key_type,
135 purpose,
136 security_level,
137 read_only,
138 disabled_at: None,
139 data,
140 contract_bounds,
141 };
142 Ok((identity_public_key, private_data))
143 }
144
145 pub fn random_key_with_rng(
146 id: KeyID,
147 rng: &mut StdRng,
148 used_key_matrix: Option<(KeyCount, &mut UsedKeyMatrix)>,
149 platform_version: &PlatformVersion,
150 ) -> Result<Self, ProtocolError> {
151 let mut binding = [false; 64].to_vec();
153 let (key_count, key_matrix) = used_key_matrix.unwrap_or((0, &mut binding));
154 if key_count > 64 {
155 return Err(ProtocolError::PublicKeyGenerationError(
156 "too many keys already created".to_string(),
157 ));
158 }
159 let key_number = rng.gen_range(0..(64 - key_count as u8));
160 let mut needed_pos = None;
162 let mut counter = 0;
163 key_matrix.iter_mut().enumerate().for_each(|(pos, is_set)| {
164 if !*is_set {
165 if counter == key_number {
166 needed_pos = Some(pos as u8);
167 *is_set = true;
168 }
169 counter += 1;
170 }
171 });
172 let needed_pos = needed_pos.ok_or(ProtocolError::PublicKeyGenerationError(
173 "too many keys already created".to_string(),
174 ))?;
175 let security_level = needed_pos.div(&16);
176 let left = needed_pos.rem(&16);
177 let security_level = SecurityLevel::try_from(security_level).unwrap();
178 let key_type = left.div(&4);
179 let purpose = left.rem(&4);
180 let purpose = Purpose::try_from(purpose).unwrap();
181 let key_type = KeyType::try_from(key_type).unwrap();
182 let read_only = false;
183 let data = BinaryData::new(key_type.random_public_key_data(rng, platform_version)?);
184 Ok(IdentityPublicKeyV0 {
185 id,
186 key_type,
187 purpose,
188 security_level,
189 read_only,
190 disabled_at: None,
191 data,
192 contract_bounds: None,
193 })
194 }
195
196 pub fn random_ecdsa_master_authentication_key_with_rng(
197 id: KeyID,
198 rng: &mut StdRng,
199 platform_version: &PlatformVersion,
200 ) -> Result<(Self, [u8; 32]), ProtocolError> {
201 let key_type = ECDSA_SECP256K1;
202 let purpose = AUTHENTICATION;
203 let security_level = MASTER;
204 let read_only = false;
205 let (data, private_data) =
206 key_type.random_public_and_private_key_data(rng, platform_version)?;
207 Ok((
208 IdentityPublicKeyV0 {
209 id,
210 key_type,
211 purpose,
212 security_level,
213 read_only,
214 disabled_at: None,
215 data: data.into(),
216 contract_bounds: None,
217 },
218 private_data,
219 ))
220 }
221
222 pub fn random_voting_key_with_rng(
223 id: KeyID,
224 rng: &mut StdRng,
225 platform_version: &PlatformVersion,
226 ) -> Result<(Self, [u8; 32]), ProtocolError> {
227 let key_type = ECDSA_HASH160;
228 let purpose = VOTING;
229 let security_level = MEDIUM;
230 let read_only = false;
231 let (data, private_data) =
232 key_type.random_public_and_private_key_data(rng, platform_version)?;
233 Ok((
234 IdentityPublicKeyV0 {
235 id,
236 key_type,
237 purpose,
238 security_level,
239 read_only,
240 disabled_at: None,
241 data: data.into(),
242 contract_bounds: None,
243 },
244 private_data,
245 ))
246 }
247
248 pub fn random_owner_key_with_rng(
249 id: KeyID,
250 rng: &mut StdRng,
251 platform_version: &PlatformVersion,
252 ) -> Result<(Self, [u8; 32]), ProtocolError> {
253 let key_type = ECDSA_HASH160;
254 let purpose = OWNER;
255 let security_level = CRITICAL;
256 let read_only = true;
257 let (data, private_data) =
258 key_type.random_public_and_private_key_data(rng, platform_version)?;
259 Ok((
260 IdentityPublicKeyV0 {
261 id,
262 key_type,
263 purpose,
264 security_level,
265 read_only,
266 disabled_at: None,
267 data: data.into(),
268 contract_bounds: None,
269 },
270 private_data,
271 ))
272 }
273
274 pub fn random_masternode_transfer_key_with_rng(
275 id: KeyID,
276 rng: &mut StdRng,
277 platform_version: &PlatformVersion,
278 ) -> Result<(Self, [u8; 32]), ProtocolError> {
279 let key_type = ECDSA_HASH160;
280 let purpose = TRANSFER;
281 let security_level = CRITICAL;
282 let read_only = true;
283 let (data, private_data) =
284 key_type.random_public_and_private_key_data(rng, platform_version)?;
285 Ok((
286 IdentityPublicKeyV0 {
287 id,
288 key_type,
289 purpose,
290 security_level,
291 read_only,
292 disabled_at: None,
293 data: data.into(),
294 contract_bounds: None,
295 },
296 private_data,
297 ))
298 }
299
300 pub fn random_ecdsa_critical_level_authentication_key_with_rng(
301 id: KeyID,
302 rng: &mut StdRng,
303 platform_version: &PlatformVersion,
304 ) -> Result<(Self, [u8; 32]), ProtocolError> {
305 let key_type = ECDSA_SECP256K1;
306 let purpose = AUTHENTICATION;
307 let security_level = CRITICAL;
308 let read_only = false;
309 let (data, private_data) =
310 key_type.random_public_and_private_key_data(rng, platform_version)?;
311 Ok((
312 IdentityPublicKeyV0 {
313 id,
314 key_type,
315 purpose,
316 security_level,
317 read_only,
318 disabled_at: None,
319 data: data.into(),
320 contract_bounds: None,
321 },
322 private_data,
323 ))
324 }
325
326 pub fn random_ecdsa_high_level_authentication_key_with_rng(
327 id: KeyID,
328 rng: &mut StdRng,
329 platform_version: &PlatformVersion,
330 ) -> Result<(Self, [u8; 32]), ProtocolError> {
331 let key_type = ECDSA_SECP256K1;
332 let purpose = AUTHENTICATION;
333 let security_level = HIGH;
334 let read_only = false;
335 let (data, private_data) =
336 key_type.random_public_and_private_key_data(rng, platform_version)?;
337 Ok((
338 IdentityPublicKeyV0 {
339 id,
340 key_type,
341 purpose,
342 security_level,
343 read_only,
344 disabled_at: None,
345 data: data.into(),
346 contract_bounds: None,
347 },
348 private_data,
349 ))
350 }
351}