mirror of
https://github.com/saymrwulf/anza-cryptography-source.git
synced 2026-09-05 20:30:51 +00:00
refactor and merge curve and ed crates (#6)
* refactor and merge curve and ed crates * fmt * ci * fmt again * ci * Update bench.rs * fix ubuntu
This commit is contained in:
parent
8024e4ed31
commit
1587b4c24f
104 changed files with 249 additions and 3417 deletions
460
Cargo.lock
generated
460
Cargo.lock
generated
|
|
@ -13,21 +13,6 @@ dependencies = [
|
|||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "addr2line"
|
||||
version = "0.25.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b"
|
||||
dependencies = [
|
||||
"gimli",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "adler2"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.4"
|
||||
|
|
@ -67,21 +52,6 @@ version = "1.5.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.76"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6"
|
||||
dependencies = [
|
||||
"addr2line",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"miniz_oxide",
|
||||
"object",
|
||||
"rustc-demangle",
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "base64ct"
|
||||
version = "1.8.3"
|
||||
|
|
@ -130,15 +100,6 @@ dependencies = [
|
|||
"wyz",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.12.0"
|
||||
|
|
@ -154,12 +115,6 @@ version = "3.20.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||
|
||||
[[package]]
|
||||
name = "cast"
|
||||
version = "0.3.0"
|
||||
|
|
@ -245,33 +200,6 @@ version = "1.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9"
|
||||
|
||||
[[package]]
|
||||
name = "color-eyre"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5920befb47832a6d61ee3a3a846565cfa39b331331e68a3b1d1116630f2f26d"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"color-spantrace",
|
||||
"eyre",
|
||||
"indenter",
|
||||
"once_cell",
|
||||
"owo-colors",
|
||||
"tracing-error",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "color-spantrace"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8b88ea9df13354b55bc7234ebcce36e6ef896aca2e42a15de9e10edce01b427"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"owo-colors",
|
||||
"tracing-core",
|
||||
"tracing-error",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "const-oid"
|
||||
version = "0.9.6"
|
||||
|
|
@ -306,9 +234,9 @@ dependencies = [
|
|||
"cast",
|
||||
"ciborium",
|
||||
"clap",
|
||||
"criterion-plot 0.5.0",
|
||||
"criterion-plot",
|
||||
"is-terminal",
|
||||
"itertools 0.10.5",
|
||||
"itertools",
|
||||
"num-traits",
|
||||
"once_cell",
|
||||
"oorandom",
|
||||
|
|
@ -322,29 +250,6 @@ dependencies = [
|
|||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "criterion"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e1c047a62b0cc3e145fa84415a3191f628e980b194c2755aa12300a4e6cbd928"
|
||||
dependencies = [
|
||||
"anes",
|
||||
"cast",
|
||||
"ciborium",
|
||||
"clap",
|
||||
"criterion-plot 0.6.0",
|
||||
"itertools 0.13.0",
|
||||
"num-traits",
|
||||
"oorandom",
|
||||
"plotters",
|
||||
"rayon",
|
||||
"regex",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tinytemplate",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "criterion-plot"
|
||||
version = "0.5.0"
|
||||
|
|
@ -352,17 +257,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1"
|
||||
dependencies = [
|
||||
"cast",
|
||||
"itertools 0.10.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "criterion-plot"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b1bcc0dc7dfae599d84ad0b1a55f80cde8af3725da8313b528da95ef783e338"
|
||||
dependencies = [
|
||||
"cast",
|
||||
"itertools 0.13.0",
|
||||
"itertools",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -406,16 +301,14 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "curve25519-dalek"
|
||||
version = "3.2.0"
|
||||
name = "curve25519-dalek-derive"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61"
|
||||
checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"digest 0.9.0",
|
||||
"rand_core 0.5.1",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -429,22 +322,13 @@ dependencies = [
|
|||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4850db49bf08e663084f7fb5c87d202ef91a3907271aff24a94eb97ff039153c"
|
||||
dependencies = [
|
||||
"block-buffer 0.12.0",
|
||||
"block-buffer",
|
||||
"crypto-common",
|
||||
]
|
||||
|
||||
|
|
@ -455,47 +339,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53"
|
||||
dependencies = [
|
||||
"pkcs8",
|
||||
"serde",
|
||||
"signature",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ed25519-heea"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"color-eyre",
|
||||
"criterion 0.7.0",
|
||||
"der",
|
||||
"ed25519",
|
||||
"ed25519-zebra",
|
||||
"hashbrown 0.16.1",
|
||||
"hex",
|
||||
"once_cell",
|
||||
"pkcs8",
|
||||
"rand 0.8.5",
|
||||
"rand_core 0.6.4",
|
||||
"serde",
|
||||
"sha2 0.11.0-rc.5",
|
||||
"solana-curve25519",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ed25519-zebra"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c85a1fff1b329c96789427b09d4d5949b2d2f717851fd1e65a18878bee19d1ff"
|
||||
dependencies = [
|
||||
"curve25519-dalek",
|
||||
"hex",
|
||||
"rand_core 0.5.1",
|
||||
"serde",
|
||||
"sha2 0.9.9",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.15.0"
|
||||
|
|
@ -518,16 +364,6 @@ dependencies = [
|
|||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "eyre"
|
||||
version = "0.6.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec"
|
||||
dependencies = [
|
||||
"indenter",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "2.3.0"
|
||||
|
|
@ -552,39 +388,12 @@ version = "0.1.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
||||
|
||||
[[package]]
|
||||
name = "foldhash"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb"
|
||||
|
||||
[[package]]
|
||||
name = "funty"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.1.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi 0.9.0+wasi-snapshot-preview1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.17"
|
||||
|
|
@ -593,7 +402,7 @@ checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0"
|
|||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi 0.11.1+wasi-snapshot-preview1",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -622,12 +431,6 @@ dependencies = [
|
|||
"wasip3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.32.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7"
|
||||
|
||||
[[package]]
|
||||
name = "half"
|
||||
version = "2.7.1"
|
||||
|
|
@ -645,7 +448,9 @@ version = "0.15.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
|
||||
dependencies = [
|
||||
"foldhash 0.1.5",
|
||||
"allocator-api2",
|
||||
"equivalent",
|
||||
"foldhash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -653,11 +458,6 @@ name = "hashbrown"
|
|||
version = "0.16.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
|
||||
dependencies = [
|
||||
"allocator-api2",
|
||||
"equivalent",
|
||||
"foldhash 0.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
|
|
@ -701,12 +501,6 @@ version = "2.3.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954"
|
||||
|
||||
[[package]]
|
||||
name = "indenter"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "964de6e86d545b246d84badc0fef527924ace5134f30641c203ef52ba83f58d5"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.13.0"
|
||||
|
|
@ -739,15 +533,6 @@ dependencies = [
|
|||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.18"
|
||||
|
|
@ -764,12 +549,6 @@ dependencies = [
|
|||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||
|
||||
[[package]]
|
||||
name = "leb128fmt"
|
||||
version = "0.1.0"
|
||||
|
|
@ -806,15 +585,6 @@ version = "2.8.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.8.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316"
|
||||
dependencies = [
|
||||
"adler2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint"
|
||||
version = "0.3.3"
|
||||
|
|
@ -844,15 +614,6 @@ dependencies = [
|
|||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.37.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.21.4"
|
||||
|
|
@ -865,18 +626,6 @@ version = "11.1.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e"
|
||||
|
||||
[[package]]
|
||||
name = "opaque-debug"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
|
||||
|
||||
[[package]]
|
||||
name = "owo-colors"
|
||||
version = "4.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d211803b9b6b570f68772237e415a029d5a50c65d382910b879fb19d3271f94d"
|
||||
|
||||
[[package]]
|
||||
name = "pem-rfc7468"
|
||||
version = "0.7.0"
|
||||
|
|
@ -886,12 +635,6 @@ dependencies = [
|
|||
"base64ct",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
|
||||
|
||||
[[package]]
|
||||
name = "pkcs8"
|
||||
version = "0.10.2"
|
||||
|
|
@ -1062,15 +805,6 @@ dependencies = [
|
|||
"rand_core 0.9.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
|
||||
dependencies = [
|
||||
"getrandom 0.1.16",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.4"
|
||||
|
|
@ -1153,12 +887,6 @@ version = "0.8.10"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b50b8869d9fc858ce7266cce0194bd74df58b9d0e3f6df3a9fc8eb470d95c09d"
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.4.1"
|
||||
|
|
@ -1308,19 +1036,6 @@ dependencies = [
|
|||
"zmij",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.9.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800"
|
||||
dependencies = [
|
||||
"block-buffer 0.9.0",
|
||||
"cfg-if",
|
||||
"cpufeatures 0.2.17",
|
||||
"digest 0.9.0",
|
||||
"opaque-debug",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.11.0-rc.5"
|
||||
|
|
@ -1329,16 +1044,7 @@ checksum = "7c5f3b1e2dc8aad28310d8410bd4d7e180eca65fca176c52ab00d364475d0024"
|
|||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures 0.2.17",
|
||||
"digest 0.11.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sharded-slab"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1352,20 +1058,36 @@ name = "signature"
|
|||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
|
||||
|
||||
[[package]]
|
||||
name = "solana-curve25519-cuda"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"criterion",
|
||||
"rand 0.8.5",
|
||||
"rand_chacha 0.3.1",
|
||||
"rand_core 0.6.4",
|
||||
"rayon",
|
||||
"solana-ed25519",
|
||||
"which",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-curve25519"
|
||||
name = "solana-ed25519"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"cfg-if",
|
||||
"cpufeatures 0.2.17",
|
||||
"criterion 0.5.1",
|
||||
"digest 0.11.2",
|
||||
"criterion",
|
||||
"curve25519-dalek-derive",
|
||||
"der",
|
||||
"digest",
|
||||
"ed25519",
|
||||
"hashbrown 0.15.5",
|
||||
"hex",
|
||||
"pkcs8",
|
||||
"proptest",
|
||||
"rand 0.10.0",
|
||||
"rand_core 0.10.0",
|
||||
|
|
@ -1373,35 +1095,11 @@ dependencies = [
|
|||
"rustcrypto-ff",
|
||||
"rustcrypto-group",
|
||||
"serde",
|
||||
"sha2 0.11.0-rc.5",
|
||||
"solana-curve25519-derive",
|
||||
"sha2",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-curve25519-cuda"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"criterion 0.5.1",
|
||||
"rand 0.8.5",
|
||||
"rand_chacha 0.3.1",
|
||||
"rand_core 0.6.4",
|
||||
"rayon",
|
||||
"solana-curve25519",
|
||||
"which",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-curve25519-derive"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spki"
|
||||
version = "0.7.3"
|
||||
|
|
@ -1459,35 +1157,6 @@ dependencies = [
|
|||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "1.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinytemplate"
|
||||
version = "1.2.1"
|
||||
|
|
@ -1498,47 +1167,6 @@ dependencies = [
|
|||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing"
|
||||
version = "0.1.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100"
|
||||
dependencies = [
|
||||
"pin-project-lite",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-core"
|
||||
version = "0.1.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"valuable",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-error"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b1581020d7a273442f5b45074a6a57d5757ad0a47dac0e9f0bd57b81936f3db"
|
||||
dependencies = [
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-subscriber"
|
||||
version = "0.3.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319"
|
||||
dependencies = [
|
||||
"sharded-slab",
|
||||
"thread_local",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.19.0"
|
||||
|
|
@ -1563,18 +1191,6 @@ version = "0.2.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
|
||||
|
||||
[[package]]
|
||||
name = "valuable"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||
|
||||
[[package]]
|
||||
name = "wait-timeout"
|
||||
version = "0.2.1"
|
||||
|
|
@ -1594,12 +1210,6 @@ dependencies = [
|
|||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.9.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.1+wasi-snapshot-preview1"
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
[workspace]
|
||||
members = [
|
||||
"curve25519/curve25519-cuda",
|
||||
"curve25519/curve25519",
|
||||
"curve25519/curve25519-derive",
|
||||
"curve25519/ed25519-heea",
|
||||
"curve25519/solana-ed25519",
|
||||
]
|
||||
resolver = "2"
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ authors = ["Anza Cryptography Team"]
|
|||
[dependencies]
|
||||
# Keep the dependency key as "curve25519" so that all existing `use curve25519::…`
|
||||
# references in source files remain valid; the actual package is curve25519-sol.
|
||||
curve25519 = { path = "../curve25519", package = "solana-curve25519" }
|
||||
curve25519 = { path = "../solana-ed25519", package = "solana-ed25519" }
|
||||
rand = "0.8"
|
||||
rand_chacha = "0.3"
|
||||
rand_core = "0.6"
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
# Changelog
|
||||
|
||||
Entries are listed in reverse chronological order per undeprecated
|
||||
major series.
|
||||
|
||||
### 0.1.1
|
||||
|
||||
* Copied over license files from [original](https://github.com/koute/unsafe_target_feature/tree/389ae00d34cf0ff589cb8d9b38a85ae1b05ebfdc) repo
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
[package]
|
||||
name = "solana-curve25519-derive"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
authors = ["Anza Cryptography Team"]
|
||||
license = "MIT OR Apache-2.0"
|
||||
readme = "README.md"
|
||||
description = "Proc-macro helpers for solana-curve25519 (forked from curve25519-derive)"
|
||||
|
||||
[lib]
|
||||
name = "curve25519_derive"
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
proc-macro2 = "1.0.66"
|
||||
quote = "1.0.31"
|
||||
syn = { version = "2.0.27", features = ["full"] }
|
||||
|
|
@ -1,201 +0,0 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
Permission is hereby granted, free of charge, to any
|
||||
person obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the
|
||||
Software without restriction, including without
|
||||
limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software
|
||||
is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice
|
||||
shall be included in all copies or substantial portions
|
||||
of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||||
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
|
@ -1,191 +0,0 @@
|
|||
# A more convenient `#[target_feature]` replacement
|
||||
|
||||
To get good performance out of SIMD everything on the SIMD codepath must be inlined.
|
||||
With how SIMD is currently implemented in Rust one of two things have to be true for
|
||||
a function using SIMD to be inlinable: (and this includes the SIMD intrinsics themselves)
|
||||
|
||||
a) The whole program has to be compiled with the relevant `-C target-cpu` or `-C target-feature` flags.
|
||||
|
||||
b) SIMD support must be automatically detected at runtime, and every function on the SIMD codepath must be marked with `#[target_feature]`.
|
||||
|
||||
Both have their downsides. Setting the `target-cpu` or `target-features` makes the resulting binary
|
||||
incompatible with older CPUs, while using `#[target_feature]` is incredibly inconvenient.
|
||||
|
||||
This crate is meant to make `#[target_feature]` less painful to use.
|
||||
|
||||
## Problems with `#[target_feature]`
|
||||
|
||||
When we're not compiling with the relevant `target-cpu`/`target-feature` flags everything on
|
||||
the SIMD codepath must be marked with the `#[target_feature]` attribute. This is not a problem
|
||||
when all of your SIMD code is neatly encapsulated inside of a single function, but once you start
|
||||
to build out more elaborate abstractions it starts to become painful to use.
|
||||
|
||||
* It can only be used on `unsafe` functions, so everything on your SIMD codepath now has to be `unsafe`.
|
||||
|
||||
In theory this is nice - these functions require the relevant SIMD instructions to be present at runtime,
|
||||
so calling them without checking is obviously unsafe! But in practice this is rarely what you want. When
|
||||
you build an abstraction over SIMD code you usually want to assume that *internally* within your module
|
||||
all of the necessary SIMD instructions are available, and you only want to check this at the boundaries
|
||||
when you're first entering your module. You do *not* want to infect everything *inside* of the module with
|
||||
`unsafe` since you've already checked this invariant at the module's API boundary.
|
||||
|
||||
* It cannot be used on non-`unsafe` trait methods.
|
||||
|
||||
If you're implementing a trait, say for example `std::ops::Add`, then you cannot mark the method `unsafe`
|
||||
unless the original trait also has it marked as `unsafe`, and usually it doesn't.
|
||||
|
||||
* It makes it impossible to abstract over a given SIMD instruction set using a trait.
|
||||
|
||||
For example, let's assume you want to abstract over which SIMD instructions you use using a trait in the following way:
|
||||
|
||||
```rust
|
||||
trait Backend {
|
||||
unsafe fn sum(input: &[u32]) -> u32;
|
||||
}
|
||||
|
||||
struct AVX;
|
||||
# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
impl Backend for AVX {
|
||||
#[target_feature(enable = "avx")]
|
||||
unsafe fn sum(xs: &[u32]) -> u32 {
|
||||
// ...
|
||||
todo!();
|
||||
}
|
||||
}
|
||||
|
||||
struct AVX2;
|
||||
# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
impl Backend for AVX2 {
|
||||
#[target_feature(enable = "avx2")]
|
||||
unsafe fn sum(xs: &[u32]) -> u32 {
|
||||
// ...
|
||||
todo!();
|
||||
}
|
||||
}
|
||||
|
||||
// And now you want a have function which calls into that trait:
|
||||
unsafe fn do_calculations<B>(xs: &[u32]) -> u32 where B: Backend {
|
||||
let value = B::sum(xs);
|
||||
// ...do some more calculations here...
|
||||
value
|
||||
}
|
||||
```
|
||||
|
||||
We have a problem here. This has to be marked with `#[target_feature]`, and that has to specify the concrete
|
||||
feature flag for a given SIMD instruction set, but this function is generic so we can't do that!
|
||||
|
||||
## How does this crate make it better?
|
||||
|
||||
### You can now mark safe functions with `#[target_feature]`
|
||||
|
||||
This crate exposes an `#[unsafe_target_feature]` macro which works just like `#[target_feature]` except
|
||||
it moves the `unsafe` from the function prototype into the macro name, and can be used on safe functions.
|
||||
|
||||
```rust
|
||||
# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
#[target_feature(enable = "avx2")]
|
||||
unsafe fn func() {}
|
||||
```
|
||||
|
||||
```rust
|
||||
use curve25519_derive::unsafe_target_feature;
|
||||
|
||||
// No `unsafe` on the function itself!
|
||||
# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
#[unsafe_target_feature("avx2")]
|
||||
fn func() {}
|
||||
```
|
||||
|
||||
It can also be used to mark functions inside of impls:
|
||||
|
||||
```rust,compile_fail
|
||||
struct S;
|
||||
|
||||
impl core::ops::Add for S {
|
||||
type Output = S;
|
||||
// ERROR: method `add` has an incompatible type for trait
|
||||
#[target_feature(enable = "avx2")]
|
||||
unsafe fn add(self, rhs: S) -> S {
|
||||
S
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```rust
|
||||
use curve25519_derive::unsafe_target_feature;
|
||||
|
||||
struct S;
|
||||
|
||||
# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
#[unsafe_target_feature("avx2")]
|
||||
impl core::ops::Add for S {
|
||||
type Output = S;
|
||||
// No `unsafe` on the function itself!
|
||||
fn add(self, rhs: S) -> S {
|
||||
S
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### You can generate specialized copies of a module for each target feature
|
||||
|
||||
```rust
|
||||
use curve25519_derive::unsafe_target_feature_specialize;
|
||||
|
||||
# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
#[unsafe_target_feature_specialize("sse2", "avx2", conditional("avx512ifma", nightly))]
|
||||
mod simd {
|
||||
#[for_target_feature("sse2")]
|
||||
pub const CONSTANT: u32 = 1;
|
||||
|
||||
#[for_target_feature("avx2")]
|
||||
pub const CONSTANT: u32 = 2;
|
||||
|
||||
#[for_target_feature("avx512ifma")]
|
||||
pub const CONSTANT: u32 = 3;
|
||||
|
||||
pub fn func() { /* ... */ }
|
||||
}
|
||||
|
||||
# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
fn entry_point() {
|
||||
#[cfg(nightly)]
|
||||
if std::is_x86_feature_detected!("avx512ifma") {
|
||||
return simd_avx512ifma::func();
|
||||
}
|
||||
|
||||
if std::is_x86_feature_detected!("avx2") {
|
||||
return simd_avx2::func();
|
||||
}
|
||||
|
||||
if std::is_x86_feature_detected!("sse2") {
|
||||
return simd_sse2::func();
|
||||
}
|
||||
|
||||
unimplemented!();
|
||||
}
|
||||
```
|
||||
|
||||
## How to use `#[unsafe_target_feature]`?
|
||||
|
||||
- Can be used on `fn`s, `impl`s and `mod`s.
|
||||
- When used on a function will only apply to that function; it won't apply to any nested functions, traits, mods, etc.
|
||||
- When used on an `impl` will only apply to all of the functions directly defined inside of that `impl`.
|
||||
- When used on a `mod` will only apply to all of the `fn`s and `impl`s directly defined inside of that `mod`.
|
||||
- Cannot be used on methods which use `self` or `Self`; instead use it on the `impl` in which the method is defined.
|
||||
|
||||
## License
|
||||
|
||||
Licensed under either of
|
||||
|
||||
* Apache License, Version 2.0, [LICENSE-APACHE](LICENSE-APACHE)
|
||||
* MIT license ([LICENSE-MIT](LICENSE-MIT))
|
||||
|
||||
at your option.
|
||||
|
||||
### Contribution
|
||||
|
||||
Unless you explicitly state otherwise, any contribution intentionally submitted
|
||||
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
|
||||
dual licensed as above, without any additional terms or conditions.
|
||||
|
|
@ -1,463 +0,0 @@
|
|||
#![doc = include_str!("../README.md")]
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
use proc_macro2::TokenStream as TokenStream2;
|
||||
use syn::spanned::Spanned;
|
||||
|
||||
macro_rules! unsupported_if_some {
|
||||
($value:expr) => {
|
||||
if let Some(value) = $value {
|
||||
return syn::Error::new(value.span(), "unsupported by #[unsafe_target_feature(...)]")
|
||||
.into_compile_error()
|
||||
.into();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! unsupported {
|
||||
($value: expr) => {
|
||||
return syn::Error::new(
|
||||
$value.span(),
|
||||
"unsupported by #[unsafe_target_feature(...)]",
|
||||
)
|
||||
.into_compile_error()
|
||||
.into()
|
||||
};
|
||||
}
|
||||
|
||||
mod kw {
|
||||
syn::custom_keyword!(conditional);
|
||||
}
|
||||
|
||||
enum SpecializeArg {
|
||||
LitStr(syn::LitStr),
|
||||
Conditional(Conditional),
|
||||
}
|
||||
|
||||
impl SpecializeArg {
|
||||
fn lit(&self) -> &syn::LitStr {
|
||||
match self {
|
||||
SpecializeArg::LitStr(lit) => lit,
|
||||
SpecializeArg::Conditional(conditional) => &conditional.lit,
|
||||
}
|
||||
}
|
||||
|
||||
fn condition(&self) -> Option<&TokenStream2> {
|
||||
match self {
|
||||
SpecializeArg::LitStr(..) => None,
|
||||
SpecializeArg::Conditional(conditional) => Some(&conditional.attr),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Conditional {
|
||||
lit: syn::LitStr,
|
||||
attr: TokenStream2,
|
||||
}
|
||||
|
||||
impl syn::parse::Parse for Conditional {
|
||||
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
|
||||
let lit = input.parse()?;
|
||||
input.parse::<syn::Token![,]>()?;
|
||||
let attr = input.parse()?;
|
||||
|
||||
Ok(Conditional { lit, attr })
|
||||
}
|
||||
}
|
||||
|
||||
impl syn::parse::Parse for SpecializeArg {
|
||||
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
|
||||
let lookahead = input.lookahead1();
|
||||
if lookahead.peek(kw::conditional) {
|
||||
input.parse::<kw::conditional>()?;
|
||||
|
||||
let content;
|
||||
syn::parenthesized!(content in input);
|
||||
|
||||
let conditional = content.parse()?;
|
||||
Ok(SpecializeArg::Conditional(conditional))
|
||||
} else {
|
||||
Ok(SpecializeArg::LitStr(input.parse()?))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct SpecializeArgs(syn::punctuated::Punctuated<SpecializeArg, syn::Token![,]>);
|
||||
|
||||
impl syn::parse::Parse for SpecializeArgs {
|
||||
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
|
||||
Ok(Self(syn::punctuated::Punctuated::parse_terminated(input)?))
|
||||
}
|
||||
}
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn unsafe_target_feature(attributes: TokenStream, input: TokenStream) -> TokenStream {
|
||||
let attributes = syn::parse_macro_input!(attributes as syn::LitStr);
|
||||
let item = syn::parse_macro_input!(input as syn::Item);
|
||||
process_item(&attributes, item, true)
|
||||
}
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn unsafe_target_feature_specialize(
|
||||
attributes: TokenStream,
|
||||
input: TokenStream,
|
||||
) -> TokenStream {
|
||||
let attributes = syn::parse_macro_input!(attributes as SpecializeArgs);
|
||||
let item_mod = syn::parse_macro_input!(input as syn::ItemMod);
|
||||
|
||||
let mut out = Vec::new();
|
||||
for attributes in attributes.0 {
|
||||
let features: Vec<_> = attributes
|
||||
.lit()
|
||||
.value()
|
||||
.split(',')
|
||||
.map(|feature| feature.replace(' ', ""))
|
||||
.collect();
|
||||
let name = format!("{}_{}", item_mod.ident, features.join("_"));
|
||||
let ident = syn::Ident::new(&name, item_mod.ident.span());
|
||||
let mut attrs = item_mod.attrs.clone();
|
||||
if let Some(condition) = attributes.condition() {
|
||||
attrs.push(syn::Attribute {
|
||||
pound_token: Default::default(),
|
||||
style: syn::AttrStyle::Outer,
|
||||
bracket_token: Default::default(),
|
||||
meta: syn::Meta::List(syn::MetaList {
|
||||
path: syn::Ident::new("cfg", attributes.lit().span()).into(),
|
||||
delimiter: syn::MacroDelimiter::Paren(Default::default()),
|
||||
tokens: condition.clone(),
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
let item_mod = process_mod(
|
||||
attributes.lit(),
|
||||
syn::ItemMod {
|
||||
attrs,
|
||||
ident,
|
||||
..item_mod.clone()
|
||||
},
|
||||
Some(features),
|
||||
);
|
||||
|
||||
out.push(item_mod);
|
||||
}
|
||||
|
||||
quote::quote! {
|
||||
#(#out)*
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
fn process_item(attributes: &syn::LitStr, item: syn::Item, strict: bool) -> TokenStream {
|
||||
match item {
|
||||
syn::Item::Fn(function) => process_function(attributes, function, None),
|
||||
syn::Item::Impl(item_impl) => process_impl(attributes, item_impl),
|
||||
syn::Item::Mod(item_mod) => process_mod(attributes, item_mod, None).into(),
|
||||
item => {
|
||||
if strict {
|
||||
unsupported!(item)
|
||||
} else {
|
||||
quote::quote! { #item }.into()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn process_mod(
|
||||
attributes: &syn::LitStr,
|
||||
mut item_mod: syn::ItemMod,
|
||||
spec_features: Option<Vec<String>>,
|
||||
) -> TokenStream2 {
|
||||
if let Some((_, ref mut content)) = item_mod.content {
|
||||
'next_item: for item in content {
|
||||
if let Some(ref spec_features) = spec_features {
|
||||
match item {
|
||||
syn::Item::Const(syn::ItemConst { ref mut attrs, .. })
|
||||
| syn::Item::Enum(syn::ItemEnum { ref mut attrs, .. })
|
||||
| syn::Item::ExternCrate(syn::ItemExternCrate { ref mut attrs, .. })
|
||||
| syn::Item::Fn(syn::ItemFn { ref mut attrs, .. })
|
||||
| syn::Item::ForeignMod(syn::ItemForeignMod { ref mut attrs, .. })
|
||||
| syn::Item::Impl(syn::ItemImpl { ref mut attrs, .. })
|
||||
| syn::Item::Macro(syn::ItemMacro { ref mut attrs, .. })
|
||||
| syn::Item::Mod(syn::ItemMod { ref mut attrs, .. })
|
||||
| syn::Item::Static(syn::ItemStatic { ref mut attrs, .. })
|
||||
| syn::Item::Struct(syn::ItemStruct { ref mut attrs, .. })
|
||||
| syn::Item::Trait(syn::ItemTrait { ref mut attrs, .. })
|
||||
| syn::Item::TraitAlias(syn::ItemTraitAlias { ref mut attrs, .. })
|
||||
| syn::Item::Type(syn::ItemType { ref mut attrs, .. })
|
||||
| syn::Item::Union(syn::ItemUnion { ref mut attrs, .. })
|
||||
| syn::Item::Use(syn::ItemUse { ref mut attrs, .. }) => {
|
||||
let mut index = 0;
|
||||
while index < attrs.len() {
|
||||
let attr = &attrs[index];
|
||||
if matches!(attr.style, syn::AttrStyle::Outer) {
|
||||
match attr.meta {
|
||||
syn::Meta::List(ref list)
|
||||
if is_path_eq(&list.path, "for_target_feature") =>
|
||||
{
|
||||
let feature: syn::LitStr = match list.parse_args() {
|
||||
Ok(feature) => feature,
|
||||
Err(error) => {
|
||||
return error.into_compile_error();
|
||||
}
|
||||
};
|
||||
|
||||
let feature = feature.value();
|
||||
if !spec_features.contains(&feature) {
|
||||
*item = syn::Item::Verbatim(Default::default());
|
||||
continue 'next_item;
|
||||
}
|
||||
|
||||
attrs.remove(index);
|
||||
continue;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
index += 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
unsupported!(item_mod);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*item = syn::Item::Verbatim(
|
||||
process_item(
|
||||
attributes,
|
||||
std::mem::replace(item, syn::Item::Verbatim(Default::default())),
|
||||
false,
|
||||
)
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
quote::quote! {
|
||||
#item_mod
|
||||
}
|
||||
}
|
||||
|
||||
fn process_impl(attributes: &syn::LitStr, mut item_impl: syn::ItemImpl) -> TokenStream {
|
||||
unsupported_if_some!(item_impl.defaultness);
|
||||
unsupported_if_some!(item_impl.unsafety);
|
||||
|
||||
let mut items = Vec::new();
|
||||
for item in item_impl.items.drain(..) {
|
||||
match item {
|
||||
syn::ImplItem::Fn(function) => {
|
||||
unsupported_if_some!(function.defaultness);
|
||||
let function = syn::ItemFn {
|
||||
attrs: function.attrs,
|
||||
vis: function.vis,
|
||||
sig: function.sig,
|
||||
block: Box::new(function.block),
|
||||
};
|
||||
let output_item = process_function(
|
||||
attributes,
|
||||
function,
|
||||
Some((item_impl.generics.clone(), item_impl.self_ty.clone())),
|
||||
);
|
||||
items.push(syn::ImplItem::Verbatim(output_item.into()));
|
||||
}
|
||||
item => items.push(item),
|
||||
}
|
||||
}
|
||||
|
||||
item_impl.items = items;
|
||||
quote::quote! {
|
||||
#item_impl
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
fn is_path_eq(path: &syn::Path, ident: &str) -> bool {
|
||||
let segments: Vec<_> = ident.split("::").collect();
|
||||
path.segments.len() == segments.len()
|
||||
&& path
|
||||
.segments
|
||||
.iter()
|
||||
.zip(segments.iter())
|
||||
.all(|(segment, expected)| segment.ident == expected && segment.arguments.is_none())
|
||||
}
|
||||
|
||||
fn process_function(
|
||||
attributes: &syn::LitStr,
|
||||
function: syn::ItemFn,
|
||||
outer: Option<(syn::Generics, Box<syn::Type>)>,
|
||||
) -> TokenStream {
|
||||
if function.sig.unsafety.is_some() {
|
||||
return quote::quote! {
|
||||
#[target_feature(enable = #attributes)]
|
||||
#function
|
||||
}
|
||||
.into();
|
||||
}
|
||||
|
||||
unsupported_if_some!(function.sig.constness);
|
||||
unsupported_if_some!(function.sig.asyncness);
|
||||
unsupported_if_some!(function.sig.abi);
|
||||
unsupported_if_some!(function.sig.variadic);
|
||||
|
||||
let function_visibility = function.vis;
|
||||
let function_name = function.sig.ident;
|
||||
let function_return = function.sig.output;
|
||||
let function_inner_name =
|
||||
syn::Ident::new(&format!("_impl_{}", function_name), function_name.span());
|
||||
let function_args = function.sig.inputs;
|
||||
let function_body = function.block;
|
||||
let mut function_call_args = Vec::new();
|
||||
let mut function_args_outer = Vec::new();
|
||||
let mut function_args_inner = Vec::new();
|
||||
for (index, arg) in function_args.iter().enumerate() {
|
||||
match arg {
|
||||
syn::FnArg::Receiver(receiver) => {
|
||||
unsupported_if_some!(receiver.attrs.first());
|
||||
unsupported_if_some!(receiver.colon_token);
|
||||
|
||||
if outer.is_none() {
|
||||
return syn::Error::new(receiver.span(), "unsupported by #[unsafe_target_feature(...)]; put the attribute on the outer `impl`").into_compile_error().into();
|
||||
}
|
||||
|
||||
function_args_inner.push(syn::FnArg::Receiver(receiver.clone()));
|
||||
function_args_outer.push(syn::FnArg::Receiver(receiver.clone()));
|
||||
function_call_args.push(syn::Ident::new("self", receiver.self_token.span()));
|
||||
}
|
||||
syn::FnArg::Typed(ty) => {
|
||||
unsupported_if_some!(ty.attrs.first());
|
||||
|
||||
match &*ty.pat {
|
||||
syn::Pat::Ident(pat_ident) => {
|
||||
unsupported_if_some!(pat_ident.attrs.first());
|
||||
|
||||
function_args_inner.push(arg.clone());
|
||||
function_args_outer.push(syn::FnArg::Typed(syn::PatType {
|
||||
attrs: Vec::new(),
|
||||
pat: Box::new(syn::Pat::Ident(syn::PatIdent {
|
||||
attrs: Vec::new(),
|
||||
by_ref: None,
|
||||
mutability: None,
|
||||
ident: pat_ident.ident.clone(),
|
||||
subpat: None,
|
||||
})),
|
||||
colon_token: ty.colon_token,
|
||||
ty: ty.ty.clone(),
|
||||
}));
|
||||
function_call_args.push(pat_ident.ident.clone());
|
||||
}
|
||||
syn::Pat::Wild(pat_wild) => {
|
||||
unsupported_if_some!(pat_wild.attrs.first());
|
||||
|
||||
let ident = syn::Ident::new(
|
||||
&format!("__arg_{}__", index),
|
||||
pat_wild.underscore_token.span(),
|
||||
);
|
||||
function_args_inner.push(arg.clone());
|
||||
function_args_outer.push(syn::FnArg::Typed(syn::PatType {
|
||||
attrs: Vec::new(),
|
||||
pat: Box::new(syn::Pat::Ident(syn::PatIdent {
|
||||
attrs: Vec::new(),
|
||||
by_ref: None,
|
||||
mutability: None,
|
||||
ident: ident.clone(),
|
||||
subpat: None,
|
||||
})),
|
||||
colon_token: ty.colon_token,
|
||||
ty: ty.ty.clone(),
|
||||
}));
|
||||
function_call_args.push(ident);
|
||||
}
|
||||
_ => unsupported!(arg),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut maybe_inline = quote::quote! {};
|
||||
let mut maybe_outer_attributes = Vec::new();
|
||||
let mut maybe_cfg = quote::quote! {};
|
||||
for attribute in function.attrs {
|
||||
match &attribute.meta {
|
||||
syn::Meta::Path(path) if is_path_eq(path, "inline") => {
|
||||
maybe_inline = quote::quote! { #[inline] };
|
||||
}
|
||||
syn::Meta::Path(path) if is_path_eq(path, "test") => {
|
||||
maybe_outer_attributes.push(attribute);
|
||||
maybe_cfg = quote::quote! { #[cfg(target_feature = #attributes)] };
|
||||
}
|
||||
syn::Meta::List(syn::MetaList { path, tokens, .. })
|
||||
if is_path_eq(path, "inline") && tokens.to_string() == "always" =>
|
||||
{
|
||||
maybe_inline = quote::quote! { #[inline] };
|
||||
}
|
||||
syn::Meta::NameValue(syn::MetaNameValue { path, .. }) if is_path_eq(path, "doc") => {
|
||||
maybe_outer_attributes.push(attribute);
|
||||
}
|
||||
syn::Meta::List(syn::MetaList { path, .. })
|
||||
if is_path_eq(path, "cfg")
|
||||
|| is_path_eq(path, "allow")
|
||||
|| is_path_eq(path, "deny") =>
|
||||
{
|
||||
maybe_outer_attributes.push(attribute);
|
||||
}
|
||||
syn::Meta::Path(path) if is_path_eq(path, "rustfmt::skip") => {
|
||||
maybe_outer_attributes.push(attribute);
|
||||
}
|
||||
_ => unsupported!(attribute),
|
||||
}
|
||||
}
|
||||
|
||||
let (fn_impl_generics, fn_ty_generics, fn_where_clause) =
|
||||
function.sig.generics.split_for_impl();
|
||||
let fn_call_generics = fn_ty_generics.as_turbofish();
|
||||
|
||||
if let Some((generics, self_ty)) = outer {
|
||||
let (outer_impl_generics, outer_ty_generics, outer_where_clause) =
|
||||
generics.split_for_impl();
|
||||
let trait_ident =
|
||||
syn::Ident::new(&format!("__Impl_{}__", function_name), function_name.span());
|
||||
let item_trait = quote::quote! {
|
||||
#[allow(non_camel_case_types)]
|
||||
trait #trait_ident #outer_impl_generics #outer_where_clause {
|
||||
unsafe fn #function_inner_name #fn_impl_generics (#(#function_args_outer),*) #function_return #fn_where_clause;
|
||||
}
|
||||
};
|
||||
|
||||
let item_trait_impl = quote::quote! {
|
||||
impl #outer_impl_generics #trait_ident #outer_ty_generics for #self_ty #outer_where_clause {
|
||||
#[target_feature(enable = #attributes)]
|
||||
#maybe_inline
|
||||
unsafe fn #function_inner_name #fn_impl_generics (#(#function_args_inner),*) #function_return #fn_where_clause #function_body
|
||||
}
|
||||
};
|
||||
|
||||
quote::quote! {
|
||||
#[inline(always)]
|
||||
#(#maybe_outer_attributes)*
|
||||
#function_visibility fn #function_name #fn_impl_generics (#(#function_args_outer),*) #function_return #fn_where_clause {
|
||||
#item_trait
|
||||
#item_trait_impl
|
||||
unsafe {
|
||||
<Self as #trait_ident #outer_ty_generics> ::#function_inner_name #fn_call_generics (#(#function_call_args),*)
|
||||
}
|
||||
}
|
||||
}.into()
|
||||
} else {
|
||||
quote::quote! {
|
||||
#[inline(always)]
|
||||
#maybe_cfg
|
||||
#(#maybe_outer_attributes)*
|
||||
#function_visibility fn #function_name #fn_impl_generics (#(#function_args_outer),*) #function_return #fn_where_clause {
|
||||
#[target_feature(enable = #attributes)]
|
||||
#maybe_inline
|
||||
unsafe fn #function_inner_name #fn_impl_generics (#(#function_args_inner),*) #function_return #fn_where_clause #function_body
|
||||
unsafe {
|
||||
#function_inner_name #fn_call_generics (#(#function_call_args),*)
|
||||
}
|
||||
}
|
||||
}.into()
|
||||
}
|
||||
}
|
||||
|
|
@ -1,152 +0,0 @@
|
|||
#![cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
#![allow(dead_code)]
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use curve25519_derive::{unsafe_target_feature, unsafe_target_feature_specialize};
|
||||
|
||||
#[unsafe_target_feature("sse2")]
|
||||
/// A doc comment.
|
||||
fn function(a: u32, b: u32) -> u32 {
|
||||
a - b
|
||||
}
|
||||
|
||||
#[unsafe_target_feature("sse2")]
|
||||
fn function_with_const_arg<const N: u32>(b: u32) -> u32 {
|
||||
N - b
|
||||
}
|
||||
|
||||
#[unsafe_target_feature("sse2")]
|
||||
fn function_with_where_clause<T>(a: T, b: T) -> T::Output
|
||||
where
|
||||
T: Copy + core::ops::Sub,
|
||||
{
|
||||
a - b
|
||||
}
|
||||
|
||||
#[unsafe_target_feature("sse2")]
|
||||
#[rustfmt::skip]
|
||||
fn function_with_rustfmt_skip() {}
|
||||
|
||||
struct Struct {
|
||||
a: u32,
|
||||
}
|
||||
|
||||
#[unsafe_target_feature("sse2")]
|
||||
impl Struct {
|
||||
#[allow(unused_mut)]
|
||||
fn member_function(&self, mut b: u32) -> u32 {
|
||||
self.a - b
|
||||
}
|
||||
|
||||
fn member_function_with_const_arg<const N: u32>(self) -> u32 {
|
||||
self.a - N
|
||||
}
|
||||
}
|
||||
|
||||
struct StructWithGenerics<T>
|
||||
where
|
||||
T: Copy + core::ops::Sub,
|
||||
{
|
||||
a: T,
|
||||
}
|
||||
|
||||
#[unsafe_target_feature("sse2")]
|
||||
impl<T> StructWithGenerics<T>
|
||||
where
|
||||
T: Copy + core::ops::Sub,
|
||||
{
|
||||
#[inline]
|
||||
fn member_function(&self, b: T) -> T::Output {
|
||||
self.a - b
|
||||
}
|
||||
}
|
||||
|
||||
struct StructWithGenericsNoWhere<T: Copy + core::ops::Sub> {
|
||||
a: T,
|
||||
}
|
||||
|
||||
#[unsafe_target_feature("sse2")]
|
||||
impl<T: Copy + core::ops::Sub> StructWithGenericsNoWhere<T> {
|
||||
#[inline(always)]
|
||||
fn member_function(&self, b: T) -> T::Output {
|
||||
self.a - b
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe_target_feature("sse2")]
|
||||
#[allow(dead_code)]
|
||||
impl<'a> From<&'a Struct> for () {
|
||||
fn from(_: &'a Struct) -> Self {}
|
||||
}
|
||||
|
||||
#[unsafe_target_feature("sse2")]
|
||||
mod inner {
|
||||
fn inner_function(a: u32, b: u32) -> u32 {
|
||||
a - b
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe_target_feature_specialize("sse2", "avx2")]
|
||||
mod inner_spec {
|
||||
#[for_target_feature("sse2")]
|
||||
const CONST: u32 = 1;
|
||||
|
||||
#[for_target_feature("avx2")]
|
||||
const CONST: u32 = 2;
|
||||
|
||||
pub fn spec_function(a: u32, b: u32) -> u32 {
|
||||
a - b - CONST
|
||||
}
|
||||
|
||||
#[for_target_feature("sse2")]
|
||||
const IS_AVX2: bool = false;
|
||||
|
||||
#[for_target_feature("avx2")]
|
||||
const IS_AVX2: bool = true;
|
||||
|
||||
#[test]
|
||||
fn test_specialized() {
|
||||
#[allow(clippy::assertions_on_constants)]
|
||||
{
|
||||
assert!(!IS_AVX2);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn test_specialized_inner() {
|
||||
#[allow(clippy::assertions_on_constants)]
|
||||
{
|
||||
assert!(!super::IS_AVX2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe_target_feature("sse2")]
|
||||
#[test]
|
||||
fn test_sse2_only() {}
|
||||
|
||||
// it turns out that for compilation to succeed, the feature needs be supported by rustc. For this
|
||||
// test actually verify what happens when the target_feature is not enabled, this needs to be a
|
||||
// pretty esoteric feature. Looking at the table of supported avx512 features at
|
||||
// https://en.wikipedia.org/wiki/AVX-512#CPUs_with_AVX-512 it seems avx512vp2intersect is one of the
|
||||
// most unusual ones that has rustc knows about
|
||||
#[unsafe_target_feature("avx512vp2intersect")]
|
||||
#[test]
|
||||
fn test_unset_target_feature() {
|
||||
compile_error!("When an unknown target_feature is set on a test, unsafe_target_feature is expected remove the function");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_function() {
|
||||
assert_eq!(function(10, 3), 7);
|
||||
assert_eq!(function_with_where_clause(10, 3), 7);
|
||||
assert_eq!(function_with_const_arg::<10>(3), 7);
|
||||
assert_eq!(Struct { a: 10 }.member_function(3), 7);
|
||||
assert_eq!(StructWithGenerics { a: 10 }.member_function(3), 7);
|
||||
assert_eq!(StructWithGenericsNoWhere { a: 10 }.member_function(3), 7);
|
||||
assert_eq!(inner_spec_sse2::spec_function(10, 3), 6);
|
||||
assert_eq!(inner_spec_avx2::spec_function(10, 3), 5);
|
||||
}
|
||||
|
|
@ -1,136 +0,0 @@
|
|||
# CHANGELOG
|
||||
|
||||
Entries are listed in reverse chronological order.
|
||||
|
||||
# 4.2.0
|
||||
|
||||
* Bump MSRV from 1.65 to 1.85.
|
||||
* Bump `hashbrown` from 0.15 to 0.16.
|
||||
|
||||
# 4.1.0
|
||||
|
||||
* Implement `PartialEq` and `Eq` in `SigningKey` and `VerificationKey` (#102)
|
||||
* Add `alloc` feature by @nazar-pc in (#161, #174)
|
||||
* Add helper methods by @conradoplg in (#179)
|
||||
|
||||
Note: to use Rust older than `1.85`, you will need to downgrade the `base64ct`
|
||||
crate:
|
||||
|
||||
```
|
||||
cargo update base64ct --precise 1.6.0
|
||||
```
|
||||
|
||||
# 4.0.3
|
||||
|
||||
* Update `curve25519` to `4.1.0`
|
||||
|
||||
# 4.0.2
|
||||
|
||||
* Update `curve25519` to `4.0.0`
|
||||
|
||||
# 4.0.1
|
||||
|
||||
* Fix no-std build with serde activated (#87)
|
||||
* Update `curve25519` to `4.0.0-rc.3`
|
||||
|
||||
# 4.0.0
|
||||
|
||||
* `Signature` is now an alias for `ed25519::Signature`
|
||||
* `impl From<Signature> for [u8; 64]` no longer exists; use `to_bytes()` instead.
|
||||
* `signature::{Signer, Verifier} is now implemented for `SigningKey` and `VerificationKey`.
|
||||
* Updates `sha2` version to `0.10` and `curve25519` version to `4.0.0-rc.2`.
|
||||
* Add DER & PEM support for SigningKeySeed and VerificationKeyBytes (RFC 8410) #46 https://github.com/ZcashFoundation/ed25519-zebra/pull/46
|
||||
* This is under the non-default `pem` and `pkcs8` features
|
||||
|
||||
MSRV increased to `1.65.0`.
|
||||
|
||||
# 3.1.0
|
||||
|
||||
* Add no_std support by @pvdrz in https://github.com/ZcashFoundation/ed25519-zebra/pull/57
|
||||
|
||||
# 3.0.0
|
||||
|
||||
* Fix typo by @rex4539 in https://github.com/ZcashFoundation/ed25519-zebra/pull/32
|
||||
* Add Zeroize impl for SigningKey by @kim in https://github.com/ZcashFoundation/ed25519-zebra/pull/34
|
||||
* Add JNI code for ed25519-zebra by @droark in https://github.com/ZcashFoundation/ed25519-zebra/pull/37
|
||||
* Update rand_core to 0.6 and rand to 0.8 by @dconnolly in https://github.com/ZcashFoundation/ed25519-zebra/pull/44
|
||||
* dependencies: update zeroize to 1.2 by @FintanH in https://github.com/ZcashFoundation/ed25519-zebra/pull/52
|
||||
|
||||
# 2.2.0
|
||||
|
||||
* Add `PartialOrd`, `Ord` implementations for `VerificationKeyBytes`. While
|
||||
the derived ordering is not cryptographically meaningful, deriving these
|
||||
traits is useful because it allows, e.g., using `VerificationKeyBytes` as the
|
||||
key to a `BTreeMap` (contributed by @cloudhead).
|
||||
|
||||
# 2.1.2
|
||||
|
||||
* Updates `sha2` version to `0.9` and `curve25519` version to `3`.
|
||||
|
||||
# 2.1.1
|
||||
|
||||
* Add a missing multiplication by the cofactor in batch verification and test
|
||||
that individual and batch verification agree. This corrects an omission that
|
||||
should have been included in `2.0.0`.
|
||||
|
||||
# 2.1.0
|
||||
|
||||
* Implements `Clone + Debug` for `batch::Item` and provides
|
||||
`batch::Item::verify_single` to perform fallback verification in case
|
||||
of batch failure.
|
||||
|
||||
# 2.0.0
|
||||
|
||||
* Implements ZIP 215, so that batched and individual verification
|
||||
agree on whether signatures are valid.
|
||||
|
||||
# 1.0.0
|
||||
|
||||
* Adds `impl TryFrom<&[u8]>` for all types.
|
||||
|
||||
# 1.0.0-pre.0
|
||||
|
||||
* Add a note about versioning to handle ZIP 215.
|
||||
|
||||
# 0.4.1
|
||||
|
||||
* Change `docs.rs` configuration in `Cargo.toml` to not refer to the removed
|
||||
`batch` feature so that the docs render correctly on `docs.rs`.
|
||||
|
||||
# 0.4.0
|
||||
|
||||
* The sync batch verification api is changed to remove a dependence on the
|
||||
message lifetime that made it difficult to use in async contexts.
|
||||
|
||||
# 0.3.0
|
||||
|
||||
* Change terminology from secret and public keys to signing and verification
|
||||
keys.
|
||||
* Remove async batch verification in favor of a sync api; the async approach is
|
||||
to be developed in another crate.
|
||||
|
||||
# 0.2.3
|
||||
|
||||
* The previous implementation exactly matched the behavior of `libsodium`
|
||||
`1.0.15` with the `ED25519_COMPAT` configuration, but this configuration
|
||||
wasn't used by `zcashd`. This commit changes the validation rules to exactly
|
||||
match without `ED25519_COMPAT`, and highlights the remaining inconsistencies
|
||||
with the Zcash specification that were not addressed in the previous spec
|
||||
fix.
|
||||
|
||||
# 0.2.2
|
||||
|
||||
* Adds `impl AsRef<[u8]> for PublicKey`.
|
||||
* Adds `impl AsRef<[u8]> for SecretKey`.
|
||||
|
||||
# 0.2.1
|
||||
|
||||
* Adds `impl AsRef<[u8]> for PublicKeyBytes`.
|
||||
|
||||
# 0.2.0
|
||||
|
||||
* Adds experimental futures-based batch verification API, gated by the `batch` feature.
|
||||
|
||||
# 0.1.0
|
||||
|
||||
Initial release, attempting to match the actual `zcashd` behavior.
|
||||
1190
curve25519/ed25519-heea/Cargo.lock
generated
1190
curve25519/ed25519-heea/Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -1,79 +0,0 @@
|
|||
[package]
|
||||
name = "ed25519-heea"
|
||||
version = "0.1.0"
|
||||
rust-version = "1.85.0"
|
||||
authors = [
|
||||
"Henry de Valence <hdevalence@hdevalence.ca>",
|
||||
"Zcash Foundation <zebra@zfnd.org>",
|
||||
"Anza Cryptography Team",
|
||||
]
|
||||
license = "MIT OR Apache-2.0"
|
||||
edition = "2024"
|
||||
description = "ZIP-215-compliant Ed25519 with HEEA-accelerated verification (forked from ed25519-zebra)"
|
||||
resolver = "2"
|
||||
include = [
|
||||
"/src",
|
||||
"/README.md",
|
||||
"/CHANGELOG.md",
|
||||
"/LICENSE-APACHE",
|
||||
"/LICENSE-MIT",
|
||||
"/tests",
|
||||
"/benches",
|
||||
]
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
features = ["nightly"]
|
||||
|
||||
[dependencies]
|
||||
# Keep the dependency key as "curve25519" so that all existing `use curve25519::…`
|
||||
# references in source files remain valid; the actual package is curve25519-sol.
|
||||
curve25519 = { path = "../curve25519", package = "solana-curve25519", default-features = false, features = ["digest", "zeroize", "precomputed-tables"] }
|
||||
der = { version = "0.7.9", optional = true }
|
||||
ed25519 = { version = "2.2.3", default-features = false }
|
||||
hashbrown = { version = "0.16", optional = true }
|
||||
pkcs8 = { version = "0.10.1", optional = true, features = ["pem"] }
|
||||
rand_core = "0.6"
|
||||
serde = { version = "1", default-features = false, optional = true, features = ["derive"] }
|
||||
sha2 = { version = "0.11.0-rc.3", default-features = false }
|
||||
subtle = { version = "2.6.1", default-features = false }
|
||||
zeroize = { version = "1.8", default-features = false, features = ["derive"] }
|
||||
|
||||
[dev-dependencies]
|
||||
rand = "0.8"
|
||||
bincode = "1"
|
||||
criterion = "0.7"
|
||||
ed25519-zebra-legacy = { package = "ed25519-zebra", version = "1" }
|
||||
color-eyre = "0.6"
|
||||
hex = { version = "0.4.3", default-features = false, features = ["alloc"] }
|
||||
once_cell = "1.21"
|
||||
|
||||
[features]
|
||||
nightly = []
|
||||
default = ["serde", "std"]
|
||||
alloc = [
|
||||
"curve25519/alloc",
|
||||
"ed25519/alloc",
|
||||
"hashbrown",
|
||||
"pkcs8?/alloc",
|
||||
"zeroize/alloc",
|
||||
]
|
||||
pem = ["pkcs8", "dep:der", "ed25519/pem"]
|
||||
pkcs8 = ["dep:pkcs8", "ed25519/pkcs8", "alloc"]
|
||||
serde = ["dep:serde", "ed25519/serde"]
|
||||
std = ["alloc", "ed25519/std", "subtle/std"]
|
||||
|
||||
[[test]]
|
||||
name = "rfc8032"
|
||||
|
||||
[[test]]
|
||||
name = "unit_tests"
|
||||
|
||||
[[test]]
|
||||
name = "batch"
|
||||
|
||||
[[test]]
|
||||
name = "heea"
|
||||
|
||||
[[bench]]
|
||||
name = "bench"
|
||||
harness = false
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
## Release Checklist
|
||||
|
||||
- Run `cargo semver-checks` to see if a major version bump is required
|
||||
- Bump version in Cargo.toml
|
||||
- If major version was bumped, update README.md
|
||||
- Update CHANGELOG.md
|
||||
- Ensure the MSRV in Cargo.toml (`rust-version` key) is equal to the MSRV being
|
||||
tested (main.yml)
|
||||
- Update locked dependencies: `cargo update`. Run `cargo test --all-features`
|
||||
to check if anything breaks. If that happens, see next section.
|
||||
- Test if it's publishable: `cargo publish --dry-run`
|
||||
- Open a PR with the version bump and changelog update, wait for review and merge
|
||||
- Tag a new release in GitHub: https://github.com/ZcashFoundation/ed25519-zebra/releases/new
|
||||
- Create a tag with the version (e.g. `4.0.3`)
|
||||
- Name: e.g. `ed25519-zebra 4.0.3`
|
||||
- Paste the changelog for the version
|
||||
- Publish: `cargo publish`
|
||||
|
||||
## If something breaks
|
||||
|
||||
If testing broke after running `cargo update`, first determine if it's a
|
||||
test-only dependency or not. Run `cargo build --all-features`. If that works,
|
||||
then it's probably a test-only dependency, and you can avoid updating that
|
||||
specific dependency (leave a old version in the lockfile). Otherwise investigate
|
||||
why it caused build to fail.
|
||||
|
||||
If the "test on nightly" test failed, then either there is some bug in the code
|
||||
or some dependency update caused it to fail. Investigate and if it's the latter,
|
||||
you can either downgrade in the lockfile or try to workaround it.
|
||||
|
||||
If the "build with no_std" test failed, then some change was introduced that
|
||||
depended on the std-library. You will probably need to fix this by changing
|
||||
to some no_std dependency, or gating the code so it only compiles when
|
||||
`std` is enabled.
|
||||
|
||||
If one of the dependencies bumped its MSRV, we might require a MSRV bump too:
|
||||
|
||||
- Double check if the dependency is not a test-only dependency. (The MSRV
|
||||
test in CI only builds the library but does not test it, to prevent
|
||||
a test-only dependency MSRV bump from breaking it.)
|
||||
- If it's not a test-only dependency, check if the main consumers of the
|
||||
library are OK with a MSRV bump. I usually ask ECC devs.
|
||||
- If it's OK, bump it in Cargo.toml and main.yml.
|
||||
- If not, you will need to find some workaround.
|
||||
|
|
@ -1,203 +0,0 @@
|
|||
Copyright (c) 2020 Zcash Foundation
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
Copyright (c) 2020 Zcash Foundation
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
|
|
@ -1,139 +0,0 @@
|
|||
# ed25519-heea
|
||||
|
||||
**ZIP-215-compliant Ed25519 signatures with HEEA-accelerated verification, forked from
|
||||
[ed25519-zebra].**
|
||||
|
||||
> For the original ed25519-zebra documentation see [README_zebra.md](README_zebra.md).
|
||||
|
||||
This crate is part of the [curve25519-sol](../README.md) workspace.
|
||||
|
||||
---
|
||||
|
||||
## Changes from ed25519-zebra
|
||||
|
||||
### `verify_heea`: fast-path signature verification
|
||||
|
||||
A new method `VerificationKey::verify_heea` has been added alongside the existing `verify`.
|
||||
Both methods accept the same arguments and produce identical results — `verify_heea` is a
|
||||
**drop-in accelerated replacement** for `verify`.
|
||||
|
||||
The HEEA method (from the TCHES 2025 paper _"Accelerating EdDSA Signature Verification with
|
||||
Faster Scalar Size Halving"_) transforms the standard 2-point MSM:
|
||||
|
||||
```text
|
||||
[8][s]B = [8]R + [8][h]A (standard)
|
||||
```
|
||||
|
||||
into a 4-point MSM over half-size (~128-bit) scalars:
|
||||
|
||||
```text
|
||||
τs_lo·B + τs_hi·(2¹²⁸·B) = τ·R + ρ·A (HEEA)
|
||||
```
|
||||
|
||||
where `ρ ≡ ±τ·h (mod ℓ)` and `τs = τs_hi·2¹²⁸ + τs_lo`. All four scalars are ≤128 bits,
|
||||
and the two basepoints (`B` and `2¹²⁸B`) use precomputed lookup tables, giving approximately
|
||||
**~15% faster** verification compared to the standard path.
|
||||
|
||||
### Dependencies
|
||||
|
||||
`ed25519-zebra` was updated to depend on this fork's `curve25519` crate instead of
|
||||
`curve25519-dalek`, in order to access `HEEADecomposition` and `vartime_triple_scalar_mul_basepoint`.
|
||||
|
||||
---
|
||||
|
||||
## ZIP 215
|
||||
|
||||
ZIP-215-compliant Ed25519 validation rules are fully preserved from ed25519-zebra:
|
||||
|
||||
- Non-canonical point encodings are accepted for `A` and `R`.
|
||||
- `s` must be a canonical integer less than the group order `ℓ`.
|
||||
- The cofactor-cleared equation `[8][s]B = [8]R + [8][h]A` is used (not the RFC 8032 variant).
|
||||
|
||||
See [README_zebra.md](README_zebra.md) and [ZIP 215] for full details.
|
||||
|
||||
---
|
||||
|
||||
## Usage
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
ed25519-heea = { git = "https://github.com/zz-sol/ed25519-sol", package = "ed25519-heea" }
|
||||
```
|
||||
|
||||
### Example
|
||||
|
||||
```rust,no_run
|
||||
use core::convert::TryFrom;
|
||||
use rand::thread_rng;
|
||||
use ed25519_heea::{SigningKey, VerificationKey};
|
||||
|
||||
let msg = b"curve25519-sol";
|
||||
|
||||
// Generate key and sign
|
||||
let sk = SigningKey::new(thread_rng());
|
||||
let sig = sk.sign(msg);
|
||||
let vk = VerificationKey::from(&sk);
|
||||
|
||||
// Standard ZIP-215 verification (from ed25519-zebra)
|
||||
vk.verify(&sig, msg).expect("valid signature");
|
||||
|
||||
// HEEA-accelerated verification (same result, ~15% faster)
|
||||
vk.verify_heea(&sig, msg).expect("valid signature");
|
||||
```
|
||||
|
||||
### Batch verification
|
||||
|
||||
Batch verification is unchanged from ed25519-zebra and uses a randomised linear combination to
|
||||
check multiple signatures in one pass:
|
||||
|
||||
```rust,ignore
|
||||
#[cfg(feature = "alloc")]
|
||||
{
|
||||
use ed25519_heea::batch;
|
||||
|
||||
let mut verifier = batch::Verifier::new();
|
||||
for (vk_bytes, sig, msg) in items {
|
||||
verifier.queue((vk_bytes, sig, msg));
|
||||
}
|
||||
verifier.verify(thread_rng()).expect("all valid");
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Features
|
||||
|
||||
| Feature | Default? | Description |
|
||||
|---|:---:|---|
|
||||
| `std` | ✓ | Enables `std`; without it the crate is `no_std` + `alloc`. |
|
||||
| `alloc` | ✓ | Enables batch verification. |
|
||||
| `serde` | | Serialization for key and signature types. |
|
||||
| `pkcs8` | | PKCS#8 DER encoding/decoding for `VerificationKey`. |
|
||||
|
||||
---
|
||||
|
||||
## MSRV
|
||||
|
||||
Rust **1.85.0** (Edition 2024).
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- [TCHES 2025 paper] – _Accelerating EdDSA Signature Verification with Faster Scalar Size Halving_
|
||||
- [ed25519-zebra] – upstream library (Zcash Foundation)
|
||||
- [ZIP 215] – Ed25519 validation rules for Zcash
|
||||
- [Original ed25519-zebra README](README_zebra.md)
|
||||
|
||||
## License
|
||||
|
||||
Licensed under either of
|
||||
|
||||
- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE))
|
||||
- MIT license ([LICENSE-MIT](LICENSE-MIT))
|
||||
|
||||
at your option.
|
||||
|
||||
[TCHES 2025 paper]: https://tches.iacr.org/index.php/TCHES/article/view/11971
|
||||
[ed25519-zebra]: https://github.com/ZcashFoundation/ed25519-zebra
|
||||
[ZIP 215]: https://zips.z.cash/zip-0215
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
[package]
|
||||
name = "solana-curve25519"
|
||||
name = "solana-ed25519"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
rust-version = "1.85.0"
|
||||
|
|
@ -30,7 +30,6 @@ rustdoc-args = [
|
|||
all-features = true
|
||||
|
||||
[dev-dependencies]
|
||||
sha2 = { version = "0.11.0-rc.3", default-features = false }
|
||||
bincode = "1"
|
||||
criterion = { version = "0.5", features = ["html_reports"] }
|
||||
hex = "0.4.2"
|
||||
|
|
@ -43,39 +42,46 @@ rustc_version = "0.4.0"
|
|||
[[bench]]
|
||||
name = "dalek_benchmarks"
|
||||
harness = false
|
||||
required-features = ["alloc", "rand_core"]
|
||||
required-features = ["alloc"]
|
||||
|
||||
[dependencies]
|
||||
cfg-if = "1"
|
||||
ed25519 = { version = "2.2.3", default-features = false }
|
||||
ff = { version = "=0.14.0-pre.0", package = "rustcrypto-ff", default-features = false, optional = true }
|
||||
group = { version = "=0.14.0-pre.0", package = "rustcrypto-group", default-features = false, optional = true }
|
||||
rand_core = { version = "0.10.0-rc-3", default-features = false, optional = true }
|
||||
digest = { version = "0.11.0-rc.4", default-features = false, optional = true, features = [
|
||||
"block-api",
|
||||
] }
|
||||
hashbrown = { version = "0.15" }
|
||||
der = { version = "0.7.9", optional = true }
|
||||
pkcs8 = { version = "0.10.1", optional = true, features = ["pem"] }
|
||||
sha2 = { version = "0.11.0-rc.3", default-features = false }
|
||||
subtle = { version = "2.6.0", default-features = false, features = [
|
||||
"const-generics",
|
||||
] }
|
||||
serde = { version = "1.0", default-features = false, optional = true, features = [
|
||||
"derive",
|
||||
] }
|
||||
zeroize = { version = "1", default-features = false, optional = true }
|
||||
zeroize = { version = "1", default-features = false, optional = true, features = ["derive"] }
|
||||
|
||||
# Keep the dependency key as "curve25519-derive" so existing #[curve25519_derive::…]
|
||||
# attributes in source files remain valid; the actual package is curve25519-derive-sol.
|
||||
[target.'cfg(target_arch = "x86_64")'.dependencies]
|
||||
cpufeatures = "0.2.17"
|
||||
curve25519-derive = { path = "../curve25519-derive", package = "solana-curve25519-derive" }
|
||||
curve25519-dalek-derive = "0.1.1"
|
||||
|
||||
[features]
|
||||
default = ["alloc", "precomputed-tables", "zeroize"]
|
||||
default = ["alloc", "precomputed-tables", "zeroize", "rand_core", "digest"]
|
||||
alloc = ["zeroize?/alloc"]
|
||||
precomputed-tables = []
|
||||
legacy_compatibility = []
|
||||
rand_core = ["dep:rand_core"]
|
||||
std = ["alloc"]
|
||||
group = ["dep:group", "rand_core"]
|
||||
group-bits = ["group", "ff/bits"]
|
||||
digest = ["dep:digest"]
|
||||
lizard = ["digest"]
|
||||
pkcs8 = ["dep:pkcs8", "ed25519/pkcs8", "alloc"]
|
||||
pem = ["pkcs8", "dep:der", "ed25519/pem"]
|
||||
|
||||
[lints.rust.unexpected_cfgs]
|
||||
level = "warn"
|
||||
|
|
@ -48,12 +48,86 @@ have been removed.
|
|||
|
||||
---
|
||||
|
||||
## Ed25519 Signatures (`ed_sigs`)
|
||||
|
||||
This crate includes a **ZIP-215-compliant Ed25519 signature implementation** in the
|
||||
`ed_sigs` module, forked from [ed25519-zebra] and extended with HEEA-accelerated
|
||||
verification.
|
||||
|
||||
> For the original ed25519-zebra documentation see [README_zebra.md](README_zebra.md).
|
||||
|
||||
### `verify_heea`: fast-path signature verification
|
||||
|
||||
A new method `VerificationKey::verify_heea` sits alongside the existing `verify`.
|
||||
Both accept the same arguments and produce identical results — `verify_heea` is a
|
||||
**drop-in accelerated replacement** for `verify`.
|
||||
|
||||
The HEEA method (TCHES 2025) transforms the standard 2-point MSM:
|
||||
|
||||
```text
|
||||
[8][s]B = [8]R + [8][h]A (standard)
|
||||
```
|
||||
|
||||
into a 4-point MSM over half-size (~128-bit) scalars:
|
||||
|
||||
```text
|
||||
τs_lo·B + τs_hi·(2¹²⁸·B) = τ·R + ρ·A (HEEA)
|
||||
```
|
||||
|
||||
where `ρ ≡ ±τ·h (mod ℓ)` and `τs = τs_hi·2¹²⁸ + τs_lo`. All four scalars are ≤128 bits
|
||||
and the two basepoints (`B` and `2¹²⁸B`) use precomputed lookup tables, giving approximately
|
||||
**~15% faster** verification compared to the standard path.
|
||||
|
||||
### ZIP 215
|
||||
|
||||
ZIP-215-compliant Ed25519 validation rules are fully preserved from ed25519-zebra:
|
||||
|
||||
- Non-canonical point encodings are accepted for `A` and `R`.
|
||||
- `s` must be a canonical integer less than the group order `ℓ`.
|
||||
- The cofactor-cleared equation `[8][s]B = [8]R + [8][h]A` is used (not the RFC 8032 variant).
|
||||
|
||||
See [ZIP 215] for full details.
|
||||
|
||||
---
|
||||
|
||||
## Use
|
||||
|
||||
```toml
|
||||
curve25519-sol = { git = "https://github.com/zz-sol/ed25519-sol" }
|
||||
```
|
||||
|
||||
### Ed25519 signing and verification
|
||||
|
||||
```rust,no_run
|
||||
use core::convert::TryFrom;
|
||||
use curve25519::ed_sigs::{SigningKey, VerificationKey};
|
||||
|
||||
let msg = b"curve25519-sol";
|
||||
|
||||
// Generate key and sign
|
||||
let sk = SigningKey::new(rand::rng());
|
||||
let sig = sk.sign(msg);
|
||||
let vk = VerificationKey::from(&sk);
|
||||
|
||||
// Standard ZIP-215 verification (from ed25519-zebra)
|
||||
vk.verify(&sig, msg).expect("valid signature");
|
||||
|
||||
// HEEA-accelerated verification (same result, ~15% faster)
|
||||
vk.verify_heea(&sig, msg).expect("valid signature");
|
||||
```
|
||||
|
||||
### Batch verification
|
||||
|
||||
```rust,ignore
|
||||
use curve25519::ed_sigs::batch;
|
||||
|
||||
let mut verifier = batch::Verifier::new();
|
||||
for (vk_bytes, sig, msg) in items {
|
||||
verifier.queue((vk_bytes, sig, msg));
|
||||
}
|
||||
verifier.verify(rand::rng()).expect("all valid");
|
||||
```
|
||||
|
||||
### HEEA decomposition example
|
||||
|
||||
```rust,ignore
|
||||
|
|
@ -73,16 +147,17 @@ let (rho, tau, flip_h) = h.heea_decompose();
|
|||
|
||||
## Feature Flags
|
||||
|
||||
The feature flags are inherited from upstream with no additions:
|
||||
|
||||
| Feature | Default? | Description |
|
||||
|---|:---:|---|
|
||||
| `alloc` | ✓ | Multiscalar multiplication, batch inversion, batch compress. |
|
||||
| `alloc` | ✓ | Multiscalar multiplication, batch inversion, batch compress, batch Ed25519 verification. |
|
||||
| `zeroize` | ✓ | `Zeroize` for all scalar and point types. |
|
||||
| `precomputed-tables` | ✓ | Precomputed basepoint tables (~400 KB, ~4× faster basepoint mul). |
|
||||
| `rand_core` | | `Scalar::random`, `RistrettoPoint::random`. |
|
||||
| `digest` | | Hash-to-curve and `Scalar::from_hash`. |
|
||||
| `serde` | | Serialization for all point and scalar types. |
|
||||
| `rand_core` | ✓ | `Scalar::random`, `RistrettoPoint::random`, `SigningKey::new`. |
|
||||
| `digest` | ✓ | Hash-to-curve, `Scalar::from_hash`, and Ed25519 hashing. |
|
||||
| `std` | | Enables `std::error::Error` impl on `ed_sigs::Error`. |
|
||||
| `serde` | | Serialization for all point, scalar, and key types. |
|
||||
| `pkcs8` | | PKCS#8 DER encoding/decoding for Ed25519 keys. |
|
||||
| `pem` | | PEM encoding/decoding for Ed25519 keys (requires `pkcs8`). |
|
||||
| `legacy_compatibility` | | `Scalar::from_bits` (broken arithmetic, use only if required). |
|
||||
| `group` | | `group` and `ff` crate trait impls. |
|
||||
| `group-bits` | | `ff::PrimeFieldBits` for `Scalar`. |
|
||||
|
|
@ -135,10 +210,15 @@ Rust **1.85.0** (Edition 2024).
|
|||
## References
|
||||
|
||||
- [TCHES 2025 paper] – _Accelerating EdDSA Signature Verification with Faster Scalar Size Halving_
|
||||
- [curve25519-dalek] – upstream library (isis lovecruft, Henry de Valence)
|
||||
- [curve25519-dalek] – upstream curve25519 library (isis lovecruft, Henry de Valence)
|
||||
- [ed25519-zebra] – upstream Ed25519 library (Zcash Foundation)
|
||||
- [ZIP 215] – Ed25519 validation rules for Zcash
|
||||
- [Original curve25519-dalek README](README_dalek.md)
|
||||
- [Original ed25519-zebra README](README_zebra.md)
|
||||
|
||||
[TCHES 2025 paper]: https://tches.iacr.org/index.php/TCHES/article/view/11971
|
||||
[curve25519-dalek]: https://github.com/dalek-cryptography/curve25519-dalek
|
||||
[ed25519-zebra]: https://github.com/ZcashFoundation/ed25519-zebra
|
||||
[ZIP 215]: https://zips.z.cash/zip-0215
|
||||
[SPPARK]: https://github.com/supranational/sppark
|
||||
[subtle]: https://docs.rs/subtle
|
||||
|
|
@ -1,12 +1,10 @@
|
|||
use criterion::{BenchmarkId, Criterion, Throughput, criterion_group, criterion_main};
|
||||
|
||||
use core::convert::TryFrom;
|
||||
use ed25519_heea::*;
|
||||
use rand::thread_rng;
|
||||
use curve25519::ed_sigs::*;
|
||||
|
||||
fn sigs_with_distinct_pubkeys() -> impl Iterator<Item = (VerificationKeyBytes, Signature)> {
|
||||
std::iter::repeat_with(|| {
|
||||
let sk = SigningKey::new(thread_rng());
|
||||
let sk = SigningKey::new(rand::rng());
|
||||
let pk_bytes = VerificationKeyBytes::from(&sk);
|
||||
let sig = sk.sign(b"");
|
||||
(pk_bytes, sig)
|
||||
|
|
@ -14,7 +12,7 @@ fn sigs_with_distinct_pubkeys() -> impl Iterator<Item = (VerificationKeyBytes, S
|
|||
}
|
||||
|
||||
fn sigs_with_same_pubkey() -> impl Iterator<Item = (VerificationKeyBytes, Signature)> {
|
||||
let sk = SigningKey::new(thread_rng());
|
||||
let sk = SigningKey::new(rand::rng());
|
||||
let pk_bytes = VerificationKeyBytes::from(&sk);
|
||||
std::iter::repeat_with(move || {
|
||||
let sig = sk.sign(b"");
|
||||
|
|
@ -30,11 +28,11 @@ fn bench_batch_verify(c: &mut Criterion) {
|
|||
group.bench_with_input(
|
||||
BenchmarkId::new("Unbatched verification", n),
|
||||
&sigs,
|
||||
|b, sigs| {
|
||||
|b, sigs: &Vec<(VerificationKeyBytes, Signature)>| {
|
||||
b.iter(|| {
|
||||
for (vk_bytes, sig) in sigs.iter() {
|
||||
let _ =
|
||||
VerificationKey::try_from(*vk_bytes).and_then(|vk| vk.verify(sig, b""));
|
||||
let _ = VerificationKey::try_from(*vk_bytes)
|
||||
.and_then(|vk: VerificationKey| vk.verify(sig, b""));
|
||||
}
|
||||
})
|
||||
},
|
||||
|
|
@ -43,13 +41,13 @@ fn bench_batch_verify(c: &mut Criterion) {
|
|||
group.bench_with_input(
|
||||
BenchmarkId::new("Signatures with Distinct Pubkeys", n),
|
||||
&sigs,
|
||||
|b, sigs| {
|
||||
|b, sigs: &Vec<(VerificationKeyBytes, Signature)>| {
|
||||
b.iter(|| {
|
||||
let mut batch = batch::Verifier::new();
|
||||
for (vk_bytes, sig) in sigs.iter().cloned() {
|
||||
batch.queue((vk_bytes, sig, b""));
|
||||
}
|
||||
batch.verify(thread_rng())
|
||||
batch.verify(rand::rng())
|
||||
})
|
||||
},
|
||||
);
|
||||
|
|
@ -59,13 +57,13 @@ fn bench_batch_verify(c: &mut Criterion) {
|
|||
group.bench_with_input(
|
||||
BenchmarkId::new("Signatures with the Same Pubkey", n),
|
||||
&sigs,
|
||||
|b, sigs| {
|
||||
|b, sigs: &Vec<(VerificationKeyBytes, Signature)>| {
|
||||
b.iter(|| {
|
||||
let mut batch = batch::Verifier::new();
|
||||
for (vk_bytes, sig) in sigs.iter().cloned() {
|
||||
batch.queue((vk_bytes, sig, b""));
|
||||
}
|
||||
batch.verify(thread_rng())
|
||||
batch.verify(rand::rng())
|
||||
})
|
||||
},
|
||||
);
|
||||
|
|
@ -77,7 +75,7 @@ fn bench_single_verify(c: &mut Criterion) {
|
|||
let mut group = c.benchmark_group("Single Verification");
|
||||
|
||||
group.bench_function("ed25519", |b| {
|
||||
let sk = SigningKey::new(thread_rng());
|
||||
let sk = SigningKey::new(rand::rng());
|
||||
let vk = VerificationKey::from(&sk);
|
||||
let sig = sk.sign(b"");
|
||||
b.iter(|| {
|
||||
|
|
@ -86,7 +84,7 @@ fn bench_single_verify(c: &mut Criterion) {
|
|||
});
|
||||
|
||||
group.bench_function("ed25519_hEEA", |b| {
|
||||
let sk = SigningKey::new(thread_rng());
|
||||
let sk = SigningKey::new(rand::rng());
|
||||
let vk = VerificationKey::from(&sk);
|
||||
let sig = sk.sign(b"");
|
||||
b.iter(|| {
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
#![allow(non_snake_case)]
|
||||
|
||||
use rand::{RngCore, TryRngCore, rng, rngs::SysRng};
|
||||
use rand::rng;
|
||||
use rand_core::Rng as RngCore;
|
||||
|
||||
use criterion::{
|
||||
BatchSize, BenchmarkGroup, BenchmarkId, Criterion, criterion_main, measurement::Measurement,
|
||||
|
|
@ -31,10 +32,10 @@ mod edwards_benches {
|
|||
BenchmarkId::new("Batch EdwardsPoint compression", batch_size),
|
||||
&batch_size,
|
||||
|b, &size| {
|
||||
let mut rng = SysRng.unwrap_err();
|
||||
let mut rng = rng();
|
||||
let points: Vec<EdwardsPoint> =
|
||||
(0..size).map(|_| EdwardsPoint::random(&mut rng)).collect();
|
||||
b.iter(|| EdwardsPoint::compress_batch_alloc(&points));
|
||||
b.iter(|| EdwardsPoint::compress_batch(&points));
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
@ -301,9 +302,9 @@ mod ristretto_benches {
|
|||
BenchmarkId::new("Batch Ristretto double-and-encode", *batch_size),
|
||||
&batch_size,
|
||||
|b, &&size| {
|
||||
let mut rng = SysRng;
|
||||
let mut rng = rng();
|
||||
let points: Vec<RistrettoPoint> = (0..size)
|
||||
.map(|_| RistrettoPoint::try_from_rng(&mut rng).unwrap())
|
||||
.map(|_| RistrettoPoint::random(&mut rng))
|
||||
.collect();
|
||||
b.iter(|| RistrettoPoint::double_and_compress_batch(&points));
|
||||
},
|
||||
|
|
@ -388,7 +389,7 @@ mod scalar_benches {
|
|||
BenchmarkId::new("Batch scalar inversion", *batch_size),
|
||||
&batch_size,
|
||||
|b, &&size| {
|
||||
let mut rng = SysRng.unwrap_err();
|
||||
let mut rng = rng();
|
||||
let scalars: Vec<Scalar> =
|
||||
(0..size).map(|_| Scalar::random(&mut rng)).collect();
|
||||
b.iter(|| {
|
||||
|
|
@ -40,7 +40,7 @@ use core::ops::{Add, Neg, Sub};
|
|||
use subtle::Choice;
|
||||
use subtle::ConditionallySelectable;
|
||||
|
||||
use curve25519_derive::unsafe_target_feature;
|
||||
use curve25519_dalek_derive::unsafe_target_feature;
|
||||
|
||||
use crate::edwards;
|
||||
use crate::window::{LookupTable, NafLookupTable5};
|
||||
|
|
@ -53,7 +53,7 @@ use crate::backend::vector::avx2::constants::{
|
|||
P_TIMES_2_HI, P_TIMES_2_LO, P_TIMES_16_HI, P_TIMES_16_LO,
|
||||
};
|
||||
|
||||
use curve25519_derive::unsafe_target_feature;
|
||||
use curve25519_dalek_derive::unsafe_target_feature;
|
||||
|
||||
/// Unpack 32-bit lanes into 64-bit lanes:
|
||||
/// ```ascii,no_run
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
//! by the callers of this code.
|
||||
use core::ops::{Add, AddAssign, BitAnd, BitAndAssign, BitXor, BitXorAssign, Sub};
|
||||
|
||||
use curve25519_derive::unsafe_target_feature;
|
||||
use curve25519_dalek_derive::unsafe_target_feature;
|
||||
|
||||
macro_rules! impl_shared {
|
||||
(
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
#[curve25519_derive::unsafe_target_feature_specialize("avx2")]
|
||||
#[curve25519_dalek_derive::unsafe_target_feature_specialize("avx2")]
|
||||
pub mod spec {
|
||||
|
||||
use alloc::vec::Vec;
|
||||
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
#[curve25519_derive::unsafe_target_feature_specialize("avx2")]
|
||||
#[curve25519_dalek_derive::unsafe_target_feature_specialize("avx2")]
|
||||
pub mod spec {
|
||||
|
||||
use alloc::vec::Vec;
|
||||
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
#[curve25519_derive::unsafe_target_feature_specialize("avx2")]
|
||||
#[curve25519_dalek_derive::unsafe_target_feature_specialize("avx2")]
|
||||
pub mod spec {
|
||||
|
||||
use alloc::vec::Vec;
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
#![allow(non_snake_case)]
|
||||
|
||||
#[curve25519_derive::unsafe_target_feature_specialize("avx2")]
|
||||
#[curve25519_dalek_derive::unsafe_target_feature_specialize("avx2")]
|
||||
pub mod spec {
|
||||
|
||||
#[for_target_feature("avx2")]
|
||||
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
#[curve25519_derive::unsafe_target_feature_specialize("avx2")]
|
||||
#[curve25519_dalek_derive::unsafe_target_feature_specialize("avx2")]
|
||||
pub mod spec {
|
||||
|
||||
use core::cmp::Ordering;
|
||||
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
#[curve25519_derive::unsafe_target_feature_specialize("avx2")]
|
||||
#[curve25519_dalek_derive::unsafe_target_feature_specialize("avx2")]
|
||||
pub mod spec {
|
||||
|
||||
use core::cmp::Ordering;
|
||||
|
|
@ -1,11 +1,7 @@
|
|||
#![deny(missing_docs)]
|
||||
#![doc = include_str!("../README.md")]
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
//! Ed25519 signing and verification (ZIP-215 / HEEA-accelerated).
|
||||
|
||||
//! Docs require the `nightly` feature until RFC 1990 lands.
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
extern crate alloc;
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
pub mod batch;
|
||||
|
|
@ -14,8 +10,8 @@ mod signing_key;
|
|||
mod verification_key;
|
||||
|
||||
// Allows importing traits used by `Signature`.
|
||||
pub use ed25519;
|
||||
pub use ed25519::Signature;
|
||||
pub use ::ed25519;
|
||||
pub use ::ed25519::Signature;
|
||||
pub use error::Error;
|
||||
pub use signing_key::SigningKey;
|
||||
pub use verification_key::{VerificationKey, VerificationKeyBytes};
|
||||
|
|
@ -34,16 +34,16 @@
|
|||
//!
|
||||
//! # Example
|
||||
//! ```
|
||||
//! # use ed25519_heea::*;
|
||||
//! # use curve25519::ed_sigs::*;
|
||||
//! let mut batch = batch::Verifier::new();
|
||||
//! for _ in 0..32 {
|
||||
//! let sk = SigningKey::new(rand::thread_rng());
|
||||
//! let sk = SigningKey::new(rand::rng());
|
||||
//! let vk_bytes = VerificationKeyBytes::from(&sk);
|
||||
//! let msg = b"BatchVerifyTest";
|
||||
//! let sig = sk.sign(&msg[..]);
|
||||
//! batch.queue((vk_bytes, sig, &msg[..]));
|
||||
//! }
|
||||
//! assert!(batch.verify(rand::thread_rng()).is_ok());
|
||||
//! assert!(batch.verify(rand::rng()).is_ok());
|
||||
//! ```
|
||||
//!
|
||||
//! [ZIP215]: https://zips.z.cash/zip-0215
|
||||
|
|
@ -51,20 +51,20 @@
|
|||
use alloc::vec::Vec;
|
||||
use core::convert::TryFrom;
|
||||
|
||||
use curve25519::{
|
||||
use crate::{
|
||||
edwards::{CompressedEdwardsY, EdwardsPoint},
|
||||
scalar::Scalar,
|
||||
traits::{IsIdentity, VartimeMultiscalarMul},
|
||||
};
|
||||
use hashbrown::HashMap;
|
||||
use rand_core::{CryptoRng, RngCore};
|
||||
use rand_core::{CryptoRng, Rng};
|
||||
use sha2::{Sha512, digest::Update};
|
||||
|
||||
use crate::{Error, VerificationKey, VerificationKeyBytes};
|
||||
use super::{Error, VerificationKey, VerificationKeyBytes};
|
||||
use ed25519::Signature;
|
||||
|
||||
// Shim to generate a u128 without importing `rand`.
|
||||
fn gen_u128<R: RngCore + CryptoRng>(mut rng: R) -> u128 {
|
||||
fn gen_u128<R: Rng + CryptoRng>(mut rng: R) -> u128 {
|
||||
let mut bytes = [0u8; 16];
|
||||
rng.fill_bytes(&mut bytes[..]);
|
||||
u128::from_le_bytes(bytes)
|
||||
|
|
@ -142,7 +142,7 @@ impl Verifier {
|
|||
/// Perform batch verification, returning `Ok(())` if all signatures were
|
||||
/// valid and `Err` otherwise.
|
||||
#[allow(non_snake_case)]
|
||||
pub fn verify<R: RngCore + CryptoRng>(self, mut rng: R) -> Result<(), Error> {
|
||||
pub fn verify<R: Rng + CryptoRng>(self, mut rng: R) -> Result<(), Error> {
|
||||
// The batch verification equation is
|
||||
//
|
||||
// 8*[-sum(z_i * s_i)]B + 8*sum([z_i]R_i) + 8*sum([z_i * k_i]A_i) = 0.
|
||||
|
|
@ -199,8 +199,8 @@ impl Verifier {
|
|||
A_coeffs.push(A_coeff);
|
||||
}
|
||||
|
||||
use crate::constants::ED25519_BASEPOINT_POINT as B;
|
||||
use core::iter::once;
|
||||
use curve25519::constants::ED25519_BASEPOINT_POINT as B;
|
||||
let check = EdwardsPoint::vartime_multiscalar_mul(
|
||||
once(&B_coeff).chain(A_coeffs.iter()).chain(R_coeffs.iter()),
|
||||
once(&B).chain(As.iter()).chain(Rs.iter()),
|
||||
|
|
@ -6,14 +6,14 @@ const ALGORITHM_ID: AlgorithmIdentifierRef = AlgorithmIdentifierRef {
|
|||
parameters: None,
|
||||
};
|
||||
|
||||
use crate::Error;
|
||||
use super::Error;
|
||||
use crate::{constants, scalar::Scalar};
|
||||
#[cfg(all(feature = "pem", feature = "pkcs8"))]
|
||||
use alloc::string::String;
|
||||
use core::convert::TryFrom;
|
||||
#[cfg(feature = "pkcs8")]
|
||||
use core::convert::TryInto;
|
||||
use curve25519::{constants, scalar::Scalar};
|
||||
use rand_core::{CryptoRng, RngCore};
|
||||
use rand_core::{CryptoRng, Rng};
|
||||
use sha2::{Digest, Sha512, digest::Update};
|
||||
use subtle::ConstantTimeEq;
|
||||
use zeroize::Zeroize;
|
||||
|
|
@ -40,7 +40,7 @@ use zeroize::Zeroizing;
|
|||
#[cfg(all(feature = "pem", feature = "pkcs8"))]
|
||||
use pkcs8::der::pem::PemLabel;
|
||||
|
||||
use crate::{VerificationKey, VerificationKeyBytes};
|
||||
use super::{VerificationKey, VerificationKeyBytes};
|
||||
|
||||
/// The length of a ed25519 `SecretKey`, in bytes.
|
||||
pub const SECRET_KEY_LENGTH: usize = 32;
|
||||
|
|
@ -68,7 +68,7 @@ pub struct SigningKey {
|
|||
}
|
||||
|
||||
impl core::fmt::Debug for SigningKey {
|
||||
fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||
fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
fmt.debug_struct("SigningKey")
|
||||
.field("vk", &self.vk)
|
||||
.finish()
|
||||
|
|
@ -317,7 +317,7 @@ impl SigningKey {
|
|||
}
|
||||
|
||||
/// Generate a new signing key.
|
||||
pub fn new<R: RngCore + CryptoRng>(mut rng: R) -> SigningKey {
|
||||
pub fn new<R: Rng + CryptoRng>(mut rng: R) -> SigningKey {
|
||||
let mut bytes = [0u8; 32];
|
||||
rng.fill_bytes(&mut bytes[..]);
|
||||
bytes.into()
|
||||
9
curve25519/solana-ed25519/src/ed_sigs/tests.rs
Normal file
9
curve25519/solana-ed25519/src/ed_sigs/tests.rs
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
pub mod util;
|
||||
|
||||
mod batch;
|
||||
mod decoding;
|
||||
mod encoding;
|
||||
mod heea;
|
||||
mod rfc8032;
|
||||
mod small_order;
|
||||
mod unit_tests;
|
||||
|
|
@ -1,20 +1,19 @@
|
|||
#![cfg(feature = "alloc")]
|
||||
|
||||
use rand::thread_rng;
|
||||
|
||||
use ed25519_heea::*;
|
||||
use crate::ed_sigs::*;
|
||||
use alloc::vec::Vec;
|
||||
|
||||
#[test]
|
||||
fn batch_verify() {
|
||||
let mut batch = batch::Verifier::new();
|
||||
for _ in 0..32 {
|
||||
let sk = SigningKey::new(thread_rng());
|
||||
let sk = SigningKey::new(rand::rng());
|
||||
let pk_bytes = VerificationKeyBytes::from(&sk);
|
||||
let msg = b"BatchVerifyTest";
|
||||
let sig = sk.sign(&msg[..]);
|
||||
batch.queue((pk_bytes, sig, msg));
|
||||
}
|
||||
assert!(batch.verify(thread_rng()).is_ok());
|
||||
assert!(batch.verify(rand::rng()).is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -23,7 +22,7 @@ fn batch_verify_with_one_bad_sig() {
|
|||
let mut batch = batch::Verifier::new();
|
||||
let mut items = Vec::new();
|
||||
for i in 0..32 {
|
||||
let sk = SigningKey::new(thread_rng());
|
||||
let sk = SigningKey::new(rand::rng());
|
||||
let pk_bytes = VerificationKeyBytes::from(&sk);
|
||||
let msg = b"BatchVerifyTest";
|
||||
let sig = if i != bad_index {
|
||||
|
|
@ -35,7 +34,7 @@ fn batch_verify_with_one_bad_sig() {
|
|||
items.push(item.clone());
|
||||
batch.queue(item);
|
||||
}
|
||||
assert!(batch.verify(thread_rng()).is_err());
|
||||
assert!(batch.verify(rand::rng()).is_err());
|
||||
for (i, item) in items.drain(..).enumerate() {
|
||||
if i != bad_index {
|
||||
assert!(item.verify_single().is_ok());
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
#[cfg(any(feature = "pem", feature = "pkcs8"))]
|
||||
use ed25519_heea::*;
|
||||
use crate::ed_sigs::*;
|
||||
|
||||
#[cfg(feature = "pkcs8")]
|
||||
use pkcs8::{DecodePrivateKey, DecodePublicKey};
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
#[cfg(any(feature = "pem", feature = "pkcs8"))]
|
||||
use crate::ed_sigs::*;
|
||||
#[cfg(feature = "pem")]
|
||||
use der::pem::LineEnding;
|
||||
#[cfg(any(feature = "pem", feature = "pkcs8"))]
|
||||
use ed25519_heea::*;
|
||||
#[cfg(feature = "pkcs8")]
|
||||
pub use pkcs8::{
|
||||
EncodePrivateKey, EncodePublicKey, ObjectIdentifier, PrivateKeyInfo,
|
||||
|
|
@ -1,11 +1,9 @@
|
|||
use ed25519_heea::SigningKey;
|
||||
use ed25519_heea::VerificationKey;
|
||||
|
||||
use rand::thread_rng;
|
||||
use crate::ed_sigs::SigningKey;
|
||||
use crate::ed_sigs::VerificationKey;
|
||||
|
||||
#[test]
|
||||
fn test_verify_heea_invalid_signature() {
|
||||
let mut rng = thread_rng();
|
||||
let mut rng = rand::rng();
|
||||
let signing_key = SigningKey::new(&mut rng);
|
||||
let verification_key = VerificationKey::from(&signing_key);
|
||||
|
||||
|
|
@ -31,7 +29,7 @@ fn test_verify_heea_invalid_signature() {
|
|||
|
||||
#[test]
|
||||
fn test_verify_heea_multiple_signatures() {
|
||||
let mut rng = thread_rng();
|
||||
let mut rng = rand::rng();
|
||||
|
||||
for i in 0..100 {
|
||||
let signing_key = SigningKey::new(&mut rng);
|
||||
|
|
@ -5,8 +5,8 @@
|
|||
//! in consensus.rs.
|
||||
#![cfg(feature = "serde")]
|
||||
|
||||
use crate::ed_sigs::*;
|
||||
use ed25519::Signature;
|
||||
use ed25519_heea::*;
|
||||
|
||||
fn rfc8032_test_case(sk_bytes: Vec<u8>, pk_bytes: Vec<u8>, sig_bytes: Vec<u8>, msg: Vec<u8>) {
|
||||
let sk: SigningKey = bincode::deserialize(&sk_bytes).expect("sk should deserialize");
|
||||
|
|
@ -1,14 +1,14 @@
|
|||
#![cfg(feature = "std")]
|
||||
|
||||
use color_eyre::Report;
|
||||
use curve25519::{
|
||||
use crate::{
|
||||
constants::EIGHT_TORSION, digest::Update, edwards::CompressedEdwardsY, scalar::Scalar,
|
||||
traits::IsIdentity,
|
||||
};
|
||||
use color_eyre::Report;
|
||||
use once_cell::sync::Lazy;
|
||||
use sha2::Sha512;
|
||||
|
||||
mod util;
|
||||
use super::util;
|
||||
use util::TestCase;
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
|
|
@ -86,9 +86,9 @@ fn conformance() -> Result<(), Report> {
|
|||
#[cfg(feature = "alloc")]
|
||||
#[test]
|
||||
fn individual_matches_batch_verification() -> Result<(), Report> {
|
||||
use crate::ed_sigs::{VerificationKey, VerificationKeyBytes, batch};
|
||||
use core::convert::TryFrom;
|
||||
use ed25519::Signature;
|
||||
use ed25519_heea::{VerificationKey, VerificationKeyBytes, batch};
|
||||
|
||||
for case in SMALL_ORDER_SIGS.iter() {
|
||||
let msg = b"Zcash";
|
||||
|
|
@ -98,7 +98,7 @@ fn individual_matches_batch_verification() -> Result<(), Report> {
|
|||
VerificationKey::try_from(vkb).and_then(|vk| vk.verify(&sig, msg));
|
||||
let mut bv = batch::Verifier::new();
|
||||
bv.queue((vkb, sig, msg));
|
||||
let batch_verification = bv.verify(rand::thread_rng());
|
||||
let batch_verification = bv.verify(rand::rng());
|
||||
assert_eq!(individual_verification.is_ok(), batch_verification.is_ok());
|
||||
}
|
||||
Ok(())
|
||||
|
|
@ -2,13 +2,11 @@
|
|||
|
||||
use core::convert::TryFrom;
|
||||
|
||||
use rand::thread_rng;
|
||||
|
||||
use ed25519_heea::{Signature, SigningKey, VerificationKey, VerificationKeyBytes};
|
||||
use crate::ed_sigs::{Signature, SigningKey, VerificationKey, VerificationKeyBytes};
|
||||
|
||||
#[test]
|
||||
fn parsing() {
|
||||
let sk = SigningKey::new(thread_rng());
|
||||
let sk = SigningKey::new(rand::rng());
|
||||
let pk = VerificationKey::from(&sk);
|
||||
let pkb = VerificationKeyBytes::from(&sk);
|
||||
let sig = sk.sign(b"test");
|
||||
|
|
@ -39,7 +37,7 @@ fn parsing() {
|
|||
|
||||
#[test]
|
||||
fn sign_and_verify() {
|
||||
let sk = SigningKey::new(thread_rng());
|
||||
let sk = SigningKey::new(rand::rng());
|
||||
let pk = VerificationKey::from(&sk);
|
||||
|
||||
let msg = b"ed25519-zebra test message";
|
||||
|
|
@ -2,9 +2,9 @@
|
|||
#![allow(dead_code)]
|
||||
#![cfg(feature = "std")]
|
||||
|
||||
use crate::ed_sigs as ed25519_heea_zip215;
|
||||
use crate::edwards::{CompressedEdwardsY, EdwardsPoint};
|
||||
use color_eyre::{Report, eyre::eyre};
|
||||
use curve25519::edwards::{CompressedEdwardsY, EdwardsPoint};
|
||||
use ed25519_heea as ed25519_heea_zip215;
|
||||
|
||||
use core::convert::TryFrom;
|
||||
|
||||
|
|
@ -170,7 +170,7 @@ fn print_non_canonical_points() {
|
|||
}
|
||||
|
||||
pub fn order(point: EdwardsPoint) -> &'static str {
|
||||
use curve25519::traits::IsIdentity;
|
||||
use crate::traits::IsIdentity;
|
||||
if point.is_small_order() {
|
||||
let point2 = point + point;
|
||||
let point4 = point2 + point2;
|
||||
|
|
@ -12,12 +12,12 @@
|
|||
// Halving" (TCHES 2025) for the algorithm.
|
||||
// - `verify` and all ZIP-215 consensus logic are unchanged from ed25519-zebra.
|
||||
|
||||
use core::convert::{TryFrom, TryInto};
|
||||
use curve25519::{
|
||||
use crate::{
|
||||
edwards::{CompressedEdwardsY, EdwardsPoint},
|
||||
scalar::Scalar,
|
||||
traits::{HEEADecomposition, IsIdentity},
|
||||
};
|
||||
use core::convert::{TryFrom, TryInto};
|
||||
use sha2::{Sha512, digest::Update};
|
||||
use zeroize::DefaultIsZeroes;
|
||||
|
||||
|
|
@ -32,7 +32,7 @@ use pkcs8::spki::{
|
|||
#[cfg(feature = "pkcs8")]
|
||||
use pkcs8::{Document, ObjectIdentifier};
|
||||
|
||||
use crate::Error;
|
||||
use super::Error;
|
||||
|
||||
/// The length of an ed25519 `VerificationKey`, in bytes.
|
||||
pub const VERIFICATION_KEY_LENGTH: usize = 32;
|
||||
|
|
@ -48,10 +48,9 @@ pub const VERIFICATION_KEY_LENGTH: usize = 32;
|
|||
/// following idiom:
|
||||
/// ```
|
||||
/// use core::convert::TryFrom;
|
||||
/// # use rand::thread_rng;
|
||||
/// # use ed25519_heea::*;
|
||||
/// # use curve25519::ed_sigs::*;
|
||||
/// # let msg = b"Zcash";
|
||||
/// # let sk = SigningKey::new(thread_rng());
|
||||
/// # let sk = SigningKey::new(rand::rng());
|
||||
/// # let sig = sk.sign(msg);
|
||||
/// # let vk_bytes = VerificationKeyBytes::from(&sk);
|
||||
/// VerificationKey::try_from(vk_bytes)
|
||||
|
|
@ -62,7 +61,7 @@ pub const VERIFICATION_KEY_LENGTH: usize = 32;
|
|||
pub struct VerificationKeyBytes(pub(crate) [u8; VERIFICATION_KEY_LENGTH]);
|
||||
|
||||
impl core::fmt::Debug for VerificationKeyBytes {
|
||||
fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||
fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
fmt.debug_tuple("VerificationKeyBytes")
|
||||
.field(&self.0)
|
||||
.finish()
|
||||
|
|
@ -113,12 +113,12 @@ use digest::{
|
|||
#[cfg(feature = "group")]
|
||||
use {
|
||||
group::{GroupEncoding, cofactor::CofactorGroup, prime::PrimeGroup},
|
||||
rand_core::TryRngCore,
|
||||
rand_core::TryRng,
|
||||
subtle::CtOption,
|
||||
};
|
||||
|
||||
#[cfg(feature = "rand_core")]
|
||||
use rand_core::RngCore;
|
||||
use rand_core::Rng as RngCore;
|
||||
|
||||
use subtle::Choice;
|
||||
use subtle::ConditionallyNegatable;
|
||||
|
|
@ -1481,7 +1481,7 @@ impl Debug for EdwardsPoint {
|
|||
impl group::Group for EdwardsPoint {
|
||||
type Scalar = Scalar;
|
||||
|
||||
fn try_from_rng<R: TryRngCore + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
|
||||
fn try_from_rng<R: TryRng + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
|
||||
let mut repr = CompressedEdwardsY([0u8; 32]);
|
||||
loop {
|
||||
rng.try_fill_bytes(&mut repr.0)?;
|
||||
|
|
@ -1733,7 +1733,7 @@ impl Zeroize for SubgroupPoint {
|
|||
impl group::Group for SubgroupPoint {
|
||||
type Scalar = Scalar;
|
||||
|
||||
fn try_from_rng<R: TryRngCore + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
|
||||
fn try_from_rng<R: TryRng + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
|
||||
use group::ff::Field;
|
||||
|
||||
// This will almost never loop, but `Group::random` is documented as returning a
|
||||
|
|
@ -78,6 +78,12 @@ pub mod constants;
|
|||
// External (and internal) traits.
|
||||
pub mod traits;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// ed25519 public modules
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
pub mod ed_sigs;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// curve25519 internal modules
|
||||
//------------------------------------------------------------------------
|
||||
|
|
@ -180,7 +180,7 @@ use crate::field::FieldElement;
|
|||
#[cfg(feature = "group")]
|
||||
use {
|
||||
group::{GroupEncoding, cofactor::CofactorGroup, prime::PrimeGroup},
|
||||
rand_core::TryRngCore,
|
||||
rand_core::TryRng,
|
||||
subtle::CtOption,
|
||||
};
|
||||
|
||||
|
|
@ -543,12 +543,11 @@ impl RistrettoPoint {
|
|||
#[cfg_attr(feature = "rand_core", doc = "```")]
|
||||
#[cfg_attr(not(feature = "rand_core"), doc = "```ignore")]
|
||||
/// # use curve25519::ristretto::RistrettoPoint;
|
||||
/// use rand::{rngs::SysRng, TryRngCore};
|
||||
///
|
||||
/// # // Need fn main() here in comment so the doctest compiles
|
||||
/// # // See https://doc.rust-lang.org/book/documentation.html#documentation-as-tests
|
||||
/// # fn main() {
|
||||
/// let mut rng = SysRng.unwrap_err();
|
||||
/// let mut rng = rand::rng();
|
||||
///
|
||||
/// let points: Vec<RistrettoPoint> =
|
||||
/// (0..32).map(|_| RistrettoPoint::random(&mut rng)).collect();
|
||||
|
|
@ -1179,7 +1178,7 @@ impl Debug for RistrettoPoint {
|
|||
impl group::Group for RistrettoPoint {
|
||||
type Scalar = Scalar;
|
||||
|
||||
fn try_from_rng<R: TryRngCore + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
|
||||
fn try_from_rng<R: TryRng + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
|
||||
// NOTE: this is duplicated due to different `rng` bounds
|
||||
let mut uniform_bytes = [0u8; 64];
|
||||
rng.try_fill_bytes(&mut uniform_bytes)?;
|
||||
|
|
@ -1277,8 +1276,8 @@ mod test {
|
|||
use crate::edwards::CompressedEdwardsY;
|
||||
#[cfg(feature = "group")]
|
||||
use proptest::prelude::*;
|
||||
#[cfg(feature = "rand_core")]
|
||||
use rand::{TryRngCore, rngs::SysRng};
|
||||
#[cfg(all(feature = "rand_core", feature = "group"))]
|
||||
use rand::rngs::SysRng;
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "serde")]
|
||||
|
|
@ -1477,7 +1476,7 @@ mod test {
|
|||
#[cfg(feature = "rand_core")]
|
||||
#[test]
|
||||
fn four_torsion_random() {
|
||||
let mut rng = SysRng.unwrap_err();
|
||||
let mut rng = rand::rng();
|
||||
let P = RistrettoPoint::mul_base(&Scalar::random(&mut rng));
|
||||
let P_coset = P.coset4();
|
||||
for point in P_coset {
|
||||
|
|
@ -1488,11 +1487,13 @@ mod test {
|
|||
#[cfg(feature = "rand_core")]
|
||||
#[test]
|
||||
fn random_roundtrip() {
|
||||
let mut rng = SysRng.unwrap_err();
|
||||
let mut rng = rand::rng();
|
||||
for _ in 0..100 {
|
||||
let P = RistrettoPoint::mul_base(&Scalar::random(&mut rng));
|
||||
let compressed_P = P.compress();
|
||||
let Q = compressed_P.decompress().unwrap();
|
||||
let Q = compressed_P
|
||||
.decompress()
|
||||
.expect("compression round-trip should decompress");
|
||||
assert_eq!(P, Q);
|
||||
}
|
||||
}
|
||||
|
|
@ -126,7 +126,7 @@ use group::ff::{Field, FromUniformBytes, PrimeField};
|
|||
use group::ff::{FieldBits, PrimeFieldBits};
|
||||
|
||||
#[cfg(feature = "group")]
|
||||
use rand_core::TryRngCore;
|
||||
use rand_core::TryRng;
|
||||
|
||||
#[cfg(feature = "rand_core")]
|
||||
use rand_core::CryptoRng;
|
||||
|
|
@ -1263,7 +1263,7 @@ impl Field for Scalar {
|
|||
const ZERO: Self = Self::ZERO;
|
||||
const ONE: Self = Self::ONE;
|
||||
|
||||
fn try_from_rng<R: TryRngCore + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
|
||||
fn try_from_rng<R: TryRng + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
|
||||
// NOTE: this is duplicated due to different `rng` bounds
|
||||
let mut scalar_bytes = [0u8; 64];
|
||||
rng.try_fill_bytes(&mut scalar_bytes)?;
|
||||
|
|
@ -423,7 +423,7 @@ mod tests {
|
|||
use crate::{Scalar, digest::Update, traits::HEEADecomposition};
|
||||
|
||||
#[cfg(feature = "rand_core")]
|
||||
use rand::RngCore;
|
||||
use rand_core::Rng;
|
||||
|
||||
#[test]
|
||||
#[cfg(all(feature = "rand_core", feature = "digest"))]
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue