dpp/identity/identity_public_key/random.rs
1use crate::identity::identity_public_key::v0::IdentityPublicKeyV0;
2
3use crate::identity::{IdentityPublicKey, KeyCount, KeyID, KeyType, Purpose, SecurityLevel};
4use crate::version::PlatformVersion;
5use crate::ProtocolError;
6
7use crate::identity::contract_bounds::ContractBounds;
8use rand::rngs::StdRng;
9use rand::SeedableRng;
10
11pub type UsedKeyMatrix = Vec<bool>;
12
13impl IdentityPublicKey {
14 pub fn random_key(id: KeyID, seed: Option<u64>, platform_version: &PlatformVersion) -> Self {
15 let mut rng = match seed {
16 None => StdRng::from_entropy(),
17 Some(seed_value) => StdRng::seed_from_u64(seed_value),
18 };
19 Self::random_key_with_rng(id, &mut rng, None, platform_version).unwrap()
20 }
21
22 pub fn random_keys(
23 first_id: KeyID,
24 count: KeyCount,
25 seed: Option<u64>,
26 platform_version: &PlatformVersion,
27 ) -> Vec<Self> {
28 let mut rng = match seed {
29 None => StdRng::from_entropy(),
30 Some(seed_value) => StdRng::seed_from_u64(seed_value),
31 };
32 let end_id = first_id + count;
33 (first_id..end_id)
34 .map(|key_id| {
35 Self::random_key_with_rng(key_id, &mut rng, None, platform_version).unwrap()
36 })
37 .collect()
38 }
39
40 pub fn random_authentication_key(
41 key_id: KeyID,
42 seed: Option<u64>,
43 platform_version: &PlatformVersion,
44 ) -> Self {
45 let mut rng = match seed {
46 None => StdRng::from_entropy(),
47 Some(seed_value) => StdRng::seed_from_u64(seed_value),
48 };
49 Self::random_authentication_key_with_rng(key_id, &mut rng, None, platform_version).unwrap()
50 }
51
52 pub fn random_authentication_keys(
53 first_id: KeyID,
54 count: KeyCount,
55 seed: Option<u64>,
56 platform_version: &PlatformVersion,
57 ) -> Vec<Self> {
58 let mut rng = match seed {
59 None => StdRng::from_entropy(),
60 Some(seed_value) => StdRng::seed_from_u64(seed_value),
61 };
62 let end_id = first_id + count;
63 (first_id..end_id)
64 .map(|key_id| {
65 Self::random_authentication_key_with_rng(key_id, &mut rng, None, platform_version)
66 .unwrap()
67 })
68 .collect()
69 }
70
71 /// Generates a random authentication key based on the platform version.
72 ///
73 /// # Parameters
74 ///
75 /// * `id`: The `KeyID` for the generated key.
76 /// * `rng`: A mutable reference to a random number generator of type `StdRng`.
77 /// * `used_key_matrix`: An optional tuple that contains the count of keys that have already been used
78 /// and a mutable reference to a matrix (or vector) that tracks which keys have been used.
79 /// * `platform_version`: The platform version which determines the structure of the identity key.
80 ///
81 /// # Returns
82 ///
83 /// * `Result<Self, ProtocolError>`: If successful, returns an instance of `Self`.
84 /// In case of an error, it returns a `ProtocolError`.
85 ///
86 /// # Errors
87 ///
88 /// * `ProtocolError::PublicKeyGenerationError`: This error is returned if too many keys have already been created.
89 /// * `ProtocolError::UnknownVersionMismatch`: This error is returned if the provided platform version is not recognized.
90 ///
91 pub fn random_authentication_key_with_rng(
92 id: KeyID,
93 rng: &mut StdRng,
94 used_key_matrix: Option<(KeyCount, &mut UsedKeyMatrix)>,
95 platform_version: &PlatformVersion,
96 ) -> Result<Self, ProtocolError> {
97 match platform_version
98 .dpp
99 .identity_versions
100 .identity_key_structure_version
101 {
102 0 => Ok(IdentityPublicKeyV0::random_authentication_key_with_rng(
103 id,
104 rng,
105 used_key_matrix,
106 platform_version,
107 )?
108 .into()),
109 version => Err(ProtocolError::UnknownVersionMismatch {
110 method: "IdentityPublicKey::random_authentication_key_with_rng".to_string(),
111 known_versions: vec![0],
112 received: version,
113 }),
114 }
115 }
116
117 /// Generates a random authentication key and its corresponding private key based on the platform version.
118 ///
119 /// # Parameters
120 ///
121 /// * `id`: The `KeyID` for the generated key.
122 /// * `seed`: A seed that will create a random number generator `StdRng`.
123 /// * `used_key_matrix`: An optional tuple that contains the count of keys that have already been used
124 /// and a mutable reference to a matrix (or vector) that tracks which keys have been used.
125 /// * `platform_version`: The platform version which determines the structure of the identity key.
126 ///
127 /// # Returns
128 ///
129 /// * `Result<(Self, Vec<u8>), ProtocolError>`: If successful, returns an instance of `Self` and the private key as `Vec<u8>`.
130 /// In case of an error, it returns a `ProtocolError`.
131 ///
132 /// # Errors
133 ///
134 /// * `ProtocolError::PublicKeyGenerationError`: This error is returned if too many keys have already been created.
135 /// * `ProtocolError::UnknownVersionMismatch`: This error is returned if the provided platform version is not recognized.
136 ///
137 pub fn random_authentication_key_with_private_key(
138 id: KeyID,
139 seed: Option<u64>,
140 platform_version: &PlatformVersion,
141 ) -> Result<(Self, [u8; 32]), ProtocolError> {
142 let mut rng = match seed {
143 None => StdRng::from_entropy(),
144 Some(seed_value) => StdRng::seed_from_u64(seed_value),
145 };
146 Self::random_authentication_key_with_private_key_with_rng(
147 id,
148 &mut rng,
149 None,
150 platform_version,
151 )
152 }
153
154 /// Generates a random authentication key and its corresponding private key based on the platform version.
155 ///
156 /// # Parameters
157 ///
158 /// * `id`: The `KeyID` for the generated key.
159 /// * `rng`: A mutable reference to a random number generator of type `StdRng`.
160 /// * `used_key_matrix`: An optional tuple that contains the count of keys that have already been used
161 /// and a mutable reference to a matrix (or vector) that tracks which keys have been used.
162 /// * `platform_version`: The platform version which determines the structure of the identity key.
163 ///
164 /// # Returns
165 ///
166 /// * `Result<(Self, Vec<u8>), ProtocolError>`: If successful, returns an instance of `Self` and the private key as `Vec<u8>`.
167 /// In case of an error, it returns a `ProtocolError`.
168 ///
169 /// # Errors
170 ///
171 /// * `ProtocolError::PublicKeyGenerationError`: This error is returned if too many keys have already been created.
172 /// * `ProtocolError::UnknownVersionMismatch`: This error is returned if the provided platform version is not recognized.
173 ///
174 pub fn random_authentication_key_with_private_key_with_rng(
175 id: KeyID,
176 rng: &mut StdRng,
177 used_key_matrix: Option<(KeyCount, &mut UsedKeyMatrix)>,
178 platform_version: &PlatformVersion,
179 ) -> Result<(Self, [u8; 32]), ProtocolError> {
180 match platform_version
181 .dpp
182 .identity_versions
183 .identity_key_structure_version
184 {
185 0 => IdentityPublicKeyV0::random_authentication_key_with_private_key_with_rng(
186 id,
187 rng,
188 used_key_matrix,
189 platform_version,
190 )
191 .map(|(key, private_key)| (key.into(), private_key)),
192 version => Err(ProtocolError::UnknownVersionMismatch {
193 method: "IdentityPublicKey::random_authentication_key_with_private_key_with_rng"
194 .to_string(),
195 known_versions: vec![0],
196 received: version,
197 }),
198 }
199 }
200
201 /// Generates a random key based on the platform version.
202 ///
203 /// # Parameters
204 ///
205 /// * `id`: The `KeyID` for the generated key.
206 /// * `rng`: A mutable reference to a random number generator of type `StdRng`.
207 /// * `used_key_matrix`: An optional tuple that contains the count of keys that have already been used
208 /// and a mutable reference to a matrix (or vector) that tracks which keys have been used.
209 /// * `platform_version`: The platform version which determines the structure of the identity key.
210 ///
211 /// # Returns
212 ///
213 /// * `Result<Self, ProtocolError>`: If successful, returns an instance of `Self`.
214 /// In case of an error, it returns a `ProtocolError`.
215 ///
216 /// # Errors
217 ///
218 /// * `ProtocolError::PublicKeyGenerationError`: This error is returned if too many keys have already been created.
219 /// * `ProtocolError::UnknownVersionMismatch`: This error is returned if the provided platform version is not recognized.
220 ///
221 pub fn random_key_with_rng(
222 id: KeyID,
223 rng: &mut StdRng,
224 used_key_matrix: Option<(KeyCount, &mut UsedKeyMatrix)>,
225 platform_version: &PlatformVersion,
226 ) -> Result<Self, ProtocolError> {
227 match platform_version
228 .dpp
229 .identity_versions
230 .identity_key_structure_version
231 {
232 0 => Ok(IdentityPublicKeyV0::random_key_with_rng(
233 id,
234 rng,
235 used_key_matrix,
236 platform_version,
237 )?
238 .into()),
239 version => Err(ProtocolError::UnknownVersionMismatch {
240 method: "IdentityPublicKey::random_key_with_rng".to_string(),
241 known_versions: vec![0],
242 received: version,
243 }),
244 }
245 }
246
247 /// Generates a random key based on the platform version.
248 ///
249 /// # Parameters
250 ///
251 /// * `id`: The `KeyID` for the generated key.
252 /// * `rng`: A mutable reference to a random number generator of type `StdRng`.
253 /// * `used_key_matrix`: An optional tuple that contains the count of keys that have already been used
254 /// and a mutable reference to a matrix (or vector) that tracks which keys have been used.
255 /// * `platform_version`: The platform version which determines the structure of the identity key.
256 ///
257 /// # Returns
258 ///
259 /// * `Result<Self, ProtocolError>`: If successful, returns an instance of `Self`.
260 /// In case of an error, it returns a `ProtocolError`.
261 ///
262 /// # Errors
263 ///
264 /// * `ProtocolError::PublicKeyGenerationError`: This error is returned if too many keys have already been created.
265 /// * `ProtocolError::UnknownVersionMismatch`: This error is returned if the provided platform version is not recognized.
266 ///
267 pub fn random_key_with_known_attributes(
268 id: KeyID,
269 rng: &mut StdRng,
270 purpose: Purpose,
271 security_level: SecurityLevel,
272 key_type: KeyType,
273 contract_bounds: Option<ContractBounds>,
274 platform_version: &PlatformVersion,
275 ) -> Result<(Self, [u8; 32]), ProtocolError> {
276 match platform_version
277 .dpp
278 .identity_versions
279 .identity_key_structure_version
280 {
281 0 => {
282 let (key, private_key) = IdentityPublicKeyV0::random_key_with_known_attributes(
283 id,
284 rng,
285 purpose,
286 security_level,
287 key_type,
288 contract_bounds,
289 platform_version,
290 )?;
291 Ok((key.into(), private_key))
292 }
293 version => Err(ProtocolError::UnknownVersionMismatch {
294 method: "IdentityPublicKey::random_key_with_known_attributes".to_string(),
295 known_versions: vec![0],
296 received: version,
297 }),
298 }
299 }
300
301 /// Generates a random ECDSA master authentication public key along with its corresponding private key.
302 ///
303 /// This method constructs a random ECDSA (using the secp256k1 curve) master authentication public key
304 /// and returns both the public key and its corresponding private key.
305 ///
306 /// # Parameters
307 ///
308 /// * `id`: The `KeyID` for the generated key.
309 /// * `rng`: A mutable reference to the random number generator.
310 ///
311 /// # Returns
312 ///
313 /// * `(Self, Vec<u8>)`: A tuple where the first element is an instance of the `IdentityPublicKey` struct,
314 /// and the second element is the corresponding private key.
315 ///
316 pub fn random_ecdsa_master_authentication_key_with_rng(
317 id: KeyID,
318 rng: &mut StdRng,
319 platform_version: &PlatformVersion,
320 ) -> Result<(Self, [u8; 32]), ProtocolError> {
321 match platform_version
322 .dpp
323 .identity_versions
324 .identity_key_structure_version
325 {
326 0 => {
327 let (key, private_key) =
328 IdentityPublicKeyV0::random_ecdsa_master_authentication_key_with_rng(
329 id,
330 rng,
331 platform_version,
332 )?;
333 Ok((key.into(), private_key))
334 }
335 version => Err(ProtocolError::UnknownVersionMismatch {
336 method: "IdentityPublicKey::random_ecdsa_master_authentication_key_with_rng"
337 .to_string(),
338 known_versions: vec![0],
339 received: version,
340 }),
341 }
342 }
343
344 pub fn random_voting_key_with_rng(
345 id: KeyID,
346 rng: &mut StdRng,
347 platform_version: &PlatformVersion,
348 ) -> Result<(Self, [u8; 32]), ProtocolError> {
349 match platform_version
350 .dpp
351 .identity_versions
352 .identity_key_structure_version
353 {
354 0 => {
355 let (key, private_key) =
356 IdentityPublicKeyV0::random_voting_key_with_rng(id, rng, platform_version)?;
357 Ok((key.into(), private_key))
358 }
359 version => Err(ProtocolError::UnknownVersionMismatch {
360 method: "IdentityPublicKey::random_voting_key_with_rng".to_string(),
361 known_versions: vec![0],
362 received: version,
363 }),
364 }
365 }
366
367 /// Generates a random ECDSA master-level authentication public key along with its corresponding private key.
368 ///
369 /// This method constructs a random ECDSA (using the secp256k1 curve) high-level authentication public key
370 /// and returns both the public key and its corresponding private key.
371 ///
372 /// # Parameters
373 ///
374 /// * `id`: The `KeyID` for the generated key.
375 /// * `seed`: A seed that will create a random number generator `StdRng`.
376 ///
377 /// # Returns
378 ///
379 /// * `(Self, Vec<u8>)`: A tuple where the first element is an instance of the `IdentityPublicKey` struct,
380 /// and the second element is the corresponding private key.
381 ///
382 pub fn random_ecdsa_master_authentication_key(
383 id: KeyID,
384 seed: Option<u64>,
385 platform_version: &PlatformVersion,
386 ) -> Result<(Self, [u8; 32]), ProtocolError> {
387 let mut rng = match seed {
388 None => StdRng::from_entropy(),
389 Some(seed_value) => StdRng::seed_from_u64(seed_value),
390 };
391 Self::random_ecdsa_master_authentication_key_with_rng(id, &mut rng, platform_version)
392 }
393
394 /// Generates a random ECDSA critical-level authentication public key along with its corresponding private key.
395 ///
396 /// This method constructs a random ECDSA (using the secp256k1 curve) high-level authentication public key
397 /// and returns both the public key and its corresponding private key.
398 ///
399 /// # Parameters
400 ///
401 /// * `id`: The `KeyID` for the generated key.
402 /// * `seed`: A seed that will create a random number generator `StdRng`.
403 ///
404 /// # Returns
405 ///
406 /// * `(Self, Vec<u8>)`: A tuple where the first element is an instance of the `IdentityPublicKey` struct,
407 /// and the second element is the corresponding private key.
408 ///
409 pub fn random_ecdsa_critical_level_authentication_key(
410 id: KeyID,
411 seed: Option<u64>,
412 platform_version: &PlatformVersion,
413 ) -> Result<(Self, [u8; 32]), ProtocolError> {
414 let mut rng = match seed {
415 None => StdRng::from_entropy(),
416 Some(seed_value) => StdRng::seed_from_u64(seed_value),
417 };
418 Self::random_ecdsa_critical_level_authentication_key_with_rng(
419 id,
420 &mut rng,
421 platform_version,
422 )
423 }
424
425 /// Generates a random ECDSA high-level authentication public key along with its corresponding private key.
426 ///
427 /// This method constructs a random ECDSA (using the secp256k1 curve) high-level authentication public key
428 /// and returns both the public key and its corresponding private key.
429 ///
430 /// # Parameters
431 ///
432 /// * `id`: The `KeyID` for the generated key.
433 /// * `rng`: A mutable reference to the random number generator.
434 ///
435 /// # Returns
436 ///
437 /// * `(Self, Vec<u8>)`: A tuple where the first element is an instance of the `IdentityPublicKey` struct,
438 /// and the second element is the corresponding private key.
439 ///
440 pub fn random_ecdsa_critical_level_authentication_key_with_rng(
441 id: KeyID,
442 rng: &mut StdRng,
443 platform_version: &PlatformVersion,
444 ) -> Result<(Self, [u8; 32]), ProtocolError> {
445 match platform_version
446 .dpp
447 .identity_versions
448 .identity_key_structure_version
449 {
450 0 => {
451 let (key, private_key) =
452 IdentityPublicKeyV0::random_ecdsa_critical_level_authentication_key_with_rng(
453 id,
454 rng,
455 platform_version,
456 )?;
457 Ok((key.into(), private_key))
458 }
459 version => Err(ProtocolError::UnknownVersionMismatch {
460 method:
461 "IdentityPublicKey::random_ecdsa_critical_level_authentication_key_with_rng"
462 .to_string(),
463 known_versions: vec![0],
464 received: version,
465 }),
466 }
467 }
468
469 /// Generates a random ECDSA critical-level authentication key for a masternode owner.
470 ///
471 /// This function generates a random key that can be used for owner authentication in a masternode context.
472 /// The function accepts an optional seed for deterministic key generation, or uses entropy-based randomness if no seed is provided.
473 ///
474 /// # Parameters
475 ///
476 /// * `id`: The identifier (`KeyID`) for the masternode owner key.
477 /// * `seed`: An optional `u64` value used to seed the random number generator. If `None`, the RNG will be seeded from entropy.
478 /// * `platform_version`: A reference to the `PlatformVersion` struct, which is used to determine the correct key structure version.
479 ///
480 /// # Returns
481 ///
482 /// Returns a tuple containing the generated `IdentityPublicKey` for the masternode owner and the corresponding private key as a byte vector.
483 ///
484 /// # Errors
485 ///
486 /// Returns a `ProtocolError` if the platform version is not supported.
487 pub fn random_masternode_owner_key(
488 id: KeyID,
489 seed: Option<u64>,
490 platform_version: &PlatformVersion,
491 ) -> Result<(Self, [u8; 32]), ProtocolError> {
492 let mut rng = match seed {
493 None => StdRng::from_entropy(),
494 Some(seed_value) => StdRng::seed_from_u64(seed_value),
495 };
496 Self::random_masternode_owner_key_with_rng(id, &mut rng, platform_version)
497 }
498
499 /// Generates a random ECDSA critical-level authentication key for a masternode owner using a custom RNG.
500 ///
501 /// This function generates a random key using a given random number generator (RNG). This is useful when specific control over the randomness is needed.
502 ///
503 /// # Parameters
504 ///
505 /// * `id`: The identifier (`KeyID`) for the masternode owner key.
506 /// * `rng`: A mutable reference to a `StdRng` instance used to generate randomness.
507 /// * `platform_version`: A reference to the `PlatformVersion` struct, which is used to determine the correct key structure version.
508 ///
509 /// # Returns
510 ///
511 /// Returns a tuple containing the generated `IdentityPublicKey` for the masternode owner and the corresponding private key as a byte vector.
512 ///
513 /// # Errors
514 ///
515 /// Returns a `ProtocolError` if the platform version is not supported.
516 pub fn random_masternode_owner_key_with_rng(
517 id: KeyID,
518 rng: &mut StdRng,
519 platform_version: &PlatformVersion,
520 ) -> Result<(Self, [u8; 32]), ProtocolError> {
521 match platform_version
522 .dpp
523 .identity_versions
524 .identity_key_structure_version
525 {
526 0 => {
527 let (key, private_key) =
528 IdentityPublicKeyV0::random_owner_key_with_rng(id, rng, platform_version)?;
529 Ok((key.into(), private_key))
530 }
531 version => Err(ProtocolError::UnknownVersionMismatch {
532 method: "IdentityPublicKey::random_masternode_owner_key_with_rng".to_string(),
533 known_versions: vec![0],
534 received: version,
535 }),
536 }
537 }
538
539 /// Generates a random ECDSA critical-level transfer key for a masternode.
540 ///
541 /// This function generates a random key for use in transferring ownership of a masternode. An optional seed can be provided for deterministic key generation, or entropy-based randomness is used if no seed is given.
542 ///
543 /// # Parameters
544 ///
545 /// * `id`: The identifier (`KeyID`) for the masternode transfer key.
546 /// * `seed`: An optional `u64` value used to seed the random number generator. If `None`, the RNG will be seeded from entropy.
547 /// * `platform_version`: A reference to the `PlatformVersion` struct, which is used to determine the correct key structure version.
548 ///
549 /// # Returns
550 ///
551 /// Returns a tuple containing the generated `IdentityPublicKey` for the masternode transfer key and the corresponding private key as a byte vector.
552 ///
553 /// # Errors
554 ///
555 /// Returns a `ProtocolError` if the platform version is not supported.
556 pub fn random_masternode_transfer_key(
557 id: KeyID,
558 seed: Option<u64>,
559 platform_version: &PlatformVersion,
560 ) -> Result<(Self, [u8; 32]), ProtocolError> {
561 let mut rng = match seed {
562 None => StdRng::from_entropy(),
563 Some(seed_value) => StdRng::seed_from_u64(seed_value),
564 };
565 Self::random_masternode_transfer_key_with_rng(id, &mut rng, platform_version)
566 }
567
568 /// Generates a random ECDSA critical-level transfer key for a masternode using a custom RNG.
569 ///
570 /// This function generates a random key for masternode transfers using a given random number generator (RNG).
571 ///
572 /// # Parameters
573 ///
574 /// * `id`: The identifier (`KeyID`) for the masternode transfer key.
575 /// * `rng`: A mutable reference to a `StdRng` instance used to generate randomness.
576 /// * `platform_version`: A reference to the `PlatformVersion` struct, which is used to determine the correct key structure version.
577 ///
578 /// # Returns
579 ///
580 /// Returns a tuple containing the generated `IdentityPublicKey` for the masternode transfer key and the corresponding private key as a byte vector.
581 ///
582 /// # Errors
583 ///
584 /// Returns a `ProtocolError` if the platform version is not supported.
585 pub fn random_masternode_transfer_key_with_rng(
586 id: KeyID,
587 rng: &mut StdRng,
588 platform_version: &PlatformVersion,
589 ) -> Result<(Self, [u8; 32]), ProtocolError> {
590 match platform_version
591 .dpp
592 .identity_versions
593 .identity_key_structure_version
594 {
595 0 => {
596 let (key, private_key) =
597 IdentityPublicKeyV0::random_masternode_transfer_key_with_rng(
598 id,
599 rng,
600 platform_version,
601 )?;
602 Ok((key.into(), private_key))
603 }
604 version => Err(ProtocolError::UnknownVersionMismatch {
605 method: "IdentityPublicKey::random_masternode_transfer_key_with_rng".to_string(),
606 known_versions: vec![0],
607 received: version,
608 }),
609 }
610 }
611
612 /// Generates a random ECDSA high-level authentication public key along with its corresponding private key.
613 ///
614 /// This method constructs a random ECDSA (using the secp256k1 curve) high-level authentication public key
615 /// and returns both the public key and its corresponding private key.
616 ///
617 /// # Parameters
618 ///
619 /// * `id`: The `KeyID` for the generated key.
620 /// * `seed`: A seed that will create a random number generator `StdRng`.
621 ///
622 /// # Returns
623 ///
624 /// * `(Self, Vec<u8>)`: A tuple where the first element is an instance of the `IdentityPublicKey` struct,
625 /// and the second element is the corresponding private key.
626 ///
627 pub fn random_ecdsa_high_level_authentication_key(
628 id: KeyID,
629 seed: Option<u64>,
630 platform_version: &PlatformVersion,
631 ) -> Result<(Self, [u8; 32]), ProtocolError> {
632 let mut rng = match seed {
633 None => StdRng::from_entropy(),
634 Some(seed_value) => StdRng::seed_from_u64(seed_value),
635 };
636 Self::random_ecdsa_high_level_authentication_key_with_rng(id, &mut rng, platform_version)
637 }
638
639 /// Generates a random ECDSA high-level authentication public key along with its corresponding private key.
640 ///
641 /// This method constructs a random ECDSA (using the secp256k1 curve) high-level authentication public key
642 /// and returns both the public key and its corresponding private key.
643 ///
644 /// # Parameters
645 ///
646 /// * `id`: The `KeyID` for the generated key.
647 /// * `rng`: A mutable reference to the random number generator.
648 ///
649 /// # Returns
650 ///
651 /// * `(Self, Vec<u8>)`: A tuple where the first element is an instance of the `IdentityPublicKey` struct,
652 /// and the second element is the corresponding private key.
653 ///
654 pub fn random_ecdsa_high_level_authentication_key_with_rng(
655 id: KeyID,
656 rng: &mut StdRng,
657 platform_version: &PlatformVersion,
658 ) -> Result<(Self, [u8; 32]), ProtocolError> {
659 match platform_version
660 .dpp
661 .identity_versions
662 .identity_key_structure_version
663 {
664 0 => {
665 let (key, private_key) =
666 IdentityPublicKeyV0::random_ecdsa_high_level_authentication_key_with_rng(
667 id,
668 rng,
669 platform_version,
670 )?;
671 Ok((key.into(), private_key))
672 }
673 version => Err(ProtocolError::UnknownVersionMismatch {
674 method: "IdentityPublicKey::random_ecdsa_high_level_authentication_key_with_rng"
675 .to_string(),
676 known_versions: vec![0],
677 received: version,
678 }),
679 }
680 }
681
682 pub fn random_authentication_keys_with_rng(
683 key_count: KeyCount,
684 rng: &mut StdRng,
685 platform_version: &PlatformVersion,
686 ) -> Result<Vec<Self>, ProtocolError> {
687 let mut used_key_matrix = [false; 16].to_vec();
688 (0..key_count)
689 .map(|i| {
690 Self::random_authentication_key_with_rng(
691 i,
692 rng,
693 Some((i, &mut used_key_matrix)),
694 platform_version,
695 )
696 })
697 .collect()
698 }
699
700 pub fn random_authentication_keys_with_private_keys_with_rng(
701 start_id: KeyID,
702 key_count: KeyCount,
703 rng: &mut StdRng,
704 platform_version: &PlatformVersion,
705 ) -> Result<Vec<(Self, [u8; 32])>, ProtocolError> {
706 (start_id..(start_id + key_count))
707 .map(|i| {
708 Self::random_authentication_key_with_private_key_with_rng(
709 i,
710 rng,
711 None,
712 platform_version,
713 )
714 })
715 .collect()
716 }
717
718 pub fn main_keys_with_random_authentication_keys_with_private_keys_with_rng(
719 key_count: KeyCount,
720 rng: &mut StdRng,
721 platform_version: &PlatformVersion,
722 ) -> Result<Vec<(Self, [u8; 32])>, ProtocolError> {
723 if key_count < 2 {
724 return Err(ProtocolError::PublicKeyGenerationError(
725 "at least 2 keys must be created".to_string(),
726 ));
727 }
728 //create a master and a high level key
729 let mut main_keys = if key_count == 2 {
730 vec![
731 Self::random_ecdsa_master_authentication_key_with_rng(0, rng, platform_version)?,
732 Self::random_ecdsa_high_level_authentication_key_with_rng(
733 1,
734 rng,
735 platform_version,
736 )?,
737 ]
738 } else {
739 vec![
740 Self::random_ecdsa_master_authentication_key_with_rng(0, rng, platform_version)?,
741 Self::random_ecdsa_critical_level_authentication_key_with_rng(
742 1,
743 rng,
744 platform_version,
745 )?,
746 Self::random_ecdsa_high_level_authentication_key_with_rng(
747 2,
748 rng,
749 platform_version,
750 )?,
751 ]
752 };
753 let mut used_key_matrix = [false; 16].to_vec();
754 used_key_matrix[0] = true;
755 used_key_matrix[1] = true;
756 used_key_matrix[2] = true;
757 used_key_matrix[4] = true; //also a master key
758 used_key_matrix[8] = true; //also a master key
759 used_key_matrix[12] = true; //also a master key
760 main_keys.extend((3..key_count).map(|i| {
761 Self::random_authentication_key_with_private_key_with_rng(
762 i,
763 rng,
764 Some((i, &mut used_key_matrix)),
765 platform_version,
766 )
767 .unwrap()
768 }));
769 Ok(main_keys)
770 }
771
772 pub fn random_unique_keys_with_rng(
773 key_count: KeyCount,
774 rng: &mut StdRng,
775 platform_version: &PlatformVersion,
776 ) -> Result<Vec<Self>, ProtocolError> {
777 let mut keys = [false; 64].to_vec();
778 (0..key_count)
779 .map(|i| Self::random_key_with_rng(i, rng, Some((i, &mut keys)), platform_version))
780 .collect()
781 }
782
783 pub fn random_keys_with_rng(
784 key_count: KeyCount,
785 rng: &mut StdRng,
786 platform_version: &PlatformVersion,
787 ) -> Vec<Self> {
788 (0..key_count)
789 .map(|i| Self::random_key_with_rng(i, rng, None, platform_version).unwrap())
790 .collect()
791 }
792}