* 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>cherry-pick
@ -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" ] |
@ -0,0 +1 @@ |
|||
../LICENSE-APACHE |
@ -0,0 +1 @@ |
|||
../LICENSE-MIT |
@ -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 |
|||
} |
@ -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 |
|||
} |
@ -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();
|
|||
}
|
@ -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();
|
|||
}
|
@ -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::*;
|
@ -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");
|
@ -0,0 +1,4 @@ |
|||
use crate::*;
|
|||
use ark_algebra_test_templates::*;
|
|||
|
|||
test_group!(te; EdwardsProjective; te);
|
@ -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>>;
|
@ -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>>;
|
@ -0,0 +1,8 @@ |
|||
mod fq;
|
|||
mod fr;
|
|||
|
|||
pub use fq::*;
|
|||
pub use fr::*;
|
|||
|
|||
#[cfg(test)]
|
|||
mod tests;
|
@ -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);
|
@ -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::*;
|