Refinements to VRF types (#14036)

* Allow extra signing data

* Fix tests after renaming

* Rename VrfSecret/VrfVerifier to VrfSecret/VrfPublic

* Further encrapsulation of 'transcript' type to the sr25519 implementation

* Keystore sr25519 pre-output

* Leave additional custom input field hidden in the associated VrfInput type

* Fix test

* More ergonomic output_bytes

* Trigger pipeline

* Define a separated type for vrf signature data

* Fix docs

* Fix doc

* Remove annotation

* Directly use dleq_proove and dleq_verify in sr25519

* Trigger CI

* Remove cruft before merge
This commit is contained in:
Davide Galassi
2023-05-04 15:41:59 +02:00
committed by GitHub
parent 93165bc4d2
commit 3a90728de0
12 changed files with 384 additions and 138 deletions
@@ -24,7 +24,7 @@ use sc_consensus_epochs::Epoch as EpochT;
use sp_application_crypto::AppCrypto;
use sp_consensus_babe::{
digests::{PreDigest, PrimaryPreDigest, SecondaryPlainPreDigest, SecondaryVRFPreDigest},
make_transcript, AuthorityId, BabeAuthorityWeight, Randomness, Slot,
make_vrf_sign_data, AuthorityId, BabeAuthorityWeight, Randomness, Slot,
};
use sp_core::{
blake2_256,
@@ -148,9 +148,9 @@ fn claim_secondary_slot(
for (authority_id, authority_index) in keys {
if authority_id == expected_author {
let pre_digest = if author_secondary_vrf {
let transcript = make_transcript(randomness, slot, epoch_index);
let data = make_vrf_sign_data(randomness, slot, epoch_index);
let result =
keystore.sr25519_vrf_sign(AuthorityId::ID, authority_id.as_ref(), &transcript);
keystore.sr25519_vrf_sign(AuthorityId::ID, authority_id.as_ref(), &data);
if let Ok(Some(vrf_signature)) = result {
Some(PreDigest::SecondaryVRF(SecondaryVRFPreDigest {
slot,
@@ -239,18 +239,18 @@ fn claim_primary_slot(
epoch_index = epoch.clone_for_slot(slot).epoch_index;
}
let transcript = make_transcript(randomness, slot, epoch_index);
let data = make_vrf_sign_data(randomness, slot, epoch_index);
for (authority_id, authority_index) in keys {
let result = keystore.sr25519_vrf_sign(AuthorityId::ID, authority_id.as_ref(), &transcript);
let result = keystore.sr25519_vrf_sign(AuthorityId::ID, authority_id.as_ref(), &data);
if let Ok(Some(vrf_signature)) = result {
let threshold = calculate_primary_threshold(c, authorities, *authority_index);
let can_claim = authority_id
.as_inner_ref()
.make_bytes::<[u8; AUTHORING_SCORE_LENGTH]>(
.make_bytes::<AUTHORING_SCORE_LENGTH>(
AUTHORING_SCORE_VRF_CONTEXT,
&transcript,
&data.as_ref(),
&vrf_signature.output,
)
.map(|bytes| u128::from_le_bytes(bytes) < threshold)
+9 -21
View File
@@ -29,7 +29,7 @@ use sc_network_test::{Block as TestBlock, *};
use sp_application_crypto::key_types::BABE;
use sp_consensus::{DisableProofRecording, NoNetwork as DummyOracle, Proposal};
use sp_consensus_babe::{
inherents::InherentDataProvider, make_transcript, AllowedSlots, AuthorityId, AuthorityPair,
inherents::InherentDataProvider, make_vrf_sign_data, AllowedSlots, AuthorityId, AuthorityPair,
Slot,
};
use sp_consensus_slots::SlotDuration;
@@ -630,11 +630,8 @@ fn claim_vrf_check() {
PreDigest::Primary(d) => d,
v => panic!("Unexpected pre-digest variant {:?}", v),
};
let transcript = make_transcript(&epoch.randomness.clone(), 0.into(), epoch.epoch_index);
let sign = keystore
.sr25519_vrf_sign(AuthorityId::ID, &public, &transcript)
.unwrap()
.unwrap();
let data = make_vrf_sign_data(&epoch.randomness.clone(), 0.into(), epoch.epoch_index);
let sign = keystore.sr25519_vrf_sign(AuthorityId::ID, &public, &data).unwrap().unwrap();
assert_eq!(pre_digest.vrf_signature.output, sign.output);
// We expect a SecondaryVRF claim for slot 1
@@ -642,11 +639,8 @@ fn claim_vrf_check() {
PreDigest::SecondaryVRF(d) => d,
v => panic!("Unexpected pre-digest variant {:?}", v),
};
let transcript = make_transcript(&epoch.randomness.clone(), 1.into(), epoch.epoch_index);
let sign = keystore
.sr25519_vrf_sign(AuthorityId::ID, &public, &transcript)
.unwrap()
.unwrap();
let data = make_vrf_sign_data(&epoch.randomness.clone(), 1.into(), epoch.epoch_index);
let sign = keystore.sr25519_vrf_sign(AuthorityId::ID, &public, &data).unwrap().unwrap();
assert_eq!(pre_digest.vrf_signature.output, sign.output);
// Check that correct epoch index has been used if epochs are skipped (primary VRF)
@@ -656,11 +650,8 @@ fn claim_vrf_check() {
v => panic!("Unexpected claim variant {:?}", v),
};
let fixed_epoch = epoch.clone_for_slot(slot);
let transcript = make_transcript(&epoch.randomness.clone(), slot, fixed_epoch.epoch_index);
let sign = keystore
.sr25519_vrf_sign(AuthorityId::ID, &public, &transcript)
.unwrap()
.unwrap();
let data = make_vrf_sign_data(&epoch.randomness.clone(), slot, fixed_epoch.epoch_index);
let sign = keystore.sr25519_vrf_sign(AuthorityId::ID, &public, &data).unwrap().unwrap();
assert_eq!(fixed_epoch.epoch_index, 11);
assert_eq!(claim.vrf_signature.output, sign.output);
@@ -671,11 +662,8 @@ fn claim_vrf_check() {
v => panic!("Unexpected claim variant {:?}", v),
};
let fixed_epoch = epoch.clone_for_slot(slot);
let transcript = make_transcript(&epoch.randomness.clone(), slot, fixed_epoch.epoch_index);
let sign = keystore
.sr25519_vrf_sign(AuthorityId::ID, &public, &transcript)
.unwrap()
.unwrap();
let data = make_vrf_sign_data(&epoch.randomness.clone(), slot, fixed_epoch.epoch_index);
let sign = keystore.sr25519_vrf_sign(AuthorityId::ID, &public, &data).unwrap().unwrap();
assert_eq!(fixed_epoch.epoch_index, 11);
assert_eq!(pre_digest.vrf_signature.output, sign.output);
}
@@ -30,11 +30,11 @@ use sp_consensus_babe::{
CompatibleDigestItem, PreDigest, PrimaryPreDigest, SecondaryPlainPreDigest,
SecondaryVRFPreDigest,
},
make_transcript, AuthorityId, AuthorityPair, AuthoritySignature,
make_vrf_sign_data, AuthorityId, AuthorityPair, AuthoritySignature,
};
use sp_consensus_slots::Slot;
use sp_core::{
crypto::{VrfVerifier, Wraps},
crypto::{VrfPublic, Wraps},
Pair,
};
use sp_runtime::{traits::Header, DigestItem};
@@ -171,9 +171,9 @@ fn check_primary_header<B: BlockT + Sized>(
return Err(babe_err(Error::BadSignature(pre_hash)))
}
let transcript = make_transcript(&epoch.randomness, pre_digest.slot, epoch_index);
let data = make_vrf_sign_data(&epoch.randomness, pre_digest.slot, epoch_index);
if !authority_id.as_inner_ref().vrf_verify(&transcript, &pre_digest.vrf_signature) {
if !authority_id.as_inner_ref().vrf_verify(&data, &pre_digest.vrf_signature) {
return Err(babe_err(Error::VrfVerificationFailed))
}
@@ -182,9 +182,9 @@ fn check_primary_header<B: BlockT + Sized>(
let score = authority_id
.as_inner_ref()
.make_bytes::<[u8; AUTHORING_SCORE_LENGTH]>(
.make_bytes::<AUTHORING_SCORE_LENGTH>(
AUTHORING_SCORE_VRF_CONTEXT,
&transcript,
&data.as_ref(),
&pre_digest.vrf_signature.output,
)
.map(u128::from_le_bytes)
@@ -253,9 +253,9 @@ fn check_secondary_vrf_header<B: BlockT>(
return Err(Error::BadSignature(pre_hash))
}
let transcript = make_transcript(&epoch.randomness, pre_digest.slot, epoch_index);
let data = make_vrf_sign_data(&epoch.randomness, pre_digest.slot, epoch_index);
if !author.as_inner_ref().vrf_verify(&transcript, &pre_digest.vrf_signature) {
if !author.as_inner_ref().vrf_verify(&data, &pre_digest.vrf_signature) {
return Err(Error::VrfVerificationFailed)
}