ripple / ripple-keypairs

Moved to: https://github.com/XRPLF/xrpl.js/tree/develop/packages/ripple-keypairs
https://github.com/XRPLF/xrpl.js/tree/develop/packages/ripple-keypairs
ISC License
67 stars 49 forks source link

Always same signature and same random k #18

Closed hanwencheng closed 8 years ago

hanwencheng commented 8 years ago

Hi, I use the library to sign the same message with same seed, it always get the same signature, I check the code, every time it create the same K, as I understand for the ECDSA, the k should be variant, right?

sublimator commented 8 years ago

https://tools.ietf.org/html/rfc6979

hanwencheng commented 8 years ago

Hi, Sublimator,

Thanks, I am glad that you answered the question. In RFC6979 it says Produced signatures remain fully compatible with plain DSA and ECDSA. Entities that verify the signatures need not be changed or even be aware of the process used to generate k.

But with the repository ripple-lib-java as java signer, ripple-keypair as js verifier, seems that it does not work, ripple-lib-java produced the same hash, public key, but different signature. Furthermore this signature is unfortunately UNCOMPATIBLE with ripple-keypairs's verify function.

In signer side:

    Security.addProvider(new BouncyCastleProvider());
    String messageString = "hello,world";

    //get private key
    String passPhrase = "sp5fghtJtpUorTwvof1NpDXAzNwf5";
    IKeyPair keyPair = Seed.getKeyPair(passPhrase);
    String privateKey = Utils.bigToHex(keyPair.priv());
    String newPriv =  "00" + privateKey;

    //get hash
    MessageDigest md = MessageDigest.getInstance("SHA-256");
    byte[] digest = md.digest(messageString.getBytes());

    //get signature
    assert keyPair.priv().compareTo(new BigInteger(newPriv, 16)) == 0;
    byte[] signature = KeyPair.sign(digest , new BigInteger(newPriv, 16));

    //transmit hex parameters
    String messageHex = Utils.bytesToHex(digest);
    String signatureHex = Utils.bytesToHex(signature);
    String publicKeyHex = Utils.bigToHex(keyPair.pub());

In verifier side

    var keypairs = require('ripple-keypairs')
    var isCorrect = keypairs.verify(messageHex, signatureHex, publicKeyHex) //which is always false
clark800 commented 8 years ago

They should be compatible. I see that your first parameter to verify is hashHex whereas the documentation says messageHex. Is that the issue?

hanwencheng commented 8 years ago

Hi, Clark,

Thanks! That is my typo, the result is still false yet.

I update the code snippet with the real use case, hope that make sense.

Hanwen

hanwencheng commented 8 years ago

A further Js test case could be seen here

    //====further test case====
    var wallet =  { address: 'rU6K7V3Po4snVhBBaU29sesqs2qTQJWDw1',
        secret: 'sp5fghtJtpUorTwvof1NpDXAzNwf5' }
    //hash
    var message = "hello, world";
    var hash = sjcl.hash.sha256.hash(message);
    var hashHexJS = sjcl.codec.hex.fromBits(hash)
    //publicKey
    var keypair = keypairs.deriveKeypair(wallet.secret);
    var publicKeyJS = keypair.publicKey;
    //signature
    var signatureJS = keypairs.sign(hashHexJS, keypair.privateKey )

    var publicKey =   "030D58EB48B4420B1F7B9DF55087E0E29FEF0E8468F9A6825B01CA2C361042D435" //derive from java code
    var hashHex = "09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b" //derive from java code
    var signature = "3045022100e5a0063e360be13a5f5c568ffe5137c5d0abe893075112d14ffc0db566eded5c0220045e5443938fee9af97c4a23aed4055a824d3b844c0a540ea716a758b0cf143f" //derive from java code

    console.log('derived pubicKey is same', publicKey === publicKeyJS)//true!
    console.log('derived hash is same', hashHex === hashHexJS)//true!
    console.log('derived signature is same', signature === signatureJS)//false!

    //check if the request is from the certain user
    var isTrue = keypairs.verify(hashHex, signature, publicKey)//false!
    var isTrueJS = keypairs.verify(hashHexJS, signatureJS, publicKeyJS)//true!
clark800 commented 8 years ago

You are still signing the hash instead of signing the message. The sign and verify functions already hash the message internally, so you are double hashing: https://github.com/ripple/ripple-keypairs/blob/master/src/index.js#L37

I don't know how you are generating the ripple-lib-java signature, but if you are signing the message then that would explain the difference.

hanwencheng commented 8 years ago

Thanks! That's exactly where the problem is!

The ripple-lib-java does not implement the hash for the massage, whereas ripple-keypair use hash-512 as default!

sublimator commented 8 years ago

@hanwencheng

I have a branch of ripple-lib-java with ed25519 support which has yet to be merged to master, which takes care of the hashing itself, with the sign/verify api methods taking the full message rather than a digest.

What do you use ripple-lib-java for?

hanwencheng commented 8 years ago

@sublimator Which branch? I am building another java client app to connect REST API , so I use ripple-lib-java to do the public key generation and ECDSA signature.

sublimator commented 8 years ago

Oh, FYI, I believe the public REST server is due to be decommissioned soon, if you aren't already using a local node (which I guess you aren't ... given that you are using java for signing)

I believe there is an early iteration branch pushed, but I vaguely recall it had a bug that I missed, so hold off. I will try and push the code in the coming days.

hanwencheng commented 8 years ago

Thanks for your information! One question, after closing REST server, how could we build and use our own applications?

sublimator commented 8 years ago

The rest source will remain available so if push comes to shove, there is always that.

I'm not sure what the plan is for official support of non JavaScript languages.

@clark800 ?

Will there be a locally installable node server that exposes RippleAPI for non JS projects?

sublimator commented 8 years ago

Or a public service etc ?

clark800 commented 8 years ago

There is a pull request for an experimental JSON-RPC HTTP interface for RippleAPI: https://github.com/ripple/ripple-lib/pull/663