* 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>cherry-pick
| @ -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" ] | ||||
| @ -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,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 | ||||
|  | } | ||||
| @ -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();
 | ||||
|  | }
 | ||||
| @ -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_curve25519`.
 | ||||
|  | //! It requires a curve that embeds curve25519.
 | ||||
|  | 
 | ||||
|  | mod curves;
 | ||||
|  | mod fields;
 | ||||
|  | 
 | ||||
|  | pub use curves::*;
 | ||||
|  | pub use fields::*;
 | ||||
| @ -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");
 | ||||
| @ -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 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::*;
 | ||||