Skip to content

Commit

Permalink
Update the incoming method of signed messages
Browse files Browse the repository at this point in the history
  • Loading branch information
joii2020 committed Sep 20, 2023
1 parent 509d8c1 commit c7c9484
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 42 deletions.
38 changes: 18 additions & 20 deletions docs/ethereum.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ As `ethkey` is required, we compile all components for convenience. The compiled
## Address
First, you need to create a test account (you will need to set a password):
```shell
./geth account new
geth account new
```

Once created, look for this line in the output:
Expand All @@ -46,40 +46,38 @@ In Ethereum, the `Address` is a 20-byte fixed-length array. When used in program

## Signature

Ethereum's message is calculated using sha3: `Ethereum Signed Message:\n` + 'message' hash. While ckb-auth's message is a fixed length of 32 bytes, so here, we use a 32-character string for the message.
Ethereum's message is calculated using sha3: `Ethereum Signed Message:\n` + 'message' hash. While ckb-auth's message is a fixed length of 32 bytes, so here, `ethkey` supports the input of messages in both textual form and through a file (by using the `--msgfile` parameter). In this context, Ethereum's message is directly utilized as a data parameter hash, necessitating the use of the `--msgfile` to input a file.

You can generate a ckb-auth-compatible message using the following command:
You can use the command provided by `ckb-auth-cli` to convert the message to file:
```
message=0011223344556677889900112233445500112233445566778899001122334455
message_file=
ethereum generate -m $message --msgfile $message_file
```
(You need to set the path of `message_file` here)

After generating the message file, you can use `ethkey` to sign:
```shell
my_key_file=
message=00112233445566778899001122334455
./ethkey signmessage $my_key_file $message
ethkey signmessage --msgfile $message_file $my_key_file
```
output:
```
Signature: 2d87792d122d9187433bffee9723483cca9c8f848d14a9b772f247ff75637103448d825ff0366a1b6572f48b03ef28705feedeb009e9d95c190922435ae271f401
Signature: 5a62aa66a32a41fb44a58e7284ca964952da485dc0fcec24dadb7402d65274d8733f9a2c34274c573d09743d04f25fdfb00ffee8d821a1422c7d3f4e97ce97e100
```

After signing, you can verify it using geth to prevent any basic errors:
```shell
./ethkey verifymessage 0x027a5b3c90216149a42ceaa0431ac7179d0e663b 2d87792d122d9187433bffee9723483cca9c8f848d14a9b772f247ff75637103448d825ff0366a1b6572f48b03ef28705feedeb009e9d95c190922435ae271f401 $message
ethkey verifymessage --msgfile $message_file 0x027a5b3c90216149a42ceaa0431ac7179d0e663b 5a62aa66a32a41fb44a58e7284ca964952da485dc0fcec24dadb7402d65274d8733f9a2c34274c573d09743d04f25fdfb00ffee8d821a1422c7d3f4e97ce97e100
```

## Verify
* Here need to pay attention to the order of command parameters.

As mentioned earlier, ckb-auth uses a 32-byte message, while geth uses text. You can convert the message used by geth into ckb-auth's format using ckb-auth-cli.
## Verify

Since ckb-auth-cli has already processed the message, you can directly use the 32-character message used when signing with geth, or you can use the 64-character message generated using `ckb-auth-cli ethereum parse`. So, you can directly use geth's signature for verification:
This can now be verified in ckb-auth:

```shell
ckb-auth-cli ethereum parse -m 00112233445566778899001122334455
ckb-auth-cli ethereum verify -a 027a5b3c90216149a42ceaa0431ac7179d0e663b -s 5a62aa66a32a41fb44a58e7284ca964952da485dc0fcec24dadb7402d65274d8733f9a2c34274c573d09743d04f25fdfb00ffee8d821a1422c7d3f4e97ce97e100 -m 0011223344556677889900112233445500112233445566778899001122334455
```

output
```
3030313132323333343435353636373738383939303031313232333334343535
```

Here, we use ckb-auth to verify the signature from geth:
```shell
ckb-auth-cli ethereum verify -a 027a5b3c90216149a42ceaa0431ac7179d0e663b -s 2d87792d122d9187433bffee9723483cca9c8f848d14a9b772f247ff75637103448d825ff0366a1b6572f48b03ef28705feedeb009e9d95c190922435ae271f401 -m 3030313132323333343435353636373738383939303031313232333334343535
```
54 changes: 32 additions & 22 deletions tools/ckb-auth-cli/src/ethereum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ impl BlockChainArgs for EthereumLockArgs {
}

fn reg_parse_args(&self, cmd: Command) -> Command {
cmd.arg(arg!(-m --message <PUBKEYHASH> "The signature message"))
cmd
}
fn reg_generate_args(&self, cmd: Command) -> Command {
cmd
cmd.arg(arg!(-m --message <MESSAGE> "Generate message binary for ethereum signing"))
.arg(arg!(--msgfile <MESSAGE_FILE> "Output file"))
}
fn reg_verify_args(&self, cmd: Command) -> Command {
cmd.arg(arg!(-a --address <PUBKEYHASH> "The ethereum address"))
Expand All @@ -31,19 +32,33 @@ impl BlockChainArgs for EthereumLockArgs {
pub struct BitcoinLock {}

impl BlockChain for BitcoinLock {
fn parse(&self, operate_mathches: &ArgMatches) -> Result<(), Error> {
let message = operate_mathches
.get_one::<String>("message")
.expect("Get signature message");
fn parse(&self, _operate_mathches: &ArgMatches) -> Result<(), Error> {
Err(anyhow!("ethereum does not generate"))
}

fn generate(&self, operate_mathches: &ArgMatches) -> Result<(), Error> {
let message = decode(
operate_mathches
.get_one::<String>("message")
.expect("Get signature message"),
)
.expect("Decode message");
if message.len() != 32 {
return Err(anyhow!("Signature length must be 32"));
}
println!("{}", hex::encode(message.as_bytes()));
Ok(())
}

fn generate(&self, _operate_mathches: &ArgMatches) -> Result<(), Error> {
Err(anyhow!("ethereum does not generate"))
let msgfile = operate_mathches
.get_one::<String>("msgfile")
.expect("Get signature message output file");

let msgfile = std::path::PathBuf::from(msgfile);
// if msgfile.exists() && msgfile.is_file() {
// std::fs::remove_file(&msgfile);
// }

std::fs::write(msgfile, message).expect("write message file");

Ok(())
}

fn verify(&self, operate_mathches: &ArgMatches) -> Result<(), Error> {
Expand All @@ -63,17 +78,12 @@ impl BlockChain for BitcoinLock {
)
.expect("decode ethereum signature");

let message = operate_mathches
.get_one::<String>("message")
.expect("Get message from args");

let message = if message.len() == 32 {
message.as_bytes().to_vec()
} else if message.len() == 64 {
decode(message).expect("Decode ethereum message")
} else {
return Err(anyhow!("ethereum message size is not 32"));
};
let message = decode(
operate_mathches
.get_one::<String>("message")
.expect("Get message from args"),
)
.expect("decode ethereum message");

if address.len() != 20 {
return Err(anyhow!("ethereum address invalidate"));
Expand Down

0 comments on commit c7c9484

Please sign in to comment.