-
Notifications
You must be signed in to change notification settings - Fork 313
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
Inconsistent Public Keys #173
Comments
The issue seems to be that the message is not keccak256 or sha3 hashed before signing. Instead, it's hex'd and byte padded with leading zeros. |
Are you fix this problem? |
I try the public key recovery in python where I got the code from https://replit.com/@nakov/ECDSA-public-key-recovery-in-Python#main.py Public key recovery: round2: Public key recovery: The two results have a same public key (0xe71cc44b7a738250fe80c40f1b64a95686a927d4400ca7d404a010c0e7366b40, 0xef39e52814806ebe53dafa767315f13c176e7c281350cc0800d64435e6671fc), |
@artrepreneur , reading your logs I can make an assumption that in each of the rounds you're running the command from within the same/single directory and just use different keystores. If you confirm this is the case, and if you still experience this problem -- let me know, and I would explain how to solve it :) I ran into this issue by myself, though it got manifested in a different way in my case. |
@alexshchur I'm running into the same issue now, would you be able to explain how to resolve this? |
So, I think the intent and the way the codebase is designed assumes that, given the initial After doing that, as explained in the doc, you probably want to run gg18 demo by launching You will end up with 3 similar folders, each having After that you would be able to launch commands like Let me know if that works |
@alexshchur Thanks for response! I just tried that and ended up with the same problems as @artrepreneur. In In The output for the above was:
Afterwards, I ran the above two commands in the same folders again, and the output I received was:
Which is a different signature (with a different public key) than the first signature, despite signing the same message. My goal is to sign a tx on ethereum that sends eth, but right now I'm stuck on even generating consistent eth addresses/signatures. Were you able to get consistent public keys when signing messages? If so, how? |
@alexreyes hm hm it sounds like you're doing everything right. It's weird that you don't receive consistent output. Check out this my playground codebase. I've recorded a video demonstrating the whole process of creating signatures and then consistently recovering the same public key: https://github.com/alexshchur/tss-experiments#video |
@alexreyes @alexshchur From my testing, A message can be generated with two different signatures twice, but the public key will be recovered the same. |
@alexshchur thanks for the video + sending your repo! That was super helpful and we were able to get it working. I really appreciate it! @KunPengRen Yup, that seems to be the case. Thanks for confirming! |
hey @alexshchur, thanks for the video. I tried out your script. I did the signing process and ended up with the signature. But when I tried to use ethers.utils.verifyMessage() it outputted a different address than ethers.utils.recoverAddress(). I also tried to verify the message on Etherscan (https://etherscan.io/verifiedSignatures) from ethers.utils.recoverAddress() but it fails. I generated the signature for the message on Etherscan using ethers.utils.joinSignature(). Do you have any thoughts on this? Maybe I'm messing up somewhere? Thanks! |
@neocho verifyMessage is a bit different. If you look under the hood of what it does with the supplied message arg, you'll find out that it prepends that ethereum prefix:
Essentially you end up dealing with a totally different message to recover against |
Ahh I see! Will check that out 💯 |
Hey @alexshchur, have you been able to verify a signature with the recovered address with a tool like this https://etherscan.io/verifiedSignatures? I've been trying to get it to work with recoveredAddress but no luck still. Thanks :) |
Hey @neocho , I suppose it's already solved for you? Saw the conversations in TG channel ;) Will repost Steph's response from there for others who might be curious
|
Hey! @alexshchur yea unfortunately I kept getting different addresses after signing. 🤣🤣 I think I'll do a fresh clone and go from there. |
Problem is solved for me too. Sigs are consistent. If using Web3.js use something like: let myMsgHashAndPrefix = web3.eth.accounts.hashMessage(<your_message_here>); Then combine R, s and recid to create a concatenated signature as say "sig", and recover the address with ethers.js like: sigAddress = ethers.utils.recoverAddress(myMsgHashAndPrefix, sig); |
@alexreyes @neocho @alexshchur can you explain what you did to get this working? I'm running into this same issue (same message, different signatures, different public keys) for ETH. If it makes a difference, I'm signing an EIP-1559 transaction type. For greater context, I using a 2-2 scheme that's based on the gotham-city repo (which uses multi-party-ecdsa). Each node is on its own process and storing its own data. I was able to get Bitcoin signing working no problem. The message I'm signing is a curv::BigInt that represents the keccak256 hash of the RLP-encoded transaction. Steps to produce this:
Any help would be appreciated. |
The problem of the example given in the readme is that: "68656c6c6f20776f726c64" is not a hash value with size = 32 byte. However, the signing protocol assumed that the signer input a hash value with size = 32. If the input size is < 32 byte, it will be padded. That's why the recovery of public key does not work properly when using ethers.util. |
will check soon |
When signing using gg18, if the same message is signed multiple times as in: it will result in a unique (r,s) pair each time.
Example, Round 1:
./gg18_sign_client http://127.0.0.1:8000 keys.store "68656c6c6f20776f726c64"
./gg18_sign_client http://127.0.0.1:8000 keys2.store "68656c6c6f20776f726c64"
R: Secp256k1Scalar { purpose: "from_bigint", fe: Zeroizing(Some(SK(SecretKey(9870cfd7bc3fa04b93976960579d316bb9d015d2abcbc1e204747d023f95f0c3)))) }
s: Secp256k1Scalar { purpose: "add", fe: Zeroizing(Some(SK(SecretKey(46f5dfd387beb601cac41fce7079a6564740986a0ac186624de44e4d3860cf0f)))) }
recid: 0
Round 2:
./gg18_sign_client http://127.0.0.1:8000 keys.store "68656c6c6f20776f726c64"
./gg18_sign_client http://127.0.0.1:8000 keys2.store "68656c6c6f20776f726c64"
R: Secp256k1Scalar { purpose: "from_bigint", fe: Zeroizing(Some(SK(SecretKey(82bfefea43e679127cf6932bcb06ecec281f1a7e5586727cc853346cacaaae0f)))) }
s: Secp256k1Scalar { purpose: "from_bigint", fe: Zeroizing(Some(SK(SecretKey(33ab25e2d97be2af94e1046a5b29a11c3a46d7b7093b1cc03333a20c81006dee)))) }
recid: 0
This results in different public keys as well. Also public keys do not match the public keys in keys.store. What explains this discrepancy?
The text was updated successfully, but these errors were encountered: