1#[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::CanonicalSerialize,
35 suites::bandersnatch::{self, BandersnatchSha512Ell2 as BandersnatchSuite, Secret, VrfIo},
36 CanonicalDeserializeExact,
37};
38use codec::{Decode, DecodeWithMemTracking, Encode, EncodeLike, MaxEncodedLen};
39use scale_info::TypeInfo;
40
41pub const CRYPTO_ID: CryptoTypeId = CryptoTypeId(*b"band");
43
44pub const SEED_SERIALIZED_SIZE: usize = 32;
46
47pub const PUBLIC_SERIALIZED_SIZE: usize = 32;
49
50pub const SIGNATURE_SERIALIZED_SIZE: usize = 64;
52
53pub const PREOUT_SERIALIZED_SIZE: usize = 32;
55
56#[doc(hidden)]
57pub struct BandersnatchTag;
58
59pub type Public = PublicBytes<PUBLIC_SERIALIZED_SIZE, BandersnatchTag>;
61
62impl CryptoType for Public {
63 type Pair = Pair;
64}
65
66pub type Signature = SignatureBytes<SIGNATURE_SERIALIZED_SIZE, BandersnatchTag>;
68
69pub type ProofOfPossession = Signature;
71
72impl CryptoType for Signature {
73 type Pair = Pair;
74}
75
76type Seed = [u8; SEED_SERIALIZED_SIZE];
78
79#[derive(Clone)]
81pub struct Pair {
82 secret: Secret,
83 seed: Seed,
84}
85
86impl Pair {
87 pub fn seed(&self) -> Seed {
89 self.seed
90 }
91}
92
93impl TraitPair for Pair {
94 type Seed = Seed;
95 type Public = Public;
96 type Signature = Signature;
97 type ProofOfPossession = Signature;
98
99 fn from_seed_slice(seed_slice: &[u8]) -> Result<Pair, SecretStringError> {
103 if seed_slice.len() != SEED_SERIALIZED_SIZE {
104 return Err(SecretStringError::InvalidSeedLength);
105 }
106 let mut seed = [0; SEED_SERIALIZED_SIZE];
107 seed.copy_from_slice(seed_slice);
108 let secret = Secret::from_seed(seed);
109 Ok(Pair { secret, seed })
110 }
111
112 fn derive<Iter: Iterator<Item = DeriveJunction>>(
116 &self,
117 path: Iter,
118 _seed: Option<Seed>,
119 ) -> Result<(Pair, Option<Seed>), DeriveError> {
120 let derive_hard = |seed, cc| -> Seed {
121 ("bandersnatch-vrf-HDKD", seed, cc).using_encoded(sp_crypto_hashing::blake2_256)
122 };
123
124 let mut seed = self.seed();
125 for p in path {
126 if let DeriveJunction::Hard(cc) = p {
127 seed = derive_hard(seed, cc);
128 } else {
129 return Err(DeriveError::SoftKeyInPath);
130 }
131 }
132 Ok((Self::from_seed(&seed), Some(seed)))
133 }
134
135 fn public(&self) -> Public {
136 let public = self.secret.public();
137 let mut raw = [0; PUBLIC_SERIALIZED_SIZE];
138 public
139 .serialize_compressed(raw.as_mut_slice())
140 .expect("serialization length is constant and checked by test; qed");
141 Public::unchecked_from(raw)
142 }
143
144 #[cfg(feature = "full_crypto")]
145 fn sign(&self, data: &[u8]) -> Signature {
146 vrf::vrf_sign(&self.secret, &[], data)
147 }
148
149 fn verify<M: AsRef<[u8]>>(signature: &Signature, data: M, public: &Public) -> bool {
150 vrf::vrf_verify(public, &[], signature, data.as_ref())
151 }
152
153 fn to_raw_vec(&self) -> Vec<u8> {
155 self.seed().to_vec()
156 }
157}
158
159impl CryptoType for Pair {
160 type Pair = Pair;
161}
162
163impl NonAggregatable for Pair {}
164
165pub mod vrf {
167 use super::*;
168 use crate::crypto::VrfCrypto;
169
170 pub const VRF_SIGNATURE_SERIALIZED_SIZE: usize =
172 PREOUT_SERIALIZED_SIZE + SIGNATURE_SERIALIZED_SIZE;
173
174 #[derive(Clone, Debug)]
176 pub struct VrfInput(pub(super) bandersnatch::Input);
177
178 impl VrfInput {
179 pub fn new(data: &[u8]) -> Self {
183 Self(bandersnatch::Input::new(data).expect("H2C for Bandersnatch can't fail; qed"))
184 }
185 }
186
187 #[derive(Clone, Debug, PartialEq, Eq)]
191 pub struct VrfPreOutput(pub(super) bandersnatch::Output);
192
193 impl Encode for VrfPreOutput {
194 fn encode(&self) -> Vec<u8> {
195 let mut bytes = [0; PREOUT_SERIALIZED_SIZE];
196 self.0
197 .serialize_compressed(bytes.as_mut_slice())
198 .expect("serialization length is constant and checked by test; qed");
199 bytes.encode()
200 }
201 }
202
203 impl Decode for VrfPreOutput {
204 fn decode<R: codec::Input>(i: &mut R) -> Result<Self, codec::Error> {
205 let buf = <[u8; PREOUT_SERIALIZED_SIZE]>::decode(i)?;
206 let preout = bandersnatch::Output::deserialize_compressed_exact(buf.as_slice())
207 .map_err(|_| "vrf-preout decode error: bad preout")?;
208 Ok(VrfPreOutput(preout))
209 }
210 }
211
212 impl DecodeWithMemTracking for VrfPreOutput {}
223
224 impl EncodeLike for VrfPreOutput {}
225
226 impl MaxEncodedLen for VrfPreOutput {
227 fn max_encoded_len() -> usize {
228 <[u8; PREOUT_SERIALIZED_SIZE]>::max_encoded_len()
229 }
230 }
231
232 impl TypeInfo for VrfPreOutput {
233 type Identity = [u8; PREOUT_SERIALIZED_SIZE];
234
235 fn type_info() -> scale_info::Type {
236 Self::Identity::type_info()
237 }
238 }
239
240 #[derive(Clone)]
248 pub struct VrfSignData {
249 pub vrf_input: VrfInput,
251 pub aux_data: Vec<u8>,
253 }
254
255 impl VrfSignData {
256 pub fn new(vrf_input_data: &[u8], aux_data: &[u8]) -> Self {
258 Self { vrf_input: VrfInput::new(vrf_input_data), aux_data: aux_data.to_vec() }
259 }
260 }
261
262 #[derive(Clone, Debug, PartialEq, Eq, Encode, Decode, MaxEncodedLen, TypeInfo)]
269 pub struct VrfSignature {
270 pub pre_output: VrfPreOutput,
272 pub proof: Signature,
274 }
275
276 #[cfg(feature = "full_crypto")]
277 impl VrfCrypto for Pair {
278 type VrfInput = VrfInput;
279 type VrfPreOutput = VrfPreOutput;
280 type VrfSignData = VrfSignData;
281 type VrfSignature = VrfSignature;
282 }
283
284 #[cfg(feature = "full_crypto")]
285 pub(super) fn vrf_sign(secret: &Secret, ios: &[VrfIo], aux_data: &[u8]) -> Signature {
286 let proof_impl = secret.prove_thin(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 let Ok(public) = bandersnatch::Public::deserialize_compressed_exact(public.as_slice())
301 else {
302 return false;
303 };
304 let Ok(proof) = bandersnatch::ThinProof::deserialize_compressed_exact(proof.as_slice())
305 else {
306 return false;
307 };
308 public.verify_thin(ios, aux_data, &proof).is_ok()
309 }
310
311 #[cfg(feature = "full_crypto")]
312 impl VrfSecret for Pair {
313 fn vrf_sign(&self, data: &VrfSignData) -> VrfSignature {
314 let output = self.secret.output(data.vrf_input.0);
315 let pre_output = VrfPreOutput(output);
316 let io = VrfIo { input: data.vrf_input.0, output };
317 let proof = vrf_sign(&self.secret, &[io], &data.aux_data);
318 VrfSignature { pre_output, proof }
319 }
320
321 fn vrf_pre_output(&self, input: &Self::VrfInput) -> Self::VrfPreOutput {
322 let pre_output_impl = self.secret.output(input.0);
323 VrfPreOutput(pre_output_impl)
324 }
325 }
326
327 impl VrfCrypto for Public {
328 type VrfInput = VrfInput;
329 type VrfPreOutput = VrfPreOutput;
330 type VrfSignData = VrfSignData;
331 type VrfSignature = VrfSignature;
332 }
333
334 impl VrfPublic for Public {
335 fn vrf_verify(&self, data: &VrfSignData, signature: &VrfSignature) -> bool {
336 let io = VrfIo { input: data.vrf_input.0, output: signature.pre_output.0 };
337 vrf_verify(self, &[io], &signature.proof, &data.aux_data)
338 }
339 }
340
341 #[cfg(feature = "full_crypto")]
342 impl Pair {
343 pub fn make_bytes(&self, input: &VrfInput) -> [u8; 32] {
345 self.vrf_pre_output(input).make_bytes()
346 }
347 }
348
349 impl VrfPreOutput {
350 pub fn make_bytes(&self) -> [u8; 32] {
352 self.0.hash::<32>()
353 }
354 }
355}
356
357pub mod ring_vrf {
359 use super::{vrf::*, *};
360 pub use bandersnatch::{RingProver, RingVerifier};
361 use bandersnatch::{RingSetup, RingVerifierKey as RingVerifierKeyImpl};
362
363 pub(crate) fn ring_context_serialized_size(ring_size: usize) -> usize {
365 const G1_POINT_UNCOMPRESSED_SIZE: usize = 96;
366 const G2_POINT_UNCOMPRESSED_SIZE: usize = 192;
367 const OVERHEAD_SIZE: usize = 16;
368 const G2_POINTS_NUM: usize = 2;
369 let g1_points_num = ark_vrf::ring::pcs_domain_size::<BandersnatchSuite>(ring_size);
370 OVERHEAD_SIZE +
371 g1_points_num * G1_POINT_UNCOMPRESSED_SIZE +
372 G2_POINTS_NUM * G2_POINT_UNCOMPRESSED_SIZE
373 }
374
375 pub const RING_VERIFIER_KEY_SERIALIZED_SIZE: usize = 384;
377 pub(crate) const RING_PROOF_SERIALIZED_SIZE: usize = 752;
379 pub const RING_SIGNATURE_SERIALIZED_SIZE: usize =
381 RING_PROOF_SERIALIZED_SIZE + PREOUT_SERIALIZED_SIZE;
382
383 pub struct RingVerifierKey(RingVerifierKeyImpl);
385
386 impl Encode for RingVerifierKey {
387 fn encode(&self) -> Vec<u8> {
388 let mut buf = Vec::with_capacity(RING_VERIFIER_KEY_SERIALIZED_SIZE);
389 self.0
390 .serialize_compressed(&mut buf)
391 .expect("serialization length is constant and checked by test; qed");
392 buf
393 }
394 }
395
396 impl Decode for RingVerifierKey {
397 fn decode<R: codec::Input>(input: &mut R) -> Result<Self, codec::Error> {
398 let mut buf = vec![0; RING_VERIFIER_KEY_SERIALIZED_SIZE];
399 input.read(&mut buf[..])?;
400 let vk = RingVerifierKeyImpl::deserialize_compressed_exact(buf.as_slice())
401 .map_err(|_| "RingVerifierKey decode error")?;
402 Ok(RingVerifierKey(vk))
403 }
404 }
405
406 impl EncodeLike for RingVerifierKey {}
407
408 impl MaxEncodedLen for RingVerifierKey {
409 fn max_encoded_len() -> usize {
410 RING_VERIFIER_KEY_SERIALIZED_SIZE
411 }
412 }
413
414 impl TypeInfo for RingVerifierKey {
415 type Identity = [u8; RING_VERIFIER_KEY_SERIALIZED_SIZE];
416 fn type_info() -> scale_info::Type {
417 Self::Identity::type_info()
418 }
419 }
420
421 #[derive(Clone)]
425 pub struct RingContext<const R: usize>(RingSetup);
426
427 impl<const R: usize> RingContext<R> {
428 pub fn new_testing() -> Self {
430 Self(RingSetup::from_seed_insecure(R, [0; 32]))
431 }
432
433 pub fn max_keyset_size(&self) -> usize {
435 self.0.ring_context().max_ring_size()
436 }
437
438 pub fn prover(&self, public_keys: &[Public], public_idx: usize) -> RingProver {
440 let pks = Self::make_ring_vector(public_keys);
441 let prover_key = self.0.prover_key(&pks).expect("ring size within bounds; qed");
442 self.0.ring_context().ring_prover(prover_key, public_idx)
443 }
444
445 pub fn verifier(&self, public_keys: &[Public]) -> RingVerifier {
447 let vk = self.verifier_key(public_keys);
448 self.0.ring_context().ring_verifier(vk.0)
449 }
450
451 pub fn verifier_key(&self, public_keys: &[Public]) -> RingVerifierKey {
453 let pks = Self::make_ring_vector(public_keys);
454 RingVerifierKey(self.0.verifier_key(&pks).expect("ring size within bounds; qed"))
455 }
456
457 pub fn verifier_no_context(verifier_key: RingVerifierKey) -> RingVerifier {
465 bandersnatch::RingContext::new(R).into_ring_verifier(verifier_key.0)
466 }
467
468 fn make_ring_vector(public_keys: &[Public]) -> Vec<bandersnatch::Public> {
472 public_keys
473 .iter()
474 .map(|pk| {
475 bandersnatch::Public::deserialize_compressed_exact(pk.as_slice())
476 .unwrap_or(bandersnatch::Public::padding())
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_exact(buf.as_slice())
498 .map_err(|_| "RingContext decode error")?;
499 Ok(RingContext(ctx))
500 }
501 }
502
503 impl<const R: usize> EncodeLike for RingContext<R> {}
504
505 impl<const R: usize> MaxEncodedLen for RingContext<R> {
506 fn max_encoded_len() -> usize {
507 ring_context_serialized_size(R)
508 }
509 }
510
511 impl<const R: usize> TypeInfo for RingContext<R> {
512 type Identity = Self;
513 fn type_info() -> scale_info::Type {
514 let path = scale_info::Path::new("RingContext", module_path!());
515 let array_type_def = scale_info::TypeDefArray {
516 len: ring_context_serialized_size(R) as u32,
517 type_param: scale_info::MetaType::new::<u8>(),
518 };
519 let type_def = scale_info::TypeDef::Array(array_type_def);
520 scale_info::Type { path, type_params: Vec::new(), type_def, docs: Vec::new() }
521 }
522 }
523
524 #[derive(
526 Clone, Debug, PartialEq, Eq, Encode, Decode, DecodeWithMemTracking, MaxEncodedLen, TypeInfo,
527 )]
528 pub struct RingVrfSignature {
529 pub pre_output: VrfPreOutput,
531 pub proof: [u8; RING_PROOF_SERIALIZED_SIZE],
533 }
534
535 #[cfg(feature = "full_crypto")]
536 impl Pair {
537 pub fn ring_vrf_sign(&self, data: &VrfSignData, prover: &RingProver) -> RingVrfSignature {
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_ring(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 pub fn ring_vrf_verify(&self, data: &VrfSignData, verifier: &RingVerifier) -> bool {
561 let Ok(proof) =
562 bandersnatch::RingProof::deserialize_compressed_exact(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 proof.verify(io, &data.aux_data, 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_insecure(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 =
603 ark_vrf::ring::pcs_domain_size::<BandersnatchSuite>(ctx.ring_context().max_ring_size());
604 assert_eq!(domain_size, domain_size2);
605 assert_eq!(
606 ark_vrf::ring::max_ring_size_from_pcs_domain_size::<BandersnatchSuite>(domain_size),
607 Some(ctx.ring_context().max_ring_size())
608 );
609
610 assert_eq!(ctx.uncompressed_size(), ring_context_serialized_size(TEST_RING_SIZE));
611
612 let prover_key_index = 3;
613 let secret = Secret::from_seed([prover_key_index as u8; 32]);
614 let public = secret.public();
615 assert_eq!(public.compressed_size(), PUBLIC_SERIALIZED_SIZE);
616
617 let input = Input::new(b"foo").unwrap();
618 let preout = secret.output(input);
619 assert_eq!(preout.compressed_size(), PREOUT_SERIALIZED_SIZE);
620
621 let ring_keys: Vec<_> =
622 (0..TEST_RING_SIZE).map(|i| Secret::from_seed([i as u8; 32]).public()).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_context().ring_prover(prover_key, prover_key_index);
629
630 {
631 let io = VrfIo { input, output: preout };
632 let proof = secret.prove_thin(io, &[]);
633 assert_eq!(proof.compressed_size(), SIGNATURE_SERIALIZED_SIZE);
634 }
635
636 {
637 let io = VrfIo { input, output: preout };
638 let proof = secret.prove_ring(io, &[], &ring_prover);
639 assert_eq!(proof.compressed_size(), RING_PROOF_SERIALIZED_SIZE);
640 }
641 }
642
643 #[test]
644 fn derive_works() {
645 let pair = Pair::from_string(&format!("{}//Alice//Hard", DEV_PHRASE), None).unwrap();
646 let known = h2b("915626c7d4363856277e3dc0729c11df1f5a1caa1d3d0ec4986f0ae9226c5c45");
647 assert_eq!(pair.public().as_ref(), known);
648
649 let res = Pair::from_string(&format!("{}//Alice/Soft", DEV_PHRASE), None);
651 assert!(res.is_err());
652 }
653
654 #[test]
655 fn generate_with_phrase_should_be_recoverable_with_from_string() {
656 let (pair, phrase, seed) = Pair::generate_with_phrase(None);
657 let repair_seed = Pair::from_seed_slice(seed.as_ref()).expect("seed slice is valid");
658 assert_eq!(pair.public(), repair_seed.public());
659 let (repair_phrase, reseed) =
660 Pair::from_phrase(phrase.as_ref(), None).expect("seed slice is valid");
661 assert_eq!(seed, reseed);
662 assert_eq!(pair.public(), repair_phrase.public());
663 let repair_string = Pair::from_string(phrase.as_str(), None).expect("seed slice is valid");
664 assert_eq!(pair.public(), repair_string.public());
665 }
666
667 #[test]
668 fn sign_verify() {
669 let pair = Pair::from_seed(TEST_SEED);
670 let public = pair.public();
671 let msg = b"foo";
672 let signature = pair.sign(msg);
673 assert!(Pair::verify(&signature, msg, &public));
674 }
675
676 #[test]
677 fn vrf_sign_verify() {
678 let pair = Pair::from_seed(TEST_SEED);
679 let public = pair.public();
680 let data = VrfSignData::new(b"foo", b"aux");
681 let signature = pair.vrf_sign(&data);
682 assert!(public.vrf_verify(&data, &signature));
683 }
684
685 #[test]
686 fn vrf_sign_verify_with_bad_input() {
687 let pair = Pair::from_seed(TEST_SEED);
688 let public = pair.public();
689 let data = VrfSignData::new(b"foo", b"aux");
690 let signature = pair.vrf_sign(&data);
691 let data = VrfSignData::new(b"foo", b"bad");
692 assert!(!public.vrf_verify(&data, &signature));
693 let data = VrfSignData::new(b"bar", b"aux");
694 assert!(!public.vrf_verify(&data, &signature));
695 }
696
697 #[test]
698 fn vrf_output_bytes_match() {
699 let pair = Pair::from_seed(TEST_SEED);
700 let data = VrfSignData::new(b"foo", b"aux");
701 let signature = pair.vrf_sign(&data);
702 let o0 = pair.make_bytes(&data.vrf_input);
703 let o1 = signature.pre_output.make_bytes();
704 assert_eq!(o0, o1);
705 }
706
707 #[test]
708 fn vrf_signature_encode_decode() {
709 let pair = Pair::from_seed(TEST_SEED);
710
711 let data = VrfSignData::new(b"data", b"aux");
712 let expected = pair.vrf_sign(&data);
713
714 let bytes = expected.encode();
715
716 let expected_len = PREOUT_SERIALIZED_SIZE + SIGNATURE_SERIALIZED_SIZE;
717 assert_eq!(bytes.len(), expected_len);
718
719 let decoded = VrfSignature::decode(&mut bytes.as_slice()).unwrap();
720 assert_eq!(expected, decoded);
721 }
722
723 #[test]
724 fn ring_vrf_sign_verify() {
725 let ring_ctx = TestRingContext::new_testing();
726
727 let mut pks: Vec<_> =
728 (0..TEST_RING_SIZE).map(|i| Pair::from_seed(&[i as u8; 32]).public()).collect();
729 assert!(pks.len() <= ring_ctx.max_keyset_size());
730
731 let pair = Pair::from_seed(TEST_SEED);
732
733 let prover_idx = 3;
735 pks[prover_idx] = pair.public();
736 let prover = ring_ctx.prover(&pks, prover_idx);
737
738 let data = VrfSignData::new(b"data", b"aux");
739 let signature = pair.ring_vrf_sign(&data, &prover);
740
741 let verifier = ring_ctx.verifier(&pks);
742 assert!(signature.ring_vrf_verify(&data, &verifier));
743 }
744
745 #[test]
746 fn ring_vrf_sign_verify_with_out_of_ring_key() {
747 let ring_ctx = TestRingContext::new_testing();
748
749 let pks: Vec<_> =
750 (0..TEST_RING_SIZE).map(|i| Pair::from_seed(&[i as u8; 32]).public()).collect();
751 let pair = Pair::from_seed(TEST_SEED);
752
753 let data = VrfSignData::new(b"foo", b"aux");
754
755 let prover = ring_ctx.prover(&pks, 0);
757 let signature = pair.ring_vrf_sign(&data, &prover);
758
759 let verifier = ring_ctx.verifier(&pks);
760 assert!(!signature.ring_vrf_verify(&data, &verifier));
761 }
762
763 #[test]
764 fn ring_vrf_make_bytes_matches() {
765 let ring_ctx = TestRingContext::new_testing();
766
767 let mut pks: Vec<_> =
768 (0..TEST_RING_SIZE).map(|i| Pair::from_seed(&[i as u8; 32]).public()).collect();
769 assert!(pks.len() <= ring_ctx.max_keyset_size());
770
771 let pair = Pair::from_seed(TEST_SEED);
772
773 let prover_idx = 3;
775 pks[prover_idx] = pair.public();
776
777 let data = VrfSignData::new(b"data", b"aux");
778
779 let prover = ring_ctx.prover(&pks, prover_idx);
780 let signature = pair.ring_vrf_sign(&data, &prover);
781
782 let o0 = pair.make_bytes(&data.vrf_input);
783 let o1 = signature.pre_output.make_bytes();
784 assert_eq!(o0, o1);
785 }
786
787 #[test]
788 fn ring_vrf_signature_encode_decode() {
789 let ring_ctx = TestRingContext::new_testing();
790
791 let mut pks: Vec<_> =
792 (0..TEST_RING_SIZE).map(|i| Pair::from_seed(&[i as u8; 32]).public()).collect();
793 assert!(pks.len() <= ring_ctx.max_keyset_size());
794
795 let pair = Pair::from_seed(TEST_SEED);
796
797 let prover_idx = 3;
799 pks[prover_idx] = pair.public();
800
801 let data = VrfSignData::new(b"foo", b"aux");
802
803 let prover = ring_ctx.prover(&pks, prover_idx);
804 let expected = pair.ring_vrf_sign(&data, &prover);
805
806 let bytes = expected.encode();
807 assert_eq!(bytes.len(), RING_SIGNATURE_SERIALIZED_SIZE);
808
809 let decoded = RingVrfSignature::decode(&mut bytes.as_slice()).unwrap();
810 assert_eq!(expected, decoded);
811 }
812
813 #[test]
814 fn ring_vrf_context_encode_decode() {
815 let ctx1 = TestRingContext::new_testing();
816 let enc1 = ctx1.encode();
817
818 assert_eq!(enc1.len(), ring_context_serialized_size(TEST_RING_SIZE));
819 assert_eq!(enc1.len(), TestRingContext::max_encoded_len());
820
821 let ctx2 = TestRingContext::decode(&mut enc1.as_slice()).unwrap();
822 let enc2 = ctx2.encode();
823
824 assert_eq!(enc1, enc2);
825 }
826
827 #[test]
828 fn verifier_key_encode_decode() {
829 let ring_ctx = TestRingContext::new_testing();
830
831 let pks: Vec<_> =
832 (0..TEST_RING_SIZE).map(|i| Pair::from_seed(&[i as u8; 32]).public()).collect();
833 assert!(pks.len() <= ring_ctx.max_keyset_size());
834
835 let verifier_key = ring_ctx.verifier_key(&pks);
836 let enc1 = verifier_key.encode();
837 assert_eq!(enc1.len(), RING_VERIFIER_KEY_SERIALIZED_SIZE);
838 assert_eq!(RingVerifierKey::max_encoded_len(), RING_VERIFIER_KEY_SERIALIZED_SIZE);
839
840 let vd2 = RingVerifierKey::decode(&mut enc1.as_slice()).unwrap();
841 let enc2 = vd2.encode();
842 assert_eq!(enc1, enc2);
843 }
844
845 #[test]
849 fn ring_vrf_invalid_ring_keys_become_padding() {
850 use ark_vrf::reexports::ark_ff::{One, Zero};
851 use bandersnatch::{AffinePoint, BaseField};
852
853 fn public_from(point: impl CanonicalSerialize) -> Public {
854 let mut raw = [0; PUBLIC_SERIALIZED_SIZE];
855 point.serialize_compressed(raw.as_mut_slice()).unwrap();
856 Public::unchecked_from(raw)
857 }
858 let identity = public_from(AffinePoint::zero());
859 let order_two =
860 public_from(AffinePoint::new_unchecked(BaseField::zero(), -BaseField::one()));
861 let padding = public_from(bandersnatch::Public::padding());
862
863 let ring_ctx = TestRingContext::new_testing();
864 let mut pks: Vec<_> =
865 (0..TEST_RING_SIZE).map(|i| Pair::from_seed(&[i as u8; 32]).public()).collect();
866 let mut padded_pks = pks.clone();
867 pks[1] = identity;
868 pks[2] = order_two;
869 padded_pks[1] = padding;
870 padded_pks[2] = padding;
871
872 assert_eq!(
873 ring_ctx.verifier_key(&pks).encode(),
874 ring_ctx.verifier_key(&padded_pks).encode()
875 );
876 }
877
878 #[test]
881 fn verifier_key_decode_rejects_point_out_of_subgroup() {
882 const G1_COMPRESSED_SIZE: usize = 48;
883 const COMPRESSED_FLAG: u8 = 0x80;
884
885 let ring_ctx = TestRingContext::new_testing();
886 let pks: Vec<_> =
887 (0..TEST_RING_SIZE).map(|i| Pair::from_seed(&[i as u8; 32]).public()).collect();
888 let mut encoded = ring_ctx.verifier_key(&pks).encode();
889
890 let commitment = encoded.len() - G1_COMPRESSED_SIZE;
893 encoded[commitment..].fill(0);
894 encoded[commitment] = COMPRESSED_FLAG;
895 assert!(bandersnatch::RingVerifierKey::deserialize_compressed_unchecked_exact(
896 encoded.as_slice()
897 )
898 .is_ok());
899
900 assert!(RingVerifierKey::decode(&mut encoded.as_slice()).is_err());
901 }
902
903 #[test]
904 fn good_proof_of_possession_should_work_bad_proof_of_possession_should_fail() {
905 let owner = b"owner";
906 let not_owner = b"not owner";
907 let mut pair = Pair::from_seed(b"12345678901234567890123456789012");
908 let other_pair = Pair::from_seed(b"23456789012345678901234567890123");
909 let proof_of_possession = pair.generate_proof_of_possession(owner);
910 assert!(Pair::verify_proof_of_possession(owner, &proof_of_possession, &pair.public()));
911 assert!(!Pair::verify_proof_of_possession(
912 owner,
913 &proof_of_possession,
914 &other_pair.public()
915 ));
916 assert!(!Pair::verify_proof_of_possession(not_owner, &proof_of_possession, &pair.public()));
917 }
918}