snowbridge_beacon_primitives/
bls.rs1use crate::{PublicKey, Signature};
4use codec::{Decode, DecodeWithMemTracking, Encode};
5use frame_support::{ensure, PalletError};
6pub use milagro_bls::{
7 AggregatePublicKey, AggregateSignature, PublicKey as PublicKeyPrepared,
8 Signature as SignaturePrepared,
9};
10use scale_info::TypeInfo;
11use sp_core::H256;
12use sp_runtime::RuntimeDebug;
13use sp_std::prelude::*;
14
15#[derive(
16 Copy,
17 Clone,
18 Encode,
19 Decode,
20 DecodeWithMemTracking,
21 Eq,
22 PartialEq,
23 TypeInfo,
24 RuntimeDebug,
25 PalletError,
26)]
27pub enum BlsError {
28 InvalidSignature,
29 InvalidPublicKey,
30 InvalidAggregatePublicKeys,
31 SignatureVerificationFailed,
32}
33
34pub fn fast_aggregate_verify(
36 aggregate_pubkey: &PublicKeyPrepared,
37 absent_pubkeys: &Vec<PublicKeyPrepared>,
38 message: H256,
39 signature: &Signature,
40) -> Result<(), BlsError> {
41 let agg_sig = prepare_aggregate_signature(signature)?;
42 let agg_key = prepare_aggregate_pubkey_from_absent(aggregate_pubkey, absent_pubkeys)?;
43 fast_aggregate_verify_pre_aggregated(agg_sig, agg_key, message)
44}
45
46pub fn prepare_milagro_pubkey(pubkey: &PublicKey) -> Result<PublicKeyPrepared, BlsError> {
48 PublicKeyPrepared::from_bytes_unchecked(&pubkey.0).map_err(|_| BlsError::InvalidPublicKey)
49}
50
51pub fn prepare_g1_pubkeys(pubkeys: &[PublicKey]) -> Result<Vec<PublicKeyPrepared>, BlsError> {
53 pubkeys
54 .iter()
55 .map(prepare_milagro_pubkey)
57 .collect::<Result<Vec<PublicKeyPrepared>, BlsError>>()
58}
59
60pub fn prepare_aggregate_pubkey(
62 pubkeys: &[PublicKeyPrepared],
63) -> Result<AggregatePublicKey, BlsError> {
64 AggregatePublicKey::into_aggregate(pubkeys).map_err(|_| BlsError::InvalidPublicKey)
65}
66
67pub fn prepare_aggregate_pubkey_from_absent(
69 aggregate_key: &PublicKeyPrepared,
70 absent_pubkeys: &Vec<PublicKeyPrepared>,
71) -> Result<AggregatePublicKey, BlsError> {
72 let mut aggregate_pubkey = AggregatePublicKey::from_public_key(aggregate_key);
73 if !absent_pubkeys.is_empty() {
74 let absent_aggregate_key = prepare_aggregate_pubkey(absent_pubkeys)?;
75 aggregate_pubkey.point.sub(&absent_aggregate_key.point);
76 }
77 Ok(AggregatePublicKey { point: aggregate_pubkey.point })
78}
79
80pub fn prepare_aggregate_signature(signature: &Signature) -> Result<AggregateSignature, BlsError> {
82 Ok(AggregateSignature::from_signature(
83 &SignaturePrepared::from_bytes(&signature.0).map_err(|_| BlsError::InvalidSignature)?,
84 ))
85}
86
87pub fn fast_aggregate_verify_pre_aggregated(
89 agg_sig: AggregateSignature,
90 aggregate_key: AggregatePublicKey,
91 message: H256,
92) -> Result<(), BlsError> {
93 ensure!(
94 agg_sig.fast_aggregate_verify_pre_aggregated(&message[..], &aggregate_key),
95 BlsError::SignatureVerificationFailed
96 );
97 Ok(())
98}