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 bls12_381_multi_miller_loop(
73 g1: impl Iterator<Item = <Bls12_381 as Pairing>::G1Prepared>,
74 g2: impl Iterator<Item = <Bls12_381 as Pairing>::G2Prepared>,
75 ) -> Result<<Bls12_381 as Pairing>::TargetField, ()> {
76 let g1 = utils::encode(g1.collect::<Vec<_>>());
77 let g2 = utils::encode(g2.collect::<Vec<_>>());
78 let res = host_calls::bls12_381_multi_miller_loop(g1, g2).unwrap_or_default();
79 utils::decode(res)
80 }
81
82 fn bls12_381_final_exponentiation(
83 target: <Bls12_381 as Pairing>::TargetField,
84 ) -> Result<<Bls12_381 as Pairing>::TargetField, ()> {
85 let target = utils::encode(target);
86 let res = host_calls::bls12_381_final_exponentiation(target).unwrap_or_default();
87 utils::decode(res)
88 }
89
90 fn bls12_381_msm_g1(
91 bases: &[G1Affine],
92 scalars: &[<G1Config as CurveConfig>::ScalarField],
93 ) -> Result<G1Projective, ()> {
94 let bases = utils::encode(bases);
95 let scalars = utils::encode(scalars);
96 let res = host_calls::bls12_381_msm_g1(bases, scalars).unwrap_or_default();
97 utils::decode_proj_sw(res)
98 }
99
100 fn bls12_381_msm_g2(
101 bases: &[G2Affine],
102 scalars: &[<G2Config as CurveConfig>::ScalarField],
103 ) -> Result<G2Projective, ()> {
104 let bases = utils::encode(bases);
105 let scalars = utils::encode(scalars);
106 let res = host_calls::bls12_381_msm_g2(bases, scalars).unwrap_or_default();
107 utils::decode_proj_sw(res)
108 }
109
110 fn bls12_381_mul_projective_g1(
111 base: &G1Projective,
112 scalar: &[u64],
113 ) -> Result<G1Projective, ()> {
114 let base = utils::encode_proj_sw(base);
115 let scalar = utils::encode(scalar);
116 let res = host_calls::bls12_381_mul_projective_g1(base, scalar).unwrap_or_default();
117 utils::decode_proj_sw(res)
118 }
119
120 fn bls12_381_mul_projective_g2(
121 base: &G2Projective,
122 scalar: &[u64],
123 ) -> Result<G2Projective, ()> {
124 let base = utils::encode_proj_sw(base);
125 let scalar = utils::encode(scalar);
126 let res = host_calls::bls12_381_mul_projective_g2(base, scalar).unwrap_or_default();
127 utils::decode_proj_sw(res)
128 }
129}
130
131#[runtime_interface]
140pub trait HostCalls {
141 fn bls12_381_multi_miller_loop(
148 a: PassFatPointerAndRead<Vec<u8>>,
149 b: PassFatPointerAndRead<Vec<u8>>,
150 ) -> AllocateAndReturnByCodec<Result<Vec<u8>, ()>> {
151 utils::multi_miller_loop::<ark_bls12_381::Bls12_381>(a, b)
152 }
153
154 fn bls12_381_final_exponentiation(
159 f: PassFatPointerAndRead<Vec<u8>>,
160 ) -> AllocateAndReturnByCodec<Result<Vec<u8>, ()>> {
161 utils::final_exponentiation::<ark_bls12_381::Bls12_381>(f)
162 }
163
164 fn bls12_381_msm_g1(
171 bases: PassFatPointerAndRead<Vec<u8>>,
172 scalars: PassFatPointerAndRead<Vec<u8>>,
173 ) -> AllocateAndReturnByCodec<Result<Vec<u8>, ()>> {
174 utils::msm_sw::<ark_bls12_381::g1::Config>(bases, scalars)
175 }
176
177 fn bls12_381_msm_g2(
184 bases: PassFatPointerAndRead<Vec<u8>>,
185 scalars: PassFatPointerAndRead<Vec<u8>>,
186 ) -> AllocateAndReturnByCodec<Result<Vec<u8>, ()>> {
187 utils::msm_sw::<ark_bls12_381::g2::Config>(bases, scalars)
188 }
189
190 fn bls12_381_mul_projective_g1(
197 base: PassFatPointerAndRead<Vec<u8>>,
198 scalar: PassFatPointerAndRead<Vec<u8>>,
199 ) -> AllocateAndReturnByCodec<Result<Vec<u8>, ()>> {
200 utils::mul_projective_sw::<ark_bls12_381::g1::Config>(base, scalar)
201 }
202
203 fn bls12_381_mul_projective_g2(
210 base: PassFatPointerAndRead<Vec<u8>>,
211 scalar: PassFatPointerAndRead<Vec<u8>>,
212 ) -> AllocateAndReturnByCodec<Result<Vec<u8>, ()>> {
213 utils::mul_projective_sw::<ark_bls12_381::g2::Config>(base, scalar)
214 }
215}