// 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. use ark_ec::{ pairing::{MillerLoopOutput, Pairing, PairingOutput}, short_weierstrass, short_weierstrass::SWCurveConfig, twisted_edwards, twisted_edwards::TECurveConfig, CurveConfig, VariableBaseMSM, }; use ark_scale::{ hazmat::ArkScaleProjective, scale::{Decode, Encode}, }; use sp_std::vec::Vec; // Scale codec type which is expected to be used by the host functions. // // Encoding is set to `HOST_CALL` which is a shortcut for "not-validated" and "not-compressed". type ArkScale = ark_scale::ArkScale; pub fn multi_miller_loop(g1: Vec, g2: Vec) -> Result, ()> { let g1 = ::G1Affine>> as Decode>::decode(&mut g1.as_slice()) .map_err(|_| ())?; let g2 = ::G2Affine>> as Decode>::decode(&mut g2.as_slice()) .map_err(|_| ())?; let result = Curve::multi_miller_loop(g1.0, g2.0).0; let result: ArkScale<::TargetField> = result.into(); Ok(result.encode()) } pub fn final_exponentiation(target: Vec) -> Result, ()> { let target = ::TargetField> as Decode>::decode(&mut target.as_slice()) .map_err(|_| ())?; let result = Curve::final_exponentiation(MillerLoopOutput(target.0)).ok_or(())?; let result: ArkScale> = result.into(); Ok(result.encode()) } pub fn msm_sw(bases: Vec, scalars: Vec) -> Result, ()> { let bases = >> as Decode>::decode(&mut bases.as_slice()) .map_err(|_| ())?; let scalars = ::ScalarField>> as Decode>::decode( &mut scalars.as_slice(), ) .map_err(|_| ())?; let result = as VariableBaseMSM>::msm(&bases.0, &scalars.0) .map_err(|_| ())?; let result: ArkScaleProjective> = result.into(); Ok(result.encode()) } pub fn msm_te(bases: Vec, scalars: Vec) -> Result, ()> { let bases = >> as Decode>::decode(&mut bases.as_slice()) .map_err(|_| ())?; let scalars = ::ScalarField>> as Decode>::decode( &mut scalars.as_slice(), ) .map_err(|_| ())?; let result = as VariableBaseMSM>::msm(&bases.0, &scalars.0) .map_err(|_| ())?; let result: ArkScaleProjective> = result.into(); Ok(result.encode()) } pub fn mul_projective_sw( base: Vec, scalar: Vec, ) -> Result, ()> { let base = > as Decode>::decode( &mut base.as_slice(), ) .map_err(|_| ())?; let scalar = > as Decode>::decode(&mut scalar.as_slice()).map_err(|_| ())?; let result = ::mul_projective(&base.0, &scalar.0); let result: ArkScaleProjective> = result.into(); Ok(result.encode()) } pub fn mul_projective_te( base: Vec, scalar: Vec, ) -> Result, ()> { let base = > as Decode>::decode( &mut base.as_slice(), ) .map_err(|_| ())?; let scalar = > as Decode>::decode(&mut scalar.as_slice()).map_err(|_| ())?; let result = ::mul_projective(&base.0, &scalar.0); let result: ArkScaleProjective> = result.into(); Ok(result.encode()) }