88
99use anyhow:: { Context , Result } ;
1010use clap:: Parser ;
11- use secp256k1:: { rand, Keypair , PublicKey , Secp256k1 , SecretKey } ;
11+ use secp256k1:: { rand, PublicKey , Secp256k1 , SecretKey } ;
12+ use sha3:: { Digest , Keccak256 } ;
1213use std:: { ffi:: OsString , os:: unix:: process:: CommandExt , process:: Command } ;
1314use teepot:: quote:: get_quote;
1415use tracing:: error;
@@ -28,6 +29,19 @@ struct Args {
2829 cmd_args : Vec < OsString > ,
2930}
3031
32+ /// Converts a public key into an Ethereum address by hashing the encoded public key with Keccak256.
33+ pub fn public_key_to_address ( public : & PublicKey ) -> [ u8 ; 20 ] {
34+ let public_key_bytes = public. serialize_uncompressed ( ) ;
35+
36+ // Skip the first byte (0x04) which indicates uncompressed key
37+ let hash: [ u8 ; 32 ] = Keccak256 :: digest ( & public_key_bytes[ 1 ..] ) . into ( ) ;
38+
39+ // Take the last 20 bytes of the hash to get the Ethereum address
40+ let mut address = [ 0u8 ; 20 ] ;
41+ address. copy_from_slice ( & hash[ 12 ..] ) ;
42+ address
43+ }
44+
3145fn main_with_error ( ) -> Result < ( ) > {
3246 LogTracer :: init ( ) . context ( "Failed to set logger" ) ?;
3347
@@ -37,14 +51,11 @@ fn main_with_error() -> Result<()> {
3751 tracing:: subscriber:: set_global_default ( subscriber) . context ( "Failed to set logger" ) ?;
3852
3953 let args = Args :: parse ( ) ;
40-
4154 let mut rng = rand:: thread_rng ( ) ;
4255 let secp = Secp256k1 :: new ( ) ;
43- let keypair = Keypair :: new ( & secp, & mut rng) ;
44- let signing_key = SecretKey :: from_keypair ( & keypair) ;
45- let verifying_key = PublicKey :: from_keypair ( & keypair) ;
46- let verifying_key_bytes = verifying_key. serialize ( ) ;
47- let tee_type = match get_quote ( verifying_key_bytes. as_ref ( ) ) {
56+ let ( signing_key, verifying_key) = secp. generate_keypair ( & mut rng) ;
57+ let ethereum_address = public_key_to_address ( & verifying_key) ;
58+ let tee_type = match get_quote ( ethereum_address. as_ref ( ) ) {
4859 Ok ( ( tee_type, quote) ) => {
4960 // save quote to file
5061 std:: fs:: write ( TEE_QUOTE_FILE , quote) ?;
@@ -85,3 +96,22 @@ fn main() -> Result<()> {
8596 }
8697 ret
8798}
99+
100+ #[ cfg( test) ]
101+ mod tests {
102+ use super :: * ;
103+
104+ #[ test]
105+ fn test_public_key_to_address ( ) {
106+ let secp = Secp256k1 :: new ( ) ;
107+ let secret_key_bytes =
108+ hex:: decode ( "c87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3" )
109+ . unwrap ( ) ;
110+ let secret_key = SecretKey :: from_slice ( & secret_key_bytes) . unwrap ( ) ;
111+ let public_key = PublicKey :: from_secret_key ( & secp, & secret_key) ;
112+ let expected_address = hex:: decode ( "627306090abaB3A6e1400e9345bC60c78a8BEf57" ) . unwrap ( ) ;
113+ let address = public_key_to_address ( & public_key) ;
114+
115+ assert_eq ! ( address, expected_address. as_slice( ) ) ;
116+ }
117+ }
0 commit comments