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::{CanonicalDeserialize, CanonicalSerialize},
35 suites::bandersnatch::{self, BandersnatchSha512Ell2 as BandersnatchSuite, Secret, VrfIo},
36};
37use codec::{Decode, DecodeWithMemTracking, Encode, EncodeLike, MaxEncodedLen};
38use scale_info::TypeInfo;
39
40pub const CRYPTO_ID: CryptoTypeId = CryptoTypeId(*b"band");
42
43pub const SEED_SERIALIZED_SIZE: usize = 32;
45
46pub const PUBLIC_SERIALIZED_SIZE: usize = 32;
48
49pub const SIGNATURE_SERIALIZED_SIZE: usize = 64;
51
52pub const PREOUT_SERIALIZED_SIZE: usize = 32;
54
55#[doc(hidden)]
56pub struct BandersnatchTag;
57
58pub type Public = PublicBytes<PUBLIC_SERIALIZED_SIZE, BandersnatchTag>;
60
61impl CryptoType for Public {
62 type Pair = Pair;
63}
64
65pub type Signature = SignatureBytes<SIGNATURE_SERIALIZED_SIZE, BandersnatchTag>;
67
68pub type ProofOfPossession = Signature;
70
71impl CryptoType for Signature {
72 type Pair = Pair;
73}
74
75type Seed = [u8; SEED_SERIALIZED_SIZE];
77
78#[derive(Clone)]
80pub struct Pair {
81 secret: Secret,
82 seed: Seed,
83}
84
85impl Pair {
86 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 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 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 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
164pub mod vrf {
166 use super::*;
167 use crate::crypto::VrfCrypto;
168
169 pub const VRF_SIGNATURE_SERIALIZED_SIZE: usize =
171 PREOUT_SERIALIZED_SIZE + SIGNATURE_SERIALIZED_SIZE;
172
173 #[derive(Clone, Debug)]
175 pub struct VrfInput(pub(super) bandersnatch::Input);
176
177 impl VrfInput {
178 pub fn new(data: &[u8]) -> Self {
182 Self(bandersnatch::Input::new(data).expect("H2C for Bandersnatch can't fail; qed"))
183 }
184 }
185
186 #[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 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 #[derive(Clone)]
247 pub struct VrfSignData {
248 pub vrf_input: VrfInput,
250 pub aux_data: Vec<u8>,
252 }
253
254 impl VrfSignData {
255 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 #[derive(Clone, Debug, PartialEq, Eq, Encode, Decode, MaxEncodedLen, TypeInfo)]
268 pub struct VrfSignature {
269 pub pre_output: VrfPreOutput,
271 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 pub fn make_bytes(&self, input: &VrfInput) -> [u8; 32] {
346 self.vrf_pre_output(input).make_bytes()
347 }
348 }
349
350 impl VrfPreOutput {
351 pub fn make_bytes(&self) -> [u8; 32] {
353 self.0.hash::<32>()
354 }
355 }
356}
357
358pub mod ring_vrf {
360 use super::{vrf::*, *};
361 pub use bandersnatch::{RingProver, RingVerifier};
362 use bandersnatch::{RingSetup, RingVerifierKey as RingVerifierKeyImpl};
363
364 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 pub const RING_VERIFIER_KEY_SERIALIZED_SIZE: usize = 384;
378 pub(crate) const RING_PROOF_SERIALIZED_SIZE: usize = 752;
380 pub const RING_SIGNATURE_SERIALIZED_SIZE: usize =
382 RING_PROOF_SERIALIZED_SIZE + PREOUT_SERIALIZED_SIZE;
383
384 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 #[derive(Clone)]
426 pub struct RingContext<const R: usize>(RingSetup);
427
428 impl<const R: usize> RingContext<R> {
429 pub fn new_testing() -> Self {
431 Self(RingSetup::from_seed(R, [0; 32]))
432 }
433
434 pub fn max_keyset_size(&self) -> usize {
436 self.0.max_ring_size()
437 }
438
439 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 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 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 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 #[derive(
525 Clone, Debug, PartialEq, Eq, Encode, Decode, DecodeWithMemTracking, MaxEncodedLen, TypeInfo,
526 )]
527 pub struct RingVrfSignature {
528 pub pre_output: VrfPreOutput,
530 pub proof: [u8; RING_PROOF_SERIALIZED_SIZE],
532 }
533
534 #[cfg(feature = "full_crypto")]
535 impl Pair {
536 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 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 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 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 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 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 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}