Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Invalid signature generation and signature verification. #321

Open
bleichenbacher-daniel opened this issue Oct 13, 2024 · 0 comments
Open

Comments

@bleichenbacher-daniel
Copy link

I have noticed that the elliptic library v. 6.5.7 may generate incorrect ECDSA signatures and also verify incorrect ECDSA signatures.
An example for an invalid signature that is verified as true is the following (all values are in hexadecimal):

curve: "secp224r1"
messageDigest: "SHA-256",
publicKeyUncompressed: "04afb8a1081da80211db6983ab7c94e4f5b8a13c939da4bbc0e7acdf6b3939f24928a427a783632fc520c78e78ee9452d6afb205e1c6e03ca2"
publicKeyCompressed: "02afb8a1081da80211db6983ab7c94e4f5b8a13c939da4bbc0e7acdf6b"
msg: "049a27b5204bb2be"
sig: "303c021c344cc8cd2571137ce4186ffd03ee7626e9d91ede7ea3afd45aeaf6b2021c2e4743bde502b2c1dda87c55a4451e5956e04e38e68257311d89def3"

Similar miscalculations can happen whenever the size of the message digest is longer than the size of the curve. A possible cause for the error is the function truncateToN in the file ec/index.js


EC.prototype._truncateToN = function _truncateToN(msg, truncOnly) {
  var delta = msg.byteLength() * 8 - this.n.bitLength();
  if (delta > 0)
    msg = msg.ushrn(delta);
  if (!truncOnly && msg.cmp(this.n) >= 0)
    return msg.sub(this.n);
  else
    return msg;
};

This code uses the length of the integer msg to compute the length of the truncation. The correct method would be to use the length of the message digest from which the integer msg is computed. If the first byte of the message digest is 0 then this function truncates incorrectly.

I have briefly looked at potential key leakages since ECDSA implementations using RFC 6979 are notoriously brittle when the implementation contains arithmetic errors. My impression is that the bug is likely not exploitable under normal assumptions (attacker can perform a chosen message attack, but the signer hashes before signing). The situation is less clear in a prehash setup where the attacker can select the message digest without providing proof that the prehash is actually the result of the hash.

It may of course be the case that the library is only intended for a selection of curve/hash combinations. However, neither the documentation nor the API, nor the implementation accepting any size of hashes provide any indication what is supported.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant