A list of potentially unsafe ed25519 signature libraries that allow a public api where secret and public key can be provided independently as signing function inputs. Misuse of these public apis can result to private key exposure.
Μost of the repositories in our analysis are enlisted in IANIX :: Things that use Ed25519.
Number of impacted libraries: 45
Number of libraries that fixed the issue after the announcement: 8
last updated: May 04, 2023
Note that normally and according to the related rfc8032, EdDSA signatures are deterministic, and thus for the same input message to be signed, a unique signature output that includes two elements, a curve point R and a scalar S, is returned.
An algorithmic detail is that that signer's public key is involved in the deterministic computation of the S part of the signature only, but not in the R value. The latter implies that if an adversary could somehow use the signing function as an Oracle (that expects arbitrary public keys as inputs), then it is possible that for the same message one can get two signatures sharing the same R and only differ on the S part. Unfortunately, when this happens, one can easily extract the private key; this StackOverflow post post explains why this is feasible.
That said, public apis should NOT allow a decoupled private/public key-pair as signing input. To circumvent that, many implementations store the public key along with the private key (or seed) and consider the whole keypair as the secret OR they always re-derive the public key inside the signing function. Unfortunately, a large number of existing libraries fail to address this issue by allowing arbitrary public keys as inputs without checking if the input public key corresponds to the input private key.
Of course, this does not mean that all applications with dependencies to these libraries are prone to key exposure attacks; actually, most are probably safe due to usually not publicly exposing the affected api to their users and coupling their pub/priv key pair just before the sign invocation. On the other hand, even when these apis are not exposed, there are applications with different TCB threat model strategies on how the private and public keys are managed and stored. That said, to prevent this attack, developers should also enforce an integrity protection protocol for the public keys as well.
Here, we enlist some affected libraries along with the related code-references.
Fig 1. An example api misuse in the ed25519-dalek Rust crate.
https://github.com/gnbdev/opengnb/blob/master/libs/ed25519/sign.c#L7
https://github.com/hyperledger/iroha-ed25519/blob/main/lib/ed25519/ref10/ed25519.c#L27 and https://github.com/hyperledger/iroha-ed25519/blob/main/lib/ed25519/amd64-64-24k-pic/ed25519.c#L30
https://github.com/floodyberry/ed25519-donna/blob/master/ed25519.c#L59
https://github.com/orlp/ed25519/blob/master/src/sign.c#L7
https://github.com/kevsmith/libbrine/blob/master/src/ed25519/sign.c#L7
https://rweather.github.io/arduinolibs/classEd25519.html#a36ecf67b4c5d2d39a31888f56af1f8a5
https://github.com/hanswolff/ed25519/blob/master/Ed25519/Ed25519.cs#L146
https://github.com/semolex/ed25519_dart/blob/master/lib/src/ed25519_dart_base.dart#L200
https://github.com/riclava/ed25519/blob/master/lib/ed25519.dart#L125
https://github.com/hiredman/ed25519/blob/master/src/ed25519/core.clj#L168
https://github.com/vincenthz/hs-scraps/blob/master/Crypto/Signature/Ed25519.hs#L115
https://github.com/k3d3/ed25519-java/blob/master/ed25519.java#L144
https://github.com/BjornArnelid/ed25519/blob/master/src/ed25519/application/Ed25519.java#L32
https://github.com/michami/ED25519/blob/master/ED25519.java#L60
https://ed25519.cr.yp.to/python/ed25519.py
https://github.com/pyca/ed25519/blob/main/ed25519.py#L243 (authors mention it’s unsafe against side channels anyway)
https://github.com/warner/python-pure25519/blob/master/pure25519/eddsa.py#L21
https://github.com/naturalmessage/nmed25519/blob/master/nmed25519.py#L150
https://gist.github.com/elliptic-shiho/f41fd75cc30646a61d7ad63043fdd56e#file-ed25519-py-L77
https://github.com/polkascan/py-ed25519-bindings/blob/master/src/lib.rs#L111
https://github.com/pebble8888/ed25519swift/blob/master/Ed25519ref/ed25519s.swift#L120
https://github.com/1p6/supercop.js/blob/master/index.js#L29
https://github.com/substack/ed25519-supercop/blob/master/index.js#L3
https://github.com/phlay/libeddsa/blob/master/lib/ed25519-sha512.c#L85
https://github.com/SommerEngineering/Ed25519/blob/master/Ed25519/Signer.cs#L80
https://github.com/ChorusOne/solanity/blob/master/src/cuda-ecc-ed25519/sign.cu#L10
[https://github.com/ncme/c25519/blob/master/src/edsign.c#L115](https://github.com/ncme/c
$ claude mcp add ed25519-unsafe-libs \
-- python -m otcore.mcp_server <graph>