referrerpolicy=no-referrer-when-downgrade

sp_core/
bandersnatch.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//! VRFs backed by [Bandersnatch](https://neuromancer.sk/std/bls/Bandersnatch),
19//! an elliptic curve built over BLS12-381 scalar field.
20//!
21//! The primitive can operate both as a regular VRF or as an anonymized Ring VRF.
22
23#[cfg(feature = "full_crypto")]
24use crate::crypto::VrfSecret;
25use crate::{
26	crypto::{
27		ByteArray, CryptoType, CryptoTypeId, DeriveError, DeriveJunction, Pair as TraitPair,
28		PublicBytes, SecretStringError, SignatureBytes, UncheckedFrom, VrfPublic,
29	},
30	proof_of_possession::NonAggregatable,
31};
32use alloc::{vec, vec::Vec};
33use ark_vrf::{
34	reexports::ark_serialize::{CanonicalDeserialize, CanonicalSerialize},
35	suites::bandersnatch::{self, BandersnatchSha512Ell2 as BandersnatchSuite, Secret, VrfIo},
36};
37use codec::{Decode, DecodeWithMemTracking, Encode, EncodeLike, MaxEncodedLen};
38use scale_info::TypeInfo;
39
40/// Identifier used to match public keys against bandersnatch-vrf keys.
41pub const CRYPTO_ID: CryptoTypeId = CryptoTypeId(*b"band");
42
43/// The byte length of secret key seed.
44pub const SEED_SERIALIZED_SIZE: usize = 32;
45
46/// The byte length of serialized public key.
47pub const PUBLIC_SERIALIZED_SIZE: usize = 32;
48
49/// The byte length of serialized signature (thin VRF proof: 32-byte point + 32-byte scalar).
50pub const SIGNATURE_SERIALIZED_SIZE: usize = 64;
51
52/// The byte length of serialized pre-output.
53pub const PREOUT_SERIALIZED_SIZE: usize = 32;
54
55#[doc(hidden)]
56pub struct BandersnatchTag;
57
58/// Bandersnatch public key.
59pub type Public = PublicBytes<PUBLIC_SERIALIZED_SIZE, BandersnatchTag>;
60
61impl CryptoType for Public {
62	type Pair = Pair;
63}
64
65/// Bandersnatch Schnorr signature.
66pub type Signature = SignatureBytes<SIGNATURE_SERIALIZED_SIZE, BandersnatchTag>;
67
68/// Proof of Possession is the same as Signature for Bandersnatch
69pub type ProofOfPossession = Signature;
70
71impl CryptoType for Signature {
72	type Pair = Pair;
73}
74
75/// The raw secret seed, which can be used to reconstruct the secret [`Pair`].
76type Seed = [u8; SEED_SERIALIZED_SIZE];
77
78/// Bandersnatch secret key.
79#[derive(Clone)]
80pub struct Pair {
81	secret: Secret,
82	seed: Seed,
83}
84
85impl Pair {
86	/// Get the key seed.
87	pub fn seed(&self) -> Seed {
88		self.seed
89	}
90}
91
92impl TraitPair for Pair {
93	type Seed = Seed;
94	type Public = Public;
95	type Signature = Signature;
96	type ProofOfPossession = Signature;
97
98	/// Make a new key pair from secret seed material.
99	///
100	/// The slice must be 32 bytes long or it will return an error.
101	fn from_seed_slice(seed_slice: &[u8]) -> Result<Pair, SecretStringError> {
102		if seed_slice.len() != SEED_SERIALIZED_SIZE {
103			return Err(SecretStringError::InvalidSeedLength);
104		}
105		let mut seed = [0; SEED_SERIALIZED_SIZE];
106		seed.copy_from_slice(seed_slice);
107		let secret = Secret::from_seed(seed);
108		Ok(Pair { secret, seed })
109	}
110
111	/// Derive a child key from a series of given (hard) junctions.
112	///
113	/// Soft junctions are not supported.
114	fn derive<Iter: Iterator<Item = DeriveJunction>>(
115		&self,
116		path: Iter,
117		_seed: Option<Seed>,
118	) -> Result<(Pair, Option<Seed>), DeriveError> {
119		let derive_hard = |seed, cc| -> Seed {
120			("bandersnatch-vrf-HDKD", seed, cc).using_encoded(sp_crypto_hashing::blake2_256)
121		};
122
123		let mut seed = self.seed();
124		for p in path {
125			if let DeriveJunction::Hard(cc) = p {
126				seed = derive_hard(seed, cc);
127			} else {
128				return Err(DeriveError::SoftKeyInPath);
129			}
130		}
131		Ok((Self::from_seed(&seed), Some(seed)))
132	}
133
134	fn public(&self) -> Public {
135		let public = self.secret.public();
136		let mut raw = [0; PUBLIC_SERIALIZED_SIZE];
137		public
138			.serialize_compressed(raw.as_mut_slice())
139			.expect("serialization length is constant and checked by test; qed");
140		Public::unchecked_from(raw)
141	}
142
143	#[cfg(feature = "full_crypto")]
144	fn sign(&self, data: &[u8]) -> Signature {
145		vrf::vrf_sign(&self.secret, &[], data)
146	}
147
148	fn verify<M: AsRef<[u8]>>(signature: &Signature, data: M, public: &Public) -> bool {
149		vrf::vrf_verify(public, &[], signature, data.as_ref())
150	}
151
152	/// Return a vector filled with the seed.
153	fn to_raw_vec(&self) -> Vec<u8> {
154		self.seed().to_vec()
155	}
156}
157
158impl CryptoType for Pair {
159	type Pair = Pair;
160}
161
162impl NonAggregatable for Pair {}
163
164/// Bandersnatch VRF types and operations.
165pub mod vrf {
166	use super::*;
167	use crate::crypto::VrfCrypto;
168
169	/// [`VrfSignature`] serialized size.
170	pub const VRF_SIGNATURE_SERIALIZED_SIZE: usize =
171		PREOUT_SERIALIZED_SIZE + SIGNATURE_SERIALIZED_SIZE;
172
173	/// VRF input to construct a [`VrfPreOutput`] instance and embeddable in [`VrfSignData`].
174	#[derive(Clone, Debug)]
175	pub struct VrfInput(pub(super) bandersnatch::Input);
176
177	impl VrfInput {
178		/// Construct a new VRF input.
179		///
180		/// Hash to Curve (H2C) using Elligator2.
181		pub fn new(data: &[u8]) -> Self {
182			Self(bandersnatch::Input::new(data).expect("H2C for Bandersnatch can't fail; qed"))
183		}
184	}
185
186	/// VRF pre-output derived from [`VrfInput`] using a [`VrfSecret`].
187	///
188	/// This object is hashed to produce the actual VRF output.
189	#[derive(Clone, Debug, PartialEq, Eq)]
190	pub struct VrfPreOutput(pub(super) bandersnatch::Output);
191
192	impl Encode for VrfPreOutput {
193		fn encode(&self) -> Vec<u8> {
194			let mut bytes = [0; PREOUT_SERIALIZED_SIZE];
195			self.0
196				.serialize_compressed(bytes.as_mut_slice())
197				.expect("serialization length is constant and checked by test; qed");
198			bytes.encode()
199		}
200	}
201
202	impl Decode for VrfPreOutput {
203		fn decode<R: codec::Input>(i: &mut R) -> Result<Self, codec::Error> {
204			let buf = <[u8; PREOUT_SERIALIZED_SIZE]>::decode(i)?;
205			let preout = bandersnatch::Output::deserialize_compressed(buf.as_slice())
206				.map_err(|_| "vrf-preout decode error: bad preout")?;
207			Ok(VrfPreOutput(preout))
208		}
209	}
210
211	// `VrfPreOutput` resolves to:
212	// ```
213	// pub struct Affine<P: TECurveConfig> {
214	//     pub x: P::BaseField,
215	//     pub y: P::BaseField,
216	// }
217	// ```
218	// where each `P::BaseField` contains a `pub struct BigInt<const N: usize>(pub [u64; N]);`
219	// Since none of these structures is allocated on the heap, we don't need any special
220	// memory tracking logic. We can simply implement `DecodeWithMemTracking`.
221	impl DecodeWithMemTracking for VrfPreOutput {}
222
223	impl EncodeLike for VrfPreOutput {}
224
225	impl MaxEncodedLen for VrfPreOutput {
226		fn max_encoded_len() -> usize {
227			<[u8; PREOUT_SERIALIZED_SIZE]>::max_encoded_len()
228		}
229	}
230
231	impl TypeInfo for VrfPreOutput {
232		type Identity = [u8; PREOUT_SERIALIZED_SIZE];
233
234		fn type_info() -> scale_info::Type {
235			Self::Identity::type_info()
236		}
237	}
238
239	/// Data to be signed via one of the two provided vrf flavors.
240	///
241	/// The object contains the VRF input and additional data to be signed together
242	/// with the VRF input. Additional data doesn't influence the VRF output.
243	///
244	/// The `input` is a [`VrfInput`]s which, during the signing procedure, is first mapped
245	/// to a [`VrfPreOutput`].
246	#[derive(Clone)]
247	pub struct VrfSignData {
248		/// VRF input.
249		pub vrf_input: VrfInput,
250		/// Additional data.
251		pub aux_data: Vec<u8>,
252	}
253
254	impl VrfSignData {
255		/// Construct a new data to be signed.
256		pub fn new(vrf_input_data: &[u8], aux_data: &[u8]) -> Self {
257			Self { vrf_input: VrfInput::new(vrf_input_data), aux_data: aux_data.to_vec() }
258		}
259	}
260
261	/// VRF signature.
262	///
263	/// Includes both the VRF proof and the pre-output generated from the
264	/// [`VrfSignData::vrf_input`].
265	///
266	/// Refer to [`VrfSignData`] for more details.
267	#[derive(Clone, Debug, PartialEq, Eq, Encode, Decode, MaxEncodedLen, TypeInfo)]
268	pub struct VrfSignature {
269		/// VRF pre-output.
270		pub pre_output: VrfPreOutput,
271		/// VRF proof.
272		pub proof: Signature,
273	}
274
275	#[cfg(feature = "full_crypto")]
276	impl VrfCrypto for Pair {
277		type VrfInput = VrfInput;
278		type VrfPreOutput = VrfPreOutput;
279		type VrfSignData = VrfSignData;
280		type VrfSignature = VrfSignature;
281	}
282
283	#[cfg(feature = "full_crypto")]
284	pub(super) fn vrf_sign(secret: &Secret, ios: &[VrfIo], aux_data: &[u8]) -> Signature {
285		use ark_vrf::thin::Prover;
286		let proof_impl = secret.prove(ios, aux_data);
287		let mut proof = Signature::default();
288		proof_impl
289			.serialize_compressed(proof.0.as_mut_slice())
290			.expect("serialization length is constant and checked by test; qed");
291		proof
292	}
293
294	pub(super) fn vrf_verify(
295		public: &Public,
296		ios: &[VrfIo],
297		proof: &Signature,
298		aux_data: &[u8],
299	) -> bool {
300		use ark_vrf::thin::Verifier;
301		let Ok(public) = bandersnatch::Public::deserialize_compressed(public.as_slice()) else {
302			return false;
303		};
304		let Ok(proof) =
305			ark_vrf::thin::Proof::<BandersnatchSuite>::deserialize_compressed(proof.as_slice())
306		else {
307			return false;
308		};
309		public.verify(ios, aux_data, &proof).is_ok()
310	}
311
312	#[cfg(feature = "full_crypto")]
313	impl VrfSecret for Pair {
314		fn vrf_sign(&self, data: &VrfSignData) -> VrfSignature {
315			let output = self.secret.output(data.vrf_input.0);
316			let pre_output = VrfPreOutput(output);
317			let io = VrfIo { input: data.vrf_input.0, output };
318			let proof = vrf_sign(&self.secret, &[io], &data.aux_data);
319			VrfSignature { pre_output, proof }
320		}
321
322		fn vrf_pre_output(&self, input: &Self::VrfInput) -> Self::VrfPreOutput {
323			let pre_output_impl = self.secret.output(input.0);
324			VrfPreOutput(pre_output_impl)
325		}
326	}
327
328	impl VrfCrypto for Public {
329		type VrfInput = VrfInput;
330		type VrfPreOutput = VrfPreOutput;
331		type VrfSignData = VrfSignData;
332		type VrfSignature = VrfSignature;
333	}
334
335	impl VrfPublic for Public {
336		fn vrf_verify(&self, data: &VrfSignData, signature: &VrfSignature) -> bool {
337			let io = VrfIo { input: data.vrf_input.0, output: signature.pre_output.0 };
338			vrf_verify(self, &[io], &signature.proof, &data.aux_data)
339		}
340	}
341
342	#[cfg(feature = "full_crypto")]
343	impl Pair {
344		/// Generate VRF output bytes for the given `input`.
345		pub fn make_bytes(&self, input: &VrfInput) -> [u8; 32] {
346			self.vrf_pre_output(input).make_bytes()
347		}
348	}
349
350	impl VrfPreOutput {
351		/// Generate VRF output bytes.
352		pub fn make_bytes(&self) -> [u8; 32] {
353			self.0.hash::<32>()
354		}
355	}
356}
357
358/// Bandersnatch Ring-VRF types and operations.
359pub mod ring_vrf {
360	use super::{vrf::*, *};
361	pub use bandersnatch::{RingProver, RingVerifier};
362	use bandersnatch::{RingSetup, RingVerifierKey as RingVerifierKeyImpl};
363
364	// Max size of serialized ring-vrf context given `domain_len`.
365	pub(crate) fn ring_context_serialized_size(ring_size: usize) -> usize {
366		const G1_POINT_UNCOMPRESSED_SIZE: usize = 96;
367		const G2_POINT_UNCOMPRESSED_SIZE: usize = 192;
368		const OVERHEAD_SIZE: usize = 16;
369		const G2_POINTS_NUM: usize = 2;
370		let g1_points_num = ark_vrf::ring::pcs_domain_size::<BandersnatchSuite>(ring_size);
371		OVERHEAD_SIZE +
372			g1_points_num * G1_POINT_UNCOMPRESSED_SIZE +
373			G2_POINTS_NUM * G2_POINT_UNCOMPRESSED_SIZE
374	}
375
376	/// [`RingVerifierKey`] serialized size.
377	pub const RING_VERIFIER_KEY_SERIALIZED_SIZE: usize = 384;
378	/// [`RingProof`] serialized size.
379	pub(crate) const RING_PROOF_SERIALIZED_SIZE: usize = 752;
380	/// [`RingVrfSignature`] serialized size.
381	pub const RING_SIGNATURE_SERIALIZED_SIZE: usize =
382		RING_PROOF_SERIALIZED_SIZE + PREOUT_SERIALIZED_SIZE;
383
384	/// Ring verifier key
385	pub struct RingVerifierKey(RingVerifierKeyImpl);
386
387	impl Encode for RingVerifierKey {
388		fn encode(&self) -> Vec<u8> {
389			let mut buf = Vec::with_capacity(RING_VERIFIER_KEY_SERIALIZED_SIZE);
390			self.0
391				.serialize_compressed(&mut buf)
392				.expect("serialization length is constant and checked by test; qed");
393			buf
394		}
395	}
396
397	impl Decode for RingVerifierKey {
398		fn decode<R: codec::Input>(input: &mut R) -> Result<Self, codec::Error> {
399			let mut buf = vec![0; RING_VERIFIER_KEY_SERIALIZED_SIZE];
400			input.read(&mut buf[..])?;
401			let vk = RingVerifierKeyImpl::deserialize_compressed_unchecked(buf.as_slice())
402				.map_err(|_| "RingVerifierKey decode error")?;
403			Ok(RingVerifierKey(vk))
404		}
405	}
406
407	impl EncodeLike for RingVerifierKey {}
408
409	impl MaxEncodedLen for RingVerifierKey {
410		fn max_encoded_len() -> usize {
411			RING_VERIFIER_KEY_SERIALIZED_SIZE
412		}
413	}
414
415	impl TypeInfo for RingVerifierKey {
416		type Identity = [u8; RING_VERIFIER_KEY_SERIALIZED_SIZE];
417		fn type_info() -> scale_info::Type {
418			Self::Identity::type_info()
419		}
420	}
421
422	/// Context used to construct ring prover and verifier.
423	///
424	/// Generic parameter `R` represents the ring size.
425	#[derive(Clone)]
426	pub struct RingContext<const R: usize>(RingSetup);
427
428	impl<const R: usize> RingContext<R> {
429		/// Build an dummy instance for testing purposes.
430		pub fn new_testing() -> Self {
431			Self(RingSetup::from_seed(R, [0; 32]))
432		}
433
434		/// Get the keyset max size.
435		pub fn max_keyset_size(&self) -> usize {
436			self.0.max_ring_size()
437		}
438
439		/// Get ring prover for the key at index `public_idx` in the `public_keys` set.
440		pub fn prover(&self, public_keys: &[Public], public_idx: usize) -> RingProver {
441			let pks = Self::make_ring_vector(public_keys);
442			let prover_key = self.0.prover_key(&pks).expect("ring size within bounds; qed");
443			self.0.ring_prover(prover_key, public_idx)
444		}
445
446		/// Get ring verifier for the `public_keys` set.
447		pub fn verifier(&self, public_keys: &[Public]) -> RingVerifier {
448			let vk = self.verifier_key(public_keys);
449			self.0.ring_verifier(vk.0)
450		}
451
452		/// Build `RingVerifierKey` for lazy `RingVerifier` construction.
453		pub fn verifier_key(&self, public_keys: &[Public]) -> RingVerifierKey {
454			let pks = Self::make_ring_vector(public_keys);
455			RingVerifierKey(self.0.verifier_key(&pks).expect("ring size within bounds; qed"))
456		}
457
458		/// Constructs a `RingVerifier` from a `VerifierKey` without a `RingContext` instance.
459		///
460		/// While this approach is computationally slightly less efficient than using a
461		/// pre-constructed `RingContext`, as some parameters need to be computed on-the-fly, it
462		/// is beneficial in memory or storage constrained environments. This avoids the need to
463		/// retain the full `RingContext` for ring signature verification. Instead, the
464		/// `VerifierKey` contains only the essential information needed to verify ring proofs.
465		pub fn verifier_no_context(verifier_key: RingVerifierKey) -> RingVerifier {
466			ark_vrf::ring::RingContext::<BandersnatchSuite>::new(R)
467				.into_ring_verifier(verifier_key.0)
468		}
469
470		fn make_ring_vector(public_keys: &[Public]) -> Vec<bandersnatch::AffinePoint> {
471			use bandersnatch::AffinePoint;
472			public_keys
473				.iter()
474				.map(|pk| {
475					AffinePoint::deserialize_compressed_unchecked(pk.as_slice())
476						.unwrap_or(RingSetup::padding_point())
477				})
478				.collect()
479		}
480	}
481
482	impl<const R: usize> Encode for RingContext<R> {
483		fn encode(&self) -> Vec<u8> {
484			let mut buf = Vec::with_capacity(ring_context_serialized_size(R));
485			self.0
486				.serialize_uncompressed(&mut buf)
487				.expect("serialization length is constant and checked by test; qed");
488			buf
489		}
490	}
491
492	impl<const R: usize> Decode for RingContext<R> {
493		fn decode<I: codec::Input>(input: &mut I) -> Result<Self, codec::Error> {
494			let mut buf = vec![0; ring_context_serialized_size(R)];
495			input.read(&mut buf[..])?;
496			let ctx = RingSetup::deserialize_uncompressed_unchecked(buf.as_slice())
497				.map_err(|_| "RingContext decode error")?;
498			Ok(RingContext(ctx))
499		}
500	}
501
502	impl<const R: usize> EncodeLike for RingContext<R> {}
503
504	impl<const R: usize> MaxEncodedLen for RingContext<R> {
505		fn max_encoded_len() -> usize {
506			ring_context_serialized_size(R)
507		}
508	}
509
510	impl<const R: usize> TypeInfo for RingContext<R> {
511		type Identity = Self;
512		fn type_info() -> scale_info::Type {
513			let path = scale_info::Path::new("RingContext", module_path!());
514			let array_type_def = scale_info::TypeDefArray {
515				len: ring_context_serialized_size(R) as u32,
516				type_param: scale_info::MetaType::new::<u8>(),
517			};
518			let type_def = scale_info::TypeDef::Array(array_type_def);
519			scale_info::Type { path, type_params: Vec::new(), type_def, docs: Vec::new() }
520		}
521	}
522
523	/// Ring VRF signature.
524	#[derive(
525		Clone, Debug, PartialEq, Eq, Encode, Decode, DecodeWithMemTracking, MaxEncodedLen, TypeInfo,
526	)]
527	pub struct RingVrfSignature {
528		/// VRF pre-output.
529		pub pre_output: VrfPreOutput,
530		/// Ring signature.
531		pub proof: [u8; RING_PROOF_SERIALIZED_SIZE],
532	}
533
534	#[cfg(feature = "full_crypto")]
535	impl Pair {
536		/// Produce a ring-vrf signature.
537		///
538		/// The ring signature is verifiable if the public key corresponding to the
539		/// signing [`Pair`] is part of the ring from which the [`RingProver`] has
540		/// been constructed. If not, the produced signature is just useless.
541		pub fn ring_vrf_sign(&self, data: &VrfSignData, prover: &RingProver) -> RingVrfSignature {
542			use ark_vrf::ring::Prover;
543			let pre_output_impl = self.secret.output(data.vrf_input.0);
544			let pre_output = VrfPreOutput(pre_output_impl);
545			let io = VrfIo { input: data.vrf_input.0, output: pre_output.0 };
546			let proof_impl = self.secret.prove(io, &data.aux_data, prover);
547			let mut proof = [0; RING_PROOF_SERIALIZED_SIZE];
548			proof_impl
549				.serialize_compressed(proof.as_mut_slice())
550				.expect("serialization length is constant and checked by test; qed");
551			RingVrfSignature { pre_output, proof }
552		}
553	}
554
555	impl RingVrfSignature {
556		/// Verify a ring-vrf signature.
557		///
558		/// The signature is verifiable if it has been produced by a member of the ring
559		/// from which the [`RingVerifier`] has been constructed.
560		pub fn ring_vrf_verify(&self, data: &VrfSignData, verifier: &RingVerifier) -> bool {
561			use ark_vrf::ring::Verifier;
562			let Ok(proof) = bandersnatch::RingProof::deserialize_compressed(self.proof.as_slice())
563			else {
564				return false;
565			};
566			let io = VrfIo { input: data.vrf_input.0, output: self.pre_output.0 };
567			bandersnatch::Public::verify(io, &data.aux_data, &proof, verifier).is_ok()
568		}
569	}
570}
571
572#[cfg(test)]
573mod tests {
574	use super::{ring_vrf::*, vrf::*, *};
575	use crate::{
576		crypto::{VrfPublic, VrfSecret, DEV_PHRASE},
577		proof_of_possession::{ProofOfPossessionGenerator, ProofOfPossessionVerifier},
578	};
579
580	const TEST_SEED: &[u8; SEED_SERIALIZED_SIZE] = &[0xcb; SEED_SERIALIZED_SIZE];
581	const TEST_RING_SIZE: usize = 16;
582
583	type TestRingContext = RingContext<TEST_RING_SIZE>;
584
585	#[allow(unused)]
586	fn b2h(bytes: &[u8]) -> String {
587		array_bytes::bytes2hex("", bytes)
588	}
589
590	fn h2b(hex: &str) -> Vec<u8> {
591		array_bytes::hex2bytes_unchecked(hex)
592	}
593
594	#[test]
595	fn backend_assumptions_sanity_check() {
596		use bandersnatch::{Input, RingSetup};
597
598		let ctx = RingSetup::from_seed(TEST_RING_SIZE, [0_u8; 32]);
599
600		let domain_size = ark_vrf::ring::pcs_domain_size::<BandersnatchSuite>(TEST_RING_SIZE);
601		assert_eq!(domain_size, ctx.pcs_params.powers_in_g1.len());
602		let domain_size2 = ark_vrf::ring::pcs_domain_size::<BandersnatchSuite>(ctx.max_ring_size());
603		assert_eq!(domain_size, domain_size2);
604		assert_eq!(
605			ark_vrf::ring::max_ring_size_from_pcs_domain_size::<BandersnatchSuite>(domain_size),
606			ctx.max_ring_size()
607		);
608
609		assert_eq!(ctx.uncompressed_size(), ring_context_serialized_size(TEST_RING_SIZE));
610
611		let prover_key_index = 3;
612		let secret = Secret::from_seed([prover_key_index as u8; 32]);
613		let public = secret.public();
614		assert_eq!(public.compressed_size(), PUBLIC_SERIALIZED_SIZE);
615
616		let input = Input::new(b"foo").unwrap();
617		let preout = secret.output(input);
618		assert_eq!(preout.compressed_size(), PREOUT_SERIALIZED_SIZE);
619
620		let ring_keys: Vec<_> = (0..TEST_RING_SIZE)
621			.map(|i| Secret::from_seed([i as u8; 32]).public().0.into())
622			.collect();
623
624		let verifier_key = ctx.verifier_key(&ring_keys[..]).expect("valid ring; qed");
625		assert_eq!(verifier_key.compressed_size(), RING_VERIFIER_KEY_SERIALIZED_SIZE);
626
627		let prover_key = ctx.prover_key(&ring_keys).expect("valid ring; qed");
628		let ring_prover = ctx.ring_prover(prover_key, prover_key_index);
629
630		{
631			use ark_vrf::thin::Prover;
632			let io = ark_vrf::VrfIo::<BandersnatchSuite> { input, output: preout };
633			let proof = secret.prove(io, &[]);
634			assert_eq!(proof.compressed_size(), SIGNATURE_SERIALIZED_SIZE);
635		}
636
637		{
638			use ark_vrf::ring::Prover;
639			let io = ark_vrf::VrfIo::<BandersnatchSuite> { input, output: preout };
640			let proof = secret.prove(io, &[], &ring_prover);
641			assert_eq!(proof.compressed_size(), RING_PROOF_SERIALIZED_SIZE);
642		}
643	}
644
645	#[test]
646	fn derive_works() {
647		let pair = Pair::from_string(&format!("{}//Alice//Hard", DEV_PHRASE), None).unwrap();
648		let known = h2b("915626c7d4363856277e3dc0729c11df1f5a1caa1d3d0ec4986f0ae9226c5c45");
649		assert_eq!(pair.public().as_ref(), known);
650
651		// Soft derivation not supported
652		let res = Pair::from_string(&format!("{}//Alice/Soft", DEV_PHRASE), None);
653		assert!(res.is_err());
654	}
655
656	#[test]
657	fn generate_with_phrase_should_be_recoverable_with_from_string() {
658		let (pair, phrase, seed) = Pair::generate_with_phrase(None);
659		let repair_seed = Pair::from_seed_slice(seed.as_ref()).expect("seed slice is valid");
660		assert_eq!(pair.public(), repair_seed.public());
661		let (repair_phrase, reseed) =
662			Pair::from_phrase(phrase.as_ref(), None).expect("seed slice is valid");
663		assert_eq!(seed, reseed);
664		assert_eq!(pair.public(), repair_phrase.public());
665		let repair_string = Pair::from_string(phrase.as_str(), None).expect("seed slice is valid");
666		assert_eq!(pair.public(), repair_string.public());
667	}
668
669	#[test]
670	fn sign_verify() {
671		let pair = Pair::from_seed(TEST_SEED);
672		let public = pair.public();
673		let msg = b"foo";
674		let signature = pair.sign(msg);
675		assert!(Pair::verify(&signature, msg, &public));
676	}
677
678	#[test]
679	fn vrf_sign_verify() {
680		let pair = Pair::from_seed(TEST_SEED);
681		let public = pair.public();
682		let data = VrfSignData::new(b"foo", b"aux");
683		let signature = pair.vrf_sign(&data);
684		assert!(public.vrf_verify(&data, &signature));
685	}
686
687	#[test]
688	fn vrf_sign_verify_with_bad_input() {
689		let pair = Pair::from_seed(TEST_SEED);
690		let public = pair.public();
691		let data = VrfSignData::new(b"foo", b"aux");
692		let signature = pair.vrf_sign(&data);
693		let data = VrfSignData::new(b"foo", b"bad");
694		assert!(!public.vrf_verify(&data, &signature));
695		let data = VrfSignData::new(b"bar", b"aux");
696		assert!(!public.vrf_verify(&data, &signature));
697	}
698
699	#[test]
700	fn vrf_output_bytes_match() {
701		let pair = Pair::from_seed(TEST_SEED);
702		let data = VrfSignData::new(b"foo", b"aux");
703		let signature = pair.vrf_sign(&data);
704		let o0 = pair.make_bytes(&data.vrf_input);
705		let o1 = signature.pre_output.make_bytes();
706		assert_eq!(o0, o1);
707	}
708
709	#[test]
710	fn vrf_signature_encode_decode() {
711		let pair = Pair::from_seed(TEST_SEED);
712
713		let data = VrfSignData::new(b"data", b"aux");
714		let expected = pair.vrf_sign(&data);
715
716		let bytes = expected.encode();
717
718		let expected_len = PREOUT_SERIALIZED_SIZE + SIGNATURE_SERIALIZED_SIZE;
719		assert_eq!(bytes.len(), expected_len);
720
721		let decoded = VrfSignature::decode(&mut bytes.as_slice()).unwrap();
722		assert_eq!(expected, decoded);
723	}
724
725	#[test]
726	fn ring_vrf_sign_verify() {
727		let ring_ctx = TestRingContext::new_testing();
728
729		let mut pks: Vec<_> =
730			(0..TEST_RING_SIZE).map(|i| Pair::from_seed(&[i as u8; 32]).public()).collect();
731		assert!(pks.len() <= ring_ctx.max_keyset_size());
732
733		let pair = Pair::from_seed(TEST_SEED);
734
735		// Just pick one index to patch with the actual public key
736		let prover_idx = 3;
737		pks[prover_idx] = pair.public();
738		let prover = ring_ctx.prover(&pks, prover_idx);
739
740		let data = VrfSignData::new(b"data", b"aux");
741		let signature = pair.ring_vrf_sign(&data, &prover);
742
743		let verifier = ring_ctx.verifier(&pks);
744		assert!(signature.ring_vrf_verify(&data, &verifier));
745	}
746
747	#[test]
748	fn ring_vrf_sign_verify_with_out_of_ring_key() {
749		let ring_ctx = TestRingContext::new_testing();
750
751		let pks: Vec<_> =
752			(0..TEST_RING_SIZE).map(|i| Pair::from_seed(&[i as u8; 32]).public()).collect();
753		let pair = Pair::from_seed(TEST_SEED);
754
755		let data = VrfSignData::new(b"foo", b"aux");
756
757		// pair.public != pks[0]
758		let prover = ring_ctx.prover(&pks, 0);
759		let signature = pair.ring_vrf_sign(&data, &prover);
760
761		let verifier = ring_ctx.verifier(&pks);
762		assert!(!signature.ring_vrf_verify(&data, &verifier));
763	}
764
765	#[test]
766	fn ring_vrf_make_bytes_matches() {
767		let ring_ctx = TestRingContext::new_testing();
768
769		let mut pks: Vec<_> =
770			(0..TEST_RING_SIZE).map(|i| Pair::from_seed(&[i as u8; 32]).public()).collect();
771		assert!(pks.len() <= ring_ctx.max_keyset_size());
772
773		let pair = Pair::from_seed(TEST_SEED);
774
775		// Just pick one index to patch with the actual public key
776		let prover_idx = 3;
777		pks[prover_idx] = pair.public();
778
779		let data = VrfSignData::new(b"data", b"aux");
780
781		let prover = ring_ctx.prover(&pks, prover_idx);
782		let signature = pair.ring_vrf_sign(&data, &prover);
783
784		let o0 = pair.make_bytes(&data.vrf_input);
785		let o1 = signature.pre_output.make_bytes();
786		assert_eq!(o0, o1);
787	}
788
789	#[test]
790	fn ring_vrf_signature_encode_decode() {
791		let ring_ctx = TestRingContext::new_testing();
792
793		let mut pks: Vec<_> =
794			(0..TEST_RING_SIZE).map(|i| Pair::from_seed(&[i as u8; 32]).public()).collect();
795		assert!(pks.len() <= ring_ctx.max_keyset_size());
796
797		let pair = Pair::from_seed(TEST_SEED);
798
799		// Just pick one index to patch with the actual public key
800		let prover_idx = 3;
801		pks[prover_idx] = pair.public();
802
803		let data = VrfSignData::new(b"foo", b"aux");
804
805		let prover = ring_ctx.prover(&pks, prover_idx);
806		let expected = pair.ring_vrf_sign(&data, &prover);
807
808		let bytes = expected.encode();
809		assert_eq!(bytes.len(), RING_SIGNATURE_SERIALIZED_SIZE);
810
811		let decoded = RingVrfSignature::decode(&mut bytes.as_slice()).unwrap();
812		assert_eq!(expected, decoded);
813	}
814
815	#[test]
816	fn ring_vrf_context_encode_decode() {
817		let ctx1 = TestRingContext::new_testing();
818		let enc1 = ctx1.encode();
819
820		assert_eq!(enc1.len(), ring_context_serialized_size(TEST_RING_SIZE));
821		assert_eq!(enc1.len(), TestRingContext::max_encoded_len());
822
823		let ctx2 = TestRingContext::decode(&mut enc1.as_slice()).unwrap();
824		let enc2 = ctx2.encode();
825
826		assert_eq!(enc1, enc2);
827	}
828
829	#[test]
830	fn verifier_key_encode_decode() {
831		let ring_ctx = TestRingContext::new_testing();
832
833		let pks: Vec<_> =
834			(0..TEST_RING_SIZE).map(|i| Pair::from_seed(&[i as u8; 32]).public()).collect();
835		assert!(pks.len() <= ring_ctx.max_keyset_size());
836
837		let verifier_key = ring_ctx.verifier_key(&pks);
838		let enc1 = verifier_key.encode();
839		assert_eq!(enc1.len(), RING_VERIFIER_KEY_SERIALIZED_SIZE);
840		assert_eq!(RingVerifierKey::max_encoded_len(), RING_VERIFIER_KEY_SERIALIZED_SIZE);
841
842		let vd2 = RingVerifierKey::decode(&mut enc1.as_slice()).unwrap();
843		let enc2 = vd2.encode();
844		assert_eq!(enc1, enc2);
845	}
846
847	#[test]
848	fn good_proof_of_possession_should_work_bad_proof_of_possession_should_fail() {
849		let owner = b"owner";
850		let not_owner = b"not owner";
851		let mut pair = Pair::from_seed(b"12345678901234567890123456789012");
852		let other_pair = Pair::from_seed(b"23456789012345678901234567890123");
853		let proof_of_possession = pair.generate_proof_of_possession(owner);
854		assert!(Pair::verify_proof_of_possession(owner, &proof_of_possession, &pair.public()));
855		assert!(!Pair::verify_proof_of_possession(
856			owner,
857			&proof_of_possession,
858			&other_pair.public()
859		));
860		assert!(!Pair::verify_proof_of_possession(not_owner, &proof_of_possession, &pair.public()));
861	}
862}