From 5103748bf4b570563a93c93108d380be2b037b3d Mon Sep 17 00:00:00 2001 From: shaorongqiang Date: Mon, 6 Nov 2023 12:00:01 +0800 Subject: [PATCH] add precompile ed25519 verify --- Cargo.toml | 1 + .../modules/evm/precompile/Cargo.toml | 1 + .../evm/precompile/ed25519_verify/Cargo.toml | 14 +++++ .../evm/precompile/ed25519_verify/src/lib.rs | 59 +++++++++++++++++++ .../modules/evm/precompile/src/lib.rs | 4 ++ src/components/finutils/src/bins/fn.rs | 2 +- src/components/finutils/src/bins/fn.yml | 6 -- 7 files changed, 80 insertions(+), 7 deletions(-) create mode 100644 src/components/contracts/modules/evm/precompile/ed25519_verify/Cargo.toml create mode 100644 src/components/contracts/modules/evm/precompile/ed25519_verify/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index 57d92f5b6..6cdcd8239 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,7 @@ members = [ "src/components/contracts/modules/evm/precompile/anemoi", "src/components/contracts/modules/evm/precompile/blake2", "src/components/contracts/modules/evm/precompile/bn128", + "src/components/contracts/modules/evm/precompile/ed25519_verify", "src/components/contracts/modules/evm/precompile/utils", "src/components/contracts/modules/evm/precompile/utils/macro", "src/components/contracts/modules/xhub", diff --git a/src/components/contracts/modules/evm/precompile/Cargo.toml b/src/components/contracts/modules/evm/precompile/Cargo.toml index 875e9a0cf..5e1533656 100644 --- a/src/components/contracts/modules/evm/precompile/Cargo.toml +++ b/src/components/contracts/modules/evm/precompile/Cargo.toml @@ -18,6 +18,7 @@ evm-precompile-sha3fips = {path = "./sha3fips"} evm-precompile-anemoi = {path = "./anemoi"} evm-precompile-blake2 = {path = "./blake2"} evm-precompile-bn128 = {path = "./bn128"} +evm-precompile-ed25519-verify = {path = "./ed25519_verify"} fp-core = {path = "../../../primitives/core"} module-evm = {path = "../../../modules/evm"} parking_lot = "0.12" diff --git a/src/components/contracts/modules/evm/precompile/ed25519_verify/Cargo.toml b/src/components/contracts/modules/evm/precompile/ed25519_verify/Cargo.toml new file mode 100644 index 000000000..9afa0bc9e --- /dev/null +++ b/src/components/contracts/modules/evm/precompile/ed25519_verify/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "evm-precompile-ed25519-verify" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +evm = { version = "0.35.0", default-features = false, features = ["with-serde"] } +evm-precompile-utils = { path = "../utils"} +tracing = "0.1" +module-evm = { path = "../../../../modules/evm"} +num_enum = { version = "0.5.4", default-features = false } +zei = { git = "https://github.com/FindoraNetwork/zei", branch = "stable-main" } diff --git a/src/components/contracts/modules/evm/precompile/ed25519_verify/src/lib.rs b/src/components/contracts/modules/evm/precompile/ed25519_verify/src/lib.rs new file mode 100644 index 000000000..dfecb85c0 --- /dev/null +++ b/src/components/contracts/modules/evm/precompile/ed25519_verify/src/lib.rs @@ -0,0 +1,59 @@ +use evm::executor::stack::{PrecompileFailure, PrecompileOutput}; +use evm::{Context, ExitError, ExitSucceed}; +use module_evm::precompile::{FinState, Precompile, PrecompileId, PrecompileResult}; +use zei::{ + serialization::ZeiFromToBytes, + xfr::sig::{XfrPublicKey, XfrSignature}, +}; + +pub struct Ed25519Verify; + +impl Ed25519Verify { + const GAS_COST: u64 = 50000; // https://eips.ethereum.org/EIPS/eip-1108 +} + +impl PrecompileId for Ed25519Verify { + fn contract_id() -> u64 { + 0x2003 + } +} + +impl Precompile for Ed25519Verify { + fn execute( + input: &[u8], + _target_gas: Option, + _context: &Context, + _state: &FinState, + ) -> PrecompileResult { + if input.len() < 128 { + return Err(PrecompileFailure::Error { + exit_status: ExitError::Other("input must contain 128 bytes".into()), + }); + }; + let pk = &input[0..32]; + let msg = &input[32..64]; + let sig = &input[64..128]; + let pub_key = + XfrPublicKey::zei_from_bytes(pk).map_err(|_| PrecompileFailure::Error { + exit_status: ExitError::Other("Public key recover failed".into()), + })?; + let sig = + XfrSignature::zei_from_bytes(sig).map_err(|_| PrecompileFailure::Error { + exit_status: ExitError::Other("Signature recover failed".into()), + })?; + + let mut buf = [0u8; 4]; + if pub_key.verify(msg, &sig).is_ok() { + buf[3] = 0u8; + } else { + buf[3] = 1u8; + }; + + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + cost: Self::GAS_COST, + output: buf.to_vec(), + logs: Default::default(), + }) + } +} diff --git a/src/components/contracts/modules/evm/precompile/src/lib.rs b/src/components/contracts/modules/evm/precompile/src/lib.rs index 994ec14ae..2eb3e07c6 100644 --- a/src/components/contracts/modules/evm/precompile/src/lib.rs +++ b/src/components/contracts/modules/evm/precompile/src/lib.rs @@ -1,5 +1,6 @@ use ethereum_types::H160; use evm::{executor::stack::PrecompileSet, Context}; +use evm_precompile_ed25519_verify::Ed25519Verify; use module_evm::precompile::{Precompile, PrecompileResult}; use std::marker::PhantomData; @@ -79,6 +80,9 @@ where a if a == H160::from_low_u64_be(Anemoi::contract_id()) => { Some(Anemoi::execute(input, target_gas, context, ctx)) } + a if a == H160::from_low_u64_be(Ed25519Verify::contract_id()) => { + Some(Ed25519Verify::execute(input, target_gas, context, ctx)) + } //a if a == H160::from_low_u64_be(EthPairing::contract_id()) => { // Some(EthPairing::execute(input, target_gas, context, ctx)) //} diff --git a/src/components/finutils/src/bins/fn.rs b/src/components/finutils/src/bins/fn.rs index 40889dc9f..dd0b8b3eb 100644 --- a/src/components/finutils/src/bins/fn.rs +++ b/src/components/finutils/src/bins/fn.rs @@ -277,7 +277,7 @@ fn run() -> Result<()> { let td_addr = m.value_of("validator-td-addr"); common::unstake(am, staker.as_deref(), td_addr).c(d!())?; } else if let Some(m) = matches.subcommand_matches("claim") { - let am = m.value_of("amount"); + let am = None; let seckey = match m.value_of("seckey") { Some(path) => { Some(fs::read_to_string(path).c(d!("Failed to read seckey file"))?) diff --git a/src/components/finutils/src/bins/fn.yml b/src/components/finutils/src/bins/fn.yml index 98a3a95b8..008be37cf 100644 --- a/src/components/finutils/src/bins/fn.yml +++ b/src/components/finutils/src/bins/fn.yml @@ -149,12 +149,6 @@ subcommands: long: validator-td-addr takes_value: true value_name: TendermintAddr - - amount: - help: how much `FRA unit`s to claim - short: n - long: amount - takes_value: true - value_name: Amount - seckey: help: the file which contains base64-formated `XfrPrivateKey` of an existing wallet long: seckey