`web3/schnorrkel` failed to verify `ext_sr_sign` generated signatures
See original GitHub issueDescription
Hello! I’m trying to use the repository https://github.com/w3f/schnorrkel
, more specifically the function verify_simple to verify signatures generated by polkadot-js using thesignRaw
function and unforunately it’s not working. However the function signatureVerify
from @polkadot/util-crypto
verify correctly the same signature.
Steps to reproduce
- I’ve used the polkadot extension and the polkadot-js to generate the signature
output at console.log
Public Key (hex) 0xf84d048da2ddae2d9d8fd6763f469566e8817a26114f39408de15547f6d47805
Message => message to sign
Signature (hex) 0x48ce2c90e08651adfc8ecef84e916f6d1bb51ebebd16150ee12df247841a5437951ea0f9d632ca165e6ab391532e75e701be6a1caa88c8a6bcca3511f55b4183
- With the
https://github.com/w3f/schnorrkel
cloned at my machine I created the following test case (which fails) atsrc/sign.rs
file:
#[test]
fn verify_polkadot_js_signature() {
use hex_literal::hex;
const CTX : &'static [u8] = b"substrate";
let message = b"message to sign";
let public = hex!("f84d048da2ddae2d9d8fd6763f469566e8817a26114f39408de15547f6d47805");
let public = PublicKey::from_bytes(&public[..]).unwrap();
let signature = hex!("48ce2c90e08651adfc8ecef84e916f6d1bb51ebebd16150ee12df247841a5437951ea0f9d632ca165e6ab391532e75e701be6a1caa88c8a6bcca3511f55b4183");
let signature = Signature::from_bytes(&signature).unwrap();
let ok = public.verify_simple(CTX, message, &signature).is_ok();
assert!(ok)
}
Debugging the polkadot-js signatureVerify
function I noticed that this function calls the rust function ext_sr_verify
under the hoods by a WASM biding (very interestingly 😄 ) and the rust function uses the same w3f/schnorrkel
repository, then I assumed the function ext_sr_sign
is used to generate the signature so I decided to create the following test case that uses these 2 functions to generate and verify a signature:
#[test]
fn sign_and_verify() {
const CTX : &'static [u8] = b"substrate";
let sec = SecretKey::generate();
let pub_bytes = sec.to_public().to_bytes();
// ext_sr_sign function
let sig = match (SecretKey::from_ed25519_bytes(&sec.to_bytes()), PublicKey::from_bytes(&pub_bytes)) {
(Ok(s), Ok(k)) => s
.sign_simple(CTX, message, &k)
.to_bytes()
.to_vec(),
_ => panic!("Invalid secret or pubkey provided.")
};
// ext_sr_verify function
let res = match (Signature::from_bytes(&sig), PublicKey::from_bytes(&pub_bytes)) {
(Ok(s), Ok(k)) => k
.verify_simple(CTX, message, &s)
.is_ok(),
_ => false
};
assert!(res)
}
And unfortunately, this test case fails. The same thing happens with the https://github.com/ChainSafe/go-schnorrkel
package, the original issue was reported into Gossamer discord channel.
Thanks in advance!
Issue Analytics
- State:
- Created 2 years ago
- Comments:6 (2 by maintainers)
Here is your test data adapted to use the signature supplied by the extension -
https://github.com/polkadot-js/wasm/pull/257/files#diff-adf4dccb86867d4d556199a23c9457df917d84c5dc1d9a9f12dc3a5f31ea4289R251-R259
It is your first test above (same public, same signature), the only change is to adapt the message to
b"<Bytes>message to sign</Bytes>"
since thesignRaw
adds that exact wrapping - and obviously, since it is added in this repo, it adapts the wasm-interface-isms exposed, aka theext_sr_verify
handles the signature & public conversions.It passes -
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue if you think you have a related problem or query.