PrivateKey and SigningKey from same seed but to_curve25519_private_key with different output
kernel1983 opened this issue · comments
I write a simple test to figure out the PrivateKey and SigningKey on version 1.5.0:
import base64
import nacl.public
import nacl.signing
import nacl.utils
seed = nacl.utils.random()
sk = nacl.public.PrivateKey.from_seed(seed)
sign_key = nacl.signing.SigningKey(seed)
print(base64.b16encode(sk._private_key))
print(base64.b16encode((sign_key.to_curve25519_private_key())._private_key))
The output is always diffident for the first byte and sometimes the last byte:
python3 test_nacl.py
b'965240CAE82380D486DC6A0BE50D1EB2ECFF3ED48778CDFDB7969D4E0D3CFB97'
b'905240CAE82380D486DC6A0BE50D1EB2ECFF3ED48778CDFDB7969D4E0D3CFB57'
python3 test_nacl.py
b'D6F2B255AB2FF4060EB2CC6E45B66E7E88DEB9AD3A2596C867F45403FEBAD871'
b'D0F2B255AB2FF4060EB2CC6E45B66E7E88DEB9AD3A2596C867F45403FEBAD871'
May I know if I used this in the right way? Or is this a bug?
I tried on both ubuntu 20.04 and macOS.
@kernel1983 I think there are two things to consider:
- Curve25519/X25519 is not a cipher that can be used for public key signatures. Unless the "Curve25519" is a generalisation of the different expressions of the curve for ECDH in X25519 and EdDSA in Ed25519.
- For Curve25519 there is a particular bit-mask applied to the (random) seed before it becomes a private key as it is used internally. The two are functionally identical as after application of the bit mask (before cryptographic operations) they are resulting in the same binary sequence.
I hope that explains enough of the phenomenon.