sp_crypto_ec_utils/
bls12_381.rs1use crate::utils;
21use alloc::vec::Vec;
22use ark_bls12_381_ext::CurveHooks;
23use ark_ec::{pairing::Pairing, CurveConfig};
24use sp_runtime_interface::{
25 pass_by::{AllocateAndReturnByCodec, PassFatPointerAndRead},
26 runtime_interface,
27};
28
29pub mod g1 {
31 pub use ark_bls12_381_ext::g1::{BETA, G1_GENERATOR_X, G1_GENERATOR_Y};
32 pub type Config = ark_bls12_381_ext::g1::Config<super::HostHooks>;
34 pub type G1Affine = ark_bls12_381_ext::g1::G1Affine<super::HostHooks>;
36 pub type G1Projective = ark_bls12_381_ext::g1::G1Projective<super::HostHooks>;
38}
39
40pub mod g2 {
42 pub use ark_bls12_381_ext::g2::{
43 G2_GENERATOR_X, G2_GENERATOR_X_C0, G2_GENERATOR_X_C1, G2_GENERATOR_Y, G2_GENERATOR_Y_C0,
44 G2_GENERATOR_Y_C1,
45 };
46 pub type Config = ark_bls12_381_ext::g2::Config<super::HostHooks>;
48 pub type G2Affine = ark_bls12_381_ext::g2::G2Affine<super::HostHooks>;
50 pub type G2Projective = ark_bls12_381_ext::g2::G2Projective<super::HostHooks>;
52}
53
54pub use self::{
55 g1::{Config as G1Config, G1Affine, G1Projective},
56 g2::{Config as G2Config, G2Affine, G2Projective},
57};
58
59#[derive(Copy, Clone)]
61pub struct HostHooks;
62
63pub type Config = ark_bls12_381_ext::Config<HostHooks>;
65
66pub type Bls12_381 = ark_bls12_381_ext::Bls12_381<HostHooks>;
70
71impl CurveHooks for HostHooks {
72 fn multi_miller_loop(
73 g1: impl Iterator<Item = <Bls12_381 as Pairing>::G1Prepared>,
74 g2: impl Iterator<Item = <Bls12_381 as Pairing>::G2Prepared>,
75 ) -> <Bls12_381 as Pairing>::TargetField {
76 host_calls::bls12_381_multi_miller_loop(utils::encode_iter(g1), utils::encode_iter(g2))
77 .and_then(|res| utils::decode(res))
78 .unwrap_or_default()
79 }
80
81 fn final_exponentiation(
82 target: <Bls12_381 as Pairing>::TargetField,
83 ) -> <Bls12_381 as Pairing>::TargetField {
84 host_calls::bls12_381_final_exponentiation(utils::encode(target))
85 .and_then(|res| utils::decode(res))
86 .unwrap_or_default()
87 }
88
89 fn msm_g1(
90 bases: &[G1Affine],
91 scalars: &[<G1Config as CurveConfig>::ScalarField],
92 ) -> G1Projective {
93 host_calls::bls12_381_msm_g1(utils::encode(bases), utils::encode(scalars))
94 .and_then(|res| utils::decode_proj_sw(res))
95 .unwrap_or_default()
96 }
97
98 fn msm_g2(
99 bases: &[G2Affine],
100 scalars: &[<G2Config as CurveConfig>::ScalarField],
101 ) -> G2Projective {
102 host_calls::bls12_381_msm_g2(utils::encode(bases), utils::encode(scalars))
103 .and_then(|res| utils::decode_proj_sw(res))
104 .unwrap_or_default()
105 }
106
107 fn mul_projective_g1(base: &G1Projective, scalar: &[u64]) -> G1Projective {
108 host_calls::bls12_381_mul_projective_g1(utils::encode_proj_sw(base), utils::encode(scalar))
109 .and_then(|res| utils::decode_proj_sw(res))
110 .unwrap_or_default()
111 }
112
113 fn mul_projective_g2(base: &G2Projective, scalar: &[u64]) -> G2Projective {
114 host_calls::bls12_381_mul_projective_g2(utils::encode_proj_sw(base), utils::encode(scalar))
115 .and_then(|res| utils::decode_proj_sw(res))
116 .unwrap_or_default()
117 }
118}
119
120#[runtime_interface]
129pub trait HostCalls {
130 fn bls12_381_multi_miller_loop(
137 a: PassFatPointerAndRead<Vec<u8>>,
138 b: PassFatPointerAndRead<Vec<u8>>,
139 ) -> AllocateAndReturnByCodec<Result<Vec<u8>, ()>> {
140 utils::multi_miller_loop::<ark_bls12_381::Bls12_381>(a, b)
141 }
142
143 fn bls12_381_final_exponentiation(
148 f: PassFatPointerAndRead<Vec<u8>>,
149 ) -> AllocateAndReturnByCodec<Result<Vec<u8>, ()>> {
150 utils::final_exponentiation::<ark_bls12_381::Bls12_381>(f)
151 }
152
153 fn bls12_381_msm_g1(
160 bases: PassFatPointerAndRead<Vec<u8>>,
161 scalars: PassFatPointerAndRead<Vec<u8>>,
162 ) -> AllocateAndReturnByCodec<Result<Vec<u8>, ()>> {
163 utils::msm_sw::<ark_bls12_381::g1::Config>(bases, scalars)
164 }
165
166 fn bls12_381_msm_g2(
173 bases: PassFatPointerAndRead<Vec<u8>>,
174 scalars: PassFatPointerAndRead<Vec<u8>>,
175 ) -> AllocateAndReturnByCodec<Result<Vec<u8>, ()>> {
176 utils::msm_sw::<ark_bls12_381::g2::Config>(bases, scalars)
177 }
178
179 fn bls12_381_mul_projective_g1(
186 base: PassFatPointerAndRead<Vec<u8>>,
187 scalar: PassFatPointerAndRead<Vec<u8>>,
188 ) -> AllocateAndReturnByCodec<Result<Vec<u8>, ()>> {
189 utils::mul_projective_sw::<ark_bls12_381::g1::Config>(base, scalar)
190 }
191
192 fn bls12_381_mul_projective_g2(
199 base: PassFatPointerAndRead<Vec<u8>>,
200 scalar: PassFatPointerAndRead<Vec<u8>>,
201 ) -> AllocateAndReturnByCodec<Result<Vec<u8>, ()>> {
202 utils::mul_projective_sw::<ark_bls12_381::g2::Config>(base, scalar)
203 }
204}