Browse Source

init

main
kilic 9 months ago
commit
d688e34d8e
9 changed files with 1074 additions and 0 deletions
  1. +2
    -0
      .gitignore
  2. +666
    -0
      Cargo.lock
  3. +26
    -0
      Cargo.toml
  4. +5
    -0
      README.md
  5. +102
    -0
      src/ed_on_bn254_twist.rs
  6. +143
    -0
      src/eddsa.rs
  7. +55
    -0
      src/lib.rs
  8. +19
    -0
      src/poseidon.rs
  9. +56
    -0
      src/signature.rs

+ 2
- 0
.gitignore

@ -0,0 +1,2 @@
/target
*.py

+ 666
- 0
Cargo.lock

@ -0,0 +1,666 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "ahash"
version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
dependencies = [
"cfg-if",
"once_cell",
"version_check",
"zerocopy",
]
[[package]]
name = "ark-algebra-test-templates"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "400bd3a79c741b1832f1416d4373ae077ef82ca14a8b4cee1248a2f11c8b9172"
dependencies = [
"ark-ec",
"ark-ff",
"ark-serialize",
"ark-std",
"hex",
"num-bigint",
"num-integer",
"num-traits",
"serde",
"serde_derive",
"serde_json",
"sha2",
]
[[package]]
name = "ark-bls12-381"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c775f0d12169cba7aae4caeb547bb6a50781c7449a8aa53793827c9ec4abf488"
dependencies = [
"ark-ec",
"ark-ff",
"ark-serialize",
"ark-std",
]
[[package]]
name = "ark-bn254"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a22f4561524cd949590d78d7d4c5df8f592430d221f7f3c9497bbafd8972120f"
dependencies = [
"ark-ec",
"ark-ff",
"ark-std",
]
[[package]]
name = "ark-crypto-primitives"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f3a13b34da09176a8baba701233fdffbaa7c1b1192ce031a3da4e55ce1f1a56"
dependencies = [
"ark-ec",
"ark-ff",
"ark-relations",
"ark-serialize",
"ark-snark",
"ark-std",
"blake2",
"derivative",
"digest",
"sha2",
]
[[package]]
name = "ark-ec"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba"
dependencies = [
"ark-ff",
"ark-poly",
"ark-serialize",
"ark-std",
"derivative",
"hashbrown",
"itertools",
"num-traits",
"zeroize",
]
[[package]]
name = "ark-ed-on-bls12-381"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba6d678bb98a7e4f825bd4e332e93ac4f5a114ce2e3340dee4d7dc1c7ab5b323"
dependencies = [
"ark-bls12-381",
"ark-ec",
"ark-ff",
"ark-std",
]
[[package]]
name = "ark-ed-on-bls12-381-bandersnatch"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9cde0f2aa063a2a5c28d39b47761aa102bda7c13c84fc118a61b87c7b2f785c"
dependencies = [
"ark-bls12-381",
"ark-ec",
"ark-ff",
"ark-std",
]
[[package]]
name = "ark-ed-on-bn254"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71892f265d01650e34988a546b37ea1d2ba1da162a639597a03d1550f26004d8"
dependencies = [
"ark-bn254",
"ark-ec",
"ark-ff",
"ark-std",
]
[[package]]
name = "ark-ff"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba"
dependencies = [
"ark-ff-asm",
"ark-ff-macros",
"ark-serialize",
"ark-std",
"derivative",
"digest",
"itertools",
"num-bigint",
"num-traits",
"paste",
"rustc_version",
"zeroize",
]
[[package]]
name = "ark-ff-asm"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348"
dependencies = [
"quote",
"syn 1.0.109",
]
[[package]]
name = "ark-ff-macros"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565"
dependencies = [
"num-bigint",
"num-traits",
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]]
name = "ark-poly"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf"
dependencies = [
"ark-ff",
"ark-serialize",
"ark-std",
"derivative",
"hashbrown",
]
[[package]]
name = "ark-relations"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00796b6efc05a3f48225e59cb6a2cda78881e7c390872d5786aaf112f31fb4f0"
dependencies = [
"ark-ff",
"ark-std",
"tracing",
]
[[package]]
name = "ark-serialize"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5"
dependencies = [
"ark-serialize-derive",
"ark-std",
"digest",
"num-bigint",
]
[[package]]
name = "ark-serialize-derive"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea"
dependencies = [
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]]
name = "ark-snark"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84d3cc6833a335bb8a600241889ead68ee89a3cf8448081fb7694c0fe503da63"
dependencies = [
"ark-ff",
"ark-relations",
"ark-serialize",
"ark-std",
]
[[package]]
name = "ark-std"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185"
dependencies = [
"num-traits",
"rand",
]
[[package]]
name = "arkeddsa"
version = "0.1.0"
dependencies = [
"ark-algebra-test-templates",
"ark-crypto-primitives",
"ark-ec",
"ark-ed-on-bls12-381",
"ark-ed-on-bls12-381-bandersnatch",
"ark-ed-on-bn254",
"ark-ff",
"ark-serialize",
"ark-std",
"blake2",
"digest",
"rand",
"rand_core",
"sha2",
]
[[package]]
name = "autocfg"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
[[package]]
name = "blake2"
version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe"
dependencies = [
"digest",
]
[[package]]
name = "block-buffer"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
dependencies = [
"generic-array",
]
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "cpufeatures"
version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504"
dependencies = [
"libc",
]
[[package]]
name = "crypto-common"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
dependencies = [
"generic-array",
"typenum",
]
[[package]]
name = "derivative"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
dependencies = [
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]]
name = "digest"
version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
"crypto-common",
"subtle",
]
[[package]]
name = "either"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b"
[[package]]
name = "generic-array"
version = "0.14.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
dependencies = [
"typenum",
"version_check",
]
[[package]]
name = "getrandom"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "hashbrown"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e"
dependencies = [
"ahash",
]
[[package]]
name = "hex"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]]
name = "itertools"
version = "0.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
dependencies = [
"either",
]
[[package]]
name = "itoa"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
[[package]]
name = "libc"
version = "0.2.155"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
[[package]]
name = "num-bigint"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7"
dependencies = [
"num-integer",
"num-traits",
]
[[package]]
name = "num-integer"
version = "0.1.46"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
dependencies = [
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
]
[[package]]
name = "once_cell"
version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
[[package]]
name = "paste"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
[[package]]
name = "pin-project-lite"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
[[package]]
name = "ppv-lite86"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "proc-macro2"
version = "1.0.85"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom",
]
[[package]]
name = "rustc_version"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
dependencies = [
"semver",
]
[[package]]
name = "ryu"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
[[package]]
name = "semver"
version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
[[package]]
name = "serde"
version = "1.0.203"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.203"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.66",
]
[[package]]
name = "serde_json"
version = "1.0.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3"
dependencies = [
"itoa",
"ryu",
"serde",
]
[[package]]
name = "sha2"
version = "0.10.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
]
[[package]]
name = "subtle"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
[[package]]
name = "syn"
version = "1.0.109"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "syn"
version = "2.0.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "tracing"
version = "0.1.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
dependencies = [
"pin-project-lite",
"tracing-core",
]
[[package]]
name = "tracing-core"
version = "0.1.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
[[package]]
name = "typenum"
version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "version_check"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "zerocopy"
version = "0.7.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.7.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.66",
]
[[package]]
name = "zeroize"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde"
dependencies = [
"zeroize_derive",
]
[[package]]
name = "zeroize_derive"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.66",
]

+ 26
- 0
Cargo.toml

@ -0,0 +1,26 @@
[package]
edition = "2021"
name = "arkeddsa"
version = "0.1.0"
[dependencies]
ark-crypto-primitives = {version = "^0.4.0", default-features = false, features = ["sponge", "crh"]}
ark-ec = "0.4"
ark-ed-on-bn254 = {version = "0.4.0"}
ark-ff = "0.4"
ark-serialize = "0.4"
ark-std = "0.4"
digest = "0.10.7"
rand = "0.8"
rand_core = {version = "0.6", default-features = false}
[dev-dependencies]
ark-algebra-test-templates = "0.4.2"
ark-ed-on-bls12-381 = {version = "0.4.0"}
ark-ed-on-bls12-381-bandersnatch = {version = "0.4.0"}
blake2 = "0.10.6"
sha2 = "0.10.8"
[features]
default = []

+ 5
- 0
README.md

@ -0,0 +1,5 @@
# arkeddsa
Do not use in production.
EDDSA signature scheme implementation with Poseidon hasher and ark-works backend. Additionally circom compatible `ed_on_bn254_twist` twist is available.

+ 102
- 0
src/ed_on_bn254_twist.rs

@ -0,0 +1,102 @@
use ark_ec::{
models::CurveConfig,
twisted_edwards::{Affine, MontCurveConfig, Projective, TECurveConfig},
};
use ark_ff::MontFp;
pub type EdwardsAffine = Affine<EdwardsConfig>;
pub type EdwardsProjective = Projective<EdwardsConfig>;
/// Twist of `Baby-JubJub` is a twist of twisted Edwards curve. These curves have equations of the
/// form: ax² + y² = 1 + dx²y².
/// over some base finite field BaseField.
///
/// q = 21888242871839275222246405745257275088548364400416034343698204186575808495617
#[derive(Clone, Default, PartialEq, Eq)]
pub struct EdwardsConfig;
#[cfg(test)]
ark_algebra_test_templates::test_group!(te; EdwardsProjective; te);
impl CurveConfig for EdwardsConfig {
type BaseField = ark_ed_on_bn254::Fq;
type ScalarField = ark_ed_on_bn254::Fr;
/// COFACTOR = 8
const COFACTOR: &'static [u64] = &[8];
/// COFACTOR^(-1) mod r =
/// 2394026564107420727433200628387514462817212225638746351800188703329891451411
const COFACTOR_INV: ark_ed_on_bn254::Fr =
MontFp!("2394026564107420727433200628387514462817212225638746351800188703329891451411");
}
impl TECurveConfig for EdwardsConfig {
const COEFF_A: ark_ed_on_bn254::Fq = MontFp!("168700");
#[inline(always)]
fn mul_by_a(elem: Self::BaseField) -> Self::BaseField {
elem * <Self as TECurveConfig>::COEFF_A
}
const COEFF_D: ark_ed_on_bn254::Fq = MontFp!("168696");
const GENERATOR: EdwardsAffine = EdwardsAffine::new_unchecked(GENERATOR_X, GENERATOR_Y);
type MontCurveConfig = EdwardsConfig;
}
impl MontCurveConfig for EdwardsConfig {
/// COEFF_A = 168698
const COEFF_A: ark_ed_on_bn254::Fq = MontFp!("168698");
/// COEFF_B = 168700
const COEFF_B: ark_ed_on_bn254::Fq = MontFp!("1");
type TECurveConfig = EdwardsConfig;
}
/// GENERATOR_X =
/// 19698561148652590122159747500897617769866003486955115824547446575314762165298
pub const GENERATOR_X: ark_ed_on_bn254::Fq =
MontFp!("5299619240641551281634865583518297030282874472190772894086521144482721001553");
/// GENERATOR_Y =
/// 19298250018296453272277890825869354524455968081175474282777126169995084727839
pub const GENERATOR_Y: ark_ed_on_bn254::Fq =
MontFp!("16950150798460657717958625567821834550301663161624707787222815936182638968203");
#[test]
fn test_twist() {
fn twist(twist: ark_ed_on_bn254::EdwardsAffine) -> EdwardsAffine {
use ark_ff::Field;
let inv_sqrt_a = MontFp!("168700").sqrt().unwrap().inverse().unwrap();
EdwardsAffine {
x: twist.x * inv_sqrt_a,
y: twist.y,
}
}
fn untwist(curve: EdwardsAffine) -> ark_ed_on_bn254::EdwardsAffine {
use ark_ff::Field;
const A: ark_ed_on_bn254::Fq = MontFp!("168700");
let sqrt_a = A.sqrt().unwrap();
ark_ed_on_bn254::EdwardsAffine {
x: curve.x * sqrt_a,
y: curve.y,
}
}
use ark_ec::{AffineRepr, CurveGroup};
use ark_ed_on_bn254::Fr;
use ark_std::UniformRand;
use rand_core::OsRng;
let v0: ark_ed_on_bn254::EdwardsAffine = ark_ed_on_bn254::EdwardsAffine::generator();
let u0: crate::ed_on_bn254_twist::EdwardsAffine = twist(v0);
assert!(u0.is_on_curve());
assert!(u0.is_in_correct_subgroup_assuming_on_curve());
let x = Fr::rand(&mut OsRng);
let u1 = (u0 * x).into_affine();
let v1 = (v0 * x).into_affine();
let v2 = untwist(u1);
assert_eq!(v1, v2);
}

+ 143
- 0
src/eddsa.rs

@ -0,0 +1,143 @@
use crate::{signature::Signature, Error};
use ark_crypto_primitives::sponge::{
poseidon::{PoseidonConfig, PoseidonSponge},
Absorb, CryptographicSponge,
};
use ark_ec::{twisted_edwards::TECurveConfig, AffineRepr, CurveGroup};
use ark_ff::PrimeField;
use digest::Digest;
use digest::OutputSizeUser;
use rand_core::CryptoRngCore;
fn prune_buffer<F: PrimeField>(mut bytes: [u8; 32]) -> F {
bytes[0] &= 0b1111_1000;
bytes[31] &= 0b0111_1111;
bytes[31] |= 0b0100_0000;
F::from_le_bytes_mod_order(&bytes[..])
}
#[derive(Copy, Clone, Debug)]
/// EdDSA secret key is 32 byte data
pub struct SecretKey([u8; 32]);
impl SecretKey {
fn expand<F: PrimeField, D: Digest>(&self) -> (F, [u8; 32]) {
let hash = D::new().chain_update(self.0).finalize();
let (buffer, hash_prefix) = hash.split_at(32);
let buffer: [u8; 32] = buffer.try_into().unwrap();
let hash_prefix: [u8; 32] = hash_prefix.try_into().unwrap();
let x = prune_buffer(buffer);
(x, hash_prefix)
}
}
#[derive(Copy, Clone, Debug)]
/// `PublicKey` is EdDSA signature verification key
pub struct PublicKey<A: AffineRepr>(A)
where
A::Config: TECurveConfig;
#[derive(Copy, Clone, Debug)]
/// `SigningKey` produces EdDSA signatures for given message
pub struct SigningKey<A: AffineRepr>
where
A::Config: TECurveConfig,
{
secret_key: SecretKey,
public_key: PublicKey<A>,
}
impl<A: AffineRepr> SigningKey<A>
where
A::Config: TECurveConfig,
A::BaseField: PrimeField + Absorb,
{
pub fn new<D: Digest>(secret_key: &SecretKey) -> Result<Self, Error> {
(<D as OutputSizeUser>::output_size() == 64)
.then_some(())
.ok_or(Error::BadOutputSize)?;
let (x, _) = secret_key.expand::<A::ScalarField, D>();
let public_key: A = (A::generator() * x).into_affine();
let signing_key = Self {
secret_key: *secret_key,
public_key: PublicKey(public_key),
};
Ok(signing_key)
}
pub fn generate<D: Digest>(rng: &mut impl CryptoRngCore) -> Result<Self, Error> {
let mut secret_key = SecretKey([0; 32]);
rng.fill_bytes(&mut secret_key.0);
Self::new::<D>(&secret_key)
}
pub fn public_key(&self) -> PublicKey<A> {
self.public_key
}
pub fn sign<D: Digest, E: Absorb>(
&self,
poseidon: &PoseidonConfig<A::BaseField>,
message: &[E],
) -> Signature<A> {
let (x, prefix) = self.secret_key.expand::<A::ScalarField, D>();
let mut h = D::new();
h.update(prefix);
message
.iter()
.for_each(|m| h.update(m.to_sponge_bytes_as_vec()));
let r: A::ScalarField = crate::from_digest(h);
let sig_r = (A::generator() * r).into_affine();
let mut poseidon = PoseidonSponge::new(poseidon);
let (sig_r_x, sig_r_y) = sig_r.xy().unwrap();
poseidon.absorb(sig_r_x);
poseidon.absorb(sig_r_y);
let (vk_x, vk_y) = self.public_key.0.xy().unwrap();
poseidon.absorb(vk_x);
poseidon.absorb(vk_y);
message.iter().for_each(|m| poseidon.absorb(m));
let k = poseidon.squeeze_field_elements::<A::ScalarField>(1);
let k = k.first().unwrap();
let sig_s = (x * k) + r;
Signature::new(sig_r, sig_s)
}
}
impl<A: AffineRepr> PublicKey<A>
where
A::Config: TECurveConfig,
A::BaseField: PrimeField + Absorb,
{
pub fn verify<E: Absorb>(
&self,
poseidon: &PoseidonConfig<A::BaseField>,
message: &[E],
signature: &Signature<A>,
) -> Result<(), Error> {
let mut poseidon = PoseidonSponge::new(poseidon);
let (sig_r_x, sig_r_y) = signature.r().xy().unwrap();
poseidon.absorb(sig_r_x);
poseidon.absorb(sig_r_y);
let (vk_x, vk_y) = self.0.xy().unwrap();
poseidon.absorb(vk_x);
poseidon.absorb(vk_y);
message.iter().for_each(|m| poseidon.absorb(m));
let k = poseidon.squeeze_field_elements::<A::ScalarField>(1);
let k = k.first().unwrap();
let kx_b = self.0 * k;
let s_b = A::generator() * signature.s();
let r_rec: A = (s_b - kx_b).into();
(signature.r() == &r_rec).then_some(()).ok_or(Error::Verify)
}
}

+ 55
- 0
src/lib.rs

@ -0,0 +1,55 @@
pub mod ed_on_bn254_twist;
pub mod eddsa;
pub mod poseidon;
pub mod signature;
use ark_ff::PrimeField;
use digest::Digest;
pub use eddsa::*;
pub(crate) fn from_digest<F: PrimeField, D: Digest>(digest: D) -> F {
let bytes = digest.finalize();
F::from_le_bytes_mod_order(&bytes)
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Error {
Verify,
BadOutputSize,
InvalidData,
}
#[cfg(test)]
mod test {
use ark_crypto_primitives::sponge::Absorb;
use ark_ec::{twisted_edwards::TECurveConfig, AffineRepr};
use ark_ff::PrimeField;
use digest::Digest;
use rand_core::OsRng;
use crate::SigningKey;
fn run_test<A: AffineRepr, D: Digest>()
where
A::BaseField: Absorb + PrimeField,
A::Config: TECurveConfig,
{
let poseidon = crate::poseidon::poseidon_config(4, 8, 55);
let signing_key = SigningKey::<A>::generate::<D>(&mut OsRng).unwrap();
let message = b"xxx yyy <<< zzz >>> bunny";
let signature = signing_key.sign::<D, _>(&poseidon, &message[..]);
let public_key = signing_key.public_key();
public_key
.verify::<_>(&poseidon, &message[..], &signature)
.unwrap();
}
#[test]
fn test_eddsa() {
run_test::<ark_ed_on_bn254::EdwardsAffine, sha2::Sha512>();
run_test::<ark_ed_on_bn254::EdwardsAffine, blake2::Blake2b512>();
run_test::<crate::ed_on_bn254_twist::EdwardsAffine, sha2::Sha512>();
run_test::<ark_ed_on_bls12_381::EdwardsAffine, sha2::Sha512>();
run_test::<ark_ed_on_bls12_381_bandersnatch::EdwardsAffine, sha2::Sha512>();
}
}

+ 19
- 0
src/poseidon.rs

@ -0,0 +1,19 @@
use ark_crypto_primitives::sponge::poseidon::{find_poseidon_ark_and_mds, PoseidonConfig};
use ark_ff::PrimeField;
/// Generates poseidon constants and returns the config
pub fn poseidon_config<F: PrimeField>(
rate: usize,
full_rounds: usize,
partial_rounds: usize,
) -> PoseidonConfig<F> {
let prime_bits = F::MODULUS_BIT_SIZE as u64;
let (ark, mds) = find_poseidon_ark_and_mds(
prime_bits,
rate,
full_rounds as u64,
partial_rounds as u64,
0,
);
PoseidonConfig::new(full_rounds, partial_rounds, 5, mds, ark, rate, 1)
}

+ 56
- 0
src/signature.rs

@ -0,0 +1,56 @@
use crate::Error;
use ark_ec::twisted_edwards::TECurveConfig;
use ark_ec::AffineRepr;
use ark_serialize::CanonicalDeserialize;
use ark_serialize::CanonicalSerialize;
#[derive(Clone, Copy, Debug)]
/// `SignatureComponents` contains the realized parts of a signature
pub struct Signature<A: AffineRepr> {
r: A,
s: A::ScalarField,
}
impl<A: AffineRepr> Signature<A>
where
A::Config: TECurveConfig,
{
/// Serializes the signature components to bytes as uncompressed.
/// Expect output size to be `size_of(A::BaseField) * 2 + size_of(A::ScalarField)`
pub fn to_bytes(&self) -> Vec<u8> {
let mut bytes = Vec::new();
self.r.serialize_uncompressed(&mut bytes).unwrap();
self.s.serialize_uncompressed(&mut bytes).unwrap();
bytes
}
/// Checked deserialization of the signature components from bytes.
/// Expects input size to be `size_of(A::BaseField) * 2 + size_of(A::ScalarField)`
pub fn from_bytes(bytes: &[u8]) -> Result<Signature<A>, Error> {
let point_size = A::Config::serialized_size(ark_serialize::Compress::No);
(bytes.len() == 32 + A::Config::serialized_size(ark_serialize::Compress::No))
.then_some(true)
.ok_or(Error::InvalidData)?;
let off1 = point_size;
let off2 = off1 + 32;
let r =
A::deserialize_uncompressed(&bytes[00..off1]).map_err(|_| crate::Error::InvalidData)?;
let s = A::ScalarField::deserialize_uncompressed(&bytes[off1..off2])
.map_err(|_| crate::Error::InvalidData)?;
Ok(Signature { r, s })
}
pub fn new(r: A, s: A::ScalarField) -> Self {
Self { r, s }
}
pub(crate) fn r(&self) -> &A {
&self.r
}
pub(crate) fn s(&self) -> &A::ScalarField {
&self.s
}
}

Loading…
Cancel
Save