ethcore-builtin (#10850)
* ethcore-builtin * rename ethcore-builtin Impl to Implementation
This commit is contained in:
parent
c4c5d79a0f
commit
fe7bc545bf
20
Cargo.lock
generated
20
Cargo.lock
generated
@ -812,7 +812,6 @@ dependencies = [
|
|||||||
"account-db 0.1.0",
|
"account-db 0.1.0",
|
||||||
"ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"blooms-db 0.1.0",
|
"blooms-db 0.1.0",
|
||||||
"bn 0.4.4 (git+https://github.com/paritytech/bn)",
|
|
||||||
"common-types 0.1.0",
|
"common-types 0.1.0",
|
||||||
"criterion 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"criterion 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -825,6 +824,7 @@ dependencies = [
|
|||||||
"ethcore-accounts 0.1.0",
|
"ethcore-accounts 0.1.0",
|
||||||
"ethcore-blockchain 0.1.0",
|
"ethcore-blockchain 0.1.0",
|
||||||
"ethcore-bloom-journal 0.1.0",
|
"ethcore-bloom-journal 0.1.0",
|
||||||
|
"ethcore-builtin 0.1.0",
|
||||||
"ethcore-call-contract 0.1.0",
|
"ethcore-call-contract 0.1.0",
|
||||||
"ethcore-db 0.1.0",
|
"ethcore-db 0.1.0",
|
||||||
"ethcore-io 1.12.0",
|
"ethcore-io 1.12.0",
|
||||||
@ -851,10 +851,8 @@ dependencies = [
|
|||||||
"macros 0.1.0",
|
"macros 0.1.0",
|
||||||
"memory-cache 0.1.0",
|
"memory-cache 0.1.0",
|
||||||
"memory-db 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"memory-db 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parity-crypto 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"parity-runtime 0.1.0",
|
"parity-runtime 0.1.0",
|
||||||
"parity-snappy 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parity-snappy 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parity-util-mem 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parity-util-mem 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -934,6 +932,22 @@ dependencies = [
|
|||||||
"siphasher 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"siphasher 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ethcore-builtin"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"bn 0.4.4 (git+https://github.com/paritytech/bn)",
|
||||||
|
"ethereum-types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"ethjson 0.1.0",
|
||||||
|
"ethkey 0.3.0",
|
||||||
|
"keccak-hash 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"parity-crypto 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ethcore-call-contract"
|
name = "ethcore-call-contract"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -10,7 +10,6 @@ authors = ["Parity Technologies <admin@parity.io>"]
|
|||||||
account-db = { path = "account-db" }
|
account-db = { path = "account-db" }
|
||||||
ansi_term = "0.11"
|
ansi_term = "0.11"
|
||||||
blooms-db = { path = "../util/blooms-db", optional = true }
|
blooms-db = { path = "../util/blooms-db", optional = true }
|
||||||
bn = { git = "https://github.com/paritytech/bn", default-features = false }
|
|
||||||
common-types = { path = "types" }
|
common-types = { path = "types" }
|
||||||
crossbeam-utils = "0.6"
|
crossbeam-utils = "0.6"
|
||||||
derive_more = "0.14.0"
|
derive_more = "0.14.0"
|
||||||
@ -21,6 +20,7 @@ ethabi-derive = "8.0"
|
|||||||
ethash = { path = "../ethash" }
|
ethash = { path = "../ethash" }
|
||||||
ethcore-blockchain = { path = "./blockchain" }
|
ethcore-blockchain = { path = "./blockchain" }
|
||||||
ethcore-bloom-journal = { path = "../util/bloom" }
|
ethcore-bloom-journal = { path = "../util/bloom" }
|
||||||
|
ethcore-builtin = { path = "./builtin" }
|
||||||
ethcore-call-contract = { path = "./call-contract" }
|
ethcore-call-contract = { path = "./call-contract" }
|
||||||
ethcore-db = { path = "./db" }
|
ethcore-db = { path = "./db" }
|
||||||
ethcore-io = { path = "../util/io" }
|
ethcore-io = { path = "../util/io" }
|
||||||
@ -47,10 +47,8 @@ lru-cache = "0.1"
|
|||||||
macros = { path = "../util/macros" }
|
macros = { path = "../util/macros" }
|
||||||
memory-cache = { path = "../util/memory-cache" }
|
memory-cache = { path = "../util/memory-cache" }
|
||||||
memory-db = "0.12.4"
|
memory-db = "0.12.4"
|
||||||
num = { version = "0.1", default-features = false, features = ["bigint"] }
|
|
||||||
num_cpus = "1.2"
|
num_cpus = "1.2"
|
||||||
parity-bytes = "0.1"
|
parity-bytes = "0.1"
|
||||||
parity-crypto = "0.4.0"
|
|
||||||
parity-snappy = "0.1"
|
parity-snappy = "0.1"
|
||||||
parking_lot = "0.8"
|
parking_lot = "0.8"
|
||||||
pod-account = { path = "pod-account" }
|
pod-account = { path = "pod-account" }
|
||||||
|
21
ethcore/builtin/Cargo.toml
Normal file
21
ethcore/builtin/Cargo.toml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
[package]
|
||||||
|
description = "ethereum vm builtin"
|
||||||
|
name = "ethcore-builtin"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
bn = { git = "https://github.com/paritytech/bn", default-features = false }
|
||||||
|
ethereum-types = "0.6.0"
|
||||||
|
ethjson = { path = "../../json" }
|
||||||
|
ethkey = { path = "../../accounts/ethkey" }
|
||||||
|
keccak-hash = "0.2.0"
|
||||||
|
log = "0.4"
|
||||||
|
num = { version = "0.1", default-features = false, features = ["bigint"] }
|
||||||
|
parity-bytes = "0.1"
|
||||||
|
parity-crypto = "0.4.0"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
rustc-hex = "1.0"
|
||||||
|
|
@ -16,42 +16,29 @@
|
|||||||
|
|
||||||
//! Standard built-in contracts.
|
//! Standard built-in contracts.
|
||||||
|
|
||||||
use std::cmp::{max, min};
|
use std::{
|
||||||
use std::io::{self, Read};
|
cmp::{max, min},
|
||||||
|
io::{self, Read},
|
||||||
|
};
|
||||||
|
|
||||||
use parity_crypto::digest;
|
use bn;
|
||||||
use num::{BigUint, Zero, One};
|
|
||||||
|
|
||||||
use hash::keccak;
|
|
||||||
use ethereum_types::{H256, U256};
|
use ethereum_types::{H256, U256};
|
||||||
use bytes::BytesRef;
|
|
||||||
use ethkey::{Signature, recover as ec_recover};
|
|
||||||
use ethjson;
|
use ethjson;
|
||||||
|
use ethkey::{Signature, recover as ec_recover};
|
||||||
/// Execution error.
|
use keccak_hash::keccak;
|
||||||
#[derive(Debug)]
|
use log::{warn, trace};
|
||||||
pub struct Error(pub &'static str);
|
use num::{BigUint, Zero, One};
|
||||||
|
use parity_bytes::BytesRef;
|
||||||
impl From<&'static str> for Error {
|
use parity_crypto::digest;
|
||||||
fn from(val: &'static str) -> Self {
|
|
||||||
Error(val)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Into<::vm::Error> for Error {
|
|
||||||
fn into(self) -> ::vm::Error {
|
|
||||||
::vm::Error::BuiltIn(self.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Native implementation of a built-in contract.
|
/// Native implementation of a built-in contract.
|
||||||
pub trait Impl: Send + Sync {
|
trait Implementation: Send + Sync {
|
||||||
/// execute this built-in on the given input, writing to the given output.
|
/// execute this built-in on the given input, writing to the given output.
|
||||||
fn execute(&self, input: &[u8], output: &mut BytesRef) -> Result<(), Error>;
|
fn execute(&self, input: &[u8], output: &mut BytesRef) -> Result<(), &'static str>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A gas pricing scheme for built-in contracts.
|
/// A gas pricing scheme for built-in contracts.
|
||||||
pub trait Pricer: Send + Sync {
|
trait Pricer: Send + Sync {
|
||||||
/// The gas cost of running this built-in for the given input data.
|
/// The gas cost of running this built-in for the given input data.
|
||||||
fn cost(&self, input: &[u8]) -> U256;
|
fn cost(&self, input: &[u8]) -> U256;
|
||||||
}
|
}
|
||||||
@ -157,21 +144,25 @@ impl ModexpPricer {
|
|||||||
/// Unless `is_active` is true,
|
/// Unless `is_active` is true,
|
||||||
pub struct Builtin {
|
pub struct Builtin {
|
||||||
pricer: Box<dyn Pricer>,
|
pricer: Box<dyn Pricer>,
|
||||||
native: Box<dyn Impl>,
|
native: Box<dyn Implementation>,
|
||||||
activate_at: u64,
|
activate_at: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Builtin {
|
impl Builtin {
|
||||||
/// Simple forwarder for cost.
|
/// Simple forwarder for cost.
|
||||||
pub fn cost(&self, input: &[u8]) -> U256 { self.pricer.cost(input) }
|
pub fn cost(&self, input: &[u8]) -> U256 {
|
||||||
|
self.pricer.cost(input)
|
||||||
|
}
|
||||||
|
|
||||||
/// Simple forwarder for execute.
|
/// Simple forwarder for execute.
|
||||||
pub fn execute(&self, input: &[u8], output: &mut BytesRef) -> Result<(), Error> {
|
pub fn execute(&self, input: &[u8], output: &mut BytesRef) -> Result<(), &'static str> {
|
||||||
self.native.execute(input, output)
|
self.native.execute(input, output)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether the builtin is activated at the given block number.
|
/// Whether the builtin is activated at the given block number.
|
||||||
pub fn is_active(&self, at: u64) -> bool { at >= self.activate_at }
|
pub fn is_active(&self, at: u64) -> bool {
|
||||||
|
at >= self.activate_at
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ethjson::spec::Builtin> for Builtin {
|
impl From<ethjson::spec::Builtin> for Builtin {
|
||||||
@ -210,16 +201,16 @@ impl From<ethjson::spec::Builtin> for Builtin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Ethereum built-in factory.
|
/// Ethereum built-in factory.
|
||||||
pub fn ethereum_builtin(name: &str) -> Box<dyn Impl> {
|
fn ethereum_builtin(name: &str) -> Box<dyn Implementation> {
|
||||||
match name {
|
match name {
|
||||||
"identity" => Box::new(Identity) as Box<dyn Impl>,
|
"identity" => Box::new(Identity) as Box<dyn Implementation>,
|
||||||
"ecrecover" => Box::new(EcRecover) as Box<dyn Impl>,
|
"ecrecover" => Box::new(EcRecover) as Box<dyn Implementation>,
|
||||||
"sha256" => Box::new(Sha256) as Box<dyn Impl>,
|
"sha256" => Box::new(Sha256) as Box<dyn Implementation>,
|
||||||
"ripemd160" => Box::new(Ripemd160) as Box<dyn Impl>,
|
"ripemd160" => Box::new(Ripemd160) as Box<dyn Implementation>,
|
||||||
"modexp" => Box::new(ModexpImpl) as Box<dyn Impl>,
|
"modexp" => Box::new(Modexp) as Box<dyn Implementation>,
|
||||||
"alt_bn128_add" => Box::new(Bn128AddImpl) as Box<dyn Impl>,
|
"alt_bn128_add" => Box::new(Bn128Add) as Box<dyn Implementation>,
|
||||||
"alt_bn128_mul" => Box::new(Bn128MulImpl) as Box<dyn Impl>,
|
"alt_bn128_mul" => Box::new(Bn128Mul) as Box<dyn Implementation>,
|
||||||
"alt_bn128_pairing" => Box::new(Bn128PairingImpl) as Box<dyn Impl>,
|
"alt_bn128_pairing" => Box::new(Bn128Pairing) as Box<dyn Implementation>,
|
||||||
_ => panic!("invalid builtin name: {}", name),
|
_ => panic!("invalid builtin name: {}", name),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -245,26 +236,26 @@ struct Sha256;
|
|||||||
struct Ripemd160;
|
struct Ripemd160;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct ModexpImpl;
|
struct Modexp;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Bn128AddImpl;
|
struct Bn128Add;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Bn128MulImpl;
|
struct Bn128Mul;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Bn128PairingImpl;
|
struct Bn128Pairing;
|
||||||
|
|
||||||
impl Impl for Identity {
|
impl Implementation for Identity {
|
||||||
fn execute(&self, input: &[u8], output: &mut BytesRef) -> Result<(), Error> {
|
fn execute(&self, input: &[u8], output: &mut BytesRef) -> Result<(), &'static str> {
|
||||||
output.write(0, input);
|
output.write(0, input);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Impl for EcRecover {
|
impl Implementation for EcRecover {
|
||||||
fn execute(&self, i: &[u8], output: &mut BytesRef) -> Result<(), Error> {
|
fn execute(&self, i: &[u8], output: &mut BytesRef) -> Result<(), &'static str> {
|
||||||
let len = min(i.len(), 128);
|
let len = min(i.len(), 128);
|
||||||
|
|
||||||
let mut input = [0; 128];
|
let mut input = [0; 128];
|
||||||
@ -293,16 +284,16 @@ impl Impl for EcRecover {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Impl for Sha256 {
|
impl Implementation for Sha256 {
|
||||||
fn execute(&self, input: &[u8], output: &mut BytesRef) -> Result<(), Error> {
|
fn execute(&self, input: &[u8], output: &mut BytesRef) -> Result<(), &'static str> {
|
||||||
let d = digest::sha256(input);
|
let d = digest::sha256(input);
|
||||||
output.write(0, &*d);
|
output.write(0, &*d);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Impl for Ripemd160 {
|
impl Implementation for Ripemd160 {
|
||||||
fn execute(&self, input: &[u8], output: &mut BytesRef) -> Result<(), Error> {
|
fn execute(&self, input: &[u8], output: &mut BytesRef) -> Result<(), &'static str> {
|
||||||
let hash = digest::ripemd160(input);
|
let hash = digest::ripemd160(input);
|
||||||
output.write(0, &[0; 12][..]);
|
output.write(0, &[0; 12][..]);
|
||||||
output.write(12, &hash);
|
output.write(12, &hash);
|
||||||
@ -358,8 +349,8 @@ fn modexp(mut base: BigUint, exp: Vec<u8>, modulus: BigUint) -> BigUint {
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Impl for ModexpImpl {
|
impl Implementation for Modexp {
|
||||||
fn execute(&self, input: &[u8], output: &mut BytesRef) -> Result<(), Error> {
|
fn execute(&self, input: &[u8], output: &mut BytesRef) -> Result<(), &'static str> {
|
||||||
let mut reader = input.chain(io::repeat(0));
|
let mut reader = input.chain(io::repeat(0));
|
||||||
let mut buf = [0; 32];
|
let mut buf = [0; 32];
|
||||||
|
|
||||||
@ -412,35 +403,35 @@ impl Impl for ModexpImpl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_fr(reader: &mut io::Chain<&[u8], io::Repeat>) -> Result<::bn::Fr, Error> {
|
fn read_fr(reader: &mut io::Chain<&[u8], io::Repeat>) -> Result<bn::Fr, &'static str> {
|
||||||
let mut buf = [0u8; 32];
|
let mut buf = [0u8; 32];
|
||||||
|
|
||||||
reader.read_exact(&mut buf[..]).expect("reading from zero-extended memory cannot fail; qed");
|
reader.read_exact(&mut buf[..]).expect("reading from zero-extended memory cannot fail; qed");
|
||||||
::bn::Fr::from_slice(&buf[0..32]).map_err(|_| Error::from("Invalid field element"))
|
bn::Fr::from_slice(&buf[0..32]).map_err(|_| "Invalid field element")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_point(reader: &mut io::Chain<&[u8], io::Repeat>) -> Result<::bn::G1, Error> {
|
fn read_point(reader: &mut io::Chain<&[u8], io::Repeat>) -> Result<bn::G1, &'static str> {
|
||||||
use bn::{Fq, AffineG1, G1, Group};
|
use bn::{Fq, AffineG1, G1, Group};
|
||||||
|
|
||||||
let mut buf = [0u8; 32];
|
let mut buf = [0u8; 32];
|
||||||
|
|
||||||
reader.read_exact(&mut buf[..]).expect("reading from zero-extended memory cannot fail; qed");
|
reader.read_exact(&mut buf[..]).expect("reading from zero-extended memory cannot fail; qed");
|
||||||
let px = Fq::from_slice(&buf[0..32]).map_err(|_| Error::from("Invalid point x coordinate"))?;
|
let px = Fq::from_slice(&buf[0..32]).map_err(|_| "Invalid point x coordinate")?;
|
||||||
|
|
||||||
reader.read_exact(&mut buf[..]).expect("reading from zero-extended memory cannot fail; qed");
|
reader.read_exact(&mut buf[..]).expect("reading from zero-extended memory cannot fail; qed");
|
||||||
let py = Fq::from_slice(&buf[0..32]).map_err(|_| Error::from("Invalid point y coordinate"))?;
|
let py = Fq::from_slice(&buf[0..32]).map_err(|_| "Invalid point y coordinate")?;
|
||||||
Ok(
|
Ok(
|
||||||
if px == Fq::zero() && py == Fq::zero() {
|
if px == Fq::zero() && py == Fq::zero() {
|
||||||
G1::zero()
|
G1::zero()
|
||||||
} else {
|
} else {
|
||||||
AffineG1::new(px, py).map_err(|_| Error::from("Invalid curve point"))?.into()
|
AffineG1::new(px, py).map_err(|_| "Invalid curve point")?.into()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Impl for Bn128AddImpl {
|
impl Implementation for Bn128Add {
|
||||||
// Can fail if any of the 2 points does not belong the bn128 curve
|
// Can fail if any of the 2 points does not belong the bn128 curve
|
||||||
fn execute(&self, input: &[u8], output: &mut BytesRef) -> Result<(), Error> {
|
fn execute(&self, input: &[u8], output: &mut BytesRef) -> Result<(), &'static str> {
|
||||||
use bn::AffineG1;
|
use bn::AffineG1;
|
||||||
|
|
||||||
let mut padded_input = input.chain(io::repeat(0));
|
let mut padded_input = input.chain(io::repeat(0));
|
||||||
@ -459,9 +450,9 @@ impl Impl for Bn128AddImpl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Impl for Bn128MulImpl {
|
impl Implementation for Bn128Mul {
|
||||||
// Can fail if first paramter (bn128 curve point) does not actually belong to the curve
|
// Can fail if first paramter (bn128 curve point) does not actually belong to the curve
|
||||||
fn execute(&self, input: &[u8], output: &mut BytesRef) -> Result<(), Error> {
|
fn execute(&self, input: &[u8], output: &mut BytesRef) -> Result<(), &'static str> {
|
||||||
use bn::AffineG1;
|
use bn::AffineG1;
|
||||||
|
|
||||||
let mut padded_input = input.chain(io::repeat(0));
|
let mut padded_input = input.chain(io::repeat(0));
|
||||||
@ -479,12 +470,12 @@ impl Impl for Bn128MulImpl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Impl for Bn128PairingImpl {
|
impl Implementation for Bn128Pairing {
|
||||||
/// Can fail if:
|
/// Can fail if:
|
||||||
/// - input length is not a multiple of 192
|
/// - input length is not a multiple of 192
|
||||||
/// - any of odd points does not belong to bn128 curve
|
/// - any of odd points does not belong to bn128 curve
|
||||||
/// - any of even points does not belong to the twisted bn128 curve over the field F_p^2 = F_p[i] / (i^2 + 1)
|
/// - any of even points does not belong to the twisted bn128 curve over the field F_p^2 = F_p[i] / (i^2 + 1)
|
||||||
fn execute(&self, input: &[u8], output: &mut BytesRef) -> Result<(), Error> {
|
fn execute(&self, input: &[u8], output: &mut BytesRef) -> Result<(), &'static str> {
|
||||||
if input.len() % 192 != 0 {
|
if input.len() % 192 != 0 {
|
||||||
return Err("Invalid input length, must be multiple of 192 (3 * (32*2))".into())
|
return Err("Invalid input length, must be multiple of 192 (3 * (32*2))".into())
|
||||||
}
|
}
|
||||||
@ -497,8 +488,8 @@ impl Impl for Bn128PairingImpl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Bn128PairingImpl {
|
impl Bn128Pairing {
|
||||||
fn execute_with_error(&self, input: &[u8], output: &mut BytesRef) -> Result<(), Error> {
|
fn execute_with_error(&self, input: &[u8], output: &mut BytesRef) -> Result<(), &'static str> {
|
||||||
use bn::{AffineG1, AffineG2, Fq, Fq2, pairing_batch, G1, G2, Gt, Group};
|
use bn::{AffineG1, AffineG2, Fq, Fq2, pairing_batch, G1, G2, Gt, Group};
|
||||||
|
|
||||||
let elements = input.len() / 192; // (a, b_a, b_b - each 64-byte affine coordinates)
|
let elements = input.len() / 192; // (a, b_a, b_b - each 64-byte affine coordinates)
|
||||||
@ -508,34 +499,34 @@ impl Bn128PairingImpl {
|
|||||||
let mut vals = Vec::new();
|
let mut vals = Vec::new();
|
||||||
for idx in 0..elements {
|
for idx in 0..elements {
|
||||||
let a_x = Fq::from_slice(&input[idx*192..idx*192+32])
|
let a_x = Fq::from_slice(&input[idx*192..idx*192+32])
|
||||||
.map_err(|_| Error::from("Invalid a argument x coordinate"))?;
|
.map_err(|_| "Invalid a argument x coordinate")?;
|
||||||
|
|
||||||
let a_y = Fq::from_slice(&input[idx*192+32..idx*192+64])
|
let a_y = Fq::from_slice(&input[idx*192+32..idx*192+64])
|
||||||
.map_err(|_| Error::from("Invalid a argument y coordinate"))?;
|
.map_err(|_| "Invalid a argument y coordinate")?;
|
||||||
|
|
||||||
let b_a_y = Fq::from_slice(&input[idx*192+64..idx*192+96])
|
let b_a_y = Fq::from_slice(&input[idx*192+64..idx*192+96])
|
||||||
.map_err(|_| Error::from("Invalid b argument imaginary coeff x coordinate"))?;
|
.map_err(|_| "Invalid b argument imaginary coeff x coordinate")?;
|
||||||
|
|
||||||
let b_a_x = Fq::from_slice(&input[idx*192+96..idx*192+128])
|
let b_a_x = Fq::from_slice(&input[idx*192+96..idx*192+128])
|
||||||
.map_err(|_| Error::from("Invalid b argument imaginary coeff y coordinate"))?;
|
.map_err(|_| "Invalid b argument imaginary coeff y coordinate")?;
|
||||||
|
|
||||||
let b_b_y = Fq::from_slice(&input[idx*192+128..idx*192+160])
|
let b_b_y = Fq::from_slice(&input[idx*192+128..idx*192+160])
|
||||||
.map_err(|_| Error::from("Invalid b argument real coeff x coordinate"))?;
|
.map_err(|_| "Invalid b argument real coeff x coordinate")?;
|
||||||
|
|
||||||
let b_b_x = Fq::from_slice(&input[idx*192+160..idx*192+192])
|
let b_b_x = Fq::from_slice(&input[idx*192+160..idx*192+192])
|
||||||
.map_err(|_| Error::from("Invalid b argument real coeff y coordinate"))?;
|
.map_err(|_| "Invalid b argument real coeff y coordinate")?;
|
||||||
|
|
||||||
let b_a = Fq2::new(b_a_x, b_a_y);
|
let b_a = Fq2::new(b_a_x, b_a_y);
|
||||||
let b_b = Fq2::new(b_b_x, b_b_y);
|
let b_b = Fq2::new(b_b_x, b_b_y);
|
||||||
let b = if b_a.is_zero() && b_b.is_zero() {
|
let b = if b_a.is_zero() && b_b.is_zero() {
|
||||||
G2::zero()
|
G2::zero()
|
||||||
} else {
|
} else {
|
||||||
G2::from(AffineG2::new(b_a, b_b).map_err(|_| Error::from("Invalid b argument - not on curve"))?)
|
G2::from(AffineG2::new(b_a, b_b).map_err(|_| "Invalid b argument - not on curve")?)
|
||||||
};
|
};
|
||||||
let a = if a_x.is_zero() && a_y.is_zero() {
|
let a = if a_x.is_zero() && a_y.is_zero() {
|
||||||
G1::zero()
|
G1::zero()
|
||||||
} else {
|
} else {
|
||||||
G1::from(AffineG1::new(a_x, a_y).map_err(|_| Error::from("Invalid a argument - not on curve"))?)
|
G1::from(AffineG1::new(a_x, a_y).map_err(|_| "Invalid a argument - not on curve")?)
|
||||||
};
|
};
|
||||||
vals.push((a, b));
|
vals.push((a, b));
|
||||||
};
|
};
|
||||||
@ -559,12 +550,12 @@ impl Bn128PairingImpl {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::{Builtin, Linear, ethereum_builtin, Pricer, ModexpPricer, modexp as me};
|
|
||||||
use ethjson;
|
|
||||||
use ethereum_types::U256;
|
use ethereum_types::U256;
|
||||||
use bytes::BytesRef;
|
use ethjson;
|
||||||
use rustc_hex::FromHex;
|
|
||||||
use num::{BigUint, Zero, One};
|
use num::{BigUint, Zero, One};
|
||||||
|
use parity_bytes::BytesRef;
|
||||||
|
use rustc_hex::FromHex;
|
||||||
|
use super::{Builtin, Linear, ethereum_builtin, Pricer, ModexpPricer, modexp as me};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn modexp_func() {
|
fn modexp_func() {
|
||||||
@ -946,8 +937,8 @@ mod tests {
|
|||||||
let res = f.execute(input, &mut BytesRef::Fixed(&mut output[..]));
|
let res = f.execute(input, &mut BytesRef::Fixed(&mut output[..]));
|
||||||
if let Some(msg) = msg_contains {
|
if let Some(msg) = msg_contains {
|
||||||
if let Err(e) = res {
|
if let Err(e) = res {
|
||||||
if !e.0.contains(msg) {
|
if !e.contains(msg) {
|
||||||
panic!("There should be error containing '{}' here, but got: '{}'", msg, e.0);
|
panic!("There should be error containing '{}' here, but got: '{}'", msg, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
@ -406,7 +406,7 @@ impl<'a> CallCreateExecutive<'a> {
|
|||||||
if let Err(e) = result {
|
if let Err(e) = result {
|
||||||
state.revert_to_checkpoint();
|
state.revert_to_checkpoint();
|
||||||
|
|
||||||
Err(e.into())
|
Err(vm::Error::BuiltIn(e))
|
||||||
} else {
|
} else {
|
||||||
state.discard_checkpoint();
|
state.discard_checkpoint();
|
||||||
|
|
||||||
|
@ -55,13 +55,13 @@
|
|||||||
|
|
||||||
extern crate account_db;
|
extern crate account_db;
|
||||||
extern crate ansi_term;
|
extern crate ansi_term;
|
||||||
extern crate bn;
|
|
||||||
extern crate common_types as types;
|
extern crate common_types as types;
|
||||||
extern crate crossbeam_utils;
|
extern crate crossbeam_utils;
|
||||||
extern crate ethabi;
|
extern crate ethabi;
|
||||||
extern crate ethash;
|
extern crate ethash;
|
||||||
extern crate ethcore_blockchain as blockchain;
|
extern crate ethcore_blockchain as blockchain;
|
||||||
extern crate ethcore_bloom_journal as bloom_journal;
|
extern crate ethcore_bloom_journal as bloom_journal;
|
||||||
|
extern crate ethcore_builtin as builtin;
|
||||||
extern crate ethcore_call_contract as call_contract;
|
extern crate ethcore_call_contract as call_contract;
|
||||||
extern crate ethcore_db as db;
|
extern crate ethcore_db as db;
|
||||||
extern crate ethcore_io as io;
|
extern crate ethcore_io as io;
|
||||||
@ -83,10 +83,8 @@ extern crate len_caching_lock;
|
|||||||
extern crate lru_cache;
|
extern crate lru_cache;
|
||||||
extern crate memory_cache;
|
extern crate memory_cache;
|
||||||
extern crate memory_db;
|
extern crate memory_db;
|
||||||
extern crate num;
|
|
||||||
extern crate num_cpus;
|
extern crate num_cpus;
|
||||||
extern crate parity_bytes as bytes;
|
extern crate parity_bytes as bytes;
|
||||||
extern crate parity_crypto;
|
|
||||||
extern crate parity_snappy as snappy;
|
extern crate parity_snappy as snappy;
|
||||||
extern crate parking_lot;
|
extern crate parking_lot;
|
||||||
extern crate pod_account;
|
extern crate pod_account;
|
||||||
@ -153,7 +151,6 @@ extern crate fetch;
|
|||||||
extern crate parity_runtime;
|
extern crate parity_runtime;
|
||||||
|
|
||||||
pub mod block;
|
pub mod block;
|
||||||
pub mod builtin;
|
|
||||||
pub mod client;
|
pub mod client;
|
||||||
pub mod engines;
|
pub mod engines;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
|
Loading…
Reference in New Issue
Block a user