move all curve25519 related crates into curve25519 directory (#5)

This commit is contained in:
Sam Kim 2026-03-24 20:42:07 +09:00 committed by GitHub
parent e56e48a473
commit 8024e4ed31
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
116 changed files with 802 additions and 800 deletions

View file

@ -1,11 +1,12 @@
[workspace]
members = [
"curve25519-cuda",
"curve25519",
"curve25519-derive",
"ed25519-heea",
members = [
"curve25519/curve25519-cuda",
"curve25519/curve25519",
"curve25519/curve25519-derive",
"curve25519/ed25519-heea",
]
resolver = "2"
[profile.dev]
opt-level = 2
opt-level = 2

201
LICENSE
View file

@ -1,201 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

137
README.md
View file

@ -1,137 +0,0 @@
# curve25519-sol
A high-performance, opinionated fork of [curve25519-dalek] and [ed25519-zebra] focused on
accelerated Ed25519 signature verification via the **HEEA** (Half-Extended Euclidean Algorithm)
method and a reduced set of well-tested backends.
> Original library READMEs: [README_dalek.md](README_dalek.md) (workspace) ·
> [curve25519/README_dalek.md](curve25519/README_dalek.md) ·
> [ed25519-heea/README_zebra.md](ed25519-heea/README_zebra.md)
---
## Crates
| Crate | Description |
|---|---|
| [`curve25519`](./curve25519) | Fork of `curve25519-dalek`. Core elliptic-curve arithmetic over Curve25519, Edwards, Ristretto, and Short-Weierstrass forms, with HEEA scalar decomposition and a narrowed backend set (removed `u32` and constraint device supports). |
| [`ed25519-heea`](./ed25519-heea) | Fork of `ed25519-zebra`. ZIP-215-compliant Ed25519 with an added `verify_heea` fast-path that uses HEEA half-size scalars. |
| [`curve25519-cuda`](./curve25519-cuda) | GPU-accelerated multi-scalar multiplication (MSM) via CUDA/SPPARK. Falls back to CPU when CUDA is unavailable. |
| [`curve25519-derive`](./curve25519-derive) | Helper proc-macro crate (`#[unsafe_target_feature]`) inherited from upstream; required to write clean SIMD code. Identical to the one in dalek 0.5.0 |
---
## Key Changes from Upstream
### HEEA Signature Verification
Standard Ed25519 verification checks **sB = R + hA**, where `h` is a 256-bit scalar.
HEEA (from the TCHES 2025 paper _"Accelerating EdDSA Signature Verification with Faster Scalar
Size Halving"_) transforms this into a 4-point MSM with ~128-bit scalars:
```
τs_lo · B + τs_hi · (2¹²⁸·B) = τ·R + ρ·A
```
where `ρ` and `τ` are half-size (~127-bit) values derived from `h` via a half-extended
Euclidean algorithm, and `τs = τs_hi · 2¹²⁸ + τs_lo`. All four scalars are ≤128 bits, and
two of the bases (`B` and `2¹²⁸B`) use precomputed tables. In practice this yields roughly
**~15% faster** verification compared to the standard double-scalar-multiplication path.
The algorithm is implemented in:
- [`curve25519/src/scalar/heea.rs`](curve25519/src/scalar/heea.rs) `curve25519_heea_vartime`
- [`curve25519/src/traits.rs`](curve25519/src/traits.rs) `HEEADecomposition` trait
- [`curve25519/src/backend/serial/scalar_mul/vartime_triple_base.rs`](curve25519/src/backend/serial/scalar_mul/vartime_triple_base.rs) optimised 128+128+256 MSM
- [`ed25519-heea/src/verification_key.rs`](ed25519-heea/src/verification_key.rs) `VerificationKey::verify_heea`
### Reduced Backend Set
Upstream `curve25519-dalek` supports serial, fiat-crypto, AVX2, and unstable AVX512 backends.
This fork retains only the backends actively tested and maintained here:
| Backend | Platform | Selection |
|---|---|---|
| `serial` | All (macOS, Linux, …) | Automatic fallback |
| `simd` / AVX2 | x86-64 with AVX2 | Runtime CPU detection |
| CUDA (separate crate) | NVIDIA GPU | Opt-in via `curve25519-cuda` |
The `fiat` (formally-verified) and `unstable_avx512` backends have been removed to reduce
maintenance surface. If you need them, use upstream `curve25519-dalek` directly.
---
## Usage
Add the relevant crate to `Cargo.toml`:
```toml
# Core curve arithmetic with HEEA
curve25519-sol = { git = "https://github.com/zz-sol/ed25519-sol" }
# Ed25519 signatures with fast HEEA verification
ed25519-heea = { git = "https://github.com/zz-sol/ed25519-sol" }
```
### Standard Ed25519 verification
```rust
use ed25519_heea::{SigningKey, VerificationKey};
use rand::thread_rng;
let msg = b"hello world";
let sk = SigningKey::new(thread_rng());
let sig = sk.sign(msg);
let vk = VerificationKey::from(&sk);
// Standard ZIP-215-compliant verification
vk.verify(&sig, msg).expect("valid signature");
```
### HEEA-accelerated verification
```rust
// Fast path: ~15% faster via half-size scalars (same result)
vk.verify_heea(&sig, msg).expect("valid signature");
```
---
## Building
```sh
# Standard build
cargo build --release
# With AVX2 (automatic on x86-64 at runtime; or force compile-time)
RUSTFLAGS='-C target-feature=+avx2' cargo build --release
# Run benchmarks
cargo bench --features "rand_core" -p curve25519
cargo bench -p ed25519-heea
```
---
## References
- [Accelerating EdDSA Signature Verification with Faster Scalar Size Halving](https://tches.iacr.org/index.php/TCHES/article/view/11971) — TCHES 2025
- [ZIP 215](https://zips.z.cash/zip-0215) — Ed25519 validation rules used by Zcash
- [curve25519-dalek](https://github.com/dalek-cryptography/curve25519-dalek) — upstream curve library
- [ed25519-zebra](https://github.com/ZcashFoundation/ed25519-zebra) — upstream signature library
---
## License
Licensed under either of
- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
at your option.
Portions of this library are derived from [curve25519-dalek] (isis lovecruft, Henry de Valence)
and [ed25519-zebra] (Zcash Foundation), both dual-licensed MIT/Apache-2.0.
[curve25519-dalek]: https://github.com/dalek-cryptography/curve25519-dalek
[ed25519-zebra]: https://github.com/ZcashFoundation/ed25519-zebra

View file

@ -1,31 +0,0 @@
<p align="center">
<img
alt="dalek-cryptography logo: a dalek with edwards curves as sparkles coming out of its radar-schnozzley blaster thingies"
width="200px"
src="https://cdn.jsdelivr.net/gh/dalek-cryptography/curve25519/docs/assets/dalek-logo-clear.png"/>
</p>
# Dalek elliptic curve cryptography
This repo contains pure-Rust crates for elliptic curve cryptography:
| Crate | Description | Crates.io | Docs | CI |
-------------------------------------------|----------------|-----------|------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| [`curve25519dalek`](./curve25519) | A library for arithmetic over the Curve25519 and Ristretto elliptic curves and their associated scalars. | [![](https://img.shields.io/crates/v/curve25519.svg)](https://crates.io/crates/curve25519) | [![](https://img.shields.io/docsrs/curve25519)](https://docs.rs/curve25519) | [![CI](https://github.com/dalek-cryptography/curve25519/actions/workflows/curve25519.yml/badge.svg?branch=main)](https://github.com/dalek-cryptography/curve25519/actions/workflows/curve25519.yml) |
| [`ed25519dalek`](./ed25519-dalek) | An implementation of the EdDSA digital signature scheme over Curve25519. | [![](https://img.shields.io/crates/v/ed25519-dalek.svg)](https://crates.io/crates/ed25519-dalek) | [![](https://docs.rs/ed25519-dalek/badge.svg)](https://docs.rs/ed25519-dalek) | [![CI](https://github.com/dalek-cryptography/curve25519/actions/workflows/ed25519-dalek.yml/badge.svg?branch=main)](https://github.com/dalek-cryptography/curve25519/actions/workflows/ed25519-dalek.yml) |
| [`x25519dalek`](./x25519-dalek) | An implementation of elliptic curve Diffie-Hellman key exchange over Curve25519. | [![](https://img.shields.io/crates/v/x25519-dalek.svg)](https://crates.io/crates/x25519-dalek) | [![](https://docs.rs/x25519-dalek/badge.svg)](https://docs.rs/x25519-dalek) | [![CI](https://github.com/dalek-cryptography/curve25519/actions/workflows/x25519-dalek.yml/badge.svg?branch=main)](https://github.com/dalek-cryptography/curve25519/actions/workflows/x25519-dalek.yml) |
There is also the [`curve25519-derive`](./curve25519-derive) crate, which is just a helper crate with some macros that make curve25519 easier to write.
# Contributing
Please see [`CONTRIBUTING.md`](./CONTRIBUTING.md).
# Code of Conduct
We follow the [Rust Code of Conduct](http://www.rust-lang.org/conduct.html),
with the following additional clauses:
* We respect the rights to privacy and anonymity for contributors and people in
the community. If someone wishes to contribute under a pseudonym different to
their primary identity, that wish is to be respected by all contributors.

View file

@ -1,29 +1,201 @@
Copyright (c) 2016-2021 isis agora lovecruft. All rights reserved.
Copyright (c) 2016-2021 Henry de Valence. All rights reserved.
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
1. Definitions.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View file

@ -1,144 +1,137 @@
# curve25519 (curve25519-sol)
# curve25519-sol
**A pure-Rust implementation of group operations on Ristretto and Curve25519, forked from
[curve25519-dalek] with HEEA scalar decomposition and a reduced backend set.**
A high-performance, opinionated fork of [curve25519-dalek] and [ed25519-zebra] focused on
accelerated Ed25519 signature verification via the **HEEA** (Half-Extended Euclidean Algorithm)
method and a reduced set of well-tested backends.
> For the original curve25519-dalek documentation see [README_dalek.md](README_dalek.md).
This crate is part of the [curve25519-sol](../README.md) workspace.
> Original library READMEs: [README_dalek.md](README_dalek.md) (workspace) ·
> [curve25519/README_dalek.md](curve25519/README_dalek.md) ·
> [ed25519-heea/README_zebra.md](ed25519-heea/README_zebra.md)
---
## Changes from curve25519-dalek
## Crates
### HEEA Scalar Decomposition
| Crate | Description |
|---|---|
| [`curve25519`](./curve25519) | Fork of `curve25519-dalek`. Core elliptic-curve arithmetic over Curve25519, Edwards, Ristretto, and Short-Weierstrass forms, with HEEA scalar decomposition and a narrowed backend set (removed `u32` and constraint device supports). |
| [`ed25519-heea`](./ed25519-heea) | Fork of `ed25519-zebra`. ZIP-215-compliant Ed25519 with an added `verify_heea` fast-path that uses HEEA half-size scalars. |
| [`curve25519-cuda`](./curve25519-cuda) | GPU-accelerated multi-scalar multiplication (MSM) via CUDA/SPPARK. Falls back to CPU when CUDA is unavailable. |
| [`curve25519-derive`](./curve25519-derive) | Helper proc-macro crate (`#[unsafe_target_feature]`) inherited from upstream; required to write clean SIMD code. Identical to the one in dalek 0.5.0 |
A new `HEEADecomposition` trait and implementation have been added in:
---
- [`src/scalar/heea.rs`](src/scalar/heea.rs) `curve25519_heea_vartime`, the core
half-extended Euclidean algorithm
- [`src/traits.rs`](src/traits.rs) `HEEADecomposition` trait (`heea_decompose`)
- [`src/backend/serial/scalar_mul/vartime_triple_base.rs`](src/backend/serial/scalar_mul/vartime_triple_base.rs)
`mul_128_128_256`, a four-variable MSM optimised for two 128-bit and one 256-bit scalar
## Key Changes from Upstream
Given a 256-bit hash scalar `h`, `heea_decompose` returns `(ρ, τ, flip_h)` such that:
### HEEA Signature Verification
```text
ρ ≡ ±τ·h (mod ) // ρ and τ are both ≤ 128 bits
Standard Ed25519 verification checks **sB = R + hA**, where `h` is a 256-bit scalar.
HEEA (from the TCHES 2025 paper _"Accelerating EdDSA Signature Verification with Faster Scalar
Size Halving"_) transforms this into a 4-point MSM with ~128-bit scalars:
```
τs_lo · B + τs_hi · (2¹²⁸·B) = τ·R + ρ·A
```
This allows verification of `sB = R + hA` to be rewritten as a 4-point MSM over ~128-bit
scalars, reducing the number of point doublings required and yielding roughly **~15% faster**
verification in practice.
where `ρ` and `τ` are half-size (~127-bit) values derived from `h` via a half-extended
Euclidean algorithm, and `τs = τs_hi · 2¹²⁸ + τs_lo`. All four scalars are ≤128 bits, and
two of the bases (`B` and `2¹²⁸B`) use precomputed tables. In practice this yields roughly
**~15% faster** verification compared to the standard double-scalar-multiplication path.
See the [TCHES 2025 paper] for the full algorithm description.
The algorithm is implemented in:
- [`curve25519/src/scalar/heea.rs`](curve25519/src/scalar/heea.rs) `curve25519_heea_vartime`
- [`curve25519/src/traits.rs`](curve25519/src/traits.rs) `HEEADecomposition` trait
- [`curve25519/src/backend/serial/scalar_mul/vartime_triple_base.rs`](curve25519/src/backend/serial/scalar_mul/vartime_triple_base.rs) optimised 128+128+256 MSM
- [`ed25519-heea/src/verification_key.rs`](ed25519-heea/src/verification_key.rs) `VerificationKey::verify_heea`
### Reduced Backends
### Reduced Backend Set
Only the following backends are maintained in this fork:
Upstream `curve25519-dalek` supports serial, fiat-crypto, AVX2, and unstable AVX512 backends.
This fork retains only the backends actively tested and maintained here:
| Backend | Selection | Notes |
| Backend | Platform | Selection |
|---|---|---|
| `serial` | Automatic fallback | Pure Rust, 64-bit word size on 64-bit targets |
| `simd` / AVX2 | Runtime on x86-64 | Vectorised 4-wide field arithmetic |
| CUDA | Opt-in (`curve25519-cuda` crate) | GPU MSM via SPPARK/BLST |
| `serial` | All (macOS, Linux, …) | Automatic fallback |
| `simd` / AVX2 | x86-64 with AVX2 | Runtime CPU detection |
| CUDA (separate crate) | NVIDIA GPU | Opt-in via `curve25519-cuda` |
The `fiat` (formally-verified fiat-crypto) and `unstable_avx512` backends present in upstream
have been removed.
The `fiat` (formally-verified) and `unstable_avx512` backends have been removed to reduce
maintenance surface. If you need them, use upstream `curve25519-dalek` directly.
---
## Use
## Usage
Add the relevant crate to `Cargo.toml`:
```toml
# Core curve arithmetic with HEEA
curve25519-sol = { git = "https://github.com/zz-sol/ed25519-sol" }
# Ed25519 signatures with fast HEEA verification
ed25519-heea = { git = "https://github.com/zz-sol/ed25519-sol" }
```
### HEEA decomposition example
### Standard Ed25519 verification
```rust,ignore
use curve25519::traits::HEEADecomposition;
use curve25519::scalar::Scalar;
use sha2::{Sha512, Digest};
```rust
use ed25519_heea::{SigningKey, VerificationKey};
use rand::thread_rng;
// h is a typical 256-bit hash scalar
let h = Scalar::from_hash(Sha512::new().chain_update(b"some message"));
let msg = b"hello world";
let sk = SigningKey::new(thread_rng());
let sig = sk.sign(msg);
let vk = VerificationKey::from(&sk);
// Decompose into two ~128-bit scalars
let (rho, tau, flip_h) = h.heea_decompose();
// rho ≡ ±tau·h (mod )
// Standard ZIP-215-compliant verification
vk.verify(&sig, msg).expect("valid signature");
```
### HEEA-accelerated verification
```rust
// Fast path: ~15% faster via half-size scalars (same result)
vk.verify_heea(&sig, msg).expect("valid signature");
```
---
## Feature Flags
The feature flags are inherited from upstream with no additions:
| Feature | Default? | Description |
|---|:---:|---|
| `alloc` | ✓ | Multiscalar multiplication, batch inversion, batch compress. |
| `zeroize` | ✓ | `Zeroize` for all scalar and point types. |
| `precomputed-tables` | ✓ | Precomputed basepoint tables (~400 KB, ~4× faster basepoint mul). |
| `rand_core` | | `Scalar::random`, `RistrettoPoint::random`. |
| `digest` | | Hash-to-curve and `Scalar::from_hash`. |
| `serde` | | Serialization for all point and scalar types. |
| `legacy_compatibility` | | `Scalar::from_bits` (broken arithmetic, use only if required). |
| `group` | | `group` and `ff` crate trait impls. |
| `group-bits` | | `ff::PrimeFieldBits` for `Scalar`. |
| `lizard` | | Bytestring-to-Ristretto-point injection. |
---
## Backends
### Serial (default)
Pure-Rust, available on all targets. 64-bit arithmetic on 64-bit platforms.
### AVX2 (automatic on x86-64)
Runtime CPU-feature detection via `cpufeatures`. 4-wide vectorised field elements in
radix-25.5 representation. Automatically selected when the CPU supports AVX2; falls through to
`serial` otherwise.
To hard-code AVX2 at compile time:
## Building
```sh
# Standard build
cargo build --release
# With AVX2 (automatic on x86-64 at runtime; or force compile-time)
RUSTFLAGS='-C target-feature=+avx2' cargo build --release
# Run benchmarks
cargo bench --features "rand_core" -p curve25519
cargo bench -p ed25519-heea
```
### CUDA (opt-in)
See the [`curve25519-cuda`](../curve25519-cuda) crate. Provides GPU-accelerated
multi-scalar multiplication using the [SPPARK] library.
---
## Safety
All point types enforce validity invariants at the type level (no invalid `EdwardsPoint` can be
constructed). All secret-operand operations use constant-time logic via the [`subtle`] crate.
Variable-time functions are explicitly marked `vartime`.
The SIMD backend uses `unsafe` internally for SIMD intrinsics, guarded by runtime CPU-feature
checks.
---
## MSRV
Rust **1.85.0** (Edition 2024).
---
## References
- [TCHES 2025 paper] _Accelerating EdDSA Signature Verification with Faster Scalar Size Halving_
- [curve25519-dalek] upstream library (isis lovecruft, Henry de Valence)
- [Original curve25519-dalek README](README_dalek.md)
- [Accelerating EdDSA Signature Verification with Faster Scalar Size Halving](https://tches.iacr.org/index.php/TCHES/article/view/11971) — TCHES 2025
- [ZIP 215](https://zips.z.cash/zip-0215) — Ed25519 validation rules used by Zcash
- [curve25519-dalek](https://github.com/dalek-cryptography/curve25519-dalek) — upstream curve library
- [ed25519-zebra](https://github.com/ZcashFoundation/ed25519-zebra) — upstream signature library
---
## License
Licensed under either of
- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
at your option.
Portions of this library are derived from [curve25519-dalek] (isis lovecruft, Henry de Valence)
and [ed25519-zebra] (Zcash Foundation), both dual-licensed MIT/Apache-2.0.
[TCHES 2025 paper]: https://tches.iacr.org/index.php/TCHES/article/view/11971
[curve25519-dalek]: https://github.com/dalek-cryptography/curve25519-dalek
[SPPARK]: https://github.com/supranational/sppark
[subtle]: https://docs.rs/subtle
[ed25519-zebra]: https://github.com/ZcashFoundation/ed25519-zebra

View file

@ -1,6 +1,3 @@
# curve25519 [![](https://buildstats.info/crate/curve25519)](https://crates.io/crates/curve25519) [![](https://img.shields.io/docsrs/curve25519)](https://docs.rs/curve25519) [![CI](https://github.com/dalek-cryptography/curve25519/actions/workflows/curve25519.yml/badge.svg?branch=main)](https://github.com/dalek-cryptography/curve25519/actions/workflows/curve25519.yml)
<p align="center">
<img
alt="dalek-cryptography logo: a dalek with edwards curves as sparkles coming out of its radar-schnozzley blaster thingies"
@ -8,310 +5,27 @@
src="https://cdn.jsdelivr.net/gh/dalek-cryptography/curve25519/docs/assets/dalek-logo-clear.png"/>
</p>
**A pure-Rust implementation of group operations on Ristretto and Curve25519.**
# Dalek elliptic curve cryptography
`curve25519` is a library providing group operations on the Edwards and
Montgomery forms of Curve25519, and on the prime-order Ristretto group.
This repo contains pure-Rust crates for elliptic curve cryptography:
`curve25519` is not intended to provide implementations of any particular
crypto protocol. Rather, implementations of those protocols (such as
[`x25519-dalek`][x25519-dalek] and [`ed25519-dalek`][ed25519-dalek]) should use
`curve25519` as a library.
| Crate | Description | Crates.io | Docs | CI |
-------------------------------------------|----------------|-----------|------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| [`curve25519dalek`](./curve25519) | A library for arithmetic over the Curve25519 and Ristretto elliptic curves and their associated scalars. | [![](https://img.shields.io/crates/v/curve25519.svg)](https://crates.io/crates/curve25519) | [![](https://img.shields.io/docsrs/curve25519)](https://docs.rs/curve25519) | [![CI](https://github.com/dalek-cryptography/curve25519/actions/workflows/curve25519.yml/badge.svg?branch=main)](https://github.com/dalek-cryptography/curve25519/actions/workflows/curve25519.yml) |
| [`ed25519dalek`](./ed25519-dalek) | An implementation of the EdDSA digital signature scheme over Curve25519. | [![](https://img.shields.io/crates/v/ed25519-dalek.svg)](https://crates.io/crates/ed25519-dalek) | [![](https://docs.rs/ed25519-dalek/badge.svg)](https://docs.rs/ed25519-dalek) | [![CI](https://github.com/dalek-cryptography/curve25519/actions/workflows/ed25519-dalek.yml/badge.svg?branch=main)](https://github.com/dalek-cryptography/curve25519/actions/workflows/ed25519-dalek.yml) |
| [`x25519dalek`](./x25519-dalek) | An implementation of elliptic curve Diffie-Hellman key exchange over Curve25519. | [![](https://img.shields.io/crates/v/x25519-dalek.svg)](https://crates.io/crates/x25519-dalek) | [![](https://docs.rs/x25519-dalek/badge.svg)](https://docs.rs/x25519-dalek) | [![CI](https://github.com/dalek-cryptography/curve25519/actions/workflows/x25519-dalek.yml/badge.svg?branch=main)](https://github.com/dalek-cryptography/curve25519/actions/workflows/x25519-dalek.yml) |
`curve25519` is intended to provide a clean and safe _mid-level_ API for use
implementing a wide range of ECC-based crypto protocols, such as key agreement,
signatures, anonymous credentials, rangeproofs, and zero-knowledge proof
systems.
In particular, `curve25519` implements Ristretto, which constructs a
prime-order group from a non-prime-order Edwards curve. This provides the
speed and safety benefits of Edwards curve arithmetic, without the pitfalls of
cofactor-related abstraction mismatches.
# Use
## Stable
To import `curve25519`, add the following to the dependencies section of
your project's `Cargo.toml`:
```toml
curve25519 = "5.0.0-pre.4"
```
If opting into [SemVer-exempted features](#public-api-semver-exemptions) a range
can be used to scope the tested compatible version range e.g.:
```toml
curve25519 = ">= 5.0, < 5.2"
```
## Feature Flags
| Feature | Default? | Description |
| :--- | :---: | :--- |
| `alloc` | ✓ | Enables Edwards and Ristretto multiscalar multiplication, batch scalar inversion, and batch Ristretto double-and-compress. |
| `zeroize` | ✓ | Enables [`Zeroize`][zeroize-trait] for all scalar and curve point types. |
| `precomputed-tables` | ✓ | Includes precomputed basepoint multiplication tables. This speeds up `EdwardsPoint::mul_base` and `RistrettoPoint::mul_base` by ~4x, at the cost of ~400KB added to the code size. |
| `rand_core` | | Enables `Scalar::random` and `RistrettoPoint::random`. This is an optional dependency whose version is not subject to SemVer. See [below](#public-api-semver-exemptions) for more details. |
| `digest` | | Enables `RistrettoPoint::{from_hash, hash_from_bytes}` and `Scalar::{from_hash, hash_from_bytes}`. Also enables hash-to-curve methods `EdwardsPoint::{encode_to_curve, hash_to_curve}`. This is an optional dependency whose version is not subject to SemVer. See [below](#public-api-semver-exemptions) for more details. |
| `serde` | | Enables `serde` serialization/deserialization for all the point and scalar types. |
| `legacy_compatibility`| | Enables `Scalar::from_bits`, which allows the user to build unreduced scalars whose arithmetic is broken. Do not use this unless you know what you're doing. |
| `group` | | Enables external `group` and `ff` crate traits. |
| `group-bits` | | Enables `group` and impls `ff::PrimeFieldBits` for `Scalar`. |
| `lizard` | | Enables the [Lizard](src/lizard/README.md) bytestring-to-point injection for `RistrettoPoint`. Specifically enables the methods `lizard_encode` and `lizard_decode`. |
To disable the default features when using `curve25519` as a dependency,
add `default-features = false` to the dependency in your `Cargo.toml`. To
disable it when running `cargo`, add the `--no-default-features` CLI flag.
## Major Version API Changes
Breaking changes for each major version release can be found in
[`CHANGELOG.md`](CHANGELOG.md), under the "Breaking changes" subheader. The
latest breaking changes in high level are below:
### Breaking changes in 5.0.0
* Update edition to 2024
* Update the MSRV from 1.60 to 1.85
* Remove deprecated functions `FieldElement::as_bytes()` and `EdwardsPoint::nonspec_map_to_curve()`
* Use constant-time equality testing for compressed Ristretto and Edwards points, rather than autoderived equality
* Undeprecate `Scalar::from_bits()`
# Backends
Curve arithmetic is implemented and used by one of the following backends:
| Backend | Selection | Implementation | Bits / Word sizes |
| :--- | :--- | :--- | :--- |
| `serial` | Automatic | An optimized, non-parllel implementation | `32` and `64` |
| `fiat` | Manual | Formally verified field arithmetic from [fiat-crypto] | `32` and `64` |
| `simd` | Automatic | Intel AVX2 accelerated backend | `64` only |
| `unstable_avx512` | Manual | Intel AVX512 IFMA accelerated backend (requires nightly) | `64` only |
At runtime, `curve25519` selects an arithmetic backend from the set of backends it was compiled to support. For Intel x86-64 targets, unless otherwise specified, it will build itself with `simd` support, and default to `serial` at runtime if the appropriate CPU features aren't detected. See [SIMD backend] for more details.
In the future, `simd` backend may be extended to cover more instruction sets. This change will be non-breaking as this is considered an implementation detail.
## Manual Backend Override
You can force the crate to compile with specific backend support, e.g., `serial` for x86-64 targets to save code size, or `fiat` to force the runtime to use verified code. To do this, set the environment variable:
```sh
RUSTFLAGS='--cfg curve25519_backend="BACKEND"'
```
Equivalently, you can write to
`~/.cargo/config`:
```toml
[build]
rustflags = ['--cfg=curve25519_backend="BACKEND"']
```
More info [here](https://doc.rust-lang.org/cargo/reference/config.html#buildrustflags).
Note for contributors: The target backends are not entirely independent of each
other. The [SIMD backend] directly depends on parts of the serial backend to
function.
## Bits / Word size
`curve25519` will automatically choose the word size for the `fiat` and
`serial` backends, based on the build target.
For example, building for a 64-bit machine, the default 64 bit word size is
automatically chosen when either the `serial` or `fiat` backend is selected.
In some targets it might be required to override the word size for better
performance.
Backend word size can be overridden for `serial` and `fiat` by setting the
environment variable:
```sh
RUSTFLAGS='--cfg curve25519_bits="SIZE"'
```
`SIZE` is `32` or `64`. As in the above section, this can also be placed
in `~/.cargo/config`.
Note: The [SIMD backend] requires a word size of 64 bits. Attempting to set bits=32 and backend=`simd` will yield a compile error.
### Cross-compilation
Because backend selection is done by target, cross-compiling will select the correct word size automatically. For example, if a x86-64 Linux machine runs the following commands, `curve25519` will be compiled with the 32-bit `serial` backend.
```console
$ sudo apt install gcc-multilib # (or whatever package manager you use)
$ rustup target add i686-unknown-linux-gnu
$ cargo build --target i686-unknown-linux-gnu
```
## SIMD backend
When the `simd` backend is selected, the AVX2 or `serial` implementation is selected automatically at runtime, depending on the currently available CPU features. Similarly, when the `unstable_avx512` backend is selected, the AVX512 implementation is selected automatically at runtime if available, or else selection falls through to the aforementioned `simd` backend logic.
For a given CPU feature, you can also specify an appropriate `-C target_feature` to build a binary which assumes the required SIMD instructions are always available. Don't do this if you don't have a good reason.
| Backend | `RUSTFLAGS` | Requires nightly? |
| :--- | :--- | :--- |
| AVX2 | `-C target_feature=+avx2` | no |
| AVX512 | `-C target_feature=+avx512ifma,+avx512vl` | yes |
To reiterate, the `simd` backend will NOT use AVX512 code under any circumstance. The only way to enable AVX512 currently is to select the `unstable_avx512` backend and use a nightly compiler.
# Documentation
The semver-stable, public-facing `curve25519` API is documented [here][docs].
## Building Docs Locally
The `curve25519` documentation requires a custom HTML header to include
KaTeX for math support. Unfortunately `cargo doc` does not currently support
this, but docs can be built using
```sh
make doc
```
for regular docs, and
```sh
make doc-internal
```
for docs that include private items.
# Maintenance Policies
All on-by-default features of this library are covered by
[semantic versioning][semver] (SemVer). SemVer exemptions are outlined below
for MSRV and public API.
## Minimum Supported Rust Version
| Releases | MSRV |
| :--- |:-------|
| 5.x | 1.85.0 |
| 4.x | 1.60.0 |
| 3.x | 1.41.0 |
From 4.x and on, MSRV changes will be accompanied by a minor version bump.
## Public API SemVer Exemptions
Breaking changes to SemVer-exempted components affecting the public API will be accompanied by
_some_ version bump. Below are the specific policies:
| Releases | Public API Component(s) | Policy |
| :--- | :--- | :--- |
| 5.x | Dependencies `group`, `digest` and `rand_core` | Minor SemVer bump |
| 4.x | Dependencies `group`, `digest` and `rand_core` | Minor SemVer bump |
# Safety
The `curve25519` types are designed to make illegal states
unrepresentable. For example, any instance of an `EdwardsPoint` is
guaranteed to hold a point on the Edwards curve, and any instance of a
`RistrettoPoint` is guaranteed to hold a valid point in the Ristretto
group.
All operations are implemented using constant-time logic (no
secret-dependent branches, no secret-dependent memory accesses),
unless specifically marked as being variable-time code.
We believe that our constant-time logic is lowered to constant-time
assembly, at least on `x86_64` targets.
As an additional guard against possible future compiler optimizations,
the `subtle` crate places an optimization barrier before every
conditional move or assignment. More details can be found in [the
documentation for the `subtle` crate][subtle_doc].
Some functionality (e.g., multiscalar multiplication or batch
inversion) requires heap allocation for temporary buffers. All
heap-allocated buffers of potentially secret data are explicitly
zeroed before release.
However, we do not attempt to zero stack data, for two reasons.
First, it's not possible to do so correctly: we don't have control
over stack allocations, so there's no way to know how much data to
wipe. Second, because `curve25519` provides a mid-level API,
the correct place to start zeroing stack data is likely not at the
entrypoints of `curve25519` functions, but at the entrypoints of
functions in other crates.
The implementation is memory-safe, and contains no significant
`unsafe` code. The SIMD backend uses `unsafe` internally to call SIMD
intrinsics. These are marked `unsafe` only because invoking them on an
inappropriate CPU would cause `SIGILL`, but the entire backend is only
invoked when the appropriate CPU features are detected at runtime, or
when the whole program is compiled with the appropriate `target_feature`s.
# Performance
Benchmarks are run using [`criterion.rs`][criterion]:
```sh
cargo bench --features "rand_core"
export RUSTFLAGS='-C target_cpu=native'
cargo +nightly bench --features "rand_core"
```
Performance is a secondary goal behind correctness, safety, and
clarity, but we aim to be competitive with other implementations.
# FFI
Unfortunately, we have no plans to add FFI to `curve25519` directly. The
reason is that we use Rust features to provide an API that maintains safety
invariants, which are not possible to maintain across an FFI boundary. For
instance, as described in the _Safety_ section above, invalid points are
impossible to construct, and this would not be the case if we exposed point
operations over FFI.
However, `curve25519` is designed as a *mid-level* API, aimed at
implementing other, higher-level primitives. Instead of providing FFI at the
mid-level, our suggestion is to implement the higher-level primitive (a
signature, PAKE, ZKP, etc) in Rust, using `curve25519` as a dependency,
and have that crate provide a minimal, byte-buffer-oriented FFI specific to
that primitive.
There is also the [`curve25519-derive`](./curve25519-derive) crate, which is just a helper crate with some macros that make curve25519 easier to write.
# Contributing
Please see [CONTRIBUTING.md][contributing].
Please see [`CONTRIBUTING.md`](./CONTRIBUTING.md).
# About
# Code of Conduct
**SPOILER ALERT:** *The Twelfth Doctor's first encounter with the Daleks is in
his second full episode, "Into the Dalek". A beleaguered ship of the "Combined
Galactic Resistance" has discovered a broken Dalek that has turned "good",
desiring to kill all other Daleks. The Doctor, Clara and a team of soldiers
are miniaturized and enter the Dalek, which the Doctor names Rusty. They
repair the damage, but accidentally restore it to its original nature, causing
it to go on the rampage and alert the Dalek fleet to the whereabouts of the
rebel ship. However, the Doctor manages to return Rusty to its previous state
by linking his mind with the Dalek's: Rusty shares the Doctor's view of the
universe's beauty, but also his deep hatred of the Daleks. Rusty destroys the
other Daleks and departs the ship, determined to track down and bring an end
to the Dalek race.*
We follow the [Rust Code of Conduct](http://www.rust-lang.org/conduct.html),
with the following additional clauses:
`curve25519` is authored by Isis Agora Lovecruft and Henry de Valence.
Portions of this library were originally a port of [Adam Langley's
Golang ed25519 library](https://github.com/agl/ed25519), which was in
turn a port of the reference `ref10` implementation. Most of this code,
including the 32-bit field arithmetic, has since been rewritten.
The fast `u32` and `u64` scalar arithmetic was implemented by Andrew Moon, and
the addition chain for scalar inversion was provided by Brian Smith. The
optimised batch inversion was contributed by Sean Bowe and Daira Hopwood.
The `no_std` and `zeroize` support was contributed by Tony Arcieri.
The formally verified `fiat_backend` integrates Rust code generated by the
[Fiat Crypto project](https://github.com/mit-plv/fiat-crypto) and was
contributed by François Garillot.
Thanks also to Ashley Hauck, Lucas Salibian, Manish Goregaokar, Jack Grigg,
Pratyush Mishra, Michael Rosenberg, @pinkforest, and countless others for their
contributions.
[ed25519-dalek]: https://github.com/dalek-cryptography/curve25519/tree/main/ed25519-dalek
[x25519-dalek]: https://github.com/dalek-cryptography/curve25519/tree/main/x25519-dalek
[docs]: https://docs.rs/curve25519/
[contributing]: https://github.com/dalek-cryptography/curve25519/blob/master/CONTRIBUTING.md
[criterion]: https://github.com/japaric/criterion.rs
[parallel_doc]: https://docs.rs/curve25519/latest/curve25519/backend/vector/index.html
[subtle_doc]: https://docs.rs/subtle
[fiat-crypto]: https://github.com/mit-plv/fiat-crypto
[semver]: https://semver.org/spec/v2.0.0.html
[rngcorestd]: https://github.com/rust-random/rand/tree/7aa25d577e2df84a5156f824077bb7f6bdf28d97/rand_core#crate-features
[zeroize-trait]: https://docs.rs/zeroize/latest/zeroize/trait.Zeroize.html
[SIMD backend]: #simd-backend
* We respect the rights to privacy and anonymity for contributors and people in
the community. If someone wishes to contribute under a pseudonym different to
their primary identity, that wish is to be respected by all contributors.

View file

@ -0,0 +1,29 @@
Copyright (c) 2016-2021 isis agora lovecruft. All rights reserved.
Copyright (c) 2016-2021 Henry de Valence. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View file

@ -0,0 +1,144 @@
# curve25519 (curve25519-sol)
**A pure-Rust implementation of group operations on Ristretto and Curve25519, forked from
[curve25519-dalek] with HEEA scalar decomposition and a reduced backend set.**
> For the original curve25519-dalek documentation see [README_dalek.md](README_dalek.md).
This crate is part of the [curve25519-sol](../README.md) workspace.
---
## Changes from curve25519-dalek
### HEEA Scalar Decomposition
A new `HEEADecomposition` trait and implementation have been added in:
- [`src/scalar/heea.rs`](src/scalar/heea.rs) `curve25519_heea_vartime`, the core
half-extended Euclidean algorithm
- [`src/traits.rs`](src/traits.rs) `HEEADecomposition` trait (`heea_decompose`)
- [`src/backend/serial/scalar_mul/vartime_triple_base.rs`](src/backend/serial/scalar_mul/vartime_triple_base.rs)
`mul_128_128_256`, a four-variable MSM optimised for two 128-bit and one 256-bit scalar
Given a 256-bit hash scalar `h`, `heea_decompose` returns `(ρ, τ, flip_h)` such that:
```text
ρ ≡ ±τ·h (mod ) // ρ and τ are both ≤ 128 bits
```
This allows verification of `sB = R + hA` to be rewritten as a 4-point MSM over ~128-bit
scalars, reducing the number of point doublings required and yielding roughly **~15% faster**
verification in practice.
See the [TCHES 2025 paper] for the full algorithm description.
### Reduced Backends
Only the following backends are maintained in this fork:
| Backend | Selection | Notes |
|---|---|---|
| `serial` | Automatic fallback | Pure Rust, 64-bit word size on 64-bit targets |
| `simd` / AVX2 | Runtime on x86-64 | Vectorised 4-wide field arithmetic |
| CUDA | Opt-in (`curve25519-cuda` crate) | GPU MSM via SPPARK/BLST |
The `fiat` (formally-verified fiat-crypto) and `unstable_avx512` backends present in upstream
have been removed.
---
## Use
```toml
curve25519-sol = { git = "https://github.com/zz-sol/ed25519-sol" }
```
### HEEA decomposition example
```rust,ignore
use curve25519::traits::HEEADecomposition;
use curve25519::scalar::Scalar;
use sha2::{Sha512, Digest};
// h is a typical 256-bit hash scalar
let h = Scalar::from_hash(Sha512::new().chain_update(b"some message"));
// Decompose into two ~128-bit scalars
let (rho, tau, flip_h) = h.heea_decompose();
// rho ≡ ±tau·h (mod )
```
---
## Feature Flags
The feature flags are inherited from upstream with no additions:
| Feature | Default? | Description |
|---|:---:|---|
| `alloc` | ✓ | Multiscalar multiplication, batch inversion, batch compress. |
| `zeroize` | ✓ | `Zeroize` for all scalar and point types. |
| `precomputed-tables` | ✓ | Precomputed basepoint tables (~400 KB, ~4× faster basepoint mul). |
| `rand_core` | | `Scalar::random`, `RistrettoPoint::random`. |
| `digest` | | Hash-to-curve and `Scalar::from_hash`. |
| `serde` | | Serialization for all point and scalar types. |
| `legacy_compatibility` | | `Scalar::from_bits` (broken arithmetic, use only if required). |
| `group` | | `group` and `ff` crate trait impls. |
| `group-bits` | | `ff::PrimeFieldBits` for `Scalar`. |
| `lizard` | | Bytestring-to-Ristretto-point injection. |
---
## Backends
### Serial (default)
Pure-Rust, available on all targets. 64-bit arithmetic on 64-bit platforms.
### AVX2 (automatic on x86-64)
Runtime CPU-feature detection via `cpufeatures`. 4-wide vectorised field elements in
radix-25.5 representation. Automatically selected when the CPU supports AVX2; falls through to
`serial` otherwise.
To hard-code AVX2 at compile time:
```sh
RUSTFLAGS='-C target-feature=+avx2' cargo build --release
```
### CUDA (opt-in)
See the [`curve25519-cuda`](../curve25519-cuda) crate. Provides GPU-accelerated
multi-scalar multiplication using the [SPPARK] library.
---
## Safety
All point types enforce validity invariants at the type level (no invalid `EdwardsPoint` can be
constructed). All secret-operand operations use constant-time logic via the [`subtle`] crate.
Variable-time functions are explicitly marked `vartime`.
The SIMD backend uses `unsafe` internally for SIMD intrinsics, guarded by runtime CPU-feature
checks.
---
## MSRV
Rust **1.85.0** (Edition 2024).
---
## References
- [TCHES 2025 paper] _Accelerating EdDSA Signature Verification with Faster Scalar Size Halving_
- [curve25519-dalek] upstream library (isis lovecruft, Henry de Valence)
- [Original curve25519-dalek README](README_dalek.md)
[TCHES 2025 paper]: https://tches.iacr.org/index.php/TCHES/article/view/11971
[curve25519-dalek]: https://github.com/dalek-cryptography/curve25519-dalek
[SPPARK]: https://github.com/supranational/sppark
[subtle]: https://docs.rs/subtle

View file

@ -0,0 +1,317 @@
# curve25519 [![](https://buildstats.info/crate/curve25519)](https://crates.io/crates/curve25519) [![](https://img.shields.io/docsrs/curve25519)](https://docs.rs/curve25519) [![CI](https://github.com/dalek-cryptography/curve25519/actions/workflows/curve25519.yml/badge.svg?branch=main)](https://github.com/dalek-cryptography/curve25519/actions/workflows/curve25519.yml)
<p align="center">
<img
alt="dalek-cryptography logo: a dalek with edwards curves as sparkles coming out of its radar-schnozzley blaster thingies"
width="200px"
src="https://cdn.jsdelivr.net/gh/dalek-cryptography/curve25519/docs/assets/dalek-logo-clear.png"/>
</p>
**A pure-Rust implementation of group operations on Ristretto and Curve25519.**
`curve25519` is a library providing group operations on the Edwards and
Montgomery forms of Curve25519, and on the prime-order Ristretto group.
`curve25519` is not intended to provide implementations of any particular
crypto protocol. Rather, implementations of those protocols (such as
[`x25519-dalek`][x25519-dalek] and [`ed25519-dalek`][ed25519-dalek]) should use
`curve25519` as a library.
`curve25519` is intended to provide a clean and safe _mid-level_ API for use
implementing a wide range of ECC-based crypto protocols, such as key agreement,
signatures, anonymous credentials, rangeproofs, and zero-knowledge proof
systems.
In particular, `curve25519` implements Ristretto, which constructs a
prime-order group from a non-prime-order Edwards curve. This provides the
speed and safety benefits of Edwards curve arithmetic, without the pitfalls of
cofactor-related abstraction mismatches.
# Use
## Stable
To import `curve25519`, add the following to the dependencies section of
your project's `Cargo.toml`:
```toml
curve25519 = "5.0.0-pre.4"
```
If opting into [SemVer-exempted features](#public-api-semver-exemptions) a range
can be used to scope the tested compatible version range e.g.:
```toml
curve25519 = ">= 5.0, < 5.2"
```
## Feature Flags
| Feature | Default? | Description |
| :--- | :---: | :--- |
| `alloc` | ✓ | Enables Edwards and Ristretto multiscalar multiplication, batch scalar inversion, and batch Ristretto double-and-compress. |
| `zeroize` | ✓ | Enables [`Zeroize`][zeroize-trait] for all scalar and curve point types. |
| `precomputed-tables` | ✓ | Includes precomputed basepoint multiplication tables. This speeds up `EdwardsPoint::mul_base` and `RistrettoPoint::mul_base` by ~4x, at the cost of ~400KB added to the code size. |
| `rand_core` | | Enables `Scalar::random` and `RistrettoPoint::random`. This is an optional dependency whose version is not subject to SemVer. See [below](#public-api-semver-exemptions) for more details. |
| `digest` | | Enables `RistrettoPoint::{from_hash, hash_from_bytes}` and `Scalar::{from_hash, hash_from_bytes}`. Also enables hash-to-curve methods `EdwardsPoint::{encode_to_curve, hash_to_curve}`. This is an optional dependency whose version is not subject to SemVer. See [below](#public-api-semver-exemptions) for more details. |
| `serde` | | Enables `serde` serialization/deserialization for all the point and scalar types. |
| `legacy_compatibility`| | Enables `Scalar::from_bits`, which allows the user to build unreduced scalars whose arithmetic is broken. Do not use this unless you know what you're doing. |
| `group` | | Enables external `group` and `ff` crate traits. |
| `group-bits` | | Enables `group` and impls `ff::PrimeFieldBits` for `Scalar`. |
| `lizard` | | Enables the [Lizard](src/lizard/README.md) bytestring-to-point injection for `RistrettoPoint`. Specifically enables the methods `lizard_encode` and `lizard_decode`. |
To disable the default features when using `curve25519` as a dependency,
add `default-features = false` to the dependency in your `Cargo.toml`. To
disable it when running `cargo`, add the `--no-default-features` CLI flag.
## Major Version API Changes
Breaking changes for each major version release can be found in
[`CHANGELOG.md`](CHANGELOG.md), under the "Breaking changes" subheader. The
latest breaking changes in high level are below:
### Breaking changes in 5.0.0
* Update edition to 2024
* Update the MSRV from 1.60 to 1.85
* Remove deprecated functions `FieldElement::as_bytes()` and `EdwardsPoint::nonspec_map_to_curve()`
* Use constant-time equality testing for compressed Ristretto and Edwards points, rather than autoderived equality
* Undeprecate `Scalar::from_bits()`
# Backends
Curve arithmetic is implemented and used by one of the following backends:
| Backend | Selection | Implementation | Bits / Word sizes |
| :--- | :--- | :--- | :--- |
| `serial` | Automatic | An optimized, non-parllel implementation | `32` and `64` |
| `fiat` | Manual | Formally verified field arithmetic from [fiat-crypto] | `32` and `64` |
| `simd` | Automatic | Intel AVX2 accelerated backend | `64` only |
| `unstable_avx512` | Manual | Intel AVX512 IFMA accelerated backend (requires nightly) | `64` only |
At runtime, `curve25519` selects an arithmetic backend from the set of backends it was compiled to support. For Intel x86-64 targets, unless otherwise specified, it will build itself with `simd` support, and default to `serial` at runtime if the appropriate CPU features aren't detected. See [SIMD backend] for more details.
In the future, `simd` backend may be extended to cover more instruction sets. This change will be non-breaking as this is considered an implementation detail.
## Manual Backend Override
You can force the crate to compile with specific backend support, e.g., `serial` for x86-64 targets to save code size, or `fiat` to force the runtime to use verified code. To do this, set the environment variable:
```sh
RUSTFLAGS='--cfg curve25519_backend="BACKEND"'
```
Equivalently, you can write to
`~/.cargo/config`:
```toml
[build]
rustflags = ['--cfg=curve25519_backend="BACKEND"']
```
More info [here](https://doc.rust-lang.org/cargo/reference/config.html#buildrustflags).
Note for contributors: The target backends are not entirely independent of each
other. The [SIMD backend] directly depends on parts of the serial backend to
function.
## Bits / Word size
`curve25519` will automatically choose the word size for the `fiat` and
`serial` backends, based on the build target.
For example, building for a 64-bit machine, the default 64 bit word size is
automatically chosen when either the `serial` or `fiat` backend is selected.
In some targets it might be required to override the word size for better
performance.
Backend word size can be overridden for `serial` and `fiat` by setting the
environment variable:
```sh
RUSTFLAGS='--cfg curve25519_bits="SIZE"'
```
`SIZE` is `32` or `64`. As in the above section, this can also be placed
in `~/.cargo/config`.
Note: The [SIMD backend] requires a word size of 64 bits. Attempting to set bits=32 and backend=`simd` will yield a compile error.
### Cross-compilation
Because backend selection is done by target, cross-compiling will select the correct word size automatically. For example, if a x86-64 Linux machine runs the following commands, `curve25519` will be compiled with the 32-bit `serial` backend.
```console
$ sudo apt install gcc-multilib # (or whatever package manager you use)
$ rustup target add i686-unknown-linux-gnu
$ cargo build --target i686-unknown-linux-gnu
```
## SIMD backend
When the `simd` backend is selected, the AVX2 or `serial` implementation is selected automatically at runtime, depending on the currently available CPU features. Similarly, when the `unstable_avx512` backend is selected, the AVX512 implementation is selected automatically at runtime if available, or else selection falls through to the aforementioned `simd` backend logic.
For a given CPU feature, you can also specify an appropriate `-C target_feature` to build a binary which assumes the required SIMD instructions are always available. Don't do this if you don't have a good reason.
| Backend | `RUSTFLAGS` | Requires nightly? |
| :--- | :--- | :--- |
| AVX2 | `-C target_feature=+avx2` | no |
| AVX512 | `-C target_feature=+avx512ifma,+avx512vl` | yes |
To reiterate, the `simd` backend will NOT use AVX512 code under any circumstance. The only way to enable AVX512 currently is to select the `unstable_avx512` backend and use a nightly compiler.
# Documentation
The semver-stable, public-facing `curve25519` API is documented [here][docs].
## Building Docs Locally
The `curve25519` documentation requires a custom HTML header to include
KaTeX for math support. Unfortunately `cargo doc` does not currently support
this, but docs can be built using
```sh
make doc
```
for regular docs, and
```sh
make doc-internal
```
for docs that include private items.
# Maintenance Policies
All on-by-default features of this library are covered by
[semantic versioning][semver] (SemVer). SemVer exemptions are outlined below
for MSRV and public API.
## Minimum Supported Rust Version
| Releases | MSRV |
| :--- |:-------|
| 5.x | 1.85.0 |
| 4.x | 1.60.0 |
| 3.x | 1.41.0 |
From 4.x and on, MSRV changes will be accompanied by a minor version bump.
## Public API SemVer Exemptions
Breaking changes to SemVer-exempted components affecting the public API will be accompanied by
_some_ version bump. Below are the specific policies:
| Releases | Public API Component(s) | Policy |
| :--- | :--- | :--- |
| 5.x | Dependencies `group`, `digest` and `rand_core` | Minor SemVer bump |
| 4.x | Dependencies `group`, `digest` and `rand_core` | Minor SemVer bump |
# Safety
The `curve25519` types are designed to make illegal states
unrepresentable. For example, any instance of an `EdwardsPoint` is
guaranteed to hold a point on the Edwards curve, and any instance of a
`RistrettoPoint` is guaranteed to hold a valid point in the Ristretto
group.
All operations are implemented using constant-time logic (no
secret-dependent branches, no secret-dependent memory accesses),
unless specifically marked as being variable-time code.
We believe that our constant-time logic is lowered to constant-time
assembly, at least on `x86_64` targets.
As an additional guard against possible future compiler optimizations,
the `subtle` crate places an optimization barrier before every
conditional move or assignment. More details can be found in [the
documentation for the `subtle` crate][subtle_doc].
Some functionality (e.g., multiscalar multiplication or batch
inversion) requires heap allocation for temporary buffers. All
heap-allocated buffers of potentially secret data are explicitly
zeroed before release.
However, we do not attempt to zero stack data, for two reasons.
First, it's not possible to do so correctly: we don't have control
over stack allocations, so there's no way to know how much data to
wipe. Second, because `curve25519` provides a mid-level API,
the correct place to start zeroing stack data is likely not at the
entrypoints of `curve25519` functions, but at the entrypoints of
functions in other crates.
The implementation is memory-safe, and contains no significant
`unsafe` code. The SIMD backend uses `unsafe` internally to call SIMD
intrinsics. These are marked `unsafe` only because invoking them on an
inappropriate CPU would cause `SIGILL`, but the entire backend is only
invoked when the appropriate CPU features are detected at runtime, or
when the whole program is compiled with the appropriate `target_feature`s.
# Performance
Benchmarks are run using [`criterion.rs`][criterion]:
```sh
cargo bench --features "rand_core"
export RUSTFLAGS='-C target_cpu=native'
cargo +nightly bench --features "rand_core"
```
Performance is a secondary goal behind correctness, safety, and
clarity, but we aim to be competitive with other implementations.
# FFI
Unfortunately, we have no plans to add FFI to `curve25519` directly. The
reason is that we use Rust features to provide an API that maintains safety
invariants, which are not possible to maintain across an FFI boundary. For
instance, as described in the _Safety_ section above, invalid points are
impossible to construct, and this would not be the case if we exposed point
operations over FFI.
However, `curve25519` is designed as a *mid-level* API, aimed at
implementing other, higher-level primitives. Instead of providing FFI at the
mid-level, our suggestion is to implement the higher-level primitive (a
signature, PAKE, ZKP, etc) in Rust, using `curve25519` as a dependency,
and have that crate provide a minimal, byte-buffer-oriented FFI specific to
that primitive.
# Contributing
Please see [CONTRIBUTING.md][contributing].
# About
**SPOILER ALERT:** *The Twelfth Doctor's first encounter with the Daleks is in
his second full episode, "Into the Dalek". A beleaguered ship of the "Combined
Galactic Resistance" has discovered a broken Dalek that has turned "good",
desiring to kill all other Daleks. The Doctor, Clara and a team of soldiers
are miniaturized and enter the Dalek, which the Doctor names Rusty. They
repair the damage, but accidentally restore it to its original nature, causing
it to go on the rampage and alert the Dalek fleet to the whereabouts of the
rebel ship. However, the Doctor manages to return Rusty to its previous state
by linking his mind with the Dalek's: Rusty shares the Doctor's view of the
universe's beauty, but also his deep hatred of the Daleks. Rusty destroys the
other Daleks and departs the ship, determined to track down and bring an end
to the Dalek race.*
`curve25519` is authored by Isis Agora Lovecruft and Henry de Valence.
Portions of this library were originally a port of [Adam Langley's
Golang ed25519 library](https://github.com/agl/ed25519), which was in
turn a port of the reference `ref10` implementation. Most of this code,
including the 32-bit field arithmetic, has since been rewritten.
The fast `u32` and `u64` scalar arithmetic was implemented by Andrew Moon, and
the addition chain for scalar inversion was provided by Brian Smith. The
optimised batch inversion was contributed by Sean Bowe and Daira Hopwood.
The `no_std` and `zeroize` support was contributed by Tony Arcieri.
The formally verified `fiat_backend` integrates Rust code generated by the
[Fiat Crypto project](https://github.com/mit-plv/fiat-crypto) and was
contributed by François Garillot.
Thanks also to Ashley Hauck, Lucas Salibian, Manish Goregaokar, Jack Grigg,
Pratyush Mishra, Michael Rosenberg, @pinkforest, and countless others for their
contributions.
[ed25519-dalek]: https://github.com/dalek-cryptography/curve25519/tree/main/ed25519-dalek
[x25519-dalek]: https://github.com/dalek-cryptography/curve25519/tree/main/x25519-dalek
[docs]: https://docs.rs/curve25519/
[contributing]: https://github.com/dalek-cryptography/curve25519/blob/master/CONTRIBUTING.md
[criterion]: https://github.com/japaric/criterion.rs
[parallel_doc]: https://docs.rs/curve25519/latest/curve25519/backend/vector/index.html
[subtle_doc]: https://docs.rs/subtle
[fiat-crypto]: https://github.com/mit-plv/fiat-crypto
[semver]: https://semver.org/spec/v2.0.0.html
[rngcorestd]: https://github.com/rust-random/rand/tree/7aa25d577e2df84a5156f824077bb7f6bdf28d97/rand_core#crate-features
[zeroize-trait]: https://docs.rs/zeroize/latest/zeroize/trait.Zeroize.html
[SIMD backend]: #simd-backend

Some files were not shown because too many files have changed in this diff Show more