mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-07-19 19:15:41 +00:00
sp-core: Rename VrfOutput to VrfPreOutput (#2534)
This will make more sense after https://github.com/paritytech/polkadot-sdk/pull/2524 since the schnorrkel type for VRF outputs is also renamed in the latest version. Can be reviewed independently though. Can be merged after https://github.com/paritytech/polkadot-sdk/pull/1577 so that there is less pain for @davxy. --------- Co-authored-by: Bastian Köcher <git@kchr.de>
This commit is contained in:
@@ -33,7 +33,7 @@ use sp_std::vec::Vec;
|
||||
use crate::digests::{NextConfigDescriptor, NextEpochDescriptor};
|
||||
|
||||
pub use sp_core::sr25519::vrf::{
|
||||
VrfInput, VrfOutput, VrfProof, VrfSignData, VrfSignature, VrfTranscript,
|
||||
VrfInput, VrfPreOutput, VrfProof, VrfSignData, VrfSignature, VrfTranscript,
|
||||
};
|
||||
|
||||
/// Key type for BABE module.
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! Utilities related to VRF input, output and signatures.
|
||||
//! Utilities related to VRF input, pre-output and signatures.
|
||||
|
||||
use crate::{Randomness, TicketBody, TicketId};
|
||||
use scale_codec::Encode;
|
||||
@@ -24,7 +24,7 @@ use sp_std::vec::Vec;
|
||||
|
||||
pub use sp_core::bandersnatch::{
|
||||
ring_vrf::{RingProver, RingVerifier, RingVerifierData, RingVrfSignature},
|
||||
vrf::{VrfInput, VrfOutput, VrfSignData, VrfSignature},
|
||||
vrf::{VrfInput, VrfPreOutput, VrfSignData, VrfSignature},
|
||||
};
|
||||
|
||||
/// Ring VRF domain size for Sassafras consensus.
|
||||
@@ -90,21 +90,21 @@ pub fn ticket_body_sign_data(ticket_body: &TicketBody, ticket_id_input: VrfInput
|
||||
)
|
||||
}
|
||||
|
||||
/// Make ticket-id from the given VRF input and output.
|
||||
/// Make ticket-id from the given VRF input and pre-output.
|
||||
///
|
||||
/// Input should have been obtained via [`ticket_id_input`].
|
||||
/// Output should have been obtained from the input directly using the vrf secret key
|
||||
/// or from the vrf signature outputs.
|
||||
pub fn make_ticket_id(input: &VrfInput, output: &VrfOutput) -> TicketId {
|
||||
let bytes = output.make_bytes::<16>(b"ticket-id", input);
|
||||
/// Pre-output should have been obtained from the input directly using the vrf
|
||||
/// secret key or from the vrf signature pre-outputs.
|
||||
pub fn make_ticket_id(input: &VrfInput, pre_output: &VrfPreOutput) -> TicketId {
|
||||
let bytes = pre_output.make_bytes::<16>(b"ticket-id", input);
|
||||
u128::from_le_bytes(bytes)
|
||||
}
|
||||
|
||||
/// Make revealed key seed from a given VRF input and ouput.
|
||||
/// Make revealed key seed from a given VRF input and pre-ouput.
|
||||
///
|
||||
/// Input should have been obtained via [`revealed_key_input`].
|
||||
/// Output should have been obtained from the input directly using the vrf secret key
|
||||
/// or from the vrf signature outputs.
|
||||
pub fn make_revealed_key_seed(input: &VrfInput, output: &VrfOutput) -> [u8; 32] {
|
||||
output.make_bytes::<32>(b"revealed-seed", input)
|
||||
/// Pre-output should have been obtained from the input directly using the vrf
|
||||
/// secret key or from the vrf signature pre-outputs.
|
||||
pub fn make_revealed_key_seed(input: &VrfInput, pre_output: &VrfPreOutput) -> [u8; 32] {
|
||||
pre_output.make_bytes::<32>(b"revealed-seed", input)
|
||||
}
|
||||
|
||||
@@ -295,7 +295,7 @@ impl TraitPair for Pair {
|
||||
fn verify<M: AsRef<[u8]>>(signature: &Signature, data: M, public: &Public) -> bool {
|
||||
let data = vrf::VrfSignData::new_unchecked(SIGNING_CTX, &[data.as_ref()], None);
|
||||
let signature =
|
||||
vrf::VrfSignature { signature: *signature, outputs: vrf::VrfIosVec::default() };
|
||||
vrf::VrfSignature { signature: *signature, pre_outputs: vrf::VrfIosVec::default() };
|
||||
public.vrf_verify(&data, &signature)
|
||||
}
|
||||
|
||||
@@ -319,18 +319,18 @@ pub mod vrf {
|
||||
ThinVrfSignature, Transcript,
|
||||
};
|
||||
|
||||
/// Max number of inputs/outputs which can be handled by the VRF signing procedures.
|
||||
/// Max number of inputs/pre-outputs which can be handled by the VRF signing procedures.
|
||||
///
|
||||
/// The number is quite arbitrary and chosen to fulfill the use cases found so far.
|
||||
/// If required it can be extended in the future.
|
||||
pub const MAX_VRF_IOS: u32 = 3;
|
||||
|
||||
/// Bounded vector used for VRF inputs and outputs.
|
||||
/// Bounded vector used for VRF inputs and pre-outputs.
|
||||
///
|
||||
/// Can contain at most [`MAX_VRF_IOS`] elements.
|
||||
pub type VrfIosVec<T> = BoundedVec<T, ConstU32<MAX_VRF_IOS>>;
|
||||
|
||||
/// VRF input to construct a [`VrfOutput`] instance and embeddable in [`VrfSignData`].
|
||||
/// VRF input to construct a [`VrfPreOutput`] instance and embeddable in [`VrfSignData`].
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct VrfInput(pub(super) bandersnatch_vrfs::VrfInput);
|
||||
|
||||
@@ -342,15 +342,15 @@ pub mod vrf {
|
||||
}
|
||||
}
|
||||
|
||||
/// VRF (pre)output derived from [`VrfInput`] using a [`VrfSecret`].
|
||||
/// VRF pre-output derived from [`VrfInput`] using a [`VrfSecret`].
|
||||
///
|
||||
/// This object is used to produce an arbitrary number of verifiable pseudo random
|
||||
/// bytes and is often called pre-output to emphasize that this is not the actual
|
||||
/// output of the VRF but an object capable of generating the output.
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct VrfOutput(pub(super) bandersnatch_vrfs::VrfPreOut);
|
||||
pub struct VrfPreOutput(pub(super) bandersnatch_vrfs::VrfPreOut);
|
||||
|
||||
impl Encode for VrfOutput {
|
||||
impl Encode for VrfPreOutput {
|
||||
fn encode(&self) -> Vec<u8> {
|
||||
let mut bytes = [0; PREOUT_SERIALIZED_SIZE];
|
||||
self.0
|
||||
@@ -360,25 +360,25 @@ pub mod vrf {
|
||||
}
|
||||
}
|
||||
|
||||
impl Decode for VrfOutput {
|
||||
impl Decode for VrfPreOutput {
|
||||
fn decode<R: codec::Input>(i: &mut R) -> Result<Self, codec::Error> {
|
||||
let buf = <[u8; PREOUT_SERIALIZED_SIZE]>::decode(i)?;
|
||||
let preout =
|
||||
bandersnatch_vrfs::VrfPreOut::deserialize_compressed_unchecked(buf.as_slice())
|
||||
.map_err(|_| "vrf-preout decode error: bad preout")?;
|
||||
Ok(VrfOutput(preout))
|
||||
Ok(VrfPreOutput(preout))
|
||||
}
|
||||
}
|
||||
|
||||
impl EncodeLike for VrfOutput {}
|
||||
impl EncodeLike for VrfPreOutput {}
|
||||
|
||||
impl MaxEncodedLen for VrfOutput {
|
||||
impl MaxEncodedLen for VrfPreOutput {
|
||||
fn max_encoded_len() -> usize {
|
||||
<[u8; PREOUT_SERIALIZED_SIZE]>::max_encoded_len()
|
||||
}
|
||||
}
|
||||
|
||||
impl TypeInfo for VrfOutput {
|
||||
impl TypeInfo for VrfPreOutput {
|
||||
type Identity = [u8; PREOUT_SERIALIZED_SIZE];
|
||||
|
||||
fn type_info() -> scale_info::Type {
|
||||
@@ -395,14 +395,14 @@ pub mod vrf {
|
||||
/// A good explaination of the topic can be found in Merlin [docs](https://merlin.cool/)
|
||||
///
|
||||
/// The `inputs` is a sequence of [`VrfInput`]s which, during the signing procedure, are
|
||||
/// first transformed to [`VrfOutput`]s. Both inputs and outputs are then appended to
|
||||
/// first transformed to [`VrfPreOutput`]s. Both inputs and pre-outputs are then appended to
|
||||
/// the transcript before signing the Fiat-Shamir transform result (the challenge).
|
||||
///
|
||||
/// In practice, as a user, all these technical details can be easily ignored.
|
||||
/// What is important to remember is:
|
||||
/// - *Transcript* is an object defining the protocol and used to produce the signature. This
|
||||
/// object doesn't influence the `VrfOutput`s values.
|
||||
/// - *Vrf inputs* is some additional data which is used to produce *vrf outputs*. This data
|
||||
/// object doesn't influence the `VrfPreOutput`s values.
|
||||
/// - *Vrf inputs* is some additional data which is used to produce *vrf pre-outputs*. This data
|
||||
/// will contribute to the signature as well.
|
||||
#[derive(Clone)]
|
||||
pub struct VrfSignData {
|
||||
@@ -473,7 +473,7 @@ pub mod vrf {
|
||||
|
||||
/// VRF signature.
|
||||
///
|
||||
/// Includes both the transcript `signature` and the `outputs` generated from the
|
||||
/// Includes both the transcript `signature` and the `pre-outputs` generated from the
|
||||
/// [`VrfSignData::inputs`].
|
||||
///
|
||||
/// Refer to [`VrfSignData`] for more details.
|
||||
@@ -481,14 +481,14 @@ pub mod vrf {
|
||||
pub struct VrfSignature {
|
||||
/// Transcript signature.
|
||||
pub signature: Signature,
|
||||
/// VRF (pre)outputs.
|
||||
pub outputs: VrfIosVec<VrfOutput>,
|
||||
/// VRF pre-outputs.
|
||||
pub pre_outputs: VrfIosVec<VrfPreOutput>,
|
||||
}
|
||||
|
||||
#[cfg(feature = "full_crypto")]
|
||||
impl VrfCrypto for Pair {
|
||||
type VrfInput = VrfInput;
|
||||
type VrfOutput = VrfOutput;
|
||||
type VrfPreOutput = VrfPreOutput;
|
||||
type VrfSignData = VrfSignData;
|
||||
type VrfSignature = VrfSignature;
|
||||
}
|
||||
@@ -507,15 +507,15 @@ pub mod vrf {
|
||||
}
|
||||
}
|
||||
|
||||
fn vrf_output(&self, input: &Self::VrfInput) -> Self::VrfOutput {
|
||||
let output = self.secret.vrf_preout(&input.0);
|
||||
VrfOutput(output)
|
||||
fn vrf_pre_output(&self, input: &Self::VrfInput) -> Self::VrfPreOutput {
|
||||
let pre_output = self.secret.vrf_preout(&input.0);
|
||||
VrfPreOutput(pre_output)
|
||||
}
|
||||
}
|
||||
|
||||
impl VrfCrypto for Public {
|
||||
type VrfInput = VrfInput;
|
||||
type VrfOutput = VrfOutput;
|
||||
type VrfPreOutput = VrfPreOutput;
|
||||
type VrfSignData = VrfSignData;
|
||||
type VrfSignature = VrfSignature;
|
||||
}
|
||||
@@ -523,12 +523,12 @@ pub mod vrf {
|
||||
impl VrfPublic for Public {
|
||||
fn vrf_verify(&self, data: &Self::VrfSignData, signature: &Self::VrfSignature) -> bool {
|
||||
const _: () = assert!(MAX_VRF_IOS == 3, "`MAX_VRF_IOS` expected to be 3");
|
||||
let outputs_len = signature.outputs.len();
|
||||
if outputs_len != data.inputs.len() {
|
||||
let pre_outputs_len = signature.pre_outputs.len();
|
||||
if pre_outputs_len != data.inputs.len() {
|
||||
return false
|
||||
}
|
||||
// Workaround to overcome backend signature generic over the number of IOs.
|
||||
match outputs_len {
|
||||
match pre_outputs_len {
|
||||
0 => self.vrf_verify_gen::<0>(data, signature),
|
||||
1 => self.vrf_verify_gen::<1>(data, signature),
|
||||
2 => self.vrf_verify_gen::<2>(data, signature),
|
||||
@@ -546,11 +546,12 @@ pub mod vrf {
|
||||
let thin_signature: ThinVrfSignature<N> =
|
||||
self.secret.sign_thin_vrf(data.transcript.clone(), &ios);
|
||||
|
||||
let outputs: Vec<_> = thin_signature.preouts.into_iter().map(VrfOutput).collect();
|
||||
let outputs = VrfIosVec::truncate_from(outputs);
|
||||
let pre_outputs: Vec<_> =
|
||||
thin_signature.preouts.into_iter().map(VrfPreOutput).collect();
|
||||
let pre_outputs = VrfIosVec::truncate_from(pre_outputs);
|
||||
|
||||
let mut signature =
|
||||
VrfSignature { signature: Signature([0; SIGNATURE_SERIALIZED_SIZE]), outputs };
|
||||
VrfSignature { signature: Signature([0; SIGNATURE_SERIALIZED_SIZE]), pre_outputs };
|
||||
|
||||
thin_signature
|
||||
.proof
|
||||
@@ -583,7 +584,7 @@ pub mod vrf {
|
||||
};
|
||||
|
||||
let preouts: [bandersnatch_vrfs::VrfPreOut; N] =
|
||||
core::array::from_fn(|i| signature.outputs[i].0);
|
||||
core::array::from_fn(|i| signature.pre_outputs[i].0);
|
||||
|
||||
// Deserialize only the proof, the rest has already been deserialized
|
||||
// This is another hack used because backend signature type is generic over
|
||||
@@ -602,7 +603,7 @@ pub mod vrf {
|
||||
}
|
||||
}
|
||||
|
||||
impl VrfOutput {
|
||||
impl VrfPreOutput {
|
||||
/// Generate an arbitrary number of bytes from the given `context` and VRF `input`.
|
||||
pub fn make_bytes<const N: usize>(
|
||||
&self,
|
||||
@@ -804,8 +805,8 @@ pub mod ring_vrf {
|
||||
pub struct RingVrfSignature {
|
||||
/// Ring signature.
|
||||
pub signature: [u8; RING_SIGNATURE_SERIALIZED_SIZE],
|
||||
/// VRF (pre)outputs.
|
||||
pub outputs: VrfIosVec<VrfOutput>,
|
||||
/// VRF pre-outputs.
|
||||
pub pre_outputs: VrfIosVec<VrfPreOutput>,
|
||||
}
|
||||
|
||||
#[cfg(feature = "full_crypto")]
|
||||
@@ -838,11 +839,12 @@ pub mod ring_vrf {
|
||||
bandersnatch_vrfs::RingProver { ring_prover: prover, secret: &self.secret }
|
||||
.sign_ring_vrf(data.transcript.clone(), &ios);
|
||||
|
||||
let outputs: Vec<_> = ring_signature.preouts.into_iter().map(VrfOutput).collect();
|
||||
let outputs = VrfIosVec::truncate_from(outputs);
|
||||
let pre_outputs: Vec<_> =
|
||||
ring_signature.preouts.into_iter().map(VrfPreOutput).collect();
|
||||
let pre_outputs = VrfIosVec::truncate_from(pre_outputs);
|
||||
|
||||
let mut signature =
|
||||
RingVrfSignature { outputs, signature: [0; RING_SIGNATURE_SERIALIZED_SIZE] };
|
||||
RingVrfSignature { pre_outputs, signature: [0; RING_SIGNATURE_SERIALIZED_SIZE] };
|
||||
|
||||
ring_signature
|
||||
.proof
|
||||
@@ -860,7 +862,7 @@ pub mod ring_vrf {
|
||||
/// from which the [`RingVerifier`] has been constructed.
|
||||
pub fn ring_vrf_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();
|
||||
let preouts_len = self.pre_outputs.len();
|
||||
if preouts_len != data.inputs.len() {
|
||||
return false
|
||||
}
|
||||
@@ -888,7 +890,7 @@ pub mod ring_vrf {
|
||||
};
|
||||
|
||||
let preouts: [bandersnatch_vrfs::VrfPreOut; N] =
|
||||
core::array::from_fn(|i| self.outputs[i].0);
|
||||
core::array::from_fn(|i| self.pre_outputs[i].0);
|
||||
|
||||
let signature =
|
||||
bandersnatch_vrfs::RingVrfSignature { proof: vrf_signature.proof, preouts };
|
||||
@@ -1038,11 +1040,11 @@ mod tests {
|
||||
let signature = pair.vrf_sign(&data);
|
||||
|
||||
let o10 = pair.make_bytes::<32>(b"ctx1", &i1);
|
||||
let o11 = signature.outputs[0].make_bytes::<32>(b"ctx1", &i1);
|
||||
let o11 = signature.pre_outputs[0].make_bytes::<32>(b"ctx1", &i1);
|
||||
assert_eq!(o10, o11);
|
||||
|
||||
let o20 = pair.make_bytes::<48>(b"ctx2", &i2);
|
||||
let o21 = signature.outputs[1].make_bytes::<48>(b"ctx2", &i2);
|
||||
let o21 = signature.pre_outputs[1].make_bytes::<48>(b"ctx2", &i2);
|
||||
assert_eq!(o20, o21);
|
||||
}
|
||||
|
||||
@@ -1142,11 +1144,11 @@ mod tests {
|
||||
let signature = pair.ring_vrf_sign(&data, &prover);
|
||||
|
||||
let o10 = pair.make_bytes::<32>(b"ctx1", &i1);
|
||||
let o11 = signature.outputs[0].make_bytes::<32>(b"ctx1", &i1);
|
||||
let o11 = signature.pre_outputs[0].make_bytes::<32>(b"ctx1", &i1);
|
||||
assert_eq!(o10, o11);
|
||||
|
||||
let o20 = pair.make_bytes::<48>(b"ctx2", &i2);
|
||||
let o21 = signature.outputs[1].make_bytes::<48>(b"ctx2", &i2);
|
||||
let o21 = signature.pre_outputs[1].make_bytes::<48>(b"ctx2", &i2);
|
||||
assert_eq!(o20, o21);
|
||||
}
|
||||
|
||||
|
||||
@@ -1109,8 +1109,8 @@ impl<'a> TryFrom<&'a str> for KeyTypeId {
|
||||
pub trait VrfCrypto {
|
||||
/// VRF input.
|
||||
type VrfInput;
|
||||
/// VRF output.
|
||||
type VrfOutput;
|
||||
/// VRF pre-output.
|
||||
type VrfPreOutput;
|
||||
/// VRF signing data.
|
||||
type VrfSignData;
|
||||
/// VRF signature.
|
||||
@@ -1119,8 +1119,8 @@ pub trait VrfCrypto {
|
||||
|
||||
/// VRF Secret Key.
|
||||
pub trait VrfSecret: VrfCrypto {
|
||||
/// Get VRF-specific output .
|
||||
fn vrf_output(&self, data: &Self::VrfInput) -> Self::VrfOutput;
|
||||
/// Get VRF-specific pre-output.
|
||||
fn vrf_pre_output(&self, data: &Self::VrfInput) -> Self::VrfPreOutput;
|
||||
|
||||
/// Sign VRF-specific data.
|
||||
fn vrf_sign(&self, input: &Self::VrfSignData) -> Self::VrfSignature;
|
||||
|
||||
@@ -628,36 +628,36 @@ pub mod vrf {
|
||||
/// VRF signature data
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Encode, Decode, MaxEncodedLen, TypeInfo)]
|
||||
pub struct VrfSignature {
|
||||
/// VRF output.
|
||||
pub output: VrfOutput,
|
||||
/// VRF pre-output.
|
||||
pub pre_output: VrfPreOutput,
|
||||
/// VRF proof.
|
||||
pub proof: VrfProof,
|
||||
}
|
||||
|
||||
/// VRF output type suitable for schnorrkel operations.
|
||||
/// VRF pre-output type suitable for schnorrkel operations.
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct VrfOutput(pub schnorrkel::vrf::VRFOutput);
|
||||
pub struct VrfPreOutput(pub schnorrkel::vrf::VRFOutput);
|
||||
|
||||
impl Encode for VrfOutput {
|
||||
impl Encode for VrfPreOutput {
|
||||
fn encode(&self) -> Vec<u8> {
|
||||
self.0.as_bytes().encode()
|
||||
}
|
||||
}
|
||||
|
||||
impl Decode for VrfOutput {
|
||||
impl Decode for VrfPreOutput {
|
||||
fn decode<R: codec::Input>(i: &mut R) -> Result<Self, codec::Error> {
|
||||
let decoded = <[u8; VRF_OUTPUT_LENGTH]>::decode(i)?;
|
||||
Ok(Self(schnorrkel::vrf::VRFOutput::from_bytes(&decoded).map_err(convert_error)?))
|
||||
}
|
||||
}
|
||||
|
||||
impl MaxEncodedLen for VrfOutput {
|
||||
impl MaxEncodedLen for VrfPreOutput {
|
||||
fn max_encoded_len() -> usize {
|
||||
<[u8; VRF_OUTPUT_LENGTH]>::max_encoded_len()
|
||||
}
|
||||
}
|
||||
|
||||
impl TypeInfo for VrfOutput {
|
||||
impl TypeInfo for VrfPreOutput {
|
||||
type Identity = [u8; VRF_OUTPUT_LENGTH];
|
||||
|
||||
fn type_info() -> scale_info::Type {
|
||||
@@ -699,7 +699,7 @@ pub mod vrf {
|
||||
#[cfg(feature = "full_crypto")]
|
||||
impl VrfCrypto for Pair {
|
||||
type VrfInput = VrfTranscript;
|
||||
type VrfOutput = VrfOutput;
|
||||
type VrfPreOutput = VrfPreOutput;
|
||||
type VrfSignData = VrfSignData;
|
||||
type VrfSignature = VrfSignature;
|
||||
}
|
||||
@@ -717,18 +717,18 @@ pub mod vrf {
|
||||
|
||||
let proof = self.0.dleq_proove(extra, &inout, true).0;
|
||||
|
||||
VrfSignature { output: VrfOutput(inout.to_output()), proof: VrfProof(proof) }
|
||||
VrfSignature { pre_output: VrfPreOutput(inout.to_output()), proof: VrfProof(proof) }
|
||||
}
|
||||
|
||||
fn vrf_output(&self, input: &Self::VrfInput) -> Self::VrfOutput {
|
||||
let output = self.0.vrf_create_hash(input.0.clone()).to_output();
|
||||
VrfOutput(output)
|
||||
fn vrf_pre_output(&self, input: &Self::VrfInput) -> Self::VrfPreOutput {
|
||||
let pre_output = self.0.vrf_create_hash(input.0.clone()).to_output();
|
||||
VrfPreOutput(pre_output)
|
||||
}
|
||||
}
|
||||
|
||||
impl VrfCrypto for Public {
|
||||
type VrfInput = VrfTranscript;
|
||||
type VrfOutput = VrfOutput;
|
||||
type VrfPreOutput = VrfPreOutput;
|
||||
type VrfSignData = VrfSignData;
|
||||
type VrfSignature = VrfSignature;
|
||||
}
|
||||
@@ -739,7 +739,7 @@ pub mod vrf {
|
||||
let public = schnorrkel::PublicKey::from_bytes(self)?;
|
||||
|
||||
let inout =
|
||||
signature.output.0.attach_input_hash(&public, data.transcript.0.clone())?;
|
||||
signature.pre_output.0.attach_input_hash(&public, data.transcript.0.clone())?;
|
||||
|
||||
let extra = data
|
||||
.extra
|
||||
@@ -802,19 +802,21 @@ pub mod vrf {
|
||||
&self,
|
||||
context: &[u8],
|
||||
input: &VrfInput,
|
||||
output: &VrfOutput,
|
||||
pre_output: &VrfPreOutput,
|
||||
) -> Result<[u8; N], codec::Error>
|
||||
where
|
||||
[u8; N]: Default,
|
||||
{
|
||||
let pubkey = schnorrkel::PublicKey::from_bytes(&self.0).map_err(convert_error)?;
|
||||
let inout =
|
||||
output.0.attach_input_hash(&pubkey, input.0.clone()).map_err(convert_error)?;
|
||||
let inout = pre_output
|
||||
.0
|
||||
.attach_input_hash(&pubkey, input.0.clone())
|
||||
.map_err(convert_error)?;
|
||||
Ok(inout.make_bytes::<[u8; N]>(context))
|
||||
}
|
||||
}
|
||||
|
||||
impl VrfOutput {
|
||||
impl VrfPreOutput {
|
||||
/// Generate output bytes from the given VRF configuration.
|
||||
pub fn make_bytes<const N: usize>(
|
||||
&self,
|
||||
@@ -1097,10 +1099,10 @@ mod tests {
|
||||
|
||||
let input = VrfTranscript::new(b"label", &[(b"domain1", b"data1")]);
|
||||
|
||||
let output = pair.vrf_output(&input);
|
||||
let pre_output = pair.vrf_pre_output(&input);
|
||||
|
||||
let out1 = pair.make_bytes::<32>(ctx, &input);
|
||||
let out2 = output.make_bytes::<32>(ctx, &input, &public).unwrap();
|
||||
let out2 = pre_output.make_bytes::<32>(ctx, &input, &public).unwrap();
|
||||
assert_eq!(out1, out2);
|
||||
|
||||
let extra = VrfTranscript::new(b"extra", &[(b"domain2", b"data2")]);
|
||||
@@ -1108,7 +1110,7 @@ mod tests {
|
||||
let signature = pair.vrf_sign(&data);
|
||||
assert!(public.vrf_verify(&data, &signature));
|
||||
|
||||
let out3 = public.make_bytes::<32>(ctx, &input, &signature.output).unwrap();
|
||||
let out3 = public.make_bytes::<32>(ctx, &input, &signature.pre_output).unwrap();
|
||||
assert_eq!(out2, out3);
|
||||
}
|
||||
|
||||
@@ -1126,7 +1128,7 @@ mod tests {
|
||||
assert!(public.vrf_verify(&data, &signature));
|
||||
|
||||
let out1 = pair.make_bytes::<32>(ctx, &input);
|
||||
let out2 = public.make_bytes::<32>(ctx, &input, &signature.output).unwrap();
|
||||
let out2 = public.make_bytes::<32>(ctx, &input, &signature.pre_output).unwrap();
|
||||
assert_eq!(out1, out2);
|
||||
|
||||
// Direct call to backend version of sign after check with extra params
|
||||
@@ -1139,9 +1141,9 @@ mod tests {
|
||||
})
|
||||
.unwrap();
|
||||
let signature2 =
|
||||
VrfSignature { output: VrfOutput(inout.to_output()), proof: VrfProof(proof) };
|
||||
VrfSignature { pre_output: VrfPreOutput(inout.to_output()), proof: VrfProof(proof) };
|
||||
|
||||
assert!(public.vrf_verify(&data, &signature2));
|
||||
assert_eq!(signature.output, signature2.output);
|
||||
assert_eq!(signature.pre_output, signature2.pre_output);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,19 +92,19 @@ pub trait Keystore: Send + Sync {
|
||||
data: &sr25519::vrf::VrfSignData,
|
||||
) -> Result<Option<sr25519::vrf::VrfSignature>, Error>;
|
||||
|
||||
/// Generate an sr25519 VRF output for a given input data.
|
||||
/// Generate an sr25519 VRF pre-output for a given input data.
|
||||
///
|
||||
/// Receives [`KeyTypeId`] and an [`sr25519::Public`] key to be able to map
|
||||
/// them to a private key that exists in the keystore.
|
||||
///
|
||||
/// Returns `None` if the given `key_type` and `public` combination doesn't
|
||||
/// exist in the keystore or an `Err` when something failed.
|
||||
fn sr25519_vrf_output(
|
||||
fn sr25519_vrf_pre_output(
|
||||
&self,
|
||||
key_type: KeyTypeId,
|
||||
public: &sr25519::Public,
|
||||
input: &sr25519::vrf::VrfInput,
|
||||
) -> Result<Option<sr25519::vrf::VrfOutput>, Error>;
|
||||
) -> Result<Option<sr25519::vrf::VrfPreOutput>, Error>;
|
||||
|
||||
/// Returns all ed25519 public keys for the given key type.
|
||||
fn ed25519_public_keys(&self, key_type: KeyTypeId) -> Vec<ed25519::Public>;
|
||||
@@ -223,7 +223,7 @@ pub trait Keystore: Send + Sync {
|
||||
input: &bandersnatch::vrf::VrfSignData,
|
||||
) -> Result<Option<bandersnatch::vrf::VrfSignature>, Error>;
|
||||
|
||||
/// Generate a bandersnatch VRF (pre)output for a given input data.
|
||||
/// Generate a bandersnatch VRF pre-output for a given input data.
|
||||
///
|
||||
/// Receives [`KeyTypeId`] and an [`bandersnatch::Public`] key to be able to map
|
||||
/// them to a private key that exists in the keystore.
|
||||
@@ -231,12 +231,12 @@ pub trait Keystore: Send + Sync {
|
||||
/// Returns `None` if the given `key_type` and `public` combination doesn't
|
||||
/// exist in the keystore or an `Err` when something failed.
|
||||
#[cfg(feature = "bandersnatch-experimental")]
|
||||
fn bandersnatch_vrf_output(
|
||||
fn bandersnatch_vrf_pre_output(
|
||||
&self,
|
||||
key_type: KeyTypeId,
|
||||
public: &bandersnatch::Public,
|
||||
input: &bandersnatch::vrf::VrfInput,
|
||||
) -> Result<Option<bandersnatch::vrf::VrfOutput>, Error>;
|
||||
) -> Result<Option<bandersnatch::vrf::VrfPreOutput>, Error>;
|
||||
|
||||
/// Generate a bandersnatch ring-VRF signature for the given data.
|
||||
///
|
||||
@@ -474,13 +474,13 @@ impl<T: Keystore + ?Sized> Keystore for Arc<T> {
|
||||
(**self).sr25519_vrf_sign(key_type, public, data)
|
||||
}
|
||||
|
||||
fn sr25519_vrf_output(
|
||||
fn sr25519_vrf_pre_output(
|
||||
&self,
|
||||
key_type: KeyTypeId,
|
||||
public: &sr25519::Public,
|
||||
input: &sr25519::vrf::VrfInput,
|
||||
) -> Result<Option<sr25519::vrf::VrfOutput>, Error> {
|
||||
(**self).sr25519_vrf_output(key_type, public, input)
|
||||
) -> Result<Option<sr25519::vrf::VrfPreOutput>, Error> {
|
||||
(**self).sr25519_vrf_pre_output(key_type, public, input)
|
||||
}
|
||||
|
||||
fn ed25519_public_keys(&self, key_type: KeyTypeId) -> Vec<ed25519::Public> {
|
||||
@@ -569,13 +569,13 @@ impl<T: Keystore + ?Sized> Keystore for Arc<T> {
|
||||
}
|
||||
|
||||
#[cfg(feature = "bandersnatch-experimental")]
|
||||
fn bandersnatch_vrf_output(
|
||||
fn bandersnatch_vrf_pre_output(
|
||||
&self,
|
||||
key_type: KeyTypeId,
|
||||
public: &bandersnatch::Public,
|
||||
input: &bandersnatch::vrf::VrfInput,
|
||||
) -> Result<Option<bandersnatch::vrf::VrfOutput>, Error> {
|
||||
(**self).bandersnatch_vrf_output(key_type, public, input)
|
||||
) -> Result<Option<bandersnatch::vrf::VrfPreOutput>, Error> {
|
||||
(**self).bandersnatch_vrf_pre_output(key_type, public, input)
|
||||
}
|
||||
|
||||
#[cfg(feature = "bandersnatch-experimental")]
|
||||
|
||||
@@ -113,14 +113,14 @@ impl MemoryKeystore {
|
||||
Ok(sig)
|
||||
}
|
||||
|
||||
fn vrf_output<T: Pair + VrfSecret>(
|
||||
fn vrf_pre_output<T: Pair + VrfSecret>(
|
||||
&self,
|
||||
key_type: KeyTypeId,
|
||||
public: &T::Public,
|
||||
input: &T::VrfInput,
|
||||
) -> Result<Option<T::VrfOutput>, Error> {
|
||||
let preout = self.pair::<T>(key_type, public).map(|pair| pair.vrf_output(input));
|
||||
Ok(preout)
|
||||
) -> Result<Option<T::VrfPreOutput>, Error> {
|
||||
let pre_output = self.pair::<T>(key_type, public).map(|pair| pair.vrf_pre_output(input));
|
||||
Ok(pre_output)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,13 +155,13 @@ impl Keystore for MemoryKeystore {
|
||||
self.vrf_sign::<sr25519::Pair>(key_type, public, data)
|
||||
}
|
||||
|
||||
fn sr25519_vrf_output(
|
||||
fn sr25519_vrf_pre_output(
|
||||
&self,
|
||||
key_type: KeyTypeId,
|
||||
public: &sr25519::Public,
|
||||
input: &sr25519::vrf::VrfInput,
|
||||
) -> Result<Option<sr25519::vrf::VrfOutput>, Error> {
|
||||
self.vrf_output::<sr25519::Pair>(key_type, public, input)
|
||||
) -> Result<Option<sr25519::vrf::VrfPreOutput>, Error> {
|
||||
self.vrf_pre_output::<sr25519::Pair>(key_type, public, input)
|
||||
}
|
||||
|
||||
fn ed25519_public_keys(&self, key_type: KeyTypeId) -> Vec<ed25519::Public> {
|
||||
@@ -265,13 +265,13 @@ impl Keystore for MemoryKeystore {
|
||||
}
|
||||
|
||||
#[cfg(feature = "bandersnatch-experimental")]
|
||||
fn bandersnatch_vrf_output(
|
||||
fn bandersnatch_vrf_pre_output(
|
||||
&self,
|
||||
key_type: KeyTypeId,
|
||||
public: &bandersnatch::Public,
|
||||
input: &bandersnatch::vrf::VrfInput,
|
||||
) -> Result<Option<bandersnatch::vrf::VrfOutput>, Error> {
|
||||
self.vrf_output::<bandersnatch::Pair>(key_type, public, input)
|
||||
) -> Result<Option<bandersnatch::vrf::VrfPreOutput>, Error> {
|
||||
self.vrf_pre_output::<bandersnatch::Pair>(key_type, public, input)
|
||||
}
|
||||
|
||||
#[cfg(feature = "bls-experimental")]
|
||||
@@ -443,7 +443,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sr25519_vrf_output() {
|
||||
fn sr25519_vrf_pre_output() {
|
||||
let store = MemoryKeystore::new();
|
||||
|
||||
let secret_uri = "//Alice";
|
||||
@@ -458,16 +458,17 @@ mod tests {
|
||||
],
|
||||
);
|
||||
|
||||
let result = store.sr25519_vrf_output(SR25519, &pair.public(), &input);
|
||||
let result = store.sr25519_vrf_pre_output(SR25519, &pair.public(), &input);
|
||||
assert!(result.unwrap().is_none());
|
||||
|
||||
store
|
||||
.insert(SR25519, secret_uri, pair.public().as_ref())
|
||||
.expect("Inserts unknown key");
|
||||
|
||||
let preout = store.sr25519_vrf_output(SR25519, &pair.public(), &input).unwrap().unwrap();
|
||||
let pre_output =
|
||||
store.sr25519_vrf_pre_output(SR25519, &pair.public(), &input).unwrap().unwrap();
|
||||
|
||||
let result = preout.make_bytes::<32>(b"rand", &input, &pair.public());
|
||||
let result = pre_output.make_bytes::<32>(b"rand", &input, &pair.public());
|
||||
assert!(result.is_ok());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user