mirror of
https://github.com/arnaucube/ark-curves-cherry-picked.git
synced 2026-01-09 07:21:30 +01:00
Add the curve25519 curve (#124)
* add ed25519 curve * changelog * curve info * fix * edit * update * add more explanation * Update curve25519/src/curves/mod.rs * Update curve25519/src/curves/mod.rs * fixed the comment * Update curve25519/src/curves/mod.rs Co-authored-by: onewayfunc <onewayfunc@gmail.com>
This commit is contained in:
30
curve25519/Cargo.toml
Normal file
30
curve25519/Cargo.toml
Normal file
@@ -0,0 +1,30 @@
|
||||
[package]
|
||||
name = "ark-curve25519"
|
||||
version = "0.3.0"
|
||||
authors = [ "arkworks contributors" ]
|
||||
description = "The curve25519 Montgomery curve"
|
||||
homepage = "https://arkworks.rs"
|
||||
repository = "https://github.com/arkworks-rs/curves"
|
||||
documentation = "https://docs.rs/ark-curve25519/"
|
||||
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
curve25519/LICENSE-APACHE
Symbolic link
1
curve25519/LICENSE-APACHE
Symbolic link
@@ -0,0 +1 @@
|
||||
../LICENSE-APACHE
|
||||
1
curve25519/LICENSE-MIT
Symbolic link
1
curve25519/LICENSE-MIT
Symbolic link
@@ -0,0 +1 @@
|
||||
../LICENSE-MIT
|
||||
91
curve25519/scripts/fr.ipynb
Normal file
91
curve25519/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
|
||||
}
|
||||
162
curve25519/scripts/g1.ipynb
Normal file
162
curve25519/scripts/g1.ipynb
Normal file
@@ -0,0 +1,162 @@
|
||||
{
|
||||
"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": [],
|
||||
"source": [
|
||||
"A = 486662\n",
|
||||
"B = 1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"id": "1b2aebc5",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"486664\n",
|
||||
"486660\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"a = (A + 2) * 1\n",
|
||||
"d = (A - 2) * 1\n",
|
||||
"print(a)\n",
|
||||
"print(d)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"id": "aae2f8bf",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"9"
|
||||
]
|
||||
},
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"u = 9\n",
|
||||
"u"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"id": "ea9a4d90",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"14781619447589544791020593568409986887264606134616475288964881837755586237401"
|
||||
]
|
||||
},
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"v = mod(u^3 + A * u^2 + u, q).sqrt()\n",
|
||||
"v"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"id": "95895004",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"38213832894368730265794714087330135568483813637251082400757400312561599933396"
|
||||
]
|
||||
},
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"u * pow(v, -1, q) % q"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"id": "1134cf74",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"46316835694926478169428394003475163141307993866256225615783033603165251855960"
|
||||
]
|
||||
},
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"(u - 1) * pow(u + 1, -1, q) % q"
|
||||
]
|
||||
},
|
||||
{
|
||||
"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
|
||||
}
|
||||
14
curve25519/src/constraints/curves.rs
Normal file
14
curve25519/src/constraints/curves.rs
Normal file
@@ -0,0 +1,14 @@
|
||||
use ark_r1cs_std::groups::curves::twisted_edwards::{AffineVar, MontgomeryAffineVar};
|
||||
|
||||
use crate::{constraints::FqVar, *};
|
||||
|
||||
/// A variable that is the R1CS equivalent of `crate::EdwardsAffine`.
|
||||
pub type EdwardsVar = AffineVar<Curve25519Config, FqVar>;
|
||||
|
||||
/// A variable that is the R1CS equivalent of `crate::NonZeroMontgomeryAffine`.
|
||||
pub type NonZeroMontgomeryVar = MontgomeryAffineVar<Curve25519Config, FqVar>;
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
ark_curve_constraint_tests::curves::te_test::<Curve25519Config, EdwardsVar>().unwrap();
|
||||
}
|
||||
11
curve25519/src/constraints/fields.rs
Normal file
11
curve25519/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
curve25519/src/constraints/mod.rs
Normal file
8
curve25519/src/constraints/mod.rs
Normal file
@@ -0,0 +1,8 @@
|
||||
//! This module implements the R1CS equivalent of `ark_curve25519`.
|
||||
//! It requires a curve that embeds curve25519.
|
||||
|
||||
mod curves;
|
||||
mod fields;
|
||||
|
||||
pub use curves::*;
|
||||
pub use fields::*;
|
||||
71
curve25519/src/curves/mod.rs
Normal file
71
curve25519/src/curves/mod.rs
Normal file
@@ -0,0 +1,71 @@
|
||||
use crate::{Fq, Fr};
|
||||
use ark_ec::{
|
||||
models::CurveConfig,
|
||||
twisted_edwards::{Affine, MontCurveConfig, MontgomeryAffine, Projective, TECurveConfig},
|
||||
};
|
||||
use ark_ff::MontFp;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
pub type EdwardsAffine = Affine<Curve25519Config>;
|
||||
pub type EdwardsProjective = Projective<Curve25519Config>;
|
||||
pub type NonZeroMontgomeryAffine = MontgomeryAffine<Curve25519Config>;
|
||||
|
||||
#[derive(Clone, Default, PartialEq, Eq)]
|
||||
pub struct Curve25519Config;
|
||||
|
||||
impl CurveConfig for Curve25519Config {
|
||||
type BaseField = Fq;
|
||||
type ScalarField = Fr;
|
||||
|
||||
/// COFACTOR = 8
|
||||
const COFACTOR: &'static [u64] = &[8];
|
||||
|
||||
/// COFACTOR_INV (mod r) =
|
||||
/// 2713877091499598330239944961141122840321418634767465352250731601857045344121
|
||||
const COFACTOR_INV: Fr =
|
||||
MontFp!("2713877091499598330239944961141122840321418634767465352250731601857045344121");
|
||||
}
|
||||
|
||||
// We want to emphasize that this twisted Edwards curve is not ed25519.
|
||||
// Ed25519 has COEFF_A = -1 and COEFF_D = -121665 / 121666.
|
||||
impl TECurveConfig for Curve25519Config {
|
||||
/// COEFF_A = 486664
|
||||
const COEFF_A: Fq = MontFp!("486664");
|
||||
|
||||
/// COEFF_D = 486660
|
||||
const COEFF_D: Fq = MontFp!("486660");
|
||||
|
||||
/// Standard generators from <https://neuromancer.sk/std/other/Curve25519>.
|
||||
/// The Montgomery form is
|
||||
/// x = 0x09,
|
||||
/// y = 0x20ae19a1b8a086b4e01edd2c7748d14c923d4d7e6d7c61b229e9c5a27eced3d9
|
||||
/// The twisted Edwards form is
|
||||
/// x = 0x547c4350219f5e19dd26a3d6668b74346a8eb726eb2396e1228cfa397ffe6bd4
|
||||
/// y = 0x6666666666666666666666666666666666666666666666666666666666666658
|
||||
const GENERATOR: EdwardsAffine = EdwardsAffine::new_unchecked(GENERATOR_X, GENERATOR_Y);
|
||||
|
||||
type MontCurveConfig = Curve25519Config;
|
||||
}
|
||||
|
||||
impl MontCurveConfig for Curve25519Config {
|
||||
/// COEFF_A = 486662
|
||||
const COEFF_A: Fq = MontFp!("486662");
|
||||
|
||||
/// COEFF_B = 1
|
||||
const COEFF_B: Fq = MontFp!("1");
|
||||
|
||||
type TECurveConfig = Curve25519Config;
|
||||
}
|
||||
|
||||
/// GENERATOR_X =
|
||||
/// 38213832894368730265794714087330135568483813637251082400757400312561599933396
|
||||
const GENERATOR_X: Fq =
|
||||
MontFp!("38213832894368730265794714087330135568483813637251082400757400312561599933396");
|
||||
|
||||
/// GENERATOR_Y =
|
||||
/// (4/5)
|
||||
/// 46316835694926478169428394003475163141307993866256225615783033603165251855960
|
||||
const GENERATOR_Y: Fq =
|
||||
MontFp!("46316835694926478169428394003475163141307993866256225615783033603165251855960");
|
||||
4
curve25519/src/curves/tests.rs
Normal file
4
curve25519/src/curves/tests.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
use crate::*;
|
||||
use ark_algebra_test_templates::*;
|
||||
|
||||
test_group!(te; EdwardsProjective; te);
|
||||
7
curve25519/src/fields/fq.rs
Normal file
7
curve25519/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
curve25519/src/fields/fr.rs
Normal file
7
curve25519/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
curve25519/src/fields/mod.rs
Normal file
8
curve25519/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
curve25519/src/fields/tests.rs
Normal file
5
curve25519/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
curve25519/src/lib.rs
Executable file
28
curve25519/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 curve25519 Montgomery curve.
|
||||
//!
|
||||
//! Curve information:
|
||||
//! * Base field: q =
|
||||
//! 57896044618658097711785492504343953926634992332820282019728792003956564819949
|
||||
//! * Scalar field: r =
|
||||
//! 7237005577332262213973186563042994240857116359379907606001950938285454250989
|
||||
//! * Curve equation: B * y^2 = x^3 + A * x^2 + x, where
|
||||
//! * A = 486662
|
||||
//! * B = 1
|
||||
|
||||
#[cfg(feature = "r1cs")]
|
||||
pub mod constraints;
|
||||
mod curves;
|
||||
mod fields;
|
||||
|
||||
pub use curves::*;
|
||||
pub use fields::*;
|
||||
Reference in New Issue
Block a user