summaryrefslogtreecommitdiffstats
path: root/vendor/elliptic-curve
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 12:41:41 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 12:41:41 +0000
commit10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87 (patch)
treebdffd5d80c26cf4a7a518281a204be1ace85b4c1 /vendor/elliptic-curve
parentReleasing progress-linux version 1.70.0+dfsg1-9~progress7.99u1. (diff)
downloadrustc-10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87.tar.xz
rustc-10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87.zip
Merging upstream version 1.70.0+dfsg2.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/elliptic-curve')
-rw-r--r--vendor/elliptic-curve/.cargo-checksum.json1
-rw-r--r--vendor/elliptic-curve/CHANGELOG.md657
-rw-r--r--vendor/elliptic-curve/Cargo.toml209
-rw-r--r--vendor/elliptic-curve/LICENSE-APACHE201
-rw-r--r--vendor/elliptic-curve/LICENSE-MIT25
-rw-r--r--vendor/elliptic-curve/README.md54
-rw-r--r--vendor/elliptic-curve/src/arithmetic.rs87
-rw-r--r--vendor/elliptic-curve/src/dev.rs794
-rw-r--r--vendor/elliptic-curve/src/ecdh.rs236
-rw-r--r--vendor/elliptic-curve/src/error.rs42
-rw-r--r--vendor/elliptic-curve/src/hash2curve.rs15
-rw-r--r--vendor/elliptic-curve/src/hash2curve/group_digest.rs120
-rw-r--r--vendor/elliptic-curve/src/hash2curve/hash2field.rs48
-rw-r--r--vendor/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs115
-rw-r--r--vendor/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs449
-rw-r--r--vendor/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs353
-rw-r--r--vendor/elliptic-curve/src/hash2curve/isogeny.rs57
-rw-r--r--vendor/elliptic-curve/src/hash2curve/map2curve.rs12
-rw-r--r--vendor/elliptic-curve/src/hash2curve/osswu.rs87
-rw-r--r--vendor/elliptic-curve/src/jwk.rs692
-rw-r--r--vendor/elliptic-curve/src/lib.rs220
-rw-r--r--vendor/elliptic-curve/src/macros.rs440
-rw-r--r--vendor/elliptic-curve/src/ops.rs96
-rw-r--r--vendor/elliptic-curve/src/point.rs40
-rw-r--r--vendor/elliptic-curve/src/public_key.rs411
-rw-r--r--vendor/elliptic-curve/src/scalar.rs32
-rw-r--r--vendor/elliptic-curve/src/scalar/core.rs434
-rw-r--r--vendor/elliptic-curve/src/scalar/nonzero.rs353
-rw-r--r--vendor/elliptic-curve/src/sec1.rs114
-rw-r--r--vendor/elliptic-curve/src/secret_key.rs395
-rw-r--r--vendor/elliptic-curve/src/secret_key/pkcs8.rs92
-rw-r--r--vendor/elliptic-curve/src/weierstrass.rs128
-rw-r--r--vendor/elliptic-curve/tests/examples/pkcs8-private-key.derbin0 -> 138 bytes
-rw-r--r--vendor/elliptic-curve/tests/examples/pkcs8-private-key.pem5
-rw-r--r--vendor/elliptic-curve/tests/examples/pkcs8-public-key.derbin0 -> 91 bytes
-rw-r--r--vendor/elliptic-curve/tests/examples/pkcs8-public-key.pem4
-rw-r--r--vendor/elliptic-curve/tests/pkcs8.rs55
-rw-r--r--vendor/elliptic-curve/tests/secret_key.rs10
38 files changed, 7083 insertions, 0 deletions
diff --git a/vendor/elliptic-curve/.cargo-checksum.json b/vendor/elliptic-curve/.cargo-checksum.json
new file mode 100644
index 000000000..bd44426f4
--- /dev/null
+++ b/vendor/elliptic-curve/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"CHANGELOG.md":"0c64ef00c74dfb3135bf6c48b6a7a34ac9552653fcff3c40c6481e9c71b20e77","Cargo.toml":"c25efca1464e5c7af224e242922865cdf9b310476fefa80eb350cb72afd21e54","LICENSE-APACHE":"a9040321c3712d8fd0b09cf52b17445de04a23a10165049ae187cd39e5c86be5","LICENSE-MIT":"d27687b51f2874822c1530976b7e837eac4f308d94bf3dd42047011b7d437b47","README.md":"564ad8f9f8b80adeac3a961778857336a8ec6a77c54c07c7e9038cd0d36fad48","src/arithmetic.rs":"a4c7a7b350eaf75898dc412e0d6224b9e285a6fa20908c9e5150a4e31eed6bc2","src/dev.rs":"a9cb4426a348d2dedb4bbb0813f54a5715c7d3f50473c9668e11d73df65e35cf","src/ecdh.rs":"f4e0d9bfa7c4d5535261eefae0f4a85d96a155427b70d49f9b2ae43cf82a4949","src/error.rs":"8aedd93298b729ee396bc1a31754119130fbf865cb1e330c65be178cbbb0d1e4","src/hash2curve.rs":"861857145cc973ca64fc765731dada9aa3d7d97f61d324f6dba2aacc2d5e2135","src/hash2curve/group_digest.rs":"0557858097e159f98d8f6f0bd2dc03dd7e6e296da331db811cdad622c7f72834","src/hash2curve/hash2field.rs":"f4649686071bdf8fd4652d176878fc90bdd58111834f0f145b1b18009d53678b","src/hash2curve/hash2field/expand_msg.rs":"b92d8b959497cccd9cfa510dc257f2e7aab37331033498ac69946a6ec56bc81c","src/hash2curve/hash2field/expand_msg/xmd.rs":"ecac9f50043e5388f749528e7bed69f0b8686f8e62921ff272d6b87232efaf47","src/hash2curve/hash2field/expand_msg/xof.rs":"6cf5475e5bc6eda79c401e3855db67f59be4e6231af4bd22a6dedb0961d196cb","src/hash2curve/isogeny.rs":"7dcfc4f4263432ea1903f1580c28771b1082b8c4e344993b709e9995eaeaa674","src/hash2curve/map2curve.rs":"fc05c553ccd92de762e083f02079581376e8e4a193acd0d902cfdb33f59ce10a","src/hash2curve/osswu.rs":"9a300863c3c1f6893edcc612483228177a342e1c955407353fba24bf2676b34d","src/jwk.rs":"f701055c5af1bc8049ad3a3d5d3c47684f89fc0f90afae773e17de1ad2a413c0","src/lib.rs":"0fe6f10f2a0cb9480f8a42fcafad95fa47f9f2b5696eb8f078e0c377cabba9d9","src/macros.rs":"647f46540b407e12f633f635ed5d986c1be139d43a11ebff3edcce8295e1945c","src/ops.rs":"815f0c6f00e8d9b26f7bdde630cbc055cb6842599c3698fe55df66b1cddc6c99","src/point.rs":"19e92d2b64d1856fc12ff1d3d67940fc9801488f7ccbe488d318f5d06caeeb7e","src/public_key.rs":"5620b669b3a7aa00b7ad12732b171b042372d7d0e88e3e7d039771e0d13672c6","src/scalar.rs":"222680eb4f0e2fff8abf1dc4bdb82252bf71bb6060fdb00963627b1e5b2a40fa","src/scalar/core.rs":"8816c955ea0c89930dce42a2f5a7f0bcb6f1ed76a75ac5f663bd5100927eea34","src/scalar/nonzero.rs":"dec1a3fa2b4e2dcbe1c31504cd4b71ed64f06f98ac9676e7bb252013f4c2b61e","src/sec1.rs":"7c328e84d5cdf966114921bd23af53c2ab8ad335cf0d8bcf48d9def6354be474","src/secret_key.rs":"5da9d77b1483920e4dd1d9da42660c5bd0db560d195aaa2f5e07e8ed0c8d010e","src/secret_key/pkcs8.rs":"d049371aae570dc1519397d79772b676d549b81e91ca2e7fc33d270b352efdd5","src/weierstrass.rs":"b49e30b886ca5ee8a6725fa34d5c58108ee844888b73e5983856c7e2740bc9e2","tests/examples/pkcs8-private-key.der":"8125ab208d2181ed3ef05ff0ab1906e5898c36a858277e5b987e78e505288769","tests/examples/pkcs8-private-key.pem":"e0d0ce22e72577e5d00d7b8d65288f158032402fc9dbcaf63dc771d0eb91ae5f","tests/examples/pkcs8-public-key.der":"b9968d56ed8d6aa3fb43b15fa01e355d7a3a0203b1408b3fd2733637c4d1642c","tests/examples/pkcs8-public-key.pem":"d1ff198dc495da63f5f909db0254d6e49cff519487fcb26d055a762fc3ca47a1","tests/pkcs8.rs":"e99adb4b5282323911c6e0e89a126e7a32f930882d03d56013b2efab4abee15c","tests/secret_key.rs":"83fe5172364fb915ce54a47eee4579873a1b38ed9d6510f520c857f990d26027"},"package":"e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3"} \ No newline at end of file
diff --git a/vendor/elliptic-curve/CHANGELOG.md b/vendor/elliptic-curve/CHANGELOG.md
new file mode 100644
index 000000000..975e749d4
--- /dev/null
+++ b/vendor/elliptic-curve/CHANGELOG.md
@@ -0,0 +1,657 @@
+# Changelog
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
+and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+## 0.12.3 (2022-08-01)
+### Added
+- Aliases for SEC1 compressed/uncompressed points ([#1067])
+
+### Fixed
+- `arithmetic` + `serde` feature combo ([#1066])
+
+[#1066]: https://github.com/RustCrypto/traits/pull/1066
+[#1067]: https://github.com/RustCrypto/traits/pull/1067
+
+## 0.12.2 (2022-07-01)
+### Changed
+- Bump `crypto-bigint` to v0.4.8 ([#1039])
+
+[#1039]: https://github.com/RustCrypto/traits/pull/1039
+
+## 0.12.1 (2022-06-12)
+### Added
+- `impl_field_element!` macro ([#1021])
+- Generic impl of complete prime order formulas ([#1022])
+
+### Changed
+- Bump `crypto-bigint` to v0.4.4 ([#1018], [#1020])
+
+[#1018]: https://github.com/RustCrypto/traits/pull/1018
+[#1020]: https://github.com/RustCrypto/traits/pull/1020
+[#1021]: https://github.com/RustCrypto/traits/pull/1021
+[#1022]: https://github.com/RustCrypto/traits/pull/1022
+
+## 0.12.0 (2022-05-08)
+### Added
+- `ecdh::SharedSecret::extract` HKDF helper ([#1007])
+
+### Changed
+- Bump `digest` dependency to v0.10 ([#883], [#904])
+- Make `NonZeroScalar::invert` infallible ([#894])
+- `ToCompactEncodedPoint` now returns `CtOption` ([#895])
+- Move `hash2field` into `hash2curve` module ([#903])
+- Bump `ff` and `group` dependencies to v0.12 ([#994])
+- Use `serdect` crate ([#996])
+- Replace `AlgorithmParamters` with `AssociatedOid` ([#1001])
+- Bump `crypto-bigint` dependency to v0.4 ([#1005])
+- Bump `der` dependency to v0.6 ([#1006])
+- Bump `pkcs8` dependency to v0.9 ([#1006])
+- Bump `sec1` dependency to v0.3 ([#1006])
+- Bump `pem-rfc7468` dependency to v0.6 ([#1009])
+
+### Removed
+- `Zeroize` impl from `ecdh::SharedSecret` ([#978])
+
+[#883]: https://github.com/RustCrypto/traits/pull/883
+[#894]: https://github.com/RustCrypto/traits/pull/894
+[#895]: https://github.com/RustCrypto/traits/pull/895
+[#903]: https://github.com/RustCrypto/traits/pull/903
+[#904]: https://github.com/RustCrypto/traits/pull/904
+[#978]: https://github.com/RustCrypto/traits/pull/978
+[#994]: https://github.com/RustCrypto/traits/pull/994
+[#996]: https://github.com/RustCrypto/traits/pull/996
+[#1001]: https://github.com/RustCrypto/traits/pull/1001
+[#1005]: https://github.com/RustCrypto/traits/pull/1005
+[#1006]: https://github.com/RustCrypto/traits/pull/1006
+[#1007]: https://github.com/RustCrypto/traits/pull/1007
+[#1009]: https://github.com/RustCrypto/traits/pull/1009
+
+## 0.11.12 (2022-01-30)
+### Changed
+- Disable `bits` feature on docs.rs due to nightly breakage ([#927])
+
+[#927]: https://github.com/RustCrypto/traits/pull/927
+
+## 0.11.11 (2022-01-30)
+- No changes; triggering a docs.rs rebuild
+
+## 0.11.10 (2022-01-27)
+### Changed
+- Revert [#884] to support a wider range of `zeroize` versions ([#923])
+
+[#923]: https://github.com/RustCrypto/traits/pull/891
+
+## 0.11.9 (2022-01-17) [YANKED]
+### Changed
+- Activate `bits`, `hash2curve`, and `voprf` features on docs.rs ([#891])
+
+[#891]: https://github.com/RustCrypto/traits/pull/891
+
+## 0.11.8 (2022-01-15) [YANKED]
+### Added
+- Impl `ZeroizeOnDrop` on appropriate items ([#884])
+
+### Changed
+- Use the `base16ct` crate for hex serialization ([#886], [#887], [#888])
+
+[#884]: https://github.com/RustCrypto/traits/pull/884
+[#886]: https://github.com/RustCrypto/traits/pull/886
+[#887]: https://github.com/RustCrypto/traits/pull/887
+[#888]: https://github.com/RustCrypto/traits/pull/888
+
+## 0.11.7 (2022-01-14) [YANKED]
+### Added
+- Initial hash-to-field support ([#854], [#855], [#871], [#874])
+- Initial hash-to-curve support ([#865], [#876])
+- Impl `Mul` for `NonZeroScalar` * `NonZeroScalar` ([#857], [#862])
+- `Reduce::from_*e_digest_reduced` ([#869])
+- `VoprfParameters` trait ([#878])
+
+[#854]: https://github.com/RustCrypto/traits/pull/854
+[#855]: https://github.com/RustCrypto/traits/pull/855
+[#857]: https://github.com/RustCrypto/traits/pull/857
+[#862]: https://github.com/RustCrypto/traits/pull/862
+[#865]: https://github.com/RustCrypto/traits/pull/865
+[#869]: https://github.com/RustCrypto/traits/pull/869
+[#871]: https://github.com/RustCrypto/traits/pull/871
+[#874]: https://github.com/RustCrypto/traits/pull/874
+[#876]: https://github.com/RustCrypto/traits/pull/876
+[#878]: https://github.com/RustCrypto/traits/pull/878
+
+## 0.11.6 (2021-12-20)
+### Added
+- Type conversions chart ([#852])
+
+[#852]: https://github.com/RustCrypto/traits/pull/852
+
+## 0.11.5 (2021-12-05)
+### Changed
+- Revised `LinearCombination` trait ([#835])
+
+[#835]: https://github.com/RustCrypto/traits/pull/835
+
+## 0.11.4 (2021-12-04) [YANKED]
+### Added
+- `LinearCombination` trait ([#832])
+
+[#832]: https://github.com/RustCrypto/traits/pull/832
+
+## 0.11.3 (2021-12-03) [YANKED]
+### Added
+- `ReduceNonZero` trait ([#827])
+
+[#827]: https://github.com/RustCrypto/traits/pull/827
+
+## 0.11.2 (2021-12-03) [YANKED]
+### Changed
+- Bump `pem-rfc7468` dependency to v0.3 ([#825])
+
+[#825]: https://github.com/RustCrypto/traits/pull/825
+
+## 0.11.1 (2021-11-21) [YANKED]
+### Added
+- `NonZeroScalar::from_uint` ([#822])
+
+[#822]: https://github.com/RustCrypto/traits/pull/822
+
+## 0.11.0 (2021-11-19) [YANKED]
+### Added
+- `ScalarCore<C>` type ([#732])
+- `PrimeCurveArithmetic` trait ([#739])
+- SEC1 private key support ([#762])
+- `Reduce` trait ([#768])
+- Re-export `ff` and `PrimeField` ([#796])
+- `Encoding` bound on `Curve::UInt` ([#806])
+- `scalar::IsHigh` trait ([#814], [#815])
+- `Neg` impl for `NonZeroScalar<C>` ([#816])
+- `AffineXCoordinate` trait ([#817])
+- `serde` support for scalar and `PublicKey` types ([#818])
+
+### Changed
+- Bump `ff` + `group` to v0.11 ([#730])
+- Make `SecretKey::to_jwk_string` self-zeroizing ([#742])
+- Use `sec1` crate's `EncodedPoint` ([#771])
+- Make `FromEncodedPoint` return a `CtOption` ([#782])
+- Rust 2021 edition upgrade; MSRV to 1.56 ([#795])
+- Bump `crypto-bigint` dependency to v0.3 ([#807])
+- Use `sec1` crate for `pkcs8` support ([#809])
+- Bump `spki` dependency to v0.5 release ([#810])
+- `NonZeroScalar` is now bounded on `ScalarArithmetic` instead of
+ `ProjectiveArithmetic` ([#812])
+
+### Fixed
+- `Zeroize` impl on `NonZeroScalar` ([#785])
+
+[#730]: https://github.com/RustCrypto/traits/pull/730
+[#732]: https://github.com/RustCrypto/traits/pull/732
+[#739]: https://github.com/RustCrypto/traits/pull/739
+[#742]: https://github.com/RustCrypto/traits/pull/742
+[#762]: https://github.com/RustCrypto/traits/pull/762
+[#768]: https://github.com/RustCrypto/traits/pull/768
+[#771]: https://github.com/RustCrypto/traits/pull/771
+[#782]: https://github.com/RustCrypto/traits/pull/782
+[#785]: https://github.com/RustCrypto/traits/pull/785
+[#795]: https://github.com/RustCrypto/traits/pull/795
+[#796]: https://github.com/RustCrypto/traits/pull/796
+[#806]: https://github.com/RustCrypto/traits/pull/806
+[#807]: https://github.com/RustCrypto/traits/pull/807
+[#809]: https://github.com/RustCrypto/traits/pull/809
+[#810]: https://github.com/RustCrypto/traits/pull/810
+[#812]: https://github.com/RustCrypto/traits/pull/812
+[#814]: https://github.com/RustCrypto/traits/pull/814
+[#815]: https://github.com/RustCrypto/traits/pull/815
+[#816]: https://github.com/RustCrypto/traits/pull/816
+[#817]: https://github.com/RustCrypto/traits/pull/817
+[#818]: https://github.com/RustCrypto/traits/pull/818
+
+## 0.10.6 (2021-08-23)
+### Changed
+- Bump `crypto-bigint` dependency to v0.2.4 ([#710])
+
+[#710]: https://github.com/RustCrypto/traits/pull/710
+
+## 0.10.5 (2021-07-20)
+### Changed
+- Pin `zeroize` dependency to v1.4 and `subtle` to v2.4 ([#689])
+
+[#689]: https://github.com/RustCrypto/traits/pull/689
+
+## 0.10.4 (2021-07-12)
+### Added
+- Re-export `rand_core` ([#683])
+
+[#683]: https://github.com/RustCrypto/traits/pull/683
+
+## 0.10.3 (2021-06-21)
+### Changed
+- Bump `crypto-bigint` to v0.2.1 ([#673])
+
+[#673]: https://github.com/RustCrypto/traits/pull/673
+
+## 0.10.2 (2021-06-14) [YANKED]
+### Added
+- `ConstantTimeEq` impl for `NonZeroScalar` ([#669])
+
+[#669]: https://github.com/RustCrypto/traits/pull/669
+
+## 0.10.1 (2021-06-09) [YANKED]
+### Added
+- Explicit `Copy` bounds on `PublicKey` ([#667])
+
+[#667]: https://github.com/RustCrypto/traits/pull/667
+
+## 0.10.0 (2021-06-07) [YANKED]
+### Added
+- `ScalarBytes::from_uint` ([#651])
+- `dev::ScalarBytes` ([#652])
+- `ScalarArithmetic` trait ([#654])
+- `AffineArithmetic` trait ([#658])
+- `PointCompaction` trait and SEC1 tag support ([#659])
+
+### Changed
+- Bump `ff` and `group` to v0.10; MSRV 1.51+ ([#643])
+- Merge `Curve` and `Order` traits ([#644])
+- Use `crypto-bigint` to represent `Curve::ORDER` ([#645])
+- Source `FieldSize<C>` from `C::UInt` type ([#646])
+- Impl `ScalarBytes<C>` using `C::UInt` ([#647])
+- Make `ScalarBytes<C>` the `SecretKey<C>` internal repr ([#649])
+- Bump `crypto-bigint` to v0.2 ([#662])
+- Bump `pkcs8` to v0.7 ([#662])
+
+### Removed
+- `util` module ([#648])
+
+[#643]: https://github.com/RustCrypto/traits/pull/643
+[#644]: https://github.com/RustCrypto/traits/pull/644
+[#645]: https://github.com/RustCrypto/traits/pull/645
+[#646]: https://github.com/RustCrypto/traits/pull/646
+[#647]: https://github.com/RustCrypto/traits/pull/647
+[#648]: https://github.com/RustCrypto/traits/pull/648
+[#649]: https://github.com/RustCrypto/traits/pull/649
+[#651]: https://github.com/RustCrypto/traits/pull/651
+[#652]: https://github.com/RustCrypto/traits/pull/652
+[#654]: https://github.com/RustCrypto/traits/pull/654
+[#658]: https://github.com/RustCrypto/traits/pull/658
+[#659]: https://github.com/RustCrypto/traits/pull/659
+[#662]: https://github.com/RustCrypto/traits/pull/662
+
+## 0.9.12 (2021-05-18)
+### Added
+- `Ord` and `PartialOrd` impls on `PublicKey` ([#637])
+
+[#637]: https://github.com/RustCrypto/traits/pull/637
+
+## 0.9.11 (2021-04-21)
+### Added
+- Impl `subtle` traits on `ScalarBytes<C>` ([#612])
+
+### Fixed
+- Always re-export ScalarBytes ([#613])
+
+[#612]: https://github.com/RustCrypto/traits/pull/612
+[#613]: https://github.com/RustCrypto/traits/pull/613
+
+## 0.9.10 (2021-04-21)
+### Added
+- `ScalarBytes` type ([#610])
+
+[#610]: https://github.com/RustCrypto/traits/pull/610
+
+## 0.9.9 (2021-04-21) [YANKED]
+### Added
+- `Order::is_scalar_repr_in_range` ([#608])
+
+[#608]: https://github.com/RustCrypto/traits/pull/608
+
+## 0.9.8 (2021-04-21)
+### Added
+- Define `Order` for `MockCurve` ([#606])
+
+[#606]: https://github.com/RustCrypto/traits/pull/606
+
+## 0.9.7 (2021-04-21)
+### Added
+- `Order` trait ([#603])
+
+### Fixed
+- Warnings from `pkcs8` imports ([#604])
+
+[#603]: https://github.com/RustCrypto/traits/pull/603
+[#604]: https://github.com/RustCrypto/traits/pull/604
+
+## 0.9.6 (2021-03-22)
+### Changed
+- Bump `pkcs8` dependency to v0.6 ([#585])
+
+[#585]: https://github.com/RustCrypto/traits/pull/585
+
+## 0.9.5 (2021-03-17) [YANKED]
+### Added
+- Implement `{to,char}_le_bits` for `MockCurve` ([#565])
+- Implement `one()` for mock `Scalar` ([#566])
+
+### Changed
+- Use string-based OID constants ([#561])
+- Bump `base64ct` dependency to v1.0 ([#581])
+
+[#561]: https://github.com/RustCrypto/traits/pull/561
+[#565]: https://github.com/RustCrypto/traits/pull/565
+[#566]: https://github.com/RustCrypto/traits/pull/566
+[#581]: https://github.com/RustCrypto/traits/pull/581
+
+## 0.9.4 (2021-02-18) [YANKED]
+### Fixed
+- Breakage related to the `pkcs8` v0.5.1 crate ([#556])
+
+[#556]: https://github.com/RustCrypto/traits/pull/556
+
+## 0.9.3 (2021-02-16) [YANKED]
+### Changed
+- Bump `pkcs8` dependency to v0.5.0 ([#549])
+
+### Fixed
+- Workaround for bitvecto-rs/bitvec#105 ([#550])
+
+[#549]: https://github.com/RustCrypto/traits/pull/549
+[#550]: https://github.com/RustCrypto/traits/pull/550
+
+## 0.9.2 (2021-02-12) [YANKED]
+### Changed
+- Flatten `weierstrass` module ([#542])
+
+[#542]: https://github.com/RustCrypto/traits/pull/542
+
+## 0.9.1 (2021-02-11) [YANKED]
+### Removed
+- `BitView` re-export ([#540])
+
+[#540]: https://github.com/RustCrypto/traits/pull/540
+
+## 0.9.0 (2021-02-10) [YANKED]
+### Added
+- JWK support ([#483])
+- `sec1::ValidatePublicKey` trait ([#485])
+- `hazmat` crate feature ([#487])
+- `Result` alias ([#534])
+
+### Changed
+- Bump `ff` and `group` crates to v0.9 ([#452])
+- Simplify ECDH trait bounds ([#475])
+- Flatten API ([#487])
+- Bump `pkcs8` crate dependency to v0.4 ([#493])
+
+### Removed
+- Direct `bitvec` dependency ([#484])
+- `FromDigest` trait ([#532])
+
+[#452]: https://github.com/RustCrypto/traits/pull/452
+[#475]: https://github.com/RustCrypto/traits/pull/475
+[#483]: https://github.com/RustCrypto/traits/pull/483
+[#484]: https://github.com/RustCrypto/traits/pull/484
+[#485]: https://github.com/RustCrypto/traits/pull/485
+[#487]: https://github.com/RustCrypto/traits/pull/487
+[#493]: https://github.com/RustCrypto/traits/pull/493
+[#432]: https://github.com/RustCrypto/traits/pull/432
+[#532]: https://github.com/RustCrypto/traits/pull/532
+[#534]: https://github.com/RustCrypto/traits/pull/534
+
+## 0.8.5 (2021-02-17)
+### Fixed
+- Workaround for bitvecto-rs/bitvec#105 ([#553])
+
+[#553]: https://github.com/RustCrypto/traits/pull/553
+
+## 0.8.4 (2020-12-23)
+### Fixed
+- Rust `nightly` regression ([#432])
+
+[#432]: https://github.com/RustCrypto/traits/pull/432
+
+## 0.8.3 (2020-12-22)
+### Fixed
+- Regression in combination of `pem`+`zeroize` features ([#429])
+
+[#429]: https://github.com/RustCrypto/traits/pull/429
+
+## 0.8.2 (2020-12-22) [YANKED]
+### Added
+- Low-level ECDH API ([#418])
+- `dev` module ([#419])
+- Impl `pkcs8::ToPrivateKey` for `SecretKey<C>` ([#423])
+- Impl `pkcs8::ToPublicKey` for `PublicKey<C>` ([#427])
+
+### Changed
+- Bump `subtle` dependency to 2.4.0 ([#414])
+- Bump `pkcs8` dependency to v0.3.3 ([#425])
+- Use `der` crate to parse `SecretKey` ([#422])
+
+### Fixed
+- Make `PublicKey::from_encoded_point` go through `PublicKey::from_affine` ([#416])
+
+[#414]: https://github.com/RustCrypto/traits/pull/414
+[#416]: https://github.com/RustCrypto/traits/pull/416
+[#418]: https://github.com/RustCrypto/traits/pull/418
+[#419]: https://github.com/RustCrypto/traits/pull/419
+[#422]: https://github.com/RustCrypto/traits/pull/422
+[#423]: https://github.com/RustCrypto/traits/pull/423
+[#425]: https://github.com/RustCrypto/traits/pull/425
+[#427]: https://github.com/RustCrypto/traits/pull/427
+
+## 0.8.1 (2020-12-16) [YANKED]
+### Fixed
+- Builds on Rust `nightly` compiler ([#412])
+
+[#412]: https://github.com/RustCrypto/traits/pull/412
+
+## 0.8.0 (2020-12-16) [YANKED]
+### Added
+- Impl `subtle::ConditionallySelectable` for `sec1::EncodedPoint` ([#409])
+- `sec1::EncodedPoint::identity()` method ([#408])
+- `sec1::Coordinates::tag` method ([#407])
+- Support for SEC1 identity encoding ([#401])
+
+### Changed
+- Bump `pkcs8` crate dependency to v0.3 ([#405])
+- Ensure `PublicKey<C>` is not the identity point ([#404])
+- Have `SecretKey::secret_scalar` return `NonZeroScalar` ([#402])
+
+### Removed
+- `SecretKey::secret_value` ([#403])
+
+[#409]: https://github.com/RustCrypto/traits/pull/409
+[#408]: https://github.com/RustCrypto/traits/pull/408
+[#407]: https://github.com/RustCrypto/traits/pull/407
+[#405]: https://github.com/RustCrypto/traits/pull/405
+[#404]: https://github.com/RustCrypto/traits/pull/404
+[#403]: https://github.com/RustCrypto/traits/pull/403
+[#402]: https://github.com/RustCrypto/traits/pull/402
+[#401]: https://github.com/RustCrypto/traits/pull/401
+
+## 0.7.1 (2020-12-07)
+### Changed
+- Have `SecretKey::secret_value` always return `NonZeroScalar` ([#390])
+
+[#390]: https://github.com/RustCrypto/traits/pull/390
+
+## 0.7.0 (2020-12-06) [YANKED]
+### Added
+- Impl `pkcs8::FromPublicKey` for `PublicKey<C>` ([#385])
+- Impl `pkcs8::FromPrivateKey` trait for `SecretKey<C>` ([#381], [#383])
+- PKCS#8 PEM support ([#382])
+- `SecretKey::secret_value()` method ([#375])
+- `PublicKey<C>` type ([#363], [#366])
+
+### Changed
+- Rename `PublicKey::from_bytes()` to `::from_sec1_bytes()` ([#376])
+- `sec1::EncodedPoint` uses `Option` instead of `subtle::CtOption` ([#367])
+- Bump `const-oid` to v0.3; MSRV 1.46+ ([#365], [#381])
+
+### Fixed
+- `ecdh` rustdoc ([#364])
+
+[#385]: https://github.com/RustCrypto/traits/pull/385
+[#383]: https://github.com/RustCrypto/traits/pull/383
+[#382]: https://github.com/RustCrypto/traits/pull/382
+[#381]: https://github.com/RustCrypto/traits/pull/381
+[#376]: https://github.com/RustCrypto/traits/pull/376
+[#375]: https://github.com/RustCrypto/traits/pull/375
+[#367]: https://github.com/RustCrypto/traits/pull/367
+[#366]: https://github.com/RustCrypto/traits/pull/366
+[#365]: https://github.com/RustCrypto/traits/pull/365
+[#364]: https://github.com/RustCrypto/traits/pull/364
+[#363]: https://github.com/RustCrypto/traits/pull/363
+
+## 0.6.6 (2020-10-08)
+### Added
+- Derive `Clone` on `SecretBytes` ([#330])
+
+[#300]: https://github.com/RustCrypto/traits/pull/300
+
+## 0.6.5 (2020-10-08)
+### Fixed
+- Work around `nightly-2020-10-06` breakage ([#328])
+
+[#328]: https://github.com/RustCrypto/traits/pull/328
+
+## 0.6.4 (2020-10-08)
+### Added
+- Impl `From<SecretBytes<C>>` for `FieldBytes<C>` ([#326])
+
+[#326]: https://github.com/RustCrypto/traits/pull/326
+
+## 0.6.3 (2020-10-08)
+### Added
+- `SecretBytes` newtype ([#324])
+
+[#324]: https://github.com/RustCrypto/traits/pull/324
+
+## 0.6.2 (2020-09-24)
+### Added
+- `sec1::EncodedPoint::to_untagged_bytes()` method ([#312])
+
+[#312]: https://github.com/RustCrypto/traits/pull/312
+
+## 0.6.1 (2020-09-21)
+### Fixed
+- `sec1::EncodedPoint::decompress` ([#309])
+
+[#309]: https://github.com/RustCrypto/traits/pull/309
+
+## 0.6.0 (2020-09-11) [YANKED]
+### Added
+- `arithmetic` feature ([#293])
+- Generic curve/field arithmetic using the `ff` and `group` crates
+ ([#287], [#291], [#292])
+- `sec1::Coordinates` ([#286])
+- `weierstrass::point::Compression` trait ([#283], [#300])
+- Arithmetic helper functions ([#281])
+- `digest` feature and `FromDigest` trait ([#279])
+- impl `Deref` for `NonZeroScalar` ([#278])
+- Conditionally impl `Invert` for `NonZeroScalar` ([#277])
+- `NonZeroScalar::to_bytes` ([#276])
+- `EncodedPoint::decompress` ([#275])
+- `sec1::Tag` ([#270])
+- `weierstrass::point::Decompress` trait ([#266])
+- `alloc` feature + `EncodedPoint::to_bytes()` ([#265])
+
+### Changed
+- Renamed `Arithmetic` trait to `point::ProjectiveArithmetic` ([#300])
+- Replaced `Arithmetic::Scalar` and `Arithmetic::AffinePoint`
+ with `Scalar<C>` and `AffinePoint<C>` ([#300])
+- Made `SecretKey<C>` inner type generic ([#297])
+- Renamed `ElementBytes<C>` to `FieldBytes<C>` ([#296])
+- MSRV 1.44 ([#292])
+- Minimum `subtle` version now v2.3 ([#290])
+- Renamed `Curve::ElementSize` to `::FieldSize` ([#282])
+- Refactor `PublicKey` into `sec1::EncodedPoint` ([#264])
+
+### Removed
+- `FromBytes` trait ([#300])
+- `Generate` trait ([#295])
+
+[#300]: https://github.com/RustCrypto/traits/pull/300
+[#297]: https://github.com/RustCrypto/traits/pull/297
+[#296]: https://github.com/RustCrypto/traits/pull/296
+[#295]: https://github.com/RustCrypto/traits/pull/295
+[#293]: https://github.com/RustCrypto/traits/pull/293
+[#292]: https://github.com/RustCrypto/traits/pull/292
+[#291]: https://github.com/RustCrypto/traits/pull/291
+[#290]: https://github.com/RustCrypto/traits/pull/290
+[#287]: https://github.com/RustCrypto/traits/pull/293
+[#286]: https://github.com/RustCrypto/traits/pull/286
+[#283]: https://github.com/RustCrypto/traits/pull/283
+[#282]: https://github.com/RustCrypto/traits/pull/282
+[#281]: https://github.com/RustCrypto/traits/pull/281
+[#279]: https://github.com/RustCrypto/traits/pull/279
+[#278]: https://github.com/RustCrypto/traits/pull/278
+[#277]: https://github.com/RustCrypto/traits/pull/277
+[#276]: https://github.com/RustCrypto/traits/pull/276
+[#275]: https://github.com/RustCrypto/traits/pull/275
+[#270]: https://github.com/RustCrypto/traits/pull/270
+[#266]: https://github.com/RustCrypto/traits/pull/266
+[#265]: https://github.com/RustCrypto/traits/pull/265
+[#264]: https://github.com/RustCrypto/traits/pull/264
+
+## 0.5.0 (2020-08-10)
+### Added
+- `Arithmetic` trait ([#219])
+- `Generate` trait ([#220], [#226])
+- Toplevel `Curve` trait ([#223])
+- `Invert` trait ([#228])
+- `FromPublicKey` trait ([#229], [#248])
+- Re-export `zeroize` ([#233])
+- OID support ([#240], [#245])
+- `NonZeroScalar` type ([#241])
+- `Generator` trait ([#241])
+- `weierstrass::PublicKey::compress` method ([#243])
+- Derive `Clone` on `SecretKey` ([#244])
+- Generic Elliptic Curve Diffie-Hellman support ([#251])
+
+### Changed
+- Moved repo to https://github.com/RustCrypto/traits ([#213])
+- Rename `ScalarBytes` to `ElementBytes` ([#246])
+- Rename `CompressedCurvePoint`/`UncompressedCurvePoint` to
+ `CompressedPoint`/`UncompressedPoint`
+
+[#213]: https://github.com/RustCrypto/traits/pull/213
+[#219]: https://github.com/RustCrypto/traits/pull/219
+[#220]: https://github.com/RustCrypto/traits/pull/220
+[#223]: https://github.com/RustCrypto/traits/pull/223
+[#226]: https://github.com/RustCrypto/traits/pull/226
+[#228]: https://github.com/RustCrypto/traits/pull/228
+[#229]: https://github.com/RustCrypto/traits/pull/229
+[#233]: https://github.com/RustCrypto/traits/pull/233
+[#240]: https://github.com/RustCrypto/traits/pull/240
+[#241]: https://github.com/RustCrypto/traits/pull/241
+[#243]: https://github.com/RustCrypto/traits/pull/243
+[#244]: https://github.com/RustCrypto/traits/pull/244
+[#245]: https://github.com/RustCrypto/traits/pull/245
+[#246]: https://github.com/RustCrypto/traits/pull/246
+[#248]: https://github.com/RustCrypto/traits/pull/248
+[#251]: https://github.com/RustCrypto/traits/pull/251
+
+## 0.4.0 (2020-06-04)
+### Changed
+- Bump `generic-array` dependency from v0.12 to v0.14
+
+## 0.3.0 (2020-01-15)
+### Added
+- `Scalar` struct type
+
+### Changed
+- Repository moved to <https://github.com/RustCrypto/elliptic-curves>
+
+### Removed
+- Curve definitions/arithmetic extracted out into per-curve crates
+
+## 0.2.0 (2019-12-11)
+### Added
+- `secp256r1` (P-256) point compression and decompression
+
+### Changed
+- Bump MSRV to 1.37
+
+## 0.1.0 (2019-12-06)
+- Initial release
diff --git a/vendor/elliptic-curve/Cargo.toml b/vendor/elliptic-curve/Cargo.toml
new file mode 100644
index 000000000..906ac569a
--- /dev/null
+++ b/vendor/elliptic-curve/Cargo.toml
@@ -0,0 +1,209 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies.
+#
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
+
+[package]
+edition = "2021"
+rust-version = "1.57"
+name = "elliptic-curve"
+version = "0.12.3"
+authors = ["RustCrypto Developers"]
+description = """
+General purpose Elliptic Curve Cryptography (ECC) support, including types
+and traits for representing various elliptic curve forms, scalars, points,
+and public/secret keys composed thereof.
+"""
+readme = "README.md"
+keywords = [
+ "crypto",
+ "ecc",
+ "elliptic",
+ "weierstrass",
+]
+categories = [
+ "cryptography",
+ "no-std",
+]
+license = "Apache-2.0 OR MIT"
+repository = "https://github.com/RustCrypto/traits/tree/master/elliptic-curve"
+resolver = "2"
+
+[package.metadata.docs.rs]
+features = [
+ "bits",
+ "ecdh",
+ "hash2curve",
+ "jwk",
+ "pem",
+ "std",
+ "voprf",
+]
+rustdoc-args = [
+ "--cfg",
+ "docsrs",
+]
+
+[dependencies.base16ct]
+version = "0.1.1"
+
+[dependencies.base64ct]
+version = "1"
+optional = true
+default-features = false
+
+[dependencies.crypto-bigint]
+version = "0.4.8"
+features = [
+ "rand_core",
+ "generic-array",
+ "zeroize",
+]
+default-features = false
+
+[dependencies.der]
+version = "0.6"
+features = ["oid"]
+default-features = false
+
+[dependencies.digest]
+version = "0.10"
+optional = true
+
+[dependencies.ff]
+version = "0.12"
+optional = true
+default-features = false
+
+[dependencies.generic-array]
+version = "0.14"
+default-features = false
+
+[dependencies.group]
+version = "0.12"
+optional = true
+default-features = false
+
+[dependencies.hex-literal]
+version = "0.3"
+optional = true
+
+[dependencies.hkdf]
+version = "0.12"
+optional = true
+default-features = false
+
+[dependencies.pem-rfc7468]
+version = "0.6"
+optional = true
+
+[dependencies.pkcs8]
+version = "0.9"
+optional = true
+default-features = false
+
+[dependencies.rand_core]
+version = "0.6"
+default-features = false
+
+[dependencies.sec1]
+version = "0.3"
+features = [
+ "subtle",
+ "zeroize",
+]
+optional = true
+
+[dependencies.serde_json]
+version = "1"
+features = ["alloc"]
+optional = true
+default-features = false
+
+[dependencies.serdect]
+version = "0.1"
+features = ["alloc"]
+optional = true
+default-features = false
+
+[dependencies.subtle]
+version = "2"
+default-features = false
+
+[dependencies.zeroize]
+version = "1.5"
+default-features = false
+
+[dev-dependencies.hex-literal]
+version = "0.3"
+
+[dev-dependencies.sha2]
+version = "0.10"
+
+[dev-dependencies.sha3]
+version = "0.10"
+
+[features]
+alloc = [
+ "base16ct/alloc",
+ "der/alloc",
+ "sec1/alloc",
+ "zeroize/alloc",
+]
+arithmetic = [
+ "ff",
+ "group",
+]
+bits = [
+ "arithmetic",
+ "ff/bits",
+]
+default = ["arithmetic"]
+dev = [
+ "arithmetic",
+ "hex-literal",
+ "pem",
+ "pkcs8",
+]
+ecdh = [
+ "arithmetic",
+ "digest",
+ "hkdf",
+]
+hash2curve = [
+ "arithmetic",
+ "digest",
+]
+hazmat = []
+jwk = [
+ "alloc",
+ "base64ct/alloc",
+ "serde",
+ "serde_json",
+ "zeroize/alloc",
+]
+pem = [
+ "alloc",
+ "arithmetic",
+ "der/pem",
+ "pem-rfc7468/alloc",
+ "pkcs8",
+ "sec1/pem",
+]
+serde = [
+ "alloc",
+ "pkcs8",
+ "sec1/serde",
+ "serdect",
+]
+std = [
+ "alloc",
+ "rand_core/std",
+]
+voprf = ["digest"]
diff --git a/vendor/elliptic-curve/LICENSE-APACHE b/vendor/elliptic-curve/LICENSE-APACHE
new file mode 100644
index 000000000..78173fa2e
--- /dev/null
+++ b/vendor/elliptic-curve/LICENSE-APACHE
@@ -0,0 +1,201 @@
+ 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.
diff --git a/vendor/elliptic-curve/LICENSE-MIT b/vendor/elliptic-curve/LICENSE-MIT
new file mode 100644
index 000000000..d4ce06527
--- /dev/null
+++ b/vendor/elliptic-curve/LICENSE-MIT
@@ -0,0 +1,25 @@
+Copyright (c) 2020-2022 RustCrypto Developers
+
+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.
diff --git a/vendor/elliptic-curve/README.md b/vendor/elliptic-curve/README.md
new file mode 100644
index 000000000..254a99433
--- /dev/null
+++ b/vendor/elliptic-curve/README.md
@@ -0,0 +1,54 @@
+# RustCrypto: Elliptic Curve Traits
+
+[![crate][crate-image]][crate-link]
+[![Docs][docs-image]][docs-link]
+[![Build Status][build-image]][build-link]
+![Apache2/MIT licensed][license-image]
+![Rust Version][rustc-image]
+[![Project Chat][chat-image]][chat-link]
+
+General purpose Elliptic Curve Cryptography (ECC) support, including types
+and traits for representing various elliptic curve forms, scalars, points,
+and public/secret keys composed thereof.
+
+[Documentation][docs-link]
+
+## Minimum Supported Rust Version
+
+Requires Rust **1.57** or higher.
+
+Minimum supported Rust version can be changed in the future, but it will be
+done with a minor version bump.
+
+## SemVer Policy
+
+- All on-by-default features of this library are covered by SemVer
+- MSRV is considered exempt from SemVer as noted above
+
+## License
+
+All crates licensed under either of
+
+ * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)
+ * [MIT license](http://opensource.org/licenses/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.
+
+[//]: # (badges)
+
+[crate-image]: https://buildstats.info/crate/elliptic-curve
+[crate-link]: https://crates.io/crates/elliptic-curve
+[docs-image]: https://docs.rs/elliptic-curve/badge.svg
+[docs-link]: https://docs.rs/elliptic-curve/
+[build-image]: https://github.com/RustCrypto/traits/actions/workflows/elliptic-curve.yml/badge.svg
+[build-link]: https://github.com/RustCrypto/traits/actions/workflows/elliptic-curve.yml
+[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg
+[rustc-image]: https://img.shields.io/badge/rustc-1.57+-blue.svg
+[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg
+[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260040-elliptic-curves
diff --git a/vendor/elliptic-curve/src/arithmetic.rs b/vendor/elliptic-curve/src/arithmetic.rs
new file mode 100644
index 000000000..fa445f1bc
--- /dev/null
+++ b/vendor/elliptic-curve/src/arithmetic.rs
@@ -0,0 +1,87 @@
+//! Elliptic curve arithmetic traits.
+
+use crate::{
+ ops::LinearCombination, AffineXCoordinate, Curve, FieldBytes, IsHigh, PrimeCurve, ScalarCore,
+};
+use core::fmt::Debug;
+use subtle::{ConditionallySelectable, ConstantTimeEq};
+use zeroize::DefaultIsZeroes;
+
+/// Elliptic curve with affine arithmetic implementation.
+#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))]
+pub trait AffineArithmetic: Curve + ScalarArithmetic {
+ /// Elliptic curve point in affine coordinates.
+ type AffinePoint: 'static
+ + AffineXCoordinate<Self>
+ + Copy
+ + Clone
+ + ConditionallySelectable
+ + ConstantTimeEq
+ + Debug
+ + Default
+ + DefaultIsZeroes
+ + Eq
+ + PartialEq
+ + Sized
+ + Send
+ + Sync;
+}
+
+/// Prime order elliptic curve with projective arithmetic implementation.
+#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))]
+pub trait PrimeCurveArithmetic:
+ PrimeCurve + ProjectiveArithmetic<ProjectivePoint = Self::CurveGroup>
+{
+ /// Prime order elliptic curve group.
+ type CurveGroup: group::prime::PrimeCurve<Affine = <Self as AffineArithmetic>::AffinePoint>;
+}
+
+/// Elliptic curve with projective arithmetic implementation.
+#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))]
+pub trait ProjectiveArithmetic: Curve + AffineArithmetic {
+ /// Elliptic curve point in projective coordinates.
+ ///
+ /// Note: the following bounds are provided by [`group::Group`]:
+ /// - `'static`
+ /// - [`Copy`]
+ /// - [`Clone`]
+ /// - [`Debug`]
+ /// - [`Eq`]
+ /// - [`Sized`]
+ /// - [`Send`]
+ /// - [`Sync`]
+ type ProjectivePoint: ConditionallySelectable
+ + ConstantTimeEq
+ + Default
+ + DefaultIsZeroes
+ + From<Self::AffinePoint>
+ + Into<Self::AffinePoint>
+ + LinearCombination
+ + group::Curve<AffineRepr = Self::AffinePoint>
+ + group::Group<Scalar = Self::Scalar>;
+}
+
+/// Scalar arithmetic.
+#[cfg(feature = "arithmetic")]
+#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))]
+pub trait ScalarArithmetic: Curve {
+ /// Scalar field type.
+ ///
+ /// Note: the following bounds are provided by [`ff::Field`]:
+ /// - `'static`
+ /// - [`Copy`]
+ /// - [`Clone`]
+ /// - [`ConditionallySelectable`]
+ /// - [`ConstantTimeEq`]
+ /// - [`Debug`]
+ /// - [`Default`]
+ /// - [`Send`]
+ /// - [`Sync`]
+ type Scalar: DefaultIsZeroes
+ + From<ScalarCore<Self>>
+ + Into<FieldBytes<Self>>
+ + Into<Self::UInt>
+ + IsHigh
+ + ff::Field
+ + ff::PrimeField<Repr = FieldBytes<Self>>;
+}
diff --git a/vendor/elliptic-curve/src/dev.rs b/vendor/elliptic-curve/src/dev.rs
new file mode 100644
index 000000000..be0c156e5
--- /dev/null
+++ b/vendor/elliptic-curve/src/dev.rs
@@ -0,0 +1,794 @@
+//! Development-related functionality.
+//!
+//! Helpers and types for writing tests against concrete implementations of
+//! the traits in this crate.
+
+use crate::{
+ bigint::{Limb, U256},
+ error::{Error, Result},
+ ops::{LinearCombination, Reduce},
+ pkcs8,
+ rand_core::RngCore,
+ sec1::{FromEncodedPoint, ToEncodedPoint},
+ subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption},
+ zeroize::DefaultIsZeroes,
+ AffineArithmetic, AffineXCoordinate, Curve, IsHigh, PrimeCurve, ProjectiveArithmetic,
+ ScalarArithmetic,
+};
+use core::{
+ iter::Sum,
+ ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign},
+};
+use ff::{Field, PrimeField};
+use generic_array::arr;
+use hex_literal::hex;
+use pkcs8::AssociatedOid;
+
+#[cfg(feature = "bits")]
+use crate::group::ff::PrimeFieldBits;
+
+#[cfg(feature = "jwk")]
+use crate::JwkParameters;
+
+/// Pseudo-coordinate for fixed-based scalar mult output
+pub const PSEUDO_COORDINATE_FIXED_BASE_MUL: [u8; 32] =
+ hex!("deadbeef00000000000000000000000000000000000000000000000000000001");
+
+/// SEC1 encoded point.
+pub type EncodedPoint = crate::sec1::EncodedPoint<MockCurve>;
+
+/// Field element bytes.
+pub type FieldBytes = crate::FieldBytes<MockCurve>;
+
+/// Non-zero scalar value.
+pub type NonZeroScalar = crate::NonZeroScalar<MockCurve>;
+
+/// Public key.
+pub type PublicKey = crate::PublicKey<MockCurve>;
+
+/// Secret key.
+pub type SecretKey = crate::SecretKey<MockCurve>;
+
+/// Scalar core.
+// TODO(tarcieri): make this the scalar type
+pub type ScalarCore = crate::ScalarCore<MockCurve>;
+
+/// Scalar bits.
+#[cfg(feature = "bits")]
+pub type ScalarBits = crate::ScalarBits<MockCurve>;
+
+/// Mock elliptic curve type useful for writing tests which require a concrete
+/// curve type.
+///
+/// Note: this type is roughly modeled off of NIST P-256, but does not provide
+/// an actual cure arithmetic implementation.
+#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, PartialOrd, Ord)]
+pub struct MockCurve;
+
+impl Curve for MockCurve {
+ type UInt = U256;
+
+ const ORDER: U256 =
+ U256::from_be_hex("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551");
+}
+
+impl PrimeCurve for MockCurve {}
+
+impl AffineArithmetic for MockCurve {
+ type AffinePoint = AffinePoint;
+}
+
+impl ProjectiveArithmetic for MockCurve {
+ type ProjectivePoint = ProjectivePoint;
+}
+
+impl ScalarArithmetic for MockCurve {
+ type Scalar = Scalar;
+}
+
+impl AssociatedOid for MockCurve {
+ /// OID for NIST P-256
+ const OID: pkcs8::ObjectIdentifier = pkcs8::ObjectIdentifier::new_unwrap("1.2.840.10045.3.1.7");
+}
+
+#[cfg(feature = "jwk")]
+#[cfg_attr(docsrs, doc(cfg(feature = "jwk")))]
+impl JwkParameters for MockCurve {
+ const CRV: &'static str = "P-256";
+}
+
+/// Example scalar type
+#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
+pub struct Scalar(ScalarCore);
+
+impl Field for Scalar {
+ fn random(mut rng: impl RngCore) -> Self {
+ let mut bytes = FieldBytes::default();
+
+ loop {
+ rng.fill_bytes(&mut bytes);
+ if let Some(scalar) = Self::from_repr(bytes).into() {
+ return scalar;
+ }
+ }
+ }
+
+ fn zero() -> Self {
+ Self(ScalarCore::ZERO)
+ }
+
+ fn one() -> Self {
+ Self(ScalarCore::ONE)
+ }
+
+ fn is_zero(&self) -> Choice {
+ self.0.is_zero()
+ }
+
+ #[must_use]
+ fn square(&self) -> Self {
+ unimplemented!();
+ }
+
+ #[must_use]
+ fn double(&self) -> Self {
+ self.add(self)
+ }
+
+ fn invert(&self) -> CtOption<Self> {
+ unimplemented!();
+ }
+
+ fn sqrt(&self) -> CtOption<Self> {
+ unimplemented!();
+ }
+}
+
+impl PrimeField for Scalar {
+ type Repr = FieldBytes;
+
+ const NUM_BITS: u32 = 256;
+ const CAPACITY: u32 = 255;
+ const S: u32 = 4;
+
+ fn from_repr(bytes: FieldBytes) -> CtOption<Self> {
+ ScalarCore::from_be_bytes(bytes).map(Self)
+ }
+
+ fn to_repr(&self) -> FieldBytes {
+ self.0.to_be_bytes()
+ }
+
+ fn is_odd(&self) -> Choice {
+ self.0.is_odd()
+ }
+
+ fn multiplicative_generator() -> Self {
+ 7u64.into()
+ }
+
+ fn root_of_unity() -> Self {
+ Self::from_repr(arr![u8;
+ 0xff, 0xc9, 0x7f, 0x06, 0x2a, 0x77, 0x09, 0x92, 0xba, 0x80, 0x7a, 0xce, 0x84, 0x2a,
+ 0x3d, 0xfc, 0x15, 0x46, 0xca, 0xd0, 0x04, 0x37, 0x8d, 0xaf, 0x05, 0x92, 0xd7, 0xfb,
+ 0xb4, 0x1e, 0x66, 0x02,
+ ])
+ .unwrap()
+ }
+}
+
+#[cfg(feature = "bits")]
+impl PrimeFieldBits for Scalar {
+ #[cfg(target_pointer_width = "32")]
+ type ReprBits = [u32; 8];
+
+ #[cfg(target_pointer_width = "64")]
+ type ReprBits = [u64; 4];
+
+ fn to_le_bits(&self) -> ScalarBits {
+ self.0.as_uint().to_words().into()
+ }
+
+ fn char_le_bits() -> ScalarBits {
+ MockCurve::ORDER.to_words().into()
+ }
+}
+
+impl TryFrom<U256> for Scalar {
+ type Error = Error;
+
+ fn try_from(w: U256) -> Result<Self> {
+ Option::from(ScalarCore::new(w)).map(Self).ok_or(Error)
+ }
+}
+
+impl From<Scalar> for U256 {
+ fn from(scalar: Scalar) -> U256 {
+ *scalar.0.as_uint()
+ }
+}
+
+impl ConditionallySelectable for Scalar {
+ fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
+ Self(ScalarCore::conditional_select(&a.0, &b.0, choice))
+ }
+}
+
+impl ConstantTimeEq for Scalar {
+ fn ct_eq(&self, other: &Self) -> Choice {
+ self.0.ct_eq(&other.0)
+ }
+}
+
+impl DefaultIsZeroes for Scalar {}
+
+impl Add<Scalar> for Scalar {
+ type Output = Scalar;
+
+ fn add(self, other: Scalar) -> Scalar {
+ self.add(&other)
+ }
+}
+
+impl Add<&Scalar> for Scalar {
+ type Output = Scalar;
+
+ fn add(self, other: &Scalar) -> Scalar {
+ Self(self.0.add(&other.0))
+ }
+}
+
+impl AddAssign<Scalar> for Scalar {
+ fn add_assign(&mut self, other: Scalar) {
+ *self = *self + other;
+ }
+}
+
+impl AddAssign<&Scalar> for Scalar {
+ fn add_assign(&mut self, other: &Scalar) {
+ *self = *self + other;
+ }
+}
+
+impl Sub<Scalar> for Scalar {
+ type Output = Scalar;
+
+ fn sub(self, other: Scalar) -> Scalar {
+ self.sub(&other)
+ }
+}
+
+impl Sub<&Scalar> for Scalar {
+ type Output = Scalar;
+
+ fn sub(self, other: &Scalar) -> Scalar {
+ Self(self.0.sub(&other.0))
+ }
+}
+
+impl SubAssign<Scalar> for Scalar {
+ fn sub_assign(&mut self, other: Scalar) {
+ *self = *self - other;
+ }
+}
+
+impl SubAssign<&Scalar> for Scalar {
+ fn sub_assign(&mut self, other: &Scalar) {
+ *self = *self - other;
+ }
+}
+
+impl Mul<Scalar> for Scalar {
+ type Output = Scalar;
+
+ fn mul(self, _other: Scalar) -> Scalar {
+ unimplemented!();
+ }
+}
+
+impl Mul<&Scalar> for Scalar {
+ type Output = Scalar;
+
+ fn mul(self, _other: &Scalar) -> Scalar {
+ unimplemented!();
+ }
+}
+
+impl MulAssign<Scalar> for Scalar {
+ fn mul_assign(&mut self, _rhs: Scalar) {
+ unimplemented!();
+ }
+}
+
+impl MulAssign<&Scalar> for Scalar {
+ fn mul_assign(&mut self, _rhs: &Scalar) {
+ unimplemented!();
+ }
+}
+
+impl Neg for Scalar {
+ type Output = Scalar;
+
+ fn neg(self) -> Scalar {
+ Self(self.0.neg())
+ }
+}
+
+impl Reduce<U256> for Scalar {
+ fn from_uint_reduced(w: U256) -> Self {
+ let (r, underflow) = w.sbb(&MockCurve::ORDER, Limb::ZERO);
+ let underflow = Choice::from((underflow.0 >> (Limb::BIT_SIZE - 1)) as u8);
+ let reduced = U256::conditional_select(&w, &r, !underflow);
+ Self(ScalarCore::new(reduced).unwrap())
+ }
+}
+
+impl From<u64> for Scalar {
+ fn from(n: u64) -> Scalar {
+ Self(n.into())
+ }
+}
+
+impl From<ScalarCore> for Scalar {
+ fn from(scalar: ScalarCore) -> Scalar {
+ Self(scalar)
+ }
+}
+
+impl From<Scalar> for FieldBytes {
+ fn from(scalar: Scalar) -> Self {
+ Self::from(&scalar)
+ }
+}
+
+impl From<&Scalar> for FieldBytes {
+ fn from(scalar: &Scalar) -> Self {
+ scalar.to_repr()
+ }
+}
+
+impl IsHigh for Scalar {
+ fn is_high(&self) -> Choice {
+ self.0.is_high()
+ }
+}
+
+/// Example affine point type
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+pub enum AffinePoint {
+ /// Result of fixed-based scalar multiplication.
+ FixedBaseOutput(Scalar),
+
+ /// Identity.
+ Identity,
+
+ /// Base point.
+ Generator,
+
+ /// Point corresponding to a given [`EncodedPoint`].
+ Other(EncodedPoint),
+}
+
+impl AffineXCoordinate<MockCurve> for AffinePoint {
+ fn x(&self) -> FieldBytes {
+ unimplemented!();
+ }
+}
+
+impl ConstantTimeEq for AffinePoint {
+ fn ct_eq(&self, _other: &Self) -> Choice {
+ unimplemented!();
+ }
+}
+
+impl ConditionallySelectable for AffinePoint {
+ fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
+ // Not really constant time, but this is dev code
+ if choice.into() {
+ *b
+ } else {
+ *a
+ }
+ }
+}
+
+impl Default for AffinePoint {
+ fn default() -> Self {
+ Self::Identity
+ }
+}
+
+impl DefaultIsZeroes for AffinePoint {}
+
+impl FromEncodedPoint<MockCurve> for AffinePoint {
+ fn from_encoded_point(encoded_point: &EncodedPoint) -> CtOption<Self> {
+ let point = if encoded_point.is_identity() {
+ Self::Identity
+ } else {
+ Self::Other(*encoded_point)
+ };
+
+ CtOption::new(point, Choice::from(1))
+ }
+}
+
+impl ToEncodedPoint<MockCurve> for AffinePoint {
+ fn to_encoded_point(&self, compress: bool) -> EncodedPoint {
+ match self {
+ Self::FixedBaseOutput(scalar) => EncodedPoint::from_affine_coordinates(
+ &scalar.to_repr(),
+ &PSEUDO_COORDINATE_FIXED_BASE_MUL.into(),
+ false,
+ ),
+ Self::Other(point) => {
+ if compress == point.is_compressed() {
+ *point
+ } else {
+ unimplemented!();
+ }
+ }
+ _ => unimplemented!(),
+ }
+ }
+}
+
+impl Mul<NonZeroScalar> for AffinePoint {
+ type Output = AffinePoint;
+
+ fn mul(self, _scalar: NonZeroScalar) -> Self {
+ unimplemented!();
+ }
+}
+
+/// Example projective point type
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+pub enum ProjectivePoint {
+ /// Result of fixed-based scalar multiplication
+ FixedBaseOutput(Scalar),
+
+ /// Is this point the identity point?
+ Identity,
+
+ /// Is this point the generator point?
+ Generator,
+
+ /// Is this point a different point corresponding to a given [`AffinePoint`]
+ Other(AffinePoint),
+}
+
+impl ConstantTimeEq for ProjectivePoint {
+ fn ct_eq(&self, _other: &Self) -> Choice {
+ unimplemented!();
+ }
+}
+
+impl ConditionallySelectable for ProjectivePoint {
+ fn conditional_select(_a: &Self, _b: &Self, _choice: Choice) -> Self {
+ unimplemented!();
+ }
+}
+
+impl Default for ProjectivePoint {
+ fn default() -> Self {
+ Self::Identity
+ }
+}
+
+impl DefaultIsZeroes for ProjectivePoint {}
+
+impl From<AffinePoint> for ProjectivePoint {
+ fn from(point: AffinePoint) -> ProjectivePoint {
+ match point {
+ AffinePoint::FixedBaseOutput(scalar) => ProjectivePoint::FixedBaseOutput(scalar),
+ AffinePoint::Identity => ProjectivePoint::Identity,
+ AffinePoint::Generator => ProjectivePoint::Generator,
+ other => ProjectivePoint::Other(other),
+ }
+ }
+}
+
+impl From<ProjectivePoint> for AffinePoint {
+ fn from(point: ProjectivePoint) -> AffinePoint {
+ group::Curve::to_affine(&point)
+ }
+}
+
+impl FromEncodedPoint<MockCurve> for ProjectivePoint {
+ fn from_encoded_point(_point: &EncodedPoint) -> CtOption<Self> {
+ unimplemented!();
+ }
+}
+
+impl ToEncodedPoint<MockCurve> for ProjectivePoint {
+ fn to_encoded_point(&self, _compress: bool) -> EncodedPoint {
+ unimplemented!();
+ }
+}
+
+impl group::Group for ProjectivePoint {
+ type Scalar = Scalar;
+
+ fn random(_rng: impl RngCore) -> Self {
+ unimplemented!();
+ }
+
+ fn identity() -> Self {
+ Self::Identity
+ }
+
+ fn generator() -> Self {
+ Self::Generator
+ }
+
+ fn is_identity(&self) -> Choice {
+ Choice::from((self == &Self::Identity) as u8)
+ }
+
+ #[must_use]
+ fn double(&self) -> Self {
+ unimplemented!();
+ }
+}
+
+impl group::Curve for ProjectivePoint {
+ type AffineRepr = AffinePoint;
+
+ fn to_affine(&self) -> AffinePoint {
+ match self {
+ Self::FixedBaseOutput(scalar) => AffinePoint::FixedBaseOutput(*scalar),
+ Self::Other(affine) => *affine,
+ _ => unimplemented!(),
+ }
+ }
+}
+
+impl LinearCombination for ProjectivePoint {}
+
+impl Add<ProjectivePoint> for ProjectivePoint {
+ type Output = ProjectivePoint;
+
+ fn add(self, _other: ProjectivePoint) -> ProjectivePoint {
+ unimplemented!();
+ }
+}
+
+impl Add<&ProjectivePoint> for ProjectivePoint {
+ type Output = ProjectivePoint;
+
+ fn add(self, _other: &ProjectivePoint) -> ProjectivePoint {
+ unimplemented!();
+ }
+}
+
+impl AddAssign<ProjectivePoint> for ProjectivePoint {
+ fn add_assign(&mut self, _rhs: ProjectivePoint) {
+ unimplemented!();
+ }
+}
+
+impl AddAssign<&ProjectivePoint> for ProjectivePoint {
+ fn add_assign(&mut self, _rhs: &ProjectivePoint) {
+ unimplemented!();
+ }
+}
+
+impl Sub<ProjectivePoint> for ProjectivePoint {
+ type Output = ProjectivePoint;
+
+ fn sub(self, _other: ProjectivePoint) -> ProjectivePoint {
+ unimplemented!();
+ }
+}
+
+impl Sub<&ProjectivePoint> for ProjectivePoint {
+ type Output = ProjectivePoint;
+
+ fn sub(self, _other: &ProjectivePoint) -> ProjectivePoint {
+ unimplemented!();
+ }
+}
+
+impl SubAssign<ProjectivePoint> for ProjectivePoint {
+ fn sub_assign(&mut self, _rhs: ProjectivePoint) {
+ unimplemented!();
+ }
+}
+
+impl SubAssign<&ProjectivePoint> for ProjectivePoint {
+ fn sub_assign(&mut self, _rhs: &ProjectivePoint) {
+ unimplemented!();
+ }
+}
+
+impl Add<AffinePoint> for ProjectivePoint {
+ type Output = ProjectivePoint;
+
+ fn add(self, _other: AffinePoint) -> ProjectivePoint {
+ unimplemented!();
+ }
+}
+
+impl Add<&AffinePoint> for ProjectivePoint {
+ type Output = ProjectivePoint;
+
+ fn add(self, _other: &AffinePoint) -> ProjectivePoint {
+ unimplemented!();
+ }
+}
+
+impl AddAssign<AffinePoint> for ProjectivePoint {
+ fn add_assign(&mut self, _rhs: AffinePoint) {
+ unimplemented!();
+ }
+}
+
+impl AddAssign<&AffinePoint> for ProjectivePoint {
+ fn add_assign(&mut self, _rhs: &AffinePoint) {
+ unimplemented!();
+ }
+}
+
+impl Sum for ProjectivePoint {
+ fn sum<I: Iterator<Item = Self>>(_iter: I) -> Self {
+ unimplemented!();
+ }
+}
+
+impl<'a> Sum<&'a ProjectivePoint> for ProjectivePoint {
+ fn sum<I: Iterator<Item = &'a ProjectivePoint>>(_iter: I) -> Self {
+ unimplemented!();
+ }
+}
+
+impl Sub<AffinePoint> for ProjectivePoint {
+ type Output = ProjectivePoint;
+
+ fn sub(self, _other: AffinePoint) -> ProjectivePoint {
+ unimplemented!();
+ }
+}
+
+impl Sub<&AffinePoint> for ProjectivePoint {
+ type Output = ProjectivePoint;
+
+ fn sub(self, _other: &AffinePoint) -> ProjectivePoint {
+ unimplemented!();
+ }
+}
+
+impl SubAssign<AffinePoint> for ProjectivePoint {
+ fn sub_assign(&mut self, _rhs: AffinePoint) {
+ unimplemented!();
+ }
+}
+
+impl SubAssign<&AffinePoint> for ProjectivePoint {
+ fn sub_assign(&mut self, _rhs: &AffinePoint) {
+ unimplemented!();
+ }
+}
+
+impl Mul<Scalar> for ProjectivePoint {
+ type Output = ProjectivePoint;
+
+ fn mul(self, scalar: Scalar) -> ProjectivePoint {
+ match self {
+ Self::Generator => Self::FixedBaseOutput(scalar),
+ _ => unimplemented!(),
+ }
+ }
+}
+
+impl Mul<&Scalar> for ProjectivePoint {
+ type Output = ProjectivePoint;
+
+ fn mul(self, scalar: &Scalar) -> ProjectivePoint {
+ self * *scalar
+ }
+}
+
+impl MulAssign<Scalar> for ProjectivePoint {
+ fn mul_assign(&mut self, _rhs: Scalar) {
+ unimplemented!();
+ }
+}
+
+impl MulAssign<&Scalar> for ProjectivePoint {
+ fn mul_assign(&mut self, _rhs: &Scalar) {
+ unimplemented!();
+ }
+}
+
+impl Neg for ProjectivePoint {
+ type Output = ProjectivePoint;
+
+ fn neg(self) -> ProjectivePoint {
+ unimplemented!();
+ }
+}
+
+/// Constant representing the base field modulus
+/// p = 2^{224}(2^{32} − 1) + 2^{192} + 2^{96} − 1
+pub const MODULUS: U256 =
+ U256::from_be_hex("ffffffff00000001000000000000000000000000ffffffffffffffffffffffff");
+
+/// Example base field element.
+#[derive(Clone, Copy, Debug)]
+pub struct FieldElement(pub(crate) U256);
+
+/// Internal field element representation.
+#[cfg(target_pointer_width = "32")]
+type FeWords = [u32; 8];
+
+/// Internal field element representation.
+#[cfg(target_pointer_width = "64")]
+type FeWords = [u64; 4];
+
+impl_field_element!(
+ FieldElement,
+ FieldBytes,
+ U256,
+ MODULUS,
+ FeWords,
+ p256_from_montgomery,
+ p256_to_montgomery,
+ p256_add,
+ p256_sub,
+ p256_mul,
+ p256_opp,
+ p256_square
+);
+
+impl FieldElement {
+ /// Returns the multiplicative inverse of self, if self is non-zero.
+ pub fn invert(&self) -> CtOption<Self> {
+ unimplemented!()
+ }
+
+ /// Returns the square root of self mod p, or `None` if no square root exists.
+ pub fn sqrt(&self) -> CtOption<Self> {
+ unimplemented!()
+ }
+}
+
+const fn p256_from_montgomery(_: &FeWords) -> FeWords {
+ unimplemented!()
+}
+
+const fn p256_to_montgomery(w: &FeWords) -> FeWords {
+ *w
+}
+
+const fn p256_add(_: &FeWords, _: &FeWords) -> FeWords {
+ unimplemented!()
+}
+
+const fn p256_sub(_: &FeWords, _: &FeWords) -> FeWords {
+ unimplemented!()
+}
+
+const fn p256_mul(_: &FeWords, _: &FeWords) -> FeWords {
+ unimplemented!()
+}
+
+const fn p256_opp(_: &FeWords) -> FeWords {
+ unimplemented!()
+}
+
+const fn p256_square(_: &FeWords) -> FeWords {
+ unimplemented!()
+}
+
+#[cfg(test)]
+mod tests {
+ use super::Scalar;
+ use ff::PrimeField;
+ use hex_literal::hex;
+
+ #[test]
+ fn round_trip() {
+ let bytes = hex!("c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721");
+ let scalar = Scalar::from_repr(bytes.into()).unwrap();
+ assert_eq!(&bytes, scalar.to_repr().as_slice());
+ }
+}
diff --git a/vendor/elliptic-curve/src/ecdh.rs b/vendor/elliptic-curve/src/ecdh.rs
new file mode 100644
index 000000000..1e9f7bc31
--- /dev/null
+++ b/vendor/elliptic-curve/src/ecdh.rs
@@ -0,0 +1,236 @@
+//! Elliptic Curve Diffie-Hellman Support.
+//!
+//! This module contains a generic ECDH implementation which is usable with
+//! any elliptic curve which implements the [`ProjectiveArithmetic`] trait (presently
+//! the `k256` and `p256` crates)
+//!
+//! # ECDH Ephemeral (ECDHE) Usage
+//!
+//! Ephemeral Diffie-Hellman provides a one-time key exchange between two peers
+//! using a randomly generated set of keys for each exchange.
+//!
+//! In practice ECDHE is used as part of an [Authenticated Key Exchange (AKE)][AKE]
+//! protocol (e.g. [SIGMA]), where an existing cryptographic trust relationship
+//! can be used to determine the authenticity of the ephemeral keys, such as
+//! a digital signature. Without such an additional step, ECDHE is insecure!
+//! (see security warning below)
+//!
+//! See the documentation for the [`EphemeralSecret`] type for more information
+//! on performing ECDH ephemeral key exchanges.
+//!
+//! # Static ECDH Usage
+//!
+//! Static ECDH key exchanges are supported via the low-level
+//! [`diffie_hellman`] function.
+//!
+//! [AKE]: https://en.wikipedia.org/wiki/Authenticated_Key_Exchange
+//! [SIGMA]: https://webee.technion.ac.il/~hugo/sigma-pdf.pdf
+
+use crate::{
+ AffineArithmetic, AffinePoint, AffineXCoordinate, Curve, FieldBytes, NonZeroScalar,
+ ProjectiveArithmetic, ProjectivePoint, PublicKey,
+};
+use core::borrow::Borrow;
+use digest::{crypto_common::BlockSizeUser, Digest};
+use group::Curve as _;
+use hkdf::{hmac::SimpleHmac, Hkdf};
+use rand_core::{CryptoRng, RngCore};
+use zeroize::{Zeroize, ZeroizeOnDrop};
+
+/// Low-level Elliptic Curve Diffie-Hellman (ECDH) function.
+///
+/// Whenever possible, we recommend using the high-level ECDH ephemeral API
+/// provided by [`EphemeralSecret`].
+///
+/// However, if you are implementing a protocol which requires a static scalar
+/// value as part of an ECDH exchange, this API can be used to compute a
+/// [`SharedSecret`] from that value.
+///
+/// Note that this API operates on the low-level [`NonZeroScalar`] and
+/// [`AffinePoint`] types. If you are attempting to use the higher-level
+/// [`SecretKey`][`crate::SecretKey`] and [`PublicKey`] types, you will
+/// need to use the following conversions:
+///
+/// ```ignore
+/// let shared_secret = elliptic_curve::ecdh::diffie_hellman(
+/// secret_key.to_nonzero_scalar(),
+/// public_key.as_affine()
+/// );
+/// ```
+pub fn diffie_hellman<C>(
+ secret_key: impl Borrow<NonZeroScalar<C>>,
+ public_key: impl Borrow<AffinePoint<C>>,
+) -> SharedSecret<C>
+where
+ C: Curve + ProjectiveArithmetic,
+{
+ let public_point = ProjectivePoint::<C>::from(*public_key.borrow());
+ let secret_point = (public_point * secret_key.borrow().as_ref()).to_affine();
+ SharedSecret::new(secret_point)
+}
+
+/// Ephemeral Diffie-Hellman Secret.
+///
+/// These are ephemeral "secret key" values which are deliberately designed
+/// to avoid being persisted.
+///
+/// To perform an ephemeral Diffie-Hellman exchange, do the following:
+///
+/// - Have each participant generate an [`EphemeralSecret`] value
+/// - Compute the [`PublicKey`] for that value
+/// - Have each peer provide their [`PublicKey`] to their counterpart
+/// - Use [`EphemeralSecret`] and the other participant's [`PublicKey`]
+/// to compute a [`SharedSecret`] value.
+///
+/// # ⚠️ SECURITY WARNING ⚠️
+///
+/// Ephemeral Diffie-Hellman exchanges are unauthenticated and without a
+/// further authentication step are trivially vulnerable to man-in-the-middle
+/// attacks!
+///
+/// These exchanges should be performed in the context of a protocol which
+/// takes further steps to authenticate the peers in a key exchange.
+pub struct EphemeralSecret<C>
+where
+ C: Curve + ProjectiveArithmetic,
+{
+ scalar: NonZeroScalar<C>,
+}
+
+impl<C> EphemeralSecret<C>
+where
+ C: Curve + ProjectiveArithmetic,
+{
+ /// Generate a cryptographically random [`EphemeralSecret`].
+ pub fn random(rng: impl CryptoRng + RngCore) -> Self {
+ Self {
+ scalar: NonZeroScalar::random(rng),
+ }
+ }
+
+ /// Get the public key associated with this ephemeral secret.
+ ///
+ /// The `compress` flag enables point compression.
+ pub fn public_key(&self) -> PublicKey<C> {
+ PublicKey::from_secret_scalar(&self.scalar)
+ }
+
+ /// Compute a Diffie-Hellman shared secret from an ephemeral secret and the
+ /// public key of the other participant in the exchange.
+ pub fn diffie_hellman(&self, public_key: &PublicKey<C>) -> SharedSecret<C> {
+ diffie_hellman(&self.scalar, public_key.as_affine())
+ }
+}
+
+impl<C> From<&EphemeralSecret<C>> for PublicKey<C>
+where
+ C: Curve + ProjectiveArithmetic,
+{
+ fn from(ephemeral_secret: &EphemeralSecret<C>) -> Self {
+ ephemeral_secret.public_key()
+ }
+}
+
+impl<C> Zeroize for EphemeralSecret<C>
+where
+ C: Curve + ProjectiveArithmetic,
+{
+ fn zeroize(&mut self) {
+ self.scalar.zeroize()
+ }
+}
+
+impl<C> ZeroizeOnDrop for EphemeralSecret<C> where C: Curve + ProjectiveArithmetic {}
+
+impl<C> Drop for EphemeralSecret<C>
+where
+ C: Curve + ProjectiveArithmetic,
+{
+ fn drop(&mut self) {
+ self.zeroize();
+ }
+}
+
+/// Shared secret value computed via ECDH key agreement.
+pub struct SharedSecret<C: Curve> {
+ /// Computed secret value
+ secret_bytes: FieldBytes<C>,
+}
+
+impl<C: Curve> SharedSecret<C> {
+ /// Create a new [`SharedSecret`] from an [`AffinePoint`] for this curve.
+ #[inline]
+ fn new(point: AffinePoint<C>) -> Self
+ where
+ C: AffineArithmetic,
+ {
+ Self {
+ secret_bytes: point.x(),
+ }
+ }
+
+ /// Use [HKDF] (HMAC-based Extract-and-Expand Key Derivation Function) to
+ /// extract entropy from this shared secret.
+ ///
+ /// This method can be used to transform the shared secret into uniformly
+ /// random values which are suitable as key material.
+ ///
+ /// The `D` type parameter is a cryptographic digest function.
+ /// `sha2::Sha256` is a common choice for use with HKDF.
+ ///
+ /// The `salt` parameter can be used to supply additional randomness.
+ /// Some examples include:
+ ///
+ /// - randomly generated (but authenticated) string
+ /// - fixed application-specific value
+ /// - previous shared secret used for rekeying (as in TLS 1.3 and Noise)
+ ///
+ /// After initializing HKDF, use [`Hkdf::expand`] to obtain output key
+ /// material.
+ ///
+ /// [HKDF]: https://en.wikipedia.org/wiki/HKDF
+ pub fn extract<D>(&self, salt: Option<&[u8]>) -> Hkdf<D, SimpleHmac<D>>
+ where
+ D: BlockSizeUser + Clone + Digest,
+ {
+ Hkdf::new(salt, &self.secret_bytes)
+ }
+
+ /// This value contains the raw serialized x-coordinate of the elliptic curve
+ /// point computed from a Diffie-Hellman exchange, serialized as bytes.
+ ///
+ /// When in doubt, use [`SharedSecret::extract`] instead.
+ ///
+ /// # ⚠️ WARNING: NOT UNIFORMLY RANDOM! ⚠️
+ ///
+ /// This value is not uniformly random and should not be used directly
+ /// as a cryptographic key for anything which requires that property
+ /// (e.g. symmetric ciphers).
+ ///
+ /// Instead, the resulting value should be used as input to a Key Derivation
+ /// Function (KDF) or cryptographic hash function to produce a symmetric key.
+ /// The [`SharedSecret::extract`] function will do this for you.
+ pub fn raw_secret_bytes(&self) -> &FieldBytes<C> {
+ &self.secret_bytes
+ }
+}
+
+impl<C: Curve> From<FieldBytes<C>> for SharedSecret<C> {
+ /// NOTE: this impl is intended to be used by curve implementations to
+ /// instantiate a [`SharedSecret`] value from their respective
+ /// [`AffinePoint`] type.
+ ///
+ /// Curve implementations should provide the field element representing
+ /// the affine x-coordinate as `secret_bytes`.
+ fn from(secret_bytes: FieldBytes<C>) -> Self {
+ Self { secret_bytes }
+ }
+}
+
+impl<C: Curve> ZeroizeOnDrop for SharedSecret<C> {}
+
+impl<C: Curve> Drop for SharedSecret<C> {
+ fn drop(&mut self) {
+ self.secret_bytes.zeroize()
+ }
+}
diff --git a/vendor/elliptic-curve/src/error.rs b/vendor/elliptic-curve/src/error.rs
new file mode 100644
index 000000000..53f5b1773
--- /dev/null
+++ b/vendor/elliptic-curve/src/error.rs
@@ -0,0 +1,42 @@
+//! Error type.
+
+use core::fmt::{self, Display};
+
+#[cfg(feature = "pkcs8")]
+use crate::pkcs8;
+
+/// Result type with the `elliptic-curve` crate's [`Error`] type.
+pub type Result<T> = core::result::Result<T, Error>;
+
+/// Elliptic curve errors.
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+pub struct Error;
+
+impl Display for Error {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.write_str("crypto error")
+ }
+}
+
+impl From<base16ct::Error> for Error {
+ fn from(_: base16ct::Error) -> Error {
+ Error
+ }
+}
+
+#[cfg(feature = "pkcs8")]
+impl From<pkcs8::Error> for Error {
+ fn from(_: pkcs8::Error) -> Error {
+ Error
+ }
+}
+
+#[cfg(feature = "sec1")]
+impl From<sec1::Error> for Error {
+ fn from(_: sec1::Error) -> Error {
+ Error
+ }
+}
+
+#[cfg(feature = "std")]
+impl std::error::Error for Error {}
diff --git a/vendor/elliptic-curve/src/hash2curve.rs b/vendor/elliptic-curve/src/hash2curve.rs
new file mode 100644
index 000000000..3df394f79
--- /dev/null
+++ b/vendor/elliptic-curve/src/hash2curve.rs
@@ -0,0 +1,15 @@
+//! Traits for hashing byte sequences to curve points.
+//!
+//! <https://datatracker.ietf.org/doc/draft-irtf-cfrg-hash-to-curve>
+
+mod group_digest;
+mod hash2field;
+mod isogeny;
+mod map2curve;
+mod osswu;
+
+pub use group_digest::*;
+pub use hash2field::*;
+pub use isogeny::*;
+pub use map2curve::*;
+pub use osswu::*;
diff --git a/vendor/elliptic-curve/src/hash2curve/group_digest.rs b/vendor/elliptic-curve/src/hash2curve/group_digest.rs
new file mode 100644
index 000000000..dbcb1512b
--- /dev/null
+++ b/vendor/elliptic-curve/src/hash2curve/group_digest.rs
@@ -0,0 +1,120 @@
+//! Traits for handling hash to curve.
+
+use super::{hash_to_field, ExpandMsg, FromOkm, MapToCurve};
+use crate::{ProjectiveArithmetic, ProjectivePoint, Result};
+use group::cofactor::CofactorGroup;
+
+/// Adds hashing arbitrary byte sequences to a valid group element
+pub trait GroupDigest: ProjectiveArithmetic
+where
+ ProjectivePoint<Self>: CofactorGroup,
+{
+ /// The field element representation for a group value with multiple elements
+ type FieldElement: FromOkm + MapToCurve<Output = ProjectivePoint<Self>> + Default + Copy;
+
+ /// Computes the hash to curve routine.
+ ///
+ /// From <https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-13.html>:
+ ///
+ /// > Uniform encoding from byte strings to points in G.
+ /// > That is, the distribution of its output is statistically close
+ /// > to uniform in G.
+ /// > This function is suitable for most applications requiring a random
+ /// > oracle returning points in G assuming a cryptographically secure
+ /// > hash function is used.
+ ///
+ /// # Examples
+ ///
+ /// ## Using a fixed size hash function
+ ///
+ /// ```ignore
+ /// let pt = ProjectivePoint::hash_from_bytes::<ExpandMsgXmd<sha2::Sha256>>(b"test data", b"CURVE_XMD:SHA-256_SSWU_RO_");
+ /// ```
+ ///
+ /// ## Using an extendable output function
+ ///
+ /// ```ignore
+ /// let pt = ProjectivePoint::hash_from_bytes::<ExpandMsgXof<sha3::Shake256>>(b"test data", b"CURVE_XOF:SHAKE-256_SSWU_RO_");
+ /// ```
+ ///
+ /// # Errors
+ /// See implementors of [`ExpandMsg`] for errors:
+ /// - [`ExpandMsgXmd`]
+ /// - [`ExpandMsgXof`]
+ ///
+ /// `len_in_bytes = <Self::FieldElement as FromOkm>::Length * 2`
+ ///
+ /// [`ExpandMsgXmd`]: crate::hash2curve::ExpandMsgXmd
+ /// [`ExpandMsgXof`]: crate::hash2curve::ExpandMsgXof
+ fn hash_from_bytes<'a, X: ExpandMsg<'a>>(
+ msgs: &[&[u8]],
+ dst: &'a [u8],
+ ) -> Result<ProjectivePoint<Self>> {
+ let mut u = [Self::FieldElement::default(), Self::FieldElement::default()];
+ hash_to_field::<X, _>(msgs, dst, &mut u)?;
+ let q0 = u[0].map_to_curve();
+ let q1 = u[1].map_to_curve();
+ // Ideally we could add and then clear cofactor once
+ // thus saving a call but the field elements may not
+ // add properly due to the underlying implementation
+ // which could result in an incorrect subgroup.
+ // This is caused curve coefficients being different than
+ // what is usually implemented.
+ // FieldElement expects the `a` and `b` to be the original values
+ // isogenies are different with curves like k256 and bls12-381.
+ // This problem doesn't manifest for curves with no isogeny like p256.
+ // For k256 and p256 clear_cofactor doesn't do anything anyway so it will be a no-op.
+ Ok(q0.clear_cofactor().into() + q1.clear_cofactor())
+ }
+
+ /// Computes the encode to curve routine.
+ ///
+ /// From <https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-13.html>:
+ ///
+ /// > Nonuniform encoding from byte strings to
+ /// > points in G. That is, the distribution of its output is not
+ /// > uniformly random in G: the set of possible outputs of
+ /// > encode_to_curve is only a fraction of the points in G, and some
+ /// > points in this set are more likely to be output than others.
+ ///
+ /// # Errors
+ /// See implementors of [`ExpandMsg`] for errors:
+ /// - [`ExpandMsgXmd`]
+ /// - [`ExpandMsgXof`]
+ ///
+ /// `len_in_bytes = <Self::FieldElement as FromOkm>::Length`
+ ///
+ /// [`ExpandMsgXmd`]: crate::hash2curve::ExpandMsgXmd
+ /// [`ExpandMsgXof`]: crate::hash2curve::ExpandMsgXof
+ fn encode_from_bytes<'a, X: ExpandMsg<'a>>(
+ msgs: &[&[u8]],
+ dst: &'a [u8],
+ ) -> Result<ProjectivePoint<Self>> {
+ let mut u = [Self::FieldElement::default()];
+ hash_to_field::<X, _>(msgs, dst, &mut u)?;
+ let q0 = u[0].map_to_curve();
+ Ok(q0.clear_cofactor().into())
+ }
+
+ /// Computes the hash to field routine according to
+ /// <https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-13.html#section-5>
+ /// and returns a scalar.
+ ///
+ /// # Errors
+ /// See implementors of [`ExpandMsg`] for errors:
+ /// - [`ExpandMsgXmd`]
+ /// - [`ExpandMsgXof`]
+ ///
+ /// `len_in_bytes = <Self::Scalar as FromOkm>::Length`
+ ///
+ /// [`ExpandMsgXmd`]: crate::hash2curve::ExpandMsgXmd
+ /// [`ExpandMsgXof`]: crate::hash2curve::ExpandMsgXof
+ fn hash_to_scalar<'a, X: ExpandMsg<'a>>(msgs: &[&[u8]], dst: &'a [u8]) -> Result<Self::Scalar>
+ where
+ Self::Scalar: FromOkm,
+ {
+ let mut u = [Self::Scalar::default()];
+ hash_to_field::<X, _>(msgs, dst, &mut u)?;
+ Ok(u[0])
+ }
+}
diff --git a/vendor/elliptic-curve/src/hash2curve/hash2field.rs b/vendor/elliptic-curve/src/hash2curve/hash2field.rs
new file mode 100644
index 000000000..6cd0723aa
--- /dev/null
+++ b/vendor/elliptic-curve/src/hash2curve/hash2field.rs
@@ -0,0 +1,48 @@
+//! Traits for hashing to field elements.
+//!
+//! <https://datatracker.ietf.org/doc/draft-irtf-cfrg-hash-to-curve>
+
+mod expand_msg;
+
+pub use expand_msg::{xmd::*, xof::*, *};
+
+use crate::Result;
+use generic_array::{typenum::Unsigned, ArrayLength, GenericArray};
+
+/// The trait for helping to convert to a field element.
+pub trait FromOkm {
+ /// The number of bytes needed to convert to a field element.
+ type Length: ArrayLength<u8>;
+
+ /// Convert a byte sequence into a field element.
+ fn from_okm(data: &GenericArray<u8, Self::Length>) -> Self;
+}
+
+/// Convert an arbitrary byte sequence into a field element.
+///
+/// <https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-11#section-5.3>
+///
+/// # Errors
+/// See implementors of [`ExpandMsg`] for errors:
+/// - [`ExpandMsgXmd`]
+/// - [`ExpandMsgXof`]
+///
+/// `len_in_bytes = T::Length * out.len()`
+///
+/// [`ExpandMsgXmd`]: crate::hash2field::ExpandMsgXmd
+/// [`ExpandMsgXof`]: crate::hash2field::ExpandMsgXof
+#[doc(hidden)]
+pub fn hash_to_field<'a, E, T>(data: &[&[u8]], domain: &'a [u8], out: &mut [T]) -> Result<()>
+where
+ E: ExpandMsg<'a>,
+ T: FromOkm + Default,
+{
+ let len_in_bytes = T::Length::to_usize() * out.len();
+ let mut tmp = GenericArray::<u8, <T as FromOkm>::Length>::default();
+ let mut expander = E::expand_message(data, domain, len_in_bytes)?;
+ for o in out.iter_mut() {
+ expander.fill_bytes(&mut tmp);
+ *o = T::from_okm(&tmp);
+ }
+ Ok(())
+}
diff --git a/vendor/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs b/vendor/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs
new file mode 100644
index 000000000..dfb3bab9c
--- /dev/null
+++ b/vendor/elliptic-curve/src/hash2curve/hash2field/expand_msg.rs
@@ -0,0 +1,115 @@
+//! `expand_message` interface `for hash_to_field`.
+
+pub(super) mod xmd;
+pub(super) mod xof;
+
+use crate::{Error, Result};
+use digest::{Digest, ExtendableOutput, Update, XofReader};
+use generic_array::typenum::{IsLess, U256};
+use generic_array::{ArrayLength, GenericArray};
+
+/// Salt when the DST is too long
+const OVERSIZE_DST_SALT: &[u8] = b"H2C-OVERSIZE-DST-";
+/// Maximum domain separation tag length
+const MAX_DST_LEN: usize = 255;
+
+/// Trait for types implementing expand_message interface for `hash_to_field`.
+///
+/// # Errors
+/// See implementors of [`ExpandMsg`] for errors.
+pub trait ExpandMsg<'a> {
+ /// Type holding data for the [`Expander`].
+ type Expander: Expander + Sized;
+
+ /// Expands `msg` to the required number of bytes.
+ ///
+ /// Returns an expander that can be used to call `read` until enough
+ /// bytes have been consumed
+ fn expand_message(msgs: &[&[u8]], dst: &'a [u8], len_in_bytes: usize)
+ -> Result<Self::Expander>;
+}
+
+/// Expander that, call `read` until enough bytes have been consumed.
+pub trait Expander {
+ /// Fill the array with the expanded bytes
+ fn fill_bytes(&mut self, okm: &mut [u8]);
+}
+
+/// The domain separation tag
+///
+/// Implements [section 5.4.3 of `draft-irtf-cfrg-hash-to-curve-13`][dst].
+///
+/// [dst]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-13#section-5.4.3
+pub(crate) enum Domain<'a, L>
+where
+ L: ArrayLength<u8> + IsLess<U256>,
+{
+ /// > 255
+ Hashed(GenericArray<u8, L>),
+ /// <= 255
+ Array(&'a [u8]),
+}
+
+impl<'a, L> Domain<'a, L>
+where
+ L: ArrayLength<u8> + IsLess<U256>,
+{
+ pub fn xof<X>(dst: &'a [u8]) -> Result<Self>
+ where
+ X: Default + ExtendableOutput + Update,
+ {
+ if dst.is_empty() {
+ Err(Error)
+ } else if dst.len() > MAX_DST_LEN {
+ let mut data = GenericArray::<u8, L>::default();
+ X::default()
+ .chain(OVERSIZE_DST_SALT)
+ .chain(dst)
+ .finalize_xof()
+ .read(&mut data);
+ Ok(Self::Hashed(data))
+ } else {
+ Ok(Self::Array(dst))
+ }
+ }
+
+ pub fn xmd<X>(dst: &'a [u8]) -> Result<Self>
+ where
+ X: Digest<OutputSize = L>,
+ {
+ if dst.is_empty() {
+ Err(Error)
+ } else if dst.len() > MAX_DST_LEN {
+ Ok(Self::Hashed({
+ let mut hash = X::new();
+ hash.update(OVERSIZE_DST_SALT);
+ hash.update(dst);
+ hash.finalize()
+ }))
+ } else {
+ Ok(Self::Array(dst))
+ }
+ }
+
+ pub fn data(&self) -> &[u8] {
+ match self {
+ Self::Hashed(d) => &d[..],
+ Self::Array(d) => *d,
+ }
+ }
+
+ pub fn len(&self) -> u8 {
+ match self {
+ // Can't overflow because it's enforced on a type level.
+ Self::Hashed(_) => L::to_u8(),
+ // Can't overflow because it's checked on creation.
+ Self::Array(d) => u8::try_from(d.len()).expect("length overflow"),
+ }
+ }
+
+ #[cfg(test)]
+ pub fn assert(&self, bytes: &[u8]) {
+ assert_eq!(self.data(), &bytes[..bytes.len() - 1]);
+ assert_eq!(self.len(), bytes[bytes.len() - 1]);
+ }
+}
diff --git a/vendor/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs b/vendor/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs
new file mode 100644
index 000000000..876b012f5
--- /dev/null
+++ b/vendor/elliptic-curve/src/hash2curve/hash2field/expand_msg/xmd.rs
@@ -0,0 +1,449 @@
+//! `expand_message_xmd` based on a hash function.
+
+use core::marker::PhantomData;
+
+use super::{Domain, ExpandMsg, Expander};
+use crate::{Error, Result};
+use digest::{
+ core_api::BlockSizeUser,
+ generic_array::{
+ typenum::{IsLess, IsLessOrEqual, Unsigned, U256},
+ GenericArray,
+ },
+ Digest,
+};
+
+/// Placeholder type for implementing `expand_message_xmd` based on a hash function
+///
+/// # Errors
+/// - `dst.is_empty()`
+/// - `len_in_bytes == 0`
+/// - `len_in_bytes > u16::MAX`
+/// - `len_in_bytes > 255 * HashT::OutputSize`
+pub struct ExpandMsgXmd<HashT>(PhantomData<HashT>)
+where
+ HashT: Digest + BlockSizeUser,
+ HashT::OutputSize: IsLess<U256>,
+ HashT::OutputSize: IsLessOrEqual<HashT::BlockSize>;
+
+/// ExpandMsgXmd implements expand_message_xmd for the ExpandMsg trait
+impl<'a, HashT> ExpandMsg<'a> for ExpandMsgXmd<HashT>
+where
+ HashT: Digest + BlockSizeUser,
+ // If `len_in_bytes` is bigger then 256, length of the `DST` will depend on
+ // the output size of the hash, which is still not allowed to be bigger then 256:
+ // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-13.html#section-5.4.1-6
+ HashT::OutputSize: IsLess<U256>,
+ // Constraint set by `expand_message_xmd`:
+ // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-13.html#section-5.4.1-4
+ HashT::OutputSize: IsLessOrEqual<HashT::BlockSize>,
+{
+ type Expander = ExpanderXmd<'a, HashT>;
+
+ fn expand_message(
+ msgs: &[&[u8]],
+ dst: &'a [u8],
+ len_in_bytes: usize,
+ ) -> Result<Self::Expander> {
+ if len_in_bytes == 0 {
+ return Err(Error);
+ }
+
+ let len_in_bytes_u16 = u16::try_from(len_in_bytes).map_err(|_| Error)?;
+
+ let b_in_bytes = HashT::OutputSize::to_usize();
+ let ell = u8::try_from((len_in_bytes + b_in_bytes - 1) / b_in_bytes).map_err(|_| Error)?;
+
+ let domain = Domain::xmd::<HashT>(dst)?;
+ let mut b_0 = HashT::new();
+ b_0.update(GenericArray::<u8, HashT::BlockSize>::default());
+
+ for msg in msgs {
+ b_0.update(msg);
+ }
+
+ b_0.update(len_in_bytes_u16.to_be_bytes());
+ b_0.update([0]);
+ b_0.update(domain.data());
+ b_0.update([domain.len()]);
+ let b_0 = b_0.finalize();
+
+ let mut b_vals = HashT::new();
+ b_vals.update(&b_0[..]);
+ b_vals.update([1u8]);
+ b_vals.update(domain.data());
+ b_vals.update([domain.len()]);
+ let b_vals = b_vals.finalize();
+
+ Ok(ExpanderXmd {
+ b_0,
+ b_vals,
+ domain,
+ index: 1,
+ offset: 0,
+ ell,
+ })
+ }
+}
+
+/// [`Expander`] type for [`ExpandMsgXmd`].
+pub struct ExpanderXmd<'a, HashT>
+where
+ HashT: Digest + BlockSizeUser,
+ HashT::OutputSize: IsLess<U256>,
+ HashT::OutputSize: IsLessOrEqual<HashT::BlockSize>,
+{
+ b_0: GenericArray<u8, HashT::OutputSize>,
+ b_vals: GenericArray<u8, HashT::OutputSize>,
+ domain: Domain<'a, HashT::OutputSize>,
+ index: u8,
+ offset: usize,
+ ell: u8,
+}
+
+impl<'a, HashT> ExpanderXmd<'a, HashT>
+where
+ HashT: Digest + BlockSizeUser,
+ HashT::OutputSize: IsLess<U256>,
+ HashT::OutputSize: IsLessOrEqual<HashT::BlockSize>,
+{
+ fn next(&mut self) -> bool {
+ if self.index < self.ell {
+ self.index += 1;
+ self.offset = 0;
+ // b_0 XOR b_(idx - 1)
+ let mut tmp = GenericArray::<u8, HashT::OutputSize>::default();
+ self.b_0
+ .iter()
+ .zip(&self.b_vals[..])
+ .enumerate()
+ .for_each(|(j, (b0val, bi1val))| tmp[j] = b0val ^ bi1val);
+ let mut b_vals = HashT::new();
+ b_vals.update(tmp);
+ b_vals.update([self.index]);
+ b_vals.update(self.domain.data());
+ b_vals.update([self.domain.len()]);
+ self.b_vals = b_vals.finalize();
+ true
+ } else {
+ false
+ }
+ }
+}
+
+impl<'a, HashT> Expander for ExpanderXmd<'a, HashT>
+where
+ HashT: Digest + BlockSizeUser,
+ HashT::OutputSize: IsLess<U256>,
+ HashT::OutputSize: IsLessOrEqual<HashT::BlockSize>,
+{
+ fn fill_bytes(&mut self, okm: &mut [u8]) {
+ for b in okm {
+ if self.offset == self.b_vals.len() && !self.next() {
+ return;
+ }
+ *b = self.b_vals[self.offset];
+ self.offset += 1;
+ }
+ }
+}
+
+#[cfg(test)]
+mod test {
+ use super::*;
+ use core::mem;
+ use generic_array::{
+ typenum::{U128, U32},
+ ArrayLength,
+ };
+ use hex_literal::hex;
+ use sha2::Sha256;
+
+ fn assert_message<HashT>(
+ msg: &[u8],
+ domain: &Domain<'_, HashT::OutputSize>,
+ len_in_bytes: u16,
+ bytes: &[u8],
+ ) where
+ HashT: Digest + BlockSizeUser,
+ HashT::OutputSize: IsLess<U256>,
+ {
+ let block = HashT::BlockSize::to_usize();
+ assert_eq!(
+ GenericArray::<u8, HashT::BlockSize>::default().as_slice(),
+ &bytes[..block]
+ );
+
+ let msg_len = block + msg.len();
+ assert_eq!(msg, &bytes[block..msg_len]);
+
+ let l = msg_len + mem::size_of::<u16>();
+ assert_eq!(len_in_bytes.to_be_bytes(), &bytes[msg_len..l]);
+
+ let pad = l + mem::size_of::<u8>();
+ assert_eq!([0], &bytes[l..pad]);
+
+ let dst = pad + domain.data().len();
+ assert_eq!(domain.data(), &bytes[pad..dst]);
+
+ let dst_len = dst + mem::size_of::<u8>();
+ assert_eq!([domain.len()], &bytes[dst..dst_len]);
+
+ assert_eq!(dst_len, bytes.len());
+ }
+
+ struct TestVector {
+ msg: &'static [u8],
+ msg_prime: &'static [u8],
+ uniform_bytes: &'static [u8],
+ }
+
+ impl TestVector {
+ fn assert<HashT, L: ArrayLength<u8>>(
+ &self,
+ dst: &'static [u8],
+ domain: &Domain<'_, HashT::OutputSize>,
+ ) -> Result<()>
+ where
+ HashT: Digest + BlockSizeUser,
+ HashT::OutputSize: IsLess<U256> + IsLessOrEqual<HashT::BlockSize>,
+ {
+ assert_message::<HashT>(self.msg, domain, L::to_u16(), self.msg_prime);
+
+ let mut expander =
+ ExpandMsgXmd::<HashT>::expand_message(&[self.msg], dst, L::to_usize())?;
+
+ let mut uniform_bytes = GenericArray::<u8, L>::default();
+ expander.fill_bytes(&mut uniform_bytes);
+
+ assert_eq!(uniform_bytes.as_slice(), self.uniform_bytes);
+ Ok(())
+ }
+ }
+
+ #[test]
+ fn expand_message_xmd_sha_256() -> Result<()> {
+ const DST: &[u8] = b"QUUX-V01-CS02-with-expander-SHA256-128";
+ const DST_PRIME: &[u8] =
+ &hex!("515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826");
+
+ let dst_prime = Domain::xmd::<Sha256>(DST)?;
+ dst_prime.assert(DST_PRIME);
+
+ const TEST_VECTORS_32: &[TestVector] = &[
+ TestVector {
+ msg: b"",
+ msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826"),
+ uniform_bytes: &hex!("68a985b87eb6b46952128911f2a4412bbc302a9d759667f87f7a21d803f07235"),
+ },
+ TestVector {
+ msg: b"abc",
+ msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000616263002000515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826"),
+ uniform_bytes: &hex!("d8ccab23b5985ccea865c6c97b6e5b8350e794e603b4b97902f53a8a0d605615"),
+ },
+ TestVector {
+ msg: b"abcdef0123456789",
+ msg_prime: &hex!("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000061626364656630313233343536373839002000515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826"),
+ uniform_bytes: &hex!("eff31487c770a893cfb36f912fbfcbff40d5661771ca4b2cb4eafe524333f5c1"),
+ },
+ TestVector {
+ msg: b"q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
+ msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000713132385f7171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171002000515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826"),
+ uniform_bytes: &hex!("b23a1d2b4d97b2ef7785562a7e8bac7eed54ed6e97e29aa51bfe3f12ddad1ff9"),
+ },
+ TestVector {
+ msg: b"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000613531325f6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161002000515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826"),
+ uniform_bytes: &hex!("4623227bcc01293b8c130bf771da8c298dede7383243dc0993d2d94823958c4c"),
+ },
+ ];
+
+ for test_vector in TEST_VECTORS_32 {
+ test_vector.assert::<Sha256, U32>(DST, &dst_prime)?;
+ }
+
+ const TEST_VECTORS_128: &[TestVector] = &[
+ TestVector {
+ msg: b"",
+ msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826"),
+ uniform_bytes: &hex!("af84c27ccfd45d41914fdff5df25293e221afc53d8ad2ac06d5e3e29485dadbee0d121587713a3e0dd4d5e69e93eb7cd4f5df4cd103e188cf60cb02edc3edf18eda8576c412b18ffb658e3dd6ec849469b979d444cf7b26911a08e63cf31f9dcc541708d3491184472c2c29bb749d4286b004ceb5ee6b9a7fa5b646c993f0ced"),
+ }, TestVector {
+ msg: b"abc",
+ msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000616263008000515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826"),
+ uniform_bytes: &hex!("abba86a6129e366fc877aab32fc4ffc70120d8996c88aee2fe4b32d6c7b6437a647e6c3163d40b76a73cf6a5674ef1d890f95b664ee0afa5359a5c4e07985635bbecbac65d747d3d2da7ec2b8221b17b0ca9dc8a1ac1c07ea6a1e60583e2cb00058e77b7b72a298425cd1b941ad4ec65e8afc50303a22c0f99b0509b4c895f40"),
+ }, TestVector {
+ msg: b"abcdef0123456789",
+ msg_prime: &hex!("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000061626364656630313233343536373839008000515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826"),
+ uniform_bytes: &hex!("ef904a29bffc4cf9ee82832451c946ac3c8f8058ae97d8d629831a74c6572bd9ebd0df635cd1f208e2038e760c4994984ce73f0d55ea9f22af83ba4734569d4bc95e18350f740c07eef653cbb9f87910d833751825f0ebefa1abe5420bb52be14cf489b37fe1a72f7de2d10be453b2c9d9eb20c7e3f6edc5a60629178d9478df"),
+ }, TestVector {
+ msg: b"q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
+ msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000713132385f7171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171008000515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826"),
+ uniform_bytes: &hex!("80be107d0884f0d881bb460322f0443d38bd222db8bd0b0a5312a6fedb49c1bbd88fd75d8b9a09486c60123dfa1d73c1cc3169761b17476d3c6b7cbbd727acd0e2c942f4dd96ae3da5de368d26b32286e32de7e5a8cb2949f866a0b80c58116b29fa7fabb3ea7d520ee603e0c25bcaf0b9a5e92ec6a1fe4e0391d1cdbce8c68a"),
+ }, TestVector {
+ msg: b"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000613531325f6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161008000515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826"),
+ uniform_bytes: &hex!("546aff5444b5b79aa6148bd81728704c32decb73a3ba76e9e75885cad9def1d06d6792f8a7d12794e90efed817d96920d728896a4510864370c207f99bd4a608ea121700ef01ed879745ee3e4ceef777eda6d9e5e38b90c86ea6fb0b36504ba4a45d22e86f6db5dd43d98a294bebb9125d5b794e9d2a81181066eb954966a487"),
+ },
+ ];
+
+ for test_vector in TEST_VECTORS_128 {
+ test_vector.assert::<Sha256, U128>(DST, &dst_prime)?;
+ }
+
+ Ok(())
+ }
+
+ #[test]
+ fn expand_message_xmd_sha_256_long() -> Result<()> {
+ const DST: &[u8] = b"QUUX-V01-CS02-with-expander-SHA256-128-long-DST-1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111";
+ const DST_PRIME: &[u8] =
+ &hex!("412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620");
+
+ let dst_prime = Domain::xmd::<Sha256>(DST)?;
+ dst_prime.assert(DST_PRIME);
+
+ const TEST_VECTORS_32: &[TestVector] = &[
+ TestVector {
+ msg: b"",
+ msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620"),
+ uniform_bytes: &hex!("e8dc0c8b686b7ef2074086fbdd2f30e3f8bfbd3bdf177f73f04b97ce618a3ed3"),
+ },
+ TestVector {
+ msg: b"abc",
+ msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000616263002000412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620"),
+ uniform_bytes: &hex!("52dbf4f36cf560fca57dedec2ad924ee9c266341d8f3d6afe5171733b16bbb12"),
+ },
+ TestVector {
+ msg: b"abcdef0123456789",
+ msg_prime: &hex!("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000061626364656630313233343536373839002000412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620"),
+ uniform_bytes: &hex!("35387dcf22618f3728e6c686490f8b431f76550b0b2c61cbc1ce7001536f4521"),
+ },
+ TestVector {
+ msg: b"q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
+ msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000713132385f7171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171002000412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620"),
+ uniform_bytes: &hex!("01b637612bb18e840028be900a833a74414140dde0c4754c198532c3a0ba42bc"),
+ },
+ TestVector {
+ msg: b"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000613531325f6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161002000412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620"),
+ uniform_bytes: &hex!("20cce7033cabc5460743180be6fa8aac5a103f56d481cf369a8accc0c374431b"),
+ },
+ ];
+
+ for test_vector in TEST_VECTORS_32 {
+ test_vector.assert::<Sha256, U32>(DST, &dst_prime)?;
+ }
+
+ const TEST_VECTORS_128: &[TestVector] = &[
+ TestVector {
+ msg: b"",
+ msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620"),
+ uniform_bytes: &hex!("14604d85432c68b757e485c8894db3117992fc57e0e136f71ad987f789a0abc287c47876978e2388a02af86b1e8d1342e5ce4f7aaa07a87321e691f6fba7e0072eecc1218aebb89fb14a0662322d5edbd873f0eb35260145cd4e64f748c5dfe60567e126604bcab1a3ee2dc0778102ae8a5cfd1429ebc0fa6bf1a53c36f55dfc"),
+ },
+ TestVector {
+ msg: b"abc",
+ msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000616263008000412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620"),
+ uniform_bytes: &hex!("1a30a5e36fbdb87077552b9d18b9f0aee16e80181d5b951d0471d55b66684914aef87dbb3626eaabf5ded8cd0686567e503853e5c84c259ba0efc37f71c839da2129fe81afdaec7fbdc0ccd4c794727a17c0d20ff0ea55e1389d6982d1241cb8d165762dbc39fb0cee4474d2cbbd468a835ae5b2f20e4f959f56ab24cd6fe267"),
+ },
+ TestVector {
+ msg: b"abcdef0123456789",
+ msg_prime: &hex!("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000061626364656630313233343536373839008000412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620"),
+ uniform_bytes: &hex!("d2ecef3635d2397f34a9f86438d772db19ffe9924e28a1caf6f1c8f15603d4028f40891044e5c7e39ebb9b31339979ff33a4249206f67d4a1e7c765410bcd249ad78d407e303675918f20f26ce6d7027ed3774512ef5b00d816e51bfcc96c3539601fa48ef1c07e494bdc37054ba96ecb9dbd666417e3de289d4f424f502a982"),
+ },
+ TestVector {
+ msg: b"q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
+ msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000713132385f7171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171008000412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620"),
+ uniform_bytes: &hex!("ed6e8c036df90111410431431a232d41a32c86e296c05d426e5f44e75b9a50d335b2412bc6c91e0a6dc131de09c43110d9180d0a70f0d6289cb4e43b05f7ee5e9b3f42a1fad0f31bac6a625b3b5c50e3a83316783b649e5ecc9d3b1d9471cb5024b7ccf40d41d1751a04ca0356548bc6e703fca02ab521b505e8e45600508d32"),
+ },
+ TestVector {
+ msg: b"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ msg_prime: &hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000613531325f6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161008000412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620"),
+ uniform_bytes: &hex!("78b53f2413f3c688f07732c10e5ced29a17c6a16f717179ffbe38d92d6c9ec296502eb9889af83a1928cd162e845b0d3c5424e83280fed3d10cffb2f8431f14e7a23f4c68819d40617589e4c41169d0b56e0e3535be1fd71fbb08bb70c5b5ffed953d6c14bf7618b35fc1f4c4b30538236b4b08c9fbf90462447a8ada60be495"),
+ },
+ ];
+
+ for test_vector in TEST_VECTORS_128 {
+ test_vector.assert::<Sha256, U128>(DST, &dst_prime)?;
+ }
+
+ Ok(())
+ }
+
+ #[test]
+ fn expand_message_xmd_sha_512() -> Result<()> {
+ use sha2::Sha512;
+
+ const DST: &[u8] = b"QUUX-V01-CS02-with-expander-SHA512-256";
+ const DST_PRIME: &[u8] =
+ &hex!("515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626");
+
+ let dst_prime = Domain::xmd::<Sha512>(DST)?;
+ dst_prime.assert(DST_PRIME);
+
+ const TEST_VECTORS_32: &[TestVector] = &[
+ TestVector {
+ msg: b"",
+ msg_prime: &hex!("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626"),
+ uniform_bytes: &hex!("6b9a7312411d92f921c6f68ca0b6380730a1a4d982c507211a90964c394179ba"),
+ },
+ TestVector {
+ msg: b"abc",
+ msg_prime: &hex!("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000616263002000515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626"),
+ uniform_bytes: &hex!("0da749f12fbe5483eb066a5f595055679b976e93abe9be6f0f6318bce7aca8dc"),
+ },
+ TestVector {
+ msg: b"abcdef0123456789",
+ msg_prime: &hex!("000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000061626364656630313233343536373839002000515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626"),
+ uniform_bytes: &hex!("087e45a86e2939ee8b91100af1583c4938e0f5fc6c9db4b107b83346bc967f58"),
+ },
+ TestVector {
+ msg: b"q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
+ msg_prime: &hex!("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000713132385f7171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171002000515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626"),
+ uniform_bytes: &hex!("7336234ee9983902440f6bc35b348352013becd88938d2afec44311caf8356b3"),
+ },
+ TestVector {
+ msg: b"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ msg_prime: &hex!("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000613531325f6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161002000515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626"),
+ uniform_bytes: &hex!("57b5f7e766d5be68a6bfe1768e3c2b7f1228b3e4b3134956dd73a59b954c66f4"),
+ },
+ ];
+
+ for test_vector in TEST_VECTORS_32 {
+ test_vector.assert::<Sha512, U32>(DST, &dst_prime)?;
+ }
+
+ const TEST_VECTORS_128: &[TestVector] = &[
+ TestVector {
+ msg: b"",
+ msg_prime: &hex!("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626"),
+ uniform_bytes: &hex!("41b037d1734a5f8df225dd8c7de38f851efdb45c372887be655212d07251b921b052b62eaed99b46f72f2ef4cc96bfaf254ebbbec091e1a3b9e4fb5e5b619d2e0c5414800a1d882b62bb5cd1778f098b8eb6cb399d5d9d18f5d5842cf5d13d7eb00a7cff859b605da678b318bd0e65ebff70bec88c753b159a805d2c89c55961"),
+ },
+ TestVector {
+ msg: b"abc",
+ msg_prime: &hex!("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000616263008000515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626"),
+ uniform_bytes: &hex!("7f1dddd13c08b543f2e2037b14cefb255b44c83cc397c1786d975653e36a6b11bdd7732d8b38adb4a0edc26a0cef4bb45217135456e58fbca1703cd6032cb1347ee720b87972d63fbf232587043ed2901bce7f22610c0419751c065922b488431851041310ad659e4b23520e1772ab29dcdeb2002222a363f0c2b1c972b3efe1"),
+ },
+ TestVector {
+ msg: b"abcdef0123456789",
+ msg_prime: &hex!("000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000061626364656630313233343536373839008000515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626"),
+ uniform_bytes: &hex!("3f721f208e6199fe903545abc26c837ce59ac6fa45733f1baaf0222f8b7acb0424814fcb5eecf6c1d38f06e9d0a6ccfbf85ae612ab8735dfdf9ce84c372a77c8f9e1c1e952c3a61b7567dd0693016af51d2745822663d0c2367e3f4f0bed827feecc2aaf98c949b5ed0d35c3f1023d64ad1407924288d366ea159f46287e61ac"),
+ },
+ TestVector {
+ msg: b"q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
+ msg_prime: &hex!("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000713132385f7171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171008000515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626"),
+ uniform_bytes: &hex!("b799b045a58c8d2b4334cf54b78260b45eec544f9f2fb5bd12fb603eaee70db7317bf807c406e26373922b7b8920fa29142703dd52bdf280084fb7ef69da78afdf80b3586395b433dc66cde048a258e476a561e9deba7060af40adf30c64249ca7ddea79806ee5beb9a1422949471d267b21bc88e688e4014087a0b592b695ed"),
+ },
+ TestVector {
+ msg: b"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ msg_prime: &hex!("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000613531325f6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161008000515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626"),
+ uniform_bytes: &hex!("05b0bfef265dcee87654372777b7c44177e2ae4c13a27f103340d9cd11c86cb2426ffcad5bd964080c2aee97f03be1ca18e30a1f14e27bc11ebbd650f305269cc9fb1db08bf90bfc79b42a952b46daf810359e7bc36452684784a64952c343c52e5124cd1f71d474d5197fefc571a92929c9084ffe1112cf5eea5192ebff330b"),
+ },
+ ];
+
+ for test_vector in TEST_VECTORS_128 {
+ test_vector.assert::<Sha512, U128>(DST, &dst_prime)?;
+ }
+
+ Ok(())
+ }
+}
diff --git a/vendor/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs b/vendor/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs
new file mode 100644
index 000000000..107ac5e06
--- /dev/null
+++ b/vendor/elliptic-curve/src/hash2curve/hash2field/expand_msg/xof.rs
@@ -0,0 +1,353 @@
+//! `expand_message_xof` for the `ExpandMsg` trait
+
+use super::{Domain, ExpandMsg, Expander};
+use crate::{Error, Result};
+use digest::{ExtendableOutput, Update, XofReader};
+use generic_array::typenum::U32;
+
+/// Placeholder type for implementing `expand_message_xof` based on an extendable output function
+///
+/// # Errors
+/// - `dst.is_empty()`
+/// - `len_in_bytes == 0`
+/// - `len_in_bytes > u16::MAX`
+pub struct ExpandMsgXof<HashT>
+where
+ HashT: Default + ExtendableOutput + Update,
+{
+ reader: <HashT as ExtendableOutput>::Reader,
+}
+
+/// ExpandMsgXof implements `expand_message_xof` for the [`ExpandMsg`] trait
+impl<'a, HashT> ExpandMsg<'a> for ExpandMsgXof<HashT>
+where
+ HashT: Default + ExtendableOutput + Update,
+{
+ type Expander = Self;
+
+ fn expand_message(
+ msgs: &[&[u8]],
+ dst: &'a [u8],
+ len_in_bytes: usize,
+ ) -> Result<Self::Expander> {
+ if len_in_bytes == 0 {
+ return Err(Error);
+ }
+
+ let len_in_bytes = u16::try_from(len_in_bytes).map_err(|_| Error)?;
+
+ let domain = Domain::<U32>::xof::<HashT>(dst)?;
+ let mut reader = HashT::default();
+
+ for msg in msgs {
+ reader = reader.chain(msg);
+ }
+
+ let reader = reader
+ .chain(len_in_bytes.to_be_bytes())
+ .chain(domain.data())
+ .chain([domain.len()])
+ .finalize_xof();
+ Ok(Self { reader })
+ }
+}
+
+impl<HashT> Expander for ExpandMsgXof<HashT>
+where
+ HashT: Default + ExtendableOutput + Update,
+{
+ fn fill_bytes(&mut self, okm: &mut [u8]) {
+ self.reader.read(okm);
+ }
+}
+
+#[cfg(test)]
+mod test {
+ use super::*;
+ use core::mem;
+ use generic_array::{
+ typenum::{U128, U32},
+ ArrayLength, GenericArray,
+ };
+ use hex_literal::hex;
+ use sha3::Shake128;
+
+ fn assert_message<HashT>(
+ msg: &[u8],
+ domain: &Domain<'_, U32>,
+ len_in_bytes: u16,
+ bytes: &[u8],
+ ) {
+ let msg_len = msg.len();
+ assert_eq!(msg, &bytes[..msg_len]);
+
+ let len_in_bytes_len = msg_len + mem::size_of::<u16>();
+ assert_eq!(
+ len_in_bytes.to_be_bytes(),
+ &bytes[msg_len..len_in_bytes_len]
+ );
+
+ let dst = len_in_bytes_len + domain.data().len();
+ assert_eq!(domain.data(), &bytes[len_in_bytes_len..dst]);
+
+ let dst_len = dst + mem::size_of::<u8>();
+ assert_eq!([domain.len()], &bytes[dst..dst_len]);
+
+ assert_eq!(dst_len, bytes.len());
+ }
+
+ struct TestVector {
+ msg: &'static [u8],
+ msg_prime: &'static [u8],
+ uniform_bytes: &'static [u8],
+ }
+
+ impl TestVector {
+ fn assert<HashT, L>(&self, dst: &'static [u8], domain: &Domain<'_, U32>) -> Result<()>
+ where
+ HashT: Default + ExtendableOutput + Update,
+ L: ArrayLength<u8>,
+ {
+ assert_message::<HashT>(self.msg, domain, L::to_u16(), self.msg_prime);
+
+ let mut expander =
+ ExpandMsgXof::<HashT>::expand_message(&[self.msg], dst, L::to_usize())?;
+
+ let mut uniform_bytes = GenericArray::<u8, L>::default();
+ expander.fill_bytes(&mut uniform_bytes);
+
+ assert_eq!(uniform_bytes.as_slice(), self.uniform_bytes);
+ Ok(())
+ }
+ }
+
+ #[test]
+ fn expand_message_xof_shake_128() -> Result<()> {
+ const DST: &[u8] = b"QUUX-V01-CS02-with-expander-SHAKE128";
+ const DST_PRIME: &[u8] =
+ &hex!("515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824");
+
+ let dst_prime = Domain::<U32>::xof::<Shake128>(DST)?;
+ dst_prime.assert(DST_PRIME);
+
+ const TEST_VECTORS_32: &[TestVector] = &[
+ TestVector {
+ msg: b"",
+ msg_prime: &hex!("0020515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824"),
+ uniform_bytes: &hex!("86518c9cd86581486e9485aa74ab35ba150d1c75c88e26b7043e44e2acd735a2"),
+ },
+ TestVector {
+ msg: b"abc",
+ msg_prime: &hex!("6162630020515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824"),
+ uniform_bytes: &hex!("8696af52a4d862417c0763556073f47bc9b9ba43c99b505305cb1ec04a9ab468"),
+ },
+ TestVector {
+ msg: b"abcdef0123456789",
+ msg_prime: &hex!("616263646566303132333435363738390020515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824"),
+ uniform_bytes: &hex!("912c58deac4821c3509dbefa094df54b34b8f5d01a191d1d3108a2c89077acca"),
+ },
+ TestVector {
+ msg: b"q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
+ msg_prime: &hex!("713132385f71717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171710020515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824"),
+ uniform_bytes: &hex!("1adbcc448aef2a0cebc71dac9f756b22e51839d348e031e63b33ebb50faeaf3f"),
+ },
+ TestVector {
+ msg: b"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ msg_prime: &hex!("613531325f61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161610020515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824"),
+ uniform_bytes: &hex!("df3447cc5f3e9a77da10f819218ddf31342c310778e0e4ef72bbaecee786a4fe"),
+ },
+ ];
+
+ for test_vector in TEST_VECTORS_32 {
+ test_vector.assert::<Shake128, U32>(DST, &dst_prime)?;
+ }
+
+ const TEST_VECTORS_128: &[TestVector] = &[
+ TestVector {
+ msg: b"",
+ msg_prime: &hex!("0080515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824"),
+ uniform_bytes: &hex!("7314ff1a155a2fb99a0171dc71b89ab6e3b2b7d59e38e64419b8b6294d03ffee42491f11370261f436220ef787f8f76f5b26bdcd850071920ce023f3ac46847744f4612b8714db8f5db83205b2e625d95afd7d7b4d3094d3bdde815f52850bb41ead9822e08f22cf41d615a303b0d9dde73263c049a7b9898208003a739a2e57"),
+ },
+ TestVector {
+ msg: b"abc",
+ msg_prime: &hex!("6162630080515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824"),
+ uniform_bytes: &hex!("c952f0c8e529ca8824acc6a4cab0e782fc3648c563ddb00da7399f2ae35654f4860ec671db2356ba7baa55a34a9d7f79197b60ddae6e64768a37d699a78323496db3878c8d64d909d0f8a7de4927dcab0d3dbbc26cb20a49eceb0530b431cdf47bc8c0fa3e0d88f53b318b6739fbed7d7634974f1b5c386d6230c76260d5337a"),
+ },
+ TestVector {
+ msg: b"abcdef0123456789",
+ msg_prime: &hex!("616263646566303132333435363738390080515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824"),
+ uniform_bytes: &hex!("19b65ee7afec6ac06a144f2d6134f08eeec185f1a890fe34e68f0e377b7d0312883c048d9b8a1d6ecc3b541cb4987c26f45e0c82691ea299b5e6889bbfe589153016d8131717ba26f07c3c14ffbef1f3eff9752e5b6183f43871a78219a75e7000fbac6a7072e2b83c790a3a5aecd9d14be79f9fd4fb180960a3772e08680495"),
+ },
+ TestVector {
+ msg: b"q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
+ msg_prime: &hex!("713132385f71717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171710080515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824"),
+ uniform_bytes: &hex!("ca1b56861482b16eae0f4a26212112362fcc2d76dcc80c93c4182ed66c5113fe41733ed68be2942a3487394317f3379856f4822a611735e50528a60e7ade8ec8c71670fec6661e2c59a09ed36386513221688b35dc47e3c3111ee8c67ff49579089d661caa29db1ef10eb6eace575bf3dc9806e7c4016bd50f3c0e2a6481ee6d"),
+ },
+ TestVector {
+ msg: b"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ msg_prime: &hex!("613531325f61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161610080515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824"),
+ uniform_bytes: &hex!("9d763a5ce58f65c91531b4100c7266d479a5d9777ba761693d052acd37d149e7ac91c796a10b919cd74a591a1e38719fb91b7203e2af31eac3bff7ead2c195af7d88b8bc0a8adf3d1e90ab9bed6ddc2b7f655dd86c730bdeaea884e73741097142c92f0e3fc1811b699ba593c7fbd81da288a29d423df831652e3a01a9374999"),
+ },
+ ];
+
+ for test_vector in TEST_VECTORS_128 {
+ test_vector.assert::<Shake128, U128>(DST, &dst_prime)?;
+ }
+
+ Ok(())
+ }
+
+ #[test]
+ fn expand_message_xof_shake_128_long() -> Result<()> {
+ const DST: &[u8] = b"QUUX-V01-CS02-with-expander-SHAKE128-long-DST-111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111";
+ const DST_PRIME: &[u8] =
+ &hex!("acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20");
+
+ let dst_prime = Domain::<U32>::xof::<Shake128>(DST)?;
+ dst_prime.assert(DST_PRIME);
+
+ const TEST_VECTORS_32: &[TestVector] = &[
+ TestVector {
+ msg: b"",
+ msg_prime: &hex!("0020acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20"),
+ uniform_bytes: &hex!("827c6216330a122352312bccc0c8d6e7a146c5257a776dbd9ad9d75cd880fc53"),
+ },
+ TestVector {
+ msg: b"abc",
+ msg_prime: &hex!("6162630020acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20"),
+ uniform_bytes: &hex!("690c8d82c7213b4282c6cb41c00e31ea1d3e2005f93ad19bbf6da40f15790c5c"),
+ },
+ TestVector {
+ msg: b"abcdef0123456789",
+ msg_prime: &hex!("616263646566303132333435363738390020acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20"),
+ uniform_bytes: &hex!("979e3a15064afbbcf99f62cc09fa9c85028afcf3f825eb0711894dcfc2f57057"),
+ },
+ TestVector {
+ msg: b"q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
+ msg_prime: &hex!("713132385f71717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171710020acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20"),
+ uniform_bytes: &hex!("c5a9220962d9edc212c063f4f65b609755a1ed96e62f9db5d1fd6adb5a8dc52b"),
+ },
+ TestVector {
+ msg: b"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ msg_prime: &hex!("613531325f61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161610020acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20"),
+ uniform_bytes: &hex!("f7b96a5901af5d78ce1d071d9c383cac66a1dfadb508300ec6aeaea0d62d5d62"),
+ },
+ ];
+
+ for test_vector in TEST_VECTORS_32 {
+ test_vector.assert::<Shake128, U32>(DST, &dst_prime)?;
+ }
+
+ const TEST_VECTORS_128: &[TestVector] = &[
+ TestVector {
+ msg: b"",
+ msg_prime: &hex!("0080acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20"),
+ uniform_bytes: &hex!("3890dbab00a2830be398524b71c2713bbef5f4884ac2e6f070b092effdb19208c7df943dc5dcbaee3094a78c267ef276632ee2c8ea0c05363c94b6348500fae4208345dd3475fe0c834c2beac7fa7bc181692fb728c0a53d809fc8111495222ce0f38468b11becb15b32060218e285c57a60162c2c8bb5b6bded13973cd41819"),
+ },
+ TestVector {
+ msg: b"abc",
+ msg_prime: &hex!("6162630080acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20"),
+ uniform_bytes: &hex!("41b7ffa7a301b5c1441495ebb9774e2a53dbbf4e54b9a1af6a20fd41eafd69ef7b9418599c5545b1ee422f363642b01d4a53449313f68da3e49dddb9cd25b97465170537d45dcbdf92391b5bdff344db4bd06311a05bca7dcd360b6caec849c299133e5c9194f4e15e3e23cfaab4003fab776f6ac0bfae9144c6e2e1c62e7d57"),
+ },
+ TestVector {
+ msg: b"abcdef0123456789",
+ msg_prime: &hex!("616263646566303132333435363738390080acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20"),
+ uniform_bytes: &hex!("55317e4a21318472cd2290c3082957e1242241d9e0d04f47026f03401643131401071f01aa03038b2783e795bdfa8a3541c194ad5de7cb9c225133e24af6c86e748deb52e560569bd54ef4dac03465111a3a44b0ea490fb36777ff8ea9f1a8a3e8e0de3cf0880b4b2f8dd37d3a85a8b82375aee4fa0e909f9763319b55778e71"),
+ },
+ TestVector {
+ msg: b"q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
+ msg_prime: &hex!("713132385f71717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171710080acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20"),
+ uniform_bytes: &hex!("19fdd2639f082e31c77717ac9bb032a22ff0958382b2dbb39020cdc78f0da43305414806abf9a561cb2d0067eb2f7bc544482f75623438ed4b4e39dd9e6e2909dd858bd8f1d57cd0fce2d3150d90aa67b4498bdf2df98c0100dd1a173436ba5d0df6be1defb0b2ce55ccd2f4fc05eb7cb2c019c35d5398b85adc676da4238bc7"),
+ },
+ TestVector {
+ msg: b"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ msg_prime: &hex!("613531325f61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161610080acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20"),
+ uniform_bytes: &hex!("945373f0b3431a103333ba6a0a34f1efab2702efde41754c4cb1d5216d5b0a92a67458d968562bde7fa6310a83f53dda1383680a276a283438d58ceebfa7ab7ba72499d4a3eddc860595f63c93b1c5e823ea41fc490d938398a26db28f61857698553e93f0574eb8c5017bfed6249491f9976aaa8d23d9485339cc85ca329308"),
+ },
+ ];
+
+ for test_vector in TEST_VECTORS_128 {
+ test_vector.assert::<Shake128, U128>(DST, &dst_prime)?;
+ }
+
+ Ok(())
+ }
+
+ #[test]
+ fn expand_message_xof_shake_256() -> Result<()> {
+ use sha3::Shake256;
+
+ const DST: &[u8] = b"QUUX-V01-CS02-with-expander-SHAKE256";
+ const DST_PRIME: &[u8] =
+ &hex!("515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624");
+
+ let dst_prime = Domain::<U32>::xof::<Shake256>(DST)?;
+ dst_prime.assert(DST_PRIME);
+
+ const TEST_VECTORS_32: &[TestVector] = &[
+ TestVector {
+ msg: b"",
+ msg_prime: &hex!("0020515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624"),
+ uniform_bytes: &hex!("2ffc05c48ed32b95d72e807f6eab9f7530dd1c2f013914c8fed38c5ccc15ad76"),
+ },
+ TestVector {
+ msg: b"abc",
+ msg_prime: &hex!("6162630020515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624"),
+ uniform_bytes: &hex!("b39e493867e2767216792abce1f2676c197c0692aed061560ead251821808e07"),
+ },
+ TestVector {
+ msg: b"abcdef0123456789",
+ msg_prime: &hex!("616263646566303132333435363738390020515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624"),
+ uniform_bytes: &hex!("245389cf44a13f0e70af8665fe5337ec2dcd138890bb7901c4ad9cfceb054b65"),
+ },
+ TestVector {
+ msg: b"q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
+ msg_prime: &hex!("713132385f71717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171710020515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624"),
+ uniform_bytes: &hex!("719b3911821e6428a5ed9b8e600f2866bcf23c8f0515e52d6c6c019a03f16f0e"),
+ },
+ TestVector {
+ msg: b"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ msg_prime: &hex!("613531325f61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161610020515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624"),
+ uniform_bytes: &hex!("9181ead5220b1963f1b5951f35547a5ea86a820562287d6ca4723633d17ccbbc"),
+ },
+ ];
+
+ for test_vector in TEST_VECTORS_32 {
+ test_vector.assert::<Shake256, U32>(DST, &dst_prime)?;
+ }
+
+ const TEST_VECTORS_128: &[TestVector] = &[
+ TestVector {
+ msg: b"",
+ msg_prime: &hex!("0080515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624"),
+ uniform_bytes: &hex!("7a1361d2d7d82d79e035b8880c5a3c86c5afa719478c007d96e6c88737a3f631dd74a2c88df79a4cb5e5d9f7504957c70d669ec6bfedc31e01e2bacc4ff3fdf9b6a00b17cc18d9d72ace7d6b81c2e481b4f73f34f9a7505dccbe8f5485f3d20c5409b0310093d5d6492dea4e18aa6979c23c8ea5de01582e9689612afbb353df"),
+ },
+ TestVector {
+ msg: b"abc",
+ msg_prime: &hex!("6162630080515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624"),
+ uniform_bytes: &hex!("a54303e6b172909783353ab05ef08dd435a558c3197db0c132134649708e0b9b4e34fb99b92a9e9e28fc1f1d8860d85897a8e021e6382f3eea10577f968ff6df6c45fe624ce65ca25932f679a42a404bc3681efe03fcd45ef73bb3a8f79ba784f80f55ea8a3c367408f30381299617f50c8cf8fbb21d0f1e1d70b0131a7b6fbe"),
+ },
+ TestVector {
+ msg: b"abcdef0123456789",
+ msg_prime: &hex!("616263646566303132333435363738390080515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624"),
+ uniform_bytes: &hex!("e42e4d9538a189316e3154b821c1bafb390f78b2f010ea404e6ac063deb8c0852fcd412e098e231e43427bd2be1330bb47b4039ad57b30ae1fc94e34993b162ff4d695e42d59d9777ea18d3848d9d336c25d2acb93adcad009bcfb9cde12286df267ada283063de0bb1505565b2eb6c90e31c48798ecdc71a71756a9110ff373"),
+ },
+ TestVector {
+ msg: b"q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
+ msg_prime: &hex!("713132385f71717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171710080515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624"),
+ uniform_bytes: &hex!("4ac054dda0a38a65d0ecf7afd3c2812300027c8789655e47aecf1ecc1a2426b17444c7482c99e5907afd9c25b991990490bb9c686f43e79b4471a23a703d4b02f23c669737a886a7ec28bddb92c3a98de63ebf878aa363a501a60055c048bea11840c4717beae7eee28c3cfa42857b3d130188571943a7bd747de831bd6444e0"),
+ },
+ TestVector {
+ msg: b"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ msg_prime: &hex!("613531325f61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161610080515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624"),
+ uniform_bytes: &hex!("09afc76d51c2cccbc129c2315df66c2be7295a231203b8ab2dd7f95c2772c68e500bc72e20c602abc9964663b7a03a389be128c56971ce81001a0b875e7fd17822db9d69792ddf6a23a151bf470079c518279aef3e75611f8f828994a9988f4a8a256ddb8bae161e658d5a2a09bcfe839c6396dc06ee5c8ff3c22d3b1f9deb7e"),
+ },
+ ];
+
+ for test_vector in TEST_VECTORS_128 {
+ test_vector.assert::<Shake256, U128>(DST, &dst_prime)?;
+ }
+
+ Ok(())
+ }
+}
diff --git a/vendor/elliptic-curve/src/hash2curve/isogeny.rs b/vendor/elliptic-curve/src/hash2curve/isogeny.rs
new file mode 100644
index 000000000..fc197246a
--- /dev/null
+++ b/vendor/elliptic-curve/src/hash2curve/isogeny.rs
@@ -0,0 +1,57 @@
+//! Traits for mapping an isogeny to another curve
+//!
+//! <https://datatracker.ietf.org/doc/draft-irtf-cfrg-hash-to-curve>
+
+use core::ops::{AddAssign, Mul};
+use ff::Field;
+use generic_array::{typenum::Unsigned, ArrayLength, GenericArray};
+
+/// The coefficients for mapping from one isogenous curve to another
+pub struct IsogenyCoefficients<F: Field + AddAssign + Mul<Output = F>> {
+ /// The coefficients for the x numerator
+ pub xnum: &'static [F],
+ /// The coefficients for the x denominator
+ pub xden: &'static [F],
+ /// The coefficients for the y numerator
+ pub ynum: &'static [F],
+ /// The coefficients for the x denominator
+ pub yden: &'static [F],
+}
+
+/// The [`Isogeny`] methods to map to another curve.
+pub trait Isogeny: Field + AddAssign + Mul<Output = Self> {
+ /// The maximum number of coefficients
+ type Degree: ArrayLength<Self>;
+ /// The isogeny coefficients
+ const COEFFICIENTS: IsogenyCoefficients<Self>;
+
+ /// Map from the isogeny points to the main curve
+ fn isogeny(x: Self, y: Self) -> (Self, Self) {
+ let mut xs = GenericArray::<Self, Self::Degree>::default();
+ xs[0] = Self::one();
+ xs[1] = x;
+ xs[2] = x.square();
+ for i in 3..Self::Degree::to_usize() {
+ xs[i] = xs[i - 1] * x;
+ }
+ let x_num = Self::compute_iso(&xs, Self::COEFFICIENTS.xnum);
+ let x_den = Self::compute_iso(&xs, Self::COEFFICIENTS.xden)
+ .invert()
+ .unwrap();
+ let y_num = Self::compute_iso(&xs, Self::COEFFICIENTS.ynum) * y;
+ let y_den = Self::compute_iso(&xs, Self::COEFFICIENTS.yden)
+ .invert()
+ .unwrap();
+
+ (x_num * x_den, y_num * y_den)
+ }
+
+ /// Compute the ISO transform
+ fn compute_iso(xxs: &[Self], k: &[Self]) -> Self {
+ let mut xx = Self::zero();
+ for (xi, ki) in xxs.iter().zip(k.iter()) {
+ xx += *xi * ki;
+ }
+ xx
+ }
+}
diff --git a/vendor/elliptic-curve/src/hash2curve/map2curve.rs b/vendor/elliptic-curve/src/hash2curve/map2curve.rs
new file mode 100644
index 000000000..6092e57ba
--- /dev/null
+++ b/vendor/elliptic-curve/src/hash2curve/map2curve.rs
@@ -0,0 +1,12 @@
+//! Traits for mapping field elements to points on the curve.
+
+/// Trait for converting field elements into a point
+/// via a mapping method like Simplified Shallue-van de Woestijne-Ulas
+/// or Elligator
+pub trait MapToCurve {
+ /// The output point
+ type Output;
+
+ /// Map a field element into a point
+ fn map_to_curve(&self) -> Self::Output;
+}
diff --git a/vendor/elliptic-curve/src/hash2curve/osswu.rs b/vendor/elliptic-curve/src/hash2curve/osswu.rs
new file mode 100644
index 000000000..f803863b1
--- /dev/null
+++ b/vendor/elliptic-curve/src/hash2curve/osswu.rs
@@ -0,0 +1,87 @@
+//! Optimized simplified Shallue-van de Woestijne-Ulas methods.
+//!
+//! <https://eprint.iacr.org/2009/340.pdf>
+
+use ff::Field;
+use subtle::Choice;
+
+/// The Optimized Simplified Shallue-van de Woestijne-Ulas parameters
+pub struct OsswuMapParams<F>
+where
+ F: Field,
+{
+ /// The first constant term
+ pub c1: [u64; 4],
+ /// The second constant term
+ pub c2: F,
+ /// The ISO A variable or Curve A variable
+ pub map_a: F,
+ /// The ISO A variable or Curve A variable
+ pub map_b: F,
+ /// The Z parameter
+ pub z: F,
+}
+
+/// Trait for determining the parity of the field
+pub trait Sgn0 {
+ /// Return the parity of the field
+ /// 1 == negative
+ /// 0 == non-negative
+ fn sgn0(&self) -> Choice;
+}
+
+/// The optimized simplified Shallue-van de Woestijne-Ulas method
+/// for mapping elliptic curve scalars to affine points.
+pub trait OsswuMap: Field + Sgn0 {
+ /// The OSSWU parameters for mapping the field to affine points.
+ /// For Weierstrass curves having A==0 or B==0, the parameters
+ /// should be for isogeny where A≠0 and B≠0.
+ const PARAMS: OsswuMapParams<Self>;
+
+ /// Convert this field element into an affine point on the elliptic curve
+ /// returning (X, Y). For Weierstrass curves having A==0 or B==0
+ /// the result is a point on an isogeny.
+ fn osswu(&self) -> (Self, Self) {
+ let tv1 = self.square(); // u^2
+ let tv3 = Self::PARAMS.z * tv1; // Z * u^2
+ let mut tv2 = tv3.square(); // tv3^2
+ let mut xd = tv2 + tv3; // tv3^2 + tv3
+ let x1n = Self::PARAMS.map_b * (xd + Self::one()); // B * (xd + 1)
+ xd *= -Self::PARAMS.map_a; // -A * xd
+
+ let tv = Self::PARAMS.z * Self::PARAMS.map_a;
+ xd.conditional_assign(&tv, xd.is_zero());
+
+ tv2 = xd.square(); //xd^2
+ let gxd = tv2 * xd; // xd^3
+ tv2 *= Self::PARAMS.map_a; // A * tv2
+
+ let mut gx1 = x1n * (tv2 + x1n.square()); //x1n *(tv2 + x1n^2)
+ tv2 = gxd * Self::PARAMS.map_b; // B * gxd
+ gx1 += tv2; // gx1 + tv2
+
+ let mut tv4 = gxd.square(); // gxd^2
+ tv2 = gx1 * gxd; // gx1 * gxd
+ tv4 *= tv2;
+
+ let y1 = tv4.pow_vartime(&Self::PARAMS.c1) * tv2; // tv4^C1 * tv2
+ let x2n = tv3 * x1n; // tv3 * x1n
+
+ let y2 = y1 * Self::PARAMS.c2 * tv1 * self; // y1 * c2 * tv1 * u
+
+ tv2 = y1.square() * gxd; //y1^2 * gxd
+
+ let e2 = tv2.ct_eq(&gx1);
+
+ // if e2 , x = x1, else x = x2
+ let mut x = Self::conditional_select(&x2n, &x1n, e2);
+ // xn / xd
+ x *= xd.invert().unwrap();
+
+ // if e2, y = y1, else y = y2
+ let mut y = Self::conditional_select(&y2, &y1, e2);
+
+ y.conditional_assign(&-y, self.sgn0() ^ y.sgn0());
+ (x, y)
+ }
+}
diff --git a/vendor/elliptic-curve/src/jwk.rs b/vendor/elliptic-curve/src/jwk.rs
new file mode 100644
index 000000000..ff5e6e638
--- /dev/null
+++ b/vendor/elliptic-curve/src/jwk.rs
@@ -0,0 +1,692 @@
+//! JSON Web Key (JWK) Support.
+//!
+//! Specified in RFC 7518 Section 6: Cryptographic Algorithms for Keys:
+//! <https://tools.ietf.org/html/rfc7518#section-6>
+
+use crate::{
+ sec1::{Coordinates, EncodedPoint, ModulusSize, ValidatePublicKey},
+ secret_key::SecretKey,
+ Curve, Error, FieldBytes, FieldSize, Result,
+};
+use alloc::{
+ borrow::ToOwned,
+ format,
+ string::{String, ToString},
+};
+use base64ct::{Base64UrlUnpadded as Base64Url, Encoding};
+use core::{
+ fmt::{self, Debug},
+ marker::PhantomData,
+ str::{self, FromStr},
+};
+use serdect::serde::{de, ser, Deserialize, Serialize};
+use zeroize::{Zeroize, ZeroizeOnDrop};
+
+#[cfg(feature = "arithmetic")]
+use crate::{
+ public_key::PublicKey,
+ sec1::{FromEncodedPoint, ToEncodedPoint},
+ AffinePoint, ProjectiveArithmetic,
+};
+
+/// Key Type (`kty`) for elliptic curve keys.
+pub const EC_KTY: &str = "EC";
+
+/// Deserialization error message.
+const DE_ERROR_MSG: &str = "struct JwkEcKey with 5 elements";
+
+/// Name of the JWK type
+const JWK_TYPE_NAME: &str = "JwkEcKey";
+
+/// Field names
+const FIELDS: &[&str] = &["kty", "crv", "x", "y", "d"];
+
+/// Elliptic curve parameters used by JSON Web Keys.
+#[cfg_attr(docsrs, doc(cfg(feature = "jwk")))]
+pub trait JwkParameters: Curve {
+ /// The `crv` parameter which identifies a particular elliptic curve
+ /// as defined in RFC 7518 Section 6.2.1.1:
+ /// <https://tools.ietf.org/html/rfc7518#section-6.2.1.1>
+ ///
+ /// Curve values are registered in the IANA "JSON Web Key Elliptic Curve"
+ /// registry defined in RFC 7518 Section 7.6:
+ /// <https://tools.ietf.org/html/rfc7518#section-7.6>
+ const CRV: &'static str;
+}
+
+/// JSON Web Key (JWK) with a `kty` of `"EC"` (elliptic curve).
+///
+/// Specified in [RFC 7518 Section 6: Cryptographic Algorithms for Keys][1].
+///
+/// This type can represent either a public/private keypair, or just a
+/// public key, depending on whether or not the `d` parameter is present.
+///
+/// [1]: https://tools.ietf.org/html/rfc7518#section-6
+// TODO(tarcieri): eagerly decode or validate `x`, `y`, and `d` as Base64
+#[derive(Clone)]
+#[cfg_attr(docsrs, doc(cfg(feature = "jwk")))]
+pub struct JwkEcKey {
+ /// The `crv` parameter which identifies a particular elliptic curve
+ /// as defined in RFC 7518 Section 6.2.1.1:
+ /// <https://tools.ietf.org/html/rfc7518#section-6.2.1.1>
+ crv: String,
+
+ /// The x-coordinate of the elliptic curve point which is the public key
+ /// value associated with this JWK as defined in RFC 7518 6.2.1.2:
+ /// <https://tools.ietf.org/html/rfc7518#section-6.2.1.2>
+ x: String,
+
+ /// The y-coordinate of the elliptic curve point which is the public key
+ /// value associated with this JWK as defined in RFC 7518 6.2.1.3:
+ /// <https://tools.ietf.org/html/rfc7518#section-6.2.1.3>
+ y: String,
+
+ /// The `d` ECC private key parameter as described in RFC 7518 6.2.2.1:
+ /// <https://tools.ietf.org/html/rfc7518#section-6.2.2.1>
+ ///
+ /// Value is optional and if omitted, this JWK represents a private key.
+ ///
+ /// Inner value is encoded according to the `Integer-to-Octet-String`
+ /// conversion as defined in SEC1 section 2.3.7:
+ /// <https://www.secg.org/sec1-v2.pdf>
+ d: Option<String>,
+}
+
+impl JwkEcKey {
+ /// Get the `crv` parameter for this JWK.
+ pub fn crv(&self) -> &str {
+ &self.crv
+ }
+
+ /// Is this JWK a keypair that includes a private key?
+ pub fn is_keypair(&self) -> bool {
+ self.d.is_some()
+ }
+
+ /// Does this JWK contain only a public key?
+ pub fn is_public_key(&self) -> bool {
+ self.d.is_none()
+ }
+
+ /// Decode a JWK into a [`PublicKey`].
+ #[cfg(feature = "arithmetic")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))]
+ pub fn to_public_key<C>(&self) -> Result<PublicKey<C>>
+ where
+ C: Curve + JwkParameters + ProjectiveArithmetic,
+ AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
+ FieldSize<C>: ModulusSize,
+ {
+ PublicKey::from_sec1_bytes(self.to_encoded_point::<C>()?.as_bytes())
+ }
+
+ /// Create a JWK from a SEC1 [`EncodedPoint`].
+ pub fn from_encoded_point<C>(point: &EncodedPoint<C>) -> Option<Self>
+ where
+ C: Curve + JwkParameters,
+ FieldSize<C>: ModulusSize,
+ {
+ match point.coordinates() {
+ Coordinates::Uncompressed { x, y } => Some(JwkEcKey {
+ crv: C::CRV.to_owned(),
+ x: Base64Url::encode_string(x),
+ y: Base64Url::encode_string(y),
+ d: None,
+ }),
+ _ => None,
+ }
+ }
+
+ /// Get the public key component of this JWK as a SEC1 [`EncodedPoint`].
+ pub fn to_encoded_point<C>(&self) -> Result<EncodedPoint<C>>
+ where
+ C: Curve + JwkParameters,
+ FieldSize<C>: ModulusSize,
+ {
+ if self.crv != C::CRV {
+ return Err(Error);
+ }
+
+ let x = decode_base64url_fe::<C>(&self.x)?;
+ let y = decode_base64url_fe::<C>(&self.y)?;
+ Ok(EncodedPoint::<C>::from_affine_coordinates(&x, &y, false))
+ }
+
+ /// Decode a JWK into a [`SecretKey`].
+ #[cfg(feature = "arithmetic")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))]
+ pub fn to_secret_key<C>(&self) -> Result<SecretKey<C>>
+ where
+ C: Curve + JwkParameters + ValidatePublicKey,
+ FieldSize<C>: ModulusSize,
+ {
+ self.try_into()
+ }
+}
+
+impl FromStr for JwkEcKey {
+ type Err = Error;
+
+ fn from_str(s: &str) -> Result<Self> {
+ serde_json::from_str(s).map_err(|_| Error)
+ }
+}
+
+impl ToString for JwkEcKey {
+ fn to_string(&self) -> String {
+ serde_json::to_string(self).expect("JWK encoding error")
+ }
+}
+
+#[cfg_attr(docsrs, doc(cfg(feature = "jwk")))]
+impl<C> TryFrom<JwkEcKey> for SecretKey<C>
+where
+ C: Curve + JwkParameters + ValidatePublicKey,
+ FieldSize<C>: ModulusSize,
+{
+ type Error = Error;
+
+ fn try_from(jwk: JwkEcKey) -> Result<SecretKey<C>> {
+ (&jwk).try_into()
+ }
+}
+
+#[cfg_attr(docsrs, doc(cfg(feature = "jwk")))]
+impl<C> TryFrom<&JwkEcKey> for SecretKey<C>
+where
+ C: Curve + JwkParameters + ValidatePublicKey,
+ FieldSize<C>: ModulusSize,
+{
+ type Error = Error;
+
+ fn try_from(jwk: &JwkEcKey) -> Result<SecretKey<C>> {
+ if let Some(d_base64) = &jwk.d {
+ let pk = jwk.to_encoded_point::<C>()?;
+ let mut d_bytes = decode_base64url_fe::<C>(d_base64)?;
+ let result = SecretKey::from_be_bytes(&d_bytes);
+ d_bytes.zeroize();
+
+ result.and_then(|secret_key| {
+ C::validate_public_key(&secret_key, &pk)?;
+ Ok(secret_key)
+ })
+ } else {
+ Err(Error)
+ }
+ }
+}
+
+#[cfg(feature = "arithmetic")]
+#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))]
+#[cfg_attr(docsrs, doc(cfg(feature = "jwk")))]
+impl<C> From<SecretKey<C>> for JwkEcKey
+where
+ C: Curve + JwkParameters + ProjectiveArithmetic,
+ AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
+ FieldSize<C>: ModulusSize,
+{
+ fn from(sk: SecretKey<C>) -> JwkEcKey {
+ (&sk).into()
+ }
+}
+
+#[cfg(feature = "arithmetic")]
+#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))]
+#[cfg_attr(docsrs, doc(cfg(feature = "jwk")))]
+impl<C> From<&SecretKey<C>> for JwkEcKey
+where
+ C: Curve + JwkParameters + ProjectiveArithmetic,
+ AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
+ FieldSize<C>: ModulusSize,
+{
+ fn from(sk: &SecretKey<C>) -> JwkEcKey {
+ let mut jwk = sk.public_key().to_jwk();
+ let mut d = sk.to_be_bytes();
+ jwk.d = Some(Base64Url::encode_string(&d));
+ d.zeroize();
+ jwk
+ }
+}
+
+#[cfg(feature = "arithmetic")]
+#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))]
+#[cfg_attr(docsrs, doc(cfg(feature = "jwk")))]
+impl<C> TryFrom<JwkEcKey> for PublicKey<C>
+where
+ C: Curve + JwkParameters + ProjectiveArithmetic,
+ AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
+ FieldSize<C>: ModulusSize,
+{
+ type Error = Error;
+
+ fn try_from(jwk: JwkEcKey) -> Result<PublicKey<C>> {
+ (&jwk).try_into()
+ }
+}
+
+#[cfg(feature = "arithmetic")]
+#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))]
+#[cfg_attr(docsrs, doc(cfg(feature = "jwk")))]
+impl<C> TryFrom<&JwkEcKey> for PublicKey<C>
+where
+ C: Curve + JwkParameters + ProjectiveArithmetic,
+ AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
+ FieldSize<C>: ModulusSize,
+{
+ type Error = Error;
+
+ fn try_from(jwk: &JwkEcKey) -> Result<PublicKey<C>> {
+ PublicKey::from_sec1_bytes(jwk.to_encoded_point::<C>()?.as_bytes())
+ }
+}
+
+#[cfg(feature = "arithmetic")]
+#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))]
+#[cfg_attr(docsrs, doc(cfg(feature = "jwk")))]
+impl<C> From<PublicKey<C>> for JwkEcKey
+where
+ C: Curve + JwkParameters + ProjectiveArithmetic,
+ AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
+ FieldSize<C>: ModulusSize,
+{
+ fn from(pk: PublicKey<C>) -> JwkEcKey {
+ (&pk).into()
+ }
+}
+
+#[cfg(feature = "arithmetic")]
+#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))]
+#[cfg_attr(docsrs, doc(cfg(feature = "jwk")))]
+impl<C> From<&PublicKey<C>> for JwkEcKey
+where
+ C: Curve + JwkParameters + ProjectiveArithmetic,
+ AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
+ FieldSize<C>: ModulusSize,
+{
+ fn from(pk: &PublicKey<C>) -> JwkEcKey {
+ Self::from_encoded_point::<C>(&pk.to_encoded_point(false)).expect("JWK encoding error")
+ }
+}
+
+impl Debug for JwkEcKey {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ let d = if self.d.is_some() {
+ "Some(...)"
+ } else {
+ "None"
+ };
+
+ // NOTE: this implementation omits the `d` private key parameter
+ f.debug_struct(JWK_TYPE_NAME)
+ .field("crv", &self.crv)
+ .field("x", &self.x)
+ .field("y", &self.y)
+ .field("d", &d)
+ .finish()
+ }
+}
+
+impl PartialEq for JwkEcKey {
+ fn eq(&self, other: &Self) -> bool {
+ use subtle::ConstantTimeEq;
+
+ // Compare private key in constant time
+ let d_eq = match &self.d {
+ Some(d1) => match &other.d {
+ Some(d2) => d1.as_bytes().ct_eq(d2.as_bytes()).into(),
+ None => other.d.is_none(),
+ },
+ None => other.d.is_none(),
+ };
+
+ self.crv == other.crv && self.x == other.x && self.y == other.y && d_eq
+ }
+}
+
+impl Eq for JwkEcKey {}
+
+impl ZeroizeOnDrop for JwkEcKey {}
+
+impl Drop for JwkEcKey {
+ fn drop(&mut self) {
+ self.zeroize();
+ }
+}
+
+impl Zeroize for JwkEcKey {
+ fn zeroize(&mut self) {
+ if let Some(d) = &mut self.d {
+ d.zeroize();
+ }
+ }
+}
+
+impl<'de> Deserialize<'de> for JwkEcKey {
+ fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
+ where
+ D: de::Deserializer<'de>,
+ {
+ /// Field positions
+ enum Field {
+ Kty,
+ Crv,
+ X,
+ Y,
+ D,
+ }
+
+ /// Field visitor
+ struct FieldVisitor;
+
+ impl<'de> de::Visitor<'de> for FieldVisitor {
+ type Value = Field;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt::Formatter::write_str(formatter, "field identifier")
+ }
+
+ fn visit_u64<E>(self, value: u64) -> core::result::Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ match value {
+ 0 => Ok(Field::Kty),
+ 1 => Ok(Field::Crv),
+ 2 => Ok(Field::X),
+ 3 => Ok(Field::Y),
+ 4 => Ok(Field::D),
+ _ => Err(de::Error::invalid_value(
+ de::Unexpected::Unsigned(value),
+ &"field index 0 <= i < 5",
+ )),
+ }
+ }
+
+ fn visit_str<E>(self, value: &str) -> core::result::Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ self.visit_bytes(value.as_bytes())
+ }
+
+ fn visit_bytes<E>(self, value: &[u8]) -> core::result::Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ match value {
+ b"kty" => Ok(Field::Kty),
+ b"crv" => Ok(Field::Crv),
+ b"x" => Ok(Field::X),
+ b"y" => Ok(Field::Y),
+ b"d" => Ok(Field::D),
+ _ => Err(de::Error::unknown_field(
+ &String::from_utf8_lossy(value),
+ FIELDS,
+ )),
+ }
+ }
+ }
+
+ impl<'de> Deserialize<'de> for Field {
+ #[inline]
+ fn deserialize<D>(__deserializer: D) -> core::result::Result<Self, D::Error>
+ where
+ D: de::Deserializer<'de>,
+ {
+ de::Deserializer::deserialize_identifier(__deserializer, FieldVisitor)
+ }
+ }
+
+ struct Visitor<'de> {
+ marker: PhantomData<JwkEcKey>,
+ lifetime: PhantomData<&'de ()>,
+ }
+
+ impl<'de> de::Visitor<'de> for Visitor<'de> {
+ type Value = JwkEcKey;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt::Formatter::write_str(formatter, "struct JwkEcKey")
+ }
+
+ #[inline]
+ fn visit_seq<A>(self, mut seq: A) -> core::result::Result<Self::Value, A::Error>
+ where
+ A: de::SeqAccess<'de>,
+ {
+ let kty = de::SeqAccess::next_element::<String>(&mut seq)?
+ .ok_or_else(|| de::Error::invalid_length(0, &DE_ERROR_MSG))?;
+
+ if kty != EC_KTY {
+ return Err(de::Error::custom(format!("unsupported JWK kty: {:?}", kty)));
+ }
+
+ let crv = de::SeqAccess::next_element::<String>(&mut seq)?
+ .ok_or_else(|| de::Error::invalid_length(1, &DE_ERROR_MSG))?;
+
+ let x = de::SeqAccess::next_element::<String>(&mut seq)?
+ .ok_or_else(|| de::Error::invalid_length(2, &DE_ERROR_MSG))?;
+
+ let y = de::SeqAccess::next_element::<String>(&mut seq)?
+ .ok_or_else(|| de::Error::invalid_length(3, &DE_ERROR_MSG))?;
+
+ let d = de::SeqAccess::next_element::<Option<String>>(&mut seq)?
+ .ok_or_else(|| de::Error::invalid_length(4, &DE_ERROR_MSG))?;
+
+ Ok(JwkEcKey { crv, x, y, d })
+ }
+
+ #[inline]
+ fn visit_map<A>(self, mut map: A) -> core::result::Result<Self::Value, A::Error>
+ where
+ A: de::MapAccess<'de>,
+ {
+ let mut kty: Option<String> = None;
+ let mut crv: Option<String> = None;
+ let mut x: Option<String> = None;
+ let mut y: Option<String> = None;
+ let mut d: Option<String> = None;
+
+ while let Some(key) = de::MapAccess::next_key::<Field>(&mut map)? {
+ match key {
+ Field::Kty => {
+ if kty.is_none() {
+ kty = Some(de::MapAccess::next_value::<String>(&mut map)?);
+ } else {
+ return Err(de::Error::duplicate_field(FIELDS[0]));
+ }
+ }
+ Field::Crv => {
+ if crv.is_none() {
+ crv = Some(de::MapAccess::next_value::<String>(&mut map)?);
+ } else {
+ return Err(de::Error::duplicate_field(FIELDS[1]));
+ }
+ }
+ Field::X => {
+ if x.is_none() {
+ x = Some(de::MapAccess::next_value::<String>(&mut map)?);
+ } else {
+ return Err(de::Error::duplicate_field(FIELDS[2]));
+ }
+ }
+ Field::Y => {
+ if y.is_none() {
+ y = Some(de::MapAccess::next_value::<String>(&mut map)?);
+ } else {
+ return Err(de::Error::duplicate_field(FIELDS[3]));
+ }
+ }
+ Field::D => {
+ if d.is_none() {
+ d = de::MapAccess::next_value::<Option<String>>(&mut map)?;
+ } else {
+ return Err(de::Error::duplicate_field(FIELDS[4]));
+ }
+ }
+ }
+ }
+
+ let kty = kty.ok_or_else(|| de::Error::missing_field("kty"))?;
+
+ if kty != EC_KTY {
+ return Err(de::Error::custom(format!("unsupported JWK kty: {}", kty)));
+ }
+
+ let crv = crv.ok_or_else(|| de::Error::missing_field("crv"))?;
+ let x = x.ok_or_else(|| de::Error::missing_field("x"))?;
+ let y = y.ok_or_else(|| de::Error::missing_field("y"))?;
+
+ Ok(JwkEcKey { crv, x, y, d })
+ }
+ }
+
+ de::Deserializer::deserialize_struct(
+ deserializer,
+ JWK_TYPE_NAME,
+ FIELDS,
+ Visitor {
+ marker: PhantomData::<JwkEcKey>,
+ lifetime: PhantomData,
+ },
+ )
+ }
+}
+
+impl Serialize for JwkEcKey {
+ fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
+ where
+ S: ser::Serializer,
+ {
+ use ser::SerializeStruct;
+
+ let mut state = serializer.serialize_struct(JWK_TYPE_NAME, 5)?;
+
+ for (i, field) in [EC_KTY, &self.crv, &self.x, &self.y].iter().enumerate() {
+ state.serialize_field(FIELDS[i], field)?;
+ }
+
+ if let Some(d) = &self.d {
+ state.serialize_field("d", d)?;
+ }
+
+ ser::SerializeStruct::end(state)
+ }
+}
+
+/// Decode a Base64url-encoded field element
+fn decode_base64url_fe<C: Curve>(s: &str) -> Result<FieldBytes<C>> {
+ let mut result = FieldBytes::<C>::default();
+ Base64Url::decode(s, &mut result).map_err(|_| Error)?;
+ Ok(result)
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[cfg(feature = "dev")]
+ use crate::dev::MockCurve;
+
+ /// Example private key. From RFC 7518 Appendix C:
+ /// <https://tools.ietf.org/html/rfc7518#appendix-C>
+ const JWK_PRIVATE_KEY: &str = r#"
+ {
+ "kty":"EC",
+ "crv":"P-256",
+ "x":"gI0GAILBdu7T53akrFmMyGcsF3n5dO7MmwNBHKW5SV0",
+ "y":"SLW_xSffzlPWrHEVI30DHM_4egVwt3NQqeUD7nMFpps",
+ "d":"0_NxaRPUMQoAJt50Gz8YiTr8gRTwyEaCumd-MToTmIo"
+ }
+ "#;
+
+ /// Example public key.
+ const JWK_PUBLIC_KEY: &str = r#"
+ {
+ "kty":"EC",
+ "crv":"P-256",
+ "x":"gI0GAILBdu7T53akrFmMyGcsF3n5dO7MmwNBHKW5SV0",
+ "y":"SLW_xSffzlPWrHEVI30DHM_4egVwt3NQqeUD7nMFpps"
+ }
+ "#;
+
+ /// Example unsupported JWK (RSA key)
+ const UNSUPPORTED_JWK: &str = r#"
+ {
+ "kty":"RSA",
+ "kid":"cc34c0a0-bd5a-4a3c-a50d-a2a7db7643df",
+ "use":"sig",
+ "n":"pjdss8ZaDfEH6K6U7GeW2nxDqR4IP049fk1fK0lndimbMMVBdPv_hSpm8T8EtBDxrUdi1OHZfMhUixGaut-3nQ4GG9nM249oxhCtxqqNvEXrmQRGqczyLxuh-fKn9Fg--hS9UpazHpfVAFnB5aCfXoNhPuI8oByyFKMKaOVgHNqP5NBEqabiLftZD3W_lsFCPGuzr4Vp0YS7zS2hDYScC2oOMu4rGU1LcMZf39p3153Cq7bS2Xh6Y-vw5pwzFYZdjQxDn8x8BG3fJ6j8TGLXQsbKH1218_HcUJRvMwdpbUQG5nvA2GXVqLqdwp054Lzk9_B_f1lVrmOKuHjTNHq48w",
+ "e":"AQAB",
+ "d":"ksDmucdMJXkFGZxiomNHnroOZxe8AmDLDGO1vhs-POa5PZM7mtUPonxwjVmthmpbZzla-kg55OFfO7YcXhg-Hm2OWTKwm73_rLh3JavaHjvBqsVKuorX3V3RYkSro6HyYIzFJ1Ek7sLxbjDRcDOj4ievSX0oN9l-JZhaDYlPlci5uJsoqro_YrE0PRRWVhtGynd-_aWgQv1YzkfZuMD-hJtDi1Im2humOWxA4eZrFs9eG-whXcOvaSwO4sSGbS99ecQZHM2TcdXeAs1PvjVgQ_dKnZlGN3lTWoWfQP55Z7Tgt8Nf1q4ZAKd-NlMe-7iqCFfsnFwXjSiaOa2CRGZn-Q",
+ "p":"4A5nU4ahEww7B65yuzmGeCUUi8ikWzv1C81pSyUKvKzu8CX41hp9J6oRaLGesKImYiuVQK47FhZ--wwfpRwHvSxtNU9qXb8ewo-BvadyO1eVrIk4tNV543QlSe7pQAoJGkxCia5rfznAE3InKF4JvIlchyqs0RQ8wx7lULqwnn0",
+ "q":"ven83GM6SfrmO-TBHbjTk6JhP_3CMsIvmSdo4KrbQNvp4vHO3w1_0zJ3URkmkYGhz2tgPlfd7v1l2I6QkIh4Bumdj6FyFZEBpxjE4MpfdNVcNINvVj87cLyTRmIcaGxmfylY7QErP8GFA-k4UoH_eQmGKGK44TRzYj5hZYGWIC8",
+ "dp":"lmmU_AG5SGxBhJqb8wxfNXDPJjf__i92BgJT2Vp4pskBbr5PGoyV0HbfUQVMnw977RONEurkR6O6gxZUeCclGt4kQlGZ-m0_XSWx13v9t9DIbheAtgVJ2mQyVDvK4m7aRYlEceFh0PsX8vYDS5o1txgPwb3oXkPTtrmbAGMUBpE",
+ "dq":"mxRTU3QDyR2EnCv0Nl0TCF90oliJGAHR9HJmBe__EjuCBbwHfcT8OG3hWOv8vpzokQPRl5cQt3NckzX3fs6xlJN4Ai2Hh2zduKFVQ2p-AF2p6Yfahscjtq-GY9cB85NxLy2IXCC0PF--Sq9LOrTE9QV988SJy_yUrAjcZ5MmECk",
+ "qi":"ldHXIrEmMZVaNwGzDF9WG8sHj2mOZmQpw9yrjLK9hAsmsNr5LTyqWAqJIYZSwPTYWhY4nu2O0EY9G9uYiqewXfCKw_UngrJt8Xwfq1Zruz0YY869zPN4GiE9-9rzdZB33RBw8kIOquY3MK74FMwCihYx_LiU2YTHkaoJ3ncvtvg"
+ }
+ "#;
+
+ #[test]
+ fn parse_private_key() {
+ let jwk = JwkEcKey::from_str(JWK_PRIVATE_KEY).unwrap();
+ assert_eq!(jwk.crv, "P-256");
+ assert_eq!(jwk.x, "gI0GAILBdu7T53akrFmMyGcsF3n5dO7MmwNBHKW5SV0");
+ assert_eq!(jwk.y, "SLW_xSffzlPWrHEVI30DHM_4egVwt3NQqeUD7nMFpps");
+ assert_eq!(
+ jwk.d.as_ref().unwrap(),
+ "0_NxaRPUMQoAJt50Gz8YiTr8gRTwyEaCumd-MToTmIo"
+ );
+ }
+
+ #[test]
+ fn parse_public_key() {
+ let jwk = JwkEcKey::from_str(JWK_PUBLIC_KEY).unwrap();
+ assert_eq!(jwk.crv, "P-256");
+ assert_eq!(jwk.x, "gI0GAILBdu7T53akrFmMyGcsF3n5dO7MmwNBHKW5SV0");
+ assert_eq!(jwk.y, "SLW_xSffzlPWrHEVI30DHM_4egVwt3NQqeUD7nMFpps");
+ assert_eq!(jwk.d, None);
+ }
+
+ #[test]
+ fn parse_unsupported() {
+ assert_eq!(JwkEcKey::from_str(UNSUPPORTED_JWK), Err(Error));
+ }
+
+ #[test]
+ fn serialize_private_key() {
+ let actual = JwkEcKey::from_str(JWK_PRIVATE_KEY).unwrap().to_string();
+ let expected: String = JWK_PRIVATE_KEY.split_whitespace().collect();
+ assert_eq!(actual, expected);
+ }
+
+ #[test]
+ fn serialize_public_key() {
+ let actual = JwkEcKey::from_str(JWK_PUBLIC_KEY).unwrap().to_string();
+ let expected: String = JWK_PUBLIC_KEY.split_whitespace().collect();
+ assert_eq!(actual, expected);
+ }
+
+ #[cfg(feature = "dev")]
+ #[test]
+ fn jwk_into_encoded_point() {
+ let jwk = JwkEcKey::from_str(JWK_PUBLIC_KEY).unwrap();
+ let point = jwk.to_encoded_point::<MockCurve>().unwrap();
+ let (x, y) = match point.coordinates() {
+ Coordinates::Uncompressed { x, y } => (x, y),
+ other => panic!("unexpected coordinates: {:?}", other),
+ };
+
+ assert_eq!(&decode_base64url_fe::<MockCurve>(&jwk.x).unwrap(), x);
+ assert_eq!(&decode_base64url_fe::<MockCurve>(&jwk.y).unwrap(), y);
+ }
+
+ #[cfg(feature = "dev")]
+ #[test]
+ fn encoded_point_into_jwk() {
+ let jwk = JwkEcKey::from_str(JWK_PUBLIC_KEY).unwrap();
+ let point = jwk.to_encoded_point::<MockCurve>().unwrap();
+ let jwk2 = JwkEcKey::from_encoded_point::<MockCurve>(&point).unwrap();
+ assert_eq!(jwk, jwk2);
+ }
+}
diff --git a/vendor/elliptic-curve/src/lib.rs b/vendor/elliptic-curve/src/lib.rs
new file mode 100644
index 000000000..62ac7856b
--- /dev/null
+++ b/vendor/elliptic-curve/src/lib.rs
@@ -0,0 +1,220 @@
+#![no_std]
+#![cfg_attr(docsrs, feature(doc_cfg))]
+#![doc = include_str!("../README.md")]
+#![doc(
+ html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg",
+ html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg"
+)]
+#![forbid(unsafe_code, clippy::unwrap_used)]
+#![warn(missing_docs, rust_2018_idioms, unused_qualifications)]
+
+//! ## Usage
+//!
+//! This crate provides traits for describing elliptic curves, along with
+//! types which are generic over elliptic curves which can be used as the
+//! basis of curve-agnostic code.
+//!
+//! It's intended to be used with the following concrete elliptic curve
+//! implementations from the [`RustCrypto/elliptic-curves`] project:
+//!
+//! - [`bp256`]: brainpoolP256r1 and brainpoolP256t1
+//! - [`bp384`]: brainpoolP384r1 and brainpoolP384t1
+//! - [`k256`]: secp256k1 a.k.a. K-256
+//! - [`p256`]: NIST P-256 a.k.a secp256r1, prime256v1
+//! - [`p384`]: NIST P-384 a.k.a. secp384r1
+//!
+//! The [`ecdsa`] crate provides a generic implementation of the
+//! Elliptic Curve Digital Signature Algorithm which can be used with any of
+//! the above crates, either via an external ECDSA implementation, or
+//! using native curve arithmetic where applicable.
+//!
+//! ## Type conversions
+//!
+//! The following chart illustrates the various conversions possible between
+//! the various types defined by this crate.
+//!
+//! ![Type Conversion Map](https://raw.githubusercontent.com/RustCrypto/media/master/img/elliptic-curve/type-transforms.svg)
+//!
+//! ## `serde` support
+//!
+//! When the `serde` feature of this crate is enabled, `Serialize` and
+//! `Deserialize` impls are provided for the following types:
+//!
+//! - [`JwkEcKey`]
+//! - [`PublicKey`]
+//! - [`ScalarCore`]
+//!
+//! Please see type-specific documentation for more information.
+//!
+//! [`RustCrypto/elliptic-curves`]: https://github.com/RustCrypto/elliptic-curves
+//! [`bp256`]: https://github.com/RustCrypto/elliptic-curves/tree/master/bp256
+//! [`bp384`]: https://github.com/RustCrypto/elliptic-curves/tree/master/bp384
+//! [`k256`]: https://github.com/RustCrypto/elliptic-curves/tree/master/k256
+//! [`p256`]: https://github.com/RustCrypto/elliptic-curves/tree/master/p256
+//! [`p384`]: https://github.com/RustCrypto/elliptic-curves/tree/master/p384
+//! [`ecdsa`]: https://github.com/RustCrypto/signatures/tree/master/ecdsa
+
+#[cfg(feature = "alloc")]
+#[allow(unused_imports)]
+#[macro_use]
+extern crate alloc;
+
+#[cfg(feature = "std")]
+extern crate std;
+
+#[cfg(feature = "rand_core")]
+#[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))]
+pub use rand_core;
+
+#[macro_use]
+mod macros;
+
+pub mod ops;
+
+#[cfg(feature = "dev")]
+#[cfg_attr(docsrs, doc(cfg(feature = "dev")))]
+pub mod dev;
+
+#[cfg(feature = "ecdh")]
+#[cfg_attr(docsrs, doc(cfg(feature = "ecdh")))]
+pub mod ecdh;
+
+#[cfg(feature = "hash2curve")]
+#[cfg_attr(docsrs, doc(cfg(feature = "hash2curve")))]
+pub mod hash2curve;
+
+#[cfg(feature = "sec1")]
+#[cfg_attr(docsrs, doc(cfg(feature = "sec1")))]
+pub mod sec1;
+
+#[cfg(feature = "arithmetic")]
+#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))]
+pub mod weierstrass;
+
+mod error;
+mod point;
+mod scalar;
+mod secret_key;
+
+#[cfg(feature = "arithmetic")]
+mod arithmetic;
+#[cfg(feature = "arithmetic")]
+mod public_key;
+
+#[cfg(feature = "jwk")]
+mod jwk;
+
+pub use crate::{
+ error::{Error, Result},
+ point::{
+ AffineXCoordinate, DecompactPoint, DecompressPoint, PointCompaction, PointCompression,
+ },
+ scalar::{core::ScalarCore, IsHigh},
+ secret_key::SecretKey,
+};
+pub use crypto_bigint as bigint;
+pub use generic_array::{self, typenum::consts};
+pub use rand_core;
+pub use subtle;
+pub use zeroize;
+
+#[cfg(feature = "arithmetic")]
+pub use {
+ crate::{
+ arithmetic::{
+ AffineArithmetic, PrimeCurveArithmetic, ProjectiveArithmetic, ScalarArithmetic,
+ },
+ public_key::PublicKey,
+ scalar::{nonzero::NonZeroScalar, Scalar},
+ },
+ ff::{self, Field, PrimeField},
+ group::{self, Group},
+};
+
+#[cfg(feature = "bits")]
+pub use crate::scalar::ScalarBits;
+
+#[cfg(feature = "jwk")]
+pub use crate::jwk::{JwkEcKey, JwkParameters};
+
+#[cfg(feature = "pkcs8")]
+pub use pkcs8;
+
+use core::fmt::Debug;
+use generic_array::GenericArray;
+
+/// Algorithm [`ObjectIdentifier`][`pkcs8::ObjectIdentifier`] for elliptic
+/// curve public key cryptography (`id-ecPublicKey`).
+///
+/// <http://oid-info.com/get/1.2.840.10045.2.1>
+#[cfg(feature = "pkcs8")]
+#[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))]
+pub const ALGORITHM_OID: pkcs8::ObjectIdentifier =
+ pkcs8::ObjectIdentifier::new_unwrap("1.2.840.10045.2.1");
+
+/// Elliptic curve.
+///
+/// This trait is intended to be impl'd by a ZST which represents a concrete
+/// elliptic curve.
+///
+/// Other traits in this crate which are bounded by [`Curve`] are intended to
+/// be impl'd by these ZSTs, facilitating types which are generic over elliptic
+/// curves (e.g. [`SecretKey`]).
+pub trait Curve: 'static + Copy + Clone + Debug + Default + Eq + Ord + Send + Sync {
+ /// Integer type used to represent field elements of this elliptic curve.
+ // TODO(tarcieri): replace this with an e.g. `const Curve::MODULUS: UInt`.
+ // Requires rust-lang/rust#60551, i.e. `const_evaluatable_checked`
+ type UInt: bigint::AddMod<Output = Self::UInt>
+ + bigint::ArrayEncoding
+ + bigint::Encoding
+ + bigint::Integer
+ + bigint::NegMod<Output = Self::UInt>
+ + bigint::Random
+ + bigint::RandomMod
+ + bigint::SubMod<Output = Self::UInt>
+ + zeroize::Zeroize;
+
+ /// Order constant.
+ ///
+ /// Subdivided into either 32-bit or 64-bit "limbs" (depending on the
+ /// target CPU's word size), specified from least to most significant.
+ const ORDER: Self::UInt;
+}
+
+/// Marker trait for elliptic curves with prime order.
+pub trait PrimeCurve: Curve {}
+
+/// Size of field elements of this elliptic curve.
+pub type FieldSize<C> = <<C as Curve>::UInt as bigint::ArrayEncoding>::ByteSize;
+
+/// Byte representation of a base/scalar field element of a given curve.
+pub type FieldBytes<C> = GenericArray<u8, FieldSize<C>>;
+
+/// Affine point type for a given curve with a [`ProjectiveArithmetic`]
+/// implementation.
+#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))]
+#[cfg(feature = "arithmetic")]
+pub type AffinePoint<C> = <C as AffineArithmetic>::AffinePoint;
+
+/// Projective point type for a given curve with a [`ProjectiveArithmetic`]
+/// implementation.
+#[cfg(feature = "arithmetic")]
+#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))]
+pub type ProjectivePoint<C> = <C as ProjectiveArithmetic>::ProjectivePoint;
+
+/// Elliptic curve parameters used by VOPRF.
+#[cfg(feature = "voprf")]
+#[cfg_attr(docsrs, doc(cfg(feature = "voprf")))]
+pub trait VoprfParameters: Curve {
+ /// The `ID` parameter which identifies a particular elliptic curve
+ /// as defined in [section 4 of `draft-irtf-cfrg-voprf-08`][voprf].
+ ///
+ /// [voprf]: https://www.ietf.org/archive/id/draft-irtf-cfrg-voprf-08.html#section-4
+ const ID: u16;
+
+ /// The `Hash` parameter which assigns a particular hash function to this
+ /// ciphersuite as defined in [section 4 of `draft-irtf-cfrg-voprf-08`][voprf].
+ ///
+ /// [voprf]: https://www.ietf.org/archive/id/draft-irtf-cfrg-voprf-08.html#section-4
+ type Hash: digest::Digest;
+}
diff --git a/vendor/elliptic-curve/src/macros.rs b/vendor/elliptic-curve/src/macros.rs
new file mode 100644
index 000000000..6ceadc833
--- /dev/null
+++ b/vendor/elliptic-curve/src/macros.rs
@@ -0,0 +1,440 @@
+/// Provides both inherent and trait impls for a field element type which are
+/// backed by a core set of arithmetic functions specified as macro arguments.
+///
+/// # Inherent impls
+/// - `const ZERO: Self`
+/// - `const ONE: Self` (multiplicative identity)
+/// - `pub fn from_be_bytes`
+/// - `pub fn from_be_slice`
+/// - `pub fn from_le_bytes`
+/// - `pub fn from_le_slice`
+/// - `pub fn from_uint`
+/// - `fn from_uint_unchecked`
+/// - `pub fn to_be_bytes`
+/// - `pub fn to_le_bytes`
+/// - `pub fn to_canonical`
+/// - `pub fn is_odd`
+/// - `pub fn is_zero`
+/// - `pub fn double`
+///
+/// NOTE: field implementations must provide their own inherent impls of
+/// the following methods in order for the code generated by this macro to
+/// compile:
+///
+/// - `pub fn invert`
+/// - `pub fn sqrt`
+///
+/// # Trait impls
+/// - `AsRef<$arr>`
+/// - `ConditionallySelectable`
+/// - `ConstantTimeEq`
+/// - `ConstantTimeGreater`
+/// - `ConstantTimeLess`
+/// - `Default`
+/// - `DefaultIsZeroes`
+/// - `Eq`
+/// - `Field`
+/// - `PartialEq`
+///
+/// ## Ops
+/// - `Add`
+/// - `AddAssign`
+/// - `Sub`
+/// - `SubAssign`
+/// - `Mul`
+/// - `MulAssign`
+/// - `Neg`
+#[macro_export]
+macro_rules! impl_field_element {
+ (
+ $fe:tt,
+ $bytes:ty,
+ $uint:ty,
+ $modulus:expr,
+ $arr:ty,
+ $from_mont:ident,
+ $to_mont:ident,
+ $add:ident,
+ $sub:ident,
+ $mul:ident,
+ $neg:ident,
+ $square:ident
+ ) => {
+ impl $fe {
+ /// Zero element.
+ pub const ZERO: Self = Self(<$uint>::ZERO);
+
+ /// Multiplicative identity.
+ pub const ONE: Self = Self::from_uint_unchecked(<$uint>::ONE);
+
+ /// Create a [`
+ #[doc = stringify!($fe)]
+ /// `] from a canonical big-endian representation.
+ pub fn from_be_bytes(repr: $bytes) -> $crate::subtle::CtOption<Self> {
+ use $crate::bigint::ArrayEncoding as _;
+ Self::from_uint(<$uint>::from_be_byte_array(repr))
+ }
+
+ /// Decode [`
+ #[doc = stringify!($fe)]
+ /// `] from a big endian byte slice.
+ pub fn from_be_slice(slice: &[u8]) -> $crate::Result<Self> {
+ <$uint as $crate::bigint::Encoding>::Repr::try_from(slice)
+ .ok()
+ .and_then(|array| Self::from_be_bytes(array.into()).into())
+ .ok_or($crate::Error)
+ }
+
+ /// Create a [`
+ #[doc = stringify!($fe)]
+ /// `] from a canonical little-endian representation.
+ pub fn from_le_bytes(repr: $bytes) -> $crate::subtle::CtOption<Self> {
+ use $crate::bigint::ArrayEncoding as _;
+ Self::from_uint(<$uint>::from_le_byte_array(repr))
+ }
+
+ /// Decode [`
+ #[doc = stringify!($fe)]
+ /// `] from a little endian byte slice.
+ pub fn from_le_slice(slice: &[u8]) -> $crate::Result<Self> {
+ <$uint as $crate::bigint::Encoding>::Repr::try_from(slice)
+ .ok()
+ .and_then(|array| Self::from_le_bytes(array.into()).into())
+ .ok_or($crate::Error)
+ }
+
+ /// Decode [`
+ #[doc = stringify!($fe)]
+ /// `]
+ /// from [`
+ #[doc = stringify!($uint)]
+ /// `] converting it into Montgomery form:
+ ///
+ /// ```text
+ /// w * R^2 * R^-1 mod p = wR mod p
+ /// ```
+ pub fn from_uint(uint: $uint) -> $crate::subtle::CtOption<Self> {
+ use $crate::subtle::ConstantTimeLess as _;
+ let is_some = uint.ct_lt(&$modulus);
+ $crate::subtle::CtOption::new(Self::from_uint_unchecked(uint), is_some)
+ }
+
+ /// Parse a [`
+ #[doc = stringify!($fe)]
+ /// `] from big endian hex-encoded bytes.
+ ///
+ /// Does *not* perform a check that the field element does not overflow the order.
+ ///
+ /// This method is primarily intended for defining internal constants.
+ #[allow(dead_code)]
+ pub(crate) const fn from_be_hex(hex: &str) -> Self {
+ Self::from_uint_unchecked(<$uint>::from_be_hex(hex))
+ }
+
+ /// Parse a [`
+ #[doc = stringify!($fe)]
+ /// `] from little endian hex-encoded bytes.
+ ///
+ /// Does *not* perform a check that the field element does not overflow the order.
+ ///
+ /// This method is primarily intended for defining internal constants.
+ #[allow(dead_code)]
+ pub(crate) const fn from_le_hex(hex: &str) -> Self {
+ Self::from_uint_unchecked(<$uint>::from_le_hex(hex))
+ }
+
+ /// Decode [`
+ #[doc = stringify!($fe)]
+ /// `] from [`
+ #[doc = stringify!($uint)]
+ /// `] converting it into Montgomery form.
+ ///
+ /// Does *not* perform a check that the field element does not overflow the order.
+ ///
+ /// Used incorrectly this can lead to invalid results!
+ pub(crate) const fn from_uint_unchecked(w: $uint) -> Self {
+ Self(<$uint>::from_words($to_mont(w.as_words())))
+ }
+
+ /// Returns the big-endian encoding of this [`
+ #[doc = stringify!($fe)]
+ /// `].
+ pub fn to_be_bytes(self) -> $bytes {
+ use $crate::bigint::ArrayEncoding as _;
+ self.to_canonical().to_be_byte_array()
+ }
+
+ /// Returns the little-endian encoding of this [`
+ #[doc = stringify!($fe)]
+ /// `].
+ pub fn to_le_bytes(self) -> $bytes {
+ use $crate::bigint::ArrayEncoding as _;
+ self.to_canonical().to_le_byte_array()
+ }
+
+ /// Translate [`
+ #[doc = stringify!($fe)]
+ /// `] out of the Montgomery domain, returning a [`
+ #[doc = stringify!($uint)]
+ /// `] in canonical form.
+ #[inline]
+ pub const fn to_canonical(self) -> $uint {
+ <$uint>::from_words($from_mont(self.0.as_words()))
+ }
+
+ /// Determine if this [`
+ #[doc = stringify!($fe)]
+ /// `] is odd in the SEC1 sense: `self mod 2 == 1`.
+ ///
+ /// # Returns
+ ///
+ /// If odd, return `Choice(1)`. Otherwise, return `Choice(0)`.
+ pub fn is_odd(&self) -> Choice {
+ use $crate::bigint::Integer;
+ self.to_canonical().is_odd()
+ }
+
+ /// Determine if this [`
+ #[doc = stringify!($fe)]
+ /// `] is even in the SEC1 sense: `self mod 2 == 0`.
+ ///
+ /// # Returns
+ ///
+ /// If even, return `Choice(1)`. Otherwise, return `Choice(0)`.
+ pub fn is_even(&self) -> Choice {
+ !self.is_odd()
+ }
+
+ /// Determine if this [`
+ #[doc = stringify!($fe)]
+ /// `] is zero.
+ ///
+ /// # Returns
+ ///
+ /// If zero, return `Choice(1)`. Otherwise, return `Choice(0)`.
+ pub fn is_zero(&self) -> Choice {
+ self.ct_eq(&Self::ZERO)
+ }
+
+ /// Add elements.
+ pub const fn add(&self, rhs: &Self) -> Self {
+ Self(<$uint>::from_words($add(
+ self.0.as_words(),
+ rhs.0.as_words(),
+ )))
+ }
+
+ /// Double element (add it to itself).
+ #[must_use]
+ pub const fn double(&self) -> Self {
+ self.add(self)
+ }
+
+ /// Subtract elements.
+ pub const fn sub(&self, rhs: &Self) -> Self {
+ Self(<$uint>::from_words($sub(
+ self.0.as_words(),
+ rhs.0.as_words(),
+ )))
+ }
+
+ /// Multiply elements.
+ pub const fn mul(&self, rhs: &Self) -> Self {
+ Self(<$uint>::from_words($mul(
+ self.0.as_words(),
+ rhs.0.as_words(),
+ )))
+ }
+
+ /// Negate element.
+ pub const fn neg(&self) -> Self {
+ Self(<$uint>::from_words($neg(self.0.as_words())))
+ }
+
+ /// Compute modular square.
+ #[must_use]
+ pub const fn square(&self) -> Self {
+ Self(<$uint>::from_words($square(self.0.as_words())))
+ }
+ }
+
+ impl AsRef<$arr> for $fe {
+ fn as_ref(&self) -> &$arr {
+ self.0.as_ref()
+ }
+ }
+
+ impl Default for $fe {
+ fn default() -> Self {
+ Self::ZERO
+ }
+ }
+
+ impl Eq for $fe {}
+
+ impl PartialEq for $fe {
+ fn eq(&self, rhs: &Self) -> bool {
+ self.0.ct_eq(&(rhs.0)).into()
+ }
+ }
+
+ impl $crate::subtle::ConditionallySelectable for $fe {
+ fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
+ Self(<$uint>::conditional_select(&a.0, &b.0, choice))
+ }
+ }
+
+ impl $crate::subtle::ConstantTimeEq for $fe {
+ fn ct_eq(&self, other: &Self) -> $crate::subtle::Choice {
+ self.0.ct_eq(&other.0)
+ }
+ }
+
+ impl $crate::subtle::ConstantTimeGreater for $fe {
+ fn ct_gt(&self, other: &Self) -> $crate::subtle::Choice {
+ self.0.ct_gt(&other.0)
+ }
+ }
+
+ impl $crate::subtle::ConstantTimeLess for $fe {
+ fn ct_lt(&self, other: &Self) -> $crate::subtle::Choice {
+ self.0.ct_lt(&other.0)
+ }
+ }
+
+ impl $crate::zeroize::DefaultIsZeroes for $fe {}
+
+ impl $crate::ff::Field for $fe {
+ fn random(mut rng: impl $crate::rand_core::RngCore) -> Self {
+ // NOTE: can't use ScalarCore::random due to CryptoRng bound
+ let mut bytes = <$bytes>::default();
+
+ loop {
+ rng.fill_bytes(&mut bytes);
+ if let Some(fe) = Self::from_be_bytes(bytes).into() {
+ return fe;
+ }
+ }
+ }
+
+ fn zero() -> Self {
+ Self::ZERO
+ }
+
+ fn one() -> Self {
+ Self::ONE
+ }
+
+ fn is_zero(&self) -> Choice {
+ Self::ZERO.ct_eq(self)
+ }
+
+ #[must_use]
+ fn square(&self) -> Self {
+ self.square()
+ }
+
+ #[must_use]
+ fn double(&self) -> Self {
+ self.double()
+ }
+
+ fn invert(&self) -> CtOption<Self> {
+ self.invert()
+ }
+
+ fn sqrt(&self) -> CtOption<Self> {
+ self.sqrt()
+ }
+ }
+
+ $crate::impl_field_op!($fe, $uint, Add, add, $add);
+ $crate::impl_field_op!($fe, $uint, Sub, sub, $sub);
+ $crate::impl_field_op!($fe, $uint, Mul, mul, $mul);
+
+ impl AddAssign<$fe> for $fe {
+ #[inline]
+ fn add_assign(&mut self, other: $fe) {
+ *self = *self + other;
+ }
+ }
+
+ impl AddAssign<&$fe> for $fe {
+ #[inline]
+ fn add_assign(&mut self, other: &$fe) {
+ *self = *self + other;
+ }
+ }
+
+ impl SubAssign<$fe> for $fe {
+ #[inline]
+ fn sub_assign(&mut self, other: $fe) {
+ *self = *self - other;
+ }
+ }
+
+ impl SubAssign<&$fe> for $fe {
+ #[inline]
+ fn sub_assign(&mut self, other: &$fe) {
+ *self = *self - other;
+ }
+ }
+
+ impl MulAssign<&$fe> for $fe {
+ #[inline]
+ fn mul_assign(&mut self, other: &$fe) {
+ *self = *self * other;
+ }
+ }
+
+ impl MulAssign for $fe {
+ #[inline]
+ fn mul_assign(&mut self, other: $fe) {
+ *self = *self * other;
+ }
+ }
+
+ impl Neg for $fe {
+ type Output = $fe;
+
+ #[inline]
+ fn neg(self) -> $fe {
+ Self($neg(self.as_ref()).into())
+ }
+ }
+ };
+}
+
+/// Emit impls for a `core::ops` trait for all combinations of reference types,
+/// which thunk to the given function.
+#[macro_export]
+macro_rules! impl_field_op {
+ ($fe:tt, $uint:ty, $op:tt, $op_fn:ident, $func:ident) => {
+ impl ::core::ops::$op for $fe {
+ type Output = $fe;
+
+ #[inline]
+ fn $op_fn(self, rhs: $fe) -> $fe {
+ $fe($func(self.as_ref(), rhs.as_ref()).into())
+ }
+ }
+
+ impl ::core::ops::$op<&$fe> for $fe {
+ type Output = $fe;
+
+ #[inline]
+ fn $op_fn(self, rhs: &$fe) -> $fe {
+ $fe($func(self.as_ref(), rhs.as_ref()).into())
+ }
+ }
+
+ impl ::core::ops::$op<&$fe> for &$fe {
+ type Output = $fe;
+
+ #[inline]
+ fn $op_fn(self, rhs: &$fe) -> $fe {
+ $fe($func(self.as_ref(), rhs.as_ref()).into())
+ }
+ }
+ };
+}
diff --git a/vendor/elliptic-curve/src/ops.rs b/vendor/elliptic-curve/src/ops.rs
new file mode 100644
index 000000000..580c5aefc
--- /dev/null
+++ b/vendor/elliptic-curve/src/ops.rs
@@ -0,0 +1,96 @@
+//! Traits for arithmetic operations on elliptic curve field elements.
+
+pub use core::ops::{Add, AddAssign, Mul, Neg, Sub, SubAssign};
+
+use crypto_bigint::{ArrayEncoding, ByteArray, Integer};
+
+#[cfg(feature = "arithmetic")]
+use {group::Group, subtle::CtOption};
+
+#[cfg(feature = "digest")]
+use digest::FixedOutput;
+
+/// Perform an inversion on a field element (i.e. base field element or scalar)
+pub trait Invert {
+ /// Field element type
+ type Output;
+
+ /// Invert a field element.
+ fn invert(&self) -> Self::Output;
+}
+
+#[cfg(feature = "arithmetic")]
+impl<F: ff::Field> Invert for F {
+ type Output = CtOption<F>;
+
+ fn invert(&self) -> CtOption<F> {
+ ff::Field::invert(self)
+ }
+}
+
+/// Linear combination.
+///
+/// This trait enables crates to provide an optimized implementation of
+/// linear combinations (e.g. Shamir's Trick), or otherwise provides a default
+/// non-optimized implementation.
+// TODO(tarcieri): replace this with a trait from the `group` crate? (see zkcrypto/group#25)
+#[cfg(feature = "arithmetic")]
+#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))]
+pub trait LinearCombination: Group {
+ /// Calculates `x * k + y * l`.
+ fn lincomb(x: &Self, k: &Self::Scalar, y: &Self, l: &Self::Scalar) -> Self {
+ (*x * k) + (*y * l)
+ }
+}
+
+/// Modular reduction.
+pub trait Reduce<UInt: Integer + ArrayEncoding>: Sized {
+ /// Perform a modular reduction, returning a field element.
+ fn from_uint_reduced(n: UInt) -> Self;
+
+ /// Interpret the given byte array as a big endian integer and perform
+ /// a modular reduction.
+ fn from_be_bytes_reduced(bytes: ByteArray<UInt>) -> Self {
+ Self::from_uint_reduced(UInt::from_be_byte_array(bytes))
+ }
+
+ /// Interpret the given byte array as a little endian integer and perform a
+ /// modular reduction.
+ fn from_le_bytes_reduced(bytes: ByteArray<UInt>) -> Self {
+ Self::from_uint_reduced(UInt::from_le_byte_array(bytes))
+ }
+
+ /// Interpret a digest as a big endian integer and perform a modular
+ /// reduction.
+ #[cfg(feature = "digest")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "digest")))]
+ fn from_be_digest_reduced<D>(digest: D) -> Self
+ where
+ D: FixedOutput<OutputSize = UInt::ByteSize>,
+ {
+ Self::from_be_bytes_reduced(digest.finalize_fixed())
+ }
+
+ /// Interpret a digest as a little endian integer and perform a modular
+ /// reduction.
+ #[cfg(feature = "digest")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "digest")))]
+ fn from_le_digest_reduced<D>(digest: D) -> Self
+ where
+ D: FixedOutput<OutputSize = UInt::ByteSize>,
+ {
+ Self::from_le_bytes_reduced(digest.finalize_fixed())
+ }
+}
+
+/// Modular reduction to a non-zero output.
+///
+/// This trait is primarily intended for use by curve implementations such
+/// as the `k256` and `p256` crates.
+///
+/// End users should use the [`Reduce`] impl on
+/// [`NonZeroScalar`][`crate::NonZeroScalar`] instead.
+pub trait ReduceNonZero<UInt: Integer + ArrayEncoding>: Sized {
+ /// Perform a modular reduction, returning a field element.
+ fn from_uint_reduced_nonzero(n: UInt) -> Self;
+}
diff --git a/vendor/elliptic-curve/src/point.rs b/vendor/elliptic-curve/src/point.rs
new file mode 100644
index 000000000..7257be66c
--- /dev/null
+++ b/vendor/elliptic-curve/src/point.rs
@@ -0,0 +1,40 @@
+//! Traits for elliptic curve points.
+
+use crate::{Curve, FieldBytes};
+use subtle::{Choice, CtOption};
+
+/// Obtain the affine x-coordinate of an elliptic curve point.
+pub trait AffineXCoordinate<C: Curve> {
+ /// Get the affine x-coordinate as a serialized field element.
+ fn x(&self) -> FieldBytes<C>;
+}
+
+/// Decompress an elliptic curve point.
+///
+/// Point decompression recovers an original curve point from its x-coordinate
+/// and a boolean flag indicating whether or not the y-coordinate is odd.
+pub trait DecompressPoint<C: Curve>: Sized {
+ /// Attempt to decompress an elliptic curve point.
+ fn decompress(x: &FieldBytes<C>, y_is_odd: Choice) -> CtOption<Self>;
+}
+
+/// Decompact an elliptic curve point from an x-coordinate.
+///
+/// Decompaction relies on properties of specially-generated keys but provides
+/// a more compact representation than standard point compression.
+pub trait DecompactPoint<C: Curve>: Sized {
+ /// Attempt to decompact an elliptic curve point
+ fn decompact(x: &FieldBytes<C>) -> CtOption<Self>;
+}
+
+/// Point compression settings.
+pub trait PointCompression {
+ /// Should point compression be applied by default?
+ const COMPRESS_POINTS: bool;
+}
+
+/// Point compaction settings.
+pub trait PointCompaction {
+ /// Should point compaction be applied by default?
+ const COMPACT_POINTS: bool;
+}
diff --git a/vendor/elliptic-curve/src/public_key.rs b/vendor/elliptic-curve/src/public_key.rs
new file mode 100644
index 000000000..1dc858581
--- /dev/null
+++ b/vendor/elliptic-curve/src/public_key.rs
@@ -0,0 +1,411 @@
+//! Elliptic curve public keys.
+
+use crate::{
+ AffinePoint, Curve, Error, NonZeroScalar, ProjectiveArithmetic, ProjectivePoint, Result,
+};
+use core::fmt::Debug;
+use group::{Curve as _, Group};
+
+#[cfg(feature = "jwk")]
+use crate::{JwkEcKey, JwkParameters};
+
+#[cfg(all(feature = "sec1", feature = "pkcs8"))]
+use crate::{
+ pkcs8::{self, AssociatedOid, DecodePublicKey},
+ ALGORITHM_OID,
+};
+
+#[cfg(feature = "pem")]
+use core::str::FromStr;
+
+#[cfg(feature = "sec1")]
+use {
+ crate::{
+ sec1::{EncodedPoint, FromEncodedPoint, ModulusSize, ToEncodedPoint},
+ FieldSize, PointCompression,
+ },
+ core::cmp::Ordering,
+ subtle::CtOption,
+};
+
+#[cfg(feature = "serde")]
+use serdect::serde::{de, ser, Deserialize, Serialize};
+
+#[cfg(all(feature = "alloc", feature = "pkcs8"))]
+use pkcs8::EncodePublicKey;
+
+#[cfg(any(feature = "jwk", feature = "pem"))]
+use alloc::string::{String, ToString};
+
+/// Elliptic curve public keys.
+///
+/// This is a wrapper type for [`AffinePoint`] which ensures an inner
+/// non-identity point and provides a common place to handle encoding/decoding.
+///
+/// # Parsing "SPKI" Keys
+///
+/// X.509 `SubjectPublicKeyInfo` (SPKI) is a commonly used format for encoding
+/// public keys, notably public keys corresponding to PKCS#8 private keys.
+/// (especially ones generated by OpenSSL).
+///
+/// Keys in SPKI format are either binary (ASN.1 BER/DER), or PEM encoded
+/// (ASCII) and begin with the following:
+///
+/// ```text
+/// -----BEGIN PUBLIC KEY-----
+/// ```
+///
+/// To decode an elliptic curve public key from SPKI, enable the `pkcs8`
+/// feature of this crate (or the `pkcs8` feature of a specific RustCrypto
+/// elliptic curve crate) and use the
+/// [`elliptic_curve::pkcs8::DecodePublicKey`][`pkcs8::DecodePublicKey`]
+/// trait to parse it.
+///
+/// When the `pem` feature of this crate (or a specific RustCrypto elliptic
+/// curve crate) is enabled, a [`FromStr`] impl is also available.
+///
+/// # `serde` support
+///
+/// When the optional `serde` feature of this create is enabled, [`Serialize`]
+/// and [`Deserialize`] impls are provided for this type.
+///
+/// The serialization is binary-oriented and supports ASN.1 DER
+/// Subject Public Key Info (SPKI) as the encoding format.
+///
+/// For a more text-friendly encoding of public keys, use [`JwkEcKey`] instead.
+#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))]
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct PublicKey<C>
+where
+ C: Curve + ProjectiveArithmetic,
+{
+ point: AffinePoint<C>,
+}
+
+impl<C> PublicKey<C>
+where
+ C: Curve + ProjectiveArithmetic,
+{
+ /// Convert an [`AffinePoint`] into a [`PublicKey`]
+ pub fn from_affine(point: AffinePoint<C>) -> Result<Self> {
+ if ProjectivePoint::<C>::from(point).is_identity().into() {
+ Err(Error)
+ } else {
+ Ok(Self { point })
+ }
+ }
+
+ /// Compute a [`PublicKey`] from a secret [`NonZeroScalar`] value
+ /// (i.e. a secret key represented as a raw scalar value)
+ pub fn from_secret_scalar(scalar: &NonZeroScalar<C>) -> Self {
+ // `NonZeroScalar` ensures the resulting point is not the identity
+ Self {
+ point: (C::ProjectivePoint::generator() * scalar.as_ref()).to_affine(),
+ }
+ }
+
+ /// Decode [`PublicKey`] (compressed or uncompressed) from the
+ /// `Elliptic-Curve-Point-to-Octet-String` encoding described in
+ /// SEC 1: Elliptic Curve Cryptography (Version 2.0) section
+ /// 2.3.3 (page 10).
+ ///
+ /// <http://www.secg.org/sec1-v2.pdf>
+ #[cfg(feature = "sec1")]
+ pub fn from_sec1_bytes(bytes: &[u8]) -> Result<Self>
+ where
+ C: Curve,
+ FieldSize<C>: ModulusSize,
+ AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
+ {
+ let point = EncodedPoint::<C>::from_bytes(bytes).map_err(|_| Error)?;
+ Option::from(Self::from_encoded_point(&point)).ok_or(Error)
+ }
+
+ /// Borrow the inner [`AffinePoint`] from this [`PublicKey`].
+ ///
+ /// In ECC, public keys are elliptic curve points.
+ pub fn as_affine(&self) -> &AffinePoint<C> {
+ &self.point
+ }
+
+ /// Convert this [`PublicKey`] to a [`ProjectivePoint`] for the given curve
+ pub fn to_projective(&self) -> ProjectivePoint<C> {
+ self.point.into()
+ }
+
+ /// Parse a [`JwkEcKey`] JSON Web Key (JWK) into a [`PublicKey`].
+ #[cfg(feature = "jwk")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))]
+ pub fn from_jwk(jwk: &JwkEcKey) -> Result<Self>
+ where
+ C: Curve + JwkParameters,
+ AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
+ FieldSize<C>: ModulusSize,
+ {
+ jwk.to_public_key::<C>()
+ }
+
+ /// Parse a string containing a JSON Web Key (JWK) into a [`PublicKey`].
+ #[cfg(feature = "jwk")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))]
+ pub fn from_jwk_str(jwk: &str) -> Result<Self>
+ where
+ C: Curve + JwkParameters,
+ AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
+ FieldSize<C>: ModulusSize,
+ {
+ jwk.parse::<JwkEcKey>().and_then(|jwk| Self::from_jwk(&jwk))
+ }
+
+ /// Serialize this public key as [`JwkEcKey`] JSON Web Key (JWK).
+ #[cfg(feature = "jwk")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))]
+ pub fn to_jwk(&self) -> JwkEcKey
+ where
+ C: Curve + JwkParameters,
+ AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
+ FieldSize<C>: ModulusSize,
+ {
+ self.into()
+ }
+
+ /// Serialize this public key as JSON Web Key (JWK) string.
+ #[cfg(feature = "jwk")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))]
+ pub fn to_jwk_string(&self) -> String
+ where
+ C: Curve + JwkParameters,
+ AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
+ FieldSize<C>: ModulusSize,
+ {
+ self.to_jwk().to_string()
+ }
+}
+
+impl<C> AsRef<AffinePoint<C>> for PublicKey<C>
+where
+ C: Curve + ProjectiveArithmetic,
+{
+ fn as_ref(&self) -> &AffinePoint<C> {
+ self.as_affine()
+ }
+}
+
+impl<C> Copy for PublicKey<C> where C: Curve + ProjectiveArithmetic {}
+
+#[cfg(feature = "sec1")]
+#[cfg_attr(docsrs, doc(cfg(feature = "sec1")))]
+impl<C> FromEncodedPoint<C> for PublicKey<C>
+where
+ C: Curve + ProjectiveArithmetic,
+ AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
+ FieldSize<C>: ModulusSize,
+{
+ /// Initialize [`PublicKey`] from an [`EncodedPoint`]
+ fn from_encoded_point(encoded_point: &EncodedPoint<C>) -> CtOption<Self> {
+ AffinePoint::<C>::from_encoded_point(encoded_point).and_then(|point| {
+ let is_identity = ProjectivePoint::<C>::from(point).is_identity();
+ CtOption::new(PublicKey { point }, !is_identity)
+ })
+ }
+}
+
+#[cfg(feature = "sec1")]
+#[cfg_attr(docsrs, doc(cfg(feature = "sec1")))]
+impl<C> ToEncodedPoint<C> for PublicKey<C>
+where
+ C: Curve + ProjectiveArithmetic,
+ AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
+ FieldSize<C>: ModulusSize,
+{
+ /// Serialize this [`PublicKey`] as a SEC1 [`EncodedPoint`], optionally applying
+ /// point compression
+ fn to_encoded_point(&self, compress: bool) -> EncodedPoint<C> {
+ self.point.to_encoded_point(compress)
+ }
+}
+
+#[cfg(feature = "sec1")]
+#[cfg_attr(docsrs, doc(cfg(feature = "sec1")))]
+impl<C> From<PublicKey<C>> for EncodedPoint<C>
+where
+ C: Curve + ProjectiveArithmetic + PointCompression,
+ AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
+ FieldSize<C>: ModulusSize,
+{
+ fn from(public_key: PublicKey<C>) -> EncodedPoint<C> {
+ EncodedPoint::<C>::from(&public_key)
+ }
+}
+
+#[cfg(feature = "sec1")]
+#[cfg_attr(docsrs, doc(cfg(feature = "sec1")))]
+impl<C> From<&PublicKey<C>> for EncodedPoint<C>
+where
+ C: Curve + ProjectiveArithmetic + PointCompression,
+ AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
+ FieldSize<C>: ModulusSize,
+{
+ fn from(public_key: &PublicKey<C>) -> EncodedPoint<C> {
+ public_key.to_encoded_point(C::COMPRESS_POINTS)
+ }
+}
+
+#[cfg(feature = "sec1")]
+#[cfg_attr(docsrs, doc(cfg(feature = "sec1")))]
+impl<C> PartialOrd for PublicKey<C>
+where
+ C: Curve + ProjectiveArithmetic,
+ AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
+ FieldSize<C>: ModulusSize,
+{
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ Some(self.cmp(other))
+ }
+}
+
+#[cfg(feature = "sec1")]
+#[cfg_attr(docsrs, doc(cfg(feature = "sec1")))]
+impl<C> Ord for PublicKey<C>
+where
+ C: Curve + ProjectiveArithmetic,
+ AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
+ FieldSize<C>: ModulusSize,
+{
+ fn cmp(&self, other: &Self) -> Ordering {
+ // TODO(tarcieri): more efficient implementation?
+ // This is implemented this way to reduce bounds for `AffinePoint<C>`
+ self.to_encoded_point(false)
+ .cmp(&other.to_encoded_point(false))
+ }
+}
+
+#[cfg(all(feature = "pkcs8", feature = "sec1"))]
+#[cfg_attr(docsrs, doc(cfg(all(feature = "pkcs8", feature = "sec1"))))]
+impl<C> TryFrom<pkcs8::SubjectPublicKeyInfo<'_>> for PublicKey<C>
+where
+ C: Curve + AssociatedOid + ProjectiveArithmetic,
+ AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
+ FieldSize<C>: ModulusSize,
+{
+ type Error = pkcs8::spki::Error;
+
+ fn try_from(spki: pkcs8::SubjectPublicKeyInfo<'_>) -> pkcs8::spki::Result<Self> {
+ spki.algorithm.assert_oids(ALGORITHM_OID, C::OID)?;
+ Self::from_sec1_bytes(spki.subject_public_key)
+ .map_err(|_| der::Tag::BitString.value_error().into())
+ }
+}
+
+#[cfg(all(feature = "pkcs8", feature = "sec1"))]
+#[cfg_attr(docsrs, doc(cfg(all(feature = "pkcs8", feature = "sec1"))))]
+impl<C> DecodePublicKey for PublicKey<C>
+where
+ C: Curve + AssociatedOid + ProjectiveArithmetic,
+ AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
+ FieldSize<C>: ModulusSize,
+{
+}
+
+#[cfg(all(feature = "alloc", feature = "pkcs8"))]
+#[cfg_attr(docsrs, doc(cfg(all(feature = "alloc", feature = "pkcs8"))))]
+impl<C> EncodePublicKey for PublicKey<C>
+where
+ C: Curve + AssociatedOid + ProjectiveArithmetic,
+ AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
+ FieldSize<C>: ModulusSize,
+{
+ fn to_public_key_der(&self) -> pkcs8::spki::Result<der::Document> {
+ let algorithm = pkcs8::AlgorithmIdentifier {
+ oid: ALGORITHM_OID,
+ parameters: Some((&C::OID).into()),
+ };
+
+ let public_key_bytes = self.to_encoded_point(false);
+
+ pkcs8::SubjectPublicKeyInfo {
+ algorithm,
+ subject_public_key: public_key_bytes.as_ref(),
+ }
+ .try_into()
+ }
+}
+
+#[cfg(feature = "pem")]
+#[cfg_attr(docsrs, doc(cfg(feature = "pem")))]
+impl<C> FromStr for PublicKey<C>
+where
+ C: Curve + AssociatedOid + ProjectiveArithmetic,
+ AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
+ FieldSize<C>: ModulusSize,
+{
+ type Err = Error;
+
+ fn from_str(s: &str) -> Result<Self> {
+ Self::from_public_key_pem(s).map_err(|_| Error)
+ }
+}
+
+#[cfg(feature = "pem")]
+#[cfg_attr(docsrs, doc(cfg(feature = "pem")))]
+impl<C> ToString for PublicKey<C>
+where
+ C: Curve + AssociatedOid + ProjectiveArithmetic,
+ AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
+ FieldSize<C>: ModulusSize,
+{
+ fn to_string(&self) -> String {
+ self.to_public_key_pem(Default::default())
+ .expect("PEM encoding error")
+ }
+}
+
+#[cfg(feature = "serde")]
+#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
+impl<C> Serialize for PublicKey<C>
+where
+ C: Curve + AssociatedOid + ProjectiveArithmetic,
+ AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
+ FieldSize<C>: ModulusSize,
+{
+ fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
+ where
+ S: ser::Serializer,
+ {
+ let der = self.to_public_key_der().map_err(ser::Error::custom)?;
+ serdect::slice::serialize_hex_upper_or_bin(&der, serializer)
+ }
+}
+
+#[cfg(feature = "serde")]
+#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
+impl<'de, C> Deserialize<'de> for PublicKey<C>
+where
+ C: Curve + AssociatedOid + ProjectiveArithmetic,
+ AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
+ FieldSize<C>: ModulusSize,
+{
+ fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
+ where
+ D: de::Deserializer<'de>,
+ {
+ let der_bytes = serdect::slice::deserialize_hex_or_bin_vec(deserializer)?;
+ Self::from_public_key_der(&der_bytes).map_err(de::Error::custom)
+ }
+}
+
+#[cfg(all(feature = "dev", test))]
+mod tests {
+ use crate::{dev::MockCurve, sec1::FromEncodedPoint};
+
+ type EncodedPoint = crate::sec1::EncodedPoint<MockCurve>;
+ type PublicKey = super::PublicKey<MockCurve>;
+
+ #[test]
+ fn from_encoded_point_rejects_identity() {
+ let identity = EncodedPoint::identity();
+ assert!(bool::from(
+ PublicKey::from_encoded_point(&identity).is_none()
+ ));
+ }
+}
diff --git a/vendor/elliptic-curve/src/scalar.rs b/vendor/elliptic-curve/src/scalar.rs
new file mode 100644
index 000000000..72d796847
--- /dev/null
+++ b/vendor/elliptic-curve/src/scalar.rs
@@ -0,0 +1,32 @@
+//! Scalar types.
+
+use subtle::Choice;
+
+pub(crate) mod core;
+
+#[cfg(feature = "arithmetic")]
+pub(crate) mod nonzero;
+
+#[cfg(feature = "arithmetic")]
+use crate::ScalarArithmetic;
+
+/// Scalar field element for a particular elliptic curve.
+#[cfg(feature = "arithmetic")]
+#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))]
+pub type Scalar<C> = <C as ScalarArithmetic>::Scalar;
+
+/// Bit representation of a scalar field element of a given curve.
+#[cfg(feature = "bits")]
+#[cfg_attr(docsrs, doc(cfg(feature = "bits")))]
+pub type ScalarBits<C> = ff::FieldBits<<Scalar<C> as ff::PrimeFieldBits>::ReprBits>;
+
+/// Is this scalar greater than n / 2?
+///
+/// # Returns
+///
+/// - For scalars 0 through n / 2: `Choice::from(0)`
+/// - For scalars (n / 2) + 1 through n - 1: `Choice::from(1)`
+pub trait IsHigh {
+ /// Is this scalar greater than or equal to n / 2?
+ fn is_high(&self) -> Choice;
+}
diff --git a/vendor/elliptic-curve/src/scalar/core.rs b/vendor/elliptic-curve/src/scalar/core.rs
new file mode 100644
index 000000000..6a088ca55
--- /dev/null
+++ b/vendor/elliptic-curve/src/scalar/core.rs
@@ -0,0 +1,434 @@
+//! Generic scalar type with core functionality.
+
+use crate::{
+ bigint::{prelude::*, Limb, NonZero},
+ rand_core::{CryptoRng, RngCore},
+ subtle::{
+ Choice, ConditionallySelectable, ConstantTimeEq, ConstantTimeGreater, ConstantTimeLess,
+ CtOption,
+ },
+ Curve, Error, FieldBytes, IsHigh, Result,
+};
+use base16ct::HexDisplay;
+use core::{
+ cmp::Ordering,
+ fmt,
+ ops::{Add, AddAssign, Neg, Sub, SubAssign},
+ str,
+};
+use generic_array::GenericArray;
+use zeroize::DefaultIsZeroes;
+
+#[cfg(feature = "arithmetic")]
+use {
+ super::{Scalar, ScalarArithmetic},
+ group::ff::PrimeField,
+};
+
+#[cfg(feature = "serde")]
+use serdect::serde::{de, ser, Deserialize, Serialize};
+
+/// Generic scalar type with core functionality.
+///
+/// This type provides a baseline level of scalar arithmetic functionality
+/// which is always available for all curves, regardless of if they implement
+/// any arithmetic traits.
+///
+/// # `serde` support
+///
+/// When the optional `serde` feature of this create is enabled, [`Serialize`]
+/// and [`Deserialize`] impls are provided for this type.
+///
+/// The serialization is a fixed-width big endian encoding. When used with
+/// textual formats, the binary data is encoded as hexadecimal.
+// TODO(tarcieri): make this a fully generic `Scalar` type and use it for `ScalarArithmetic`
+#[derive(Copy, Clone, Debug, Default)]
+#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))]
+pub struct ScalarCore<C: Curve> {
+ /// Inner unsigned integer type.
+ inner: C::UInt,
+}
+
+impl<C> ScalarCore<C>
+where
+ C: Curve,
+{
+ /// Zero scalar.
+ pub const ZERO: Self = Self {
+ inner: C::UInt::ZERO,
+ };
+
+ /// Multiplicative identity.
+ pub const ONE: Self = Self {
+ inner: C::UInt::ONE,
+ };
+
+ /// Scalar modulus.
+ pub const MODULUS: C::UInt = C::ORDER;
+
+ /// Generate a random [`ScalarCore`].
+ pub fn random(rng: impl CryptoRng + RngCore) -> Self {
+ Self {
+ inner: C::UInt::random_mod(rng, &NonZero::new(Self::MODULUS).unwrap()),
+ }
+ }
+
+ /// Create a new scalar from [`Curve::UInt`].
+ pub fn new(uint: C::UInt) -> CtOption<Self> {
+ CtOption::new(Self { inner: uint }, uint.ct_lt(&Self::MODULUS))
+ }
+
+ /// Decode [`ScalarCore`] from big endian bytes.
+ pub fn from_be_bytes(bytes: FieldBytes<C>) -> CtOption<Self> {
+ Self::new(C::UInt::from_be_byte_array(bytes))
+ }
+
+ /// Decode [`ScalarCore`] from a big endian byte slice.
+ pub fn from_be_slice(slice: &[u8]) -> Result<Self> {
+ if slice.len() == C::UInt::BYTE_SIZE {
+ Option::from(Self::from_be_bytes(GenericArray::clone_from_slice(slice))).ok_or(Error)
+ } else {
+ Err(Error)
+ }
+ }
+
+ /// Decode [`ScalarCore`] from little endian bytes.
+ pub fn from_le_bytes(bytes: FieldBytes<C>) -> CtOption<Self> {
+ Self::new(C::UInt::from_le_byte_array(bytes))
+ }
+
+ /// Decode [`ScalarCore`] from a little endian byte slice.
+ pub fn from_le_slice(slice: &[u8]) -> Result<Self> {
+ if slice.len() == C::UInt::BYTE_SIZE {
+ Option::from(Self::from_le_bytes(GenericArray::clone_from_slice(slice))).ok_or(Error)
+ } else {
+ Err(Error)
+ }
+ }
+
+ /// Borrow the inner `C::UInt`.
+ pub fn as_uint(&self) -> &C::UInt {
+ &self.inner
+ }
+
+ /// Borrow the inner limbs as a slice.
+ pub fn as_limbs(&self) -> &[Limb] {
+ self.inner.as_ref()
+ }
+
+ /// Is this [`ScalarCore`] value equal to zero?
+ pub fn is_zero(&self) -> Choice {
+ self.inner.is_zero()
+ }
+
+ /// Is this [`ScalarCore`] value even?
+ pub fn is_even(&self) -> Choice {
+ self.inner.is_even()
+ }
+
+ /// Is this [`ScalarCore`] value odd?
+ pub fn is_odd(&self) -> Choice {
+ self.inner.is_odd()
+ }
+
+ /// Encode [`ScalarCore`] as big endian bytes.
+ pub fn to_be_bytes(self) -> FieldBytes<C> {
+ self.inner.to_be_byte_array()
+ }
+
+ /// Encode [`ScalarCore`] as little endian bytes.
+ pub fn to_le_bytes(self) -> FieldBytes<C> {
+ self.inner.to_le_byte_array()
+ }
+}
+
+#[cfg(feature = "arithmetic")]
+impl<C> ScalarCore<C>
+where
+ C: Curve + ScalarArithmetic,
+{
+ /// Convert [`ScalarCore`] into a given curve's scalar type
+ // TODO(tarcieri): replace curve-specific scalars with `ScalarCore`
+ pub(super) fn to_scalar(self) -> Scalar<C> {
+ Scalar::<C>::from_repr(self.to_be_bytes()).unwrap()
+ }
+}
+
+// TODO(tarcieri): better encapsulate this?
+impl<C> AsRef<[Limb]> for ScalarCore<C>
+where
+ C: Curve,
+{
+ fn as_ref(&self) -> &[Limb] {
+ self.as_limbs()
+ }
+}
+
+impl<C> ConditionallySelectable for ScalarCore<C>
+where
+ C: Curve,
+{
+ fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
+ Self {
+ inner: C::UInt::conditional_select(&a.inner, &b.inner, choice),
+ }
+ }
+}
+
+impl<C> ConstantTimeEq for ScalarCore<C>
+where
+ C: Curve,
+{
+ fn ct_eq(&self, other: &Self) -> Choice {
+ self.inner.ct_eq(&other.inner)
+ }
+}
+
+impl<C> ConstantTimeLess for ScalarCore<C>
+where
+ C: Curve,
+{
+ fn ct_lt(&self, other: &Self) -> Choice {
+ self.inner.ct_lt(&other.inner)
+ }
+}
+
+impl<C> ConstantTimeGreater for ScalarCore<C>
+where
+ C: Curve,
+{
+ fn ct_gt(&self, other: &Self) -> Choice {
+ self.inner.ct_gt(&other.inner)
+ }
+}
+
+impl<C: Curve> DefaultIsZeroes for ScalarCore<C> {}
+
+impl<C: Curve> Eq for ScalarCore<C> {}
+
+impl<C> PartialEq for ScalarCore<C>
+where
+ C: Curve,
+{
+ fn eq(&self, other: &Self) -> bool {
+ self.ct_eq(other).into()
+ }
+}
+
+impl<C> PartialOrd for ScalarCore<C>
+where
+ C: Curve,
+{
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ Some(self.cmp(other))
+ }
+}
+
+impl<C> Ord for ScalarCore<C>
+where
+ C: Curve,
+{
+ fn cmp(&self, other: &Self) -> Ordering {
+ self.inner.cmp(&other.inner)
+ }
+}
+
+impl<C> From<u64> for ScalarCore<C>
+where
+ C: Curve,
+{
+ fn from(n: u64) -> Self {
+ Self {
+ inner: C::UInt::from(n),
+ }
+ }
+}
+
+impl<C> Add<ScalarCore<C>> for ScalarCore<C>
+where
+ C: Curve,
+{
+ type Output = Self;
+
+ fn add(self, other: Self) -> Self {
+ self.add(&other)
+ }
+}
+
+impl<C> Add<&ScalarCore<C>> for ScalarCore<C>
+where
+ C: Curve,
+{
+ type Output = Self;
+
+ fn add(self, other: &Self) -> Self {
+ Self {
+ inner: self.inner.add_mod(&other.inner, &Self::MODULUS),
+ }
+ }
+}
+
+impl<C> AddAssign<ScalarCore<C>> for ScalarCore<C>
+where
+ C: Curve,
+{
+ fn add_assign(&mut self, other: Self) {
+ *self = *self + other;
+ }
+}
+
+impl<C> AddAssign<&ScalarCore<C>> for ScalarCore<C>
+where
+ C: Curve,
+{
+ fn add_assign(&mut self, other: &Self) {
+ *self = *self + other;
+ }
+}
+
+impl<C> Sub<ScalarCore<C>> for ScalarCore<C>
+where
+ C: Curve,
+{
+ type Output = Self;
+
+ fn sub(self, other: Self) -> Self {
+ self.sub(&other)
+ }
+}
+
+impl<C> Sub<&ScalarCore<C>> for ScalarCore<C>
+where
+ C: Curve,
+{
+ type Output = Self;
+
+ fn sub(self, other: &Self) -> Self {
+ Self {
+ inner: self.inner.sub_mod(&other.inner, &Self::MODULUS),
+ }
+ }
+}
+
+impl<C> SubAssign<ScalarCore<C>> for ScalarCore<C>
+where
+ C: Curve,
+{
+ fn sub_assign(&mut self, other: Self) {
+ *self = *self - other;
+ }
+}
+
+impl<C> SubAssign<&ScalarCore<C>> for ScalarCore<C>
+where
+ C: Curve,
+{
+ fn sub_assign(&mut self, other: &Self) {
+ *self = *self - other;
+ }
+}
+
+impl<C> Neg for ScalarCore<C>
+where
+ C: Curve,
+{
+ type Output = Self;
+
+ fn neg(self) -> Self {
+ Self {
+ inner: self.inner.neg_mod(&Self::MODULUS),
+ }
+ }
+}
+
+impl<C> Neg for &ScalarCore<C>
+where
+ C: Curve,
+{
+ type Output = ScalarCore<C>;
+
+ fn neg(self) -> ScalarCore<C> {
+ -*self
+ }
+}
+
+impl<C> IsHigh for ScalarCore<C>
+where
+ C: Curve,
+{
+ fn is_high(&self) -> Choice {
+ let n_2 = C::ORDER >> 1;
+ self.inner.ct_gt(&n_2)
+ }
+}
+
+impl<C> fmt::Display for ScalarCore<C>
+where
+ C: Curve,
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "{:X}", self)
+ }
+}
+
+impl<C> fmt::LowerHex for ScalarCore<C>
+where
+ C: Curve,
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "{:x}", HexDisplay(&self.to_be_bytes()))
+ }
+}
+
+impl<C> fmt::UpperHex for ScalarCore<C>
+where
+ C: Curve,
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "{:X}", HexDisplay(&self.to_be_bytes()))
+ }
+}
+
+impl<C> str::FromStr for ScalarCore<C>
+where
+ C: Curve,
+{
+ type Err = Error;
+
+ fn from_str(hex: &str) -> Result<Self> {
+ let mut bytes = FieldBytes::<C>::default();
+ base16ct::lower::decode(hex, &mut bytes)?;
+ Option::from(Self::from_be_bytes(bytes)).ok_or(Error)
+ }
+}
+
+#[cfg(feature = "serde")]
+#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
+impl<C> Serialize for ScalarCore<C>
+where
+ C: Curve,
+{
+ fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
+ where
+ S: ser::Serializer,
+ {
+ serdect::array::serialize_hex_upper_or_bin(&self.to_be_bytes(), serializer)
+ }
+}
+
+#[cfg(feature = "serde")]
+#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
+impl<'de, C> Deserialize<'de> for ScalarCore<C>
+where
+ C: Curve,
+{
+ fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
+ where
+ D: de::Deserializer<'de>,
+ {
+ let mut bytes = FieldBytes::<C>::default();
+ serdect::array::deserialize_hex_or_bin(&mut bytes, deserializer)?;
+ Option::from(Self::from_be_bytes(bytes))
+ .ok_or_else(|| de::Error::custom("scalar out of range"))
+ }
+}
diff --git a/vendor/elliptic-curve/src/scalar/nonzero.rs b/vendor/elliptic-curve/src/scalar/nonzero.rs
new file mode 100644
index 000000000..7450537a9
--- /dev/null
+++ b/vendor/elliptic-curve/src/scalar/nonzero.rs
@@ -0,0 +1,353 @@
+//! Non-zero scalar type.
+
+use crate::{
+ bigint::Encoding as _,
+ ops::{Invert, Reduce, ReduceNonZero},
+ rand_core::{CryptoRng, RngCore},
+ Curve, Error, FieldBytes, IsHigh, PrimeCurve, Result, Scalar, ScalarArithmetic, ScalarCore,
+ SecretKey,
+};
+use base16ct::HexDisplay;
+use core::{
+ fmt,
+ ops::{Deref, Mul, Neg},
+ str,
+};
+use crypto_bigint::{ArrayEncoding, Integer};
+use ff::{Field, PrimeField};
+use generic_array::GenericArray;
+use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};
+use zeroize::Zeroize;
+
+/// Non-zero scalar type.
+///
+/// This type ensures that its value is not zero, ala `core::num::NonZero*`.
+/// To do this, the generic `S` type must impl both `Default` and
+/// `ConstantTimeEq`, with the requirement that `S::default()` returns 0.
+///
+/// In the context of ECC, it's useful for ensuring that scalar multiplication
+/// cannot result in the point at infinity.
+#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))]
+#[derive(Clone)]
+pub struct NonZeroScalar<C>
+where
+ C: Curve + ScalarArithmetic,
+{
+ scalar: Scalar<C>,
+}
+
+impl<C> NonZeroScalar<C>
+where
+ C: Curve + ScalarArithmetic,
+{
+ /// Generate a random `NonZeroScalar`.
+ pub fn random(mut rng: impl CryptoRng + RngCore) -> Self {
+ // Use rejection sampling to eliminate zero values.
+ // While this method isn't constant-time, the attacker shouldn't learn
+ // anything about unrelated outputs so long as `rng` is a secure `CryptoRng`.
+ loop {
+ if let Some(result) = Self::new(Field::random(&mut rng)).into() {
+ break result;
+ }
+ }
+ }
+
+ /// Create a [`NonZeroScalar`] from a scalar.
+ pub fn new(scalar: Scalar<C>) -> CtOption<Self> {
+ CtOption::new(Self { scalar }, !scalar.is_zero())
+ }
+
+ /// Decode a [`NonZeroScalar`] from a big endian-serialized field element.
+ pub fn from_repr(repr: FieldBytes<C>) -> CtOption<Self> {
+ Scalar::<C>::from_repr(repr).and_then(Self::new)
+ }
+
+ /// Create a [`NonZeroScalar`] from a `C::UInt`.
+ pub fn from_uint(uint: C::UInt) -> CtOption<Self> {
+ ScalarCore::new(uint).and_then(|scalar| Self::new(scalar.into()))
+ }
+}
+
+impl<C> AsRef<Scalar<C>> for NonZeroScalar<C>
+where
+ C: Curve + ScalarArithmetic,
+{
+ fn as_ref(&self) -> &Scalar<C> {
+ &self.scalar
+ }
+}
+
+impl<C> ConditionallySelectable for NonZeroScalar<C>
+where
+ C: Curve + ScalarArithmetic,
+{
+ fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
+ Self {
+ scalar: Scalar::<C>::conditional_select(&a.scalar, &b.scalar, choice),
+ }
+ }
+}
+
+impl<C> ConstantTimeEq for NonZeroScalar<C>
+where
+ C: Curve + ScalarArithmetic,
+{
+ fn ct_eq(&self, other: &Self) -> Choice {
+ self.scalar.ct_eq(&other.scalar)
+ }
+}
+
+impl<C> Copy for NonZeroScalar<C> where C: Curve + ScalarArithmetic {}
+
+impl<C> Deref for NonZeroScalar<C>
+where
+ C: Curve + ScalarArithmetic,
+{
+ type Target = Scalar<C>;
+
+ fn deref(&self) -> &Scalar<C> {
+ &self.scalar
+ }
+}
+
+impl<C> From<NonZeroScalar<C>> for FieldBytes<C>
+where
+ C: Curve + ScalarArithmetic,
+{
+ fn from(scalar: NonZeroScalar<C>) -> FieldBytes<C> {
+ Self::from(&scalar)
+ }
+}
+
+impl<C> From<&NonZeroScalar<C>> for FieldBytes<C>
+where
+ C: Curve + ScalarArithmetic,
+{
+ fn from(scalar: &NonZeroScalar<C>) -> FieldBytes<C> {
+ scalar.to_repr()
+ }
+}
+
+impl<C> From<NonZeroScalar<C>> for ScalarCore<C>
+where
+ C: Curve + ScalarArithmetic,
+{
+ fn from(scalar: NonZeroScalar<C>) -> ScalarCore<C> {
+ ScalarCore::from_be_bytes(scalar.to_repr()).unwrap()
+ }
+}
+
+impl<C> From<&NonZeroScalar<C>> for ScalarCore<C>
+where
+ C: Curve + ScalarArithmetic,
+{
+ fn from(scalar: &NonZeroScalar<C>) -> ScalarCore<C> {
+ ScalarCore::from_be_bytes(scalar.to_repr()).unwrap()
+ }
+}
+
+impl<C> From<SecretKey<C>> for NonZeroScalar<C>
+where
+ C: Curve + ScalarArithmetic,
+{
+ fn from(sk: SecretKey<C>) -> NonZeroScalar<C> {
+ Self::from(&sk)
+ }
+}
+
+impl<C> From<&SecretKey<C>> for NonZeroScalar<C>
+where
+ C: Curve + ScalarArithmetic,
+{
+ fn from(sk: &SecretKey<C>) -> NonZeroScalar<C> {
+ let scalar = sk.as_scalar_core().to_scalar();
+ debug_assert!(!bool::from(scalar.is_zero()));
+ Self { scalar }
+ }
+}
+
+impl<C> Invert for NonZeroScalar<C>
+where
+ C: Curve + ScalarArithmetic,
+{
+ type Output = Self;
+
+ fn invert(&self) -> Self {
+ Self {
+ // This will always succeed since `scalar` will never be 0
+ scalar: ff::Field::invert(&self.scalar).unwrap(),
+ }
+ }
+}
+
+impl<C> IsHigh for NonZeroScalar<C>
+where
+ C: Curve + ScalarArithmetic,
+{
+ fn is_high(&self) -> Choice {
+ self.scalar.is_high()
+ }
+}
+
+impl<C> Neg for NonZeroScalar<C>
+where
+ C: Curve + ScalarArithmetic,
+{
+ type Output = NonZeroScalar<C>;
+
+ fn neg(self) -> NonZeroScalar<C> {
+ let scalar = -self.scalar;
+ debug_assert!(!bool::from(scalar.is_zero()));
+ NonZeroScalar { scalar }
+ }
+}
+
+impl<C> Mul<NonZeroScalar<C>> for NonZeroScalar<C>
+where
+ C: PrimeCurve + ScalarArithmetic,
+{
+ type Output = Self;
+
+ #[inline]
+ fn mul(self, other: Self) -> Self {
+ Self::mul(self, &other)
+ }
+}
+
+impl<C> Mul<&NonZeroScalar<C>> for NonZeroScalar<C>
+where
+ C: PrimeCurve + ScalarArithmetic,
+{
+ type Output = Self;
+
+ fn mul(self, other: &Self) -> Self {
+ // Multiplication is modulo a prime, so the product of two non-zero
+ // scalars is also non-zero.
+ let scalar = self.scalar * other.scalar;
+ debug_assert!(!bool::from(scalar.is_zero()));
+ NonZeroScalar { scalar }
+ }
+}
+
+/// Note: implementation is the same as `ReduceNonZero`
+impl<C, I> Reduce<I> for NonZeroScalar<C>
+where
+ C: Curve + ScalarArithmetic,
+ I: Integer + ArrayEncoding,
+ Scalar<C>: ReduceNonZero<I>,
+{
+ fn from_uint_reduced(n: I) -> Self {
+ Self::from_uint_reduced_nonzero(n)
+ }
+}
+
+impl<C, I> ReduceNonZero<I> for NonZeroScalar<C>
+where
+ C: Curve + ScalarArithmetic,
+ I: Integer + ArrayEncoding,
+ Scalar<C>: ReduceNonZero<I>,
+{
+ fn from_uint_reduced_nonzero(n: I) -> Self {
+ let scalar = Scalar::<C>::from_uint_reduced_nonzero(n);
+ debug_assert!(!bool::from(scalar.is_zero()));
+ Self::new(scalar).unwrap()
+ }
+}
+
+impl<C> TryFrom<&[u8]> for NonZeroScalar<C>
+where
+ C: Curve + ScalarArithmetic,
+{
+ type Error = Error;
+
+ fn try_from(bytes: &[u8]) -> Result<Self> {
+ if bytes.len() == C::UInt::BYTE_SIZE {
+ Option::from(NonZeroScalar::from_repr(GenericArray::clone_from_slice(
+ bytes,
+ )))
+ .ok_or(Error)
+ } else {
+ Err(Error)
+ }
+ }
+}
+
+impl<C> Zeroize for NonZeroScalar<C>
+where
+ C: Curve + ScalarArithmetic,
+{
+ fn zeroize(&mut self) {
+ // Use zeroize's volatile writes to ensure value is cleared.
+ self.scalar.zeroize();
+
+ // Write a 1 instead of a 0 to ensure this type's non-zero invariant
+ // is upheld.
+ self.scalar = Scalar::<C>::one();
+ }
+}
+
+impl<C> fmt::Display for NonZeroScalar<C>
+where
+ C: Curve + ScalarArithmetic,
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "{:X}", self)
+ }
+}
+
+impl<C> fmt::LowerHex for NonZeroScalar<C>
+where
+ C: Curve + ScalarArithmetic,
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "{:x}", HexDisplay(&self.to_repr()))
+ }
+}
+
+impl<C> fmt::UpperHex for NonZeroScalar<C>
+where
+ C: Curve + ScalarArithmetic,
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "{:}", HexDisplay(&self.to_repr()))
+ }
+}
+
+impl<C> str::FromStr for NonZeroScalar<C>
+where
+ C: Curve + ScalarArithmetic,
+{
+ type Err = Error;
+
+ fn from_str(hex: &str) -> Result<Self> {
+ let mut bytes = FieldBytes::<C>::default();
+
+ if base16ct::mixed::decode(hex, &mut bytes)?.len() == bytes.len() {
+ Option::from(Self::from_repr(bytes)).ok_or(Error)
+ } else {
+ Err(Error)
+ }
+ }
+}
+
+#[cfg(all(test, feature = "dev"))]
+mod tests {
+ use crate::dev::{NonZeroScalar, Scalar};
+ use ff::{Field, PrimeField};
+ use hex_literal::hex;
+ use zeroize::Zeroize;
+
+ #[test]
+ fn round_trip() {
+ let bytes = hex!("c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721");
+ let scalar = NonZeroScalar::from_repr(bytes.into()).unwrap();
+ assert_eq!(&bytes, scalar.to_repr().as_slice());
+ }
+
+ #[test]
+ fn zeroize() {
+ let mut scalar = NonZeroScalar::new(Scalar::from(42u64)).unwrap();
+ scalar.zeroize();
+ assert_eq!(*scalar, Scalar::one());
+ }
+}
diff --git a/vendor/elliptic-curve/src/sec1.rs b/vendor/elliptic-curve/src/sec1.rs
new file mode 100644
index 000000000..3e1635941
--- /dev/null
+++ b/vendor/elliptic-curve/src/sec1.rs
@@ -0,0 +1,114 @@
+//! Support for SEC1 elliptic curve encoding formats.
+//!
+//! <https://www.secg.org/sec1-v2.pdf>
+
+pub use sec1::point::{Coordinates, ModulusSize, Tag};
+
+use crate::{Curve, FieldSize, Result, SecretKey};
+use generic_array::GenericArray;
+use subtle::CtOption;
+
+#[cfg(feature = "arithmetic")]
+use crate::{AffinePoint, Error, ProjectiveArithmetic};
+
+/// Encoded elliptic curve point with point compression.
+pub type CompressedPoint<C> = GenericArray<u8, CompressedPointSize<C>>;
+
+/// Size of a compressed elliptic curve point.
+pub type CompressedPointSize<C> = <FieldSize<C> as ModulusSize>::CompressedPointSize;
+
+/// Encoded elliptic curve point sized appropriately for a given curve.
+pub type EncodedPoint<C> = sec1::point::EncodedPoint<FieldSize<C>>;
+
+/// Encoded elliptic curve point *without* point compression.
+pub type UncompressedPoint<C> = GenericArray<u8, UncompressedPointSize<C>>;
+
+/// Size of an uncompressed elliptic curve point.
+pub type UncompressedPointSize<C> = <FieldSize<C> as ModulusSize>::UncompressedPointSize;
+
+/// Trait for deserializing a value from a SEC1 encoded curve point.
+///
+/// This is intended for use with the `AffinePoint` type for a given elliptic curve.
+pub trait FromEncodedPoint<C>
+where
+ Self: Sized,
+ C: Curve,
+ FieldSize<C>: ModulusSize,
+{
+ /// Deserialize the type this trait is impl'd on from an [`EncodedPoint`].
+ fn from_encoded_point(point: &EncodedPoint<C>) -> CtOption<Self>;
+}
+
+/// Trait for serializing a value to a SEC1 encoded curve point.
+///
+/// This is intended for use with the `AffinePoint` type for a given elliptic curve.
+pub trait ToEncodedPoint<C>
+where
+ C: Curve,
+ FieldSize<C>: ModulusSize,
+{
+ /// Serialize this value as a SEC1 [`EncodedPoint`], optionally applying
+ /// point compression.
+ fn to_encoded_point(&self, compress: bool) -> EncodedPoint<C>;
+}
+
+/// Trait for serializing a value to a SEC1 encoded curve point with compaction.
+///
+/// This is intended for use with the `AffinePoint` type for a given elliptic curve.
+pub trait ToCompactEncodedPoint<C>
+where
+ C: Curve,
+ FieldSize<C>: ModulusSize,
+{
+ /// Serialize this value as a SEC1 [`EncodedPoint`], optionally applying
+ /// point compression.
+ fn to_compact_encoded_point(&self) -> CtOption<EncodedPoint<C>>;
+}
+
+/// Validate that the given [`EncodedPoint`] represents the encoded public key
+/// value of the given secret.
+///
+/// Curve implementations which also impl [`ProjectiveArithmetic`] will receive
+/// a blanket default impl of this trait.
+pub trait ValidatePublicKey
+where
+ Self: Curve,
+ FieldSize<Self>: ModulusSize,
+{
+ /// Validate that the given [`EncodedPoint`] is a valid public key for the
+ /// provided secret value.
+ #[allow(unused_variables)]
+ fn validate_public_key(
+ secret_key: &SecretKey<Self>,
+ public_key: &EncodedPoint<Self>,
+ ) -> Result<()> {
+ // Provide a default "always succeeds" implementation.
+ // This is the intended default for curve implementations which
+ // do not provide an arithmetic implementation, since they have no
+ // way to verify this.
+ //
+ // Implementations with an arithmetic impl will receive a blanket impl
+ // of this trait.
+ Ok(())
+ }
+}
+
+#[cfg(all(feature = "arithmetic"))]
+impl<C> ValidatePublicKey for C
+where
+ C: Curve + ProjectiveArithmetic,
+ AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
+ FieldSize<C>: ModulusSize,
+{
+ fn validate_public_key(secret_key: &SecretKey<C>, public_key: &EncodedPoint<C>) -> Result<()> {
+ let pk = secret_key
+ .public_key()
+ .to_encoded_point(public_key.is_compressed());
+
+ if public_key == &pk {
+ Ok(())
+ } else {
+ Err(Error)
+ }
+ }
+}
diff --git a/vendor/elliptic-curve/src/secret_key.rs b/vendor/elliptic-curve/src/secret_key.rs
new file mode 100644
index 000000000..0fc3dafb1
--- /dev/null
+++ b/vendor/elliptic-curve/src/secret_key.rs
@@ -0,0 +1,395 @@
+//! Secret keys for elliptic curves (i.e. private scalars).
+//!
+//! The [`SecretKey`] type is a wrapper around a secret scalar value which is
+//! designed to prevent unintentional exposure (e.g. via `Debug` or other
+//! logging). It also handles zeroing the secret value out of memory securely
+//! on drop.
+
+#[cfg(all(feature = "pkcs8", feature = "sec1"))]
+mod pkcs8;
+
+use crate::{Curve, Error, FieldBytes, Result, ScalarCore};
+use core::fmt::{self, Debug};
+use crypto_bigint::Encoding;
+use generic_array::GenericArray;
+use subtle::{Choice, ConstantTimeEq};
+use zeroize::{Zeroize, ZeroizeOnDrop};
+
+#[cfg(all(feature = "alloc", feature = "arithmetic"))]
+use {
+ crate::{
+ sec1::{FromEncodedPoint, ToEncodedPoint},
+ AffinePoint,
+ },
+ alloc::vec::Vec,
+ der::Encode,
+ zeroize::Zeroizing,
+};
+
+#[cfg(feature = "arithmetic")]
+use crate::{
+ rand_core::{CryptoRng, RngCore},
+ NonZeroScalar, ProjectiveArithmetic, PublicKey,
+};
+
+#[cfg(feature = "jwk")]
+use crate::jwk::{JwkEcKey, JwkParameters};
+
+#[cfg(all(feature = "arithmetic", any(feature = "jwk", feature = "pem")))]
+use alloc::string::String;
+
+#[cfg(all(feature = "arithmetic", feature = "jwk"))]
+use alloc::string::ToString;
+
+#[cfg(feature = "pem")]
+use pem_rfc7468 as pem;
+
+#[cfg(feature = "sec1")]
+use crate::{
+ sec1::{EncodedPoint, ModulusSize, ValidatePublicKey},
+ FieldSize,
+};
+
+#[cfg(all(docsrs, feature = "pkcs8"))]
+use {crate::pkcs8::DecodePrivateKey, core::str::FromStr};
+
+/// Type label for PEM-encoded SEC1 private keys.
+#[cfg(feature = "pem")]
+pub(crate) const SEC1_PEM_TYPE_LABEL: &str = "EC PRIVATE KEY";
+
+/// Elliptic curve secret keys.
+///
+/// This type wraps a secret scalar value, helping to prevent accidental
+/// exposure and securely erasing the value from memory when dropped.
+///
+/// # Parsing PKCS#8 Keys
+///
+/// PKCS#8 is a commonly used format for encoding secret keys (especially ones
+/// generated by OpenSSL).
+///
+/// Keys in PKCS#8 format are either binary (ASN.1 BER/DER), or PEM encoded
+/// (ASCII) and begin with the following:
+///
+/// ```text
+/// -----BEGIN PRIVATE KEY-----
+/// ```
+///
+/// To decode an elliptic curve private key from PKCS#8, enable the `pkcs8`
+/// feature of this crate (or the `pkcs8` feature of a specific RustCrypto
+/// elliptic curve crate) and use the [`DecodePrivateKey`] trait to parse it.
+///
+/// When the `pem` feature of this crate (or a specific RustCrypto elliptic
+/// curve crate) is enabled, a [`FromStr`] impl is also available.
+#[derive(Clone)]
+pub struct SecretKey<C: Curve> {
+ /// Scalar value
+ inner: ScalarCore<C>,
+}
+
+impl<C> SecretKey<C>
+where
+ C: Curve,
+{
+ /// Generate a random [`SecretKey`].
+ #[cfg(feature = "arithmetic")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))]
+ pub fn random(rng: impl CryptoRng + RngCore) -> Self
+ where
+ C: ProjectiveArithmetic,
+ {
+ Self {
+ inner: NonZeroScalar::<C>::random(rng).into(),
+ }
+ }
+
+ /// Create a new secret key from a scalar value.
+ pub fn new(scalar: ScalarCore<C>) -> Self {
+ Self { inner: scalar }
+ }
+
+ /// Borrow the inner secret [`ScalarCore`] value.
+ ///
+ /// # ⚠️ Warning
+ ///
+ /// This value is key material.
+ ///
+ /// Please treat it with the care it deserves!
+ pub fn as_scalar_core(&self) -> &ScalarCore<C> {
+ &self.inner
+ }
+
+ /// Get the secret [`NonZeroScalar`] value for this key.
+ ///
+ /// # ⚠️ Warning
+ ///
+ /// This value is key material.
+ ///
+ /// Please treat it with the care it deserves!
+ #[cfg(feature = "arithmetic")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))]
+ pub fn to_nonzero_scalar(&self) -> NonZeroScalar<C>
+ where
+ C: Curve + ProjectiveArithmetic,
+ {
+ self.into()
+ }
+
+ /// Get the [`PublicKey`] which corresponds to this secret key
+ #[cfg(feature = "arithmetic")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))]
+ pub fn public_key(&self) -> PublicKey<C>
+ where
+ C: Curve + ProjectiveArithmetic,
+ {
+ PublicKey::from_secret_scalar(&self.to_nonzero_scalar())
+ }
+
+ /// Deserialize raw secret scalar as a big endian integer.
+ pub fn from_be_bytes(bytes: &[u8]) -> Result<Self> {
+ if bytes.len() != C::UInt::BYTE_SIZE {
+ return Err(Error);
+ }
+
+ let inner: ScalarCore<C> = Option::from(ScalarCore::from_be_bytes(
+ GenericArray::clone_from_slice(bytes),
+ ))
+ .ok_or(Error)?;
+
+ if inner.is_zero().into() {
+ return Err(Error);
+ }
+
+ Ok(Self { inner })
+ }
+
+ /// Serialize raw secret scalar as a big endian integer.
+ pub fn to_be_bytes(&self) -> FieldBytes<C> {
+ self.inner.to_be_bytes()
+ }
+
+ /// Deserialize secret key encoded in the SEC1 ASN.1 DER `ECPrivateKey` format.
+ #[cfg(all(feature = "sec1"))]
+ #[cfg_attr(docsrs, doc(cfg(feature = "sec1")))]
+ pub fn from_sec1_der(der_bytes: &[u8]) -> Result<Self>
+ where
+ C: Curve + ValidatePublicKey,
+ FieldSize<C>: ModulusSize,
+ {
+ sec1::EcPrivateKey::try_from(der_bytes)?
+ .try_into()
+ .map_err(|_| Error)
+ }
+
+ /// Serialize secret key in the SEC1 ASN.1 DER `ECPrivateKey` format.
+ #[cfg(all(feature = "alloc", feature = "arithmetic", feature = "sec1"))]
+ #[cfg_attr(
+ docsrs,
+ doc(cfg(all(feature = "alloc", feature = "arithmetic", feature = "sec1")))
+ )]
+ pub fn to_sec1_der(&self) -> der::Result<Zeroizing<Vec<u8>>>
+ where
+ C: Curve + ProjectiveArithmetic,
+ AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
+ FieldSize<C>: ModulusSize,
+ {
+ // TODO(tarcieri): wrap `secret_key_bytes` in `Zeroizing`
+ let mut private_key_bytes = self.to_be_bytes();
+ let public_key_bytes = self.public_key().to_encoded_point(false);
+
+ let ec_private_key = Zeroizing::new(
+ sec1::EcPrivateKey {
+ private_key: &private_key_bytes,
+ parameters: None,
+ public_key: Some(public_key_bytes.as_bytes()),
+ }
+ .to_vec()?,
+ );
+
+ // TODO(tarcieri): wrap `private_key_bytes` in `Zeroizing`
+ private_key_bytes.zeroize();
+
+ Ok(ec_private_key)
+ }
+
+ /// Parse [`SecretKey`] from PEM-encoded SEC1 `ECPrivateKey` format.
+ ///
+ /// PEM-encoded SEC1 keys can be identified by the leading delimiter:
+ ///
+ /// ```text
+ /// -----BEGIN EC PRIVATE KEY-----
+ /// ```
+ #[cfg(feature = "pem")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "pem")))]
+ pub fn from_sec1_pem(s: &str) -> Result<Self>
+ where
+ C: Curve + ValidatePublicKey,
+ FieldSize<C>: ModulusSize,
+ {
+ let (label, der_bytes) = pem::decode_vec(s.as_bytes()).map_err(|_| Error)?;
+
+ if label != SEC1_PEM_TYPE_LABEL {
+ return Err(Error);
+ }
+
+ Self::from_sec1_der(&*der_bytes).map_err(|_| Error)
+ }
+
+ /// Serialize private key as self-zeroizing PEM-encoded SEC1 `ECPrivateKey`
+ /// with the given [`pem::LineEnding`].
+ ///
+ /// Pass `Default::default()` to use the OS's native line endings.
+ #[cfg(feature = "pem")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "pem")))]
+ pub fn to_pem(&self, line_ending: pem::LineEnding) -> Result<Zeroizing<String>>
+ where
+ C: Curve + ProjectiveArithmetic,
+ AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
+ FieldSize<C>: ModulusSize,
+ {
+ self.to_sec1_der()
+ .ok()
+ .and_then(|der| pem::encode_string(SEC1_PEM_TYPE_LABEL, line_ending, &der).ok())
+ .map(Zeroizing::new)
+ .ok_or(Error)
+ }
+
+ /// Parse a [`JwkEcKey`] JSON Web Key (JWK) into a [`SecretKey`].
+ #[cfg(feature = "jwk")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))]
+ pub fn from_jwk(jwk: &JwkEcKey) -> Result<Self>
+ where
+ C: JwkParameters + ValidatePublicKey,
+ FieldSize<C>: ModulusSize,
+ {
+ Self::try_from(jwk)
+ }
+
+ /// Parse a string containing a JSON Web Key (JWK) into a [`SecretKey`].
+ #[cfg(feature = "jwk")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))]
+ pub fn from_jwk_str(jwk: &str) -> Result<Self>
+ where
+ C: JwkParameters + ValidatePublicKey,
+ FieldSize<C>: ModulusSize,
+ {
+ jwk.parse::<JwkEcKey>().and_then(|jwk| Self::from_jwk(&jwk))
+ }
+
+ /// Serialize this secret key as [`JwkEcKey`] JSON Web Key (JWK).
+ #[cfg(all(feature = "arithmetic", feature = "jwk"))]
+ #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))]
+ #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))]
+ pub fn to_jwk(&self) -> JwkEcKey
+ where
+ C: Curve + JwkParameters + ProjectiveArithmetic,
+ AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
+ FieldSize<C>: ModulusSize,
+ {
+ self.into()
+ }
+
+ /// Serialize this secret key as JSON Web Key (JWK) string.
+ #[cfg(all(feature = "arithmetic", feature = "jwk"))]
+ #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))]
+ #[cfg_attr(docsrs, doc(cfg(feature = "jwk")))]
+ pub fn to_jwk_string(&self) -> Zeroizing<String>
+ where
+ C: Curve + JwkParameters + ProjectiveArithmetic,
+ AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
+ FieldSize<C>: ModulusSize,
+ {
+ Zeroizing::new(self.to_jwk().to_string())
+ }
+}
+
+impl<C> ConstantTimeEq for SecretKey<C>
+where
+ C: Curve,
+{
+ fn ct_eq(&self, other: &Self) -> Choice {
+ self.inner.ct_eq(&other.inner)
+ }
+}
+
+impl<C> Debug for SecretKey<C>
+where
+ C: Curve,
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ // TODO(tarcieri): use `debug_struct` and `finish_non_exhaustive` when stable
+ write!(f, "SecretKey<{:?}>{{ ... }}", C::default())
+ }
+}
+
+impl<C> ZeroizeOnDrop for SecretKey<C> where C: Curve {}
+
+impl<C> Drop for SecretKey<C>
+where
+ C: Curve,
+{
+ fn drop(&mut self) {
+ self.inner.zeroize();
+ }
+}
+
+impl<C: Curve> Eq for SecretKey<C> {}
+
+impl<C> PartialEq for SecretKey<C>
+where
+ C: Curve,
+{
+ fn eq(&self, other: &Self) -> bool {
+ self.ct_eq(other).into()
+ }
+}
+
+#[cfg(all(feature = "sec1"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "sec1")))]
+impl<C> TryFrom<sec1::EcPrivateKey<'_>> for SecretKey<C>
+where
+ C: Curve + ValidatePublicKey,
+ FieldSize<C>: ModulusSize,
+{
+ type Error = der::Error;
+
+ fn try_from(sec1_private_key: sec1::EcPrivateKey<'_>) -> der::Result<Self> {
+ let secret_key = Self::from_be_bytes(sec1_private_key.private_key)
+ .map_err(|_| der::Tag::Sequence.value_error())?;
+
+ // TODO(tarcieri): validate `sec1_private_key.params`?
+ if let Some(pk_bytes) = sec1_private_key.public_key {
+ let pk = EncodedPoint::<C>::from_bytes(pk_bytes)
+ .map_err(|_| der::Tag::BitString.value_error())?;
+
+ if C::validate_public_key(&secret_key, &pk).is_err() {
+ return Err(der::Tag::BitString.value_error());
+ }
+ }
+
+ Ok(secret_key)
+ }
+}
+
+#[cfg(feature = "arithmetic")]
+#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))]
+impl<C> From<NonZeroScalar<C>> for SecretKey<C>
+where
+ C: Curve + ProjectiveArithmetic,
+{
+ fn from(scalar: NonZeroScalar<C>) -> SecretKey<C> {
+ SecretKey::from(&scalar)
+ }
+}
+
+#[cfg(feature = "arithmetic")]
+#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))]
+impl<C> From<&NonZeroScalar<C>> for SecretKey<C>
+where
+ C: Curve + ProjectiveArithmetic,
+{
+ fn from(scalar: &NonZeroScalar<C>) -> SecretKey<C> {
+ SecretKey {
+ inner: scalar.into(),
+ }
+ }
+}
diff --git a/vendor/elliptic-curve/src/secret_key/pkcs8.rs b/vendor/elliptic-curve/src/secret_key/pkcs8.rs
new file mode 100644
index 000000000..3c1a509bf
--- /dev/null
+++ b/vendor/elliptic-curve/src/secret_key/pkcs8.rs
@@ -0,0 +1,92 @@
+//! PKCS#8 encoding/decoding support.
+
+use super::SecretKey;
+use crate::{
+ pkcs8::{self, AssociatedOid, DecodePrivateKey},
+ sec1::{ModulusSize, ValidatePublicKey},
+ Curve, FieldSize, ALGORITHM_OID,
+};
+use der::Decode;
+use sec1::EcPrivateKey;
+
+// Imports for the `EncodePrivateKey` impl
+// TODO(tarcieri): use weak activation of `pkcs8/alloc` for gating `EncodePrivateKey` impl
+#[cfg(all(feature = "arithmetic", feature = "pem"))]
+use {
+ crate::{
+ sec1::{FromEncodedPoint, ToEncodedPoint},
+ AffinePoint, ProjectiveArithmetic,
+ },
+ pkcs8::EncodePrivateKey,
+};
+
+// Imports for actual PEM support
+#[cfg(feature = "pem")]
+use {
+ crate::{error::Error, Result},
+ core::str::FromStr,
+};
+
+#[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))]
+impl<C> TryFrom<pkcs8::PrivateKeyInfo<'_>> for SecretKey<C>
+where
+ C: Curve + AssociatedOid + ValidatePublicKey,
+ FieldSize<C>: ModulusSize,
+{
+ type Error = pkcs8::Error;
+
+ fn try_from(private_key_info: pkcs8::PrivateKeyInfo<'_>) -> pkcs8::Result<Self> {
+ private_key_info
+ .algorithm
+ .assert_oids(ALGORITHM_OID, C::OID)?;
+
+ let ec_private_key = EcPrivateKey::from_der(private_key_info.private_key)?;
+ Ok(Self::try_from(ec_private_key)?)
+ }
+}
+
+#[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))]
+impl<C> DecodePrivateKey for SecretKey<C>
+where
+ C: Curve + AssociatedOid + ValidatePublicKey,
+ FieldSize<C>: ModulusSize,
+{
+}
+
+// TODO(tarcieri): use weak activation of `pkcs8/alloc` for this when possible
+// It doesn't strictly depend on `pkcs8/pem` but we can't easily activate `pkcs8/alloc`
+// without adding a separate crate feature just for this functionality.
+#[cfg(all(feature = "arithmetic", feature = "pem"))]
+#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))]
+#[cfg_attr(docsrs, doc(cfg(feature = "pem")))]
+impl<C> EncodePrivateKey for SecretKey<C>
+where
+ C: Curve + AssociatedOid + ProjectiveArithmetic,
+ AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
+ FieldSize<C>: ModulusSize,
+{
+ fn to_pkcs8_der(&self) -> pkcs8::Result<der::SecretDocument> {
+ let algorithm_identifier = pkcs8::AlgorithmIdentifier {
+ oid: ALGORITHM_OID,
+ parameters: Some((&C::OID).into()),
+ };
+
+ let ec_private_key = self.to_sec1_der()?;
+ let pkcs8_key = pkcs8::PrivateKeyInfo::new(algorithm_identifier, &ec_private_key);
+ Ok(der::SecretDocument::encode_msg(&pkcs8_key)?)
+ }
+}
+
+#[cfg(feature = "pem")]
+#[cfg_attr(docsrs, doc(cfg(feature = "pem")))]
+impl<C> FromStr for SecretKey<C>
+where
+ C: Curve + AssociatedOid + ValidatePublicKey,
+ FieldSize<C>: ModulusSize,
+{
+ type Err = Error;
+
+ fn from_str(s: &str) -> Result<Self> {
+ Self::from_pkcs8_pem(s).map_err(|_| Error)
+ }
+}
diff --git a/vendor/elliptic-curve/src/weierstrass.rs b/vendor/elliptic-curve/src/weierstrass.rs
new file mode 100644
index 000000000..1782d95e1
--- /dev/null
+++ b/vendor/elliptic-curve/src/weierstrass.rs
@@ -0,0 +1,128 @@
+//! Complete projective formulas for prime order elliptic curves as described
+//! in [Renes-Costello-Batina 2015].
+//!
+//! [Renes-Costello-Batina 2015]: https://eprint.iacr.org/2015/1060
+
+#![allow(clippy::op_ref)]
+
+use ff::Field;
+
+/// Affine point whose coordinates are represented by the given field element.
+pub type AffinePoint<Fe> = (Fe, Fe);
+
+/// Projective point whose coordinates are represented by the given field element.
+pub type ProjectivePoint<Fe> = (Fe, Fe, Fe);
+
+/// Implements the complete addition formula from [Renes-Costello-Batina 2015]
+/// (Algorithm 4).
+///
+/// [Renes-Costello-Batina 2015]: https://eprint.iacr.org/2015/1060
+#[inline(always)]
+pub fn add<Fe>(
+ (ax, ay, az): ProjectivePoint<Fe>,
+ (bx, by, bz): ProjectivePoint<Fe>,
+ curve_equation_b: Fe,
+) -> ProjectivePoint<Fe>
+where
+ Fe: Field,
+{
+ // The comments after each line indicate which algorithm steps are being
+ // performed.
+ let xx = ax * bx; // 1
+ let yy = ay * by; // 2
+ let zz = az * bz; // 3
+ let xy_pairs = ((ax + ay) * &(bx + by)) - &(xx + &yy); // 4, 5, 6, 7, 8
+ let yz_pairs = ((ay + az) * &(by + bz)) - &(yy + &zz); // 9, 10, 11, 12, 13
+ let xz_pairs = ((ax + az) * &(bx + bz)) - &(xx + &zz); // 14, 15, 16, 17, 18
+
+ let bzz_part = xz_pairs - &(curve_equation_b * &zz); // 19, 20
+ let bzz3_part = bzz_part.double() + &bzz_part; // 21, 22
+ let yy_m_bzz3 = yy - &bzz3_part; // 23
+ let yy_p_bzz3 = yy + &bzz3_part; // 24
+
+ let zz3 = zz.double() + &zz; // 26, 27
+ let bxz_part = (curve_equation_b * &xz_pairs) - &(zz3 + &xx); // 25, 28, 29
+ let bxz3_part = bxz_part.double() + &bxz_part; // 30, 31
+ let xx3_m_zz3 = xx.double() + &xx - &zz3; // 32, 33, 34
+
+ (
+ (yy_p_bzz3 * &xy_pairs) - &(yz_pairs * &bxz3_part), // 35, 39, 40
+ (yy_p_bzz3 * &yy_m_bzz3) + &(xx3_m_zz3 * &bxz3_part), // 36, 37, 38
+ (yy_m_bzz3 * &yz_pairs) + &(xy_pairs * &xx3_m_zz3), // 41, 42, 43
+ )
+}
+
+/// Implements the complete mixed addition formula from
+/// [Renes-Costello-Batina 2015] (Algorithm 5).
+///
+/// [Renes-Costello-Batina 2015]: https://eprint.iacr.org/2015/1060
+#[inline(always)]
+pub fn add_mixed<Fe>(
+ (ax, ay, az): ProjectivePoint<Fe>,
+ (bx, by): AffinePoint<Fe>,
+ curve_equation_b: Fe,
+) -> ProjectivePoint<Fe>
+where
+ Fe: Field,
+{
+ // The comments after each line indicate which algorithm steps are being
+ // performed.
+ let xx = ax * &bx; // 1
+ let yy = ay * &by; // 2
+ let xy_pairs = ((ax + &ay) * &(bx + &by)) - &(xx + &yy); // 3, 4, 5, 6, 7
+ let yz_pairs = (by * &az) + &ay; // 8, 9 (t4)
+ let xz_pairs = (bx * &az) + &ax; // 10, 11 (y3)
+
+ let bz_part = xz_pairs - &(curve_equation_b * &az); // 12, 13
+ let bz3_part = bz_part.double() + &bz_part; // 14, 15
+ let yy_m_bzz3 = yy - &bz3_part; // 16
+ let yy_p_bzz3 = yy + &bz3_part; // 17
+
+ let z3 = az.double() + &az; // 19, 20
+ let bxz_part = (curve_equation_b * &xz_pairs) - &(z3 + &xx); // 18, 21, 22
+ let bxz3_part = bxz_part.double() + &bxz_part; // 23, 24
+ let xx3_m_zz3 = xx.double() + &xx - &z3; // 25, 26, 27
+
+ (
+ (yy_p_bzz3 * &xy_pairs) - &(yz_pairs * &bxz3_part), // 28, 32, 33
+ (yy_p_bzz3 * &yy_m_bzz3) + &(xx3_m_zz3 * &bxz3_part), // 29, 30, 31
+ (yy_m_bzz3 * &yz_pairs) + &(xy_pairs * &xx3_m_zz3), // 34, 35, 36
+ )
+}
+
+/// Implements the exception-free point doubling formula from
+/// [Renes-Costello-Batina 2015] (Algorithm 6).
+///
+/// [Renes-Costello-Batina 2015]: https://eprint.iacr.org/2015/1060
+#[inline(always)]
+pub fn double<Fe>((x, y, z): ProjectivePoint<Fe>, curve_equation_b: Fe) -> ProjectivePoint<Fe>
+where
+ Fe: Field,
+{
+ // The comments after each line indicate which algorithm steps are being
+ // performed.
+ let xx = x.square(); // 1
+ let yy = y.square(); // 2
+ let zz = z.square(); // 3
+ let xy2 = (x * &y).double(); // 4, 5
+ let xz2 = (x * &z).double(); // 6, 7
+
+ let bzz_part = (curve_equation_b * &zz) - &xz2; // 8, 9
+ let bzz3_part = bzz_part.double() + &bzz_part; // 10, 11
+ let yy_m_bzz3 = yy - &bzz3_part; // 12
+ let yy_p_bzz3 = yy + &bzz3_part; // 13
+ let y_frag = yy_p_bzz3 * &yy_m_bzz3; // 14
+ let x_frag = yy_m_bzz3 * &xy2; // 15
+
+ let zz3 = zz.double() + &zz; // 16, 17
+ let bxz2_part = (curve_equation_b * &xz2) - &(zz3 + &xx); // 18, 19, 20
+ let bxz6_part = bxz2_part.double() + &bxz2_part; // 21, 22
+ let xx3_m_zz3 = xx.double() + &xx - &zz3; // 23, 24, 25
+
+ let dy = y_frag + &(xx3_m_zz3 * &bxz6_part); // 26, 27
+ let yz2 = (y * &z).double(); // 28, 29
+ let dx = x_frag - &(bxz6_part * &yz2); // 30, 31
+ let dz = (yz2 * &yy).double().double(); // 32, 33, 34
+
+ (dx, dy, dz)
+}
diff --git a/vendor/elliptic-curve/tests/examples/pkcs8-private-key.der b/vendor/elliptic-curve/tests/examples/pkcs8-private-key.der
new file mode 100644
index 000000000..c0de45ef2
--- /dev/null
+++ b/vendor/elliptic-curve/tests/examples/pkcs8-private-key.der
Binary files differ
diff --git a/vendor/elliptic-curve/tests/examples/pkcs8-private-key.pem b/vendor/elliptic-curve/tests/examples/pkcs8-private-key.pem
new file mode 100644
index 000000000..62f432c74
--- /dev/null
+++ b/vendor/elliptic-curve/tests/examples/pkcs8-private-key.pem
@@ -0,0 +1,5 @@
+-----BEGIN PRIVATE KEY-----
+MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgaWJBcVYaYzQN4OfY
+afKgVJJVjhoEhotqn4VKhmeIGI2hRANCAAQcrP+1Xy8s79idies3SyaBFSRSgC3u
+oJkWBoE32DnPf8SBpESSME1+9mrBF77+g6jQjxVfK1L59hjdRHApBI4P
+-----END PRIVATE KEY----- \ No newline at end of file
diff --git a/vendor/elliptic-curve/tests/examples/pkcs8-public-key.der b/vendor/elliptic-curve/tests/examples/pkcs8-public-key.der
new file mode 100644
index 000000000..67c719c76
--- /dev/null
+++ b/vendor/elliptic-curve/tests/examples/pkcs8-public-key.der
Binary files differ
diff --git a/vendor/elliptic-curve/tests/examples/pkcs8-public-key.pem b/vendor/elliptic-curve/tests/examples/pkcs8-public-key.pem
new file mode 100644
index 000000000..ee7e5b612
--- /dev/null
+++ b/vendor/elliptic-curve/tests/examples/pkcs8-public-key.pem
@@ -0,0 +1,4 @@
+-----BEGIN PUBLIC KEY-----
+MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEHKz/tV8vLO/YnYnrN0smgRUkUoAt
+7qCZFgaBN9g5z3/EgaREkjBNfvZqwRe+/oOo0I8VXytS+fYY3URwKQSODw==
+-----END PUBLIC KEY-----
diff --git a/vendor/elliptic-curve/tests/pkcs8.rs b/vendor/elliptic-curve/tests/pkcs8.rs
new file mode 100644
index 000000000..cffb06802
--- /dev/null
+++ b/vendor/elliptic-curve/tests/pkcs8.rs
@@ -0,0 +1,55 @@
+//! PKCS#8 tests
+
+#![cfg(all(feature = "dev", feature = "pkcs8"))]
+
+use elliptic_curve::{
+ dev::{PublicKey, SecretKey},
+ pkcs8::{DecodePrivateKey, DecodePublicKey, EncodePrivateKey},
+ sec1::ToEncodedPoint,
+};
+use hex_literal::hex;
+
+/// DER-encoded PKCS#8 public key
+const PKCS8_PUBLIC_KEY_DER: &[u8; 91] = include_bytes!("examples/pkcs8-public-key.der");
+
+/// PEM-encoded PKCS#8 public key
+#[cfg(feature = "pem")]
+const PKCS8_PUBLIC_KEY_PEM: &str = include_str!("examples/pkcs8-public-key.pem");
+
+/// Example encoded scalar value
+const EXAMPLE_SCALAR: [u8; 32] =
+ hex!("AABBCCDDEEFF0000000000000000000000000000000000000000000000000001");
+
+/// Example PKCS#8 private key
+fn example_private_key() -> der::SecretDocument {
+ SecretKey::from_be_bytes(&EXAMPLE_SCALAR)
+ .unwrap()
+ .to_pkcs8_der()
+ .unwrap()
+}
+
+#[test]
+fn decode_pkcs8_private_key_from_der() {
+ let secret_key = SecretKey::from_pkcs8_der(example_private_key().as_bytes()).unwrap();
+ assert_eq!(secret_key.to_be_bytes().as_slice(), &EXAMPLE_SCALAR);
+}
+
+#[test]
+fn decode_pkcs8_public_key_from_der() {
+ let public_key = PublicKey::from_public_key_der(&PKCS8_PUBLIC_KEY_DER[..]).unwrap();
+ let expected_sec1_point = hex!("041CACFFB55F2F2CEFD89D89EB374B2681152452802DEEA09916068137D839CF7FC481A44492304D7EF66AC117BEFE83A8D08F155F2B52F9F618DD447029048E0F");
+ assert_eq!(
+ public_key.to_encoded_point(false).as_bytes(),
+ &expected_sec1_point[..]
+ );
+}
+
+#[test]
+#[cfg(feature = "pem")]
+fn decode_pkcs8_public_key_from_pem() {
+ let public_key = PKCS8_PUBLIC_KEY_PEM.parse::<PublicKey>().unwrap();
+
+ // Ensure key parses equivalently to DER
+ let der_key = PublicKey::from_public_key_der(&PKCS8_PUBLIC_KEY_DER[..]).unwrap();
+ assert_eq!(public_key, der_key);
+}
diff --git a/vendor/elliptic-curve/tests/secret_key.rs b/vendor/elliptic-curve/tests/secret_key.rs
new file mode 100644
index 000000000..50e5a95cb
--- /dev/null
+++ b/vendor/elliptic-curve/tests/secret_key.rs
@@ -0,0 +1,10 @@
+//! Secret key tests
+
+#![cfg(feature = "dev")]
+
+use elliptic_curve::dev::SecretKey;
+
+#[test]
+fn undersize_secret_key() {
+ assert!(SecretKey::from_be_bytes(&[]).is_err());
+}