// This file is part of Substrate. // Copyright (C) Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //! Generic executions of the operations for *Arkworks* elliptic curves. // As not all functions are used by each elliptic curve and some elliptic // curve may be excluded by the build we resort to `#[allow(unused)]` to // suppress the expected warning. use alloc::vec::Vec; use ark_ec::{ pairing::{MillerLoopOutput, Pairing}, short_weierstrass::{Affine as SWAffine, Projective as SWProjective, SWCurveConfig}, twisted_edwards::{Affine as TEAffine, Projective as TEProjective, TECurveConfig}, CurveConfig, VariableBaseMSM, }; use ark_scale::{ ark_serialize::{CanonicalDeserialize, CanonicalSerialize, Compress, Validate}, scale::{Decode, Encode}, }; // SCALE encoding parameters shared by all the enabled modules const SCALE_USAGE: u8 = ark_scale::make_usage(Compress::No, Validate::No); type ArkScale = ark_scale::ArkScale; type ArkScaleProjective = ark_scale::hazmat::ArkScaleProjective; #[inline(always)] pub fn encode(val: T) -> Vec { ArkScale::from(val).encode() } #[inline(always)] pub fn decode(buf: Vec) -> Result { ArkScale::::decode(&mut &buf[..]).map_err(|_| ()).map(|v| v.0) } #[inline(always)] pub fn encode_proj_sw(val: &SWProjective) -> Vec { ArkScaleProjective::from(val).encode() } #[inline(always)] pub fn decode_proj_sw(buf: Vec) -> Result, ()> { ArkScaleProjective::decode(&mut &buf[..]).map_err(|_| ()).map(|v| v.0) } #[inline(always)] pub fn encode_proj_te(val: &TEProjective) -> Vec { ArkScaleProjective::from(val).encode() } #[inline(always)] pub fn decode_proj_te(buf: Vec) -> Result, ()> { ArkScaleProjective::decode(&mut &buf[..]).map_err(|_| ()).map(|v| v.0) } #[allow(unused)] pub fn multi_miller_loop(g1: Vec, g2: Vec) -> Result, ()> { let g1 = decode::::G1Affine>>(g1)?; let g2 = decode::::G2Affine>>(g2)?; let res = T::multi_miller_loop(g1, g2); Ok(encode(res.0)) } #[allow(unused)] pub fn final_exponentiation(target: Vec) -> Result, ()> { let target = decode::<::TargetField>(target)?; let res = T::final_exponentiation(MillerLoopOutput(target)).ok_or(())?; Ok(encode(res.0)) } #[allow(unused)] pub fn msm_sw(bases: Vec, scalars: Vec) -> Result, ()> { let bases = decode::>>(bases)?; let scalars = decode::::ScalarField>>(scalars)?; let res = as VariableBaseMSM>::msm(&bases, &scalars).map_err(|_| ())?; Ok(encode_proj_sw(&res)) } #[allow(unused)] pub fn msm_te(bases: Vec, scalars: Vec) -> Result, ()> { let bases = decode::>>(bases)?; let scalars = decode::::ScalarField>>(scalars)?; let res = as VariableBaseMSM>::msm(&bases, &scalars).map_err(|_| ())?; Ok(encode_proj_te(&res)) } #[allow(unused)] pub fn mul_projective_sw(base: Vec, scalar: Vec) -> Result, ()> { let base = decode_proj_sw::(base)?; let scalar = decode::>(scalar)?; let res = ::mul_projective(&base, &scalar); Ok(encode_proj_sw(&res)) } #[allow(unused)] pub fn mul_projective_te(base: Vec, scalar: Vec) -> Result, ()> { let base = decode_proj_te::(base)?; let scalar = decode::>(scalar)?; let res = ::mul_projective(&base, &scalar); Ok(encode_proj_te(&res)) }