pub fn ecrecover(hash: [u8; 32], sig: &Vec<u8>) -> Result<Vec<u8>, secp256k1::Error> {
    let sig_start = min(R_OFFSET, sig.len());
    let sig_end = min(S_OFFSET + S_LENGTH, sig.len());
    let mut rs = [0u8; 64];
    for (i, val) in (&sig[sig_start..sig_end]).iter().enumerate() {
        rs[i] = *val;
    }

    // v should be 0 or 1 but is passed in as 27 or 28.
    let v = if sig.len() > V_OFFSET + V_LENGTH - 1 {
        (sig[V_OFFSET + V_LENGTH - 1] as i8 - 27) as u8
    } else {
        (0) as u8
    };
    if v != 0 && v != 1 {
        return Ok(vec![0u8; 0]);
    }

    let message = Message::parse(&hash);
    let rec_id = RecoveryId::parse(v)?;
    let sig = Signature::parse(&rs);

    let key = recover(&message, &sig, &rec_id)?;
    let ret = key.serialize();
    let ret = keccak(&ret[1..65]);
    let mut output = vec![0u8; 12];
    output.extend_from_slice(&ret[12..32]);
    Ok(output)
}
// Modified from parity's Ethereum precompiles code. Recovers the secp256k1
// public key used to generate the signature of the hash.
Modified from parity's Ethereum precompiles code. Recovers the secp256k1
public key used to generate the signature of the hash.
Modified from parity ' s Ethereum precompiles code . Recovers the secp256k1 public key used to generate the signature of the hash .
pub fn ecrecover(hash: [u8; 32], sig: &Vec<u8>) -> Result<Vec<u8>, secp256k1::Error> {
    let sig_start = min(R_OFFSET, sig.len());
    let sig_end = min(S_OFFSET + S_LENGTH, sig.len());
    let mut rs = [0u8; 64];
    for (i, val) in (&sig[sig_start..sig_end]).iter().enumerate() {
        rs[i] = *val;
    }
    // v should be 0 or 1 but is passed in as 27 or 28.
    let v = if sig.len() > V_OFFSET + V_LENGTH - 1 {
        (sig[V_OFFSET + V_LENGTH - 1] as i8 - 27) as u8
    } else {
        (0) as u8
    };
    if v != 0 && v != 1 {
        return Ok(vec![0u8; 0]);
    }
    let message = Message::parse(&hash);
    let rec_id = RecoveryId::parse(v)?;
    let sig = Signature::parse(&rs);
    let key = recover(&message, &sig, &rec_id)?;
    let ret = key.serialize();
    let ret = keccak(&ret[1..65]);
    let mut output = vec![0u8; 12];
    output.extend_from_slice(&ret[12..32]);
    Ok(output)
}
pub fn ecrecover ( hash : [ u8 ; 32 ] , sig : & Vec < u8 > ) -> Result < Vec < u8 > , secp256k1 :: Error > { let sig_start = min ( R_OFFSET , sig . len ( ) ) ; let sig_end = min ( S_OFFSET + S_LENGTH , sig . len ( ) ) ; let mut rs = [ 0u8 ; 64 ] ; for ( i , val ) in ( & sig [ sig_start .. sig_end ] ) . iter ( ) . enumerate ( ) { rs [ i ] = * val ; } // v should be 0 or 1 but is passed in as 27 or 28. let v = if sig . len ( ) > V_OFFSET + V_LENGTH - 1 { ( sig [ V_OFFSET + V_LENGTH - 1 ] as i8 - 27 ) as u8 } else { ( 0 ) as u8 } ; if v != 0 && v != 1 { return Ok ( vec ! [ 0u8 0 ] ) ; } let message = Message :: parse ( & hash ) ; let rec_id = RecoveryId :: parse ( v ) ? ; let sig = Signature :: parse ( & rs ) ; let key = recover ( & message , & sig , & rec_id ) ? ; let ret = key . serialize ( ) ; let ret = keccak ( & ret [ 1 .. 65 ] ) ; let mut output = vec ! [ 0u8 12 ] ; output . extend_from_slice ( & ret [ 12 .. 32 ] ) ; Ok ( output ) }
Modified from parity's Ethereum precompiles code.
Modified from parity ' s Ethereum precompiles code .
hash
[u8; 32]
sig
&Vec<u8>
hash
[u8; 32]
sig
&Vec<u8>