VYPR
Low severityNVD Advisory· Published Aug 2, 2024· Updated Nov 3, 2025

CVE-2024-42459

CVE-2024-42459

Description

In the Elliptic package 6.5.6 for Node.js, EDDSA signature malleability occurs because there is a missing signature length check, and thus zero-valued bytes can be removed or appended.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

CVE-2024-42459: Elliptic 6.5.6 EDDSA signature malleability due to missing length check allows zero-valued byte manipulation.

Vulnerability

Description

CVE-2024-42459 is a signature malleability vulnerability in the Elliptic package version 6.5.6 for Node.js, specifically affecting its EDDSA implementation. The root cause is a missing signature length check, which enables attackers to remove or append zero-valued bytes to a valid EDDSA signature without invalidating it [1]. This flaw arises in the Signature constructor where only the byte array is accepted without enforcing the fixed encoding length defined by the curve's encoding length [4].

Attack

Vector and Exploitation

An attacker can exploit this vulnerability by taking a valid EDDSA signature and either truncating leading zero bytes or appending additional zero bytes to the R or S components of the signature. The modified signature will still pass verification because the Elliptic library does not check that the signature's byte length matches the expected encodingLength * 2 (i.e., 64 bytes for Ed25519) [4]. The attack requires no special network position beyond being able to observe or obtain a valid signature; no authentication is needed to perform the malleation, though the attacker must be able to present the modified signature to a verifier.

Impact

Successful exploitation results in signature malleability, meaning that an attacker can produce multiple distinct byte strings that all verify as valid signatures for the same message under the same public key. This can break protocols that rely on signature non-repudiation or that use signatures as unique identifiers (e.g., in blockchain transactions, cryptocurrency systems, or other digital signature-based applications). The ability to create multiple valid-looking signatures from a single legitimate signature undermines the security guarantees of digital signatures [1].

Mitigation

The vulnerability was addressed in a subsequent commit that adds a length assertion in the Signature constructor: assert(sig.length === eddsa.encodingLength * 2, 'Signature has invalid size') [4]. Users of the Elliptic package should upgrade to a patched version (later than 6.5.6) to prevent signature malleability. There is no workaround other than updating the library.

AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
ellipticnpm
>= 4.0.0, < 6.5.76.5.7

Affected products

2
  • Node.js/Elliptic packagedescription
  • ghsa-coords
    Range: >= 4.0.0, < 6.5.7

Patches

2
accb61e9c1a0

lib: DER signature decoding correction

https://github.com/indutny/ellipticMarkus SchiffermüllerAug 14, 2024via ghsa
2 files changed · +11 0
  • lib/elliptic/ec/signature.js+10 0 modified
    @@ -38,6 +38,10 @@ function getLength(buf, p) {
         return false;
       }
     
    +  if(buf[p.place] === 0x00) {
    +    return false;
    +  }
    +
       var val = 0;
       for (var i = 0, off = p.place; i < octetLen; i++, off++) {
         val <<= 8;
    @@ -86,6 +90,9 @@ Signature.prototype._importDER = function _importDER(data, enc) {
       if (rlen === false) {
         return false;
       }
    +  if ((data[p.place] & 128) !== 0) {
    +    return false;
    +  }
       var r = data.slice(p.place, rlen + p.place);
       p.place += rlen;
       if (data[p.place++] !== 0x02) {
    @@ -98,6 +105,9 @@ Signature.prototype._importDER = function _importDER(data, enc) {
       if (data.length !== slen + p.place) {
         return false;
       }
    +  if ((data[p.place] & 128) !== 0) {
    +    return false;
    +  }
       var s = data.slice(p.place, slen + p.place);
       if (r[0] === 0) {
         if (r[1] & 0x80) {
    
  • lib/elliptic/eddsa/signature.js+1 0 modified
    @@ -21,6 +21,7 @@ function Signature(eddsa, sig) {
         sig = parseBytes(sig);
     
       if (Array.isArray(sig)) {
    +    assert(sig.length === eddsa.encodingLength * 2, 'Signature has invalid size');
         sig = {
           R: sig.slice(0, eddsa.encodingLength),
           S: sig.slice(eddsa.encodingLength),
    
c0690b36be04

eddsa: implementation and tests

https://github.com/indutny/ellipticNicholas DudfieldMay 18, 2015via ghsa
13 files changed · +5368 6
  • lib/elliptic/curve/edwards.js+36 2 modified
    @@ -47,7 +47,7 @@ EdwardsCurve.prototype.jpoint = function jpoint(x, y, z, t) {
       return this.point(x, y, z, t);
     };
     
    -EdwardsCurve.prototype.pointFromX = function pointFromX(odd, x) {
    +EdwardsCurve.prototype.pointFromX = function pointFromX(x, odd) {
       x = new bn(x, 16);
       if (!x.red)
         x = x.toRed(this.red);
    @@ -61,7 +61,35 @@ EdwardsCurve.prototype.pointFromX = function pointFromX(odd, x) {
       if (odd && !isOdd || !odd && isOdd)
         y = y.redNeg();
     
    -  return this.point(x, y, curve.one);
    +  return this.point(x, y);
    +};
    +
    +EdwardsCurve.prototype.pointFromY = function pointFromY(y, odd) {
    +  y = new bn(y, 16);
    +  if (!y.red)
    +    y = y.toRed(this.red);
    +
    +  // x^2 = (y^2 - 1) / (d y^2 + 1)
    +  var y2 = y.redSqr();
    +  var lhs = y2.redSub(this.one);
    +  var rhs = y2.redMul(this.d).redAdd(this.one);
    +  var x2 = lhs.redMul(rhs.redInvm());
    +
    +  if (x2.cmp(this.zero) === 0) {
    +    if (odd)
    +      throw new Error('invalid point');
    +    else
    +      return this.point(this.zero, y);
    +  }
    +
    +  var x = x2.redSqrt();
    +  if (x.redSqr().redSub(x2).cmp(this.zero) !== 0)
    +    throw new Error('invalid point');
    +
    +  if (x.isOdd() !== odd)
    +    x = x.redNeg();
    +
    +  return this.point(x, y);
     };
     
     EdwardsCurve.prototype.validate = function validate(point) {
    @@ -366,6 +394,12 @@ Point.prototype.getY = function getY() {
       return this.y.fromRed();
     };
     
    +Point.prototype.eq = function eq(other) {
    +  return this === other ||
    +         this.getX().cmp(other.getX()) === 0 &&
    +         this.getY().cmp(other.getY()) === 0;
    +};
    +
     // Compatibility with BaseCurve
     Point.prototype.toP = Point.prototype.normalize;
     Point.prototype.mixedAdd = Point.prototype.add;
    
  • lib/elliptic/curve/short.js+1 1 modified
    @@ -185,7 +185,7 @@ ShortCurve.prototype._endoSplit = function _endoSplit(k) {
       return { k1: k1, k2: k2 };
     };
     
    -ShortCurve.prototype.pointFromX = function pointFromX(odd, x) {
    +ShortCurve.prototype.pointFromX = function pointFromX(x, odd) {
       x = new bn(x, 16);
       if (!x.red)
         x = x.toRed(this.red);
    
  • lib/elliptic/ec/index.js+1 1 modified
    @@ -185,7 +185,7 @@ EC.prototype.recoverPubKey = function(msg, signature, j, enc) {
         throw new Error('Unable to find sencond key candinate');
     
       // 1.1. Let x = r + jn.
    -  r = this.curve.pointFromX(isYOdd, r);
    +  r = this.curve.pointFromX(r, isYOdd);
       var eNeg = e.neg().mod(n);
     
       // 1.6.1 Compute Q = r^-1 (sR -  eG)
    
  • lib/elliptic/ec/key.js+1 1 modified
    @@ -122,7 +122,7 @@ KeyPair.prototype._importPublicShort = function _importPublicShort(key) {
           key.slice(1, 1 + len),
           key.slice(1 + len, 1 + 2 * len));
       } else if ((key[0] === 0x02 || key[0] === 0x03) && key.length - 1 === len) {
    -    this.pub = this.ec.curve.pointFromX(key[0] === 0x03, key.slice(1, 1 + len));
    +    this.pub = this.ec.curve.pointFromX(key.slice(1, 1 + len), key[0] === 0x03);
       }
     };
     
    
  • lib/elliptic/eddsa/index.js+110 0 added
    @@ -0,0 +1,110 @@
    +'use strict';
    +
    +var hash = require('hash.js');
    +var elliptic = require('../../elliptic');
    +var utils = elliptic.utils;
    +var assert = utils.assert;
    +var parseBytes = utils.parseBytes;
    +var KeyPair = require('./key');
    +var Signature = require('./signature');
    +
    +function EDDSA(curve) {
    +  assert(curve === 'ed25519', 'only tested with ed25519 so far');
    +
    +  if (!(this instanceof EDDSA))
    +    return new EDDSA(curve);
    +
    +  var curve = elliptic.curves[curve].curve;
    +  this.curve = curve;
    +  this.g = curve.g;
    +  this.g.precompute(curve.n.bitLength() + 1);
    +
    +  this.pointClass = curve.point().constructor;
    +  this.encodingLength = Math.ceil(curve.n.bitLength() / 8);
    +  this.hash = hash.sha512;
    +}
    +
    +module.exports = EDDSA;
    +
    +/**
    +* @param {Array|String} message - message bytes
    +* @param {Array|String|KeyPair} secret - secret bytes or a keypair
    +* @returns {Signature} - signature
    +*/
    +EDDSA.prototype.sign = function sign(message, secret) {
    +  message = parseBytes(message);
    +  var key = this.keyFromSecret(secret);
    +  var r = this.hashInt(key.messagePrefix(), message);
    +  var R = this.g.mul(r);
    +  var Rencoded = this.encodePoint(R);
    +  var s_ = this.hashInt(Rencoded, key.pubBytes(), message)
    +               .mul(key.priv());
    +  var S = r.add(s_).mod(this.curve.n);
    +  return this.makeSignature({ R: R, S: S, Rencoded: Rencoded });
    +};
    +
    +/**
    +* @param {Array} message - message bytes
    +* @param {Array|String|Signature} sig - sig bytes
    +* @param {Array|String|Point|KeyPair} pub - public key
    +* @returns {Boolean} - true if public key matches sig of message
    +*/
    +EDDSA.prototype.verify = function verify(message, sig, pub) {
    +  message = parseBytes(message);
    +  sig = this.makeSignature(sig);
    +  var key = this.keyFromPublic(pub);
    +  var h = this.hashInt(sig.Rencoded(), key.pubBytes(), message);
    +  var SG = this.g.mul(sig.S());
    +  var RplusAh = sig.R().add(key.pub().mul(h));
    +  return RplusAh.eq(SG);
    +};
    +
    +EDDSA.prototype.hashInt = function hashInt() {
    +  var hash = this.hash();
    +  for (var i = 0; i < arguments.length; i++) {
    +    hash.update(arguments[i]);
    +  }
    +  return utils.intFromLE(hash.digest()).mod(this.curve.n);
    +};
    +
    +EDDSA.prototype.keyFromPublic = function keyFromPublic(pub) {
    +  return KeyPair.fromPublic(this, pub);
    +};
    +
    +EDDSA.prototype.keyFromSecret = function keyFromSecret(secret) {
    +  return KeyPair.fromSecret(this, secret);
    +};
    +
    +EDDSA.prototype.makeSignature = function makeSignature(sig) {
    +  if (sig instanceof Signature)
    +    return sig;
    +  return new Signature(this, sig);
    +};
    +
    +/**
    +* * https://tools.ietf.org/html/draft-josefsson-eddsa-ed25519-03#section-5.2
    +*
    +* EDDSA defines methods for encoding and decoding points and integers. These are
    +* helper convenience methods, that pass along to utility functions implied
    +* parameters.
    +*
    +*/
    +EDDSA.prototype.encodePoint = function encodePoint(point) {
    +  return utils.pointToLEYoddX(point, this.encodingLength);
    +};
    +
    +EDDSA.prototype.decodePoint = function decodePoint(bytes) {
    +  return utils.pointFromLEYoddX(this.curve, bytes, bytes.length);
    +};
    +
    +EDDSA.prototype.encodeInt = function encodeInt(num) {
    +  return utils.intToLE(num, this.encodingLength);
    +};
    +
    +EDDSA.prototype.decodeInt = function decodeInt(bytes) {
    +  return utils.intFromLE(bytes);
    +};
    +
    +EDDSA.prototype.isPoint = function isPoint(val) {
    +  return val instanceof this.pointClass;
    +};
    
  • lib/elliptic/eddsa/key.js+96 0 added
    @@ -0,0 +1,96 @@
    +'use strict';
    +
    +var elliptic = require('../../elliptic');
    +var utils = elliptic.utils;
    +var assert = utils.assert;
    +var parseBytes = utils.parseBytes;
    +var lazyComputed = utils.lazyComputed;
    +
    +/**
    +* @param {EDDSA} eddsa - instance
    +* @param {Object} params - public/private key parameters
    +*
    +* @param {Array<Byte>} [params.secret] - secret seed bytes
    +* @param {Point} [params.pub] - public key point (aka `A` in eddsa terms)
    +* @param {Array<Byte>} [params.pub] - public key point encoded as bytes
    +*
    +*/
    +function KeyPair(eddsa, params) {
    +  this.eddsa = eddsa;
    +  this._secret = parseBytes(params.secret);
    +  if (eddsa.isPoint(params.pub))
    +    this._pub = params.pub;
    +  else
    +    this._pubBytes = parseBytes(params.pub);
    +}
    +
    +KeyPair.fromPublic = function fromPublic(eddsa, pub) {
    +  if (pub instanceof KeyPair)
    +      return pub;
    +  return new KeyPair(eddsa, { pub: pub });
    +};
    +
    +KeyPair.fromSecret = function fromSecret(eddsa, secret) {
    +  if (secret instanceof KeyPair)
    +    return secret;
    +  return new KeyPair(eddsa, { secret: secret });
    +};
    +
    +KeyPair.prototype.secret = function secret() {
    +  return this._secret;
    +};
    +
    +lazyComputed(KeyPair, 'pubBytes', function pubBytes() {
    +  return this.eddsa.encodePoint(this.pub());
    +});
    +
    +lazyComputed(KeyPair, 'pub', function pub() {
    +  if (this._pubBytes)
    +    return this.eddsa.decodePoint(this._pubBytes);
    +  return this.eddsa.g.mul(this.priv());
    +});
    +
    +lazyComputed(KeyPair, 'privBytes', function privBytes() {
    +  var eddsa = this.eddsa;
    +  var hash = this.hash();
    +  var lastIx = eddsa.encodingLength - 1;
    +
    +  var a = hash.slice(0, eddsa.encodingLength);
    +  a[0] &= 248;
    +  a[lastIx] &= 127;
    +  a[lastIx] |= 64;
    +
    +  return a;
    +});
    +
    +lazyComputed(KeyPair, 'priv', function priv() {
    +  return this.eddsa.decodeInt(this.privBytes());
    +});
    +
    +lazyComputed(KeyPair, 'hash', function hash() {
    +  return this.eddsa.hash().update(this.secret()).digest();
    +});
    +
    +lazyComputed(KeyPair, 'messagePrefix', function messagePrefix() {
    +  return this.hash().slice(this.eddsa.encodingLength);
    +});
    +
    +KeyPair.prototype.sign = function sign(message) {
    +  assert(this._secret, 'KeyPair can only verify');
    +  return this.eddsa.sign(message, this);
    +};
    +
    +KeyPair.prototype.verify = function verify(message, sig) {
    +  return this.eddsa.verify(message, sig, this);
    +};
    +
    +KeyPair.prototype.getSecret = function getSecret(enc) {
    +  assert(this._secret, 'KeyPair is public only');
    +  return utils.encode(this.secret(), enc);
    +};
    +
    +KeyPair.prototype.getPublic = function getPublic(enc) {
    +  return utils.encode(this.pubBytes(), enc);
    +};
    +
    +module.exports = KeyPair;
    
  • lib/elliptic/eddsa/signature.js+66 0 added
    @@ -0,0 +1,66 @@
    +'use strict';
    +
    +var bn = require('bn.js');
    +var elliptic = require('../../elliptic');
    +var utils = elliptic.utils;
    +var assert = utils.assert;
    +var lazyComputed = utils.lazyComputed;
    +var parseBytes = utils.parseBytes;
    +
    +/**
    +* @param {EDDSA} eddsa - eddsa instance
    +* @param {Array<Bytes>|Object} sig -
    +* @param {Array<Bytes>|Point} [sig.R] - R point as Point or bytes
    +* @param {Array<Bytes>|bn} [sig.S] - S scalar as bn or bytes
    +* @param {Array<Bytes>} [sig.Rencoded] - R point encoded
    +* @param {Array<Bytes>} [sig.Sencoded] - S scalar encoded
    +*/
    +function Signature(eddsa, sig) {
    +  this.eddsa = eddsa;
    +
    +  if (typeof sig !== 'object')
    +    sig = parseBytes(sig);
    +
    +  if (Array.isArray(sig)) {
    +    sig = {
    +      R: sig.slice(0, eddsa.encodingLength),
    +      S: sig.slice(eddsa.encodingLength)
    +    };
    +  }
    +
    +  assert(sig.R && sig.S, 'Signature without R or S');
    +
    +  if (eddsa.isPoint(sig.R))
    +    this._R = sig.R;
    +  if (sig.S instanceof bn)
    +    this._S = sig.S;
    +
    +  this._Rencoded = Array.isArray(sig.R) ? sig.R : sig.Rencoded;
    +  this._Sencoded = Array.isArray(sig.S) ? sig.S : sig.Sencoded;
    +}
    +
    +lazyComputed(Signature, 'S', function S() {
    +  return this.eddsa.decodeInt(this.Sencoded());
    +});
    +
    +lazyComputed(Signature, 'R', function S() {
    +  return this.eddsa.decodePoint(this.Rencoded());
    +});
    +
    +lazyComputed(Signature, 'Rencoded', function S() {
    +  return this.eddsa.encodePoint(this.R());
    +});
    +
    +lazyComputed(Signature, 'Sencoded', function S() {
    +  return this.eddsa.encodeInt(this.S());
    +});
    +
    +Signature.prototype.toBytes = function toBytes() {
    +  return this.Rencoded().concat(this.Sencoded());
    +};
    +
    +Signature.prototype.toHex = function toHex() {
    +  return utils.encode(this.toBytes(), 'hex').toUpperCase();
    +};
    +
    +module.exports = Signature;
    
  • lib/elliptic.js+1 0 modified
    @@ -11,3 +11,4 @@ elliptic.curves = require('./elliptic/curves');
     
     // Protocols
     elliptic.ec = require('./elliptic/ec');
    +elliptic.eddsa = require('./elliptic/eddsa');
    
  • lib/elliptic/utils.js+51 0 modified
    @@ -1,6 +1,7 @@
     'use strict';
     
     var utils = exports;
    +var bn = require('bn.js');
     
     utils.assert = function assert(val, msg) {
       if (!val)
    @@ -148,3 +149,53 @@ function getJSF(k1, k2) {
       return jsf;
     }
     utils.getJSF = getJSF;
    +
    +function lazyComputed(obj, name, computer) {
    +  var key = '_' + name;
    +  obj.prototype[name] = function lazyComputed() {
    +    return this[key] !== undefined ? this[key] :
    +           this[key] = computer.apply(this, arguments);
    +  };
    +}
    +utils.lazyComputed = lazyComputed;
    +
    +function parseBytes(bytes) {
    +  return typeof bytes === 'string' ? utils.toArray(bytes, 'hex') :
    +                                     bytes;
    +}
    +utils.parseBytes = parseBytes;
    +
    +function intFromLE(bytes) {
    +  return new bn(bytes, 'hex', 'le');
    +}
    +utils.intFromLE = intFromLE;
    +
    +function intToLE(num, padTo) {
    +  var bytes = num.toArray('le');
    +  while (bytes.length < padTo)
    +    bytes.push(0);
    +  return bytes;
    +}
    +utils.intToLE = intToLE;
    +
    +function pointToLEYoddX(point, length) {
    +  var enc = intToLE(point.getY(), length);
    +  enc[length - 1] |= point.getX().isOdd() ? 0x80 : 0;
    +  return enc;
    +}
    +utils.pointToLEYoddX = pointToLEYoddX;
    +
    +function pointFromLEYoddX(curve, bytes, expectedLength) {
    +  bytes = parseBytes(bytes);
    +
    +  if (expectedLength !== undefined)
    +    utils.assert(bytes.length === expectedLength);
    +
    +  var lastIx = bytes.length - 1;
    +  var normed = bytes.slice(0, lastIx).concat(bytes[lastIx] & ~0x80);
    +  var xIsOdd = Boolean(bytes[lastIx] & 0x80);
    +
    +  var y = intFromLE(normed);
    +  return curve.pointFromY(y, xIsOdd);
    +}
    +utils.pointFromLEYoddX = pointFromLEYoddX;
    
  • package.json+1 1 modified
    @@ -30,7 +30,7 @@
         "uglify-js": "^2.4.13"
       },
       "dependencies": {
    -    "bn.js": "^2.0.3",
    +    "bn.js": "^2.1.0",
         "brorand": "^1.0.1",
         "hash.js": "^1.0.0",
         "inherits": "^2.0.1"
    
  • test/ed25519-test.js+138 0 added
    @@ -0,0 +1,138 @@
    +'use strict';
    +
    +var assert = require('assert');
    +var fs = require('fs');
    +var bn = require('bn.js');
    +var hash = require('hash.js');
    +var elliptic = require('../');
    +var utils = elliptic.utils;
    +var toArray = elliptic.utils.toArray;
    +var eddsa = elliptic.eddsa;
    +
    +function toHex(arr) {
    +  return elliptic.utils.toHex(arr).toUpperCase();
    +}
    +
    +var MAX_PROGRAMMATIC = process.env.CI ? Infinity : 50;
    +
    +describe('ed25519 derivations', function() {
    +  var expectedTests = 256;
    +  var ed25519, derivations;
    +
    +  before(function() {
    +    ed25519 = new eddsa('ed25519');
    +    derivations = require('./fixtures/derivation-fixtures');
    +    assert.equal(derivations.length, expectedTests);
    +  });
    +
    +  function testFactory(i) {
    +    it('can compute correct a and A for secret: ' + i, function() {
    +      var test = derivations[i];
    +      var secret = utils.toArray(test.secret_hex, 'hex');
    +      var key = ed25519.keyFromSecret(secret);
    +      assert.equal(toHex(key.privBytes()), test.a_hex);
    +      var xRecovered = toHex(ed25519.encodeInt(
    +                             ed25519.decodePoint(key.pubBytes()).getX()));
    +      assert.equal(xRecovered, test.A_P.x);
    +      assert.equal(toHex(key.pubBytes()), test.A_hex);
    +    });
    +  }
    +
    +  for (var i = 0; i < Math.min(expectedTests, MAX_PROGRAMMATIC); i++)
    +    testFactory(i);
    +});
    +
    +describe('sign.input ed25519 test vectors', function() {
    +  var expectedTests = 1024;
    +  var ed25519, lines;
    +
    +  before(function(done) {
    +    ed25519 = new eddsa('ed25519');
    +    fs.readFile(__dirname + '/fixtures/sign.input', function(err, f) {
    +       lines = f.toString().split('\n');
    +       assert.equal(lines.length, expectedTests + 1 /*blank line*/);
    +       done();
    +    })
    +  });
    +
    +  function testFactory(i) {
    +    it('vector ' + i, function() {
    +      var split = lines[i].toUpperCase().split(':');
    +      var key = ed25519.keyFromSecret(split[0].slice(0, 64));
    +      var expectedPk = split[0].slice(64);
    +
    +      assert.equal(toHex(key.pubBytes()), expectedPk);
    +
    +      var msg = toArray(split[2], 'hex');
    +      var sig = key.sign(msg).toHex();
    +      var sigR = sig.slice(0, 64);
    +      var sigS = sig.slice(64);
    +
    +      assert.equal(sigR, split[3].slice(0, 64));
    +      assert.equal(sigS, split[3].slice(64, 128));
    +      assert(key.verify(msg, sig));
    +
    +      var forged = msg.length === 0 ? [0x78] /*ord('x')*/:
    +                   msg.slice(0, msg.length-1).concat(
    +                        (msg[(msg.length-1)] + 1) % 256)
    +
    +      assert.equal(msg.length || 1, forged.length);
    +      assert(!key.verify(forged, sig));
    +    })
    +  }
    +  for (var i = 0; i < Math.min(expectedTests, MAX_PROGRAMMATIC); i++)
    +    testFactory(i);
    +});
    +
    +describe('EDDSA(\'ed25519\')', function() {
    +  var ed25519
    +
    +  before(function() {
    +    ed25519 = new eddsa('ed25519');
    +  });
    +
    +  it('has encodingLength of 32', function() {
    +    assert.equal(32, ed25519.encodingLength);
    +  });
    +
    +  it('can sign/verify messages', function() {
    +    var secret = toArray(new Array(65).join('0'), 'hex');
    +    assert(secret.length == 32);
    +    var msg = [0xB, 0xE, 0xE, 0xF];
    +    var key = ed25519.keyFromSecret(secret);
    +    var sig = key.sign(msg).toHex();
    +
    +    var R = "8F1B9A7FDB22BCD2C15D4695B1CE2B063CBFAEC9B00BE360427BAC9533943F6C";
    +    var S = "5F0B380FD7F2E43B70AB2FA29F6C6E3FFC1012710E174786814012324BF19B0C";
    +
    +    assert.equal(sig.slice(0, 64), R);
    +    assert.equal(sig.slice(64), S);
    +
    +    assert(key.verify(msg, sig));
    +  });
    +
    +  describe('KeyPair', function() {
    +    var pair;
    +    var secret = '00000000000000000000000000000000' +
    +                 '00000000000000000000000000000000';
    +
    +    before(function() {
    +      pair = ed25519.keyFromSecret(secret);
    +    });
    +
    +    it('can be created with keyFromSecret/keyFromPublic', function() {
    +      var pubKey = ed25519.keyFromPublic(toHex(pair.pubBytes()));
    +      assert(pubKey.pub() instanceof ed25519.pointClass);
    +      assert(pubKey.pub().eq(pair.pub()));
    +    });
    +    it('#getSecret returns bytes with optional encoding', function() {
    +      assert(Array.isArray(pair.getSecret()));
    +      assert(pair.getSecret('hex') === secret);
    +    });
    +    it('#getPub returns bytes with optional encoding', function() {
    +      assert(Array.isArray(pair.getPublic()));
    +      assert.equal(pair.getPublic('hex'),
    +        '3b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29');
    +    });
    +  });
    +});
    
  • test/fixtures/derivation-fixtures.js+3842 0 added
  • test/fixtures/sign.input+1024 0 added

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

6

News mentions

0

No linked articles in our index yet.