Skip to content

Commit bf3b835

Browse files
committed
add SIMD-372
1 parent c971c20 commit bf3b835

1 file changed

Lines changed: 205 additions & 0 deletions

File tree

proposals/0371-verify-strict.md

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
---
2+
simd: '0372'
3+
title: Relaxing Transaction Signature Verification
4+
authors:
5+
- David Rubin (Syndica)
6+
category: Standard
7+
type: Core
8+
status: Review
9+
created: 2025-10-06
10+
feature: (fill in with feature tracking issues once accepted)
11+
---
12+
13+
## Summary
14+
15+
This proposal replaces the `verify_strict` semantics used in Solana, derived
16+
from Agave's usage of `ed25519-dalek`'s `verify_strict`, with
17+
[ZIP-215](https://zips.z.cash/zip-0215), Zebra's EdDSA variant. In practice,
18+
this removes the $R$ and $A$ torsion checks, multiplies the verification
19+
equation by the cofactor, and makes verification insensitive to torsion
20+
elements. This change enables batch verification of transaction signatures,
21+
improves validator efficiency, and standardizes consensus behaviour across
22+
implementations.
23+
24+
## Motivation
25+
26+
Two main factors motivate this proposed change.
27+
28+
1. Today, Solana validators must perfectly replicate the behaviour of
29+
`verify_strict`, a function implemented in the `ed25519-dalek` library.
30+
This forces validators written in other languages, or ones that do not
31+
wish to use this library for better diversity, to re-implement the exact
32+
semantics. While this will always be the case, due to transaction verification
33+
being part of consensus, this proposal suggests using a better proven
34+
verification equation, which is better described,
35+
rather than the implicit behaviour found in the `ed25519-dalek` library.
36+
37+
2. `verify_strict` rejects small-order `R`, which makes batch verification
38+
impossible. Batched verification can reduce costs by ~40% for large
39+
signatures batches, which is significant at Solana's scale, where validators
40+
process hundreds of thousands of signatures every block.
41+
42+
## New Terminology
43+
44+
- Strict Verification: Ed25519 verification that explicitly rejects both public
45+
keys and ephemeral points in the signature ($A$ and $R$) with torsion
46+
components.
47+
- Cofactored Verification: A scheme where the entire verification equation
48+
is multiplied by the curve's cofactor (8), rendering torsion elements irrelevant
49+
while preserving security.
50+
- Batch Verification: Verifying many signatures together via random linear
51+
combination and a multi-scalar multiplication.
52+
53+
## Detailed Design
54+
55+
Switch to using the verification equation described in
56+
[ZIP-215](https://zips.z.cash/zip-0215) for Ed25519 EdDSA signature
57+
verification.
58+
59+
### Algorithm:
60+
61+
Given a message $M$, public key $A$, signature ephemeral point $R$, and
62+
scalar $S$.
63+
64+
1. Reject the signature if $`S \notin \{0, ..., L - 1\}`$.
65+
2. Compute the hash $\text{SHA512}(R \|\| A \|\| M)$ and reduce it
66+
$\bmod L$ to get scalar $h$.
67+
3. Given that $B$ is the Ed25519 basepoint, accept the signature if:
68+
69+
```math
70+
8(S \cdot B) - 8R - 8(h \cdot A) = \mathcal{O}
71+
```
72+
73+
Note that non-canonical $R$ and $A$ points *are allowed*. Honest parties
74+
will generate their keys according to the protocol, which in this case
75+
would be [RFC-8032](https://www.rfc-editor.org/rfc/rfc8032.html#section-5.1.6)'s
76+
definition of `sign`. As this does not produce non-canonical encodings of
77+
points, the honest parties will be unaffected, and it will only affect parties
78+
that purposefully create special signatures.
79+
80+
### Application:
81+
82+
This proposal specifically targets usages of `verify_strict`, replacing
83+
them with the Algorithm described above. This includes replacing the equation
84+
used for verification of transaction signatures, gossip packet signatures, shred
85+
packet signatures, and the Ed25519 precompile program.
86+
87+
Section 3.2 of [Taming the many EdDSAs](https://eprint.iacr.org/2020/1244.pdf)
88+
explains the relationship between batched and single cofactored verifications,
89+
proving them to be compatible. As a result, they can be used interchangeable,
90+
in use cases such as optimizing transaction signature verification.
91+
92+
## Alternatives Considered
93+
94+
- `ed25519-dalek`'s `verify`: Another option would be to just downgrade the
95+
check from `verify_strict` to `verify`. This would also be backwards compatible,
96+
however there are a few issues with this approach. It is not possible to
97+
perform a compatible batched verification of a cofactorless verification
98+
equation with some sort of incompatibility, leading back to the original issue.
99+
Our only option would be to define the protocol in terms of the batched
100+
verification equation's behaviour which is not preferable.
101+
102+
- *Taming the many EdDSAs* equation: The paper describes a cofactored
103+
verification scheme very similar to ZIP-215, the only difference being
104+
that small-order $A$ points are rejected. This allows their scheme to achieve
105+
strongly binding signatures, a property that does not affect Solana. We prefer
106+
using ZIP-215 as it has a well-proven Rust library,
107+
[ed25519-zebra](https://github.com/ZcashFoundation/ed25519-zebra),
108+
that would allow easier migration for Agave.
109+
110+
## Impact
111+
112+
- Dapp developers: No required changes, signatures already generated remain
113+
valid.
114+
- Validators: Lower CPU usage, faster verification pipelines.
115+
- Core Contributors: A more clear, standardized implementation for new validator
116+
clients and other software potentially performing transaction
117+
118+
## Security Considerations
119+
120+
There are two important qualities an EdDSA scheme can have.
121+
122+
- Strongly Binding Signatures (SBS): A signature scheme is *strongly binding*
123+
if each valid signature corresponds to exactly one valid message, i.e there
124+
is no "malleability" in the verification equation.
125+
- Strong Unforgeability under Chosen Message Attack (SUF-CMA): A signature
126+
scheme is SUF-CMA secure if an attacker cannot create *any* new valid signature,
127+
even on a message that has been signed before. In other words, they can't
128+
"malleate" an existing signature into another distinct, valid one.
129+
130+
The only quality that Solana worries about is SUF-CMA (as opposed to EUF-CMA),
131+
which ZIP-215 achieves by rejecting $S$ scalars which do not fit into $l$.
132+
133+
## Backwards Compatibility
134+
135+
- All signatures valid under `verify_strict` remain valid under ZIP-215
136+
verification.
137+
- A small class of signatures previously rejected may now be accepted.
138+
139+
This upgrade should be possible to do with two seperate feature gates. The
140+
first one will be to use both verification equations, and once enough
141+
stake has migrated, we can then disable the `verify_strict` one through
142+
another feature gate. This is still up for discussion though, while it
143+
should definitely be doable, it will require a bit of careful thought on how.
144+
145+
Here is a proof that any signature that `verify_strict` accepts would
146+
be accepted by the new verification equation as well:
147+
148+
### Lemma:
149+
150+
Consider the `verify_strict` equation (E) to be:
151+
152+
```math
153+
S \cdot B - h \cdot A = R
154+
```
155+
156+
where $B$ is the base point, $A$ is the public key point,
157+
$R$ is the ephemeral point, $S$ is the signature scalar and
158+
$h = \text{SHA512}(R \|\| A \|\| M) \bmod L$.
159+
160+
Assume `verify_strict` accepts a signature, where
161+
162+
1. The above equation (E) holds in the Edwards25519 group.
163+
2. $S$ is canonical and $`S \in \{0, ..., L - 1\}`$.
164+
3. $A$ is canonical and *not* a small-order point.
165+
4. $R$ is canonical and *not* a small-order point.
166+
167+
Then the new verification equation (C):
168+
169+
```math
170+
8(S \cdot B) - 8R - 8(h \cdot A) = \mathcal{O}
171+
```
172+
173+
also holds; therefore a new verifier that enforces (2), and the equation (C),
174+
will accept the signature.
175+
176+
### Proof:
177+
178+
Start from (E):
179+
180+
```math
181+
S \cdot B - h \cdot A = R
182+
```
183+
184+
This can be rewritten as:
185+
186+
```math
187+
S \cdot B - R - h \cdot A = \mathcal{O}
188+
```
189+
190+
Apply scalar multiplication by the cofactor (8). Since scalar multiplication
191+
is linear and the group law applies:
192+
193+
```math
194+
[8](S \cdot B - R - h \cdot A) = [8]\mathcal{O}
195+
```
196+
197+
If you distribute $[8]$ across the sum:
198+
199+
```math
200+
8(S \cdot B) - 8R - 8(h \cdot A) = \mathcal{O}
201+
```
202+
203+
which is exactly the equation (C). Therefore, assuming that $S$ is properly
204+
checked, the new verification equation should never reject a signature accepted
205+
by `verify_strict`.

0 commit comments

Comments
 (0)