mirror of
https://github.com/arnaucube/ark-curves-cherry-picked.git
synced 2026-01-08 06:51:32 +01:00
Add the ed25519 curve (#121)
* add ed25519 curve * changelog * curve info * fix * cleanup the script * Update ed25519/src/curves/mod.rs * Update ed25519/src/curves/mod.rs Co-authored-by: onewayfunc <onewayfunc@gmail.com>
This commit is contained in:
@@ -12,6 +12,8 @@
|
||||
|
||||
### Features
|
||||
|
||||
- [\#121](https://github.com/arkworks-rs/curves/pull/121) Add the ed25519 curve.
|
||||
|
||||
### Improvements
|
||||
|
||||
- [\#74](https://github.com/arkworks-rs/curves/pull/74) Use Scott's subgroup membership tests for `G1` and `G2` of BLS12-381.
|
||||
|
||||
@@ -29,6 +29,8 @@ members = [
|
||||
|
||||
"pallas",
|
||||
"vesta",
|
||||
|
||||
"ed25519",
|
||||
]
|
||||
resolver = "2"
|
||||
|
||||
|
||||
30
ed25519/Cargo.toml
Normal file
30
ed25519/Cargo.toml
Normal file
@@ -0,0 +1,30 @@
|
||||
[package]
|
||||
name = "ark-ed25519"
|
||||
version = "0.3.0"
|
||||
authors = [ "arkworks contributors" ]
|
||||
description = "The ed25519 twisted Edwards curve"
|
||||
homepage = "https://arkworks.rs"
|
||||
repository = "https://github.com/arkworks-rs/curves"
|
||||
documentation = "https://docs.rs/ark-ed25519/"
|
||||
keywords = ["cryptography", "finite-fields", "elliptic-curves" ]
|
||||
categories = ["cryptography"]
|
||||
include = ["Cargo.toml", "src", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
|
||||
license = "MIT/Apache-2.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
ark-ff = { version = "^0.3.0", default-features = false }
|
||||
ark-ec = { version = "^0.3.0", default-features = false }
|
||||
ark-std = { version = "^0.3.0", default-features = false }
|
||||
ark-r1cs-std = { version = "^0.3.0", default-features = false, optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
ark-relations = { version = "^0.3.0", default-features = false }
|
||||
ark-serialize = { version = "^0.3.0", default-features = false }
|
||||
ark-algebra-test-templates = { version = "^0.3.0", default-features = false }
|
||||
ark-curve-constraint-tests = { path = "../curve-constraint-tests", default-features = false }
|
||||
|
||||
[features]
|
||||
default = []
|
||||
std = [ "ark-std/std", "ark-ff/std", "ark-ec/std" ]
|
||||
r1cs = [ "ark-r1cs-std" ]
|
||||
1
ed25519/LICENSE-APACHE
Symbolic link
1
ed25519/LICENSE-APACHE
Symbolic link
@@ -0,0 +1 @@
|
||||
../LICENSE-APACHE
|
||||
1
ed25519/LICENSE-MIT
Symbolic link
1
ed25519/LICENSE-MIT
Symbolic link
@@ -0,0 +1 @@
|
||||
../LICENSE-MIT
|
||||
91
ed25519/scripts/fr.ipynb
Normal file
91
ed25519/scripts/fr.ipynb
Normal file
@@ -0,0 +1,91 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "04264893",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"r = 7237005577332262213973186563042994240857116359379907606001950938285454250989"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"id": "1603b293",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"2^2 * 3 * 11 * 198211423230930754013084525763697 * 276602624281642239937218680557139826668747"
|
||||
]
|
||||
},
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"factor(r - 1)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"id": "425ceac7",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"7237005577332262213973186563042994240857116359379907606001950938285454250988\n",
|
||||
"1570463851528226261927580272323658009530148727742783848239914322803198255651\n",
|
||||
"4908983020090465803374304318106080751443647916949975825112097080460587568629\n",
|
||||
"7119675135705137915307919240607293966034195415655343409829245710729128040338\n",
|
||||
"2975531125133123119648879457563281269120703404158613135195788908093573672641\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"gen = 2\n",
|
||||
"print(pow(gen, (r - 1) / 2, r))\n",
|
||||
"print(pow(gen, (r - 1) / 3, r))\n",
|
||||
"print(pow(gen, (r - 1) / 11, r))\n",
|
||||
"print(pow(gen, (r - 1) / 198211423230930754013084525763697, r))\n",
|
||||
"print(pow(gen, (r - 1) / 276602624281642239937218680557139826668747, r))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "f4c58ca4",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "SageMath 9.2",
|
||||
"language": "sage",
|
||||
"name": "sagemath"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.9.7"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
260
ed25519/scripts/g1.ipynb
Normal file
260
ed25519/scripts/g1.ipynb
Normal file
@@ -0,0 +1,260 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "f890e69f",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"q = pow(2,255) - 19"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"id": "d90a7f0b",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"37095705934669439343138083508754565189542113879843219016388785533085940283555"
|
||||
]
|
||||
},
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"d = ((q - 1) * (121665 * pow(121666, -1, q)) % q)\n",
|
||||
"d"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"id": "1b2aebc5",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"46316835694926478169428394003475163141307993866256225615783033603165251855960"
|
||||
]
|
||||
},
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"y = 4 * pow(5, -1, q) % q\n",
|
||||
"y"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"id": "aae2f8bf",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"15112221349535400772501151409588531511454012693041857206046113283949847762202"
|
||||
]
|
||||
},
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"x = 0x216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A\n",
|
||||
"x"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"id": "ea9a4d90",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"26187595835145689230469591415084376402084551887632582719101735842039498021991"
|
||||
]
|
||||
},
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"x_squared = x^2 % q\n",
|
||||
"x_squared"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"id": "3499c817",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"37053468555941182535542715202780130513046395093004980492626426882532201484768"
|
||||
]
|
||||
},
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"y_squared = y^2 % q\n",
|
||||
"y_squared"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"id": "d9617d2d",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"10865872720795493305073123787695754110961843205372397773524691040492703462777"
|
||||
]
|
||||
},
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"((q - 1) * x_squared + y_squared) % q"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"id": "ece46a74",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"10865872720795493305073123787695754110961843205372397773524691040492703462777"
|
||||
]
|
||||
},
|
||||
"execution_count": 8,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"((d * x_squared * y_squared) % q + 1) % q"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"id": "b430f926",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"21711016731996786641919559689128982722488122124807605757398297001483711807481"
|
||||
]
|
||||
},
|
||||
"execution_count": 9,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"pow(8, -1, q)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"id": "d8575e54",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"486662"
|
||||
]
|
||||
},
|
||||
"execution_count": 10,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"A = 2 * (-1 + d) / (-1 - d)\n",
|
||||
"A"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"id": "2ee580a3",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"57896044618658097711785492504343953926634992332820282019728792003956564333285"
|
||||
]
|
||||
},
|
||||
"execution_count": 11,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"B = 4 / (-1 - d)\n",
|
||||
"B"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "ec089e21",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "SageMath 9.2",
|
||||
"language": "sage",
|
||||
"name": "sagemath"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.9.7"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
11
ed25519/src/constraints/curves.rs
Normal file
11
ed25519/src/constraints/curves.rs
Normal file
@@ -0,0 +1,11 @@
|
||||
use ark_r1cs_std::groups::curves::twisted_edwards::AffineVar;
|
||||
|
||||
use crate::{constraints::FqVar, *};
|
||||
|
||||
/// A variable that is the R1CS equivalent of `crate::EdwardsAffine`.
|
||||
pub type EdwardsVar = AffineVar<EdwardsParameters, FqVar>;
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
ark_curve_constraint_tests::curves::te_test::<EdwardsParameters, EdwardsVar>().unwrap();
|
||||
}
|
||||
11
ed25519/src/constraints/fields.rs
Normal file
11
ed25519/src/constraints/fields.rs
Normal file
@@ -0,0 +1,11 @@
|
||||
use ark_r1cs_std::fields::fp::FpVar;
|
||||
|
||||
use crate::Fq;
|
||||
|
||||
/// A variable that is the R1CS equivalent of `crate::Fq`.
|
||||
pub type FqVar = FpVar<Fq>;
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
ark_curve_constraint_tests::fields::field_test::<_, _, FqVar>().unwrap();
|
||||
}
|
||||
8
ed25519/src/constraints/mod.rs
Normal file
8
ed25519/src/constraints/mod.rs
Normal file
@@ -0,0 +1,8 @@
|
||||
//! This module implements the R1CS equivalent of `ark_ed25519`.
|
||||
//! It requires a curve that embeds ed25519.
|
||||
|
||||
mod curves;
|
||||
mod fields;
|
||||
|
||||
pub use curves::*;
|
||||
pub use fields::*;
|
||||
72
ed25519/src/curves/mod.rs
Normal file
72
ed25519/src/curves/mod.rs
Normal file
@@ -0,0 +1,72 @@
|
||||
use crate::{Fq, Fr};
|
||||
use ark_ec::{
|
||||
models::CurveConfig,
|
||||
twisted_edwards::{Affine, MontCurveConfig, Projective, TECurveConfig},
|
||||
};
|
||||
use ark_ff::MontFp;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
pub type EdwardsAffine = Affine<EdwardsParameters>;
|
||||
pub type EdwardsProjective = Projective<EdwardsParameters>;
|
||||
|
||||
#[derive(Clone, Default, PartialEq, Eq)]
|
||||
pub struct EdwardsParameters;
|
||||
|
||||
impl CurveConfig for EdwardsParameters {
|
||||
type BaseField = Fq;
|
||||
type ScalarField = Fr;
|
||||
|
||||
/// COFACTOR = 8
|
||||
const COFACTOR: &'static [u64] = &[8];
|
||||
|
||||
/// COFACTOR_INV (mod r) =
|
||||
/// 2713877091499598330239944961141122840321418634767465352250731601857045344121
|
||||
const COFACTOR_INV: Fr =
|
||||
MontFp!("2713877091499598330239944961141122840321418634767465352250731601857045344121");
|
||||
}
|
||||
|
||||
impl TECurveConfig for EdwardsParameters {
|
||||
/// COEFF_A = -1
|
||||
const COEFF_A: Fq = MontFp!("-1");
|
||||
|
||||
/// COEFF_D = -121665 / 121666
|
||||
const COEFF_D: Fq =
|
||||
MontFp!("37095705934669439343138083508754565189542113879843219016388785533085940283555");
|
||||
|
||||
/// Standard generators from <https://neuromancer.sk/std/other/Ed25519>.
|
||||
const GENERATOR: EdwardsAffine = EdwardsAffine::new_unchecked(GENERATOR_X, GENERATOR_Y);
|
||||
|
||||
type MontCurveConfig = EdwardsParameters;
|
||||
|
||||
/// Multiplication by `a` is just negation.
|
||||
#[inline(always)]
|
||||
fn mul_by_a(elem: Self::BaseField) -> Self::BaseField {
|
||||
-elem
|
||||
}
|
||||
}
|
||||
|
||||
// We want to emphasize that this Montgomery curve is not Curve25519.
|
||||
impl MontCurveConfig for EdwardsParameters {
|
||||
/// COEFF_A = 486662
|
||||
const COEFF_A: Fq = MontFp!("486662");
|
||||
|
||||
/// COEFF_B = 57896044618658097711785492504343953926634992332820282019728792003956564333285
|
||||
/// This is not one, because ed25519 != curve25519
|
||||
const COEFF_B: Fq =
|
||||
MontFp!("57896044618658097711785492504343953926634992332820282019728792003956564333285");
|
||||
|
||||
type TECurveConfig = EdwardsParameters;
|
||||
}
|
||||
|
||||
/// GENERATOR_X =
|
||||
/// 15112221349535400772501151409588531511454012693041857206046113283949847762202
|
||||
const GENERATOR_X: Fq =
|
||||
MontFp!("15112221349535400772501151409588531511454012693041857206046113283949847762202");
|
||||
|
||||
/// GENERATOR_Y =
|
||||
/// (4/5)
|
||||
/// 46316835694926478169428394003475163141307993866256225615783033603165251855960
|
||||
const GENERATOR_Y: Fq =
|
||||
MontFp!("46316835694926478169428394003475163141307993866256225615783033603165251855960");
|
||||
4
ed25519/src/curves/tests.rs
Normal file
4
ed25519/src/curves/tests.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
use crate::*;
|
||||
use ark_algebra_test_templates::*;
|
||||
|
||||
test_group!(te; EdwardsProjective; te);
|
||||
7
ed25519/src/fields/fq.rs
Normal file
7
ed25519/src/fields/fq.rs
Normal file
@@ -0,0 +1,7 @@
|
||||
use ark_ff::fields::{Fp256, MontBackend, MontConfig};
|
||||
|
||||
#[derive(MontConfig)]
|
||||
#[modulus = "57896044618658097711785492504343953926634992332820282019728792003956564819949"]
|
||||
#[generator = "2"]
|
||||
pub struct FqConfig;
|
||||
pub type Fq = Fp256<MontBackend<FqConfig, 4>>;
|
||||
7
ed25519/src/fields/fr.rs
Normal file
7
ed25519/src/fields/fr.rs
Normal file
@@ -0,0 +1,7 @@
|
||||
use ark_ff::fields::{Fp256, MontBackend, MontConfig};
|
||||
|
||||
#[derive(MontConfig)]
|
||||
#[modulus = "7237005577332262213973186563042994240857116359379907606001950938285454250989"]
|
||||
#[generator = "2"]
|
||||
pub struct FrConfig;
|
||||
pub type Fr = Fp256<MontBackend<FrConfig, 4>>;
|
||||
8
ed25519/src/fields/mod.rs
Normal file
8
ed25519/src/fields/mod.rs
Normal file
@@ -0,0 +1,8 @@
|
||||
mod fq;
|
||||
mod fr;
|
||||
|
||||
pub use fq::*;
|
||||
pub use fr::*;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
5
ed25519/src/fields/tests.rs
Normal file
5
ed25519/src/fields/tests.rs
Normal file
@@ -0,0 +1,5 @@
|
||||
use crate::{Fq, Fr};
|
||||
use ark_algebra_test_templates::*;
|
||||
|
||||
test_field!(fr; Fr; mont_prime_field);
|
||||
test_field!(fq; Fq; mont_prime_field);
|
||||
28
ed25519/src/lib.rs
Executable file
28
ed25519/src/lib.rs
Executable file
@@ -0,0 +1,28 @@
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
#![deny(
|
||||
warnings,
|
||||
unused,
|
||||
future_incompatible,
|
||||
nonstandard_style,
|
||||
rust_2018_idioms
|
||||
)]
|
||||
#![forbid(unsafe_code)]
|
||||
|
||||
//! This library implements the ed25519 twisted Edwards curve.
|
||||
//!
|
||||
//! Curve information:
|
||||
//! * Base field: q =
|
||||
//! 57896044618658097711785492504343953926634992332820282019728792003956564819949
|
||||
//! * Scalar field: r =
|
||||
//! 7237005577332262213973186563042994240857116359379907606001950938285454250989
|
||||
//! * Curve equation: ax^2 + y^2 =1 + dx^2y^2, where
|
||||
//! * a = -1
|
||||
//! * d = -121665 / 121666
|
||||
|
||||
#[cfg(feature = "r1cs")]
|
||||
pub mod constraints;
|
||||
mod curves;
|
||||
mod fields;
|
||||
|
||||
pub use curves::*;
|
||||
pub use fields::*;
|
||||
Reference in New Issue
Block a user