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}