ovr_evm_precompile_ed25519/
lib.rs1extern crate alloc;
19
20use alloc::vec::Vec;
21use core::convert::TryFrom;
22use ed25519_dalek::{PublicKey, Signature, Verifier};
23use fp_evm::{ExitError, ExitSucceed, LinearCostPrecompile, PrecompileFailure};
24
25pub struct Ed25519Verify;
26
27impl LinearCostPrecompile for Ed25519Verify {
28 const BASE: u64 = 15;
29 const WORD: u64 = 3;
30
31 fn execute(input: &[u8], _: u64) -> Result<(ExitSucceed, Vec<u8>), PrecompileFailure> {
32 if input.len() < 128 {
33 return Err(PrecompileFailure::Error {
34 exit_status: ExitError::Other("input must contain 128 bytes".into()),
35 });
36 };
37
38 let mut i = [0u8; 128];
39 i[..128].copy_from_slice(&input[..128]);
40
41 let mut buf = [0u8; 4];
42
43 let msg = &i[0..32];
44 let pk = PublicKey::from_bytes(&i[32..64]).map_err(|_| PrecompileFailure::Error {
45 exit_status: ExitError::Other("Public key recover failed".into()),
46 })?;
47 let sig = Signature::try_from(&i[64..128]).map_err(|_| PrecompileFailure::Error {
48 exit_status: ExitError::Other("Signature recover failed".into()),
49 })?;
50
51 if pk.verify(msg, &sig).is_ok() {
53 buf[3] = 0u8;
54 } else {
55 buf[3] = 1u8;
56 };
57
58 Ok((ExitSucceed::Returned, buf.to_vec()))
59 }
60}
61
62#[cfg(test)]
63mod tests {
64 use super::*;
65 use ed25519_dalek::{Keypair, SecretKey, Signer};
66
67 #[test]
68 fn test_empty_input() -> Result<(), PrecompileFailure> {
69 let input: [u8; 0] = [];
70 let cost: u64 = 1;
71
72 match Ed25519Verify::execute(&input, cost) {
73 Ok((_, _)) => {
74 panic!("Test not expected to pass");
75 }
76 Err(e) => {
77 assert_eq!(
78 e,
79 PrecompileFailure::Error {
80 exit_status: ExitError::Other("input must contain 128 bytes".into())
81 }
82 );
83 Ok(())
84 }
85 }
86 }
87
88 #[test]
89 fn test_verify() -> Result<(), PrecompileFailure> {
90 let secret_key_bytes: [u8; ed25519_dalek::SECRET_KEY_LENGTH] = [
91 157, 097, 177, 157, 239, 253, 090, 096, 186, 132, 074, 244, 146, 236, 044, 196, 068,
92 073, 197, 105, 123, 050, 105, 025, 112, 059, 172, 003, 028, 174, 127, 096,
93 ];
94
95 let secret_key =
96 SecretKey::from_bytes(&secret_key_bytes).expect("Failed to generate secretkey");
97 let public_key = (&secret_key).into();
98
99 let keypair = Keypair {
100 secret: secret_key,
101 public: public_key,
102 };
103
104 let msg: &[u8] = b"abcdefghijklmnopqrstuvwxyz123456";
105 assert_eq!(msg.len(), 32);
106 let signature = keypair.sign(msg);
107
108 let mut input: Vec<u8> = Vec::with_capacity(128);
113 input.extend_from_slice(msg);
114 input.extend_from_slice(&public_key.to_bytes());
115 input.extend_from_slice(&signature.to_bytes());
116 assert_eq!(input.len(), 128);
117
118 let cost: u64 = 1;
119
120 match Ed25519Verify::execute(&input, cost) {
121 Ok((_, output)) => {
122 assert_eq!(output.len(), 4);
123 assert_eq!(output[0], 0u8);
124 assert_eq!(output[1], 0u8);
125 assert_eq!(output[2], 0u8);
126 assert_eq!(output[3], 0u8);
127 }
128 Err(e) => {
129 return Err(e);
130 }
131 };
132
133 let msg: &[u8] = b"BAD_MESSAGE_mnopqrstuvwxyz123456";
135
136 let mut input: Vec<u8> = Vec::with_capacity(128);
137 input.extend_from_slice(msg);
138 input.extend_from_slice(&public_key.to_bytes());
139 input.extend_from_slice(&signature.to_bytes());
140 assert_eq!(input.len(), 128);
141
142 match Ed25519Verify::execute(&input, cost) {
143 Ok((_, output)) => {
144 assert_eq!(output.len(), 4);
145 assert_eq!(output[0], 0u8);
146 assert_eq!(output[1], 0u8);
147 assert_eq!(output[2], 0u8);
148 assert_eq!(output[3], 1u8); }
150 Err(e) => {
151 return Err(e);
152 }
153 };
154
155 Ok(())
156 }
157}