summaryrefslogtreecommitdiffstats
path: root/vendor/ecdsa
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/ecdsa
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/ecdsa')
-rw-r--r--vendor/ecdsa/.cargo-checksum.json1
-rw-r--r--vendor/ecdsa/CHANGELOG.md455
-rw-r--r--vendor/ecdsa/Cargo.toml126
-rw-r--r--vendor/ecdsa/LICENSE-APACHE201
-rw-r--r--vendor/ecdsa/LICENSE-MIT25
-rw-r--r--vendor/ecdsa/README.md93
-rw-r--r--vendor/ecdsa/src/der.rs349
-rw-r--r--vendor/ecdsa/src/dev.rs221
-rw-r--r--vendor/ecdsa/src/hazmat.rs261
-rw-r--r--vendor/ecdsa/src/lib.rs421
-rw-r--r--vendor/ecdsa/src/recovery.rs110
-rw-r--r--vendor/ecdsa/src/sign.rs424
-rw-r--r--vendor/ecdsa/src/verify.rs325
-rw-r--r--vendor/ecdsa/tests/lib.rs14
14 files changed, 3026 insertions, 0 deletions
diff --git a/vendor/ecdsa/.cargo-checksum.json b/vendor/ecdsa/.cargo-checksum.json
new file mode 100644
index 000000000..3f233a5f2
--- /dev/null
+++ b/vendor/ecdsa/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"CHANGELOG.md":"3ce4bb9d644207d6be3015fb14fb8b21b5a5b1726d6e23e518069c09b72c3c6d","Cargo.toml":"8251cd573e1cccd72cc28d182555834efeced8c9b9b9d8b6f66dc45e66d7c88c","LICENSE-APACHE":"78779d420019e6b4630376af8e86b6b335ee8a2f89ede6e0411e0469a326aaa4","LICENSE-MIT":"bdebaf9156a298f8fdab56dd26cb5144673de522d80f4c0d88e0039145f147f9","README.md":"5b6363fc1dc18b5ea22dcb4e11481abd2c9fff9a5bce268296e119dc23cdc3d6","src/der.rs":"496d7b6047b4d346fa76c00b07db2cec06d935e552ced3abb939ea2a84a38c38","src/dev.rs":"2403e76837802f1587ea9b7da7ce62f6ae65b431691977f31bce71ae36639a05","src/hazmat.rs":"7baab4647e5e9fb2d918c69a8df557aef41e4b5cc92fc964592f315798603e40","src/lib.rs":"8a9f7e22c1ffe206eaaf0844ca4eaea29910f7cfd6dd61e3c95b1297c01931b0","src/recovery.rs":"7dd92127de3b33883ca1bf1eaadd4ce8176febe9b5c1353dc31fbee0c092a611","src/sign.rs":"6c360d0292e23c21dc5274a08ab98c5005df4b83a8d22871cfc91d4c413b0511","src/verify.rs":"19a759a7a8db7e0b17cbf6ba69a8fe2634089546b31a6423d86f8b693a6f1d7d","tests/lib.rs":"68922b3fb793f7f64a6fdf8aa59b6fb9432d4706d7ad1d82129a8337c5cf6568"},"package":"413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c"} \ No newline at end of file
diff --git a/vendor/ecdsa/CHANGELOG.md b/vendor/ecdsa/CHANGELOG.md
new file mode 100644
index 000000000..ba65d59cf
--- /dev/null
+++ b/vendor/ecdsa/CHANGELOG.md
@@ -0,0 +1,455 @@
+# 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.14.8 (2022-09-27)
+### Added
+- Impl `From<SigningKey>` for `SecretKey` ([#548])
+
+### Fixed
+- Prehash must receive zero-pads on left ([#547])
+
+[#547]: https://github.com/RustCrypto/signatures/pull/547
+[#548]: https://github.com/RustCrypto/signatures/pull/548
+
+## 0.14.7 (2022-09-15)
+### Changed
+- Relax `Keypair` bounds ([#539])
+
+[#539]: https://github.com/RustCrypto/signatures/pull/539
+
+## 0.14.6 (2022-09-12)
+### Added
+- Impl `signature::hazmat::{PrehashSigner, PrehashVerifier}` ([#534])
+- Impl `signature::Keypair` for `SigningKey` ([#535])
+
+[#534]: https://github.com/RustCrypto/signatures/pull/534
+[#535]: https://github.com/RustCrypto/signatures/pull/535
+
+## 0.14.5 (2022-09-06)
+### Added
+- Impl `EncodePrivateKey` for `SigningKey` ([#523])
+- `SigningKey::as_nonzero_scalar` ([#528])
+- `VerifyingKey::as_affine` ([#528])
+- `RecoveryId::from_byte` ([#531])
+
+### Changed
+- Make `RecoveryId` methods `const fn` ([#529])
+
+[#523]: https://github.com/RustCrypto/signatures/pull/523
+[#528]: https://github.com/RustCrypto/signatures/pull/528
+[#529]: https://github.com/RustCrypto/signatures/pull/529
+[#531]: https://github.com/RustCrypto/signatures/pull/531
+
+## 0.14.4 (2022-08-15)
+### Added
+- Impl `EncodePublicKey` for `VerifyingKey` ([#505])
+- ZeroizeOnDrop marker for SigningKey ([#509])
+
+### Changed
+- Restrict `signature` version to v1.5-v1.6 ([#508], [#512])
+
+[#505]: https://github.com/RustCrypto/signatures/pull/505
+[#508]: https://github.com/RustCrypto/signatures/pull/508
+[#509]: https://github.com/RustCrypto/signatures/pull/509
+[#512]: https://github.com/RustCrypto/signatures/pull/512
+
+## 0.14.3 (2022-06-26) [YANKED]
+### Changed
+- Simplified digest trait bounds ([#499])
+- Bump `rfc6979` dependency to v0.3 ([#500])
+
+[#499]: https://github.com/RustCrypto/signatures/pull/499
+[#500]: https://github.com/RustCrypto/signatures/pull/500
+
+## 0.14.2 (2022-06-17) [YANKED]
+### Added
+- Security warning in README.md ([#486])
+
+### Changed
+- Use `serdect` for `Signature` types ([#497])
+
+[#486]: https://github.com/RustCrypto/signatures/pull/486
+[#497]: https://github.com/RustCrypto/signatures/pull/497
+
+## 0.14.1 (2022-05-09) [YANKED]
+### Added
+- `SignPrimitive::try_sign_digest_rfc6979` ([#475])
+- `VerifyPrimitive::verify_digest` ([#475])
+
+[#475]: https://github.com/RustCrypto/signatures/pull/475
+
+## 0.14.0 (2022-05-09) [YANKED]
+### Added
+- `VerifyingKey::from_affine` ([#452])
+
+### Changed
+- Bump `digest` dependency to v0.10 ([#433])
+- `SignPrimitive` and `VerifyPrimitive` to accept `FieldBytes<C>` rather than `Scalar<C>` ([#460])
+- Replace `hazmat::rfc6979_generate_k` with `SignPrimitive::try_sign_prehashed_rfc6979` ([#460])
+- Bump `der` dependency to v0.6 ([#468])
+- Bump `elliptic-curve` dependency to v0.12 ([#468])
+- Bump `rfc6979` dependency to v0.2 ([#470])
+
+[#433]: https://github.com/RustCrypto/signatures/pull/433
+[#452]: https://github.com/RustCrypto/signatures/pull/452
+[#460]: https://github.com/RustCrypto/signatures/pull/460
+[#468]: https://github.com/RustCrypto/signatures/pull/468
+[#470]: https://github.com/RustCrypto/signatures/pull/470
+
+## 0.13.4 (2022-01-06)
+### Added
+- `Signature::to_vec` ([#428])
+
+[#428]: https://github.com/RustCrypto/signatures/pull/428
+
+## 0.13.3 (2021-12-04)
+### Changed
+- Use revised `LinearCombination` trait ([#419])
+
+[#419]: https://github.com/RustCrypto/signatures/pull/419
+
+## 0.13.2 (2021-12-04) [YANKED]
+### Changed
+- Use `LinearCombination` trait ([#417])
+
+[#417]: https://github.com/RustCrypto/signatures/pull/417
+
+## 0.13.1 (2021-12-03) [YANKED]
+### Added
+- `hazmat::rfc6979_generate_k` function ([#414])
+
+[#414]: https://github.com/RustCrypto/signatures/pull/414
+
+## 0.13.0 (2021-11-21) [YANKED]
+### Added
+- `RecoveryId` type ([#392])
+- Default generic impl of `SignPrimitive::try_sign_prehashed` ([#396])
+- Default generic impl of `VerifyPrimitive::verify_prehashed` ([#397])
+- `serde` support ([#406])
+
+### Changed
+- Make `Signature::normalize_s` non-mutating ([#355])
+- Switch from `ScalarBytes<C>` to `ScalarCore<C>` ([#356])
+- Use `PrimeCurve` trait ([#357])
+- Replace `FromDigest` trait with `Reduce` ([#372])
+- 2021 edition upgrade; MSRV 1.56 ([#384])
+- Allow `signature` v1.4 as a dependency ([#385])
+- Bump `der` dependency to v0.5 ([#408])
+- Bump `elliptic-curve` dependency to v0.11 ([#408])
+- Split out `rfc6979` crate ([#409])
+
+### Removed
+- `NormalizeLow` trait ([#393])
+- `RecoverableSignPrimitive` ([#394])
+
+[#355]: https://github.com/RustCrypto/signatures/pull/355
+[#356]: https://github.com/RustCrypto/signatures/pull/356
+[#357]: https://github.com/RustCrypto/signatures/pull/357
+[#372]: https://github.com/RustCrypto/signatures/pull/372
+[#384]: https://github.com/RustCrypto/signatures/pull/384
+[#385]: https://github.com/RustCrypto/signatures/pull/385
+[#392]: https://github.com/RustCrypto/signatures/pull/392
+[#393]: https://github.com/RustCrypto/signatures/pull/393
+[#394]: https://github.com/RustCrypto/signatures/pull/394
+[#396]: https://github.com/RustCrypto/signatures/pull/396
+[#397]: https://github.com/RustCrypto/signatures/pull/397
+[#406]: https://github.com/RustCrypto/signatures/pull/406
+[#408]: https://github.com/RustCrypto/signatures/pull/408
+[#409]: https://github.com/RustCrypto/signatures/pull/409
+
+## 0.12.4 (2021-08-12)
+### Added
+- Impl `Clone`, `Debug`, `*Eq` for `SigningKey` ([#345])
+
+[#345]: https://github.com/RustCrypto/signatures/pull/345
+
+## 0.12.3 (2021-06-17)
+### Added
+- Impl `TryFrom<&[u8]>` for `Verifying<C>` ([#329])
+- Impl `TryFrom<&[u8]>` for `SigningKey<C>` ([#330])
+
+### Changed
+- Use `signature::Result` alias ([#331])
+
+[#329]: https://github.com/RustCrypto/signatures/pull/329
+[#330]: https://github.com/RustCrypto/signatures/pull/330
+[#331]: https://github.com/RustCrypto/signatures/pull/331
+
+## 0.12.2 (2021-06-18)
+### Added
+- Zeroization on drop for `SigningKey` ([#321])
+
+[#321]: https://github.com/RustCrypto/signatures/pull/321
+
+## 0.12.1 (2021-06-09)
+### Added
+- Explicit `Copy` bounds on `VerifyingKey` ([#318])
+
+[#318]: https://github.com/RustCrypto/signatures/pull/318
+
+## 0.12.0 (2021-06-07)
+### Changed
+- Bump `der` crate to v0.4 ([#302], [#315])
+- Bump `elliptic-curve` crate dependency to v0.10 ([#315])
+- MSRV 1.51+ ([#302], [#315])
+
+### Removed
+- Bounds now expressed via `*Arithmetic` traits ([#303], [#312])
+
+[#302]: https://github.com/RustCrypto/signatures/pull/302
+[#303]: https://github.com/RustCrypto/signatures/pull/303
+[#315]: https://github.com/RustCrypto/signatures/pull/315
+
+## 0.11.1 (2021-05-24)
+### Added
+- `Ord` and `PartialOrd` impls on VerifyingKey ([#298], [#299])
+
+### Changed
+- Bump `elliptic-curve` dependency to v0.9.12 ([#299])
+
+[#298]: https://github.com/RustCrypto/signatures/pull/298
+[#299]: https://github.com/RustCrypto/signatures/pull/299
+
+## 0.11.0 (2021-04-29)
+### Added
+- `FromDigest` trait ([#238], [#244])
+- Wycheproof test vector support ([#260])
+
+### Changed
+- Use `der` crate for decoding/encoding signatures ([#226], [#267])
+- Support `HmacDrbg` with variable output size ([#243])
+- Bump `base64ct` and `pkcs8`; MSRV 1.47+ ([#262])
+- Flatten and simplify public API ([#268])
+- Use `verifying_key` name consistently ([#273])
+- Bound curve implementations on Order trait ([#280])
+- Bump `elliptic-curve` to v0.9.10+; use `ScalarBytes` ([#284])
+- Bump `hmac` crate dependency to v0.11 ([#287])
+
+### Removed
+- `FieldBytes` bounds ([#227])
+- `CheckSignatureBytes` trait ([#281])
+
+[#226]: https://github.com/RustCrypto/signatures/pull/226
+[#227]: https://github.com/RustCrypto/signatures/pull/227
+[#238]: https://github.com/RustCrypto/signatures/pull/238
+[#243]: https://github.com/RustCrypto/signatures/pull/243
+[#244]: https://github.com/RustCrypto/signatures/pull/244
+[#260]: https://github.com/RustCrypto/signatures/pull/260
+[#262]: https://github.com/RustCrypto/signatures/pull/262
+[#267]: https://github.com/RustCrypto/signatures/pull/267
+[#268]: https://github.com/RustCrypto/signatures/pull/268
+[#273]: https://github.com/RustCrypto/signatures/pull/273
+[#280]: https://github.com/RustCrypto/signatures/pull/280
+[#281]: https://github.com/RustCrypto/signatures/pull/281
+[#284]: https://github.com/RustCrypto/signatures/pull/284
+[#287]: https://github.com/RustCrypto/signatures/pull/287
+
+## 0.10.2 (2020-12-22)
+### Changed
+- Bump `elliptic-curve` crate to v0.8.3 ([#218])
+- Use the `dev` module from the `elliptic-curve` crate ([#218])
+
+[#218]: https://github.com/RustCrypto/signatures/pull/218
+
+## 0.10.1 (2020-12-16) [YANKED]
+### Fixed
+- Trigger docs.rs rebuild with nightly bugfix ([RustCrypto/traits#412])
+
+[RustCrypto/traits#412]: https://github.com/RustCrypto/traits/pull/412
+
+## 0.10.0 (2020-12-16) [YANKED]
+### Changed
+- Bump `elliptic-curve` dependency to v0.8 ([#215])
+
+[#215]: https://github.com/RustCrypto/signatures/pull/215
+
+## 0.9.0 (2020-12-06)
+### Added
+- PKCS#8 support ([#203])
+
+### Changed
+- Bump `elliptic-curve` crate dependency to v0.7; MSRV 1.46+ ([#204])
+- Rename `VerifyKey` to `VerifyingKey` ([#200])
+- Rename `VerifyingKey::new()` to `::from_sec1_bytes()` ([#198])
+- Rename `SigningKey::new()` to `::from_bytes()` ([#205])
+
+### Fixed
+- Additional validity checks on ASN.1 DER-encoded signatures ([#192])
+
+[#205]: https://github.com/RustCrypto/signatures/pull/205
+[#204]: https://github.com/RustCrypto/signatures/pull/204
+[#203]: https://github.com/RustCrypto/signatures/pull/203
+[#200]: https://github.com/RustCrypto/signatures/pull/200
+[#198]: https://github.com/RustCrypto/signatures/pull/198
+[#192]: https://github.com/RustCrypto/signatures/pull/192
+
+## 0.8.5 (2020-10-09)
+### Fixed
+- Bug in default impl of CheckSignatureBytes ([#184])
+
+[#184]: https://github.com/RustCrypto/signatures/pull/184
+
+## 0.8.4 (2020-10-08)
+### Fixed
+- Work around `nightly-2020-10-06` breakage ([#180])
+
+[#180]: https://github.com/RustCrypto/signatures/pull/180
+
+## 0.8.3 (2020-09-28)
+### Fixed
+- 32-bit builds for the `dev` feature ([#177])
+
+[#177]: https://github.com/RustCrypto/signatures/pull/177
+
+## 0.8.2 (2020-09-27)
+### Added
+- `RecoverableSignPrimitive` ([#174], [#175])
+
+[#174]: https://github.com/RustCrypto/signatures/pull/174
+[#175]: https://github.com/RustCrypto/signatures/pull/175
+
+## 0.8.1 (2020-09-23)
+### Added
+- Conditional `Copy` impl on `VerifyKey<C>` ([#171])
+
+[#171]: https://github.com/RustCrypto/signatures/pull/171
+
+## 0.8.0 (2020-09-11)
+### Added
+- `CheckSignatureBytes` trait ([#151])
+- Add `Signature::r`/`::s` methods which return `NonZeroScalar`values ([#151])
+- `alloc` feature ([#150])
+- Impl `From<&VerifyKey<C>>` for `EncodedPoint<C>` ([#144])
+- Serialization methods for `SigningKey`/`VerifyKey` ([#143])
+- RFC6979-based deterministic signatures ([#133], [#134], [#136])
+
+### Changed
+- Bump `elliptic-curve` crate dependency to v0.6 ([#165])
+- Use `ProjectiveArithmetic` trait ([#164])
+- Rename `ElementBytes` to `FieldBytes` ([#160])
+- Use `ff` and `group` crates to v0.8 ([#156])
+- MSRV 1.44+ ([#156])
+- Remove `rand` feature; make `rand_core` a hard dependency ([#154])
+- Use `impl Into<ElementBytes>` bounds on `Signature::from_scalars` ([#149])
+- Derive `Clone`, `Debug`, `Eq`, and `Ord` on `VerifyKey` ([#148])
+- Renamed `{Signer, Verifier}` => `{SigningKey, VerifyKey}` ([#140])
+- Use newly refactored `sec1::EncodedPoint` ([#131])
+
+### Removed
+- `Generate` trait ([#159])
+- `RecoverableSignPrimitive` ([#146])
+
+[#165]: https://github.com/RustCrypto/signatures/pull/165
+[#164]: https://github.com/RustCrypto/signatures/pull/164
+[#160]: https://github.com/RustCrypto/signatures/pull/160
+[#159]: https://github.com/RustCrypto/signatures/pull/159
+[#156]: https://github.com/RustCrypto/signatures/pull/156
+[#154]: https://github.com/RustCrypto/signatures/pull/154
+[#151]: https://github.com/RustCrypto/signatures/pull/151
+[#150]: https://github.com/RustCrypto/signatures/pull/150
+[#149]: https://github.com/RustCrypto/signatures/pull/149
+[#148]: https://github.com/RustCrypto/signatures/pull/148
+[#146]: https://github.com/RustCrypto/signatures/pull/146
+[#144]: https://github.com/RustCrypto/signatures/pull/144
+[#143]: https://github.com/RustCrypto/signatures/pull/143
+[#140]: https://github.com/RustCrypto/signatures/pull/140
+[#136]: https://github.com/RustCrypto/signatures/pull/136
+[#134]: https://github.com/RustCrypto/signatures/pull/134
+[#133]: https://github.com/RustCrypto/signatures/pull/133
+[#131]: https://github.com/RustCrypto/signatures/pull/131
+
+## 0.7.2 (2020-08-11)
+### Added
+- Conditional `PrehashSignature` impl for `asn1::Signature` ([#128])
+
+[#128]: https://github.com/RustCrypto/signatures/pull/128
+
+## 0.7.1 (2020-08-10)
+### Changed
+- Use `all-features = true` on docs.rs ([#126])
+
+[#126]: https://github.com/RustCrypto/signatures/pull/126
+
+## 0.7.0 (2020-08-10)
+### Added
+- `hazmat` traits: `SignPrimitive`, `RecoverableSignPrimitive`,
+ `VerifyPrimitive`, `DigestPrimitive` ([#96], [#99], [#107], [#111])
+- `dev` module ([#103])
+- `NormalizeLow` trait ([#115], [#118], [#119])
+- `Copy` impl on `Signature` ([#117])
+- `RecoverableSignPrimitive` ([#120])
+
+### Changed
+- Bumped `elliptic-curve` crate to v0.5 release ([#123])
+- Renamed `FixedSignature` to `ecdsa::Signature` ([#98])
+- Renamed `Asn1Signature` to `ecdsa::asn1::Signature` ([#98], [#102])
+
+### Removed
+- Curve-specific types - migrated to `k256`, `p256`, `p384` crates ([#96])
+
+[#96]: https://github.com/RustCrypto/signatures/pull/96
+[#98]: https://github.com/RustCrypto/signatures/pull/98
+[#99]: https://github.com/RustCrypto/signatures/pull/99
+[#102]: https://github.com/RustCrypto/signatures/pull/102
+[#103]: https://github.com/RustCrypto/signatures/pull/103
+[#107]: https://github.com/RustCrypto/signatures/pull/107
+[#111]: https://github.com/RustCrypto/signatures/pull/111
+[#115]: https://github.com/RustCrypto/signatures/pull/115
+[#117]: https://github.com/RustCrypto/signatures/pull/117
+[#118]: https://github.com/RustCrypto/signatures/pull/118
+[#119]: https://github.com/RustCrypto/signatures/pull/119
+[#120]: https://github.com/RustCrypto/signatures/pull/120
+[#123]: https://github.com/RustCrypto/signatures/pull/123
+
+## 0.6.1 (2020-06-29)
+### Added
+- `doc_cfg` attributes for https://docs.rs ([#91])
+- `ecdsa::curve::secp256k1::RecoverableSignature` ([#90])
+
+[#91]: https://github.com/RustCrypto/signatures/pull/91
+[#90]: https://github.com/RustCrypto/signatures/pull/90
+
+## 0.6.0 (2020-06-09)
+### Changed
+- Upgrade to `signature` ~1.1.0; `sha` v0.9 ([#87])
+- Bump all elliptic curve crates; MSRV 1.41+ ([#86])
+
+[#87]: https://github.com/RustCrypto/signatures/pull/87
+[#86]: https://github.com/RustCrypto/signatures/pull/86
+
+## 0.5.0 (2020-04-18)
+### Changed
+- Upgrade `signature` crate to v1.0 final release ([#80])
+
+[#80]: https://github.com/RustCrypto/signatures/pull/80
+
+## 0.4.0 (2020-01-07)
+### Changed
+- Upgrade `elliptic-curve` crate to v0.3.0; make curves cargo features ([#68])
+
+[#68]: https://github.com/RustCrypto/signatures/pull/68
+
+## 0.3.0 (2019-12-11)
+### Changed
+- Upgrade `elliptic-curve` crate to v0.2.0; MSRV 1.37+ ([#65])
+
+[#65]: https://github.com/RustCrypto/signatures/pull/65
+
+## 0.2.1 (2019-12-06)
+### Added
+- Re-export `PublicKey` and `SecretKey` from the `elliptic-curve` crate ([#61])
+
+[#61]: https://github.com/RustCrypto/signatures/pull/61
+
+## 0.2.0 (2019-12-06)
+### Changed
+- Use curve types from the `elliptic-curve` crate ([#58])
+
+[#58]: https://github.com/RustCrypto/signatures/pull/58
+
+## 0.1.0 (2019-10-29)
+
+- Initial release
diff --git a/vendor/ecdsa/Cargo.toml b/vendor/ecdsa/Cargo.toml
new file mode 100644
index 000000000..62a5410a5
--- /dev/null
+++ b/vendor/ecdsa/Cargo.toml
@@ -0,0 +1,126 @@
+# 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 = "ecdsa"
+version = "0.14.8"
+authors = ["RustCrypto Developers"]
+description = """
+Pure Rust implementation of the Elliptic Curve Digital Signature Algorithm
+(ECDSA) as specified in FIPS 186-4 (Digital Signature Standard), providing
+RFC6979 deterministic signatures as well as support for added entropy
+"""
+readme = "README.md"
+keywords = [
+ "crypto",
+ "ecc",
+ "nist",
+ "secp256k1",
+ "signature",
+]
+categories = [
+ "cryptography",
+ "no-std",
+]
+license = "Apache-2.0 OR MIT"
+repository = "https://github.com/RustCrypto/signatures/tree/master/ecdsa"
+
+[package.metadata.docs.rs]
+all-features = true
+rustdoc-args = [
+ "--cfg",
+ "docsrs",
+]
+
+[dependencies.der]
+version = "0.6"
+optional = true
+
+[dependencies.elliptic-curve]
+version = "0.12"
+features = [
+ "digest",
+ "sec1",
+]
+default-features = false
+
+[dependencies.rfc6979]
+version = "0.3"
+optional = true
+
+[dependencies.serdect]
+version = "0.1"
+features = ["alloc"]
+optional = true
+default-features = false
+
+[dependencies.signature]
+version = ">=1.6.2, <1.7"
+features = [
+ "hazmat-preview",
+ "rand-preview",
+]
+default-features = false
+
+[dev-dependencies.elliptic-curve]
+version = "0.12"
+features = ["dev"]
+default-features = false
+
+[dev-dependencies.hex-literal]
+version = "0.3"
+
+[dev-dependencies.sha2]
+version = "0.10"
+default-features = false
+
+[features]
+alloc = []
+arithmetic = ["elliptic-curve/arithmetic"]
+default = ["digest"]
+dev = [
+ "arithmetic",
+ "digest",
+ "elliptic-curve/dev",
+ "hazmat",
+]
+digest = ["signature/digest-preview"]
+hazmat = []
+pem = [
+ "elliptic-curve/pem",
+ "pkcs8",
+]
+pkcs8 = [
+ "elliptic-curve/pkcs8",
+ "der",
+]
+serde = [
+ "elliptic-curve/serde",
+ "serdect",
+]
+sign = [
+ "arithmetic",
+ "digest",
+ "hazmat",
+ "rfc6979",
+]
+std = [
+ "alloc",
+ "elliptic-curve/std",
+ "signature/std",
+]
+verify = [
+ "arithmetic",
+ "digest",
+ "hazmat",
+]
diff --git a/vendor/ecdsa/LICENSE-APACHE b/vendor/ecdsa/LICENSE-APACHE
new file mode 100644
index 000000000..c394d8ad9
--- /dev/null
+++ b/vendor/ecdsa/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 2018-2022 RustCrypto Developers
+
+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/ecdsa/LICENSE-MIT b/vendor/ecdsa/LICENSE-MIT
new file mode 100644
index 000000000..81a3d57ac
--- /dev/null
+++ b/vendor/ecdsa/LICENSE-MIT
@@ -0,0 +1,25 @@
+Copyright (c) 2018-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/ecdsa/README.md b/vendor/ecdsa/README.md
new file mode 100644
index 000000000..6da609998
--- /dev/null
+++ b/vendor/ecdsa/README.md
@@ -0,0 +1,93 @@
+# [RustCrypto]: ECDSA
+
+[![crate][crate-image]][crate-link]
+[![Docs][docs-image]][docs-link]
+[![Build Status][build-image]][build-link]
+![Apache2/MIT licensed][license-image]
+![MSRV][rustc-image]
+[![Project Chat][chat-image]][chat-link]
+
+[Elliptic Curve Digital Signature Algorithm (ECDSA)][1] as specified in
+[FIPS 186-4][2] (Digital Signature Standard).
+
+[Documentation][docs-link]
+
+## About
+
+This crate provides generic ECDSA support which can be used in the following
+ways:
+
+- Generic implementation of ECDSA usable with the following crates:
+ - [`k256`] (secp256k1)
+ - [`p256`] (NIST P-256)
+ - [`p384`] (NIST P-384)
+- Other crates which provide their own complete implementations of ECDSA can
+ also leverage the types from this crate to export ECDSA functionality in a
+ generic, interoperable way by leveraging [`ecdsa::Signature`] with the
+ [`signature::Signer`] and [`signature::Verifier`] traits.
+
+## โš ๏ธ Security Warning
+
+The ECDSA implementation contained in this crate has never been independently
+audited for security!
+
+This crate contains a generic implementation of ECDSA which must be
+instantiated using a separate crate providing a concrete implementation of
+arithmetic for a particular curve. It's possible timing variability can exist
+in concrete curve implementations, and thus this crate's security can only be
+properly assessed for a specific elliptic curve.
+
+USE AT YOUR OWN RISK!
+
+## Minimum Supported Rust Version
+
+This crate requires **Rust 1.57** at a minimum.
+
+We may change the MSRV in the future, but it will be accompanied by a minor
+version bump.
+
+## 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/ecdsa
+[crate-link]: https://crates.io/crates/ecdsa
+[docs-image]: https://docs.rs/ecdsa/badge.svg
+[docs-link]: https://docs.rs/ecdsa/
+[build-image]: https://github.com/RustCrypto/signatures/actions/workflows/ecdsa.yml/badge.svg
+[build-link]: https://github.com/RustCrypto/signatures/actions/workflows/ecdsa.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/260048-signatures
+
+[//]: # (links)
+
+[RustCrypto]: https://github.com/RustCrypto
+
+[//]: # (footnotes)
+
+[1]: https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm
+[2]: https://csrc.nist.gov/publications/detail/fips/186/4/final
+
+[//]: # (docs.rs definitions)
+
+[`ecdsa::Signature`]: https://docs.rs/ecdsa/latest/ecdsa/struct.Signature.html
+[`k256`]: https://docs.rs/k256
+[`p256`]: https://docs.rs/p256
+[`p384`]: https://docs.rs/p384
+[`signature::Signer`]: https://docs.rs/signature/latest/signature/trait.Signer.html
+[`signature::Verifier`]: https://docs.rs/signature/latest/signature/trait.Verifier.html
diff --git a/vendor/ecdsa/src/der.rs b/vendor/ecdsa/src/der.rs
new file mode 100644
index 000000000..5925df443
--- /dev/null
+++ b/vendor/ecdsa/src/der.rs
@@ -0,0 +1,349 @@
+//! Support for ECDSA signatures encoded as ASN.1 DER.
+
+use crate::{Error, Result};
+use core::{
+ fmt,
+ ops::{Add, Range},
+};
+use der::{asn1::UIntRef, Decode, Encode, Reader};
+use elliptic_curve::{
+ bigint::Encoding as _,
+ consts::U9,
+ generic_array::{ArrayLength, GenericArray},
+ FieldSize, PrimeCurve,
+};
+
+#[cfg(feature = "alloc")]
+use alloc::boxed::Box;
+
+#[cfg(feature = "serde")]
+use serdect::serde::{de, ser, Deserialize, Serialize};
+
+/// Maximum overhead of an ASN.1 DER-encoded ECDSA signature for a given curve:
+/// 9-bytes.
+///
+/// Includes 3-byte ASN.1 DER header:
+///
+/// - 1-byte: ASN.1 `SEQUENCE` tag (0x30)
+/// - 2-byte: length
+///
+/// ...followed by two ASN.1 `INTEGER` values, which each have a header whose
+/// maximum length is the following:
+///
+/// - 1-byte: ASN.1 `INTEGER` tag (0x02)
+/// - 1-byte: length
+/// - 1-byte: zero to indicate value is positive (`INTEGER` is signed)
+pub type MaxOverhead = U9;
+
+/// Maximum size of an ASN.1 DER encoded signature for the given elliptic curve.
+pub type MaxSize<C> = <<FieldSize<C> as Add>::Output as Add<MaxOverhead>>::Output;
+
+/// Byte array containing a serialized ASN.1 signature
+type SignatureBytes<C> = GenericArray<u8, MaxSize<C>>;
+
+/// ASN.1 DER-encoded signature.
+///
+/// Generic over the scalar size of the elliptic curve.
+pub struct Signature<C>
+where
+ C: PrimeCurve,
+ MaxSize<C>: ArrayLength<u8>,
+ <FieldSize<C> as Add>::Output: Add<MaxOverhead> + ArrayLength<u8>,
+{
+ /// ASN.1 DER-encoded signature data
+ bytes: SignatureBytes<C>,
+
+ /// Range of the `r` value within the signature
+ r_range: Range<usize>,
+
+ /// Range of the `s` value within the signature
+ s_range: Range<usize>,
+}
+
+impl<C> signature::Signature for Signature<C>
+where
+ C: PrimeCurve,
+ MaxSize<C>: ArrayLength<u8>,
+ <FieldSize<C> as Add>::Output: Add<MaxOverhead> + ArrayLength<u8>,
+{
+ /// Parse an ASN.1 DER-encoded ECDSA signature from a byte slice
+ fn from_bytes(bytes: &[u8]) -> Result<Self> {
+ bytes.try_into()
+ }
+}
+
+#[allow(clippy::len_without_is_empty)]
+impl<C> Signature<C>
+where
+ C: PrimeCurve,
+ MaxSize<C>: ArrayLength<u8>,
+ <FieldSize<C> as Add>::Output: Add<MaxOverhead> + ArrayLength<u8>,
+{
+ /// Get the length of the signature in bytes
+ pub fn len(&self) -> usize {
+ self.s_range.end
+ }
+
+ /// Borrow this signature as a byte slice
+ pub fn as_bytes(&self) -> &[u8] {
+ &self.bytes.as_slice()[..self.len()]
+ }
+
+ /// Serialize this signature as a boxed byte slice
+ #[cfg(feature = "alloc")]
+ pub fn to_bytes(&self) -> Box<[u8]> {
+ self.as_bytes().to_vec().into_boxed_slice()
+ }
+
+ /// Create an ASN.1 DER encoded signature from big endian `r` and `s` scalars
+ pub(crate) fn from_scalar_bytes(r: &[u8], s: &[u8]) -> der::Result<Self> {
+ let r = UIntRef::new(r)?;
+ let s = UIntRef::new(s)?;
+
+ let mut bytes = SignatureBytes::<C>::default();
+ let mut writer = der::SliceWriter::new(&mut bytes);
+
+ writer.sequence((r.encoded_len()? + s.encoded_len()?)?, |seq| {
+ seq.encode(&r)?;
+ seq.encode(&s)
+ })?;
+
+ writer
+ .finish()?
+ .try_into()
+ .map_err(|_| der::Tag::Sequence.value_error())
+ }
+
+ /// Get the `r` component of the signature (leading zeros removed)
+ pub(crate) fn r(&self) -> &[u8] {
+ &self.bytes[self.r_range.clone()]
+ }
+
+ /// Get the `s` component of the signature (leading zeros removed)
+ pub(crate) fn s(&self) -> &[u8] {
+ &self.bytes[self.s_range.clone()]
+ }
+}
+
+impl<C> AsRef<[u8]> for Signature<C>
+where
+ C: PrimeCurve,
+ MaxSize<C>: ArrayLength<u8>,
+ <FieldSize<C> as Add>::Output: Add<MaxOverhead> + ArrayLength<u8>,
+{
+ fn as_ref(&self) -> &[u8] {
+ self.as_bytes()
+ }
+}
+
+impl<C> fmt::Debug for Signature<C>
+where
+ C: PrimeCurve,
+ MaxSize<C>: ArrayLength<u8>,
+ <FieldSize<C> as Add>::Output: Add<MaxOverhead> + ArrayLength<u8>,
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "ecdsa::der::Signature<{:?}>(", C::default())?;
+
+ for &byte in self.as_ref() {
+ write!(f, "{:02X}", byte)?;
+ }
+
+ write!(f, ")")
+ }
+}
+
+impl<C> TryFrom<&[u8]> for Signature<C>
+where
+ C: PrimeCurve,
+ MaxSize<C>: ArrayLength<u8>,
+ <FieldSize<C> as Add>::Output: Add<MaxOverhead> + ArrayLength<u8>,
+{
+ type Error = Error;
+
+ fn try_from(input: &[u8]) -> Result<Self> {
+ let (r, s) = decode_der(input).map_err(|_| Error::new())?;
+
+ if r.as_bytes().len() > C::UInt::BYTE_SIZE || s.as_bytes().len() > C::UInt::BYTE_SIZE {
+ return Err(Error::new());
+ }
+
+ let r_range = find_scalar_range(input, r.as_bytes())?;
+ let s_range = find_scalar_range(input, s.as_bytes())?;
+
+ if s_range.end != input.len() {
+ return Err(Error::new());
+ }
+
+ let mut bytes = SignatureBytes::<C>::default();
+ bytes[..s_range.end].copy_from_slice(input);
+
+ Ok(Signature {
+ bytes,
+ r_range,
+ s_range,
+ })
+ }
+}
+
+impl<C> TryFrom<Signature<C>> for super::Signature<C>
+where
+ C: PrimeCurve,
+ MaxSize<C>: ArrayLength<u8>,
+ <FieldSize<C> as Add>::Output: Add<MaxOverhead> + ArrayLength<u8>,
+{
+ type Error = Error;
+
+ fn try_from(sig: Signature<C>) -> Result<super::Signature<C>> {
+ let mut bytes = super::SignatureBytes::<C>::default();
+ let r_begin = C::UInt::BYTE_SIZE.saturating_sub(sig.r().len());
+ let s_begin = bytes.len().saturating_sub(sig.s().len());
+ bytes[r_begin..C::UInt::BYTE_SIZE].copy_from_slice(sig.r());
+ bytes[s_begin..].copy_from_slice(sig.s());
+ Self::try_from(bytes.as_slice())
+ }
+}
+
+#[cfg(feature = "serde")]
+#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
+impl<C> Serialize for Signature<C>
+where
+ C: PrimeCurve,
+ MaxSize<C>: ArrayLength<u8>,
+ <FieldSize<C> as Add>::Output: Add<MaxOverhead> + ArrayLength<u8>,
+{
+ fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
+ where
+ S: ser::Serializer,
+ {
+ serdect::slice::serialize_hex_upper_or_bin(&self.as_bytes(), serializer)
+ }
+}
+
+#[cfg(feature = "serde")]
+#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
+impl<'de, C> Deserialize<'de> for Signature<C>
+where
+ C: PrimeCurve,
+ MaxSize<C>: ArrayLength<u8>,
+ <FieldSize<C> as Add>::Output: Add<MaxOverhead> + ArrayLength<u8>,
+{
+ fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
+ where
+ D: de::Deserializer<'de>,
+ {
+ let mut buf = SignatureBytes::<C>::default();
+ let slice = serdect::slice::deserialize_hex_or_bin(&mut buf, deserializer)?;
+ Self::try_from(slice).map_err(de::Error::custom)
+ }
+}
+
+/// Decode the `r` and `s` components of a DER-encoded ECDSA signature.
+fn decode_der(der_bytes: &[u8]) -> der::Result<(UIntRef<'_>, UIntRef<'_>)> {
+ let mut reader = der::SliceReader::new(der_bytes)?;
+ let header = der::Header::decode(&mut reader)?;
+ header.tag.assert_eq(der::Tag::Sequence)?;
+
+ let ret = reader.read_nested(header.length, |reader| {
+ let r = UIntRef::decode(reader)?;
+ let s = UIntRef::decode(reader)?;
+ Ok((r, s))
+ })?;
+
+ reader.finish(ret)
+}
+
+/// Locate the range within a slice at which a particular subslice is located
+fn find_scalar_range(outer: &[u8], inner: &[u8]) -> Result<Range<usize>> {
+ let outer_start = outer.as_ptr() as usize;
+ let inner_start = inner.as_ptr() as usize;
+ let start = inner_start
+ .checked_sub(outer_start)
+ .ok_or_else(Error::new)?;
+ let end = start.checked_add(inner.len()).ok_or_else(Error::new)?;
+ Ok(Range { start, end })
+}
+
+#[cfg(all(feature = "digest", feature = "hazmat"))]
+impl<C> signature::PrehashSignature for Signature<C>
+where
+ C: PrimeCurve + crate::hazmat::DigestPrimitive,
+ MaxSize<C>: ArrayLength<u8>,
+ <FieldSize<C> as Add>::Output: Add<MaxOverhead> + ArrayLength<u8>,
+{
+ type Digest = C::Digest;
+}
+
+#[cfg(all(test, feature = "arithmetic"))]
+mod tests {
+ use elliptic_curve::dev::MockCurve;
+ use signature::Signature as _;
+
+ type Signature = crate::Signature<MockCurve>;
+
+ const EXAMPLE_SIGNATURE: [u8; 64] = [
+ 0xf3, 0xac, 0x80, 0x61, 0xb5, 0x14, 0x79, 0x5b, 0x88, 0x43, 0xe3, 0xd6, 0x62, 0x95, 0x27,
+ 0xed, 0x2a, 0xfd, 0x6b, 0x1f, 0x6a, 0x55, 0x5a, 0x7a, 0xca, 0xbb, 0x5e, 0x6f, 0x79, 0xc8,
+ 0xc2, 0xac, 0x8b, 0xf7, 0x78, 0x19, 0xca, 0x5, 0xa6, 0xb2, 0x78, 0x6c, 0x76, 0x26, 0x2b,
+ 0xf7, 0x37, 0x1c, 0xef, 0x97, 0xb2, 0x18, 0xe9, 0x6f, 0x17, 0x5a, 0x3c, 0xcd, 0xda, 0x2a,
+ 0xcc, 0x5, 0x89, 0x3,
+ ];
+
+ #[test]
+ fn test_fixed_to_asn1_signature_roundtrip() {
+ let signature1 = Signature::from_bytes(&EXAMPLE_SIGNATURE).unwrap();
+
+ // Convert to ASN.1 DER and back
+ let asn1_signature = signature1.to_der();
+ let signature2 = Signature::from_der(asn1_signature.as_ref()).unwrap();
+
+ assert_eq!(signature1, signature2);
+ }
+
+ #[test]
+ fn test_asn1_too_short_signature() {
+ assert!(Signature::from_der(&[]).is_err());
+ assert!(Signature::from_der(&[der::Tag::Sequence.into()]).is_err());
+ assert!(Signature::from_der(&[der::Tag::Sequence.into(), 0x00]).is_err());
+ assert!(Signature::from_der(&[
+ der::Tag::Sequence.into(),
+ 0x03,
+ der::Tag::Integer.into(),
+ 0x01,
+ 0x01
+ ])
+ .is_err());
+ }
+
+ #[test]
+ fn test_asn1_non_der_signature() {
+ // A minimal 8-byte ASN.1 signature parses OK.
+ assert!(Signature::from_der(&[
+ der::Tag::Sequence.into(),
+ 0x06, // length of below
+ der::Tag::Integer.into(),
+ 0x01, // length of value
+ 0x01, // value=1
+ der::Tag::Integer.into(),
+ 0x01, // length of value
+ 0x01, // value=1
+ ])
+ .is_ok());
+
+ // But length fields that are not minimally encoded should be rejected, as they are not
+ // valid DER, cf.
+ // https://github.com/google/wycheproof/blob/2196000605e4/testvectors/ecdsa_secp256k1_sha256_test.json#L57-L66
+ assert!(Signature::from_der(&[
+ der::Tag::Sequence.into(),
+ 0x81, // extended length: 1 length byte to come
+ 0x06, // length of below
+ der::Tag::Integer.into(),
+ 0x01, // length of value
+ 0x01, // value=1
+ der::Tag::Integer.into(),
+ 0x01, // length of value
+ 0x01, // value=1
+ ])
+ .is_err());
+ }
+}
diff --git a/vendor/ecdsa/src/dev.rs b/vendor/ecdsa/src/dev.rs
new file mode 100644
index 000000000..ce00c7fbf
--- /dev/null
+++ b/vendor/ecdsa/src/dev.rs
@@ -0,0 +1,221 @@
+//! Development-related functionality.
+
+// TODO(tarcieri): implement full set of tests from ECDSA2VS
+// <https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/dss2/ecdsa2vs.pdf>
+
+/// ECDSA test vector
+pub struct TestVector {
+ /// Private scalar
+ pub d: &'static [u8],
+
+ /// Public key x-coordinate (`Qx`)
+ pub q_x: &'static [u8],
+
+ /// Public key y-coordinate (`Qy`)
+ pub q_y: &'static [u8],
+
+ /// Ephemeral scalar (a.k.a. nonce)
+ pub k: &'static [u8],
+
+ /// Message digest (prehashed)
+ pub m: &'static [u8],
+
+ /// Signature `r` component
+ pub r: &'static [u8],
+
+ /// Signature `s` component
+ pub s: &'static [u8],
+}
+
+/// Define ECDSA signing test.
+#[macro_export]
+#[cfg_attr(docsrs, doc(cfg(feature = "dev")))]
+macro_rules! new_signing_test {
+ ($curve:path, $vectors:expr) => {
+ use $crate::{
+ elliptic_curve::{
+ bigint::Encoding, generic_array::GenericArray, group::ff::PrimeField, Curve,
+ ProjectiveArithmetic, Scalar,
+ },
+ hazmat::SignPrimitive,
+ };
+
+ fn decode_scalar(bytes: &[u8]) -> Option<Scalar<$curve>> {
+ if bytes.len() == <$curve as Curve>::UInt::BYTE_SIZE {
+ Scalar::<$curve>::from_repr(GenericArray::clone_from_slice(bytes)).into()
+ } else {
+ None
+ }
+ }
+
+ #[test]
+ fn ecdsa_signing() {
+ for vector in $vectors {
+ let d = decode_scalar(vector.d).expect("invalid vector.d");
+ let k = decode_scalar(vector.k).expect("invalid vector.m");
+ let z = GenericArray::clone_from_slice(vector.m);
+ let sig = d.try_sign_prehashed(k, z).expect("ECDSA sign failed").0;
+
+ assert_eq!(vector.r, sig.r().to_bytes().as_slice());
+ assert_eq!(vector.s, sig.s().to_bytes().as_slice());
+ }
+ }
+ };
+}
+
+/// Define ECDSA verification test.
+#[macro_export]
+#[cfg_attr(docsrs, doc(cfg(feature = "dev")))]
+macro_rules! new_verification_test {
+ ($curve:path, $vectors:expr) => {
+ use $crate::{
+ elliptic_curve::{
+ generic_array::GenericArray,
+ group::ff::PrimeField,
+ sec1::{EncodedPoint, FromEncodedPoint},
+ AffinePoint, ProjectiveArithmetic, Scalar,
+ },
+ hazmat::VerifyPrimitive,
+ Signature,
+ };
+
+ #[test]
+ fn ecdsa_verify_success() {
+ for vector in $vectors {
+ let q_encoded = EncodedPoint::<$curve>::from_affine_coordinates(
+ GenericArray::from_slice(vector.q_x),
+ GenericArray::from_slice(vector.q_y),
+ false,
+ );
+
+ let q = AffinePoint::<$curve>::from_encoded_point(&q_encoded).unwrap();
+ let z = GenericArray::clone_from_slice(vector.m);
+
+ let sig = Signature::from_scalars(
+ GenericArray::clone_from_slice(vector.r),
+ GenericArray::clone_from_slice(vector.s),
+ )
+ .unwrap();
+
+ let result = q.verify_prehashed(z, &sig);
+ assert!(result.is_ok());
+ }
+ }
+
+ #[test]
+ fn ecdsa_verify_invalid_s() {
+ for vector in $vectors {
+ let q_encoded = EncodedPoint::<$curve>::from_affine_coordinates(
+ GenericArray::from_slice(vector.q_x),
+ GenericArray::from_slice(vector.q_y),
+ false,
+ );
+
+ let q = AffinePoint::<$curve>::from_encoded_point(&q_encoded).unwrap();
+ let z = GenericArray::clone_from_slice(vector.m);
+
+ // Flip a bit in `s`
+ let mut s_tweaked = GenericArray::clone_from_slice(vector.s);
+ s_tweaked[0] ^= 1;
+
+ let sig =
+ Signature::from_scalars(GenericArray::clone_from_slice(vector.r), s_tweaked)
+ .unwrap();
+
+ let result = q.verify_prehashed(z, &sig);
+ assert!(result.is_err());
+ }
+ }
+
+ // TODO(tarcieri): test invalid Q, invalid r, invalid m
+ };
+}
+
+/// Define a Wycheproof verification test.
+#[macro_export]
+#[cfg_attr(docsrs, doc(cfg(feature = "dev")))]
+macro_rules! new_wycheproof_test {
+ ($name:ident, $test_name: expr, $curve:path) => {
+ use $crate::{elliptic_curve::sec1::EncodedPoint, signature::Verifier, Signature};
+
+ #[test]
+ fn $name() {
+ use blobby::Blob5Iterator;
+ use elliptic_curve::{bigint::Encoding as _, generic_array::typenum::Unsigned};
+
+ // Build a field element but allow for too-short input (left pad with zeros)
+ // or too-long input (check excess leftmost bytes are zeros).
+ fn element_from_padded_slice<C: elliptic_curve::Curve>(
+ data: &[u8],
+ ) -> elliptic_curve::FieldBytes<C> {
+ let point_len = C::UInt::BYTE_SIZE;
+ if data.len() >= point_len {
+ let offset = data.len() - point_len;
+ for v in data.iter().take(offset) {
+ assert_eq!(*v, 0, "EcdsaVerifier: point too large");
+ }
+ elliptic_curve::FieldBytes::<C>::clone_from_slice(&data[offset..])
+ } else {
+ // Provided slice is too short and needs to be padded with zeros
+ // on the left. Build a combined exact iterator to do this.
+ let iter = core::iter::repeat(0)
+ .take(point_len - data.len())
+ .chain(data.iter().cloned());
+ elliptic_curve::FieldBytes::<C>::from_exact_iter(iter).unwrap()
+ }
+ }
+
+ fn run_test(
+ wx: &[u8],
+ wy: &[u8],
+ msg: &[u8],
+ sig: &[u8],
+ pass: bool,
+ ) -> Option<&'static str> {
+ let x = element_from_padded_slice::<$curve>(wx);
+ let y = element_from_padded_slice::<$curve>(wy);
+ let q_encoded = EncodedPoint::<$curve>::from_affine_coordinates(
+ &x, &y, /* compress= */ false,
+ );
+ let verifying_key =
+ $crate::VerifyingKey::<$curve>::from_encoded_point(&q_encoded).unwrap();
+
+ let sig = match Signature::from_der(sig) {
+ Ok(s) => s,
+ Err(_) if !pass => return None,
+ Err(_) => return Some("failed to parse signature ASN.1"),
+ };
+
+ match verifying_key.verify(msg, &sig) {
+ Ok(_) if pass => None,
+ Ok(_) => Some("signature verify unexpectedly succeeded"),
+ Err(_) if !pass => None,
+ Err(_) => Some("signature verify failed"),
+ }
+ }
+
+ let data = include_bytes!(concat!("test_vectors/data/", $test_name, ".blb"));
+
+ for (i, row) in Blob5Iterator::new(data).unwrap().enumerate() {
+ let [wx, wy, msg, sig, status] = row.unwrap();
+ let pass = match status[0] {
+ 0 => false,
+ 1 => true,
+ _ => panic!("invalid value for pass flag"),
+ };
+ if let Some(desc) = run_test(wx, wy, msg, sig, pass) {
+ panic!(
+ "\n\
+ Failed test โ„–{}: {}\n\
+ wx:\t{:?}\n\
+ wy:\t{:?}\n\
+ msg:\t{:?}\n\
+ sig:\t{:?}\n\
+ pass:\t{}\n",
+ i, desc, wx, wy, msg, sig, pass,
+ );
+ }
+ }
+ }
+ };
+}
diff --git a/vendor/ecdsa/src/hazmat.rs b/vendor/ecdsa/src/hazmat.rs
new file mode 100644
index 000000000..3ca3fc4ce
--- /dev/null
+++ b/vendor/ecdsa/src/hazmat.rs
@@ -0,0 +1,261 @@
+//! Low-level ECDSA primitives.
+//!
+//! # โš ๏ธ Warning: Hazmat!
+//!
+//! YOU PROBABLY DON'T WANT TO USE THESE!
+//!
+//! These primitives are easy-to-misuse low-level interfaces.
+//!
+//! If you are an end user / non-expert in cryptography, do not use these!
+//! Failure to use them correctly can lead to catastrophic failures including
+//! FULL PRIVATE KEY RECOVERY!
+
+#[cfg(feature = "arithmetic")]
+use {
+ crate::{RecoveryId, SignatureSize},
+ core::borrow::Borrow,
+ elliptic_curve::{
+ group::Curve as _,
+ ops::{Invert, LinearCombination, Reduce},
+ subtle::CtOption,
+ AffineArithmetic, AffineXCoordinate, Field, Group, ProjectiveArithmetic, ProjectivePoint,
+ Scalar, ScalarArithmetic,
+ },
+};
+
+#[cfg(feature = "digest")]
+use {
+ core::cmp,
+ elliptic_curve::{bigint::Encoding, FieldSize},
+ signature::{digest::Digest, PrehashSignature},
+};
+
+#[cfg(any(feature = "arithmetic", feature = "digest"))]
+use crate::{
+ elliptic_curve::{generic_array::ArrayLength, FieldBytes, PrimeCurve},
+ Error, Result, Signature,
+};
+
+#[cfg(all(feature = "arithmetic", feature = "digest"))]
+use signature::digest::FixedOutput;
+
+#[cfg(all(feature = "rfc6979"))]
+use {
+ elliptic_curve::ScalarCore,
+ signature::digest::{core_api::BlockSizeUser, FixedOutputReset},
+};
+
+/// Try to sign the given prehashed message using ECDSA.
+///
+/// This trait is intended to be implemented on a type with access to the
+/// secret scalar via `&self`, such as particular curve's `Scalar` type.
+#[cfg(feature = "arithmetic")]
+#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))]
+pub trait SignPrimitive<C>: Field + Into<FieldBytes<C>> + Reduce<C::UInt> + Sized
+where
+ C: PrimeCurve + ProjectiveArithmetic + ScalarArithmetic<Scalar = Self>,
+ SignatureSize<C>: ArrayLength<u8>,
+{
+ /// Try to sign the prehashed message.
+ ///
+ /// Accepts the following arguments:
+ ///
+ /// - `k`: ephemeral scalar value. MUST BE UNIFORMLY RANDOM!!!
+ /// - `z`: message digest to be signed. MUST BE OUTPUT OF A CRYPTOGRAPHICALLY
+ /// SECURE DIGEST ALGORITHM!!!
+ ///
+ /// # Returns
+ ///
+ /// ECDSA [`Signature`] and, when possible/desired, a [`RecoveryId`]
+ /// which can be used to recover the verifying key for a given signature.
+ #[allow(non_snake_case)]
+ fn try_sign_prehashed<K>(
+ &self,
+ k: K,
+ z: FieldBytes<C>,
+ ) -> Result<(Signature<C>, Option<RecoveryId>)>
+ where
+ K: Borrow<Self> + Invert<Output = CtOption<Self>>,
+ {
+ if k.borrow().is_zero().into() {
+ return Err(Error::new());
+ }
+
+ let z = Self::from_be_bytes_reduced(z);
+
+ // Compute scalar inversion of ๐‘˜
+ let k_inv = Option::<Scalar<C>>::from(k.invert()).ok_or_else(Error::new)?;
+
+ // Compute ๐‘น = ๐‘˜ร—๐‘ฎ
+ let R = (C::ProjectivePoint::generator() * k.borrow()).to_affine();
+
+ // Lift x-coordinate of ๐‘น (element of base field) into a serialized big
+ // integer, then reduce it into an element of the scalar field
+ let r = Self::from_be_bytes_reduced(R.x());
+
+ // Compute ๐’” as a signature over ๐’“ and ๐’›.
+ let s = k_inv * (z + (r * self));
+
+ if s.is_zero().into() {
+ return Err(Error::new());
+ }
+
+ // TODO(tarcieri): support for computing recovery ID
+ Ok((Signature::from_scalars(r, s)?, None))
+ }
+
+ /// Try to sign the given message digest deterministically using the method
+ /// described in [RFC6979] for computing ECDSA ephemeral scalar `k`.
+ ///
+ /// Accepts the following parameters:
+ /// - `z`: message digest to be signed.
+ /// - `ad`: optional additional data, e.g. added entropy from an RNG
+ ///
+ /// [RFC6979]: https://datatracker.ietf.org/doc/html/rfc6979
+ #[cfg(all(feature = "rfc6979"))]
+ #[cfg_attr(docsrs, doc(cfg(feature = "rfc6979")))]
+ fn try_sign_prehashed_rfc6979<D>(
+ &self,
+ z: FieldBytes<C>,
+ ad: &[u8],
+ ) -> Result<(Signature<C>, Option<RecoveryId>)>
+ where
+ Self: From<ScalarCore<C>>,
+ C::UInt: for<'a> From<&'a Self>,
+ D: Digest + BlockSizeUser + FixedOutput<OutputSize = FieldSize<C>> + FixedOutputReset,
+ {
+ let x = C::UInt::from(self);
+ let k = rfc6979::generate_k::<D, C::UInt>(&x, &C::ORDER, &z, ad);
+ let k = Self::from(ScalarCore::<C>::new(*k).unwrap());
+ self.try_sign_prehashed(k, z)
+ }
+
+ /// Try to sign the given digest instance using the method described in
+ /// [RFC6979].
+ ///
+ /// [RFC6979]: https://datatracker.ietf.org/doc/html/rfc6979
+ #[cfg(all(feature = "rfc6979"))]
+ #[cfg_attr(docsrs, doc(cfg(feature = "rfc6979")))]
+ fn try_sign_digest_rfc6979<D>(
+ &self,
+ msg_digest: D,
+ ad: &[u8],
+ ) -> Result<(Signature<C>, Option<RecoveryId>)>
+ where
+ Self: From<ScalarCore<C>>,
+ C::UInt: for<'a> From<&'a Self>,
+ D: Digest + BlockSizeUser + FixedOutput<OutputSize = FieldSize<C>> + FixedOutputReset,
+ {
+ self.try_sign_prehashed_rfc6979::<D>(msg_digest.finalize_fixed(), ad)
+ }
+}
+
+/// Verify the given prehashed message using ECDSA.
+///
+/// This trait is intended to be implemented on type which can access
+/// the affine point represeting the public key via `&self`, such as a
+/// particular curve's `AffinePoint` type.
+#[cfg(feature = "arithmetic")]
+#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))]
+pub trait VerifyPrimitive<C>: AffineXCoordinate<C> + Copy + Sized
+where
+ C: PrimeCurve + AffineArithmetic<AffinePoint = Self> + ProjectiveArithmetic,
+ Scalar<C>: Reduce<C::UInt>,
+ SignatureSize<C>: ArrayLength<u8>,
+{
+ /// Verify the prehashed message against the provided signature
+ ///
+ /// Accepts the following arguments:
+ ///
+ /// - `z`: message digest to be verified. MUST BE OUTPUT OF A
+ /// CRYPTOGRAPHICALLY SECURE DIGEST ALGORITHM!!!
+ /// - `sig`: signature to be verified against the key and message
+ fn verify_prehashed(&self, z: FieldBytes<C>, sig: &Signature<C>) -> Result<()> {
+ let z = Scalar::<C>::from_be_bytes_reduced(z);
+ let (r, s) = sig.split_scalars();
+ let s_inv = *s.invert();
+ let u1 = z * s_inv;
+ let u2 = *r * s_inv;
+ let x = ProjectivePoint::<C>::lincomb(
+ &ProjectivePoint::<C>::generator(),
+ &u1,
+ &ProjectivePoint::<C>::from(*self),
+ &u2,
+ )
+ .to_affine()
+ .x();
+
+ if Scalar::<C>::from_be_bytes_reduced(x) == *r {
+ Ok(())
+ } else {
+ Err(Error::new())
+ }
+ }
+
+ /// Verify message digest against the provided signature.
+ #[cfg(feature = "digest")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "digest")))]
+ fn verify_digest<D>(&self, msg_digest: D, sig: &Signature<C>) -> Result<()>
+ where
+ D: FixedOutput<OutputSize = FieldSize<C>>,
+ {
+ self.verify_prehashed(msg_digest.finalize_fixed(), sig)
+ }
+}
+
+/// Bind a preferred [`Digest`] algorithm to an elliptic curve type.
+///
+/// Generally there is a preferred variety of the SHA-2 family used with ECDSA
+/// for a particular elliptic curve.
+///
+/// This trait can be used to specify it, and with it receive a blanket impl of
+/// [`PrehashSignature`], used by [`signature_derive`][1]) for the [`Signature`]
+/// type for a particular elliptic curve.
+///
+/// [1]: https://github.com/RustCrypto/traits/tree/master/signature/derive
+#[cfg(feature = "digest")]
+#[cfg_attr(docsrs, doc(cfg(feature = "digest")))]
+pub trait DigestPrimitive: PrimeCurve {
+ /// Preferred digest to use when computing ECDSA signatures for this
+ /// elliptic curve. This is typically a member of the SHA-2 family.
+ // TODO(tarcieri): add BlockSizeUser + FixedOutput(Reset) bounds in next breaking release
+ // These bounds ensure the digest algorithm can be used for HMAC-DRBG for RFC6979
+ type Digest: Digest;
+
+ /// Compute field bytes for a prehash (message digest), either zero-padding
+ /// or truncating if the prehash size does not match the field size.
+ fn prehash_to_field_bytes(prehash: &[u8]) -> Result<FieldBytes<Self>> {
+ // Minimum allowed prehash size is half the field size
+ if prehash.len() < Self::UInt::BYTE_SIZE / 2 {
+ return Err(Error::new());
+ }
+
+ let mut field_bytes = FieldBytes::<Self>::default();
+
+ // This is a operation according to RFC6979 Section 2.3.2. and SEC1 Section 2.3.8.
+ // https://datatracker.ietf.org/doc/html/rfc6979#section-2.3.2
+ // https://www.secg.org/sec1-v2.pdf
+ match prehash.len().cmp(&Self::UInt::BYTE_SIZE) {
+ cmp::Ordering::Equal => field_bytes.copy_from_slice(prehash),
+ cmp::Ordering::Less => {
+ // If prehash is smaller than the field size, pad with zeroes on the left
+ field_bytes[(Self::UInt::BYTE_SIZE - prehash.len())..].copy_from_slice(prehash);
+ }
+ cmp::Ordering::Greater => {
+ // If prehash is larger than the field size, truncate
+ field_bytes.copy_from_slice(&prehash[..Self::UInt::BYTE_SIZE]);
+ }
+ }
+
+ Ok(field_bytes)
+ }
+}
+
+#[cfg(feature = "digest")]
+impl<C> PrehashSignature for Signature<C>
+where
+ C: DigestPrimitive,
+ <FieldSize<C> as core::ops::Add>::Output: ArrayLength<u8>,
+{
+ type Digest = C::Digest;
+}
diff --git a/vendor/ecdsa/src/lib.rs b/vendor/ecdsa/src/lib.rs
new file mode 100644
index 000000000..9e339ba8f
--- /dev/null
+++ b/vendor/ecdsa/src/lib.rs
@@ -0,0 +1,421 @@
+#![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)]
+#![warn(
+ clippy::cast_lossless,
+ clippy::cast_possible_truncation,
+ clippy::cast_possible_wrap,
+ clippy::cast_precision_loss,
+ clippy::cast_sign_loss,
+ clippy::checked_conversions,
+ clippy::implicit_saturating_sub,
+ clippy::panic,
+ clippy::panic_in_result_fn,
+ clippy::unwrap_used,
+ missing_docs,
+ rust_2018_idioms,
+ unused_lifetimes,
+ unused_qualifications
+)]
+
+//! ## `serde` support
+//!
+//! When the `serde` feature of this crate is enabled, `Serialize` and
+//! `Deserialize` impls are provided for the [`Signature`] and [`VerifyingKey`]
+//! types.
+//!
+//! Please see type-specific documentation for more information.
+//!
+//! ## Interop
+//!
+//! Any crates which provide an implementation of ECDSA for a particular
+//! elliptic curve can leverage the types from this crate, along with the
+//! [`k256`], [`p256`], and/or [`p384`] crates to expose ECDSA functionality in
+//! a generic, interoperable way by leveraging the [`Signature`] type with in
+//! conjunction with the [`signature::Signer`] and [`signature::Verifier`]
+//! traits.
+//!
+//! For example, the [`ring-compat`] crate implements the [`signature::Signer`]
+//! and [`signature::Verifier`] traits in conjunction with the
+//! [`p256::ecdsa::Signature`] and [`p384::ecdsa::Signature`] types to
+//! wrap the ECDSA implementations from [*ring*] in a generic, interoperable
+//! API.
+//!
+//! [`k256`]: https://docs.rs/k256
+//! [`p256`]: https://docs.rs/p256
+//! [`p256::ecdsa::Signature`]: https://docs.rs/p256/latest/p256/ecdsa/type.Signature.html
+//! [`p384`]: https://docs.rs/p384
+//! [`p384::ecdsa::Signature`]: https://docs.rs/p384/latest/p384/ecdsa/type.Signature.html
+//! [`ring-compat`]: https://docs.rs/ring-compat
+//! [*ring*]: https://docs.rs/ring
+
+#[cfg(feature = "alloc")]
+extern crate alloc;
+
+mod recovery;
+
+#[cfg(feature = "der")]
+#[cfg_attr(docsrs, doc(cfg(feature = "der")))]
+pub mod der;
+
+#[cfg(feature = "dev")]
+#[cfg_attr(docsrs, doc(cfg(feature = "dev")))]
+pub mod dev;
+
+#[cfg(feature = "hazmat")]
+#[cfg_attr(docsrs, doc(cfg(feature = "hazmat")))]
+pub mod hazmat;
+
+#[cfg(feature = "sign")]
+mod sign;
+
+#[cfg(feature = "verify")]
+mod verify;
+
+pub use crate::recovery::RecoveryId;
+
+// Re-export the `elliptic-curve` crate (and select types)
+pub use elliptic_curve::{self, sec1::EncodedPoint, PrimeCurve};
+
+// Re-export the `signature` crate (and select types)
+pub use signature::{self, Error, Result};
+
+#[cfg(feature = "sign")]
+#[cfg_attr(docsrs, doc(cfg(feature = "sign")))]
+pub use crate::sign::SigningKey;
+
+#[cfg(feature = "verify")]
+#[cfg_attr(docsrs, doc(cfg(feature = "verify")))]
+pub use crate::verify::VerifyingKey;
+
+use core::{
+ fmt::{self, Debug},
+ ops::Add,
+};
+use elliptic_curve::{
+ bigint::Encoding as _,
+ generic_array::{sequence::Concat, ArrayLength, GenericArray},
+ FieldBytes, FieldSize, ScalarCore,
+};
+
+#[cfg(feature = "alloc")]
+use alloc::vec::Vec;
+
+#[cfg(feature = "arithmetic")]
+use {
+ core::str,
+ elliptic_curve::{ff::PrimeField, IsHigh, NonZeroScalar, ScalarArithmetic},
+};
+
+#[cfg(feature = "serde")]
+use serdect::serde::{de, ser, Deserialize, Serialize};
+
+/// Size of a fixed sized signature for the given elliptic curve.
+pub type SignatureSize<C> = <FieldSize<C> as Add>::Output;
+
+/// Fixed-size byte array containing an ECDSA signature
+pub type SignatureBytes<C> = GenericArray<u8, SignatureSize<C>>;
+
+/// ECDSA signature (fixed-size). Generic over elliptic curve types.
+///
+/// Serialized as fixed-sized big endian scalar values with no added framing:
+///
+/// - `r`: field element size for the given curve, big-endian
+/// - `s`: field element size for the given curve, big-endian
+///
+/// For example, in a curve with a 256-bit modulus like NIST P-256 or
+/// secp256k1, `r` and `s` will both be 32-bytes, resulting in a signature
+/// with a total of 64-bytes.
+///
+/// ASN.1 DER-encoded signatures also supported via the
+/// [`Signature::from_der`] and [`Signature::to_der`] methods.
+///
+/// # `serde` support
+///
+/// When the `serde` feature of this crate is enabled, it provides support for
+/// serializing and deserializing ECDSA signatures using the `Serialize` and
+/// `Deserialize` traits.
+///
+/// The serialization uses a 64-byte fixed encoding when used with binary
+/// formats, and a hexadecimal encoding when used with text formats.
+#[derive(Clone, Eq, PartialEq)]
+pub struct Signature<C: PrimeCurve>
+where
+ SignatureSize<C>: ArrayLength<u8>,
+{
+ bytes: SignatureBytes<C>,
+}
+
+impl<C> Signature<C>
+where
+ C: PrimeCurve,
+ SignatureSize<C>: ArrayLength<u8>,
+{
+ /// Parse a signature from ASN.1 DER
+ #[cfg(feature = "der")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "der")))]
+ pub fn from_der(bytes: &[u8]) -> Result<Self>
+ where
+ der::MaxSize<C>: ArrayLength<u8>,
+ <FieldSize<C> as Add>::Output: Add<der::MaxOverhead> + ArrayLength<u8>,
+ {
+ der::Signature::<C>::try_from(bytes).and_then(Self::try_from)
+ }
+
+ /// Create a [`Signature`] from the serialized `r` and `s` scalar values
+ /// which comprise the signature.
+ pub fn from_scalars(r: impl Into<FieldBytes<C>>, s: impl Into<FieldBytes<C>>) -> Result<Self> {
+ Self::try_from(r.into().concat(s.into()).as_slice())
+ }
+
+ /// Split the signature into its `r` and `s` components, represented as bytes.
+ pub fn split_bytes(&self) -> (FieldBytes<C>, FieldBytes<C>) {
+ let (r_bytes, s_bytes) = self.bytes.split_at(C::UInt::BYTE_SIZE);
+
+ (
+ GenericArray::clone_from_slice(r_bytes),
+ GenericArray::clone_from_slice(s_bytes),
+ )
+ }
+
+ /// Serialize this signature as ASN.1 DER
+ #[cfg(feature = "der")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "der")))]
+ pub fn to_der(&self) -> der::Signature<C>
+ where
+ der::MaxSize<C>: ArrayLength<u8>,
+ <FieldSize<C> as Add>::Output: Add<der::MaxOverhead> + ArrayLength<u8>,
+ {
+ let (r, s) = self.bytes.split_at(C::UInt::BYTE_SIZE);
+ der::Signature::from_scalar_bytes(r, s).expect("DER encoding error")
+ }
+
+ /// Convert this signature into a byte vector.
+ #[cfg(feature = "alloc")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
+ pub fn to_vec(&self) -> Vec<u8> {
+ self.bytes.to_vec()
+ }
+}
+
+#[cfg(feature = "arithmetic")]
+#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))]
+impl<C> Signature<C>
+where
+ C: PrimeCurve + ScalarArithmetic,
+ SignatureSize<C>: ArrayLength<u8>,
+{
+ /// Get the `r` component of this signature
+ pub fn r(&self) -> NonZeroScalar<C> {
+ NonZeroScalar::try_from(self.split_bytes().0.as_slice())
+ .expect("r-component ensured valid in constructor")
+ }
+
+ /// Get the `s` component of this signature
+ pub fn s(&self) -> NonZeroScalar<C> {
+ NonZeroScalar::try_from(self.split_bytes().1.as_slice())
+ .expect("s-component ensured valid in constructor")
+ }
+
+ /// Split the signature into its `r` and `s` scalars.
+ pub fn split_scalars(&self) -> (NonZeroScalar<C>, NonZeroScalar<C>) {
+ (self.r(), self.s())
+ }
+
+ /// Normalize signature into "low S" form as described in
+ /// [BIP 0062: Dealing with Malleability][1].
+ ///
+ /// [1]: https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki
+ pub fn normalize_s(&self) -> Option<Self> {
+ let s = self.s();
+
+ if s.is_high().into() {
+ let neg_s = -s;
+ let mut result = self.clone();
+ result.bytes[C::UInt::BYTE_SIZE..].copy_from_slice(&neg_s.to_repr());
+ Some(result)
+ } else {
+ None
+ }
+ }
+}
+
+impl<C> signature::Signature for Signature<C>
+where
+ C: PrimeCurve,
+ SignatureSize<C>: ArrayLength<u8>,
+{
+ fn from_bytes(bytes: &[u8]) -> Result<Self> {
+ Self::try_from(bytes)
+ }
+}
+
+impl<C> AsRef<[u8]> for Signature<C>
+where
+ C: PrimeCurve,
+ SignatureSize<C>: ArrayLength<u8>,
+{
+ fn as_ref(&self) -> &[u8] {
+ self.bytes.as_slice()
+ }
+}
+
+impl<C> Copy for Signature<C>
+where
+ C: PrimeCurve,
+ SignatureSize<C>: ArrayLength<u8>,
+ <SignatureSize<C> as ArrayLength<u8>>::ArrayType: Copy,
+{
+}
+
+impl<C> Debug for Signature<C>
+where
+ C: PrimeCurve,
+ SignatureSize<C>: ArrayLength<u8>,
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "ecdsa::Signature<{:?}>(", C::default())?;
+
+ for &byte in self.as_ref() {
+ write!(f, "{:02X}", byte)?;
+ }
+
+ write!(f, ")")
+ }
+}
+
+impl<C> TryFrom<&[u8]> for Signature<C>
+where
+ C: PrimeCurve,
+ SignatureSize<C>: ArrayLength<u8>,
+{
+ type Error = Error;
+
+ fn try_from(bytes: &[u8]) -> Result<Self> {
+ if bytes.len() != C::UInt::BYTE_SIZE * 2 {
+ return Err(Error::new());
+ }
+
+ for scalar_bytes in bytes.chunks_exact(C::UInt::BYTE_SIZE) {
+ let scalar = ScalarCore::<C>::from_be_slice(scalar_bytes).map_err(|_| Error::new())?;
+
+ if scalar.is_zero().into() {
+ return Err(Error::new());
+ }
+ }
+
+ Ok(Self {
+ bytes: GenericArray::clone_from_slice(bytes),
+ })
+ }
+}
+
+impl<C> fmt::Display for Signature<C>
+where
+ C: PrimeCurve,
+ SignatureSize<C>: ArrayLength<u8>,
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "{:X}", self)
+ }
+}
+
+impl<C> fmt::LowerHex for Signature<C>
+where
+ C: PrimeCurve,
+ SignatureSize<C>: ArrayLength<u8>,
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ for byte in &self.bytes {
+ write!(f, "{:02x}", byte)?;
+ }
+ Ok(())
+ }
+}
+
+impl<C> fmt::UpperHex for Signature<C>
+where
+ C: PrimeCurve,
+ SignatureSize<C>: ArrayLength<u8>,
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ for byte in &self.bytes {
+ write!(f, "{:02X}", byte)?;
+ }
+ Ok(())
+ }
+}
+
+#[cfg(feature = "arithmetic")]
+#[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))]
+impl<C> str::FromStr for Signature<C>
+where
+ C: PrimeCurve + ScalarArithmetic,
+ SignatureSize<C>: ArrayLength<u8>,
+{
+ type Err = Error;
+
+ fn from_str(hex: &str) -> Result<Self> {
+ if hex.as_bytes().len() != C::UInt::BYTE_SIZE * 4 {
+ return Err(Error::new());
+ }
+
+ // This check is mainly to ensure `hex.split_at` below won't panic
+ if !hex
+ .as_bytes()
+ .iter()
+ .all(|&byte| matches!(byte, b'0'..=b'9' | b'a'..=b'z' | b'A'..=b'Z'))
+ {
+ return Err(Error::new());
+ }
+
+ let (r_hex, s_hex) = hex.split_at(C::UInt::BYTE_SIZE * 2);
+
+ let r = r_hex
+ .parse::<NonZeroScalar<C>>()
+ .map_err(|_| Error::new())?;
+
+ let s = s_hex
+ .parse::<NonZeroScalar<C>>()
+ .map_err(|_| Error::new())?;
+
+ Self::from_scalars(r, s)
+ }
+}
+
+#[cfg(feature = "serde")]
+#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
+impl<C> Serialize for Signature<C>
+where
+ C: PrimeCurve,
+ SignatureSize<C>: ArrayLength<u8>,
+{
+ 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.bytes, serializer)
+ }
+}
+
+#[cfg(feature = "serde")]
+#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
+impl<'de, C> Deserialize<'de> for Signature<C>
+where
+ C: PrimeCurve,
+ SignatureSize<C>: ArrayLength<u8>,
+{
+ fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
+ where
+ D: de::Deserializer<'de>,
+ {
+ let mut bytes = SignatureBytes::<C>::default();
+ serdect::array::deserialize_hex_or_bin(&mut bytes, deserializer)?;
+ Self::try_from(bytes.as_slice()).map_err(de::Error::custom)
+ }
+}
diff --git a/vendor/ecdsa/src/recovery.rs b/vendor/ecdsa/src/recovery.rs
new file mode 100644
index 000000000..c923bbad7
--- /dev/null
+++ b/vendor/ecdsa/src/recovery.rs
@@ -0,0 +1,110 @@
+//! Public key recovery support.
+
+use crate::{Error, Result};
+
+/// Recovery IDs, a.k.a. "recid".
+///
+/// This is an integer value `0`, `1`, `2`, or `3` included along with a
+/// signature which is used during the recovery process to select the correct
+/// public key from the signature.
+///
+/// It consists of two bits of information:
+///
+/// - low bit (0/1): was the y-coordinate of the affine point resulting from
+/// the fixed-base multiplication ๐‘˜ร—๐‘ฎ odd? This part of the algorithm
+/// functions similar to point decompression.
+/// - hi bit (3/4): did the affine x-coordinate of ๐‘˜ร—๐‘ฎ overflow the order of
+/// the scalar field, requiring a reduction when computing `r`?
+#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
+pub struct RecoveryId(u8);
+
+impl RecoveryId {
+ /// Maximum supported value for the recovery ID (inclusive).
+ pub const MAX: u8 = 3;
+
+ /// Create a new [`RecoveryId`] from the following 1-bit arguments:
+ ///
+ /// - `is_y_odd`: is the affine y-coordinate of ๐‘˜ร—๐‘ฎ odd?
+ /// - `is_x_reduced`: did the affine x-coordinate of ๐‘˜ร—๐‘ฎ overflow the curve order?
+ pub const fn new(is_y_odd: bool, is_x_reduced: bool) -> Self {
+ Self((is_x_reduced as u8) << 1 | (is_y_odd as u8))
+ }
+
+ /// Did the affine x-coordinate of ๐‘˜ร—๐‘ฎ overflow the curve order?
+ pub const fn is_x_reduced(self) -> bool {
+ (self.0 & 0b10) != 0
+ }
+
+ /// Is the affine y-coordinate of ๐‘˜ร—๐‘ฎ odd?
+ pub const fn is_y_odd(self) -> bool {
+ (self.0 & 1) != 0
+ }
+
+ /// Convert a `u8` into a [`RecoveryId`].
+ pub const fn from_byte(byte: u8) -> Option<Self> {
+ if byte <= Self::MAX {
+ Some(Self(byte))
+ } else {
+ None
+ }
+ }
+
+ /// Convert this [`RecoveryId`] into a `u8`.
+ pub const fn to_byte(self) -> u8 {
+ self.0
+ }
+}
+
+impl TryFrom<u8> for RecoveryId {
+ type Error = Error;
+
+ fn try_from(byte: u8) -> Result<Self> {
+ Self::from_byte(byte).ok_or_else(Error::new)
+ }
+}
+
+impl From<RecoveryId> for u8 {
+ fn from(id: RecoveryId) -> u8 {
+ id.0
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::RecoveryId;
+
+ #[test]
+ fn new() {
+ assert_eq!(RecoveryId::new(false, false).to_byte(), 0);
+ assert_eq!(RecoveryId::new(true, false).to_byte(), 1);
+ assert_eq!(RecoveryId::new(false, true).to_byte(), 2);
+ assert_eq!(RecoveryId::new(true, true).to_byte(), 3);
+ }
+
+ #[test]
+ fn try_from() {
+ for n in 0u8..=3 {
+ assert_eq!(RecoveryId::try_from(n).unwrap().to_byte(), n);
+ }
+
+ for n in 4u8..=255 {
+ assert!(RecoveryId::try_from(n).is_err());
+ }
+ }
+
+ #[test]
+ fn is_x_reduced() {
+ assert_eq!(RecoveryId::try_from(0).unwrap().is_x_reduced(), false);
+ assert_eq!(RecoveryId::try_from(1).unwrap().is_x_reduced(), false);
+ assert_eq!(RecoveryId::try_from(2).unwrap().is_x_reduced(), true);
+ assert_eq!(RecoveryId::try_from(3).unwrap().is_x_reduced(), true);
+ }
+
+ #[test]
+ fn is_y_odd() {
+ assert_eq!(RecoveryId::try_from(0).unwrap().is_y_odd(), false);
+ assert_eq!(RecoveryId::try_from(1).unwrap().is_y_odd(), true);
+ assert_eq!(RecoveryId::try_from(2).unwrap().is_y_odd(), false);
+ assert_eq!(RecoveryId::try_from(3).unwrap().is_y_odd(), true);
+ }
+}
diff --git a/vendor/ecdsa/src/sign.rs b/vendor/ecdsa/src/sign.rs
new file mode 100644
index 000000000..12d00edb2
--- /dev/null
+++ b/vendor/ecdsa/src/sign.rs
@@ -0,0 +1,424 @@
+//! ECDSA signing key.
+
+// TODO(tarcieri): support for hardware crypto accelerators
+
+use crate::{
+ hazmat::{DigestPrimitive, SignPrimitive},
+ Error, Result, Signature, SignatureSize,
+};
+use core::fmt::{self, Debug};
+use elliptic_curve::{
+ generic_array::ArrayLength,
+ group::ff::PrimeField,
+ ops::{Invert, Reduce},
+ subtle::{Choice, ConstantTimeEq, CtOption},
+ zeroize::{Zeroize, ZeroizeOnDrop},
+ FieldBytes, FieldSize, NonZeroScalar, PrimeCurve, ProjectiveArithmetic, Scalar, SecretKey,
+};
+use signature::{
+ digest::{core_api::BlockSizeUser, Digest, FixedOutput, FixedOutputReset},
+ hazmat::PrehashSigner,
+ rand_core::{CryptoRng, RngCore},
+ DigestSigner, RandomizedDigestSigner, RandomizedSigner, Signer,
+};
+
+#[cfg(feature = "pem")]
+use {
+ crate::elliptic_curve::pkcs8::{EncodePrivateKey, SecretDocument},
+ core::str::FromStr,
+};
+
+#[cfg(feature = "pkcs8")]
+use crate::elliptic_curve::{
+ pkcs8::{self, AssociatedOid, DecodePrivateKey},
+ sec1::{self, FromEncodedPoint, ToEncodedPoint},
+ AffinePoint,
+};
+
+#[cfg(feature = "verify")]
+use {crate::verify::VerifyingKey, elliptic_curve::PublicKey, signature::Keypair};
+
+/// ECDSA signing key. Generic over elliptic curves.
+///
+/// Requires an [`elliptic_curve::ProjectiveArithmetic`] impl on the curve, and a
+/// [`SignPrimitive`] impl on its associated `Scalar` type.
+#[derive(Clone)]
+#[cfg_attr(docsrs, doc(cfg(feature = "sign")))]
+pub struct SigningKey<C>
+where
+ C: PrimeCurve + ProjectiveArithmetic,
+ Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + Reduce<C::UInt> + SignPrimitive<C>,
+ SignatureSize<C>: ArrayLength<u8>,
+{
+ /// ECDSA signing keys are non-zero elements of a given curve's scalar field.
+ secret_scalar: NonZeroScalar<C>,
+
+ /// Verifying key which corresponds to this signing key.
+ #[cfg(feature = "verify")]
+ verifying_key: VerifyingKey<C>,
+}
+
+impl<C> SigningKey<C>
+where
+ C: PrimeCurve + ProjectiveArithmetic,
+ Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + Reduce<C::UInt> + SignPrimitive<C>,
+ SignatureSize<C>: ArrayLength<u8>,
+{
+ /// Generate a cryptographically random [`SigningKey`].
+ pub fn random(rng: impl CryptoRng + RngCore) -> Self {
+ NonZeroScalar::<C>::random(rng).into()
+ }
+
+ /// Initialize signing key from a raw scalar serialized as a byte slice.
+ pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
+ SecretKey::<C>::from_be_bytes(bytes)
+ .map(|sk| sk.to_nonzero_scalar().into())
+ .map_err(|_| Error::new())
+ }
+
+ /// Serialize this [`SigningKey`] as bytes
+ pub fn to_bytes(&self) -> FieldBytes<C> {
+ self.secret_scalar.to_repr()
+ }
+
+ /// Borrow the secret [`NonZeroScalar`] value for this key.
+ ///
+ /// # โš ๏ธ Warning
+ ///
+ /// This value is key material.
+ ///
+ /// Please treat it with the care it deserves!
+ pub fn as_nonzero_scalar(&self) -> &NonZeroScalar<C> {
+ &self.secret_scalar
+ }
+
+ /// Get the [`VerifyingKey`] which corresponds to this [`SigningKey`]
+ // TODO(tarcieri): make this return `&VerifyingKey<C>` in the next breaking release
+ #[cfg(feature = "verify")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "verify")))]
+ pub fn verifying_key(&self) -> VerifyingKey<C> {
+ self.verifying_key
+ }
+}
+
+#[cfg(feature = "verify")]
+#[cfg_attr(docsrs, doc(cfg(feature = "verify")))]
+impl<C> AsRef<VerifyingKey<C>> for SigningKey<C>
+where
+ C: PrimeCurve + ProjectiveArithmetic,
+ Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + Reduce<C::UInt> + SignPrimitive<C>,
+ SignatureSize<C>: ArrayLength<u8>,
+{
+ fn as_ref(&self) -> &VerifyingKey<C> {
+ &self.verifying_key
+ }
+}
+
+impl<C> ConstantTimeEq for SigningKey<C>
+where
+ C: PrimeCurve + ProjectiveArithmetic,
+ Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + Reduce<C::UInt> + SignPrimitive<C>,
+ SignatureSize<C>: ArrayLength<u8>,
+{
+ fn ct_eq(&self, other: &Self) -> Choice {
+ self.secret_scalar.ct_eq(&other.secret_scalar)
+ }
+}
+
+impl<C> Debug for SigningKey<C>
+where
+ C: PrimeCurve + ProjectiveArithmetic,
+ Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + Reduce<C::UInt> + SignPrimitive<C>,
+ SignatureSize<C>: ArrayLength<u8>,
+{
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("SigningKey").finish_non_exhaustive()
+ }
+}
+
+impl<C> Drop for SigningKey<C>
+where
+ C: PrimeCurve + ProjectiveArithmetic,
+ Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + Reduce<C::UInt> + SignPrimitive<C>,
+ SignatureSize<C>: ArrayLength<u8>,
+{
+ fn drop(&mut self) {
+ self.secret_scalar.zeroize();
+ }
+}
+
+impl<C> ZeroizeOnDrop for SigningKey<C>
+where
+ C: PrimeCurve + ProjectiveArithmetic,
+ Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + Reduce<C::UInt> + SignPrimitive<C>,
+ SignatureSize<C>: ArrayLength<u8>,
+{
+}
+
+/// Constant-time comparison
+impl<C> Eq for SigningKey<C>
+where
+ C: PrimeCurve + ProjectiveArithmetic,
+ Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + Reduce<C::UInt> + SignPrimitive<C>,
+ SignatureSize<C>: ArrayLength<u8>,
+{
+}
+
+/// Constant-time comparison
+impl<C> PartialEq for SigningKey<C>
+where
+ C: PrimeCurve + ProjectiveArithmetic,
+ Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + Reduce<C::UInt> + SignPrimitive<C>,
+ SignatureSize<C>: ArrayLength<u8>,
+{
+ fn eq(&self, other: &SigningKey<C>) -> bool {
+ self.ct_eq(other).into()
+ }
+}
+
+impl<C> From<SecretKey<C>> for SigningKey<C>
+where
+ C: PrimeCurve + ProjectiveArithmetic,
+ Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + Reduce<C::UInt> + SignPrimitive<C>,
+ SignatureSize<C>: ArrayLength<u8>,
+{
+ fn from(secret_key: SecretKey<C>) -> Self {
+ Self::from(&secret_key)
+ }
+}
+
+impl<C> From<&SecretKey<C>> for SigningKey<C>
+where
+ C: PrimeCurve + ProjectiveArithmetic,
+ Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + Reduce<C::UInt> + SignPrimitive<C>,
+ SignatureSize<C>: ArrayLength<u8>,
+{
+ fn from(secret_key: &SecretKey<C>) -> Self {
+ secret_key.to_nonzero_scalar().into()
+ }
+}
+
+impl<C> From<SigningKey<C>> for SecretKey<C>
+where
+ C: PrimeCurve + ProjectiveArithmetic,
+ Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + Reduce<C::UInt> + SignPrimitive<C>,
+ SignatureSize<C>: ArrayLength<u8>,
+{
+ fn from(key: SigningKey<C>) -> Self {
+ key.secret_scalar.into()
+ }
+}
+
+impl<C> From<&SigningKey<C>> for SecretKey<C>
+where
+ C: PrimeCurve + ProjectiveArithmetic,
+ Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + Reduce<C::UInt> + SignPrimitive<C>,
+ SignatureSize<C>: ArrayLength<u8>,
+{
+ fn from(secret_key: &SigningKey<C>) -> Self {
+ secret_key.secret_scalar.into()
+ }
+}
+
+impl<C, D> DigestSigner<D, Signature<C>> for SigningKey<C>
+where
+ C: PrimeCurve + ProjectiveArithmetic,
+ C::UInt: for<'a> From<&'a Scalar<C>>,
+ D: Digest + BlockSizeUser + FixedOutput<OutputSize = FieldSize<C>> + FixedOutputReset,
+ Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + Reduce<C::UInt> + SignPrimitive<C>,
+
+ SignatureSize<C>: ArrayLength<u8>,
+{
+ /// Sign message digest using a deterministic ephemeral scalar (`k`)
+ /// computed using the algorithm described in [RFC6979 ยง 3.2].
+ ///
+ /// [RFC6979 ยง 3.2]: https://tools.ietf.org/html/rfc6979#section-3
+ fn try_sign_digest(&self, msg_digest: D) -> Result<Signature<C>> {
+ Ok(self
+ .secret_scalar
+ .try_sign_digest_rfc6979::<D>(msg_digest, &[])?
+ .0)
+ }
+}
+
+#[cfg(feature = "verify")]
+#[cfg_attr(docsrs, doc(cfg(feature = "verify")))]
+impl<C> Keypair<Signature<C>> for SigningKey<C>
+where
+ C: PrimeCurve + ProjectiveArithmetic,
+ Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + Reduce<C::UInt> + SignPrimitive<C>,
+ SignatureSize<C>: ArrayLength<u8>,
+{
+ type VerifyingKey = VerifyingKey<C>;
+}
+
+impl<C> PrehashSigner<Signature<C>> for SigningKey<C>
+where
+ C: PrimeCurve + ProjectiveArithmetic + DigestPrimitive,
+ C::Digest: BlockSizeUser + FixedOutput<OutputSize = FieldSize<C>> + FixedOutputReset,
+ C::UInt: for<'a> From<&'a Scalar<C>>,
+ Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + Reduce<C::UInt> + SignPrimitive<C>,
+ SignatureSize<C>: ArrayLength<u8>,
+{
+ fn sign_prehash(&self, prehash: &[u8]) -> Result<Signature<C>> {
+ let prehash = C::prehash_to_field_bytes(prehash)?;
+
+ Ok(self
+ .secret_scalar
+ .try_sign_prehashed_rfc6979::<C::Digest>(prehash, &[])?
+ .0)
+ }
+}
+
+impl<C> Signer<Signature<C>> for SigningKey<C>
+where
+ Self: DigestSigner<C::Digest, Signature<C>>,
+ C: PrimeCurve + ProjectiveArithmetic + DigestPrimitive,
+ Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + Reduce<C::UInt> + SignPrimitive<C>,
+ SignatureSize<C>: ArrayLength<u8>,
+{
+ fn try_sign(&self, msg: &[u8]) -> Result<Signature<C>> {
+ self.try_sign_digest(C::Digest::new_with_prefix(msg))
+ }
+}
+
+impl<C, D> RandomizedDigestSigner<D, Signature<C>> for SigningKey<C>
+where
+ C: PrimeCurve + ProjectiveArithmetic,
+ C::UInt: for<'a> From<&'a Scalar<C>>,
+ D: Digest + BlockSizeUser + FixedOutput<OutputSize = FieldSize<C>> + FixedOutputReset,
+ Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + Reduce<C::UInt> + SignPrimitive<C>,
+ SignatureSize<C>: ArrayLength<u8>,
+{
+ /// Sign message prehash using an ephemeral scalar (`k`) derived according
+ /// to a variant of RFC 6979 (Section 3.6) which supplies additional
+ /// entropy from an RNG.
+ fn try_sign_digest_with_rng(
+ &self,
+ mut rng: impl CryptoRng + RngCore,
+ msg_digest: D,
+ ) -> Result<Signature<C>> {
+ let mut ad = FieldBytes::<C>::default();
+ rng.fill_bytes(&mut ad);
+ Ok(self
+ .secret_scalar
+ .try_sign_digest_rfc6979::<D>(msg_digest, &ad)?
+ .0)
+ }
+}
+
+impl<C> RandomizedSigner<Signature<C>> for SigningKey<C>
+where
+ Self: RandomizedDigestSigner<C::Digest, Signature<C>>,
+ C: PrimeCurve + ProjectiveArithmetic + DigestPrimitive,
+ Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + Reduce<C::UInt> + SignPrimitive<C>,
+ SignatureSize<C>: ArrayLength<u8>,
+{
+ fn try_sign_with_rng(&self, rng: impl CryptoRng + RngCore, msg: &[u8]) -> Result<Signature<C>> {
+ self.try_sign_digest_with_rng(rng, C::Digest::new_with_prefix(msg))
+ }
+}
+
+impl<C> From<NonZeroScalar<C>> for SigningKey<C>
+where
+ C: PrimeCurve + ProjectiveArithmetic,
+ Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + Reduce<C::UInt> + SignPrimitive<C>,
+ SignatureSize<C>: ArrayLength<u8>,
+{
+ fn from(secret_scalar: NonZeroScalar<C>) -> Self {
+ #[cfg(feature = "verify")]
+ let public_key = PublicKey::from_secret_scalar(&secret_scalar);
+
+ Self {
+ secret_scalar,
+ #[cfg(feature = "verify")]
+ verifying_key: public_key.into(),
+ }
+ }
+}
+
+impl<C> TryFrom<&[u8]> for SigningKey<C>
+where
+ C: PrimeCurve + ProjectiveArithmetic,
+ Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + Reduce<C::UInt> + SignPrimitive<C>,
+ SignatureSize<C>: ArrayLength<u8>,
+{
+ type Error = Error;
+
+ fn try_from(bytes: &[u8]) -> Result<Self> {
+ Self::from_bytes(bytes)
+ }
+}
+
+#[cfg(feature = "verify")]
+impl<C> From<&SigningKey<C>> for VerifyingKey<C>
+where
+ C: PrimeCurve + ProjectiveArithmetic,
+ Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + Reduce<C::UInt> + SignPrimitive<C>,
+ SignatureSize<C>: ArrayLength<u8>,
+{
+ fn from(signing_key: &SigningKey<C>) -> VerifyingKey<C> {
+ signing_key.verifying_key()
+ }
+}
+
+#[cfg(feature = "pkcs8")]
+#[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))]
+impl<C> TryFrom<pkcs8::PrivateKeyInfo<'_>> for SigningKey<C>
+where
+ C: PrimeCurve + AssociatedOid + ProjectiveArithmetic,
+ AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
+ FieldSize<C>: sec1::ModulusSize,
+ Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + Reduce<C::UInt> + SignPrimitive<C>,
+ SignatureSize<C>: ArrayLength<u8>,
+{
+ type Error = pkcs8::Error;
+
+ fn try_from(private_key_info: pkcs8::PrivateKeyInfo<'_>) -> pkcs8::Result<Self> {
+ SecretKey::try_from(private_key_info).map(Into::into)
+ }
+}
+
+#[cfg(feature = "pem")]
+#[cfg_attr(docsrs, doc(cfg(feature = "pem")))]
+impl<C> EncodePrivateKey for SigningKey<C>
+where
+ C: AssociatedOid + PrimeCurve + ProjectiveArithmetic,
+ AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
+ FieldSize<C>: sec1::ModulusSize,
+ Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + Reduce<C::UInt> + SignPrimitive<C>,
+ SignatureSize<C>: ArrayLength<u8>,
+{
+ fn to_pkcs8_der(&self) -> pkcs8::Result<SecretDocument> {
+ SecretKey::from(self.secret_scalar).to_pkcs8_der()
+ }
+}
+
+#[cfg(feature = "pkcs8")]
+#[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))]
+impl<C> DecodePrivateKey for SigningKey<C>
+where
+ C: PrimeCurve + AssociatedOid + ProjectiveArithmetic,
+ AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
+ FieldSize<C>: sec1::ModulusSize,
+ Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + Reduce<C::UInt> + SignPrimitive<C>,
+ SignatureSize<C>: ArrayLength<u8>,
+{
+}
+
+#[cfg(feature = "pem")]
+#[cfg_attr(docsrs, doc(cfg(feature = "pem")))]
+impl<C> FromStr for SigningKey<C>
+where
+ C: PrimeCurve + AssociatedOid + ProjectiveArithmetic,
+ AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
+ FieldSize<C>: sec1::ModulusSize,
+ Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + Reduce<C::UInt> + SignPrimitive<C>,
+ SignatureSize<C>: ArrayLength<u8>,
+{
+ type Err = Error;
+
+ fn from_str(s: &str) -> Result<Self> {
+ Self::from_pkcs8_pem(s).map_err(|_| Error::new())
+ }
+}
diff --git a/vendor/ecdsa/src/verify.rs b/vendor/ecdsa/src/verify.rs
new file mode 100644
index 000000000..5aa8bcb8d
--- /dev/null
+++ b/vendor/ecdsa/src/verify.rs
@@ -0,0 +1,325 @@
+//! ECDSA verification key.
+
+use crate::{
+ hazmat::{DigestPrimitive, VerifyPrimitive},
+ Error, Result, Signature, SignatureSize,
+};
+use core::{cmp::Ordering, fmt::Debug};
+use elliptic_curve::{
+ generic_array::ArrayLength,
+ ops::Reduce,
+ sec1::{self, EncodedPoint, FromEncodedPoint, ToEncodedPoint},
+ AffinePoint, FieldSize, PointCompression, PrimeCurve, ProjectiveArithmetic, PublicKey, Scalar,
+};
+use signature::{
+ digest::{Digest, FixedOutput},
+ hazmat::PrehashVerifier,
+ DigestVerifier, Verifier,
+};
+
+#[cfg(feature = "pkcs8")]
+use elliptic_curve::pkcs8::{self, AssociatedOid, DecodePublicKey};
+
+#[cfg(feature = "pem")]
+use elliptic_curve::pkcs8::EncodePublicKey;
+
+#[cfg(feature = "pem")]
+use core::str::FromStr;
+
+#[cfg(all(feature = "pem", feature = "serde"))]
+#[cfg_attr(docsrs, doc(cfg(all(feature = "pem", feature = "serde"))))]
+use serdect::serde::{de, ser, Deserialize, Serialize};
+
+/// ECDSA verification key (i.e. public key). Generic over elliptic curves.
+///
+/// Requires an [`elliptic_curve::ProjectiveArithmetic`] impl on the curve, and a
+/// [`VerifyPrimitive`] impl on its associated `AffinePoint` type.
+///
+/// # `serde` support
+///
+/// When the `serde` feature of this crate is enabled, it provides support for
+/// serializing and deserializing ECDSA signatures using the `Serialize` and
+/// `Deserialize` traits.
+///
+/// The serialization leverages the encoding used by the [`PublicKey`] type,
+/// which is a binary-oriented ASN.1 DER encoding.
+#[cfg_attr(docsrs, doc(cfg(feature = "verify")))]
+#[derive(Clone, Debug)]
+pub struct VerifyingKey<C>
+where
+ C: PrimeCurve + ProjectiveArithmetic,
+{
+ pub(crate) inner: PublicKey<C>,
+}
+
+impl<C> VerifyingKey<C>
+where
+ C: PrimeCurve + ProjectiveArithmetic,
+ AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
+ FieldSize<C>: sec1::ModulusSize,
+{
+ /// Initialize [`VerifyingKey`] from a SEC1-encoded public key.
+ pub fn from_sec1_bytes(bytes: &[u8]) -> Result<Self> {
+ PublicKey::from_sec1_bytes(bytes)
+ .map(|pk| Self { inner: pk })
+ .map_err(|_| Error::new())
+ }
+
+ /// Initialize [`VerifyingKey`] from an affine point.
+ ///
+ /// Returns an [`Error`] if the given affine point is the additive identity
+ /// (a.k.a. point at infinity).
+ pub fn from_affine(affine: AffinePoint<C>) -> Result<Self> {
+ Ok(Self {
+ inner: PublicKey::from_affine(affine).map_err(|_| Error::new())?,
+ })
+ }
+
+ /// Initialize [`VerifyingKey`] from an [`EncodedPoint`].
+ pub fn from_encoded_point(public_key: &EncodedPoint<C>) -> Result<Self> {
+ Option::from(PublicKey::<C>::from_encoded_point(public_key))
+ .map(|public_key| Self { inner: public_key })
+ .ok_or_else(Error::new)
+ }
+
+ /// Serialize this [`VerifyingKey`] as a SEC1 [`EncodedPoint`], optionally
+ /// applying point compression.
+ pub fn to_encoded_point(&self, compress: bool) -> EncodedPoint<C> {
+ self.inner.to_encoded_point(compress)
+ }
+
+ /// Borrow the inner [`AffinePoint`] for this public key.
+ pub fn as_affine(&self) -> &AffinePoint<C> {
+ self.inner.as_affine()
+ }
+}
+
+impl<C> AsRef<AffinePoint<C>> for VerifyingKey<C>
+where
+ C: PrimeCurve + ProjectiveArithmetic,
+ AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
+ FieldSize<C>: sec1::ModulusSize,
+{
+ fn as_ref(&self) -> &AffinePoint<C> {
+ self.as_affine()
+ }
+}
+
+impl<C> Copy for VerifyingKey<C> where C: PrimeCurve + ProjectiveArithmetic {}
+
+impl<C, D> DigestVerifier<D, Signature<C>> for VerifyingKey<C>
+where
+ C: PrimeCurve + ProjectiveArithmetic,
+ D: Digest + FixedOutput<OutputSize = FieldSize<C>>,
+ AffinePoint<C>: VerifyPrimitive<C>,
+ Scalar<C>: Reduce<C::UInt>,
+ SignatureSize<C>: ArrayLength<u8>,
+{
+ fn verify_digest(&self, msg_digest: D, signature: &Signature<C>) -> Result<()> {
+ self.inner.as_affine().verify_digest(msg_digest, signature)
+ }
+}
+
+impl<C> PrehashVerifier<Signature<C>> for VerifyingKey<C>
+where
+ C: PrimeCurve + ProjectiveArithmetic + DigestPrimitive,
+ AffinePoint<C>: VerifyPrimitive<C>,
+ Scalar<C>: Reduce<C::UInt>,
+ SignatureSize<C>: ArrayLength<u8>,
+{
+ fn verify_prehash(&self, prehash: &[u8], signature: &Signature<C>) -> Result<()> {
+ let prehash = C::prehash_to_field_bytes(prehash)?;
+ self.inner.as_affine().verify_prehashed(prehash, signature)
+ }
+}
+
+impl<C> Verifier<Signature<C>> for VerifyingKey<C>
+where
+ C: PrimeCurve + ProjectiveArithmetic + DigestPrimitive,
+ C::Digest: FixedOutput<OutputSize = FieldSize<C>>,
+ AffinePoint<C>: VerifyPrimitive<C>,
+ Scalar<C>: Reduce<C::UInt>,
+ SignatureSize<C>: ArrayLength<u8>,
+{
+ fn verify(&self, msg: &[u8], signature: &Signature<C>) -> Result<()> {
+ self.verify_digest(C::Digest::new_with_prefix(msg), signature)
+ }
+}
+
+impl<C> From<&VerifyingKey<C>> for EncodedPoint<C>
+where
+ C: PrimeCurve + ProjectiveArithmetic + PointCompression,
+ AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
+ FieldSize<C>: sec1::ModulusSize,
+{
+ fn from(verifying_key: &VerifyingKey<C>) -> EncodedPoint<C> {
+ verifying_key.to_encoded_point(C::COMPRESS_POINTS)
+ }
+}
+
+impl<C> From<PublicKey<C>> for VerifyingKey<C>
+where
+ C: PrimeCurve + ProjectiveArithmetic,
+{
+ fn from(public_key: PublicKey<C>) -> VerifyingKey<C> {
+ VerifyingKey { inner: public_key }
+ }
+}
+
+impl<C> From<&PublicKey<C>> for VerifyingKey<C>
+where
+ C: PrimeCurve + ProjectiveArithmetic,
+{
+ fn from(public_key: &PublicKey<C>) -> VerifyingKey<C> {
+ (*public_key).into()
+ }
+}
+
+impl<C> From<VerifyingKey<C>> for PublicKey<C>
+where
+ C: PrimeCurve + ProjectiveArithmetic,
+{
+ fn from(verifying_key: VerifyingKey<C>) -> PublicKey<C> {
+ verifying_key.inner
+ }
+}
+
+impl<C> From<&VerifyingKey<C>> for PublicKey<C>
+where
+ C: PrimeCurve + ProjectiveArithmetic,
+{
+ fn from(verifying_key: &VerifyingKey<C>) -> PublicKey<C> {
+ (*verifying_key).into()
+ }
+}
+
+impl<C> Eq for VerifyingKey<C> where C: PrimeCurve + ProjectiveArithmetic {}
+
+impl<C> PartialEq for VerifyingKey<C>
+where
+ C: PrimeCurve + ProjectiveArithmetic,
+{
+ fn eq(&self, other: &Self) -> bool {
+ self.inner.eq(&other.inner)
+ }
+}
+
+impl<C> PartialOrd for VerifyingKey<C>
+where
+ C: PrimeCurve + ProjectiveArithmetic,
+ AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
+ FieldSize<C>: sec1::ModulusSize,
+{
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ self.inner.partial_cmp(&other.inner)
+ }
+}
+
+impl<C> Ord for VerifyingKey<C>
+where
+ C: PrimeCurve + ProjectiveArithmetic,
+ AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
+ FieldSize<C>: sec1::ModulusSize,
+{
+ fn cmp(&self, other: &Self) -> Ordering {
+ self.inner.cmp(&other.inner)
+ }
+}
+
+impl<C> TryFrom<&[u8]> for VerifyingKey<C>
+where
+ C: PrimeCurve + ProjectiveArithmetic,
+ AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
+ FieldSize<C>: sec1::ModulusSize,
+{
+ type Error = Error;
+
+ fn try_from(bytes: &[u8]) -> Result<Self> {
+ Self::from_sec1_bytes(bytes)
+ }
+}
+
+#[cfg(feature = "pkcs8")]
+#[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))]
+impl<C> TryFrom<pkcs8::SubjectPublicKeyInfo<'_>> for VerifyingKey<C>
+where
+ C: PrimeCurve + AssociatedOid + ProjectiveArithmetic + PointCompression,
+ AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
+ FieldSize<C>: sec1::ModulusSize,
+{
+ type Error = pkcs8::spki::Error;
+
+ fn try_from(spki: pkcs8::SubjectPublicKeyInfo<'_>) -> pkcs8::spki::Result<Self> {
+ PublicKey::try_from(spki).map(|inner| Self { inner })
+ }
+}
+
+#[cfg(feature = "pkcs8")]
+#[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))]
+impl<C> DecodePublicKey for VerifyingKey<C>
+where
+ C: PrimeCurve + AssociatedOid + ProjectiveArithmetic + PointCompression,
+ AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
+ FieldSize<C>: sec1::ModulusSize,
+{
+}
+
+#[cfg(feature = "pem")]
+#[cfg_attr(docsrs, doc(cfg(feature = "pem")))]
+impl<C> EncodePublicKey for VerifyingKey<C>
+where
+ C: PrimeCurve + AssociatedOid + ProjectiveArithmetic + PointCompression,
+ AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
+ FieldSize<C>: sec1::ModulusSize,
+{
+ fn to_public_key_der(&self) -> pkcs8::spki::Result<pkcs8::Document> {
+ self.inner.to_public_key_der()
+ }
+}
+
+#[cfg(feature = "pem")]
+#[cfg_attr(docsrs, doc(cfg(feature = "pem")))]
+impl<C> FromStr for VerifyingKey<C>
+where
+ C: PrimeCurve + AssociatedOid + ProjectiveArithmetic + PointCompression,
+ AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
+ FieldSize<C>: sec1::ModulusSize,
+{
+ type Err = Error;
+
+ fn from_str(s: &str) -> Result<Self> {
+ Self::from_public_key_pem(s).map_err(|_| Error::new())
+ }
+}
+
+#[cfg(all(feature = "pem", feature = "serde"))]
+#[cfg_attr(docsrs, doc(cfg(all(feature = "pem", feature = "serde"))))]
+impl<C> Serialize for VerifyingKey<C>
+where
+ C: PrimeCurve + AssociatedOid + ProjectiveArithmetic + PointCompression,
+ AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
+ FieldSize<C>: sec1::ModulusSize,
+{
+ fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
+ where
+ S: ser::Serializer,
+ {
+ self.inner.serialize(serializer)
+ }
+}
+
+#[cfg(all(feature = "pem", feature = "serde"))]
+#[cfg_attr(docsrs, doc(cfg(all(feature = "pem", feature = "serde"))))]
+impl<'de, C> Deserialize<'de> for VerifyingKey<C>
+where
+ C: PrimeCurve + AssociatedOid + ProjectiveArithmetic + PointCompression,
+ AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
+ FieldSize<C>: sec1::ModulusSize,
+{
+ fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
+ where
+ D: de::Deserializer<'de>,
+ {
+ PublicKey::<C>::deserialize(deserializer).map(Into::into)
+ }
+}
diff --git a/vendor/ecdsa/tests/lib.rs b/vendor/ecdsa/tests/lib.rs
new file mode 100644
index 000000000..1b622f8bd
--- /dev/null
+++ b/vendor/ecdsa/tests/lib.rs
@@ -0,0 +1,14 @@
+//! Smoke tests which use `MockCurve`
+
+#![cfg(feature = "dev")]
+
+use elliptic_curve::dev::MockCurve;
+
+type Signature = ecdsa::Signature<MockCurve>;
+type SignatureBytes = ecdsa::SignatureBytes<MockCurve>;
+
+#[test]
+fn rejects_all_zero_signature() {
+ let all_zero_bytes = SignatureBytes::default();
+ assert!(Signature::try_from(all_zero_bytes.as_ref()).is_err());
+}