Expand description

Key Derivation and Signing Functions

This crate provides a set of functions for key derivation and signing of Ethereum transactions and messages. It uses the HKDF (HMAC-based Key Derivation Function) with SHA-512 as the base key derivation algorithm and SHA-256 for expanding keys.

Functions

  • get_derived_key: Computes a derived key of length SHA256_OUTPUT_LEN bytes using HKDF-SHA512.
  • get_wallet_address: Computes the Ethereum address associated with a derived key.
  • sign_transaction: Signs an Ethereum transaction using a derived key and returns the generated signature.
  • sign_message: Signs an Ethereum message using a derived key and returns the generated signature.
  • sign_typed_data: Sign EIP-712 typed data using a derived key and returns the generated signature.
  • get_signer: Returns a signer wallet from a derived key with an chain ID.

Example

#[tokio::main]
async fn main() {
    use ethers_signer_factory::{get_derived_key, get_wallet_address, sign_transaction, sign_message, sign_typed_data, get_signer};
    use ethers_contract_derive::{Eip712, EthAbiType};
    use ethers_core::types::transaction::eip2718::TypedTransaction;
    use ethers_core::types::{TransactionRequest, Address};
    
    let key: [u8; 64] = [0u8; 64];
    let salt: [u8; 64] = [0u8; 64];
    let info = "some_key_id";
    
    // Example 1: Derive a key.
    let derived_key = get_derived_key(&key, &salt, info).expect("Key derivation failed");
    assert_eq!(
        hex::encode(derived_key).as_str(),
        "de61002dc1676e6b59b2dd27da3f32280defe3bc384f77de6eee372f70ceaae7"
    );
    
    // Example 2: Get an Ethereum address from the derived key.
    let wallet_address: Address = get_wallet_address(&key, &salt, info).expect("Wallet creation failed");
    assert_eq!(
        hex::encode(wallet_address.as_bytes()).as_str(),
        "ea4d3e00f3d283cdb0e4d4fb783f208a5095fcb7"
    );
    
    // Example 3. Get a Signer Wallet from the derived key.
    let chain_id = 1;
    let _wallet = get_signer(&key, &salt, info, chain_id).expect("Signer creation failed");
    
    // Example 4: Sign a transaction.
    let tx = TypedTransaction::Legacy(TransactionRequest::default().from(wallet_address));
    let signed_tx =
        sign_transaction(&key, &salt, info, &tx).expect("Transaction signing failed");
    
    assert_eq!(
        hex::encode(signed_tx.to_vec().as_slice()).as_str(),
        "815dd9b736c52fed571b2d5d985c52d78593a6d4a602f8455e884371270760132c8cd1f163af8303dc83aaaf48d2a03bff3697f6c922951809c19c0593841b3426"
    );
    
    // Example 5: Sign a message.
    let message = "Some message to sign";
    let signature = sign_message(&key, &salt, info, message).expect("Message signing failed");
    
    assert_eq!(
        hex::encode(signature.to_vec().as_slice()).as_str(),
        "35867e62e5a2c4dd52947c0cbb4af6afc95564d5abb0584bec2f9669046f81aa0d22dba8e6844fb125b93fec9a3e3684916dc4541e45bdc824cf18b5ab2409c81c"
    );
    
    // Example 6: Sign Typed data.
    #[derive(Clone, Default, EthAbiType, Eip712)]
    struct TestTypedData {
        value: u32,
    }
    
    let test_payload = TestTypedData { value: 1 };
    let signature = sign_typed_data(&key, &salt, info, &test_payload)
        .await
        .expect("Sign typed data failed");
    
    assert_eq!(
        hex::encode(signature.to_vec().as_slice()).as_str(),
        "cdd86e133a50b7d2c4f5bff092dbfe4086ed559bb0718e9c1c9bce31171f0ff44df3cc0dcd20388ad99be26b6eca0c104bff48eb6ad8135bec9d76aee2c6930f1b"
    );
}

Dependencies

This crate depends on the following external libraries:

  • ethers_core: Ethereum core library for types and utilities.
  • ethers_signers: Ethereum wallet and signing functionality.
  • ring: Cryptographic library for key derivation.
  • hex: Hex strings encoding and decoding library.

Error Handling

Functions in this crate return a Result type that can contain errors specific to key derivation and signing. Refer to the individual function documentation for details on error types and how to handle them.

Modules

Functions

  • Derives a cryptographic key of length 32 bytes using the HKDF-SHA512 key derivation function. The input key and salt must both be 64 bytes each.
  • Gets a signer wallet from a derived key with an optional chain ID.
  • Derives a wallet address from the given input key material, salt, and info string.
  • Signs a message using a derived key, salt, and info string.
  • Signs a TypedTransaction using a derived key, salt, and info string.
  • Signs typed data using a derived key and returns the generated signature.