Impact
The Curve25519 arithmetic precompiles allow smart contract developers to cheaply utilize these curve operations in their smart contracts.
The Curve25519Add
and Curve25519ScalarMul
precompiles incorrectly handle invalid Ristretto point representations. Instead of returning an error, they silently treat invalid input bytes as the Ristretto identity element, leading to potentially incorrect cryptographic results. In frame/evm/precompile/curve25519/src/lib.rs
, when processing input points for both addition and scalar multiplication, in the execute function, the code attempts to decompress the 32-byte input using point.decompress().
If the input bytes do not represent a valid compressed Ristretto point, decompress()
returns None
. However, the code uses unwrap_or_else(RistrettoPoint::identity)
, which replaces this None result with the RistrettoPoint::identity()
element without signalling any error to the caller.
Silently treating invalid cryptographic points as the identity element could introduce critical vulnerabilities in smart contracts. This behavior could compromise confidentiality in key exchanges or allow threshold signature requirements to be bypassed. For example, in a multi-signature scheme, an attacker could submit an invalid compressed Ristretto point as a public key. Treated as the identity element, it would be incorrectly counted toward the signing threshold, enabling signature forgery with fewer valid participants.
Patches
The issue is fixed by PR 1720.
Notes on severity
In the audit by SRLabs, this issue is classified with "Medium" severity. However, we believe it's a critical severity advisory because it can bypass a smart contract's security assumptions.
It is therefore recommended that an emergency runtime upgrade to be issued if you use Curve25519Add
or Curve25519ScalarMul
precompiles.
Credits
This issue is discovered in a security audit by SRLabs with the Moonbeam team. Polkadot Assurance Legion (PAL) financially contributed to the security audit.
Impact
The Curve25519 arithmetic precompiles allow smart contract developers to cheaply utilize these curve operations in their smart contracts.
The
Curve25519Add
andCurve25519ScalarMul
precompiles incorrectly handle invalid Ristretto point representations. Instead of returning an error, they silently treat invalid input bytes as the Ristretto identity element, leading to potentially incorrect cryptographic results. Inframe/evm/precompile/curve25519/src/lib.rs
, when processing input points for both addition and scalar multiplication, in the execute function, the code attempts to decompress the 32-byte input usingpoint.decompress().
If the input bytes do not represent a valid compressed Ristretto point,decompress()
returnsNone
. However, the code usesunwrap_or_else(RistrettoPoint::identity)
, which replaces this None result with theRistrettoPoint::identity()
element without signalling any error to the caller.Silently treating invalid cryptographic points as the identity element could introduce critical vulnerabilities in smart contracts. This behavior could compromise confidentiality in key exchanges or allow threshold signature requirements to be bypassed. For example, in a multi-signature scheme, an attacker could submit an invalid compressed Ristretto point as a public key. Treated as the identity element, it would be incorrectly counted toward the signing threshold, enabling signature forgery with fewer valid participants.
Patches
The issue is fixed by PR 1720.
Notes on severity
In the audit by SRLabs, this issue is classified with "Medium" severity. However, we believe it's a critical severity advisory because it can bypass a smart contract's security assumptions.
It is therefore recommended that an emergency runtime upgrade to be issued if you use
Curve25519Add
orCurve25519ScalarMul
precompiles.Credits
This issue is discovered in a security audit by SRLabs with the Moonbeam team. Polkadot Assurance Legion (PAL) financially contributed to the security audit.