Skip to content

failed to verify signatures generated by polkadot-js #77

@EclesioMeloJunior

Description

@EclesioMeloJunior

Description

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

  1. I've used the polkadot extension and the polkadot-js to generate the signature
scren-record.mov
output at console.log 

Public Key (hex) 0xf84d048da2ddae2d9d8fd6763f469566e8817a26114f39408de15547f6d47805
Message => message to sign
Signature (hex) 0x48ce2c90e08651adfc8ecef84e916f6d1bb51ebebd16150ee12df247841a5437951ea0f9d632ca165e6ab391532e75e701be6a1caa88c8a6bcca3511f55b4183
  1. With the https://github.com/w3f/schnorrkel cloned at my machine I created the following test case (which fails) at src/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!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions