indutny / elliptic

Fast Elliptic Curve Cryptography in plain javascript
1.68k stars 372 forks source link

curve25519 incompatible with golang.org/x/crypto/curve25519 #174

Open mattlockyer opened 5 years ago

mattlockyer commented 5 years ago

Tried so many different combinations on the golang side and finally concluded it was this library.

ec = new EC('curve25519')
...
//encryption
  const receiver = ec.keyFromPublic(publicKey, 'hex')
  const ephemeral = ec.keyFromPrivate(createAccount().privateKey)
  const encryptionKey = ephemeral.derive(receiver.getPublic())
...
//decryption
  const receiver = ec.keyFromPrivate(privateKey)
  const ephemeral = ec.keyFromPublic(encryptObj.pub, 'hex')
  const encryptionKey = receiver.derive(ephemeral.getPublic())

I cannot get golang to produce the same result for encryptionKey using the standard golang.org/x/crypto/curve25519 library.

Keys are the same on both sides.

My only assumption is that your curve implementation is off or is a different variant.

I switched to https://github.com/dchest/tweetnacl-js and used the keyPair + scalarMult with zero issues.

Maybe someone could illuminate me to the pitfalls of different implementations? If that is a thing? I'm new to the cryptography side of things but have been programming for some time.

Thank you!

fanatid commented 5 years ago

.getPublic() return encoded public key, maybe will be correct:

const encryptionKey = ephemeral.derive(receiver.pub)

?

mattlockyer commented 5 years ago

Maybe it's a misnomer but encryptionKey is a BN, it's already a point / public key

fanatid commented 5 years ago

Yes, .derive return X part of point as BN instance, but in same time .derive expect point on input as instance, not encoded.

https://github.com/indutny/elliptic/blob/523da1cf71ddcfd607fbdee1858bc2af47f0e700/lib/elliptic/ec/key.js#L103

https://github.com/indutny/elliptic/blob/523da1cf71ddcfd607fbdee1858bc2af47f0e700/lib/elliptic/ec/key.js#L67

mattlockyer commented 5 years ago

So you're saying the derive method expects a Point object X value and not the public address?

Thank you for trying to help... This would be interesting to try but it doesn't seem like the example ECDH given here:

https://github.com/indutny/elliptic/blob/master/README.md

Mischala commented 5 years ago

I'm also having issues with X25519.derive() getting different results than our Python implementation, using PyNaCl.

bronze1man commented 5 years ago

Is there any code example that can compatible with golang.org/x/crypto/curve25519 or https://github.com/CryptoEsel/js-x25519?

Ps: I have checked that the test in https://github.com/CryptoEsel/js-x25519/blob/master/test/vector.js is compatible with golang.org/x/crypto/curve25519.

zhangliang-xiaohe-hanxin commented 5 years ago

I got the same problems. is there any solution yet?

bronze1man commented 5 years ago

I got the same problems. is there any solution yet?

Switch to other curve25519 project like https://github.com/CryptoEsel/js-x25519