bobcat_precompiles/
lib.rs

1#![no_std]
2
3use bobcat_maths::U;
4
5use bobcat_call::static_call_slice;
6
7use array_concat::concat_arrays;
8
9type Address = [u8; 20];
10
11pub const ADDR_ECRECOVER: Address = U::ONE.const_addr();
12
13// Upper bound of S to prevent malleability.
14#[allow(unused)]
15const ECRECOVER_MAX_S: U =
16    U::const_from_hex(b"7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0").unwrap();
17
18pub fn ecrecover(hash: U, v: u8, r: U, s: U, gas: u64) -> Option<Address> {
19    if v != 27 && v != 28 {
20        return None;
21    }
22    if s > ECRECOVER_MAX_S {
23        return None;
24    }
25    let cd: [u8; 32 * 4] = concat_arrays!(hash.0, U::from(v).0, r.0, s.0);
26    let (rc, _, rd) = static_call_slice::<20>(ADDR_ECRECOVER, &cd, gas, 32 - 20);
27    if !rc {
28        return None;
29    }
30    Some(rd)
31}