sodium-javascript icon indicating copy to clipboard operation
sodium-javascript copied to clipboard

crypto_sign_ed25519_sk_to_curve25519 assertion error

Open hklee93 opened this issue 4 years ago • 1 comments

Hi, I'm trying to convert my ed25519 keypair to x25519 keypair, which can be achieved by provided functions

  • sodium.crypto_sign_ed25519_pk_to_curve25519(x25519_public, ed25519_public)
  • sodium.crypto_sign_ed25519_sk_to_curve25519(x25519_secret, ed25519_secret)

Currently I'm generating x25519 keypair buffer with the following functions

{
  publicKey: sodium.sodium_malloc(sodium.crypto_box_PUBLICKEYBYTES),
  secretKey: sodium.sodium_malloc(sodium.crypto_box_SECRETKEYBYTES)
}

I was able to convert public key, but it looks like converting secret key raises the following assertion error.

edSk must be 'crypto_sign_ed25519_SECRETKEYBYTES' long

My ed25519 secret key is 32 bytes, and it looks like crypto_sign_ed25519_SECRETKEYBYTES is 64 bytes. Now what I'm curious is even though it's checking for 64 bytes, it looks like a subsequent call is only using 32 bytes of the buffer

crypto_hash(h, edSk, 32)
  1. Is there a reason the assertion is looking for 64 bytes when only 32 bytes are being used?
  2. Is it safe if I just pad additional 32 bytes to my private key and pass this assertion?

hklee93 avatar Sep 22 '21 23:09 hklee93

I'm new to the topic and have been reading on curves for only about a week now.

One thing I came to learn was the difference between the seed and the secret key. The seed is 32 bytes of random. You can create the secretkey from it which is effectively a concatenation of the seed and the resulting public key. There is the a function to extract the pubkey from the secretkey (taking only the latter 32 bytes of the 64 byte secret.

So if your "ed25519-secret" is 32 bytes long, you likely confused it with the seed.

You should be able to feed it into crypto_sign_seed_keypair, where pk and sk are variables to store the resulting keypair in.

https://github.com/sodium-friends/sodium-javascript/blob/ae2df3305e0cff68c3ae922813bfbb2d361d78de/crypto_sign.js#L150

This appeared to be a little confusing at first, but gives major speed advantages once you sign content and have do not really have to calculate the pubkey over and over again.

The answer to the second is no. The forged key would be invalid.

AiyionPrime avatar May 30 '22 00:05 AiyionPrime