builtins_common/bls12_381/
low_level.rs1use super::*;
20use ark_bls12_381::{
21 Bls12_381, G1Projective, G2Projective, g1::Config as G1Config, g2::Config as G2Config,
22};
23use ark_ec::{
24 CurveConfig, VariableBaseMSM,
25 bls12::Bls12Config,
26 hashing::{HashToCurve, curve_maps::wb, map_to_curve_hasher::MapToCurveBasedHasher},
27 pairing::{MillerLoopOutput, Pairing},
28 short_weierstrass::{Affine as SWAffine, Projective as SWProjective, SWCurveConfig},
29};
30use ark_ff::fields::field_hashers::DefaultFieldHasher;
31use ark_scale::{
32 HOST_CALL,
33 scale::{Decode, Encode},
34};
35use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, Compress, Validate};
36use gear_core::limited::LimitedStr;
37use sha2;
38
39type ArkScaleLocal<T> = ark_scale::ArkScale<T, HOST_CALL>;
40const _: () = assert!(HOST_CALL == ark_scale::make_usage(Compress::No, Validate::No));
41type ArkScaleProjective<T> = ark_scale::hazmat::ArkScaleProjective<T>;
42
43pub struct Bls12_381OpsLowLevel;
51
52impl Bls12_381Ops for Bls12_381OpsLowLevel {
54 fn multi_miller_loop(g1: Vec<u8>, g2: Vec<u8>) -> Result<Vec<u8>, BuiltinActorError> {
55 let a = Self::decode::<Vec<<Bls12_381 as Pairing>::G1Affine>>(g1)?;
56 let b = Self::decode::<Vec<<Bls12_381 as Pairing>::G2Affine>>(g2)?;
57 let res = Bls12_381::multi_miller_loop(a, b);
58
59 Ok(Self::encode(res.0))
60 }
61
62 fn final_exponentiation(f: Vec<u8>) -> Result<Vec<u8>, BuiltinActorError> {
63 let f = Self::decode::<<Bls12_381 as Pairing>::TargetField>(f)?;
64 let res = Bls12_381::final_exponentiation(MillerLoopOutput(f)).ok_or(
65 BuiltinActorError::Custom(LimitedStr::from_small_str("Final exponentiation failed")),
66 )?;
67
68 Ok(Self::encode(res.0))
69 }
70
71 fn msm_g1(bases: Vec<u8>, scalars: Vec<u8>) -> Result<Vec<u8>, BuiltinActorError> {
72 Self::msm_sw::<G1Config>(bases, scalars)
73 }
74
75 fn msm_g2(bases: Vec<u8>, scalars: Vec<u8>) -> Result<Vec<u8>, BuiltinActorError> {
76 Self::msm_sw::<G2Config>(bases, scalars)
77 }
78
79 fn projective_mul_g1(base: Vec<u8>, scalar: Vec<u8>) -> Result<Vec<u8>, BuiltinActorError> {
80 Self::projective_mul_sw::<G1Config>(base, scalar)
81 }
82
83 fn projective_mul_g2(base: Vec<u8>, scalar: Vec<u8>) -> Result<Vec<u8>, BuiltinActorError> {
84 Self::projective_mul_sw::<G2Config>(base, scalar)
85 }
86
87 fn aggregate_g1(points: Vec<u8>) -> Result<Vec<u8>, BuiltinActorError> {
88 let points = Self::decode::<Vec<G1Projective>>(points)?;
89
90 let point_first = points.first().ok_or(BuiltinActorError::EmptyG1PointsList)?;
91
92 let point_aggregated = points
93 .iter()
94 .skip(1)
95 .fold(*point_first, |aggregated, point| aggregated + *point);
96
97 Ok(Self::encode(point_aggregated))
98 }
99
100 fn map_to_g2affine(message: Vec<u8>) -> Result<Vec<u8>, BuiltinActorError> {
101 type WBMap = wb::WBMap<<ark_bls12_381::Config as Bls12Config>::G2Config>;
102
103 const DST_G2: &[u8] = b"BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_";
105
106 let mapper =
107 MapToCurveBasedHasher::<G2Projective, DefaultFieldHasher<sha2::Sha256>, WBMap>::new(
108 DST_G2,
109 )
110 .map_err(|_| BuiltinActorError::MapperCreationError)?;
111
112 let point = mapper
113 .hash(&message)
114 .map_err(|_| BuiltinActorError::MessageMappingError)?;
115
116 Ok(Self::encode(point))
117 }
118}
119
120impl Bls12_381OpsLowLevel {
121 fn msm_sw<T: SWCurveConfig>(
122 bases: Vec<u8>,
123 scalars: Vec<u8>,
124 ) -> Result<Vec<u8>, BuiltinActorError> {
125 let bases = Self::decode::<Vec<SWAffine<T>>>(bases)?;
126 let scalars = Self::decode::<Vec<<T as CurveConfig>::ScalarField>>(scalars)?;
127 let res = <SWProjective<T> as VariableBaseMSM>::msm(&bases, &scalars).map_err(|_| {
128 BuiltinActorError::Custom(LimitedStr::from_small_str("MSM SW: computation error"))
129 })?;
130
131 Ok(Self::encode_proj_sw(&res))
132 }
133
134 fn projective_mul_sw<T: SWCurveConfig>(
135 base: Vec<u8>,
136 scalar: Vec<u8>,
137 ) -> Result<Vec<u8>, BuiltinActorError> {
138 let base = Self::decode_proj_sw::<T>(base)?;
139 let scalar = Self::decode::<Vec<u64>>(scalar)?;
140 let res = <T as SWCurveConfig>::mul_projective(&base, &scalar);
141
142 Ok(Self::encode_proj_sw(&res))
143 }
144
145 fn encode<T: CanonicalSerialize>(val: T) -> Vec<u8> {
146 ArkScaleLocal::from(val).encode()
147 }
148
149 fn decode<T: CanonicalDeserialize>(buf: Vec<u8>) -> Result<T, BuiltinActorError> {
150 ArkScaleLocal::<T>::decode(&mut &buf[..])
151 .map(|v| v.0)
152 .map_err(|_| BuiltinActorError::DecodingError)
153 }
154
155 fn encode_proj_sw<T: SWCurveConfig>(val: &SWProjective<T>) -> Vec<u8> {
156 ArkScaleProjective::from(val).encode()
157 }
158
159 fn decode_proj_sw<T: SWCurveConfig>(
160 buf: Vec<u8>,
161 ) -> Result<SWProjective<T>, BuiltinActorError> {
162 ArkScaleProjective::decode(&mut &buf[..])
163 .map(|v| v.0)
164 .map_err(|_| BuiltinActorError::DecodingError)
165 }
166}