arnaucube 4 months ago
parent
commit
67c077e0e5
6 changed files with 357 additions and 150 deletions
  1. +241
    -56
      Cargo.lock
  2. +11
    -11
      Cargo.toml
  3. +17
    -9
      src/constraints.rs
  4. +59
    -49
      src/eddsa.rs
  5. +12
    -11
      src/lib.rs
  6. +17
    -14
      src/signature.rs

+ 241
- 56
Cargo.lock

@ -14,11 +14,17 @@ dependencies = [
"zerocopy",
]
[[package]]
name = "allocator-api2"
version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
[[package]]
name = "ark-algebra-test-templates"
version = "0.4.2"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "400bd3a79c741b1832f1416d4373ae077ef82ca14a8b4cee1248a2f11c8b9172"
checksum = "fd4c6293624cb11978fe9940af61faa16e85431fa9993ed2e11ea422099a564c"
dependencies = [
"ark-ec",
"ark-ff",
@ -36,9 +42,9 @@ dependencies = [
[[package]]
name = "ark-bls12-381"
version = "0.4.0"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c775f0d12169cba7aae4caeb547bb6a50781c7449a8aa53793827c9ec4abf488"
checksum = "3df4dcc01ff89867cd86b0da835f23c3f02738353aaee7dde7495af71363b8d5"
dependencies = [
"ark-ec",
"ark-ff",
@ -48,9 +54,9 @@ dependencies = [
[[package]]
name = "ark-bn254"
version = "0.4.0"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a22f4561524cd949590d78d7d4c5df8f592430d221f7f3c9497bbafd8972120f"
checksum = "d69eab57e8d2663efa5c63135b2af4f396d66424f88954c21104125ab6b3e6bc"
dependencies = [
"ark-ec",
"ark-ff",
@ -59,12 +65,15 @@ dependencies = [
[[package]]
name = "ark-crypto-primitives"
version = "0.4.0"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f3a13b34da09176a8baba701233fdffbaa7c1b1192ce031a3da4e55ce1f1a56"
checksum = "1e0c292754729c8a190e50414fd1a37093c786c709899f29c9f7daccecfa855e"
dependencies = [
"ahash",
"ark-crypto-primitives-macros",
"ark-ec",
"ark-ff",
"ark-r1cs-std",
"ark-relations",
"ark-serialize",
"ark-snark",
@ -72,31 +81,49 @@ dependencies = [
"blake2",
"derivative",
"digest",
"fnv",
"merlin",
"sha2",
"tracing",
]
[[package]]
name = "ark-crypto-primitives-macros"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7e89fe77d1f0f4fe5b96dfc940923d88d17b6a773808124f21e764dfb063c6a"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.66",
]
[[package]]
name = "ark-ec"
version = "0.4.2"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba"
checksum = "43d68f2d516162846c1238e755a7c4d131b892b70cc70c471a8e3ca3ed818fce"
dependencies = [
"ahash",
"ark-ff",
"ark-poly",
"ark-serialize",
"ark-std",
"derivative",
"educe",
"fnv",
"hashbrown",
"itertools",
"num-bigint",
"num-integer",
"num-traits",
"zeroize",
]
[[package]]
name = "ark-ed-on-bls12-381"
version = "0.4.0"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba6d678bb98a7e4f825bd4e332e93ac4f5a114ce2e3340dee4d7dc1c7ab5b323"
checksum = "ba93ca6e75e5f589c139e5a41ebd783ebf2153de0025cd2b00da2963929c92ec"
dependencies = [
"ark-bls12-381",
"ark-ec",
@ -106,9 +133,9 @@ dependencies = [
[[package]]
name = "ark-ed-on-bls12-381-bandersnatch"
version = "0.4.0"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9cde0f2aa063a2a5c28d39b47761aa102bda7c13c84fc118a61b87c7b2f785c"
checksum = "1786b2e3832f6f0f7c8d62d5d5a282f6952a1ab99981c54cd52b6ac1d8f02df5"
dependencies = [
"ark-bls12-381",
"ark-ec",
@ -118,9 +145,9 @@ dependencies = [
[[package]]
name = "ark-ed-on-bn254"
version = "0.4.0"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71892f265d01650e34988a546b37ea1d2ba1da162a639597a03d1550f26004d8"
checksum = "962e24e25cbdcaabe619c281a62bccc885f778b188129d6a02875c2671666219"
dependencies = [
"ark-bn254",
"ark-ec",
@ -130,99 +157,122 @@ dependencies = [
[[package]]
name = "ark-ff"
version = "0.4.2"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba"
checksum = "a177aba0ed1e0fbb62aa9f6d0502e9b46dad8c2eab04c14258a1212d2557ea70"
dependencies = [
"ark-ff-asm",
"ark-ff-macros",
"ark-serialize",
"ark-std",
"derivative",
"arrayvec",
"digest",
"educe",
"itertools",
"num-bigint",
"num-traits",
"paste",
"rustc_version",
"rayon",
"zeroize",
]
[[package]]
name = "ark-ff-asm"
version = "0.4.2"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348"
checksum = "62945a2f7e6de02a31fe400aa489f0e0f5b2502e69f95f853adb82a96c7a6b60"
dependencies = [
"quote",
"syn 1.0.109",
"syn 2.0.66",
]
[[package]]
name = "ark-ff-macros"
version = "0.4.2"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565"
checksum = "09be120733ee33f7693ceaa202ca41accd5653b779563608f1234f78ae07c4b3"
dependencies = [
"num-bigint",
"num-traits",
"proc-macro2",
"quote",
"syn 1.0.109",
"syn 2.0.66",
]
[[package]]
name = "ark-poly"
version = "0.4.2"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf"
checksum = "579305839da207f02b89cd1679e50e67b4331e2f9294a57693e5051b7703fe27"
dependencies = [
"ahash",
"ark-ff",
"ark-serialize",
"ark-std",
"derivative",
"educe",
"fnv",
"hashbrown",
]
[[package]]
name = "ark-r1cs-std"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "941551ef1df4c7a401de7068758db6503598e6f01850bdb2cfdb614a1f9dbea1"
dependencies = [
"ark-ec",
"ark-ff",
"ark-relations",
"ark-std",
"educe",
"num-bigint",
"num-integer",
"num-traits",
"tracing",
]
[[package]]
name = "ark-relations"
version = "0.4.0"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00796b6efc05a3f48225e59cb6a2cda78881e7c390872d5786aaf112f31fb4f0"
checksum = "ec46ddc93e7af44bcab5230937635b06fb5744464dd6a7e7b083e80ebd274384"
dependencies = [
"ark-ff",
"ark-std",
"tracing",
"tracing-subscriber",
]
[[package]]
name = "ark-serialize"
version = "0.4.2"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5"
checksum = "3f4d068aaf107ebcd7dfb52bc748f8030e0fc930ac8e360146ca54c1203088f7"
dependencies = [
"ark-serialize-derive",
"ark-std",
"arrayvec",
"digest",
"num-bigint",
"rayon",
]
[[package]]
name = "ark-serialize-derive"
version = "0.4.2"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea"
checksum = "213888f660fddcca0d257e88e54ac05bca01885f258ccdf695bafd77031bb69d"
dependencies = [
"proc-macro2",
"quote",
"syn 1.0.109",
"syn 2.0.66",
]
[[package]]
name = "ark-snark"
version = "0.4.0"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84d3cc6833a335bb8a600241889ead68ee89a3cf8448081fb7694c0fe503da63"
checksum = "d368e2848c2d4c129ce7679a7d0d2d612b6a274d3ea6a13bad4445d61b381b88"
dependencies = [
"ark-ff",
"ark-relations",
@ -232,12 +282,13 @@ dependencies = [
[[package]]
name = "ark-std"
version = "0.4.0"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185"
checksum = "246a225cc6131e9ee4f24619af0f19d67761fff15d7ccc22e42b80846e69449a"
dependencies = [
"num-traits",
"rand",
"rayon",
]
[[package]]
@ -251,6 +302,8 @@ dependencies = [
"ark-ed-on-bls12-381-bandersnatch",
"ark-ed-on-bn254",
"ark-ff",
"ark-r1cs-std",
"ark-relations",
"ark-serialize",
"ark-std",
"blake2",
@ -261,6 +314,12 @@ dependencies = [
"sha2",
]
[[package]]
name = "arrayvec"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
[[package]]
name = "autocfg"
version = "1.3.0"
@ -285,6 +344,12 @@ dependencies = [
"generic-array",
]
[[package]]
name = "byteorder"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "cfg-if"
version = "1.0.0"
@ -300,6 +365,31 @@ dependencies = [
"libc",
]
[[package]]
name = "crossbeam-deque"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d"
dependencies = [
"crossbeam-epoch",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-epoch"
version = "0.9.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
dependencies = [
"crossbeam-utils",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
[[package]]
name = "crypto-common"
version = "0.1.6"
@ -332,12 +422,50 @@ dependencies = [
"subtle",
]
[[package]]
name = "educe"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d7bc049e1bd8cdeb31b68bbd586a9464ecf9f3944af3958a7a9d0f8b9799417"
dependencies = [
"enum-ordinalize",
"proc-macro2",
"quote",
"syn 2.0.66",
]
[[package]]
name = "either"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b"
[[package]]
name = "enum-ordinalize"
version = "4.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fea0dcfa4e54eeb516fe454635a95753ddd39acda650ce703031c6973e315dd5"
dependencies = [
"enum-ordinalize-derive",
]
[[package]]
name = "enum-ordinalize-derive"
version = "4.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d28318a75d4aead5c4db25382e8ef717932d0346600cacae6357eb5941bc5ff"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.66",
]
[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "generic-array"
version = "0.14.7"
@ -361,11 +489,11 @@ dependencies = [
[[package]]
name = "hashbrown"
version = "0.13.2"
version = "0.15.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e"
checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
dependencies = [
"ahash",
"allocator-api2",
]
[[package]]
@ -376,9 +504,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]]
name = "itertools"
version = "0.10.5"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
dependencies = [
"either",
]
@ -389,12 +517,33 @@ version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
[[package]]
name = "keccak"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654"
dependencies = [
"cpufeatures",
]
[[package]]
name = "libc"
version = "0.2.155"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
[[package]]
name = "merlin"
version = "3.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "58c38e2799fc0978b65dfff8023ec7843e2330bb462f19198840b34b6582397d"
dependencies = [
"byteorder",
"keccak",
"rand_core",
"zeroize",
]
[[package]]
name = "num-bigint"
version = "0.4.5"
@ -496,25 +645,30 @@ dependencies = [
]
[[package]]
name = "rustc_version"
version = "0.4.0"
name = "rayon"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"
dependencies = [
"semver",
"either",
"rayon-core",
]
[[package]]
name = "ryu"
version = "1.0.18"
name = "rayon-core"
version = "1.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
dependencies = [
"crossbeam-deque",
"crossbeam-utils",
]
[[package]]
name = "semver"
version = "1.0.23"
name = "ryu"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
[[package]]
name = "serde"
@ -593,14 +747,39 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
dependencies = [
"pin-project-lite",
"tracing-attributes",
"tracing-core",
]
[[package]]
name = "tracing-attributes"
version = "0.1.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.66",
]
[[package]]
name = "tracing-core"
version = "0.1.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
dependencies = [
"once_cell",
"valuable",
]
[[package]]
name = "tracing-subscriber"
version = "0.2.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e0d2eaa99c3c2e41547cfa109e910a68ea03823cccad4a0525dcbc9b01e8c71"
dependencies = [
"tracing-core",
]
[[package]]
name = "typenum"
@ -614,6 +793,12 @@ version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "valuable"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
[[package]]
name = "version_check"
version = "0.9.4"

+ 11
- 11
Cargo.toml

@ -5,25 +5,25 @@ rust-version = "1.75.0"
version = "0.1.0"
[dependencies]
ark-crypto-primitives = {version = "^0.4.0", default-features = false, features = ["sponge", "crh", "r1cs"]}
ark-ec = "^0.4.0"
ark-ed-on-bn254 = {version = "0.4.0"}
ark-ff = "^0.4.0"
ark-serialize = {version = "^0.4.0", default-features = false}
ark-std = "^0.4.0"
ark-crypto-primitives = {version = "^0.5.0", default-features = false, features = ["sponge", "crh", "r1cs"]}
ark-ec = "^0.5.0"
ark-ed-on-bn254 = {version = "0.5.0"}
ark-ff = "^0.5.0"
ark-serialize = {version = "^0.5.0", default-features = false}
ark-std = "^0.5.0"
digest = "0.10"
rand = "0.8"
rand_core = {version = "0.6", default-features = false}
# r1cs deps related under feature="r1cs"
ark-relations = { version = "^0.4.0", default-features = false, optional = true }
ark-r1cs-std = { version = "0.4.0", default-features = false, features = ["parallel"], optional = true }
ark-relations = { version = "^0.5.0", default-features = false, optional = true }
ark-r1cs-std = { version = "0.5.0", default-features = false, features = ["parallel"], optional = true }
[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"}
ark-algebra-test-templates = "0.5.0"
ark-ed-on-bls12-381 = {version = "0.5.0"}
ark-ed-on-bls12-381-bandersnatch = {version = "0.5.0"}
blake2 = "0.10"
hex = "0.4.3"
sha2 = "0.10"

+ 17
- 9
src/constraints.rs

@ -6,8 +6,11 @@ use ark_crypto_primitives::sponge::{
use ark_ec::CurveGroup;
use ark_ff::Field;
use ark_r1cs_std::{
boolean::Boolean, fields::fp::FpVar, fields::nonnative::NonNativeFieldVar, groups::CurveVar,
ToBitsGadget, ToConstraintFieldGadget,
boolean::Boolean,
convert::{ToBitsGadget, ToConstraintFieldGadget},
fields::emulated_fp::EmulatedFpVar,
fields::fp::FpVar,
groups::CurveVar,
};
use ark_relations::r1cs::ConstraintSystemRef;
@ -19,14 +22,16 @@ pub fn verify(
cs: ConstraintSystemRef<CF<C>>,
poseidon_config: PoseidonConfig<CF<C>>,
pk: GC,
sig: (GC, NonNativeFieldVar<C::ScalarField, CF<C>>),
// sig: (GC, NonNativeFieldVar<C::ScalarField, CF<C>>),
sig: (GC, Vec<Boolean<CF<C>>>),
msg: FpVar<CF<C>>,
) -> ark_relations::r1cs::Result<Boolean<CF<C>>>
where
C: CurveGroup,
GC: CurveVar<C, CF<C>> + ToConstraintFieldGadget<CF<C>>,
{
let (r, s): (GC, NonNativeFieldVar<C::ScalarField, CF<C>>) = sig;
// let (r, s): (GC, NonNativeFieldVar<C::ScalarField, CF<C>>) = sig;
let (r, s): (GC, Vec<Boolean<CF<C>>>) = sig;
let r_xy = r.to_constraint_field()?;
let pk_xy = pk.to_constraint_field()?;
@ -43,15 +48,16 @@ where
let kx_b = pk.scalar_mul_le(k.to_bits_le()?.iter())?;
let g = GC::new_constant(cs.clone(), C::generator())?;
let s_b = g.scalar_mul_le(s.to_bits_le()?.iter())?;
// let s_b = g.scalar_mul_le(s.to_bits_le()?.iter())?;
let s_b = g.scalar_mul_le(s.iter())?;
let r_rec: GC = s_b - kx_b;
Ok(r_rec.is_eq(&r)?)
}
#[cfg(test)]
mod tests {
use ark_ff::PrimeField;
use ark_r1cs_std::{alloc::AllocVar, eq::EqGadget, fields::nonnative::NonNativeFieldVar};
use ark_ff::{BigInteger, PrimeField};
use ark_r1cs_std::{alloc::AllocVar, eq::EqGadget, fields::emulated_fp::EmulatedFpVar};
use ark_relations::r1cs::ConstraintSystem;
use rand_core::OsRng;
@ -65,7 +71,7 @@ mod tests {
#[test]
fn gadget_verify() {
let poseidon_config = poseidon_config::<Fq>(4, 8, 60);
let sk = SigningKey::<EdwardsConfig>::generate::<blake2::Blake2b512>(&mut OsRng).unwrap();
let sk = SigningKey::<G>::generate::<blake2::Blake2b512>(&mut OsRng).unwrap();
let msg_raw = b"xxx yyy <<< zzz >>> bunny";
let msg = Fq::from_le_bytes_mod_order(msg_raw);
let sig = sk
@ -77,7 +83,9 @@ mod tests {
let cs = ConstraintSystem::<Fq>::new_ref();
let pk_var: GVar = GVar::new_witness(cs.clone(), || Ok(*pk.as_ref())).unwrap();
let r_var: GVar = GVar::new_witness(cs.clone(), || Ok(*sig.r())).unwrap();
let s_var = NonNativeFieldVar::<Fr, Fq>::new_witness(cs.clone(), || Ok(sig.s())).unwrap();
let s_var =
Vec::<Boolean<Fq>>::new_witness(cs.clone(), || Ok(sig.s().into_bigint().to_bits_le()))
.unwrap();
let msg_var = FpVar::<Fq>::new_witness(cs.clone(), || Ok(msg)).unwrap();
let res = verify::<G, GVar>(cs.clone(), poseidon_config, pk_var, (r_var, s_var), msg_var)

+ 59
- 49
src/eddsa.rs

@ -5,7 +5,7 @@ use ark_crypto_primitives::sponge::{
};
use ark_ec::{
twisted_edwards::{Affine, TECurveConfig},
AffineRepr,
AffineRepr, CurveGroup,
};
use ark_ff::{BigInteger, PrimeField};
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
@ -44,11 +44,11 @@ impl SecretKey {
}
/// `PublicKey` is EdDSA signature verification key
#[derive(Copy, Clone, Debug, CanonicalSerialize, CanonicalDeserialize)]
pub struct PublicKey<TE: TECurveConfig>(Affine<TE>);
#[derive(Copy, Clone, Debug, PartialEq, CanonicalSerialize, CanonicalDeserialize)]
pub struct PublicKey<C: CurveGroup>(pub C::Affine);
impl<TE: TECurveConfig> PublicKey<TE> {
pub fn xy(&self) -> Result<(&TE::BaseField, &TE::BaseField), Error> {
impl<C: CurveGroup> PublicKey<C> {
pub fn xy(&self) -> Result<(C::BaseField, C::BaseField), Error> {
self.as_ref().xy().ok_or(Error::Coordinates)
}
@ -59,41 +59,51 @@ impl PublicKey {
}
pub fn from_bytes(bytes: &[u8]) -> Result<Self, Box<dyn ark_std::error::Error>> {
let point = Affine::<TE>::deserialize_compressed(bytes)?;
let point = C::Affine::deserialize_compressed(bytes)?;
Ok(Self(point))
}
}
impl<TE: TECurveConfig> From<Affine<TE>> for PublicKey<TE> {
fn from(affine: Affine<TE>) -> Self {
Self(affine)
}
}
impl<TE: TECurveConfig> AsRef<Affine<TE>> for PublicKey<TE> {
fn as_ref(&self) -> &Affine<TE> {
// impl<C: CurveGroup> From<C::Affine> for PublicKey<C> {
// fn from(affine: C::Affine) -> Self {
// Self(affine)
// }
// }
// impl<C: CurveGroup> From<C> for PublicKey<C> {
// fn from(proj: C) -> Self {
// PublicKey(proj.into_affine())
// }
// }
// impl<C: CurveGroup> From<C::Affine> for PublicKey<C> {
// fn from(affine: C::Affine) -> Self {
// PublicKey(affine)
// }
// }
impl<C: CurveGroup> AsRef<C::Affine> for PublicKey<C> {
fn as_ref(&self) -> &C::Affine {
&self.0
}
}
#[derive(Copy, Clone, Debug)]
/// `SigningKey` produces EdDSA signatures for given message
pub struct SigningKey<TE: TECurveConfig> {
pub struct SigningKey<C: CurveGroup> {
secret_key: SecretKey,
public_key: PublicKey<TE>,
public_key: PublicKey<C>,
}
impl<TE: TECurveConfig + Clone> SigningKey<TE>
impl<C: CurveGroup + Clone> SigningKey<C>
where
TE::BaseField: PrimeField + Absorb,
C::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::BadDigestOutput)?;
let (x, _) = secret_key.expand::<TE::ScalarField, D>();
let public_key: Affine<TE> = (Affine::<TE>::generator() * x).into();
let (x, _) = secret_key.expand::<C::ScalarField, D>();
let public_key: C::Affine = (C::Affine::generator() * x).into();
let signing_key = Self {
secret_key: *secret_key,
public_key: PublicKey(public_key),
@ -117,16 +127,16 @@ where
Self::new::<D>(&secret_key)
}
pub fn public_key(&self) -> &PublicKey<TE> {
pub fn public_key(&self) -> &PublicKey<C> {
&self.public_key
}
pub fn sign<D: Digest>(
&self,
poseidon: &PoseidonConfig<TE::BaseField>,
message: &TE::BaseField,
) -> Result<Signature<TE>, Error> {
let (x, prefix) = self.secret_key.expand::<TE::ScalarField, D>();
poseidon: &PoseidonConfig<C::BaseField>,
message: &C::BaseField,
) -> Result<Signature<C>, Error> {
let (x, prefix) = self.secret_key.expand::<C::ScalarField, D>();
let mut h = D::new();
h.update(prefix);
@ -135,23 +145,23 @@ where
msg32[..msg_bytes.len()].copy_from_slice(&msg_bytes[..]);
h.update(msg32);
let r: TE::ScalarField = crate::from_digest(h);
let sig_r: Affine<TE> = (Affine::<TE>::generator() * r).into();
let r: C::ScalarField = crate::from_digest(h);
let sig_r: C::Affine = (C::Affine::generator() * r).into();
let mut poseidon = PoseidonSponge::new(poseidon);
let (sig_r_x, sig_r_y) = sig_r.xy().ok_or(Error::Coordinates)?;
poseidon.absorb(sig_r_x);
poseidon.absorb(sig_r_y);
poseidon.absorb(&sig_r_x);
poseidon.absorb(&sig_r_y);
let (pk_x, pk_y) = self.public_key.0.xy().ok_or(Error::Coordinates)?;
poseidon.absorb(pk_x);
poseidon.absorb(pk_y);
poseidon.absorb(&pk_x);
poseidon.absorb(&pk_y);
poseidon.absorb(message);
// use poseidon over Fq, so that it can be done too in-circuit
let k = poseidon.squeeze_field_elements::<TE::BaseField>(1);
let k = poseidon.squeeze_field_elements::<C::BaseField>(1);
let k = k.first().ok_or(Error::BadDigestOutput)?;
let k = TE::ScalarField::from_le_bytes_mod_order(&k.into_bigint().to_bytes_le());
let k = C::ScalarField::from_le_bytes_mod_order(&k.into_bigint().to_bytes_le());
let sig_s = (x * k) + r;
@ -159,43 +169,43 @@ where
}
}
impl<TE: TECurveConfig> SigningKey<TE> {
pub fn shared_key<D: Digest>(&self, recipient: &PublicKey<TE>) -> [u8; 32] {
let (x, _) = self.secret_key.expand::<TE::ScalarField, D>();
let shared_key: Affine<TE> = (*recipient.as_ref() * x).into();
impl<C: CurveGroup> SigningKey<C> {
pub fn shared_key<D: Digest>(&self, recipient: &PublicKey<C>) -> [u8; 32] {
let (x, _) = self.secret_key.expand::<C::ScalarField, D>();
let shared_key: C::Affine = (recipient.0 * x).into();
let mut data = Vec::new();
shared_key.serialize_compressed(&mut data).unwrap();
data[00..32].try_into().unwrap()
}
}
impl<TE: TECurveConfig + Clone> PublicKey<TE>
impl<C: CurveGroup + Clone> PublicKey<C>
where
TE::BaseField: PrimeField + Absorb,
C::BaseField: PrimeField + Absorb,
{
pub fn verify(
&self,
poseidon: &PoseidonConfig<TE::BaseField>,
message: &TE::BaseField,
signature: &Signature<TE>,
poseidon: &PoseidonConfig<C::BaseField>,
message: &C::BaseField,
signature: &Signature<C>,
) -> Result<(), Error> {
let mut poseidon = PoseidonSponge::new(poseidon);
let (sig_r_x, sig_r_y) = signature.r().xy().ok_or(Error::Coordinates)?;
poseidon.absorb(sig_r_x);
poseidon.absorb(sig_r_y);
poseidon.absorb(&sig_r_x);
poseidon.absorb(&sig_r_y);
let (pk_x, pk_y) = self.0.xy().ok_or(Error::Coordinates)?;
poseidon.absorb(pk_x);
poseidon.absorb(pk_y);
poseidon.absorb(&pk_x);
poseidon.absorb(&pk_y);
poseidon.absorb(message);
// use poseidon over Fq, so that it can be done too in-circuit
let k = poseidon.squeeze_field_elements::<TE::BaseField>(1);
let k = poseidon.squeeze_field_elements::<C::BaseField>(1);
let k = k.first().ok_or(Error::BadDigestOutput)?;
let kx_b = self.0.mul_bigint(k.into_bigint());
let s_b = Affine::<TE>::generator() * signature.s();
let r_rec: Affine<TE> = (s_b - kx_b).into();
let s_b = C::Affine::generator() * signature.s();
let r_rec: C::Affine = (s_b - kx_b).into();
(signature.r() == &r_rec).then_some(()).ok_or(Error::Verify)
}

+ 12
- 11
src/lib.rs

@ -54,7 +54,8 @@ pub fn poseidon_config(
#[cfg(test)]
mod test {
use ark_crypto_primitives::sponge::Absorb;
use ark_ec::twisted_edwards::TECurveConfig;
// use ark_ec::twisted_edwards::TECurveConfig;
use ark_ec::CurveGroup;
use ark_ff::PrimeField;
use digest::Digest;
use rand_core::OsRng;
@ -62,14 +63,14 @@ mod test {
use super::poseidon_config;
use crate::SigningKey;
fn run_test<TE: TECurveConfig + Clone, D: Digest>()
fn run_test<C: CurveGroup + Clone, D: Digest>()
where
TE::BaseField: Absorb + PrimeField,
C::BaseField: Absorb + PrimeField,
{
let poseidon = poseidon_config::<TE::BaseField>(4, 8, 55);
let signing_key = SigningKey::<TE>::generate::<D>(&mut OsRng).unwrap();
let poseidon = poseidon_config::<C::BaseField>(4, 8, 55);
let signing_key = SigningKey::<C>::generate::<D>(&mut OsRng).unwrap();
let message_raw = b"xxx yyy <<< zzz >>> bunny";
let message = TE::BaseField::from_le_bytes_mod_order(message_raw);
let message = C::BaseField::from_le_bytes_mod_order(message_raw);
let signature = signing_key.sign::<D>(&poseidon, &message).unwrap();
let public_key = signing_key.public_key();
public_key.verify(&poseidon, &message, &signature).unwrap();
@ -77,10 +78,10 @@ mod test {
#[test]
fn test_eddsa() {
run_test::<ark_ed_on_bn254::EdwardsConfig, sha2::Sha512>();
run_test::<ark_ed_on_bn254::EdwardsConfig, blake2::Blake2b512>();
run_test::<crate::ed_on_bn254_twist::EdwardsConfig, sha2::Sha512>();
run_test::<ark_ed_on_bls12_381::EdwardsConfig, sha2::Sha512>();
run_test::<ark_ed_on_bls12_381_bandersnatch::EdwardsConfig, sha2::Sha512>();
run_test::<ark_ed_on_bn254::EdwardsProjective, sha2::Sha512>();
run_test::<ark_ed_on_bn254::EdwardsProjective, blake2::Blake2b512>();
run_test::<crate::ed_on_bn254_twist::EdwardsProjective, sha2::Sha512>();
run_test::<ark_ed_on_bls12_381::EdwardsProjective, sha2::Sha512>();
run_test::<ark_ed_on_bls12_381_bandersnatch::EdwardsProjective, sha2::Sha512>();
}
}

+ 17
- 14
src/signature.rs

@ -1,18 +1,20 @@
use ark_ec::twisted_edwards::Affine;
use ark_ec::twisted_edwards::TECurveConfig;
use ark_ec::CurveGroup;
use ark_serialize::CanonicalDeserialize;
use ark_serialize::CanonicalSerialize;
/// `SignatureComponents` contains the realized parts of a signature
#[derive(Copy, Clone, Debug, CanonicalSerialize, CanonicalDeserialize)]
pub struct Signature<TE: TECurveConfig + Clone> {
r: Affine<TE>,
s: TE::ScalarField,
#[derive(Copy, Clone, Debug, PartialEq, CanonicalSerialize, CanonicalDeserialize)]
pub struct Signature<C: CurveGroup + Clone> {
pub r: C::Affine,
pub s: C::ScalarField,
}
impl<TE: TECurveConfig + Clone> Signature<TE> {
impl<C: CurveGroup + Clone> Signature<C> {
/*
/// Serializes the signature components to bytes as uncompressed.
/// Expect output size to be `size_of(TE::BaseField) * 2 + size_of(TE::ScalarField)`
/// Expect output size to be `size_of(C::BaseField) * 2 + size_of(C::ScalarField)`
pub fn to_bytes(&self) -> Vec<u8> {
let mut bytes = Vec::new();
self.r.serialize_uncompressed(&mut bytes).unwrap();
@ -21,30 +23,31 @@ impl Signature {
}
/// Checked deserialization of the signature components from bytes.
/// Expects input size to be `size_of(TE::BaseField) * 2 + size_of(TE::ScalarField)`
/// Expects input size to be `size_of(C::BaseField) * 2 + size_of(C::ScalarField)`
pub fn from_bytes(bytes: &[u8]) -> Result<Self, Box<dyn ark_std::error::Error>> {
let point_size = TE::serialized_size(ark_serialize::Compress::No);
(bytes.len() == 32 + TE::serialized_size(ark_serialize::Compress::No))
let point_size = C::Affine::Config::serialized_size(ark_serialize::Compress::No);
(bytes.len() == 32 + C::Affine::Config::serialized_size(ark_serialize::Compress::No))
.then_some(true)
.ok_or(ark_serialize::SerializationError::InvalidData)?;
let off1 = point_size;
let off2 = off1 + 32;
let r = Affine::<TE>::deserialize_uncompressed(&bytes[00..off1])?;
let s = TE::ScalarField::deserialize_uncompressed(&bytes[off1..off2])?;
let r = C::Affine::deserialize_uncompressed(&bytes[00..off1])?;
let s = C::ScalarField::deserialize_uncompressed(&bytes[off1..off2])?;
Ok(Signature { r, s })
}
*/
pub fn new(r: Affine<TE>, s: TE::ScalarField) -> Self {
pub fn new(r: C::Affine, s: C::ScalarField) -> Self {
Self { r, s }
}
pub fn r(&self) -> &Affine<TE> {
pub fn r(&self) -> &C::Affine {
&self.r
}
pub fn s(&self) -> &TE::ScalarField {
pub fn s(&self) -> &C::ScalarField {
&self.s
}
}

Loading…
Cancel
Save