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