tonyg/js-nacl

pk from sk

Opened this issue · 9 comments

tonyg!

Your lib is so awesome! I was working away immediately after you gave those two new functions. Thank you so much!

For my implementation, a signing key needs to be known, and the public key needs to be created from that.

Is that what nacl.crypto_box_keypair_from_raw_sk does? If not, could I trouble you for another feature request, that the pk can be returned from the sk?

Thank you so much in advance and for this amazing library!

My test:

I tried with crypto_box_keypair_from_raw_sk, and it does look like the boxSk is the same as the input.

However, I'm getting a different pk than the other libraries I use, java and c. I'm using base64 encoding for length compression and UTF-8 compatibility. Here's my code:

var nacl = nacl_factory.instantiate() var k = nacl.crypto_box_keypair_from_raw_sk( base64DecToArr("d3ZVW+MgIBFiqdmtItkzF28Kf8/pDjAJxmRAQars2jU=") ); console.log( btoa( String.fromCharCode.apply(null, k.boxSk ) ).replace('=','') ) console.log( "sign" ) console.log( btoa( String.fromCharCode.apply(null, k.boxPk ) ).replace('=','') ) console.log( "public" )

The base64 function can be found here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Base64_encoding_and_decoding#Appendix.3A_Decode_a_Base64_string_to_Uint8Array_or_ArrayBuffer

The expected results are

d3ZVW+MgIBFiqdmtItkzF28Kf8/pDjAJxmRAQars2jU
sign
KdWlctDSibSHdnAtyk1dlHN4XhK7mqeciTL1ExBp6mw
public

The actual results are

d3ZVW+MgIBFiqdmtItkzF28Kf8/pDjAJxmRAQars2jU
sign
2R1rr72nXZeNxUGu7DULARY9XyUDmurN5K6yN4L8whQ
public

Again, I can't thank you enough for this library!

Try crypto_sign_keypair_from_seed.

Note that a box keypair is totally different from a signing keypair! Never use a box keypair for signing or a signing keypair for boxing.

What specific routines in which java and C libraries are you expecting the pk-derivation function to be compatible with here?

Interesting! I plead noobness to the box keypair. ;))

I played with a Java implementation, but it's too slow at present form: https://github.com/k3d3/ed25519-java static byte[] publickey(byte[] sk)

I'm currently using ed25519-donna for my application. https://github.com/floodyberry/ed25519-donna ed25519_publickey(sk, pk);

They both output the same keys.

As an aside, does your implementation automatically hash the message before signing? I, most probably improperly using the libraries, couldn't get donna to verify a signature made with your lib. Everything seemed to check out: keys, signatures, messages all equal.

js-nacl is a thin wrapper over http://nacl.cr.yp.to/. js-nacl's crypto_sign() delegates more-or-less directly to nacl's underlying C-language crypto_sign(). The only thing it does otherwise is take care of the C-language interface's padding requirements. So no, I'm not adding a hashing step; but, the underlying C library might be hashing things in a way you have to manually duplicate using ed25519-donna. I don't know either way for sure.

I suggest using https://github.com/tonyg/js-nacl/blob/master/nacl-20110221%2BEd25519-20130419.tar.bz2 from C, since it's exactly the same source code used by js-nacl. (Beware the padding requirements when you use crypto_sign() and friends, though: see http://nacl.cr.yp.to/sign.html)

Oh, libsodium should also interoperate fine with js-nacl.

Would you mind going into more detail on the padding issue? I'm wondering if it's the reason why my signatures don't match. ed25519-donna does not hash before signing.

I figured out my issue with the signing key/public key discrepancy. The argument for nacl.crypto_sign_keypair_from_seed is considered sk in those libraries.

When testing, the signing keys/seeds are equivalent, and so are the public keys. When signing "hello" as the message, they produce different results.

Crosspost: http://stackoverflow.com/questions/22032282/uint8array-equivalent-of-a-c-string-converted-to-const-unsigned-char

Looks like it was my misuse of C.

Tony, thank you so much for this lib! I can't thank you enough for those extra functions!

Looks like you already figured it out, which is good :-)

I was going to mention that in js-nacl (and many other libsodium-based wrappers around NaCl), the seed and the sk are different things and shouldn't be confused. To get the sk from the seed in js-nacl, you want crypto_sign_keypair_from_seed(seed).signSk, analogous with .signPk for the pk.

Indeed!

I'll let you know if I have a legitimate signature rejected for exhaustive testing. ;))

Now that the syntax is all ironed out, I have to say that this is one amazing library! One source file. All the functions and variables wrapped up in a nice bow. Included hashing. I think it offered wash my car...

Great job, and thank-you so very much for this lib and bearing with me!