I'm trying to get the public key with different JavaScript libraries: with elliptic and with libsodium-wrappers-sumo This is my code:

const BN = require('bn.js');
const EdDSA = require('elliptic').eddsa;
const ed25519 = new EdDSA('ed25519');
const _sodium = require('libsodium-wrappers-sumo');

(async() => {
  await _sodium.ready;
  const sodium = _sodium;
  const privKeyHex = "6220f3affaa568f554ca850f9374e7112c09af219976bb779f4fd8f297294900"
  const tmp1 = sodium.crypto_scalarmult_ed25519_base_noclamp(Buffer.from(privKeyHex, "hex"), "hex")
  const tmp2 = ed25519.curve.g.mul(new BN(privKeyHex, "hex", "le")).getY().toArrayLike(Buffer, "le", 32).toString("hex")


I expect to get the same values ​​but I get different:


The last byte is different. Inexplicably.

Checking on this site gives the result:


What could be the reason for the discrepancy between the results and what is the correct result?

1 Answer 1


See RFC8032 for an explanation of how the sign of a point is encoded into the most significant bit of the last byte. By doing getY() you're attempting to do your own encoding, and not setting this bit.

Instead, let the library do the encoding for you:

elliptic.utils.toHex(ed25519.encodePoint(ed25519.curve.g.mul(new BN(privKeyHex, "hex", "le"))))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.