referrerpolicy=no-referrer-when-downgrade

sp_keystore/
testing.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: Apache-2.0
5
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// 	http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18//! Types that should only be used for testing!
19
20use crate::{Error, Keystore, KeystorePtr};
21
22#[cfg(feature = "bandersnatch-experimental")]
23use sp_core::bandersnatch;
24#[cfg(feature = "bls-experimental")]
25use sp_core::{
26	bls381, ecdsa_bls381, proof_of_possession::ProofOfPossessionGenerator, KeccakHasher,
27};
28use sp_core::{
29	crypto::{ByteArray, KeyTypeId, Pair, VrfSecret},
30	ecdsa, ed25519, sr25519,
31};
32
33use parking_lot::RwLock;
34use std::{collections::HashMap, sync::Arc};
35
36/// A keystore implementation usable in tests.
37#[derive(Default, Clone)]
38pub struct MemoryKeystore {
39	/// `KeyTypeId` maps to public keys and public keys map to private keys.
40	keys: Arc<RwLock<HashMap<KeyTypeId, HashMap<Vec<u8>, String>>>>,
41}
42
43impl MemoryKeystore {
44	/// Creates a new instance of `Self`.
45	pub fn new() -> Self {
46		Self::default()
47	}
48
49	fn pair<T: Pair>(&self, key_type: KeyTypeId, public: &T::Public) -> Option<T> {
50		self.keys.read().get(&key_type).and_then(|inner| {
51			inner
52				.get(public.as_slice())
53				.map(|s| T::from_string(s, None).expect("seed slice is valid"))
54		})
55	}
56
57	fn public_keys<T: Pair>(&self, key_type: KeyTypeId) -> Vec<T::Public> {
58		self.keys
59			.read()
60			.get(&key_type)
61			.map(|keys| {
62				keys.iter()
63					.filter_map(|(raw_pubkey, s)| {
64						let pair = T::from_string(s, None).expect("seed slice is valid");
65						let pubkey = pair.public();
66						(pubkey.as_slice() == raw_pubkey).then_some(pubkey)
67					})
68					.collect()
69			})
70			.unwrap_or_default()
71	}
72
73	fn generate_new<T: Pair>(
74		&self,
75		key_type: KeyTypeId,
76		seed: Option<&str>,
77	) -> Result<T::Public, Error> {
78		match seed {
79			Some(seed) => {
80				let pair = T::from_string(seed, None)
81					.map_err(|_| Error::ValidationError("Generates a pair.".to_owned()))?;
82				self.keys
83					.write()
84					.entry(key_type)
85					.or_default()
86					.insert(pair.public().to_raw_vec(), seed.into());
87				Ok(pair.public())
88			},
89			None => {
90				let (pair, phrase, _) = T::generate_with_phrase(None);
91				self.keys
92					.write()
93					.entry(key_type)
94					.or_default()
95					.insert(pair.public().to_raw_vec(), phrase);
96				Ok(pair.public())
97			},
98		}
99	}
100
101	fn sign<T: Pair>(
102		&self,
103		key_type: KeyTypeId,
104		public: &T::Public,
105		msg: &[u8],
106	) -> Result<Option<T::Signature>, Error> {
107		let sig = self.pair::<T>(key_type, public).map(|pair| pair.sign(msg));
108		Ok(sig)
109	}
110
111	fn vrf_sign<T: Pair + VrfSecret>(
112		&self,
113		key_type: KeyTypeId,
114		public: &T::Public,
115		data: &T::VrfSignData,
116	) -> Result<Option<T::VrfSignature>, Error> {
117		let sig = self.pair::<T>(key_type, public).map(|pair| pair.vrf_sign(data));
118		Ok(sig)
119	}
120
121	fn vrf_pre_output<T: Pair + VrfSecret>(
122		&self,
123		key_type: KeyTypeId,
124		public: &T::Public,
125		input: &T::VrfInput,
126	) -> Result<Option<T::VrfPreOutput>, Error> {
127		let pre_output = self.pair::<T>(key_type, public).map(|pair| pair.vrf_pre_output(input));
128		Ok(pre_output)
129	}
130
131	#[cfg(feature = "bls-experimental")]
132	fn generate_proof_of_possession<T: Pair + ProofOfPossessionGenerator>(
133		&self,
134		key_type: KeyTypeId,
135		public: &T::Public,
136	) -> Result<Option<T::Signature>, Error> {
137		let proof_of_possession = self
138			.pair::<T>(key_type, public)
139			.map(|mut pair| pair.generate_proof_of_possession());
140		Ok(proof_of_possession)
141	}
142}
143
144impl Keystore for MemoryKeystore {
145	fn sr25519_public_keys(&self, key_type: KeyTypeId) -> Vec<sr25519::Public> {
146		self.public_keys::<sr25519::Pair>(key_type)
147	}
148
149	fn sr25519_generate_new(
150		&self,
151		key_type: KeyTypeId,
152		seed: Option<&str>,
153	) -> Result<sr25519::Public, Error> {
154		self.generate_new::<sr25519::Pair>(key_type, seed)
155	}
156
157	fn sr25519_sign(
158		&self,
159		key_type: KeyTypeId,
160		public: &sr25519::Public,
161		msg: &[u8],
162	) -> Result<Option<sr25519::Signature>, Error> {
163		self.sign::<sr25519::Pair>(key_type, public, msg)
164	}
165
166	fn sr25519_vrf_sign(
167		&self,
168		key_type: KeyTypeId,
169		public: &sr25519::Public,
170		data: &sr25519::vrf::VrfSignData,
171	) -> Result<Option<sr25519::vrf::VrfSignature>, Error> {
172		self.vrf_sign::<sr25519::Pair>(key_type, public, data)
173	}
174
175	fn sr25519_vrf_pre_output(
176		&self,
177		key_type: KeyTypeId,
178		public: &sr25519::Public,
179		input: &sr25519::vrf::VrfInput,
180	) -> Result<Option<sr25519::vrf::VrfPreOutput>, Error> {
181		self.vrf_pre_output::<sr25519::Pair>(key_type, public, input)
182	}
183
184	fn ed25519_public_keys(&self, key_type: KeyTypeId) -> Vec<ed25519::Public> {
185		self.public_keys::<ed25519::Pair>(key_type)
186	}
187
188	fn ed25519_generate_new(
189		&self,
190		key_type: KeyTypeId,
191		seed: Option<&str>,
192	) -> Result<ed25519::Public, Error> {
193		self.generate_new::<ed25519::Pair>(key_type, seed)
194	}
195
196	fn ed25519_sign(
197		&self,
198		key_type: KeyTypeId,
199		public: &ed25519::Public,
200		msg: &[u8],
201	) -> Result<Option<ed25519::Signature>, Error> {
202		self.sign::<ed25519::Pair>(key_type, public, msg)
203	}
204
205	fn ecdsa_public_keys(&self, key_type: KeyTypeId) -> Vec<ecdsa::Public> {
206		self.public_keys::<ecdsa::Pair>(key_type)
207	}
208
209	fn ecdsa_generate_new(
210		&self,
211		key_type: KeyTypeId,
212		seed: Option<&str>,
213	) -> Result<ecdsa::Public, Error> {
214		self.generate_new::<ecdsa::Pair>(key_type, seed)
215	}
216
217	fn ecdsa_sign(
218		&self,
219		key_type: KeyTypeId,
220		public: &ecdsa::Public,
221		msg: &[u8],
222	) -> Result<Option<ecdsa::Signature>, Error> {
223		self.sign::<ecdsa::Pair>(key_type, public, msg)
224	}
225
226	fn ecdsa_sign_prehashed(
227		&self,
228		key_type: KeyTypeId,
229		public: &ecdsa::Public,
230		msg: &[u8; 32],
231	) -> Result<Option<ecdsa::Signature>, Error> {
232		let sig = self.pair::<ecdsa::Pair>(key_type, public).map(|pair| pair.sign_prehashed(msg));
233		Ok(sig)
234	}
235
236	#[cfg(feature = "bandersnatch-experimental")]
237	fn bandersnatch_public_keys(&self, key_type: KeyTypeId) -> Vec<bandersnatch::Public> {
238		self.public_keys::<bandersnatch::Pair>(key_type)
239	}
240
241	#[cfg(feature = "bandersnatch-experimental")]
242	fn bandersnatch_generate_new(
243		&self,
244		key_type: KeyTypeId,
245		seed: Option<&str>,
246	) -> Result<bandersnatch::Public, Error> {
247		self.generate_new::<bandersnatch::Pair>(key_type, seed)
248	}
249
250	#[cfg(feature = "bandersnatch-experimental")]
251	fn bandersnatch_sign(
252		&self,
253		key_type: KeyTypeId,
254		public: &bandersnatch::Public,
255		msg: &[u8],
256	) -> Result<Option<bandersnatch::Signature>, Error> {
257		self.sign::<bandersnatch::Pair>(key_type, public, msg)
258	}
259
260	#[cfg(feature = "bandersnatch-experimental")]
261	fn bandersnatch_vrf_sign(
262		&self,
263		key_type: KeyTypeId,
264		public: &bandersnatch::Public,
265		data: &bandersnatch::vrf::VrfSignData,
266	) -> Result<Option<bandersnatch::vrf::VrfSignature>, Error> {
267		self.vrf_sign::<bandersnatch::Pair>(key_type, public, data)
268	}
269
270	#[cfg(feature = "bandersnatch-experimental")]
271	fn bandersnatch_ring_vrf_sign(
272		&self,
273		key_type: KeyTypeId,
274		public: &bandersnatch::Public,
275		data: &bandersnatch::vrf::VrfSignData,
276		prover: &bandersnatch::ring_vrf::RingProver,
277	) -> Result<Option<bandersnatch::ring_vrf::RingVrfSignature>, Error> {
278		let sig = self
279			.pair::<bandersnatch::Pair>(key_type, public)
280			.map(|pair| pair.ring_vrf_sign(data, prover));
281		Ok(sig)
282	}
283
284	#[cfg(feature = "bandersnatch-experimental")]
285	fn bandersnatch_vrf_pre_output(
286		&self,
287		key_type: KeyTypeId,
288		public: &bandersnatch::Public,
289		input: &bandersnatch::vrf::VrfInput,
290	) -> Result<Option<bandersnatch::vrf::VrfPreOutput>, Error> {
291		self.vrf_pre_output::<bandersnatch::Pair>(key_type, public, input)
292	}
293
294	#[cfg(feature = "bls-experimental")]
295	fn bls381_public_keys(&self, key_type: KeyTypeId) -> Vec<bls381::Public> {
296		self.public_keys::<bls381::Pair>(key_type)
297	}
298
299	#[cfg(feature = "bls-experimental")]
300	fn bls381_generate_new(
301		&self,
302		key_type: KeyTypeId,
303		seed: Option<&str>,
304	) -> Result<bls381::Public, Error> {
305		self.generate_new::<bls381::Pair>(key_type, seed)
306	}
307
308	#[cfg(feature = "bls-experimental")]
309	fn bls381_sign(
310		&self,
311		key_type: KeyTypeId,
312		public: &bls381::Public,
313		msg: &[u8],
314	) -> Result<Option<bls381::Signature>, Error> {
315		self.sign::<bls381::Pair>(key_type, public, msg)
316	}
317
318	#[cfg(feature = "bls-experimental")]
319	fn bls381_generate_proof_of_possession(
320		&self,
321		key_type: KeyTypeId,
322		public: &bls381::Public,
323	) -> Result<Option<bls381::Signature>, Error> {
324		self.generate_proof_of_possession::<bls381::Pair>(key_type, public)
325	}
326
327	#[cfg(feature = "bls-experimental")]
328	fn ecdsa_bls381_public_keys(&self, key_type: KeyTypeId) -> Vec<ecdsa_bls381::Public> {
329		self.public_keys::<ecdsa_bls381::Pair>(key_type)
330	}
331
332	#[cfg(feature = "bls-experimental")]
333	fn ecdsa_bls381_generate_new(
334		&self,
335		key_type: KeyTypeId,
336		seed: Option<&str>,
337	) -> Result<ecdsa_bls381::Public, Error> {
338		let pubkey = self.generate_new::<ecdsa_bls381::Pair>(key_type, seed)?;
339
340		let s: String = self
341			.keys
342			.read()
343			.get(&key_type)
344			.and_then(|inner| inner.get(pubkey.as_slice()).map(|s| s.to_string()))
345			.expect("Can Retrieve Seed");
346
347		// This is done to give the keystore access to individual keys, this is necessary to avoid
348		// redundant host functions for paired keys and re-use host functions implemented for each
349		// element of the pair.
350		self.generate_new::<ecdsa::Pair>(key_type, Some(&s))
351			.expect("seed slice is valid");
352		self.generate_new::<bls381::Pair>(key_type, Some(&s))
353			.expect("seed slice is valid");
354
355		Ok(pubkey)
356	}
357
358	#[cfg(feature = "bls-experimental")]
359	fn ecdsa_bls381_sign(
360		&self,
361		key_type: KeyTypeId,
362		public: &ecdsa_bls381::Public,
363		msg: &[u8],
364	) -> Result<Option<ecdsa_bls381::Signature>, Error> {
365		self.sign::<ecdsa_bls381::Pair>(key_type, public, msg)
366	}
367
368	#[cfg(feature = "bls-experimental")]
369	fn ecdsa_bls381_sign_with_keccak256(
370		&self,
371		key_type: KeyTypeId,
372		public: &ecdsa_bls381::Public,
373		msg: &[u8],
374	) -> Result<Option<ecdsa_bls381::Signature>, Error> {
375		let sig = self
376			.pair::<ecdsa_bls381::Pair>(key_type, public)
377			.map(|pair| pair.sign_with_hasher::<KeccakHasher>(msg));
378		Ok(sig)
379	}
380
381	fn insert(&self, key_type: KeyTypeId, suri: &str, public: &[u8]) -> Result<(), ()> {
382		self.keys
383			.write()
384			.entry(key_type)
385			.or_default()
386			.insert(public.to_owned(), suri.to_string());
387		Ok(())
388	}
389
390	fn keys(&self, key_type: KeyTypeId) -> Result<Vec<Vec<u8>>, Error> {
391		let keys = self
392			.keys
393			.read()
394			.get(&key_type)
395			.map(|map| map.keys().cloned().collect())
396			.unwrap_or_default();
397		Ok(keys)
398	}
399
400	fn has_keys(&self, public_keys: &[(Vec<u8>, KeyTypeId)]) -> bool {
401		public_keys
402			.iter()
403			.all(|(k, t)| self.keys.read().get(t).and_then(|s| s.get(k)).is_some())
404	}
405}
406
407impl Into<KeystorePtr> for MemoryKeystore {
408	fn into(self) -> KeystorePtr {
409		Arc::new(self)
410	}
411}
412
413#[cfg(test)]
414mod tests {
415	use super::*;
416	use sp_core::{
417		sr25519,
418		testing::{ECDSA, ED25519, SR25519},
419	};
420
421	#[test]
422	fn store_key_and_extract() {
423		let store = MemoryKeystore::new();
424
425		let public = store.ed25519_generate_new(ED25519, None).expect("Generates key");
426
427		let public_keys = store.ed25519_public_keys(ED25519);
428
429		assert!(public_keys.contains(&public.into()));
430	}
431
432	#[test]
433	fn store_unknown_and_extract_it() {
434		let store = MemoryKeystore::new();
435
436		let secret_uri = "//Alice";
437		let key_pair = sr25519::Pair::from_string(secret_uri, None).expect("Generates key pair");
438
439		store
440			.insert(SR25519, secret_uri, key_pair.public().as_ref())
441			.expect("Inserts unknown key");
442
443		let public_keys = store.sr25519_public_keys(SR25519);
444
445		assert!(public_keys.contains(&key_pair.public().into()));
446	}
447
448	#[test]
449	fn sr25519_vrf_sign() {
450		let store = MemoryKeystore::new();
451
452		let secret_uri = "//Alice";
453		let key_pair = sr25519::Pair::from_string(secret_uri, None).expect("Generates key pair");
454
455		let data = sr25519::vrf::VrfInput::new(
456			b"Test",
457			&[
458				(b"one", &1_u64.to_le_bytes()),
459				(b"two", &2_u64.to_le_bytes()),
460				(b"three", "test".as_bytes()),
461			],
462		)
463		.into_sign_data();
464
465		let result = store.sr25519_vrf_sign(SR25519, &key_pair.public(), &data);
466		assert!(result.unwrap().is_none());
467
468		store
469			.insert(SR25519, secret_uri, key_pair.public().as_ref())
470			.expect("Inserts unknown key");
471
472		let result = store.sr25519_vrf_sign(SR25519, &key_pair.public(), &data);
473
474		assert!(result.unwrap().is_some());
475	}
476
477	#[test]
478	fn sr25519_vrf_pre_output() {
479		let store = MemoryKeystore::new();
480
481		let secret_uri = "//Alice";
482		let pair = sr25519::Pair::from_string(secret_uri, None).expect("Generates key pair");
483
484		let input = sr25519::vrf::VrfInput::new(
485			b"Test",
486			&[
487				(b"one", &1_u64.to_le_bytes()),
488				(b"two", &2_u64.to_le_bytes()),
489				(b"three", "test".as_bytes()),
490			],
491		);
492
493		let result = store.sr25519_vrf_pre_output(SR25519, &pair.public(), &input);
494		assert!(result.unwrap().is_none());
495
496		store
497			.insert(SR25519, secret_uri, pair.public().as_ref())
498			.expect("Inserts unknown key");
499
500		let pre_output =
501			store.sr25519_vrf_pre_output(SR25519, &pair.public(), &input).unwrap().unwrap();
502
503		let result = pre_output.make_bytes::<32>(b"rand", &input, &pair.public());
504		assert!(result.is_ok());
505	}
506
507	#[test]
508	fn ecdsa_sign_prehashed_works() {
509		let store = MemoryKeystore::new();
510
511		let suri = "//Alice";
512		let pair = ecdsa::Pair::from_string(suri, None).unwrap();
513
514		// Let's pretend this to be the hash output as content doesn't really matter here.
515		let hash = [0xff; 32];
516
517		// no key in key store
518		let res = store.ecdsa_sign_prehashed(ECDSA, &pair.public(), &hash).unwrap();
519		assert!(res.is_none());
520
521		// insert key, sign again
522		store.insert(ECDSA, suri, pair.public().as_ref()).unwrap();
523
524		let res = store.ecdsa_sign_prehashed(ECDSA, &pair.public(), &hash).unwrap();
525		assert!(res.is_some());
526	}
527
528	#[test]
529	#[cfg(feature = "bls-experimental")]
530	fn ecdsa_bls381_sign_with_keccak_works() {
531		use sp_core::testing::ECDSA_BLS377;
532
533		let store = MemoryKeystore::new();
534
535		let suri = "//Alice";
536		let pair = ecdsa_bls381::Pair::from_string(suri, None).unwrap();
537
538		let msg = b"this should be a normal unhashed message not a hash of a message because bls scheme comes with its own hashing";
539
540		// insert key, sign again
541		store.insert(ECDSA_BLS377, suri, pair.public().as_ref()).unwrap();
542
543		let res = store
544			.ecdsa_bls381_sign_with_keccak256(ECDSA_BLS377, &pair.public(), &msg[..])
545			.unwrap();
546
547		assert!(res.is_some());
548
549		// does not verify with default out-of-the-box verification
550		assert!(!ecdsa_bls381::Pair::verify(&res.unwrap(), &msg[..], &pair.public()));
551
552		// should verify using keccak256 as hasher
553		assert!(ecdsa_bls381::Pair::verify_with_hasher::<KeccakHasher>(
554			&res.unwrap(),
555			msg,
556			&pair.public()
557		));
558	}
559
560	#[test]
561	#[cfg(feature = "bls-experimental")]
562	fn ecdsa_bls381_generate_with_none_works() {
563		use sp_core::testing::ECDSA_BLS381;
564
565		let store = MemoryKeystore::new();
566		let ecdsa_bls381_key =
567			store.ecdsa_bls381_generate_new(ECDSA_BLS381, None).expect("Can generate key..");
568
569		let ecdsa_keys = store.ecdsa_public_keys(ECDSA_BLS381);
570		let bls381_keys = store.bls381_public_keys(ECDSA_BLS381);
571		let ecdsa_bls381_keys = store.ecdsa_bls381_public_keys(ECDSA_BLS381);
572
573		assert_eq!(ecdsa_keys.len(), 1);
574		assert_eq!(bls381_keys.len(), 1);
575		assert_eq!(ecdsa_bls381_keys.len(), 1);
576
577		let ecdsa_key = ecdsa_keys[0];
578		let bls381_key = bls381_keys[0];
579
580		let mut combined_key_raw = [0u8; ecdsa_bls381::PUBLIC_KEY_LEN];
581		combined_key_raw[..ecdsa::PUBLIC_KEY_SERIALIZED_SIZE].copy_from_slice(ecdsa_key.as_ref());
582		combined_key_raw[ecdsa::PUBLIC_KEY_SERIALIZED_SIZE..].copy_from_slice(bls381_key.as_ref());
583		let combined_key = ecdsa_bls381::Public::from_raw(combined_key_raw);
584
585		assert_eq!(combined_key, ecdsa_bls381_key);
586	}
587
588	#[test]
589	#[cfg(feature = "bls-experimental")]
590	fn ecdsa_bls381_generate_with_seed_works() {
591		use sp_core::testing::ECDSA_BLS381;
592
593		let store = MemoryKeystore::new();
594		let ecdsa_bls381_key = store
595			.ecdsa_bls381_generate_new(ECDSA_BLS381, Some("//Alice"))
596			.expect("Can generate key..");
597
598		let ecdsa_keys = store.ecdsa_public_keys(ECDSA_BLS381);
599		let bls381_keys = store.bls381_public_keys(ECDSA_BLS381);
600		let ecdsa_bls381_keys = store.ecdsa_bls381_public_keys(ECDSA_BLS381);
601
602		assert_eq!(ecdsa_keys.len(), 1);
603		assert_eq!(bls381_keys.len(), 1);
604		assert_eq!(ecdsa_bls381_keys.len(), 1);
605
606		let ecdsa_key = ecdsa_keys[0];
607		let bls381_key = bls381_keys[0];
608
609		let mut combined_key_raw = [0u8; ecdsa_bls381::PUBLIC_KEY_LEN];
610		combined_key_raw[..ecdsa::PUBLIC_KEY_SERIALIZED_SIZE].copy_from_slice(ecdsa_key.as_ref());
611		combined_key_raw[ecdsa::PUBLIC_KEY_SERIALIZED_SIZE..].copy_from_slice(bls381_key.as_ref());
612		let combined_key = ecdsa_bls381::Public::from_raw(combined_key_raw);
613
614		assert_eq!(combined_key, ecdsa_bls381_key);
615	}
616
617	#[test]
618	#[cfg(feature = "bandersnatch-experimental")]
619	fn bandersnatch_vrf_sign() {
620		use sp_core::testing::BANDERSNATCH;
621
622		let store = MemoryKeystore::new();
623
624		let secret_uri = "//Alice";
625		let key_pair =
626			bandersnatch::Pair::from_string(secret_uri, None).expect("Generates key pair");
627		let sign_data = bandersnatch::vrf::VrfSignData::new(b"vrf_input", b"aux_data");
628
629		let result = store.bandersnatch_vrf_sign(BANDERSNATCH, &key_pair.public(), &sign_data);
630		assert!(result.unwrap().is_none());
631
632		store
633			.insert(BANDERSNATCH, secret_uri, key_pair.public().as_ref())
634			.expect("Inserts unknown key");
635
636		let result = store.bandersnatch_vrf_sign(BANDERSNATCH, &key_pair.public(), &sign_data);
637
638		assert!(result.unwrap().is_some());
639	}
640
641	#[test]
642	#[cfg(feature = "bandersnatch-experimental")]
643	fn bandersnatch_ring_vrf_sign() {
644		use sp_core::testing::BANDERSNATCH;
645
646		let store = MemoryKeystore::new();
647
648		let ring_ctx = bandersnatch::ring_vrf::RingContext::<1024>::new_testing();
649
650		let mut pks: Vec<_> = (0..16)
651			.map(|i| bandersnatch::Pair::from_seed(&[i as u8; 32]).public())
652			.collect();
653
654		let prover_idx = 3;
655		let prover = ring_ctx.prover(&pks, prover_idx);
656
657		let secret_uri = "//Alice";
658		let pair = bandersnatch::Pair::from_string(secret_uri, None).expect("Generates key pair");
659		pks[prover_idx] = pair.public();
660
661		let sign_data = bandersnatch::vrf::VrfSignData::new(b"vrf_input", b"aux_data");
662
663		let result =
664			store.bandersnatch_ring_vrf_sign(BANDERSNATCH, &pair.public(), &sign_data, &prover);
665		assert!(result.unwrap().is_none());
666
667		store
668			.insert(BANDERSNATCH, secret_uri, pair.public().as_ref())
669			.expect("Inserts unknown key");
670
671		let result =
672			store.bandersnatch_ring_vrf_sign(BANDERSNATCH, &pair.public(), &sign_data, &prover);
673
674		assert!(result.unwrap().is_some());
675	}
676}