sp_crypto_ec_utils/
bw6_761.rs1use crate::utils::{self, HostcallResult, FAIL_MSG};
21use alloc::vec::Vec;
22use ark_bw6_761_ext::CurveHooks;
23use ark_ec::{pairing::Pairing, AffineRepr, CurveGroup};
24use sp_runtime_interface::{
25 pass_by::{PassFatPointerAndRead, PassFatPointerAndReadWrite, PassFatPointerAndWrite},
26 runtime_interface,
27};
28
29pub type Config = ark_bw6_761_ext::Config<HostHooks>;
31
32pub type BW6_761 = ark_bw6_761_ext::BW6_761<HostHooks>;
34
35pub type G1Config = ark_bw6_761_ext::g1::Config<HostHooks>;
37pub type G1Affine = ark_bw6_761_ext::g1::G1Affine<HostHooks>;
39pub type G1Projective = ark_bw6_761_ext::g1::G1Projective<HostHooks>;
41
42pub type G2Config = ark_bw6_761_ext::g2::Config<HostHooks>;
44pub type G2Affine = ark_bw6_761_ext::g2::G2Affine<HostHooks>;
46pub type G2Projective = ark_bw6_761_ext::g2::G2Projective<HostHooks>;
48
49pub type ScalarField = <BW6_761 as Pairing>::ScalarField;
51
52pub type G1Prepared = <BW6_761 as Pairing>::G1Prepared;
54pub type G2Prepared = <BW6_761 as Pairing>::G2Prepared;
56pub type TargetField = <BW6_761 as Pairing>::TargetField;
58
59#[derive(Copy, Clone)]
61pub struct HostHooks;
62
63impl CurveHooks for HostHooks {
64 fn multi_miller_loop(
65 g1: impl Iterator<Item = G1Prepared>,
66 g2: impl Iterator<Item = G2Prepared>,
67 ) -> TargetField {
68 let mut out = utils::buffer_for::<TargetField>();
69 host_calls::bw6_761_multi_miller_loop(
70 &utils::encode_iter(g1),
71 &utils::encode_iter(g2),
72 &mut out,
73 )
74 .and_then(|_| utils::decode::<TargetField>(&out))
75 .expect(FAIL_MSG)
76 }
77
78 fn final_exponentiation(target: TargetField) -> TargetField {
79 let mut in_out = utils::encode(target);
80 host_calls::bw6_761_final_exponentiation(&mut in_out)
81 .and_then(|_| utils::decode::<TargetField>(&in_out))
82 .expect(FAIL_MSG)
83 }
84
85 fn msm_g1(bases: &[G1Affine], scalars: &[ScalarField]) -> G1Projective {
86 let mut out = utils::buffer_for::<G1Affine>();
87 host_calls::bw6_761_msm_g1(&utils::encode(bases), &utils::encode(scalars), &mut out)
88 .and_then(|_| utils::decode::<G1Affine>(&out))
89 .expect(FAIL_MSG)
90 .into_group()
91 }
92
93 fn msm_g2(bases: &[G2Affine], scalars: &[ScalarField]) -> G2Projective {
94 let mut out = utils::buffer_for::<G2Affine>();
95 host_calls::bw6_761_msm_g2(&utils::encode(bases), &utils::encode(scalars), &mut out)
96 .and_then(|_| utils::decode::<G2Affine>(&out))
97 .expect(FAIL_MSG)
98 .into_group()
99 }
100
101 fn mul_projective_g1(base: &G1Projective, scalar: &[u64]) -> G1Projective {
102 let mut out = utils::buffer_for::<G1Affine>();
103 host_calls::bw6_761_mul_g1(
104 &utils::encode(base.into_affine()),
105 &utils::encode(scalar),
106 &mut out,
107 )
108 .and_then(|_| utils::decode::<G1Affine>(&out))
109 .expect(FAIL_MSG)
110 .into_group()
111 }
112
113 fn mul_projective_g2(base: &G2Projective, scalar: &[u64]) -> G2Projective {
114 let mut out = utils::buffer_for::<G2Affine>();
115 host_calls::bw6_761_mul_g2(
116 &utils::encode(base.into_affine()),
117 &utils::encode(scalar),
118 &mut out,
119 )
120 .and_then(|_| utils::decode::<G2Affine>(&out))
121 .expect(FAIL_MSG)
122 .into_group()
123 }
124}
125
126#[runtime_interface]
134pub trait HostCalls {
135 fn bw6_761_multi_miller_loop(
142 a: PassFatPointerAndRead<&[u8]>,
143 b: PassFatPointerAndRead<&[u8]>,
144 out: PassFatPointerAndWrite<&mut [u8]>,
145 ) -> HostcallResult {
146 utils::multi_miller_loop::<ark_bw6_761::BW6_761>(a, b, out)
147 }
148
149 fn bw6_761_final_exponentiation(
154 in_out: PassFatPointerAndReadWrite<&mut [u8]>,
155 ) -> HostcallResult {
156 utils::final_exponentiation::<ark_bw6_761::BW6_761>(in_out)
157 }
158
159 fn bw6_761_msm_g1(
166 bases: PassFatPointerAndRead<&[u8]>,
167 scalars: PassFatPointerAndRead<&[u8]>,
168 out: PassFatPointerAndWrite<&mut [u8]>,
169 ) -> HostcallResult {
170 utils::msm_sw::<ark_bw6_761::g1::Config>(bases, scalars, out)
171 }
172
173 fn bw6_761_msm_g2(
180 bases: PassFatPointerAndRead<&[u8]>,
181 scalars: PassFatPointerAndRead<&[u8]>,
182 out: PassFatPointerAndWrite<&mut [u8]>,
183 ) -> HostcallResult {
184 utils::msm_sw::<ark_bw6_761::g2::Config>(bases, scalars, out)
185 }
186
187 fn bw6_761_mul_g1(
194 base: PassFatPointerAndRead<&[u8]>,
195 scalar: PassFatPointerAndRead<&[u8]>,
196 out: PassFatPointerAndWrite<&mut [u8]>,
197 ) -> HostcallResult {
198 utils::mul_sw::<ark_bw6_761::g1::Config>(base, scalar, out)
199 }
200
201 fn bw6_761_mul_g2(
208 base: PassFatPointerAndRead<&[u8]>,
209 scalar: PassFatPointerAndRead<&[u8]>,
210 out: PassFatPointerAndWrite<&mut [u8]>,
211 ) -> HostcallResult {
212 utils::mul_sw::<ark_bw6_761::g2::Config>(base, scalar, out)
213 }
214}
215
216#[cfg(test)]
217mod tests {
218 use super::*;
219 use crate::utils::testing::*;
220
221 #[test]
222 fn mul_g1_works() {
223 mul_test::<G1Affine, ark_bw6_761::G1Affine>();
224 }
225
226 #[test]
227 fn msm_g1_works() {
228 msm_test::<G1Affine, ark_bw6_761::G1Affine>();
229 }
230
231 #[test]
232 fn mul_g2_works() {
233 mul_test::<G2Affine, ark_bw6_761::G2Affine>();
234 }
235
236 #[test]
237 fn msm_g2_works() {
238 msm_test::<G2Affine, ark_bw6_761::G2Affine>();
239 }
240
241 #[test]
242 fn pairing_works() {
243 pairing_test::<BW6_761, ark_bw6_761::BW6_761>();
244 }
245}