Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is there any instructions or examples for verifying the signature (for gg20)? #189

Closed
hcheng826 opened this issue Nov 29, 2022 · 9 comments

Comments

@hcheng826
Copy link

Thanks for the great repository! I have walked through the example for GG20 keygen and signing. I can successfully generate the signature but I don't actually know how to extract the public key and actually verify the generated signature.

Is there any instructions or examples that I can refer to? Thanks!

@ataki
Copy link

ataki commented Nov 30, 2022

See #177 and in particular the comments after #177 (comment)

@hcheng826
Copy link
Author

thanks for the reply! will check that out!

@hcheng826
Copy link
Author

Unfortunately I didn't really get my question solved in that discussion 😢

But I tried another thing -

  1. Use the same shares to create 2 signatures from 2 different messages
  2. Recover the public keys from the message hashes and signatures
  3. And found that the recovered public keys are different

Is it a valid test? Or actually I am signing with different public key each time?

Here's my implementation in Javascript for reference: https://gist.github.com/hcheng826/2c3a4b98490a81052d8a4a1f8d4aad7f

output

recovered public key from signature 1: 
042583d64550be7b1121983675ff4c4bec6e539b63f80a6f10228f350edebcbe94db85af7728587fbe7fc8b956d2a22724f3ba4389faf40dd2e23e8adb80d72bd0
recovered public key from signature 2: 
049422bf5d394b8a5588caa4920c8c05d7a27a863e3ede8f87e8e65e97a4ef7cbec2f23ee87c0d7cad8e2ec1c6130145a9d9dc20a310e9e6709b4e4515a03e9e70

@ataki
Copy link

ataki commented Dec 7, 2022

Is it a valid test?

Yes.

Or actually I am signing with different public key each time?

No. As long as you use the same private keys, you sign with the same public key.

And found that the recovered public keys are different

How are you recovering the public keys? Check the recovery id, that's a common source of issues.

@hcheng826
Copy link
Author

@ataki Thanks for the reply!

The recovery id I used is the id from the output of the signature. Is that the correct value to use?
Screenshot 2022-12-08 at 10 27 34 AM

To my knowledge the recid could be either 0 or 1, I tried with both values but still got different public keys 🤔
You mentioned that you had the same issue earlier, is there any code snippet that you can share? Appreciate it!

@peng-huang-ch
Copy link

Try to print the signature as a hex string

let r = BigInt::from_bytes(sig.r.to_bytes().as_ref()).to_str_radix(16);
let s = BigInt::from_bytes(sig.s.to_bytes().as_ref()).to_str_radix(16);
let v = sig.recid;
let signature = format!("{:0>width$}{:0>width$}{:02x}", r, s, v, width = 64);

For Js could use the elliptic or ethers.js to verify it. Hopt it could help you
For Rust could use the check_sig

@hcheng826
Copy link
Author

Thanks for your reply! But I still cannot work it out 😥

I had another try, though. When I am tracing the code I found this: https://github.com/ZenGo-X/multi-party-ecdsa/blob/master/src/protocols/multi_party_ecdsa/gg_2020/state_machine/keygen/rounds.rs#L324-L329

I guess that points out that y_sum_s in the local_share.json file is the joint public_key for this signature. Unfortunately when I tried to verify the signature with this public key, it still fails 😥

This is how I process y_sum_s and the signature coming from the ./gg20_signing command
https://gist.github.com/hcheng826/c494f639a7646f1758e0b6fab8c6d3d3

image

@peng-huang-ch
Copy link

@hcheng826

replace

const msg = "hello";
const result = pk.verify(Buffer.from(sha3.keccak256(msg), "hex"), sig);

to

const msg = "68656c6c6f";
const result = pk.verify(Buffer.from(msg, "hex"), sig);

you need to get the actual message to be signed. data_to_sign changed

 let data_to_sign = "hello";
 let message = BigInt::from_bytes(data_to_sign.as_bytes());
 println!("message: {}", message.to_hex());
 
 => 68656c6c6f

@hcheng826
Copy link
Author

hcheng826 commented Dec 8, 2022

@peng-huang-ch Thank you so much! It works!!!!

Append the conversion in js for others' reference

const msg = "hello";
const msgHex = Buffer.from(msg).toString("hex");
const result = pk.verify(Buffer.from(msgHex, "hex"), sig);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants