avail_rust_core/substrate/
sp_core.rs

1// # This code is adapted from the Substrate project
2// Copyright (C) Parity Technologies (UK) Ltd.
3// SPDX-License-Identifier: Apache-2.0
4// See http://www.apache.org/licenses/LICENSE-2.0 for details.
5
6use codec::{Decode, Encode};
7
8/// Schnorrkel VRF related types and operations.
9pub mod vrf {
10	use super::*;
11	use schnorrkel::{
12		SignatureError,
13		errors::MultiSignatureStage,
14		vrf::{VRF_PREOUT_LENGTH, VRF_PROOF_LENGTH},
15	};
16
17	/// VRF signature data
18	#[derive(Clone, Debug, PartialEq, Eq, Encode, Decode)]
19	pub struct VrfSignature {
20		/// VRF pre-output.
21		pub pre_output: VrfPreOutput,
22		/// VRF proof.
23		pub proof: VrfProof,
24	}
25
26	/// VRF pre-output type suitable for schnorrkel operations.
27	#[derive(Clone, Debug, PartialEq, Eq)]
28	pub struct VrfPreOutput(pub schnorrkel::vrf::VRFPreOut);
29
30	impl Encode for VrfPreOutput {
31		fn encode(&self) -> Vec<u8> {
32			self.0.as_bytes().encode()
33		}
34	}
35
36	impl Decode for VrfPreOutput {
37		fn decode<R: codec::Input>(i: &mut R) -> Result<Self, codec::Error> {
38			let decoded = <[u8; VRF_PREOUT_LENGTH]>::decode(i)?;
39			Ok(Self(schnorrkel::vrf::VRFPreOut::from_bytes(&decoded).map_err(convert_error)?))
40		}
41	}
42
43	/// VRF proof type suitable for schnorrkel operations.
44	#[derive(Clone, Debug, PartialEq, Eq)]
45	pub struct VrfProof(pub schnorrkel::vrf::VRFProof);
46
47	impl Encode for VrfProof {
48		fn encode(&self) -> Vec<u8> {
49			self.0.to_bytes().encode()
50		}
51	}
52
53	impl Decode for VrfProof {
54		fn decode<R: codec::Input>(i: &mut R) -> Result<Self, codec::Error> {
55			let decoded = <[u8; VRF_PROOF_LENGTH]>::decode(i)?;
56			Ok(Self(schnorrkel::vrf::VRFProof::from_bytes(&decoded).map_err(convert_error)?))
57		}
58	}
59
60	fn convert_error(e: SignatureError) -> codec::Error {
61		use MultiSignatureStage::*;
62		use SignatureError::*;
63		match e {
64			EquationFalse => "Signature error: `EquationFalse`".into(),
65			PointDecompressionError => "Signature error: `PointDecompressionError`".into(),
66			ScalarFormatError => "Signature error: `ScalarFormatError`".into(),
67			NotMarkedSchnorrkel => "Signature error: `NotMarkedSchnorrkel`".into(),
68			BytesLengthError { .. } => "Signature error: `BytesLengthError`".into(),
69			InvalidKey => "Signature error: `InvalidKey`".into(),
70			MuSigAbsent { musig_stage: Commitment } => "Signature error: `MuSigAbsent` at stage `Commitment`".into(),
71			MuSigAbsent { musig_stage: Reveal } => "Signature error: `MuSigAbsent` at stage `Reveal`".into(),
72			MuSigAbsent { musig_stage: Cosignature } => "Signature error: `MuSigAbsent` at stage `Commitment`".into(),
73			MuSigInconsistent { musig_stage: Commitment, duplicate: true } => {
74				"Signature error: `MuSigInconsistent` at stage `Commitment` on duplicate".into()
75			},
76			MuSigInconsistent { musig_stage: Commitment, duplicate: false } => {
77				"Signature error: `MuSigInconsistent` at stage `Commitment` on not duplicate".into()
78			},
79			MuSigInconsistent { musig_stage: Reveal, duplicate: true } => {
80				"Signature error: `MuSigInconsistent` at stage `Reveal` on duplicate".into()
81			},
82			MuSigInconsistent { musig_stage: Reveal, duplicate: false } => {
83				"Signature error: `MuSigInconsistent` at stage `Reveal` on not duplicate".into()
84			},
85			MuSigInconsistent { musig_stage: Cosignature, duplicate: true } => {
86				"Signature error: `MuSigInconsistent` at stage `Cosignature` on duplicate".into()
87			},
88			MuSigInconsistent { musig_stage: Cosignature, duplicate: false } => {
89				"Signature error: `MuSigInconsistent` at stage `Cosignature` on not duplicate".into()
90			},
91		}
92	}
93}