pyca / pynacl

Python binding to the Networking and Cryptography (NaCl) library

Home Page:https://pynacl.readthedocs.io/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

PrivateKey and SigningKey from same seed but to_curve25519_private_key with different output

kernel1983 opened this issue · comments

commented

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.