Getting Address using ec recovery from PublicKey in fuel-rs / fuel-crypto

Within the examples, ec recovery is shown in the predicate example and it is fairly easy to create a script that invokes ec_recover_address() in erc.sw

in erc.sw

ec_recover_address(signature: B512, msg_hash: b256) -> Result<Address, EcRecoverError>

however when attempting to reproduce the address from ec recovery in the fuel-rs or fuel-crypto, it does not seem obvious about how to go from a uncompressed PublicKey to an Address.

For example:
A common public/private key pair from starting up fuel-core is:

PrivateKey(0xde97d8624a438121b86a1956544bd72ed68cd69f2c99555b08b1e8c51ffd511c), Address(0x6b63804cfbf9856e68e5b6e7aef238dc8311ec55bec04df774003a2c96e0418e), Balance(10000000)

signing some data data_to_sign: [u8; 32] = [0; 32]; with the above PrivateKey and using ec_recover_address() in a Sway script produces the address:

9cc4223eb3a1396ec9832312bc4220c28d3366dcd2177b6a1298f12e71fdb5cc

Attempting to reproduce this result using fuel-rs / fuel-crypto by taking this private key, and running it through the signature function similar to fuel-crypto example on L14

let secret_key1: SecretKey =
        "0xde97d8624a438121b86a1956544bd72ed68cd69f2c99555b08b1e8c51ffd511c"
            .parse()
            .unwrap();
    let data_to_sign: [u8; 32] = [0; 32];
    let message = Message::new(data_to_sign);

    let signature = Signature::sign(&secret_key1, &message);
    let recover = signature.recover(&message).expect("Failed to recover PK");

    println!("recover_PK = {:?}", recover);

    let pk_hash = recover.hash();
    println!("pk_hash = {:?}", pk_hash);

produces:

recover_PK = 64f826e6f26c7dacdc48ee8d891f55f1a76900c55a525f369c3fc635a32176dc325d20f1d396732aadf8b41fc233ec40e4524ef3d3d39a7566dc878b785a3ef2

pk_hash = 6b63804cfbf9856e68e5b6e7aef238dc8311ec55bec04df774003a2c96e0418e

with recover_PK which is of PublicKey type. How do we get an Address from this (uncompressed?) PublicKey ?

Ok ill updte this slightly. Im not looking for an address type, its actually the sha256 hash of the public_key (64 bytes) that ec_recover_address in sway and signature.recover(&message) in fuel-rs

The above two hashs of the publickeys, one produced from ec_recover in sway, and one within the fuel-rs SDK, give different results for the public key recovered from the same message signed with the same secret key (32 bytes), which in results in different hashs.

so why is the pk recovered from either, different?

Hi there @Antony
I’m taking this into the SDK team!

I’ll let you know once I have a answer, thank you so much!

Ended up figuring out what the issue was after going through the source of the ECR opcode and secp256k1 lib. Turns out i was sending in the message and not the hash of the message :man_facepalming:

1 Like