referrerpolicy=no-referrer-when-downgrade

sp_crypto_ec_utils/
vesta.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: Apache-2.0
5
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// 	http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18//! *Vesta* types and host functions.
19
20use crate::utils::{self, HostcallResult, FAIL_MSG};
21use alloc::vec::Vec;
22use ark_ec::{AffineRepr, CurveConfig, CurveGroup};
23use ark_vesta_ext::CurveHooks;
24use sp_runtime_interface::{
25	pass_by::{PassFatPointerAndRead, PassFatPointerAndWrite},
26	runtime_interface,
27};
28
29/// Group configuration.
30pub type VestaConfig = ark_vesta_ext::VestaConfig<HostHooks>;
31/// Short Weierstrass form point affine representation.
32pub type Affine = ark_vesta_ext::Affine<HostHooks>;
33/// Short Weierstrass form point projective representation.
34pub type Projective = ark_vesta_ext::Projective<HostHooks>;
35
36/// Group scalar field (Fr).
37pub type ScalarField = <VestaConfig as CurveConfig>::ScalarField;
38
39/// Curve hooks jumping into [`host_calls`] host functions.
40#[derive(Copy, Clone)]
41pub struct HostHooks;
42
43impl CurveHooks for HostHooks {
44	fn msm(bases: &[Affine], scalars: &[ScalarField]) -> Projective {
45		let mut out = utils::buffer_for::<Affine>();
46		host_calls::vesta_msm(&utils::encode(bases), &utils::encode(scalars), &mut out)
47			.and_then(|_| utils::decode::<Affine>(&out))
48			.expect(FAIL_MSG)
49			.into_group()
50	}
51
52	fn mul_projective(base: &Projective, scalar: &[u64]) -> Projective {
53		let mut out = utils::buffer_for::<Affine>();
54		host_calls::vesta_mul(&utils::encode(base.into_affine()), &utils::encode(scalar), &mut out)
55			.and_then(|_| utils::decode::<Affine>(&out))
56			.expect(FAIL_MSG)
57			.into_group()
58	}
59}
60
61/// Interfaces for working with *Arkworks* *Vesta* elliptic curve related types
62/// from within the runtime.
63///
64/// All types are (de-)serialized through the wrapper types from `ark-scale`.
65///
66/// `ArkScale`'s `Usage` generic parameter is expected to be set to "not-validated"
67/// and "not-compressed".
68#[runtime_interface]
69pub trait HostCalls {
70	/// Short Weierstrass multi scalar multiplication for *Vesta*.
71	///
72	/// Receives encoded:
73	/// - `bases`: `Vec<Affine>`.
74	/// - `scalars`: `Vec<ScalarField>`.
75	/// Writes encoded `Affine` to `out`.
76	fn vesta_msm(
77		bases: PassFatPointerAndRead<&[u8]>,
78		scalars: PassFatPointerAndRead<&[u8]>,
79		out: PassFatPointerAndWrite<&mut [u8]>,
80	) -> HostcallResult {
81		utils::msm_sw::<ark_vesta::VestaConfig>(bases, scalars, out)
82	}
83
84	/// Short Weierstrass affine multiplication for *Vesta*.
85	///
86	/// Receives encoded:
87	/// - `base`: `Affine`.
88	/// - `scalar`: `BigInteger`.
89	/// Writes encoded `Affine` to `out`.
90	fn vesta_mul(
91		base: PassFatPointerAndRead<&[u8]>,
92		scalar: PassFatPointerAndRead<&[u8]>,
93		out: PassFatPointerAndWrite<&mut [u8]>,
94	) -> HostcallResult {
95		utils::mul_sw::<ark_vesta::VestaConfig>(base, scalar, out)
96	}
97}
98
99#[cfg(test)]
100mod tests {
101	use super::*;
102	use crate::utils::testing::*;
103
104	#[test]
105	fn mul_works() {
106		mul_test::<Affine, ark_vesta::Affine>();
107	}
108
109	#[test]
110	fn msm_works() {
111		msm_test::<Affine, ark_vesta::Affine>();
112	}
113}