Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Commit

Permalink
Clarify behavior for out of ring keys signatures
Browse files Browse the repository at this point in the history
  • Loading branch information
davxy committed Aug 9, 2023
1 parent b339b3a commit 2b2676b
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 7 deletions.
32 changes: 27 additions & 5 deletions primitives/core/src/bandersnatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

//! VRFs backed by [Bandersnatch](https://neuromancer.sk/std/bls/Bandersnatch),
//! an elliptic curve built over BLS12-381 scalar field.
//!
//! The primitive can operate both as a traditional VRF or as an anonymized ring VRF.

#[cfg(feature = "std")]
use crate::crypto::Ss58Codec;
Expand Down Expand Up @@ -702,8 +704,9 @@ pub mod ring_vrf {
impl Pair {
/// Produce a ring-vrf signature.
///
/// The signature is valid if the signing [`Pair`] is part of the ring from which
/// the [`RingProver`] has been derived.
/// The ring signature is verifiable if the public key corresponding to the
/// signing [`Pair`] is part of the ring from which the [`RingProver`] has
/// been constructed. If not, the produced signature is just useless.
pub fn ring_vrf_sign(&self, data: &VrfSignData, prover: &RingProver) -> RingVrfSignature {
const _: () = assert!(MAX_VRF_IOS == 3, "`MAX_VRF_IOS` expected to be 3");
// Workaround to overcome backend signature generic over the number of IOs.
Expand Down Expand Up @@ -752,8 +755,8 @@ pub mod ring_vrf {
impl RingVrfSignature {
/// Verify a ring-vrf signature.
///
/// The signature is valid if has been produced by a member of the ring from which
/// the [`RingVerifier`] has been derived.
/// The signature is verifiable if it has been produced by a member of the ring
/// from which the [`RingVerifier`] has been constructed.
pub fn verify(&self, data: &VrfSignData, verifier: &RingVerifier) -> bool {
const _: () = assert!(MAX_VRF_IOS == 3, "`MAX_VRF_IOS` expected to be 3");
let preouts_len = self.outputs.len();
Expand Down Expand Up @@ -808,7 +811,7 @@ pub mod ring_vrf {
mod tests {
use super::{ring_vrf::*, vrf::*, *};
use crate::crypto::{VrfPublic, VrfSecret, DEV_PHRASE};
const DEV_SEED: &[u8; SEED_SERIALIZED_LEN] = &[0; SEED_SERIALIZED_LEN];
const DEV_SEED: &[u8; SEED_SERIALIZED_LEN] = &[0xcb; SEED_SERIALIZED_LEN];

#[allow(unused)]
fn b2h(bytes: &[u8]) -> String {
Expand Down Expand Up @@ -971,6 +974,25 @@ mod tests {
assert!(signature.verify(&data, &verifier));
}

#[test]
fn ring_vrf_sign_verify_with_out_of_ring_key() {
let ring_ctx = RingContext::new_testing();

let pks: Vec<_> = (0..16).map(|i| Pair::from_seed(&[i as u8; 32]).public()).collect();
let pair = Pair::from_seed(DEV_SEED);

// Just pick one index to patch with the actual public key
let i1 = VrfInput::new(b"dom1", b"foo");
let data = VrfSignData::new_unchecked(b"mydata", Some(b"tdata"), Some(i1));

// pair.public != pks[0]
let prover = ring_ctx.prover(&pks, 0).unwrap();
let signature = pair.ring_vrf_sign(&data, &prover);

let verifier = ring_ctx.verifier(&pks).unwrap();
assert!(!signature.verify(&data, &verifier));
}

#[test]
fn encode_decode_ring_vrf_signature() {
let ring_ctx = RingContext::new_testing();
Expand Down
5 changes: 3 additions & 2 deletions primitives/keystore/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,8 +245,9 @@ pub trait Keystore: Send + Sync {
/// Also takes a [`bandersnatch::ring_vrf::RingProver`] instance obtained from
/// a valid [`bandersnatch::ring_vrf::RingContext`].
///
/// The signature is valid if the signing key is part of the ring from which
/// the `RingProver` has been derived.
/// The ring signature is verifiable if the public key corresponding to the
/// signing [`Pair`] is part of the ring from which the [`RingProver`] has
/// been constructed. If not, the produced signature is just useless.
///
/// Returns `None` if the given `key_type` and `public` combination doesn't
/// exist in the keystore or an `Err` when something failed.
Expand Down

0 comments on commit 2b2676b

Please sign in to comment.