├── .github ├── dependabot.yml └── workflows │ └── ring-compat.yml ├── .gitignore ├── CHANGELOG.md ├── Cargo.lock ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── SECURITY.md ├── img └── logo.png ├── src ├── aead.rs ├── digest.rs ├── lib.rs ├── signature.rs └── signature │ ├── ecdsa.rs │ ├── ecdsa │ ├── p256.rs │ ├── p384.rs │ ├── signing_key.rs │ └── verifying_key.rs │ └── ed25519.rs └── tests ├── aead ├── aes128gcm.rs ├── aes256gcm.rs ├── chacha20poly1305.rs ├── common.rs └── mod.rs ├── digest ├── data │ ├── one_million_a.bin │ ├── sha1.blb │ ├── sha256.blb │ ├── sha256_one_million_a.bin │ ├── sha384.blb │ ├── sha512.blb │ ├── sha512_256.blb │ └── sha512_one_million_a.bin └── mod.rs ├── lib.rs └── signature ├── ecdsa.rs ├── ecdsa ├── p256.rs └── p384.rs ├── ed25519.rs └── mod.rs /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: cargo 4 | directory: "/" 5 | schedule: 6 | interval: monthly 7 | open-pull-requests-limit: 10 8 | - package-ecosystem: github-actions 9 | directory: "/" 10 | schedule: 11 | interval: monthly 12 | open-pull-requests-limit: 10 13 | -------------------------------------------------------------------------------- /.github/workflows/ring-compat.yml: -------------------------------------------------------------------------------- 1 | name: ring-compat 2 | 3 | on: 4 | pull_request: 5 | paths-ignore: 6 | - README.md 7 | push: 8 | branches: master 9 | paths-ignore: 10 | - README.md 11 | 12 | env: 13 | CARGO_INCREMENTAL: 0 14 | RUSTFLAGS: "-Dwarnings" 15 | 16 | jobs: 17 | test: 18 | runs-on: ubuntu-latest 19 | strategy: 20 | matrix: 21 | rust: 22 | - 1.65.0 # MSRV 23 | - stable 24 | steps: 25 | - uses: actions/checkout@v4 26 | - uses: dtolnay/rust-toolchain@master 27 | with: 28 | toolchain: ${{ matrix.rust }} 29 | - run: cargo test --release --no-default-features 30 | - run: cargo test --release --no-default-features --features aead 31 | - run: cargo test --release --no-default-features --features digest 32 | - run: cargo test --release --no-default-features --features signature 33 | - run: cargo test --release 34 | - run: cargo test --release --all-features 35 | 36 | minimal-versions: 37 | runs-on: ubuntu-latest 38 | steps: 39 | - uses: actions/checkout@v4 40 | - uses: actions-rs/toolchain@v1 41 | with: 42 | toolchain: nightly 43 | override: true 44 | profile: minimal 45 | - uses: RustCrypto/actions/cargo-hack-install@master 46 | - name: Test benches build 47 | run: cargo build --benches 48 | - run: rm Cargo.lock 49 | - run: cargo update -Z minimal-versions 50 | - run: cargo hack test --release --feature-powerset 51 | 52 | rustfmt: 53 | runs-on: ubuntu-latest 54 | steps: 55 | - uses: actions/checkout@v4 56 | - uses: dtolnay/rust-toolchain@master 57 | with: 58 | toolchain: stable 59 | components: rustfmt 60 | - run: cargo fmt --all -- --check 61 | 62 | clippy: 63 | runs-on: ubuntu-latest 64 | steps: 65 | - uses: actions/checkout@v4 66 | - uses: dtolnay/rust-toolchain@master 67 | with: 68 | toolchain: 1.65.0 # MSRV 69 | components: clippy 70 | - run: cargo clippy --all --all-features -- -D warnings 71 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | 4 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 5 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 6 | 7 | ## 0.8.0 (2023-10-07) 8 | ### Changed 9 | - Bump *ring* dependency from v0.16 to v0.17 ([#134]) 10 | 11 | [#134]: https://github.com/RustCrypto/ring-compat/pull/134 12 | 13 | ## 0.7.0 (2023-03-19) 14 | ### Added 15 | - `ed25518::SigningIey::from_bytes` ([#114]) 16 | - `ed25519::SigningKey::generate` ([#115]) 17 | - Impl `signature::Keypair` trait ([#116]) 18 | 19 | ### Changed 20 | - Bump elliptic curve dependencies; MSRV 1.65 ([#112]) 21 | - `ecdsa` v0.16 22 | - `elliptic-curve` v0.13 23 | - `p256` v0.13 24 | - `p384` v0.13 25 | - `pkcs8` v0.10 26 | - Rename `ed25519::SigningKey::from_seed` => `::from_slice` ([#114]) 27 | - Rename `ed25519::VerifyingKey::new` => `::from_slice` ([#114]) 28 | 29 | [#112]: https://github.com/RustCrypto/ring-compat/pull/112 30 | [#114]: https://github.com/RustCrypto/ring-compat/pull/114 31 | [#115]: https://github.com/RustCrypto/ring-compat/pull/115 32 | [#116]: https://github.com/RustCrypto/ring-compat/pull/116 33 | 34 | ## 0.6.0 (2023-01-21) 35 | ### Changed 36 | - Upgrade to `signature` v2-compatible dependencies ([#105]) 37 | 38 | [#105]: https://github.com/RustCrypto/ring-compat/pull/105 39 | 40 | ## 0.5.1 (2022-12-12) 41 | ### Added 42 | - Re-export `ring` ([#102]) 43 | 44 | [#102]: https://github.com/RustCrypto/ring-compat/pull/102 45 | 46 | ## 0.5.0 (2022-12-11) 47 | ### Added 48 | - Impl `pkcs8::DecodePrivateKey` for ECDSA and Ed25519 signing keys ([#99]) 49 | 50 | ### Changed 51 | - Bump `aead` dependency to v0.5 ([#86]) 52 | - Bump `digest` to v0.10 ([#94]) 53 | - Bump `p256` and `p384` to v0.11 ([#95]) 54 | - Use namespaced/weak features; MSRV 1.60 ([#97]) 55 | - Rename `verify_key` => `verifying_key` ([#98]) 56 | 57 | [#86]: https://github.com/RustCrypto/ring-compat/pull/86 58 | [#94]: https://github.com/RustCrypto/ring-compat/pull/94 59 | [#95]: https://github.com/RustCrypto/ring-compat/pull/95 60 | [#97]: https://github.com/RustCrypto/ring-compat/pull/97 61 | [#98]: https://github.com/RustCrypto/ring-compat/pull/98 62 | [#99]: https://github.com/RustCrypto/ring-compat/pull/99 63 | 64 | ## 0.4.1 (2022-03-12) 65 | ### Added 66 | - Re-export `ring` ([#80]) 67 | 68 | ### Changed 69 | - Reuse AEAD cipher instance ([#79]) 70 | 71 | [#79]: https://github.com/RustCrypto/ring-compat/pull/79 72 | [#80]: https://github.com/RustCrypto/ring-compat/pull/80 73 | 74 | ## 0.4.0 (2021-12-15) 75 | ### Changed 76 | - Bump `ecdsa` to v0.13 ([#65]) 77 | - Bump `p256` to v0.10 ([#65]) 78 | - Bump `p384` to v0.9 ([#65]) 79 | - Rust 2021 edition upgrade ([#66]) 80 | 81 | [#65]: https://github.com/RustCrypto/ring-compat/pull/65 82 | [#66]: https://github.com/RustCrypto/ring-compat/pull/66 83 | 84 | ## 0.3.2 (2021-09-14) 85 | - Republishing with identical code to v0.3.1 to update the crates.io description. 86 | 87 | ## 0.3.1 (2021-06-08) 88 | ### Changed 89 | - Bump `ecdsa` to v0.12 ([#45]) 90 | - Bump `p256` to v0.9 ([#45]) 91 | - Bump `p384` to v0.8 ([#45]) 92 | - MSRV 1.51+ ([#45]) 93 | 94 | [#45]: https://github.com/RustCrypto/ring-compat/pull/45 95 | 96 | ## 0.3.0 [SKIPPED] 97 | 98 | ## 0.2.1 (2021-04-30) 99 | ### Changed 100 | - Rename `VerifyKey` => `VerifyingKey` ([#38]) 101 | 102 | [#38]: https://github.com/RustCrypto/ring-compat/pull/38 103 | 104 | ## 0.2.0 (2021-04-30) [YANKED] 105 | ### Added 106 | - `std` feature that enables `digest/std` ([#33]) 107 | 108 | ### Changed 109 | - Bump `aead` to v0.4 ([#34]) 110 | - Bump `ecdsa` to v0.11 ([#34]) 111 | - Bump `p256` to v0.8 ([#34]) 112 | - Bump `p384` to v0.7 ([#34]) 113 | 114 | [#33]: https://github.com/RustCrypto/ring-compat/pull/33 115 | [#34]: https://github.com/RustCrypto/ring-compat/pull/34 116 | 117 | ## 0.1.1 (2020-12-11) 118 | ### Added 119 | - `ecdsa::VerifyKey::as_bytes()` function ([#21]) 120 | 121 | [#21]: https://github.com/RustCrypto/ring-compat/pull/21 122 | 123 | ## 0.1.0 (2020-10-09) 124 | ### Added 125 | - Signature support: ECDSA and Ed25519 ([#17]) 126 | 127 | ### Changed 128 | - Factor apart `aead` and `digest` modules ([#14], [#15]) 129 | 130 | [#17]: https://github.com/RustCrypto/ring-compat/pull/17 131 | [#15]: https://github.com/RustCrypto/ring-compat/pull/15 132 | [#14]: https://github.com/RustCrypto/ring-compat/pull/14 133 | 134 | ## 0.0.1 (2020-10-08) 135 | - Initial release 136 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "aead" 7 | version = "0.5.2" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" 10 | dependencies = [ 11 | "crypto-common", 12 | "generic-array", 13 | ] 14 | 15 | [[package]] 16 | name = "base16ct" 17 | version = "0.2.0" 18 | source = "registry+https://github.com/rust-lang/crates.io-index" 19 | checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" 20 | 21 | [[package]] 22 | name = "base64ct" 23 | version = "1.6.0" 24 | source = "registry+https://github.com/rust-lang/crates.io-index" 25 | checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" 26 | 27 | [[package]] 28 | name = "blobby" 29 | version = "0.3.1" 30 | source = "registry+https://github.com/rust-lang/crates.io-index" 31 | checksum = "847495c209977a90e8aad588b959d0ca9f5dc228096d29a6bd3defd53f35eaec" 32 | 33 | [[package]] 34 | name = "block-buffer" 35 | version = "0.10.4" 36 | source = "registry+https://github.com/rust-lang/crates.io-index" 37 | checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 38 | dependencies = [ 39 | "generic-array", 40 | ] 41 | 42 | [[package]] 43 | name = "cc" 44 | version = "1.0.83" 45 | source = "registry+https://github.com/rust-lang/crates.io-index" 46 | checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" 47 | dependencies = [ 48 | "libc", 49 | ] 50 | 51 | [[package]] 52 | name = "cfg-if" 53 | version = "1.0.0" 54 | source = "registry+https://github.com/rust-lang/crates.io-index" 55 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 56 | 57 | [[package]] 58 | name = "const-oid" 59 | version = "0.9.5" 60 | source = "registry+https://github.com/rust-lang/crates.io-index" 61 | checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" 62 | 63 | [[package]] 64 | name = "crypto-bigint" 65 | version = "0.5.3" 66 | source = "registry+https://github.com/rust-lang/crates.io-index" 67 | checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124" 68 | dependencies = [ 69 | "generic-array", 70 | "rand_core", 71 | "subtle", 72 | "zeroize", 73 | ] 74 | 75 | [[package]] 76 | name = "crypto-common" 77 | version = "0.1.6" 78 | source = "registry+https://github.com/rust-lang/crates.io-index" 79 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 80 | dependencies = [ 81 | "generic-array", 82 | "typenum", 83 | ] 84 | 85 | [[package]] 86 | name = "der" 87 | version = "0.7.8" 88 | source = "registry+https://github.com/rust-lang/crates.io-index" 89 | checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" 90 | dependencies = [ 91 | "const-oid", 92 | "zeroize", 93 | ] 94 | 95 | [[package]] 96 | name = "digest" 97 | version = "0.10.7" 98 | source = "registry+https://github.com/rust-lang/crates.io-index" 99 | checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" 100 | dependencies = [ 101 | "blobby", 102 | "block-buffer", 103 | "crypto-common", 104 | ] 105 | 106 | [[package]] 107 | name = "ecdsa" 108 | version = "0.16.8" 109 | source = "registry+https://github.com/rust-lang/crates.io-index" 110 | checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" 111 | dependencies = [ 112 | "der", 113 | "elliptic-curve", 114 | "signature", 115 | "spki", 116 | ] 117 | 118 | [[package]] 119 | name = "ed25519" 120 | version = "2.2.3" 121 | source = "registry+https://github.com/rust-lang/crates.io-index" 122 | checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" 123 | dependencies = [ 124 | "pkcs8", 125 | "signature", 126 | ] 127 | 128 | [[package]] 129 | name = "elliptic-curve" 130 | version = "0.13.6" 131 | source = "registry+https://github.com/rust-lang/crates.io-index" 132 | checksum = "d97ca172ae9dc9f9b779a6e3a65d308f2af74e5b8c921299075bdb4a0370e914" 133 | dependencies = [ 134 | "base16ct", 135 | "crypto-bigint", 136 | "digest", 137 | "ff", 138 | "generic-array", 139 | "group", 140 | "pkcs8", 141 | "rand_core", 142 | "sec1", 143 | "subtle", 144 | "zeroize", 145 | ] 146 | 147 | [[package]] 148 | name = "ff" 149 | version = "0.13.0" 150 | source = "registry+https://github.com/rust-lang/crates.io-index" 151 | checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" 152 | dependencies = [ 153 | "rand_core", 154 | "subtle", 155 | ] 156 | 157 | [[package]] 158 | name = "generic-array" 159 | version = "0.14.7" 160 | source = "registry+https://github.com/rust-lang/crates.io-index" 161 | checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" 162 | dependencies = [ 163 | "typenum", 164 | "version_check", 165 | "zeroize", 166 | ] 167 | 168 | [[package]] 169 | name = "getrandom" 170 | version = "0.2.10" 171 | source = "registry+https://github.com/rust-lang/crates.io-index" 172 | checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" 173 | dependencies = [ 174 | "cfg-if", 175 | "libc", 176 | "wasi", 177 | ] 178 | 179 | [[package]] 180 | name = "group" 181 | version = "0.13.0" 182 | source = "registry+https://github.com/rust-lang/crates.io-index" 183 | checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" 184 | dependencies = [ 185 | "ff", 186 | "rand_core", 187 | "subtle", 188 | ] 189 | 190 | [[package]] 191 | name = "hex-literal" 192 | version = "0.4.1" 193 | source = "registry+https://github.com/rust-lang/crates.io-index" 194 | checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" 195 | 196 | [[package]] 197 | name = "libc" 198 | version = "0.2.149" 199 | source = "registry+https://github.com/rust-lang/crates.io-index" 200 | checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" 201 | 202 | [[package]] 203 | name = "p256" 204 | version = "0.13.2" 205 | source = "registry+https://github.com/rust-lang/crates.io-index" 206 | checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" 207 | dependencies = [ 208 | "ecdsa", 209 | "elliptic-curve", 210 | ] 211 | 212 | [[package]] 213 | name = "p384" 214 | version = "0.13.0" 215 | source = "registry+https://github.com/rust-lang/crates.io-index" 216 | checksum = "70786f51bcc69f6a4c0360e063a4cac5419ef7c5cd5b3c99ad70f3be5ba79209" 217 | dependencies = [ 218 | "ecdsa", 219 | "elliptic-curve", 220 | "primeorder", 221 | ] 222 | 223 | [[package]] 224 | name = "pkcs8" 225 | version = "0.10.2" 226 | source = "registry+https://github.com/rust-lang/crates.io-index" 227 | checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" 228 | dependencies = [ 229 | "der", 230 | "spki", 231 | ] 232 | 233 | [[package]] 234 | name = "primeorder" 235 | version = "0.13.2" 236 | source = "registry+https://github.com/rust-lang/crates.io-index" 237 | checksum = "3c2fcef82c0ec6eefcc179b978446c399b3cdf73c392c35604e399eee6df1ee3" 238 | dependencies = [ 239 | "elliptic-curve", 240 | ] 241 | 242 | [[package]] 243 | name = "rand_core" 244 | version = "0.6.4" 245 | source = "registry+https://github.com/rust-lang/crates.io-index" 246 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 247 | dependencies = [ 248 | "getrandom", 249 | ] 250 | 251 | [[package]] 252 | name = "ring" 253 | version = "0.17.5" 254 | source = "registry+https://github.com/rust-lang/crates.io-index" 255 | checksum = "fb0205304757e5d899b9c2e448b867ffd03ae7f988002e47cd24954391394d0b" 256 | dependencies = [ 257 | "cc", 258 | "getrandom", 259 | "libc", 260 | "spin", 261 | "untrusted", 262 | "windows-sys", 263 | ] 264 | 265 | [[package]] 266 | name = "ring-compat" 267 | version = "0.8.0" 268 | dependencies = [ 269 | "aead", 270 | "digest", 271 | "ecdsa", 272 | "ed25519", 273 | "generic-array", 274 | "hex-literal", 275 | "p256", 276 | "p384", 277 | "pkcs8", 278 | "rand_core", 279 | "ring", 280 | "signature", 281 | ] 282 | 283 | [[package]] 284 | name = "sec1" 285 | version = "0.7.3" 286 | source = "registry+https://github.com/rust-lang/crates.io-index" 287 | checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" 288 | dependencies = [ 289 | "base16ct", 290 | "der", 291 | "generic-array", 292 | "pkcs8", 293 | "subtle", 294 | "zeroize", 295 | ] 296 | 297 | [[package]] 298 | name = "signature" 299 | version = "2.1.0" 300 | source = "registry+https://github.com/rust-lang/crates.io-index" 301 | checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" 302 | dependencies = [ 303 | "rand_core", 304 | ] 305 | 306 | [[package]] 307 | name = "spin" 308 | version = "0.9.8" 309 | source = "registry+https://github.com/rust-lang/crates.io-index" 310 | checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" 311 | 312 | [[package]] 313 | name = "spki" 314 | version = "0.7.2" 315 | source = "registry+https://github.com/rust-lang/crates.io-index" 316 | checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" 317 | dependencies = [ 318 | "base64ct", 319 | "der", 320 | ] 321 | 322 | [[package]] 323 | name = "subtle" 324 | version = "2.5.0" 325 | source = "registry+https://github.com/rust-lang/crates.io-index" 326 | checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" 327 | 328 | [[package]] 329 | name = "typenum" 330 | version = "1.17.0" 331 | source = "registry+https://github.com/rust-lang/crates.io-index" 332 | checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" 333 | 334 | [[package]] 335 | name = "untrusted" 336 | version = "0.9.0" 337 | source = "registry+https://github.com/rust-lang/crates.io-index" 338 | checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" 339 | 340 | [[package]] 341 | name = "version_check" 342 | version = "0.9.4" 343 | source = "registry+https://github.com/rust-lang/crates.io-index" 344 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 345 | 346 | [[package]] 347 | name = "wasi" 348 | version = "0.11.0+wasi-snapshot-preview1" 349 | source = "registry+https://github.com/rust-lang/crates.io-index" 350 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 351 | 352 | [[package]] 353 | name = "windows-sys" 354 | version = "0.48.0" 355 | source = "registry+https://github.com/rust-lang/crates.io-index" 356 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 357 | dependencies = [ 358 | "windows-targets", 359 | ] 360 | 361 | [[package]] 362 | name = "windows-targets" 363 | version = "0.48.5" 364 | source = "registry+https://github.com/rust-lang/crates.io-index" 365 | checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" 366 | dependencies = [ 367 | "windows_aarch64_gnullvm", 368 | "windows_aarch64_msvc", 369 | "windows_i686_gnu", 370 | "windows_i686_msvc", 371 | "windows_x86_64_gnu", 372 | "windows_x86_64_gnullvm", 373 | "windows_x86_64_msvc", 374 | ] 375 | 376 | [[package]] 377 | name = "windows_aarch64_gnullvm" 378 | version = "0.48.5" 379 | source = "registry+https://github.com/rust-lang/crates.io-index" 380 | checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" 381 | 382 | [[package]] 383 | name = "windows_aarch64_msvc" 384 | version = "0.48.5" 385 | source = "registry+https://github.com/rust-lang/crates.io-index" 386 | checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" 387 | 388 | [[package]] 389 | name = "windows_i686_gnu" 390 | version = "0.48.5" 391 | source = "registry+https://github.com/rust-lang/crates.io-index" 392 | checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" 393 | 394 | [[package]] 395 | name = "windows_i686_msvc" 396 | version = "0.48.5" 397 | source = "registry+https://github.com/rust-lang/crates.io-index" 398 | checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" 399 | 400 | [[package]] 401 | name = "windows_x86_64_gnu" 402 | version = "0.48.5" 403 | source = "registry+https://github.com/rust-lang/crates.io-index" 404 | checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" 405 | 406 | [[package]] 407 | name = "windows_x86_64_gnullvm" 408 | version = "0.48.5" 409 | source = "registry+https://github.com/rust-lang/crates.io-index" 410 | checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" 411 | 412 | [[package]] 413 | name = "windows_x86_64_msvc" 414 | version = "0.48.5" 415 | source = "registry+https://github.com/rust-lang/crates.io-index" 416 | checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" 417 | 418 | [[package]] 419 | name = "zeroize" 420 | version = "1.6.0" 421 | source = "registry+https://github.com/rust-lang/crates.io-index" 422 | checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" 423 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "ring-compat" 3 | version = "0.8.0" 4 | description = """ 5 | Compatibility crate for using RustCrypto's traits with the cryptographic 6 | algorithm implementations from *ring* 7 | """ 8 | authors = ["RustCrypto Developers"] 9 | license = "Apache-2.0 OR MIT" 10 | readme = "README.md" 11 | documentation = "https://docs.rs/ring-compat" 12 | repository = "https://github.com/RustCrypto/ring-compat" 13 | categories = ["cryptography", "no-std"] 14 | keywords = ["aead", "digest", "crypto", "ring", "signature"] 15 | edition = "2021" 16 | rust-version = "1.65" 17 | 18 | [dependencies] 19 | generic-array = { version = "0.14", default-features = false } 20 | ring = { version = "0.17", default-features = false } 21 | 22 | # optional dependencies 23 | aead = { version = "0.5", optional = true, default-features = false } 24 | digest = { version = "0.10", optional = true } 25 | ecdsa = { version = "0.16", optional = true, default-features = false } 26 | ed25519 = { version = "2.2", optional = true, default-features = false } 27 | p256 = { version = "0.13", optional = true, default-features = false, features = ["ecdsa-core"] } 28 | p384 = { version = "0.13", optional = true, default-features = false, features = ["ecdsa-core"] } 29 | pkcs8 = { version = "0.10", optional = true, default-features = false } 30 | rand_core = { version = "0.6.4", optional = true, default-features = false } 31 | signature = { version = "2", optional = true, default-features = false } 32 | 33 | [dev-dependencies] 34 | hex-literal = "0.4" 35 | digest = { version = "0.10", features = ["dev"] } 36 | 37 | [features] 38 | default = ["aead", "alloc", "digest", "rand_core", "signature"] 39 | alloc = ["aead?/alloc", "ed25519?/alloc", "pkcs8?/alloc"] 40 | getrandom = ["rand_core/getrandom"] 41 | pkcs8 = ["dep:pkcs8", "ed25519?/pkcs8"] 42 | signature = ["dep:ecdsa", "dep:ed25519", "dep:p256", "dep:p384", "dep:pkcs8", "dep:signature"] 43 | std = ["digest?/std", "ecdsa?/std", "ed25519?/std", "pkcs8?/std"] 44 | 45 | [package.metadata.docs.rs] 46 | all-features = true 47 | rustdoc-args = ["--cfg", "docsrs"] 48 | -------------------------------------------------------------------------------- /LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2019 The RustCrypto Project Developers 2 | 3 | Permission is hereby granted, free of charge, to any 4 | person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the 6 | Software without restriction, including without 7 | limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software 10 | is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice 14 | shall be included in all copies or substantial portions 15 | of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ring-compat 2 | 3 | [![crate][crate-image]][crate-link] 4 | [![Docs][docs-image]][docs-link] 5 | [![Build Status][build-image]][build-link] 6 | ![Ring Version][ring-image] 7 | ![Rust Version][rustc-image] 8 | ![Apache2/MIT licensed][license-image] 9 | [![Project Chat][chat-image]][chat-link] 10 | 11 | Compatibility crate for using RustCrypto's [traits] with the cryptographic 12 | algorithm implementations from [*ring*]. 13 | 14 | [Documentation][docs-link] 15 | 16 | ## Minimum Supported Rust Version 17 | 18 | **Rust 1.65** or higher. 19 | 20 | In the future the minimum supported Rust version can be changed, but it will be 21 | done with a minor version bump. 22 | 23 | ## License 24 | 25 | All crates licensed under either of 26 | 27 | * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) 28 | * [MIT license](http://opensource.org/licenses/MIT) 29 | 30 | at your option. 31 | 32 | ### Contribution 33 | 34 | Unless you explicitly state otherwise, any contribution intentionally submitted 35 | for inclusion in the work by you, as defined in the Apache-2.0 license, shall be 36 | dual licensed as above, without any additional terms or conditions. 37 | 38 | [//]: # (badges) 39 | 40 | [crate-image]: https://img.shields.io/crates/v/ring-compat.svg 41 | [crate-link]: https://crates.io/crates/ring-compat 42 | [docs-image]: https://docs.rs/ring-compat/badge.svg 43 | [docs-link]: https://docs.rs/ring-compat/ 44 | [build-image]: https://github.com/RustCrypto/ring-compat/workflows/ring-compat/badge.svg?branch=master&event=push 45 | [build-link]: https://github.com/RustCrypto/ring-compat/actions 46 | [docs-link]: https://docs.rs/ring-compat 47 | [ring-image]: https://img.shields.io/badge/ring-0.17-blue.svg 48 | [rustc-image]: https://img.shields.io/badge/rustc-1.65+-blue.svg 49 | [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg 50 | [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg 51 | [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260488-ring-compat 52 | 53 | [//]: # (general links) 54 | 55 | [*ring*]: https://github.com/briansmith/ring 56 | [traits]: https://github.com/RustCrypto/traits 57 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | Security updates are applied only to the most recent release. 6 | 7 | ## Reporting a Vulnerability 8 | 9 | If you have discovered a security vulnerability in this project, please report 10 | it privately. **Do not disclose it as a public issue.** This gives us time to 11 | work with you to fix the issue before public exposure, reducing the chance that 12 | the exploit will be used before a patch is released. 13 | 14 | Please disclose it at [security advisory](https://github.com/RustCrypto/ring-compat/security/advisories/new). 15 | 16 | This project is maintained by a team of volunteers on a reasonable-effort basis. 17 | As such, please give us at least 90 days to work on a fix before public exposure. 18 | -------------------------------------------------------------------------------- /img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustCrypto/ring-compat/8e9fec63bc0ba224ee77277c1f968e8d8ef2da55/img/logo.png -------------------------------------------------------------------------------- /src/aead.rs: -------------------------------------------------------------------------------- 1 | //! Authenticated Encryption with Associated Data Algorithms: AES-GCM, ChaCha20Poly1305 2 | 3 | pub use aead::{AeadCore, AeadInPlace, Buffer, Error, KeyInit, KeySizeUser}; 4 | 5 | #[cfg(feature = "alloc")] 6 | pub use aead::{Aead, Payload}; 7 | 8 | use aead::{ 9 | consts::{U0, U12, U16, U32}, 10 | generic_array::GenericArray, 11 | }; 12 | use ring::aead::{ 13 | Aad, LessSafeKey as Key, Nonce, UnboundKey, AES_128_GCM, AES_256_GCM, CHACHA20_POLY1305, 14 | }; 15 | 16 | /// Authentication tags 17 | pub type Tag = GenericArray; 18 | 19 | /// AES-GCM with a 128-bit key 20 | pub struct Aes128Gcm(Cipher); 21 | 22 | /// AES-GCM with a 256-bit key 23 | pub struct Aes256Gcm(Cipher); 24 | 25 | /// ChaCha20Poly1305 26 | pub struct ChaCha20Poly1305(Cipher); 27 | 28 | macro_rules! impl_aead { 29 | ($cipher:ty, $algorithm:expr, $key_size:ty) => { 30 | impl KeySizeUser for $cipher { 31 | type KeySize = $key_size; 32 | } 33 | 34 | impl KeyInit for $cipher { 35 | fn new(key: &GenericArray) -> Self { 36 | let key = UnboundKey::new(&$algorithm, key.as_slice()).unwrap(); 37 | Self(Cipher::new(key)) 38 | } 39 | } 40 | 41 | impl AeadCore for $cipher { 42 | type NonceSize = U12; 43 | type TagSize = U16; 44 | type CiphertextOverhead = U0; 45 | } 46 | 47 | impl AeadInPlace for $cipher { 48 | fn encrypt_in_place_detached( 49 | &self, 50 | nonce: &GenericArray, 51 | associated_data: &[u8], 52 | buffer: &mut [u8], 53 | ) -> Result { 54 | self.0 55 | .encrypt_in_place_detached(nonce.as_slice(), associated_data, buffer) 56 | } 57 | 58 | fn decrypt_in_place( 59 | &self, 60 | nonce: &GenericArray, 61 | associated_data: &[u8], 62 | buffer: &mut dyn Buffer, 63 | ) -> Result<(), Error> { 64 | self.0 65 | .decrypt_in_place(nonce.as_slice(), associated_data, buffer) 66 | } 67 | 68 | fn decrypt_in_place_detached( 69 | &self, 70 | _nonce: &GenericArray, 71 | _associated_data: &[u8], 72 | _buffer: &mut [u8], 73 | _tag: &Tag, 74 | ) -> Result<(), Error> { 75 | unimplemented!(); // ring does not allow us to implement this API 76 | } 77 | } 78 | }; 79 | } 80 | 81 | impl_aead!(Aes128Gcm, AES_128_GCM, U16); 82 | impl_aead!(Aes256Gcm, AES_256_GCM, U32); 83 | impl_aead!(ChaCha20Poly1305, CHACHA20_POLY1305, U32); 84 | 85 | /// Generic AEAD cipher support 86 | pub(crate) struct Cipher(Key); 87 | 88 | impl Cipher { 89 | /// Instantiate a particular AEAD algorithm 90 | pub fn new(key: UnboundKey) -> Self { 91 | Cipher(Key::new(key)) 92 | } 93 | 94 | /// Encrypt the ciphertext in place, returning a tag 95 | fn encrypt_in_place_detached( 96 | &self, 97 | nonce: &[u8], 98 | associated_data: &[u8], 99 | buffer: &mut [u8], 100 | ) -> Result { 101 | self.0 102 | .seal_in_place_separate_tag( 103 | Nonce::try_assume_unique_for_key(nonce).map_err(|_| Error)?, 104 | Aad::from(associated_data), 105 | buffer, 106 | ) 107 | .map(|tag| Tag::clone_from_slice(tag.as_ref())) 108 | .map_err(|_| Error) 109 | } 110 | 111 | fn decrypt_in_place( 112 | &self, 113 | nonce: &[u8], 114 | associated_data: &[u8], 115 | buffer: &mut dyn Buffer, 116 | ) -> Result<(), Error> { 117 | let pt_len = self 118 | .0 119 | .open_in_place( 120 | Nonce::try_assume_unique_for_key(nonce).map_err(|_| Error)?, 121 | Aad::from(associated_data), 122 | buffer.as_mut(), 123 | ) 124 | .map_err(|_| Error)? 125 | .len(); 126 | 127 | buffer.truncate(pt_len); 128 | Ok(()) 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /src/digest.rs: -------------------------------------------------------------------------------- 1 | //! Digest algorithms: SHA-1, SHA-256, SHA-384, SHA-512 2 | 3 | use core::{fmt, mem}; 4 | use digest::{ 5 | core_api::BlockSizeUser, 6 | generic_array::{typenum::*, GenericArray}, 7 | FixedOutput, FixedOutputReset, OutputSizeUser, Reset, Update, 8 | }; 9 | use ring::digest::Context; 10 | 11 | macro_rules! impl_digest { 12 | ( 13 | $(#[doc = $doc:tt])* 14 | $name:ident, $hasher:ident, $block_len:ty, $output_size:ty 15 | ) => { 16 | $(#[doc = $doc])* 17 | #[repr(transparent)] 18 | #[derive(Clone)] 19 | pub struct $name(Context); 20 | 21 | impl $name { 22 | fn take(&mut self) -> Context { 23 | mem::replace(&mut self.0, Context::new(&ring::digest::$hasher)) 24 | } 25 | } 26 | 27 | impl Default for $name { 28 | fn default() -> Self { 29 | $name(Context::new(&ring::digest::$hasher)) 30 | } 31 | } 32 | 33 | impl Update for $name { 34 | fn update(&mut self, data: &[u8]) { 35 | self.0.update(data.as_ref()) 36 | } 37 | } 38 | 39 | impl BlockSizeUser for $name { 40 | type BlockSize = $block_len; 41 | } 42 | 43 | impl OutputSizeUser for $name { 44 | type OutputSize = $output_size; 45 | } 46 | 47 | impl FixedOutput for $name { 48 | fn finalize_into(self, out: &mut GenericArray) { 49 | *out = GenericArray::clone_from_slice(self.0.finish().as_ref()); 50 | } 51 | } 52 | 53 | impl FixedOutputReset for $name { 54 | fn finalize_into_reset(&mut self, out: &mut GenericArray) { 55 | *out = GenericArray::clone_from_slice(self.take().finish().as_ref()); 56 | } 57 | } 58 | 59 | impl Reset for $name { 60 | fn reset(&mut self) { 61 | self.take(); 62 | } 63 | } 64 | 65 | impl fmt::Debug for $name { 66 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 67 | f.debug_struct(stringify!($name)).finish_non_exhaustive() 68 | } 69 | } 70 | }; 71 | } 72 | 73 | impl_digest!( 74 | /// Structure representing the state of a SHA-1 computation 75 | Sha1, 76 | SHA1_FOR_LEGACY_USE_ONLY, 77 | U64, 78 | U20 79 | ); 80 | 81 | impl_digest!( 82 | /// Structure representing the state of a SHA-256 computation 83 | Sha256, 84 | SHA256, 85 | U64, 86 | U32 87 | ); 88 | 89 | impl_digest!( 90 | /// Structure representing the state of a SHA-384 computation 91 | Sha384, 92 | SHA384, 93 | U128, 94 | U48 95 | ); 96 | 97 | impl_digest!( 98 | /// Structure representing the state of a SHA-512 computation 99 | Sha512, 100 | SHA512, 101 | U128, 102 | U64 103 | ); 104 | 105 | impl_digest!( 106 | /// Structure representing the state of a SHA-512/256 computation 107 | Sha512Trunc256, 108 | SHA512_256, 109 | U128, 110 | U32 111 | ); 112 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | #![no_std] 2 | #![cfg_attr(docsrs, feature(doc_auto_cfg))] 3 | #![doc = include_str!("../README.md")] 4 | #![doc( 5 | html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/7f79a5e/img/ring-compat/logo-sq.png" 6 | )] 7 | #![forbid(unsafe_code)] 8 | #![warn(missing_docs, rust_2018_idioms)] 9 | 10 | //! # Features 11 | //! 12 | //! Functionality in this crate is gated under the following features: 13 | //! 14 | //! - `aead`: Authenticated Encryption with Associated Data algorithms: AES-GCM, ChaCha20Poly1305 15 | //! - `digest`: Cryptographic Hash Functions: SHA-1, SHA-256, SHA-384, SHA-512, SHA-512/256 16 | //! - `signature`: Digital Signature Algorithms, gated under the following features: 17 | //! - `ecdsa`: Elliptic Curve Digital Signature Algorithm 18 | //! - `ed25519`: Edwards Digital Signature Algorithm instantiated over Curve25519 19 | //! - `p256`: ECDSA/NIST P-256 20 | //! - `p384`: ECDSA/NIST P-384 21 | 22 | #[cfg(feature = "std")] 23 | extern crate std; 24 | 25 | #[cfg(feature = "aead")] 26 | pub mod aead; 27 | 28 | #[cfg(feature = "digest")] 29 | pub mod digest; 30 | 31 | #[cfg(feature = "signature")] 32 | pub mod signature; 33 | 34 | pub use generic_array; 35 | 36 | #[cfg(feature = "signature")] 37 | pub use pkcs8; 38 | 39 | pub use ring; 40 | -------------------------------------------------------------------------------- /src/signature.rs: -------------------------------------------------------------------------------- 1 | //! Digital signatures: ECDSA (P-256/P-384), Ed25519 2 | 3 | pub mod ecdsa; 4 | pub mod ed25519; 5 | 6 | pub use ::signature::{Error, Keypair, SignatureEncoding, Signer, Verifier}; 7 | -------------------------------------------------------------------------------- /src/signature/ecdsa.rs: -------------------------------------------------------------------------------- 1 | //! Elliptic Curve Digital Signature Algorithm 2 | //! 3 | //! 4 | 5 | pub mod p256; 6 | pub mod p384; 7 | 8 | mod signing_key; 9 | mod verifying_key; 10 | 11 | pub use self::{signing_key::SigningKey, verifying_key::VerifyingKey}; 12 | pub use ::ecdsa::{der, elliptic_curve::PrimeCurve, Signature}; 13 | 14 | use ring::signature::{EcdsaSigningAlgorithm, EcdsaVerificationAlgorithm}; 15 | 16 | /// Trait for associating a *ring* [`EcdsaSigningAlgorithm`] with an 17 | /// elliptic curve 18 | pub trait CurveAlg: PrimeCurve { 19 | /// *ring* signing algorithm 20 | fn signing_alg() -> &'static EcdsaSigningAlgorithm; 21 | 22 | /// *ring* verify algorithm 23 | fn verify_alg() -> &'static EcdsaVerificationAlgorithm; 24 | } 25 | -------------------------------------------------------------------------------- /src/signature/ecdsa/p256.rs: -------------------------------------------------------------------------------- 1 | //! ECDSA support for the NIST P-256 elliptic curve 2 | 3 | pub use p256::NistP256; 4 | 5 | use super::CurveAlg; 6 | use ring::signature::{ 7 | EcdsaSigningAlgorithm, EcdsaVerificationAlgorithm, ECDSA_P256_SHA256_FIXED, 8 | ECDSA_P256_SHA256_FIXED_SIGNING, 9 | }; 10 | 11 | /// ECDSA/P-256 signature 12 | pub type Signature = super::Signature; 13 | 14 | /// ECDSA/P-256 signing key 15 | pub type SigningKey = super::SigningKey; 16 | 17 | /// ECDSA/P-256 verify key 18 | pub type VerifyingKey = super::VerifyingKey; 19 | 20 | impl CurveAlg for NistP256 { 21 | fn signing_alg() -> &'static EcdsaSigningAlgorithm { 22 | &ECDSA_P256_SHA256_FIXED_SIGNING 23 | } 24 | 25 | fn verify_alg() -> &'static EcdsaVerificationAlgorithm { 26 | &ECDSA_P256_SHA256_FIXED 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/signature/ecdsa/p384.rs: -------------------------------------------------------------------------------- 1 | //! ECDSA support for the NIST P-384 elliptic curve 2 | 3 | pub use p384::NistP384; 4 | 5 | use super::CurveAlg; 6 | use ring::signature::{ 7 | EcdsaSigningAlgorithm, EcdsaVerificationAlgorithm, ECDSA_P384_SHA384_FIXED, 8 | ECDSA_P384_SHA384_FIXED_SIGNING, 9 | }; 10 | 11 | /// ECDSA/P-384 signature 12 | pub type Signature = super::Signature; 13 | 14 | /// ECDSA/P-384 signing key 15 | pub type SigningKey = super::SigningKey; 16 | 17 | /// ECDSA/P-384 verify key 18 | pub type VerifyingKey = super::VerifyingKey; 19 | 20 | impl CurveAlg for NistP384 { 21 | fn signing_alg() -> &'static EcdsaSigningAlgorithm { 22 | &ECDSA_P384_SHA384_FIXED_SIGNING 23 | } 24 | 25 | fn verify_alg() -> &'static EcdsaVerificationAlgorithm { 26 | &ECDSA_P384_SHA384_FIXED 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/signature/ecdsa/signing_key.rs: -------------------------------------------------------------------------------- 1 | //! ECDSA signing key 2 | 3 | use super::{CurveAlg, Signature, VerifyingKey}; 4 | use crate::signature::{Error, Keypair, Signer}; 5 | use core::marker::PhantomData; 6 | use ecdsa::{ 7 | elliptic_curve::{sec1, FieldBytesSize}, 8 | SignatureSize, 9 | }; 10 | use generic_array::ArrayLength; 11 | use pkcs8::DecodePrivateKey; 12 | use ring::{ 13 | self, 14 | rand::SystemRandom, 15 | signature::{EcdsaKeyPair, KeyPair as _}, 16 | }; 17 | 18 | /// ECDSA signing key. Generic over elliptic curves. 19 | pub struct SigningKey 20 | where 21 | C: CurveAlg, 22 | SignatureSize: ArrayLength, 23 | { 24 | /// *ring* ECDSA keypair 25 | keypair: EcdsaKeyPair, 26 | 27 | /// Cryptographically secure random number generator 28 | csrng: SystemRandom, 29 | 30 | /// Elliptic curve type 31 | curve: PhantomData, 32 | } 33 | 34 | impl SigningKey 35 | where 36 | C: CurveAlg, 37 | SignatureSize: ArrayLength, 38 | { 39 | /// Initialize a [`SigningKey`] from a raw keypair 40 | pub fn from_keypair_bytes(signing_key: &[u8], verifying_key: &[u8]) -> Result { 41 | let csrng = SystemRandom::new(); 42 | 43 | let keypair = EcdsaKeyPair::from_private_key_and_public_key( 44 | C::signing_alg(), 45 | signing_key, 46 | verifying_key, 47 | &csrng, 48 | ) 49 | .map_err(|_| Error::new())?; 50 | 51 | Ok(Self { 52 | keypair, 53 | csrng, 54 | curve: PhantomData, 55 | }) 56 | } 57 | 58 | /// Get the [`VerifyingKey`] for this [`SigningKey`] 59 | pub fn verifying_key(&self) -> VerifyingKey 60 | where 61 | FieldBytesSize: sec1::ModulusSize, 62 | { 63 | VerifyingKey::new(self.keypair.public_key().as_ref()).unwrap() 64 | } 65 | } 66 | 67 | impl DecodePrivateKey for SigningKey 68 | where 69 | C: CurveAlg, 70 | SignatureSize: ArrayLength, 71 | { 72 | fn from_pkcs8_der(pkcs8_bytes: &[u8]) -> Result { 73 | let csrng = SystemRandom::new(); 74 | 75 | let keypair = EcdsaKeyPair::from_pkcs8(C::signing_alg(), pkcs8_bytes, &csrng) 76 | .map_err(|_| pkcs8::Error::KeyMalformed)?; 77 | 78 | Ok(Self { 79 | keypair, 80 | csrng, 81 | curve: PhantomData, 82 | }) 83 | } 84 | } 85 | 86 | impl Keypair for SigningKey 87 | where 88 | C: CurveAlg, 89 | FieldBytesSize: sec1::ModulusSize, 90 | SignatureSize: ArrayLength, 91 | { 92 | type VerifyingKey = VerifyingKey; 93 | 94 | fn verifying_key(&self) -> VerifyingKey { 95 | self.verifying_key() 96 | } 97 | } 98 | 99 | impl Signer> for SigningKey 100 | where 101 | C: CurveAlg, 102 | SignatureSize: ArrayLength, 103 | { 104 | fn try_sign(&self, msg: &[u8]) -> Result, Error> { 105 | self.keypair 106 | .sign(&self.csrng, msg) 107 | .map_err(|_| Error::new()) 108 | .and_then(|sig| Signature::try_from(sig.as_ref())) 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/signature/ecdsa/verifying_key.rs: -------------------------------------------------------------------------------- 1 | //! ECDSA verifying key 2 | 3 | use super::{CurveAlg, PrimeCurve, Signature}; 4 | use crate::signature::{Error, Verifier}; 5 | use ::ecdsa::{ 6 | elliptic_curve::{sec1, FieldBytesSize}, 7 | SignatureSize, 8 | }; 9 | use core::convert::TryInto; 10 | use generic_array::{typenum::Unsigned, ArrayLength}; 11 | use ring::signature::UnparsedPublicKey; 12 | 13 | /// ECDSA verifying key. Generic over elliptic curves. 14 | #[derive(Clone, Debug, Eq, PartialEq)] 15 | pub struct VerifyingKey(sec1::EncodedPoint) 16 | where 17 | C: CurveAlg, 18 | FieldBytesSize: sec1::ModulusSize, 19 | SignatureSize: ArrayLength; 20 | 21 | impl VerifyingKey 22 | where 23 | C: CurveAlg, 24 | FieldBytesSize: sec1::ModulusSize, 25 | SignatureSize: ArrayLength, 26 | { 27 | /// Initialize [`VerifyingKey`] from a SEC1-encoded public key 28 | pub fn new(bytes: &[u8]) -> Result { 29 | let point_result = if bytes.len() == C::FieldBytesSize::USIZE * 2 { 30 | Ok(sec1::EncodedPoint::::from_untagged_bytes( 31 | bytes.try_into().map_err(|_| Error::new())?, 32 | )) 33 | } else { 34 | sec1::EncodedPoint::::from_bytes(bytes) 35 | }; 36 | 37 | point_result.map(VerifyingKey).map_err(|_| Error::new()) 38 | } 39 | 40 | /// Get byte slice of inner encoded point 41 | pub fn as_bytes(&self) -> &[u8] { 42 | self.0.as_bytes() 43 | } 44 | } 45 | 46 | impl Verifier> for VerifyingKey 47 | where 48 | C: CurveAlg, 49 | FieldBytesSize: sec1::ModulusSize, 50 | SignatureSize: ArrayLength, 51 | { 52 | fn verify(&self, msg: &[u8], sig: &Signature) -> Result<(), Error> { 53 | UnparsedPublicKey::new(C::verify_alg(), self.0.as_ref()) 54 | .verify(msg, &sig.to_bytes()) 55 | .map_err(|_| Error::new()) 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/signature/ed25519.rs: -------------------------------------------------------------------------------- 1 | //! Ed25519 digital signature algorithm 2 | //! 3 | //! 4 | 5 | pub use ed25519::Signature; 6 | 7 | use super::{Error, Signer, Verifier}; 8 | use crate::signature::Keypair; 9 | use core::convert::TryInto; 10 | use ring::{ 11 | self, 12 | signature::{Ed25519KeyPair, KeyPair as _, UnparsedPublicKey}, 13 | }; 14 | 15 | #[cfg(feature = "pkcs8")] 16 | use ed25519::pkcs8; 17 | 18 | #[cfg(feature = "rand_core")] 19 | use rand_core::CryptoRngCore; 20 | 21 | /// Ed25519 signing key. 22 | pub struct SigningKey { 23 | keypair: Ed25519KeyPair, 24 | seed: [u8; Self::SIZE], 25 | } 26 | 27 | impl SigningKey { 28 | /// Size of a raw [`SigningKey`] (a.k.a. seed) in bytes. 29 | pub const SIZE: usize = 32; 30 | 31 | /// Generate a random Ed25519 key using the provided RNG. 32 | #[cfg(feature = "rand_core")] 33 | pub fn generate(rng: &mut impl CryptoRngCore) -> Self { 34 | let mut bytes = [0u8; Self::SIZE]; 35 | rng.fill_bytes(&mut bytes); 36 | Self::from_bytes(&bytes) 37 | } 38 | 39 | /// Create a new [`SigningKey`] from an unexpanded seed value (32-bytes). 40 | pub fn from_bytes(seed: &[u8; Self::SIZE]) -> Self { 41 | let keypair = Ed25519KeyPair::from_seed_unchecked(seed) 42 | .expect("all 32-byte values should be valid Ed25519 signing keys"); 43 | 44 | Self { 45 | keypair, 46 | seed: *seed, 47 | } 48 | } 49 | 50 | /// Create a new [`SigningKey`] from a byte slice containing a seed value. 51 | pub fn from_slice(seed: &[u8]) -> signature::Result { 52 | seed.try_into() 53 | .map(Self::from_bytes) 54 | .map_err(|_| Error::new()) 55 | } 56 | 57 | /// Alias for `from_slice`. 58 | #[deprecated(since = "0.7.0", note = "use `from_slice` instead")] 59 | pub fn from_seed(seed: &[u8]) -> signature::Result { 60 | Self::from_slice(seed) 61 | } 62 | 63 | /// Serialize this [`SigningKey`] as a 32-byte "seed". 64 | #[inline] 65 | pub fn to_bytes(&self) -> [u8; Self::SIZE] { 66 | self.seed 67 | } 68 | 69 | /// Get the [`VerifyingKey`] for this [`SigningKey`]. 70 | pub fn verifying_key(&self) -> VerifyingKey { 71 | debug_assert_eq!(self.keypair.public_key().as_ref().len(), 32); 72 | 73 | let mut ret = VerifyingKey(Default::default()); 74 | ret.0.copy_from_slice(self.keypair.public_key().as_ref()); 75 | ret 76 | } 77 | } 78 | 79 | impl Clone for SigningKey { 80 | fn clone(&self) -> Self { 81 | Self::from_bytes(&self.seed) 82 | } 83 | } 84 | 85 | impl Keypair for SigningKey { 86 | type VerifyingKey = VerifyingKey; 87 | 88 | fn verifying_key(&self) -> VerifyingKey { 89 | self.verifying_key() 90 | } 91 | } 92 | 93 | impl Signer for SigningKey { 94 | fn try_sign(&self, msg: &[u8]) -> signature::Result { 95 | Ok(Signature::try_from(self.keypair.sign(msg).as_ref()).unwrap()) 96 | } 97 | } 98 | 99 | impl TryFrom<&[u8]> for SigningKey { 100 | type Error = Error; 101 | 102 | fn try_from(slice: &[u8]) -> signature::Result { 103 | Self::from_slice(slice) 104 | } 105 | } 106 | 107 | #[cfg(all(feature = "alloc", feature = "pkcs8"))] 108 | impl pkcs8::EncodePrivateKey for SigningKey { 109 | fn to_pkcs8_der(&self) -> pkcs8::Result { 110 | pkcs8::KeypairBytes::from(self).to_pkcs8_der() 111 | } 112 | } 113 | 114 | #[cfg(feature = "pkcs8")] 115 | impl TryFrom for SigningKey { 116 | type Error = pkcs8::Error; 117 | 118 | fn try_from(pkcs8_key: pkcs8::KeypairBytes) -> pkcs8::Result { 119 | SigningKey::try_from(&pkcs8_key) 120 | } 121 | } 122 | 123 | #[cfg(feature = "pkcs8")] 124 | impl TryFrom<&pkcs8::KeypairBytes> for SigningKey { 125 | type Error = pkcs8::Error; 126 | 127 | fn try_from(pkcs8_key: &pkcs8::KeypairBytes) -> pkcs8::Result { 128 | let signing_key = SigningKey::from_bytes(&pkcs8_key.secret_key); 129 | 130 | // Validate the public key in the PKCS#8 document if present 131 | if let Some(expected_public_bytes) = &pkcs8_key.public_key { 132 | if signing_key.verifying_key().as_ref() != expected_public_bytes.as_ref() { 133 | return Err(pkcs8::Error::KeyMalformed); 134 | } 135 | } 136 | 137 | Ok(signing_key) 138 | } 139 | } 140 | 141 | #[cfg(feature = "pkcs8")] 142 | impl From for pkcs8::KeypairBytes { 143 | fn from(signing_key: SigningKey) -> pkcs8::KeypairBytes { 144 | pkcs8::KeypairBytes::from(&signing_key) 145 | } 146 | } 147 | 148 | #[cfg(feature = "pkcs8")] 149 | impl From<&SigningKey> for pkcs8::KeypairBytes { 150 | fn from(signing_key: &SigningKey) -> pkcs8::KeypairBytes { 151 | pkcs8::KeypairBytes { 152 | secret_key: signing_key.to_bytes(), 153 | public_key: Some(pkcs8::PublicKeyBytes(signing_key.verifying_key().0)), 154 | } 155 | } 156 | } 157 | 158 | #[cfg(feature = "pkcs8")] 159 | impl TryFrom> for SigningKey { 160 | type Error = pkcs8::Error; 161 | 162 | fn try_from(private_key: pkcs8::PrivateKeyInfo<'_>) -> pkcs8::Result { 163 | pkcs8::KeypairBytes::try_from(private_key)?.try_into() 164 | } 165 | } 166 | 167 | /// Ed25519 verifying key. 168 | #[derive(Clone, Debug, Eq, PartialEq)] 169 | pub struct VerifyingKey(pub [u8; Self::SIZE]); 170 | 171 | impl VerifyingKey { 172 | /// Size of a [`VerifyingKey`] in bytes. 173 | pub const SIZE: usize = 32; 174 | 175 | /// Parse a verify key (encoded in compressed Edwards-y form) from a byte slice. 176 | pub fn from_slice(slice: &[u8]) -> signature::Result { 177 | slice.try_into().map(Self).map_err(|_| Error::new()) 178 | } 179 | 180 | /// Alias for `from_slice`. 181 | #[deprecated(since = "0.7.0", note = "use `from_slice` instead")] 182 | pub fn new(bytes: &[u8]) -> signature::Result { 183 | Self::from_slice(bytes) 184 | } 185 | } 186 | 187 | impl AsRef<[u8]> for VerifyingKey { 188 | fn as_ref(&self) -> &[u8] { 189 | &self.0 190 | } 191 | } 192 | 193 | impl From<&SigningKey> for VerifyingKey { 194 | fn from(signing_key: &SigningKey) -> Self { 195 | signing_key.verifying_key() 196 | } 197 | } 198 | 199 | impl Verifier for VerifyingKey { 200 | fn verify(&self, msg: &[u8], signature: &Signature) -> Result<(), Error> { 201 | UnparsedPublicKey::new(&ring::signature::ED25519, self.0.as_ref()) 202 | .verify(msg, &signature.to_bytes()) 203 | .map_err(|_| Error::new()) 204 | } 205 | } 206 | 207 | impl TryFrom<&[u8]> for VerifyingKey { 208 | type Error = Error; 209 | 210 | fn try_from(slice: &[u8]) -> signature::Result { 211 | Self::from_slice(slice) 212 | } 213 | } 214 | -------------------------------------------------------------------------------- /tests/aead/chacha20poly1305.rs: -------------------------------------------------------------------------------- 1 | //! ChaCha20Poly1305 test vectors. 2 | //! 3 | //! From RFC 8439 Section 2.8.2: 4 | //! 5 | 6 | use ring_compat::{ 7 | aead::{Aead, ChaCha20Poly1305, KeyInit, Payload}, 8 | generic_array::GenericArray, 9 | }; 10 | 11 | const KEY: &[u8; 32] = &[ 12 | 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 13 | 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 14 | ]; 15 | 16 | const AAD: &[u8; 12] = &[ 17 | 0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 18 | ]; 19 | 20 | const PLAINTEXT: &[u8] = b"Ladies and Gentlemen of the class of '99: \ 21 | If I could offer you only one tip for the future, sunscreen would be it."; 22 | 23 | const NONCE: &[u8; 12] = &[ 24 | 0x07, 0x00, 0x00, 0x00, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 25 | ]; 26 | 27 | const CIPHERTEXT: &[u8] = &[ 28 | 0xd3, 0x1a, 0x8d, 0x34, 0x64, 0x8e, 0x60, 0xdb, 0x7b, 0x86, 0xaf, 0xbc, 0x53, 0xef, 0x7e, 0xc2, 29 | 0xa4, 0xad, 0xed, 0x51, 0x29, 0x6e, 0x08, 0xfe, 0xa9, 0xe2, 0xb5, 0xa7, 0x36, 0xee, 0x62, 0xd6, 30 | 0x3d, 0xbe, 0xa4, 0x5e, 0x8c, 0xa9, 0x67, 0x12, 0x82, 0xfa, 0xfb, 0x69, 0xda, 0x92, 0x72, 0x8b, 31 | 0x1a, 0x71, 0xde, 0x0a, 0x9e, 0x06, 0x0b, 0x29, 0x05, 0xd6, 0xa5, 0xb6, 0x7e, 0xcd, 0x3b, 0x36, 32 | 0x92, 0xdd, 0xbd, 0x7f, 0x2d, 0x77, 0x8b, 0x8c, 0x98, 0x03, 0xae, 0xe3, 0x28, 0x09, 0x1b, 0x58, 33 | 0xfa, 0xb3, 0x24, 0xe4, 0xfa, 0xd6, 0x75, 0x94, 0x55, 0x85, 0x80, 0x8b, 0x48, 0x31, 0xd7, 0xbc, 34 | 0x3f, 0xf4, 0xde, 0xf0, 0x8e, 0x4b, 0x7a, 0x9d, 0xe5, 0x76, 0xd2, 0x65, 0x86, 0xce, 0xc6, 0x4b, 35 | 0x61, 0x16, 36 | ]; 37 | 38 | const TAG: &[u8] = &[ 39 | 0x1a, 0xe1, 0x0b, 0x59, 0x4f, 0x09, 0xe2, 0x6a, 0x7e, 0x90, 0x2e, 0xcb, 0xd0, 0x60, 0x06, 0x91, 40 | ]; 41 | 42 | #[test] 43 | fn encrypt() { 44 | let key = GenericArray::from_slice(KEY); 45 | let nonce = GenericArray::from_slice(NONCE); 46 | let payload = Payload { 47 | msg: PLAINTEXT, 48 | aad: AAD, 49 | }; 50 | 51 | let cipher = ChaCha20Poly1305::new(key); 52 | let ciphertext = cipher.encrypt(nonce, payload).unwrap(); 53 | 54 | let tag_begins = ciphertext.len() - 16; 55 | assert_eq!(CIPHERTEXT, &ciphertext[..tag_begins]); 56 | assert_eq!(TAG, &ciphertext[tag_begins..]); 57 | } 58 | 59 | #[test] 60 | fn decrypt() { 61 | let key = GenericArray::from_slice(KEY); 62 | let nonce = GenericArray::from_slice(NONCE); 63 | 64 | let mut ciphertext = Vec::from(CIPHERTEXT); 65 | ciphertext.extend_from_slice(TAG); 66 | let payload = Payload { 67 | msg: &ciphertext, 68 | aad: AAD, 69 | }; 70 | 71 | let cipher = ChaCha20Poly1305::new(key); 72 | let plaintext = cipher.decrypt(nonce, payload).unwrap(); 73 | 74 | assert_eq!(PLAINTEXT, plaintext.as_slice()); 75 | } 76 | 77 | #[test] 78 | fn decrypt_modified() { 79 | let key = GenericArray::from_slice(KEY); 80 | let nonce = GenericArray::from_slice(NONCE); 81 | 82 | let mut ciphertext = Vec::from(CIPHERTEXT); 83 | ciphertext.extend_from_slice(TAG); 84 | 85 | // Tweak the first byte 86 | ciphertext[0] ^= 0xaa; 87 | 88 | let payload = Payload { 89 | msg: &ciphertext, 90 | aad: AAD, 91 | }; 92 | 93 | let cipher = ChaCha20Poly1305::new(key); 94 | assert!(cipher.decrypt(nonce, payload).is_err()); 95 | } 96 | -------------------------------------------------------------------------------- /tests/aead/common.rs: -------------------------------------------------------------------------------- 1 | //! Common functionality shared by tests 2 | 3 | /// Test vectors 4 | #[derive(Debug)] 5 | pub struct TestVector { 6 | pub key: &'static K, 7 | pub nonce: &'static [u8; 12], 8 | pub aad: &'static [u8], 9 | pub plaintext: &'static [u8], 10 | pub ciphertext: &'static [u8], 11 | pub tag: &'static [u8; 16], 12 | } 13 | 14 | #[macro_export] 15 | macro_rules! tests { 16 | ($aead:ty, $vectors:expr) => { 17 | #[test] 18 | fn encrypt() { 19 | for vector in $vectors { 20 | let key = GenericArray::from_slice(vector.key); 21 | let nonce = GenericArray::from_slice(vector.nonce); 22 | let payload = Payload { 23 | msg: vector.plaintext, 24 | aad: vector.aad, 25 | }; 26 | 27 | let cipher = <$aead>::new(key); 28 | let ciphertext = cipher.encrypt(nonce, payload).unwrap(); 29 | let (ct, tag) = ciphertext.split_at(ciphertext.len() - 16); 30 | assert_eq!(vector.ciphertext, ct); 31 | assert_eq!(vector.tag, tag); 32 | } 33 | } 34 | 35 | #[test] 36 | fn encrypt_in_place_detached() { 37 | for vector in $vectors { 38 | let key = GenericArray::from_slice(vector.key); 39 | let nonce = GenericArray::from_slice(vector.nonce); 40 | let mut buffer = vector.plaintext.to_vec(); 41 | 42 | let cipher = <$aead>::new(key); 43 | let tag = cipher 44 | .encrypt_in_place_detached(nonce, vector.aad, &mut buffer) 45 | .unwrap(); 46 | 47 | assert_eq!(vector.tag, &tag[..]); 48 | assert_eq!(vector.ciphertext, &buffer[..]); 49 | } 50 | } 51 | 52 | #[test] 53 | fn decrypt() { 54 | for vector in $vectors { 55 | let key = GenericArray::from_slice(vector.key); 56 | let nonce = GenericArray::from_slice(vector.nonce); 57 | let mut ciphertext = Vec::from(vector.ciphertext); 58 | ciphertext.extend_from_slice(vector.tag); 59 | 60 | let payload = Payload { 61 | msg: &ciphertext, 62 | aad: vector.aad, 63 | }; 64 | 65 | let cipher = <$aead>::new(key); 66 | let plaintext = cipher.decrypt(nonce, payload).unwrap(); 67 | 68 | assert_eq!(vector.plaintext, plaintext.as_slice()); 69 | } 70 | } 71 | 72 | #[test] 73 | fn decrypt_in_place() { 74 | for vector in $vectors { 75 | let key = GenericArray::from_slice(vector.key); 76 | let nonce = GenericArray::from_slice(vector.nonce); 77 | let mut buffer = vector.ciphertext.to_vec(); 78 | buffer.extend_from_slice(vector.tag); 79 | 80 | <$aead>::new(key) 81 | .decrypt_in_place(nonce, vector.aad, &mut buffer) 82 | .unwrap(); 83 | 84 | assert_eq!(vector.plaintext, buffer.as_slice()); 85 | } 86 | } 87 | 88 | #[test] 89 | #[should_panic] // not implemented 90 | fn decrypt_in_place_detached() { 91 | for vector in $vectors { 92 | let key = GenericArray::from_slice(vector.key); 93 | let nonce = GenericArray::from_slice(vector.nonce); 94 | let tag = GenericArray::clone_from_slice(vector.tag); 95 | let mut buffer = vector.ciphertext.to_vec(); 96 | 97 | <$aead>::new(key) 98 | .decrypt_in_place_detached(nonce, vector.aad, &mut buffer, &tag) 99 | .unwrap(); 100 | } 101 | } 102 | 103 | #[test] 104 | fn decrypt_modified() { 105 | let vector = &$vectors[0]; 106 | let key = GenericArray::from_slice(vector.key); 107 | let nonce = GenericArray::from_slice(vector.nonce); 108 | 109 | let mut ciphertext = Vec::from(vector.ciphertext); 110 | ciphertext.extend_from_slice(vector.tag); 111 | 112 | // Tweak the first byte 113 | ciphertext[0] ^= 0xaa; 114 | 115 | let payload = Payload { 116 | msg: &ciphertext, 117 | aad: vector.aad, 118 | }; 119 | 120 | let cipher = <$aead>::new(key); 121 | assert!(cipher.decrypt(nonce, payload).is_err()); 122 | 123 | // TODO(tarcieri): test ciphertext is unmodified in in-place API 124 | } 125 | }; 126 | } 127 | -------------------------------------------------------------------------------- /tests/aead/mod.rs: -------------------------------------------------------------------------------- 1 | //! AEAD tests 2 | 3 | #[macro_use] 4 | mod common; 5 | 6 | mod aes128gcm; 7 | mod aes256gcm; 8 | mod chacha20poly1305; 9 | -------------------------------------------------------------------------------- /tests/digest/data/one_million_a.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustCrypto/ring-compat/8e9fec63bc0ba224ee77277c1f968e8d8ef2da55/tests/digest/data/one_million_a.bin -------------------------------------------------------------------------------- /tests/digest/data/sha1.blb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustCrypto/ring-compat/8e9fec63bc0ba224ee77277c1f968e8d8ef2da55/tests/digest/data/sha1.blb -------------------------------------------------------------------------------- /tests/digest/data/sha256.blb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustCrypto/ring-compat/8e9fec63bc0ba224ee77277c1f968e8d8ef2da55/tests/digest/data/sha256.blb -------------------------------------------------------------------------------- /tests/digest/data/sha256_one_million_a.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustCrypto/ring-compat/8e9fec63bc0ba224ee77277c1f968e8d8ef2da55/tests/digest/data/sha256_one_million_a.bin -------------------------------------------------------------------------------- /tests/digest/data/sha384.blb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustCrypto/ring-compat/8e9fec63bc0ba224ee77277c1f968e8d8ef2da55/tests/digest/data/sha384.blb -------------------------------------------------------------------------------- /tests/digest/data/sha512.blb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustCrypto/ring-compat/8e9fec63bc0ba224ee77277c1f968e8d8ef2da55/tests/digest/data/sha512.blb -------------------------------------------------------------------------------- /tests/digest/data/sha512_256.blb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustCrypto/ring-compat/8e9fec63bc0ba224ee77277c1f968e8d8ef2da55/tests/digest/data/sha512_256.blb -------------------------------------------------------------------------------- /tests/digest/data/sha512_one_million_a.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RustCrypto/ring-compat/8e9fec63bc0ba224ee77277c1f968e8d8ef2da55/tests/digest/data/sha512_one_million_a.bin -------------------------------------------------------------------------------- /tests/digest/mod.rs: -------------------------------------------------------------------------------- 1 | //! Digest tests 2 | 3 | // TODO(tarcieri): fix commented out tests 4 | 5 | use digest::{core_api::BlockSizeUser, generic_array::typenum::Unsigned, OutputSizeUser}; 6 | use ring_compat::digest::*; 7 | 8 | // new_test!(sha1_main, "sha1", Sha1, digest_test); 9 | // new_test!(sha256_main, "sha256", Sha256, digest_test); 10 | // new_test!(sha384_main, "sha384", Sha384, digest_test); 11 | // new_test!(sha512_main, "sha512", Sha512, digest_test); 12 | // new_test!(sha512_256_main, "sha512_256", Sha512Trunc256, digest_test); 13 | 14 | // #[test] 15 | // fn sha1_1million_a() { 16 | // let output = include_bytes!("data/one_million_a.bin"); 17 | // one_million_a::(output); 18 | // } 19 | 20 | // #[test] 21 | // fn sha256_1million_a() { 22 | // let output = include_bytes!("data/sha256_one_million_a.bin"); 23 | // one_million_a::(output); 24 | // } 25 | 26 | // #[test] 27 | // fn sha512_1million_a() { 28 | // let output = include_bytes!("data/sha512_one_million_a.bin"); 29 | // one_million_a::(output); 30 | // } 31 | 32 | #[test] 33 | fn test_block_len() { 34 | assert_eq!( 35 | ring::digest::SHA1_FOR_LEGACY_USE_ONLY.block_len(), 36 | ::BlockSize::to_usize() 37 | ); 38 | assert_eq!( 39 | ring::digest::SHA256.block_len(), 40 | ::BlockSize::to_usize() 41 | ); 42 | assert_eq!( 43 | ring::digest::SHA384.block_len(), 44 | ::BlockSize::to_usize() 45 | ); 46 | assert_eq!( 47 | ring::digest::SHA512.block_len(), 48 | ::BlockSize::to_usize() 49 | ); 50 | assert_eq!( 51 | ring::digest::SHA512_256.block_len(), 52 | ::BlockSize::to_usize() 53 | ); 54 | } 55 | 56 | #[test] 57 | fn test_output_len() { 58 | assert_eq!( 59 | ring::digest::SHA1_FOR_LEGACY_USE_ONLY.output_len(), 60 | ::OutputSize::to_usize() 61 | ); 62 | assert_eq!( 63 | ring::digest::SHA256.output_len(), 64 | ::OutputSize::to_usize() 65 | ); 66 | assert_eq!( 67 | ring::digest::SHA384.output_len(), 68 | ::OutputSize::to_usize() 69 | ); 70 | assert_eq!( 71 | ring::digest::SHA512.output_len(), 72 | ::OutputSize::to_usize() 73 | ); 74 | assert_eq!( 75 | ring::digest::SHA512_256.output_len(), 76 | ::OutputSize::to_usize() 77 | ); 78 | } 79 | -------------------------------------------------------------------------------- /tests/lib.rs: -------------------------------------------------------------------------------- 1 | //! ring-compat test suite 2 | 3 | #[cfg(all(feature = "aead", feature = "alloc"))] 4 | mod aead; 5 | 6 | #[cfg(feature = "digest")] 7 | mod digest; 8 | 9 | #[cfg(feature = "signature")] 10 | mod signature; 11 | -------------------------------------------------------------------------------- /tests/signature/ecdsa.rs: -------------------------------------------------------------------------------- 1 | //! ECDSA tests 2 | 3 | mod p256; 4 | mod p384; 5 | 6 | #[macro_export] 7 | macro_rules! ecdsa_tests { 8 | ($signing_key:ty, $verifying_key:ty, $test_vectors:expr) => { 9 | fn example_signing_key() -> $signing_key { 10 | let vector = $test_vectors[0]; 11 | 12 | // Add SEC1 tag byte 13 | let mut pk = vec![0x04]; 14 | pk.extend_from_slice(vector.pk); 15 | 16 | <$signing_key>::from_keypair_bytes(vector.sk, &pk).unwrap() 17 | } 18 | 19 | #[test] 20 | fn sign_and_verify() { 21 | let signing_key = example_signing_key(); 22 | let msg = $test_vectors[0].msg; 23 | let sig = signing_key.sign(msg); 24 | 25 | let verifying_key = signing_key.verifying_key(); 26 | assert!(verifying_key.verify(msg, &sig).is_ok()); 27 | } 28 | 29 | #[test] 30 | fn verify_nist_test_vectors() { 31 | for vector in $test_vectors { 32 | let verifying_key = <$verifying_key>::new(vector.pk).unwrap(); 33 | let sig = Signature::try_from(vector.sig).unwrap(); 34 | assert!(verifying_key.verify(vector.msg, &sig).is_ok()); 35 | } 36 | } 37 | 38 | #[test] 39 | fn rejects_tweaked_nist_test_vectors() { 40 | for vector in $test_vectors { 41 | let mut tweaked_sig = Vec::from(vector.sig); 42 | *tweaked_sig.iter_mut().last().unwrap() ^= 0x42; 43 | 44 | let verifying_key = <$verifying_key>::new(vector.pk).unwrap(); 45 | let sig = Signature::try_from(tweaked_sig.as_slice()).unwrap(); 46 | assert!(verifying_key.verify(vector.msg, &sig).is_err()); 47 | } 48 | } 49 | }; 50 | } 51 | -------------------------------------------------------------------------------- /tests/signature/ecdsa/p256.rs: -------------------------------------------------------------------------------- 1 | //! NIST P-256 tests and test vectors 2 | 3 | use crate::{ecdsa_tests, signature::TestVector}; 4 | use core::convert::TryFrom; 5 | use ring_compat::signature::{ 6 | ecdsa::p256::{Signature, SigningKey, VerifyingKey}, 7 | Signer, Verifier, 8 | }; 9 | 10 | ecdsa_tests!(SigningKey, VerifyingKey, TEST_VECTORS); 11 | 12 | /// ECDSA test vectors for the NIST P-256 elliptic curve (SHA-256) 13 | /// 14 | /// Sourced from NIST's CAVP web site (FIPS 186-4 ECDSA Test Vectors): 15 | /// 16 | /// 17 | const TEST_VECTORS: &[TestVector] = &[ 18 | TestVector { 19 | sk: b"\x51\x9b\x42\x3d\x71\x5f\x8b\x58\x1f\x4f\xa8\xee\x59\xf4\x77\x1a\x5b\x44\xc8\x13\x0b\x4e\x3e\xac\xca\x54\xa5\x6d\xda\x72\xb4\x64", 20 | pk: b"\x1c\xcb\xe9\x1c\x07\x5f\xc7\xf4\xf0\x33\xbf\xa2\x48\xdb\x8f\xcc\xd3\x56\x5d\xe9\x4b\xbf\xb1\x2f\x3c\x59\xff\x46\xc2\x71\xbf\x83\xce\x40\x14\xc6\x88\x11\xf9\xa2\x1a\x1f\xdb\x2c\x0e\x61\x13\xe0\x6d\xb7\xca\x93\xb7\x40\x4e\x78\xdc\x7c\xcd\x5c\xa8\x9a\x4c\xa9", 21 | msg: b"\x59\x05\x23\x88\x77\xc7\x74\x21\xf7\x3e\x43\xee\x3d\xa6\xf2\xd9\xe2\xcc\xad\x5f\xc9\x42\xdc\xec\x0c\xbd\x25\x48\x29\x35\xfa\xaf\x41\x69\x83\xfe\x16\x5b\x1a\x04\x5e\xe2\xbc\xd2\xe6\xdc\xa3\xbd\xf4\x6c\x43\x10\xa7\x46\x1f\x9a\x37\x96\x0c\xa6\x72\xd3\xfe\xb5\x47\x3e\x25\x36\x05\xfb\x1d\xdf\xd2\x80\x65\xb5\x3c\xb5\x85\x8a\x8a\xd2\x81\x75\xbf\x9b\xd3\x86\xa5\xe4\x71\xea\x7a\x65\xc1\x7c\xc9\x34\xa9\xd7\x91\xe9\x14\x91\xeb\x37\x54\xd0\x37\x99\x79\x0f\xe2\xd3\x08\xd1\x61\x46\xd5\xc9\xb0\xd0\xde\xbd\x97\xd7\x9c\xe8", 22 | sig: b"\xf3\xac\x80\x61\xb5\x14\x79\x5b\x88\x43\xe3\xd6\x62\x95\x27\xed\x2a\xfd\x6b\x1f\x6a\x55\x5a\x7a\xca\xbb\x5e\x6f\x79\xc8\xc2\xac\x8b\xf7\x78\x19\xca\x05\xa6\xb2\x78\x6c\x76\x26\x2b\xf7\x37\x1c\xef\x97\xb2\x18\xe9\x6f\x17\x5a\x3c\xcd\xda\x2a\xcc\x05\x89\x03", 23 | }, 24 | TestVector { 25 | sk: b"\x0f\x56\xdb\x78\xca\x46\x0b\x05\x5c\x50\x00\x64\x82\x4b\xed\x99\x9a\x25\xaa\xf4\x8e\xbb\x51\x9a\xc2\x01\x53\x7b\x85\x47\x98\x13", 26 | pk: b"\xe2\x66\xdd\xfd\xc1\x26\x68\xdb\x30\xd4\xca\x3e\x8f\x77\x49\x43\x2c\x41\x60\x44\xf2\xd2\xb8\xc1\x0b\xf3\xd4\x01\x2a\xef\xfa\x8a\xbf\xa8\x64\x04\xa2\xe9\xff\xe6\x7d\x47\xc5\x87\xef\x7a\x97\xa7\xf4\x56\xb8\x63\xb4\xd0\x2c\xfc\x69\x28\x97\x3a\xb5\xb1\xcb\x39", 27 | msg: b"\xc3\x5e\x2f\x09\x25\x53\xc5\x57\x72\x92\x6b\xdb\xe8\x7c\x97\x96\x82\x7d\x17\x02\x4d\xbb\x92\x33\xa5\x45\x36\x6e\x2e\x59\x87\xdd\x34\x4d\xeb\x72\xdf\x98\x71\x44\xb8\xc6\xc4\x3b\xc4\x1b\x65\x4b\x94\xcc\x85\x6e\x16\xb9\x6d\x7a\x82\x1c\x8e\xc0\x39\xb5\x03\xe3\xd8\x67\x28\xc4\x94\xa9\x67\xd8\x30\x11\xa0\xe0\x90\xb5\xd5\x4c\xd4\x7f\x4e\x36\x6c\x09\x12\xbc\x80\x8f\xbb\x2e\xa9\x6e\xfa\xc8\x8f\xb3\xeb\xec\x93\x42\x73\x8e\x22\x5f\x7c\x7c\x2b\x01\x1c\xe3\x75\xb5\x66\x21\xa2\x06\x42\xb4\xd3\x6e\x06\x0d\xb4\x52\x4a\xf1", 28 | sig: b"\x97\x6d\x3a\x4e\x9d\x23\x32\x6d\xc0\xba\xa9\xfa\x56\x0b\x7c\x4e\x53\xf4\x28\x64\xf5\x08\x48\x3a\x64\x73\xb6\xa1\x10\x79\xb2\xdb\x1b\x76\x6e\x9c\xeb\x71\xba\x6c\x01\xdc\xd4\x6e\x0a\xf4\x62\xcd\x4c\xfa\x65\x2a\xe5\x01\x7d\x45\x55\xb8\xee\xef\xe3\x6e\x19\x32", 29 | }, 30 | TestVector { 31 | sk: b"\xe2\x83\x87\x12\x39\x83\x7e\x13\xb9\x5f\x78\x9e\x6e\x1a\xf6\x3b\xf6\x1c\x91\x8c\x99\x2e\x62\xbc\xa0\x40\xd6\x4c\xad\x1f\xc2\xef", 32 | pk: b"\x74\xcc\xd8\xa6\x2f\xba\x0e\x66\x7c\x50\x92\x9a\x53\xf7\x8c\x21\xb8\xff\x0c\x3c\x73\x7b\x0b\x40\xb1\x75\x0b\x23\x02\xb0\xbd\xe8\x29\x07\x4e\x21\xf3\xa0\xef\x88\xb9\xef\xdf\x10\xd0\x6a\xa4\xc2\x95\xcc\x16\x71\xf7\x58\xca\x0e\x4c\xd1\x08\x80\x3d\x0f\x26\x14", 33 | msg: b"\x3c\x05\x4e\x33\x3a\x94\x25\x9c\x36\xaf\x09\xab\x5b\x4f\xf9\xbe\xb3\x49\x2f\x8d\x5b\x42\x82\xd1\x68\x01\xda\xcc\xb2\x9f\x70\xfe\x61\xa0\xb3\x7f\xfe\xf5\xc0\x4c\xd1\xb7\x0e\x85\xb1\xf5\x49\xa1\xc4\xdc\x67\x29\x85\xe5\x0f\x43\xea\x03\x7e\xfa\x99\x64\xf0\x96\xb5\xf6\x2f\x7f\xfd\xf8\xd6\xbf\xb2\xcc\x85\x95\x58\xf5\xa3\x93\xcb\x94\x9d\xbd\x48\xf2\x69\x34\x3b\x52\x63\xdc\xdb\x9c\x55\x6e\xca\x07\x4f\x2e\x98\xe6\xd9\x4c\x2c\x29\xa6\x77\xaf\xaf\x80\x6e\xdf\x79\xb1\x5a\x3f\xcd\x46\xe7\x06\x7b\x76\x69\xf8\x31\x88\xee", 34 | sig: b"\x35\xfb\x60\xf5\xca\x0f\x3c\xa0\x85\x42\xfb\x3c\xc6\x41\xc8\x26\x3a\x2c\xab\x7a\x90\xee\x6a\x5e\x15\x83\xfa\xc2\xbb\x6f\x6b\xd1\xee\x59\xd8\x1b\xc9\xdb\x10\x55\xcc\x0e\xd9\x7b\x15\x9d\x87\x84\xaf\x04\xe9\x85\x11\xd0\xa9\xa4\x07\xb9\x9b\xb2\x92\x57\x2e\x96", 35 | }, 36 | TestVector { 37 | sk: b"\xa3\xd2\xd3\xb7\x59\x6f\x65\x92\xce\x98\xb4\xbf\xe1\x0d\x41\x83\x7f\x10\x02\x7a\x90\xd7\xbb\x75\x34\x94\x90\x01\x8c\xf7\x2d\x07", 38 | pk: b"\x32\x2f\x80\x37\x1b\xf6\xe0\x44\xbc\x49\x39\x1d\x97\xc1\x71\x4a\xb8\x7f\x99\x0b\x94\x9b\xc1\x78\xcb\x7c\x43\xb7\xc2\x2d\x89\xe1\x3c\x15\xd5\x4a\x5c\xc6\xb9\xf0\x9d\xe8\x45\x7e\x87\x3e\xb3\xde\xb1\xfc\xeb\x54\xb0\xb2\x95\xda\x60\x50\x29\x4f\xae\x7f\xd9\x99", 39 | msg: b"\x09\x89\x12\x24\x10\xd5\x22\xaf\x64\xce\xb0\x7d\xa2\xc8\x65\x21\x90\x46\xb4\xc3\xd9\xd9\x9b\x01\x27\x8c\x07\xff\x63\xea\xf1\x03\x9c\xb7\x87\xae\x9e\x2d\xd4\x64\x36\xcc\x04\x15\xf2\x80\xc5\x62\xbe\xbb\x83\xa2\x3e\x63\x9e\x47\x6a\x02\xec\x8c\xff\x7e\xa0\x6c\xd1\x2c\x86\xdc\xc3\xad\xef\xbf\x1a\x9e\x9a\x9b\x66\x46\xc7\x59\x9e\xc6\x31\xb0\xda\x9a\x60\xde\xbe\xb9\xb3\xe1\x93\x24\x97\x7f\x3b\x4f\x36\x89\x2c\x8a\x38\x67\x1c\x8e\x1c\xc8\xe5\x0f\xcd\x50\xf9\xe5\x1d\xea\xf9\x82\x72\xf9\x26\x6f\xc7\x02\xe4\xe5\x7c\x30", 40 | sig: b"\xd7\xc5\x62\x37\x0a\xf6\x17\xb5\x81\xc8\x4a\x24\x68\xcc\x8b\xd5\x0b\xb1\xcb\xf3\x22\xde\x41\xb7\x88\x7c\xe0\x7c\x0e\x58\x84\xca\xb4\x6d\x9f\x2d\x8c\x4b\xf8\x35\x46\xff\x17\x8f\x1d\x78\x93\x7c\x00\x8d\x64\xe8\xec\xc5\xcb\xb8\x25\xcb\x21\xd9\x4d\x67\x0d\x89", 41 | }, 42 | TestVector { 43 | sk: b"\x53\xa0\xe8\xa8\xfe\x93\xdb\x01\xe7\xae\x94\xe1\xa9\x88\x2a\x10\x2e\xbd\x07\x9b\x3a\x53\x58\x27\xd5\x83\x62\x6c\x27\x2d\x28\x0d", 44 | pk: b"\x1b\xce\xc4\x57\x0e\x1e\xc2\x43\x65\x96\xb8\xde\xd5\x8f\x60\xc3\xb1\xeb\xc6\xa4\x03\xbc\x55\x43\x04\x0b\xa8\x29\x63\x05\x72\x44\x8a\xf6\x2a\x4c\x68\x3f\x09\x6b\x28\x55\x83\x20\x73\x7b\xf8\x3b\x99\x59\xa4\x6a\xd2\x52\x10\x04\xef\x74\xcf\x85\xe6\x74\x94\xe1", 45 | msg: b"\xdc\x66\xe3\x9f\x9b\xbf\xd9\x86\x53\x18\x53\x1f\xfe\x92\x07\xf9\x34\xfa\x61\x5a\x5b\x28\x57\x08\xa5\xe9\xc4\x6b\x77\x75\x15\x0e\x81\x8d\x7f\x24\xd2\xa1\x23\xdf\x36\x72\xff\xf2\x09\x4e\x3f\xd3\xdf\x6f\xbe\x25\x9e\x39\x89\xdd\x5e\xdf\xcc\xcb\xe7\xd4\x5e\x26\xa7\x75\xa5\xc4\x32\x9a\x08\x4f\x05\x7c\x42\xc1\x3f\x32\x48\xe3\xfd\x6f\x0c\x76\x67\x8f\x89\x0f\x51\x3c\x32\x29\x2d\xd3\x06\xea\xa8\x4a\x59\xab\xe3\x4b\x16\xcb\x5e\x38\xd0\xe8\x85\x52\x5d\x10\x33\x6c\xa4\x43\xe1\x68\x2a\xa0\x4a\x7a\xf8\x32\xb0\xee\xe4\xe7", 46 | sig: b"\x18\xca\xaf\x7b\x66\x35\x07\xa8\xbc\xd9\x92\xb8\x36\xde\xc9\xdc\x57\x03\xc0\x80\xaf\x5e\x51\xdf\xa3\xa9\xa7\xc3\x87\x18\x26\x04\x77\xc6\x89\x28\xac\x3b\x88\xd9\x85\xfb\x43\xfb\x61\x5f\xb7\xff\x45\xc1\x8b\xa5\xc8\x1a\xf7\x96\xc6\x13\xdf\xa9\x83\x52\xd2\x9c", 47 | }, 48 | TestVector { 49 | sk: b"\x4a\xf1\x07\xe8\xe2\x19\x4c\x83\x0f\xfb\x71\x2a\x65\x51\x1b\xc9\x18\x6a\x13\x30\x07\x85\x5b\x49\xab\x4b\x38\x33\xae\xfc\x4a\x1d", 50 | pk: b"\xa3\x2e\x50\xbe\x3d\xae\x2c\x8b\xa3\xf5\xe4\xbd\xae\x14\xcf\x76\x45\x42\x0d\x42\x5e\xad\x94\x03\x6c\x22\xdd\x6c\x4f\xc5\x9e\x00\xd6\x23\xbf\x64\x11\x60\xc2\x89\xd6\x74\x2c\x62\x57\xae\x6b\xa5\x74\x44\x6d\xd1\xd0\xe7\x4d\xb3\xaa\xa8\x09\x00\xb7\x8d\x4a\xe9", 51 | msg: b"\x60\x09\x74\xe7\xd8\xc5\x50\x8e\x2c\x1a\xab\x07\x83\xad\x0d\x7c\x44\x94\xab\x2b\x4d\xa2\x65\xc2\xfe\x49\x64\x21\xc4\xdf\x23\x8b\x0b\xe2\x5f\x25\x65\x91\x57\xc8\xa2\x25\xfb\x03\x95\x36\x07\xf7\xdf\x99\x6a\xcf\xd4\x02\xf1\x47\xe3\x7a\xee\x2f\x16\x93\xe3\xbf\x1c\x35\xea\xb3\xae\x36\x0a\x2b\xd9\x1d\x04\x62\x2e\xa4\x7f\x83\xd8\x63\xd2\xdf\xec\xb6\x18\xe8\xb8\xbd\xc3\x9e\x17\xd1\x5d\x67\x2e\xee\x03\xbb\x4c\xe2\xcc\x5c\xf6\xb2\x17\xe5\xfa\xf3\xf3\x36\xfd\xd8\x7d\x97\x2d\x3a\x8b\x8a\x59\x3b\xa8\x59\x55\xcc\x9d\x71", 52 | sig: b"\x85\x24\xc5\x02\x4e\x2d\x9a\x73\xbd\xe8\xc7\x2d\x91\x29\xf5\x78\x73\xbb\xad\x0e\xd0\x52\x15\xa3\x72\xa8\x4f\xdb\xc7\x8f\x2e\x68\xd1\x8c\x2c\xaf\x3b\x10\x72\xf8\x70\x64\xec\x5e\x89\x53\xf5\x13\x01\xca\xda\x03\x46\x9c\x64\x02\x44\x76\x03\x28\xeb\x5a\x05\xcb", 53 | }, 54 | TestVector { 55 | sk: b"\x78\xdf\xaa\x09\xf1\x07\x68\x50\xb3\xe2\x06\xe4\x77\x49\x4c\xdd\xcf\xb8\x22\xaa\xa0\x12\x84\x75\x05\x35\x92\xc4\x8e\xba\xf4\xab", 56 | pk: b"\x8b\xcf\xe2\xa7\x21\xca\x6d\x75\x39\x68\xf5\x64\xec\x43\x15\xbe\x48\x57\xe2\x8b\xef\x19\x08\xf6\x1a\x36\x6b\x1f\x03\xc9\x74\x79\x0f\x67\x57\x6a\x30\xb8\xe2\x0d\x42\x32\xd8\x53\x0b\x52\xfb\x4c\x89\xcb\xc5\x89\xed\xe2\x91\xe4\x99\xdd\xd1\x5f\xe8\x70\xab\x96", 57 | msg: b"\xdf\xa6\xcb\x9b\x39\xad\xda\x6c\x74\xcc\x8b\x2a\x8b\x53\xa1\x2c\x49\x9a\xb9\xde\xe0\x1b\x41\x23\x64\x2b\x4f\x11\xaf\x33\x6a\x91\xa5\xc9\xce\x05\x20\xeb\x23\x95\xa6\x19\x0e\xcb\xf6\x16\x9c\x4c\xba\x81\x94\x1d\xe8\xe7\x6c\x9c\x90\x8e\xb8\x43\xb9\x8c\xe9\x5e\x0d\xa2\x9c\x5d\x43\x88\x04\x02\x64\xe0\x5e\x07\x03\x0a\x57\x7c\xc5\xd1\x76\x38\x71\x54\xea\xba\xe2\xaf\x52\xa8\x3e\x85\xc6\x1c\x7c\x61\xda\x93\x0c\x9b\x19\xe4\x5d\x7e\x34\xc8\x51\x6d\xc3\xc2\x38\xfd\xdd\x6e\x45\x0a\x77\x45\x5d\x53\x4c\x48\xa1\x52\x01\x0b", 58 | sig: b"\xc5\xa1\x86\xd7\x2d\xf4\x52\x01\x54\x80\xf7\xf3\x38\x97\x0b\xfe\x82\x50\x87\xf0\x5c\x00\x88\xd9\x53\x05\xf8\x7a\xac\xc9\xb2\x54\x84\xa5\x8f\x9e\x9d\x9e\x73\x53\x44\xb3\x16\xb1\xaa\x1a\xb5\x18\x56\x65\xb8\x51\x47\xdc\x82\xd9\x2e\x96\x9d\x7b\xee\x31\xca\x30", 59 | }, 60 | TestVector { 61 | sk: b"\x80\xe6\x92\xe3\xeb\x9f\xcd\x8c\x7d\x44\xe7\xde\x9f\x7a\x59\x52\x68\x64\x07\xf9\x00\x25\xa1\xd8\x7e\x52\xc7\x09\x6a\x62\x61\x8a", 62 | pk: b"\xa8\x8b\xc8\x43\x02\x79\xc8\xc0\x40\x0a\x77\xd7\x51\xf2\x6c\x0a\xbc\x93\xe5\xde\x4a\xd9\xa4\x16\x63\x57\x95\x2f\xe0\x41\xe7\x67\x2d\x36\x5a\x1e\xef\x25\xea\xd5\x79\xcc\x9a\x06\x9b\x6a\xbc\x1b\x16\xb8\x1c\x35\xf1\x87\x85\xce\x26\xa1\x0b\xa6\xd1\x38\x11\x85", 63 | msg: b"\x51\xd2\x54\x7c\xbf\xf9\x24\x31\x17\x4a\xa7\xfc\x73\x02\x13\x95\x19\xd9\x80\x71\xc7\x55\xff\x1c\x92\xe4\x69\x4b\x58\x58\x7e\xa5\x60\xf7\x2f\x32\xfc\x6d\xd4\xde\xe7\xd2\x2b\xb7\x38\x73\x81\xd0\x25\x6e\x28\x62\xd0\x64\x4c\xdf\x2c\x27\x7c\x5d\x74\x0f\xa0\x89\x83\x0e\xb5\x2b\xf7\x9d\x1e\x75\xb8\x59\x6e\xcf\x0e\xa5\x8a\x0b\x9d\xf6\x1e\x0c\x97\x54\xbf\xcd\x62\xef\xab\x6e\xa1\xbd\x21\x6b\xf1\x81\xc5\x59\x3d\xa7\x9f\x10\x13\x5a\x9b\xc6\xe1\x64\xf1\x85\x4b\xc8\x85\x97\x34\x34\x1a\xad\x23\x7b\xa2\x9a\x81\xa3\xfc\x8b", 64 | sig: b"\x9d\x0c\x6a\xfb\x6d\xf3\xbc\xed\x45\x5b\x45\x9c\xc2\x13\x87\xe1\x49\x29\x39\x26\x64\xbb\x87\x41\xa3\x69\x3a\x17\x95\xca\x69\x02\xd7\xf9\xdd\xd1\x91\xf1\xf4\x12\x86\x94\x29\x20\x9e\xe3\x81\x4c\x75\xc7\x2f\xa4\x6a\x9c\xcc\xf8\x04\xa2\xf5\xcc\x0b\x7e\x73\x9f", 65 | }, 66 | TestVector { 67 | sk: b"\x5e\x66\x6c\x0d\xb0\x21\x4c\x3b\x62\x7a\x8e\x48\x54\x1c\xc8\x4a\x8b\x6f\xd1\x5f\x30\x0d\xa4\xdf\xf5\xd1\x8a\xec\x6c\x55\xb8\x81", 68 | pk: b"\x1b\xc4\x87\x57\x0f\x04\x0d\xc9\x41\x96\xc9\xbe\xfe\x8a\xb2\xb6\xde\x77\x20\x8b\x1f\x38\xbd\xaa\xe2\x8f\x96\x45\xc4\xd2\xbc\x3a\xec\x81\x60\x2a\xbd\x83\x45\xe7\x18\x67\xc8\x21\x03\x13\x73\x78\x65\xb8\xaa\x18\x68\x51\xe1\xb4\x8e\xac\xa1\x40\x32\x0f\x5d\x8f", 69 | msg: b"\x55\x8c\x2a\xc1\x30\x26\x40\x2b\xad\x4a\x0a\x83\xeb\xc9\x46\x8e\x50\xf7\xff\xab\x06\xd6\xf9\x81\xe5\xdb\x1d\x08\x20\x98\x06\x5b\xcf\xf6\xf2\x1a\x7a\x74\x55\x8b\x1e\x86\x12\x91\x4b\x8b\x5a\x0a\xa2\x8e\xd5\xb5\x74\xc3\x6a\xc4\xea\x58\x68\x43\x2a\x62\xbb\x8e\xf0\x69\x5d\x27\xc1\xe3\xce\xaf\x75\xc7\xb2\x51\xc6\x5d\xdb\x26\x86\x96\xf0\x7c\x16\xd2\x76\x79\x73\xd8\x5b\xeb\x44\x3f\x21\x1e\x64\x45\xe7\xfe\x5d\x46\xf0\xdc\xe7\x0d\x58\xa4\xcd\x9f\xe7\x06\x88\xc0\x35\x68\x8e\xa8\xc6\xba\xec\x65\xa5\xfc\x7e\x2c\x93\xe8", 70 | sig: b"\x2f\x9e\x2b\x4e\x9f\x74\x7c\x65\x7f\x70\x5b\xff\xd1\x24\xee\x17\x8b\xbc\x53\x91\xc8\x6d\x05\x67\x17\xb1\x40\xc1\x53\x57\x0f\xd9\xf5\x41\x3b\xfd\x85\x94\x9d\xa8\xd8\x3d\xe8\x3a\xb0\xd1\x9b\x29\x86\x61\x3e\x22\x4d\x19\x01\xd7\x69\x19\xde\x23\xcc\xd0\x31\x99", 71 | }, 72 | TestVector { 73 | sk: b"\xf7\x3f\x45\x52\x71\xc8\x77\xc4\xd5\x33\x46\x27\xe3\x7c\x27\x8f\x68\xd1\x43\x01\x4b\x0a\x05\xaa\x62\xf3\x08\xb2\x10\x1c\x53\x08", 74 | pk: b"\xb8\x18\x8b\xd6\x87\x01\xfc\x39\x6d\xab\x53\x12\x5d\x4d\x28\xea\x33\xa9\x1d\xaf\x6d\x21\x48\x5f\x47\x70\xf6\xea\x8c\x56\x5d\xde\x42\x3f\x05\x88\x10\xf2\x77\xf8\xfe\x07\x6f\x6d\xb5\x6e\x92\x85\xa1\xbf\x2c\x2a\x1d\xae\x14\x50\x95\xed\xd9\xc0\x49\x70\xbc\x4a", 75 | msg: b"\x4d\x55\xc9\x9e\xf6\xbd\x54\x62\x16\x62\xc3\xd1\x10\xc3\xcb\x62\x7c\x03\xd6\x31\x13\x93\xb2\x64\xab\x97\xb9\x0a\x4b\x15\x21\x4a\x55\x93\xba\x25\x10\xa5\x3d\x63\xfb\x34\xbe\x25\x1f\xac\xb6\x97\xc9\x73\xe1\x1b\x66\x5c\xb7\x92\x0f\x16\x84\xb0\x03\x1b\x4d\xd3\x70\xcb\x92\x7c\xa7\x16\x8b\x0b\xf8\xad\x28\x5e\x05\xe9\xe3\x1e\x34\xbc\x24\x02\x47\x39\xfd\xc1\x0b\x78\x58\x6f\x29\xef\xf9\x44\x12\x03\x4e\x3b\x60\x6e\xd8\x50\xec\x2c\x19\x00\xe8\xe6\x81\x51\xfc\x4a\xee\x5a\xde\xbb\x06\x6e\xb6\xda\x4e\xaa\x56\x81\x37\x8e", 76 | sig: b"\x1c\xc6\x28\x53\x3d\x00\x04\xb2\xb2\x0e\x7f\x4b\xaa\xd0\xb8\xbb\x5e\x06\x73\xdb\x15\x9b\xbc\xcf\x92\x49\x1a\xef\x61\xfc\x96\x20\x88\x0e\x0b\xbf\x82\xa8\xcf\x81\x8e\xd4\x6b\xa0\x3c\xf0\xfc\x6c\x89\x8e\x36\xfc\xa3\x6c\xc7\xfd\xb1\xd2\xdb\x75\x03\x63\x44\x30", 77 | }, 78 | TestVector { 79 | sk: b"\xb2\x0d\x70\x5d\x9b\xd7\xc2\xb8\xdc\x60\x39\x3a\x53\x57\xf6\x32\x99\x0e\x59\x9a\x09\x75\x57\x3a\xc6\x7f\xd8\x9b\x49\x18\x79\x06", 80 | pk: b"\x51\xf9\x9d\x2d\x52\xd4\xa6\xe7\x34\x48\x4a\x01\x8b\x7c\xa2\xf8\x95\xc2\x92\x9b\x67\x54\xa3\xa0\x32\x24\xd0\x7a\xe6\x11\x66\xce\x47\x37\xda\x96\x3c\x6e\xf7\x24\x7f\xb8\x8d\x19\xf9\xb0\xc6\x67\xca\xc7\xfe\x12\x83\x7f\xda\xb8\x8c\x66\xf1\x0d\x3c\x14\xca\xd1", 81 | msg: b"\xf8\x24\x8a\xd4\x7d\x97\xc1\x8c\x98\x4f\x1f\x5c\x10\x95\x0d\xc1\x40\x47\x13\xc5\x6b\x6e\xa3\x97\xe0\x1e\x6d\xd9\x25\xe9\x03\xb4\xfa\xdf\xe2\xc9\xe8\x77\x16\x9e\x71\xce\x3c\x7f\xe5\xce\x70\xee\x42\x55\xd9\xcd\xc2\x6f\x69\x43\xbf\x48\x68\x78\x74\xde\x64\xf6\xcf\x30\xa0\x12\x51\x2e\x78\x7b\x88\x05\x9b\xbf\x56\x11\x62\xbd\xcc\x23\xa3\x74\x2c\x83\x5a\xc1\x44\xcc\x14\x16\x7b\x1b\xd6\x72\x7e\x94\x05\x40\xa9\xc9\x9f\x3c\xbb\x41\xfb\x1d\xcb\x00\xd7\x6d\xda\x04\x99\x58\x47\xc6\x57\xf4\xc1\x9d\x30\x3e\xb0\x9e\xb4\x8a", 82 | sig: b"\x98\x86\xae\x46\xc1\x41\x5c\x3b\xc9\x59\xe8\x2b\x76\x0a\xd7\x60\xaa\xb6\x68\x85\xa8\x4e\x62\x0a\xa3\x39\xfd\xf1\x02\x46\x5c\x42\x2b\xf3\xa8\x0b\xc0\x4f\xaa\x35\xeb\xec\xc0\xf4\x86\x4a\xc0\x2d\x34\x9f\x6f\x12\x6e\x0f\x98\x85\x01\xb8\xd3\x07\x54\x09\xa2\x6c", 83 | }, 84 | TestVector { 85 | sk: b"\xd4\x23\x4b\xeb\xfb\xc8\x21\x05\x03\x41\xa3\x7e\x12\x40\xef\xe5\xe3\x37\x63\xcb\xbb\x2e\xf7\x6a\x1c\x79\xe2\x47\x24\xe5\xa5\xe7", 86 | pk: b"\x8f\xb2\x87\xf0\x20\x2a\xd5\x7a\xe8\x41\xae\xa3\x5f\x29\xb2\xe1\xd5\x3e\x19\x6d\x0d\xdd\x9a\xec\x24\x81\x3d\x64\xc0\x92\x2f\xb7\x1f\x6d\xaf\xf1\xaa\x2d\xd2\xd6\xd3\x74\x16\x23\xee\xcb\x5e\x7b\x61\x29\x97\xa1\x03\x9a\xab\x2e\x5c\xf2\xde\x96\x9c\xfe\xa5\x73", 87 | msg: b"\x3b\x6e\xe2\x42\x59\x40\xb3\xd2\x40\xd3\x5b\x97\xb6\xdc\xd6\x1e\xd3\x42\x3d\x8e\x71\xa0\xad\xa3\x5d\x47\xb3\x22\xd1\x7b\x35\xea\x04\x72\xf3\x5e\xdd\x1d\x25\x2f\x87\xb8\xb6\x5e\xf4\xb7\x16\x66\x9f\xc9\xac\x28\xb0\x0d\x34\xa9\xd6\x6a\xd1\x18\xc9\xd9\x4e\x7f\x46\xd0\xb4\xf6\xc2\xb2\xd3\x39\xfd\x6b\xcd\x35\x12\x41\xa3\x87\xcc\x82\x60\x90\x57\x04\x8c\x12\xc4\xec\x3d\x85\xc6\x61\x97\x5c\x45\xb3\x00\xcb\x96\x93\x0d\x89\x37\x0a\x32\x7c\x98\xb6\x7d\xef\xaa\x89\x49\x7a\xa8\xef\x99\x4c\x77\xf1\x13\x0f\x75\x2f\x94\xa4", 88 | sig: b"\x49\x0e\xfd\x10\x6b\xe1\x1f\xc3\x65\xc7\x46\x7e\xb8\x9b\x8d\x39\xe1\x5d\x65\x17\x53\x56\x77\x5d\xea\xb2\x11\x16\x3c\x25\x04\xcb\x64\x43\x00\xfc\x0d\xa4\xd4\x0f\xb8\xc6\xea\xd5\x10\xd1\x4f\x0b\xd4\xe1\x32\x1a\x46\x9e\x9c\x0a\x58\x14\x64\xc7\x18\x6b\x7a\xa7", 89 | }, 90 | TestVector { 91 | sk: b"\xb5\x8f\x52\x11\xdf\xf4\x40\x62\x6b\xb5\x6d\x0a\xd4\x83\x19\x3d\x60\x6c\xf2\x1f\x36\xd9\x83\x05\x43\x32\x72\x92\xf4\xd2\x5d\x8c", 92 | pk: b"\x68\x22\x9b\x48\xc2\xfe\x19\xd3\xdb\x03\x4e\x4c\x15\x07\x7e\xb7\x47\x1a\x66\x03\x1f\x28\xa9\x80\x82\x18\x73\x91\x52\x98\xba\x76\x30\x3e\x8e\xe3\x74\x2a\x89\x3f\x78\xb8\x10\x99\x1d\xa6\x97\x08\x3d\xd8\xf1\x11\x28\xc4\x76\x51\xc2\x7a\x56\x74\x0a\x80\xc2\x4c", 93 | msg: b"\xc5\x20\x4b\x81\xec\x0a\x4d\xf5\xb7\xe9\xfd\xa3\xdc\x24\x5f\x98\x08\x2a\xe7\xf4\xef\xe8\x19\x98\xdc\xaa\x28\x6b\xd4\x50\x7c\xa8\x40\xa5\x3d\x21\xb0\x1e\x90\x4f\x55\xe3\x8f\x78\xc3\x75\x7d\x5a\x5a\x4a\x44\xb1\xd5\xd4\xe4\x80\xbe\x3a\xfb\x5b\x39\x4a\x5d\x28\x40\xaf\x42\xb1\xb4\x08\x3d\x40\xaf\xbf\xe2\x2d\x70\x2f\x37\x0d\x32\xdb\xfd\x39\x2e\x12\x8e\xa4\x72\x4d\x66\xa3\x70\x1d\xa4\x1a\xe2\xf0\x3b\xb4\xd9\x1b\xb9\x46\xc7\x96\x94\x04\xcb\x54\x4f\x71\xeb\x7a\x49\xeb\x4c\x4e\xc5\x57\x99\xbd\xa1\xeb\x54\x51\x43\xa7", 94 | sig: b"\xe6\x7a\x97\x17\xcc\xf9\x68\x41\x48\x9d\x65\x41\xf4\xf6\xad\xb1\x2d\x17\xb5\x9a\x6b\xef\x84\x7b\x61\x83\xb8\xfc\xf1\x6a\x32\xeb\x9a\xe6\xba\x6d\x63\x77\x06\x84\x9a\x6a\x9f\xc3\x88\xcf\x02\x32\xd8\x5c\x26\xea\x0d\x1f\xe7\x43\x7a\xdb\x48\xde\x58\x36\x43\x33", 95 | }, 96 | TestVector { 97 | sk: b"\x54\xc0\x66\x71\x1c\xdb\x06\x1e\xda\x07\xe5\x27\x5f\x7e\x95\xa9\x96\x2c\x67\x64\xb8\x4f\x6f\x1f\x3a\xb5\xa5\x88\xe0\xa2\xaf\xb1", 98 | pk: b"\x0a\x7d\xbb\x8b\xf5\x0c\xb6\x05\xeb\x22\x68\xb0\x81\xf2\x6d\x6b\x08\xe0\x12\xf9\x52\xc4\xb7\x0a\x5a\x1e\x6e\x7d\x46\xaf\x98\xbb\xf2\x6d\xd7\xd7\x99\x93\x00\x62\x48\x08\x49\x96\x2c\xcf\x50\x04\xed\xcf\xd3\x07\xc0\x44\xf4\xe8\xf6\x67\xc9\xba\xa8\x34\xee\xae", 99 | msg: b"\x72\xe8\x1f\xe2\x21\xfb\x40\x21\x48\xd8\xb7\xab\x03\x54\x9f\x11\x80\xbc\xc0\x3d\x41\xca\x59\xd7\x65\x38\x01\xf0\xba\x85\x3a\xdd\x1f\x6d\x29\xed\xd7\xf9\xab\xc6\x21\xb2\xd5\x48\xf8\xdb\xf8\x97\x9b\xd1\x66\x08\xd2\xd8\xfc\x32\x60\xb4\xeb\xc0\xdd\x42\x48\x24\x81\xd5\x48\xc7\x07\x57\x11\xb5\x75\x96\x49\xc4\x1f\x43\x9f\xad\x69\x95\x49\x56\xc9\x32\x68\x41\xea\x64\x92\x95\x68\x29\xf9\xe0\xdc\x78\x9f\x73\x63\x3b\x40\xf6\xac\x77\xbc\xae\x6d\xfc\x79\x30\xcf\xe8\x9e\x52\x6d\x16\x84\x36\x5c\x5b\x0b\xe2\x43\x7f\xdb\x01", 100 | sig: b"\xb5\x3c\xe4\xda\x1a\xa7\xc0\xdc\x77\xa1\x89\x6a\xb7\x16\xb9\x21\x49\x9a\xed\x78\xdf\x72\x5b\x15\x04\xab\xa1\x59\x7b\xa0\xc6\x4b\xd7\xc2\x46\xdc\x7a\xd0\xe6\x77\x00\xc3\x73\xed\xcf\xdd\x1c\x0a\x04\x95\xfc\x95\x45\x49\xad\x57\x9d\xf6\xed\x14\x38\x84\x08\x51", 101 | }, 102 | TestVector { 103 | sk: b"\x34\xfa\x46\x82\xbf\x6c\xb5\xb1\x67\x83\xad\xcd\x18\xf0\xe6\x87\x9b\x92\x18\x5f\x76\xd7\xc9\x20\x40\x9f\x90\x4f\x52\x2d\xb4\xb1", 104 | pk: b"\x10\x5d\x22\xd9\xc6\x26\x52\x0f\xac\xa1\x3e\x7c\xed\x38\x2d\xcb\xe9\x34\x98\x31\x5f\x00\xcc\x0a\xc3\x9c\x48\x21\xd0\xd7\x37\x37\x6c\x47\xf3\xcb\xbf\xa9\x7d\xfc\xeb\xe1\x62\x70\xb8\xc7\xd5\xd3\xa5\x90\x0b\x88\x8c\x42\x52\x0d\x75\x1e\x8f\xaf\x3b\x40\x1e\xf4", 105 | msg: b"\x21\x18\x8c\x3e\xdd\x5d\xe0\x88\xda\xcc\x10\x76\xb9\xe1\xbc\xec\xd7\x9d\xe1\x00\x3c\x24\x14\xc3\x86\x61\x73\x05\x4d\xc8\x2d\xde\x85\x16\x9b\xaa\x77\x99\x3a\xdb\x20\xc2\x69\xf6\x0a\x52\x26\x11\x18\x28\x57\x8b\xcc\x7c\x29\xe6\xe8\xd2\xda\xe8\x18\x06\x15\x2c\x8b\xa0\xc6\xad\xa1\x98\x6a\x19\x83\xeb\xee\xc1\x47\x3a\x73\xa0\x47\x95\xb6\x31\x9d\x48\x66\x2d\x40\x88\x1c\x17\x23\xa7\x06\xf5\x16\xfe\x75\x30\x0f\x92\x40\x8a\xa1\xdc\x6a\xe4\x28\x8d\x20\x46\xf2\x3c\x1a\xa2\xe5\x4b\x7f\xb6\x44\x8a\x0d\xa9\x22\xbd\x7f\x34", 106 | sig: b"\x54\x2c\x40\xa1\x81\x40\xa6\x26\x6d\x6f\x02\x86\xe2\x4e\x9a\x7b\xad\x76\x50\xe7\x2e\xf0\xe2\x13\x1e\x62\x9c\x07\x6d\x96\x26\x63\x4f\x7f\x65\x30\x5e\x24\xa6\xbb\xb5\xcf\xf7\x14\xba\x8f\x5a\x2c\xee\x5b\xdc\x89\xba\x8d\x75\xdc\xbf\x21\x96\x6c\xe3\x8e\xb6\x6f", 107 | }, 108 | ]; 109 | -------------------------------------------------------------------------------- /tests/signature/ecdsa/p384.rs: -------------------------------------------------------------------------------- 1 | //! NIST P-384 tests and test vectors 2 | 3 | use crate::{ecdsa_tests, signature::TestVector}; 4 | use core::convert::TryFrom; 5 | use ring_compat::signature::{ 6 | ecdsa::p384::{Signature, SigningKey, VerifyingKey}, 7 | Signer, Verifier, 8 | }; 9 | 10 | ecdsa_tests!(SigningKey, VerifyingKey, TEST_VECTORS); 11 | 12 | /// ECDSA test vectors for the NIST P-384 elliptic curve 13 | /// 14 | /// Sourced from NIST's CAVP web site (FIPS 186-4 ECDSA Test Vectors): 15 | /// 16 | /// 17 | const TEST_VECTORS: &[TestVector] = &[ 18 | TestVector { 19 | sk: b"\x20\x1b\x43\x2d\x8d\xf1\x43\x24\x18\x2d\x62\x61\xdb\x3e\x4b\x3f\x46\xa8\x28\x44\x82\xd5\x2e\x37\x0d\xa4\x1e\x6c\xbd\xf4\x5e\xc2\x95\x2f\x5d\xb7\xcc\xbc\xe3\xbc\x29\x44\x9f\x4f\xb0\x80\xac\x97", 20 | pk: b"\xc2\xb4\x79\x44\xfb\x5d\xe3\x42\xd0\x32\x85\x88\x01\x77\xca\x5f\x7d\x0f\x2f\xca\xd7\x67\x8c\xce\x42\x29\xd6\xe1\x93\x2f\xca\xc1\x1b\xfc\x3c\x3e\x97\xd9\x42\xa3\xc5\x6b\xf3\x41\x23\x01\x3d\xbf\x37\x25\x79\x06\xa8\x22\x38\x66\xed\xa0\x74\x3c\x51\x96\x16\xa7\x6a\x75\x8a\xe5\x8a\xee\x81\xc5\xfd\x35\xfb\xf3\xa8\x55\xb7\x75\x4a\x36\xd4\xa0\x67\x2d\xf9\x5d\x6c\x44\xa8\x1c\xf7\x62\x0c\x2d", 21 | msg: b"\x6b\x45\xd8\x80\x37\x39\x2e\x13\x71\xd9\xfd\x1c\xd1\x74\xe9\xc1\x83\x8d\x11\xc3\xd6\x13\x3d\xc1\x7e\x65\xfa\x0c\x48\x5d\xcc\xa9\xf5\x2d\x41\xb6\x01\x61\x24\x60\x39\xe4\x2e\xc7\x84\xd4\x94\x00\xbf\xfd\xb5\x14\x59\xf5\xde\x65\x40\x91\x30\x1a\x09\x37\x8f\x93\x46\x4d\x52\x11\x8b\x48\xd4\x4b\x30\xd7\x81\xeb\x1d\xbe\xd0\x9d\xa1\x1f\xb4\xc8\x18\xdb\xd4\x42\xd1\x61\xab\xa4\xb9\xed\xc7\x9f\x05\xe4\xb7\xe4\x01\x65\x13\x95\xb5\x3b\xd8\xb5\xbd\x3f\x2a\xaa\x6a\x00\x87\x7f\xa9\xb4\x5c\xad\xb8\xe6\x48\x55\x0b\x4c\x6c\xbe", 22 | sig: b"\x50\x83\x5a\x92\x51\xba\xd0\x08\x10\x61\x77\xef\x00\x4b\x09\x1a\x1e\x42\x35\xcd\x0d\xa8\x4f\xff\x54\x54\x2b\x0e\xd7\x55\xc1\xd6\xf2\x51\x60\x9d\x14\xec\xf1\x8f\x9e\x1d\xdf\xe6\x9b\x94\x6e\x32\x04\x75\xf3\xd3\x0c\x64\x63\xb6\x46\xe8\xd3\xbf\x24\x55\x83\x03\x14\x61\x1c\xbd\xe4\x04\xbe\x51\x8b\x14\x46\x4f\xdb\x19\x5f\xdc\xc9\x2e\xb2\x22\xe6\x1f\x42\x6a\x4a\x59\x2c\x00\xa6\xa8\x97\x21", 23 | }, 24 | TestVector { 25 | sk: b"\x23\xd9\xf4\xea\x6d\x87\xb7\xd6\x16\x3d\x64\x25\x6e\x34\x49\x25\x5d\xb1\x47\x86\x40\x1a\x51\xda\xa7\x84\x71\x61\xbf\x56\xd4\x94\x32\x5a\xd2\xac\x8b\xa9\x28\x39\x4e\x01\x06\x1d\x88\x2c\x35\x28", 26 | pk: b"\x5d\x42\xd6\x30\x1c\x54\xa4\x38\xf6\x59\x70\xba\xe2\xa0\x98\xcb\xc5\x67\xe9\x88\x40\x00\x6e\x35\x62\x21\x96\x6c\x86\xd8\x2e\x8e\xca\x51\x5b\xca\x85\x0e\xaa\x3c\xd4\x1f\x17\x5f\x03\xa0\xcb\xfd\x4a\xef\x5a\x0c\xee\xce\x95\xd3\x82\xbd\x70\xab\x5c\xe1\xcb\x77\x40\x8b\xae\x42\xb5\x1a\x08\x81\x6d\x5e\x5e\x1d\x3d\xa8\xc1\x8f\xcc\x95\x56\x4a\x75\x27\x30\xb0\xaa\xbe\xa9\x83\xcc\xea\x4e\x2e", 27 | msg: b"\xd7\x68\xf4\x1e\x6e\x8e\xc2\x12\x5d\x6c\xf5\x78\x6d\x1b\xa9\x66\x68\xac\x65\x66\xc5\xcd\xbb\xe4\x07\xf7\xf2\x05\x1f\x3a\xd6\xb1\xac\xdb\xfe\x13\xed\xf0\xd0\xa8\x6f\xa1\x10\xf4\x05\x40\x6b\x69\x08\x52\x19\xb5\xa2\x34\xeb\xdb\x93\x15\x32\x41\xf7\x85\xd4\x58\x11\xb3\x54\x0d\x1c\x37\x42\x4c\xc7\x19\x44\x24\x78\x7a\x51\xb7\x96\x79\x26\x64\x84\xc7\x87\xfb\x1d\xed\x6d\x1a\x26\xb9\x56\x7d\x5e\xa6\x8f\x04\xbe\x41\x6c\xaf\x3b\xe9\xbd\x2c\xaf\xa2\x08\xfe\x2a\x9e\x23\x4d\x3a\xe5\x57\xc6\x5d\x3f\xe6\xda\x4c\xb4\x8d\xa4", 28 | sig: b"\xfb\x31\x8f\x4c\xb1\x27\x62\x82\xbb\x43\xf7\x33\xa7\xfb\x7c\x56\x7c\xe9\x4f\x4d\x02\x92\x4f\xc7\x58\x63\x5a\xb2\xd1\x10\x71\x08\xbf\x15\x9b\x85\xdb\x08\x0c\xdc\x3b\x30\xfb\xb5\x40\x00\x16\xf3\x58\x8e\x3d\x7a\xf5\xda\x03\xea\xe2\x55\xec\xb1\x81\x31\x00\xd9\x5e\xdc\x24\x34\x76\xb7\x24\xb2\x2d\xb8\xe8\x53\x77\x66\x0d\x76\x45\xdd\xc1\xc2\xc2\xee\x4e\xae\xa8\xb6\x83\xdb\xe2\x2f\x86\xca", 29 | }, 30 | TestVector { 31 | sk: b"\xb5\xf6\x70\xe9\x8d\x8b\xef\xc4\x6f\x6f\x51\xfb\x29\x97\x06\x95\x50\xc2\xa5\x2e\xbf\xb4\xe5\xe2\x5d\xd9\x05\x35\x2d\x9e\xf8\x9e\xed\x5c\x2e\xcd\x16\x52\x18\x53\xaa\xdb\x1b\x52\xb8\xc4\x2a\xe6", 32 | pk: b"\x44\xff\xb2\xa3\xa9\x5e\x12\xd8\x7c\x72\xb5\xea\x0a\x8a\x7c\xb8\x9f\x56\xb3\xbd\x46\x34\x2b\x23\x03\x60\x8d\x72\x16\x30\x1c\x21\xb5\xd2\x92\x1d\x80\xb6\x62\x8d\xc5\x12\xcc\xb8\x4e\x2f\xc2\x78\xe4\xc1\x00\x2f\x18\x28\xab\xae\xc7\x68\xca\xdc\xb7\xcf\x42\xfb\xf9\x3b\x17\x09\xcc\xae\x6d\xf5\xb1\x34\xc4\x1f\xae\x2b\x9a\x18\x8b\xfb\xe1\xec\xcf\xf0\xbd\x34\x85\x17\xd7\x22\x7f\x20\x71\xa6", 33 | msg: b"\x6a\xf6\x65\x2e\x92\xa1\x7b\x78\x98\xe4\x0b\x67\x76\xfa\xba\xf0\xd7\x4c\xf8\x8d\x8f\x0e\xbf\xa6\x08\x83\x09\xcb\xe0\x9f\xac\x47\x2e\xea\xc2\xaa\x8e\xa9\x6b\x8c\x12\xe9\x93\xd1\x4c\x93\xf8\xef\x4e\x8b\x54\x7a\xfe\x7a\xe5\xe4\xf3\x97\x31\x70\xb3\x5d\xeb\x32\x39\x89\x89\x18\xc7\x0c\x10\x56\x33\x2c\x3f\x89\x4c\xd6\x43\xd2\xd9\xb9\x3c\x25\x61\xaa\xc0\x69\x57\x7b\xba\xb4\x58\x03\x25\x0a\x31\xcd\x62\x22\x6c\xab\x94\xd8\xcb\xa7\x26\x1d\xce\x9f\xe8\x8c\x21\x0c\x21\x2b\x54\x32\x9d\x76\xa2\x73\x52\x2c\x8b\xa9\x1d\xdf", 34 | sig: b"\xb1\x1d\xb5\x92\xe4\xeb\xc7\x5b\x64\x72\xb8\x79\xb1\xd8\xce\x57\x45\x2c\x61\x5a\xef\x20\xf6\x7a\x28\x0f\x8b\xca\x9b\x11\xa3\x0a\xd4\xac\x9d\x69\x54\x12\x58\xc7\xdd\x5d\x0b\x4a\xb8\xdd\x7d\x49\x4e\xb5\x1d\xb8\x00\x4e\x46\xd4\x38\x35\x9a\xbf\x06\x0a\x94\x44\x61\x6c\xb4\x6b\x4f\x99\xc9\xa0\x5b\x53\xba\x6d\xf0\x2e\x91\x4c\x9c\x0b\x6c\xc3\xa9\x79\x1d\x80\x4d\x2e\x4c\x09\x84\xda\xb1\xcc", 35 | }, 36 | TestVector { 37 | sk: b"\xde\x59\x75\xd8\x93\x25\x33\xf0\x92\xe7\x62\x95\xed\x6b\x23\xf1\x0f\xc5\xfb\xa4\x8b\xfb\x82\xc6\xcc\x71\x48\x26\xba\xf0\x12\x68\x13\x24\x7f\x8b\xd5\x1d\x57\x38\x50\x36\x54\xab\x22\x45\x99\x76", 38 | pk: b"\xf1\xfa\xba\xfc\x01\xfe\xc7\xe9\x6d\x98\x25\x28\xd9\xef\x3a\x2a\x18\xb7\xfe\x8a\xe0\xfa\x06\x73\x97\x73\x41\xc7\xae\x4a\xe8\xd8\xd3\xd6\x74\x20\x34\x3d\x01\x3a\x98\x4f\x5f\x61\xda\x29\xae\x38\x1a\x31\xcf\x90\x2c\x46\x34\x3d\x01\xb2\xeb\xb6\x14\xbc\x78\x9c\x31\x3b\x5f\x91\xf9\x30\x2a\xd9\x41\x8e\x9c\x79\x75\x63\xe2\xfa\x3d\x44\x50\x0f\x47\xb4\xe2\x6a\xd8\xfd\xec\x1a\x81\x6d\x1d\xcf", 39 | msg: b"\xb9\x6d\x74\xb2\x26\x5d\xd8\x95\xd9\x4e\x25\x09\x2f\xb9\x26\x2d\xc4\xf2\xf7\xa3\x28\xa3\xc0\xc3\xda\x13\x4b\x2d\x0a\x4e\x20\x58\xca\x99\x4e\x34\x45\xc5\xff\x4f\x81\x27\x38\xe1\xb0\xc0\xf7\xa1\x26\x48\x69\x42\xa1\x2e\x67\x4a\x21\xf2\x2d\x08\x86\xd6\x8d\xf2\x37\x5f\x41\x68\x5d\x69\x4d\x48\x7a\x71\x80\x24\x93\x3a\x7c\x43\x06\xf3\x3f\x1a\x42\x67\xd4\x69\xc5\x30\xb0\xfe\xd4\xe7\xde\xa5\x20\xa1\x9d\xd6\x8b\xf0\x20\x3c\xc8\x7c\xad\x65\x22\x60\xed\x43\xb7\xb2\x3f\x6e\xd1\x40\xd3\x08\x58\x75\x19\x01\x91\xa0\x38\x1a", 40 | sig: b"\xc2\xfb\xdd\x6a\x56\x78\x90\x24\x08\x21\x73\x72\x5d\x79\x7e\xf9\xfd\x6a\xcc\xb6\xae\x66\x4b\x72\x60\xf9\xe8\x3c\xb8\xab\x24\x90\x42\x8c\x8b\x9c\x52\xe1\x53\x61\x22\x95\x43\x2f\xec\x4d\x59\xcd\x80\x56\xc5\xbb\x57\xf4\x1f\x73\x08\x28\x88\xb2\x34\xfc\xda\x32\x0a\x33\x25\x0b\x5d\xa0\x12\xba\x1f\xdb\x49\x24\x35\x5a\xe6\x79\x01\x2d\x81\xd2\xc0\x8f\xc0\xf8\x63\x4c\x70\x8a\x48\x33\x23\x2f", 41 | }, 42 | TestVector { 43 | sk: b"\x11\xe0\xd4\x70\xdc\x31\xfa\xb0\xf5\x72\x2f\x87\xb7\x4a\x6c\x8d\x74\x14\x11\x5e\x58\xce\xb3\x8b\xfc\xdc\xed\x36\x7b\xea\xc3\xad\xbf\x1f\xe9\xba\x5a\x04\xf7\x2e\x97\x8b\x1e\xb5\x45\x97\xea\xbc", 44 | pk: b"\x19\x50\x16\x69\x89\x16\x4c\xbf\xd9\x79\x68\xc7\xe8\xad\xb6\xfb\xca\x18\x73\xeb\xef\x81\x1e\xa2\x59\xeb\x48\xb7\xd5\x84\x62\x7f\x0e\x6d\x6c\x64\xde\xfe\x23\xcb\xc9\x52\x36\x50\x5a\x25\x2a\xa1\x41\xef\x42\x4b\x5c\xb0\x76\xd4\xe3\x2a\xcc\xd9\x25\x0e\xa7\x5f\xcf\x4f\xfd\x81\x81\x40\x40\xc0\x50\xd5\x8c\x0a\x29\xb0\x6b\xe1\x1e\xdf\x67\xc9\x11\xb4\x03\xe4\x18\xb7\x27\x74\x17\xe5\x29\x06", 45 | msg: b"\x7c\xec\x74\x80\xa0\x37\xff\x40\xc2\x32\xc1\xd2\xd6\xe8\xcd\x4c\x08\x0b\xbe\xec\xda\xf3\x88\x6f\xcc\xc9\xf1\x29\xbb\x6d\x20\x2c\x31\x6e\xca\x76\xc8\xad\x4e\x76\x07\x9a\xfe\x62\x2f\x83\x3a\x16\xf4\x90\x7e\x81\x72\x60\xc1\xfa\x68\xb1\x0c\x7a\x15\x1a\x37\xeb\x8c\x03\x6b\x05\x7e\xd4\x65\x2c\x35\x3d\xb4\xb4\xa3\x4b\x37\xc9\xa2\xb3\x00\xfb\x5f\x5f\xcf\xb8\xaa\x8a\xda\xe1\x3d\xb3\x59\x16\x0f\x70\xa9\x24\x15\x46\x14\x0e\x55\x0a\xf0\x07\x34\x68\x68\x33\x77\xe6\x77\x1b\x65\x08\x32\x74\x08\xc2\x45\xd7\x89\x11\xc2\xcc", 46 | sig: b"\xc3\x8e\xf3\x0f\x55\x62\x4e\x89\x35\x68\x0c\x29\xf8\xc2\x48\x24\x87\x7c\xf4\x8f\xfc\x0e\xf0\x15\xe6\x2d\xe1\x06\x88\x93\x35\x30\x30\xd1\x19\x3b\xf9\xd3\x42\x37\xd7\xce\x6b\xa9\x2c\x98\xb0\xfe\x65\x1b\x8c\x3d\x5c\x9d\x5b\x93\x6d\x30\x08\x02\xa0\x6d\x82\xad\x54\xf7\xb1\xba\x43\x27\xb2\xf0\x31\xc0\xc5\xb0\xcb\x21\x5a\xd4\x35\x4e\xdc\x7f\x93\x2d\x93\x4e\x87\x7d\xfa\x1c\xf5\x1b\x13\xfe", 47 | }, 48 | TestVector { 49 | sk: b"\x5c\x6b\xbf\x9f\xbc\xbb\x7b\x97\xc9\x53\x5f\x57\xb4\x31\xed\x1c\xca\xe1\x94\x5b\x7e\x8a\x4f\x1b\x03\x20\x16\xb0\x78\x10\xbd\x24\xa9\xe2\x00\x55\xc0\xe9\x30\x66\x50\xdf\x59\xef\x7e\x2c\xd8\xc2", 50 | pk: b"\x2e\x01\xc5\xb5\x9e\x61\x9e\x00\xb7\x90\x60\xa1\xe8\xef\x69\x54\x72\xe2\x3b\xf9\xa5\x11\xfc\x3d\x5e\xd7\x7a\x33\x4a\x24\x25\x57\x09\x8e\x40\x97\x27\x13\x73\x2c\x52\x91\xc9\x7a\xdf\x9c\xf2\xcf\x56\x3e\x3f\xe4\xad\x80\x7e\x80\x3b\x9e\x96\x1b\x08\xda\x4d\xde\x4c\xea\x89\x25\x64\x9d\xa0\xd9\x32\x21\xce\x4c\xdc\xea\xbc\x6a\x1d\xb7\x61\x21\x80\xa8\xc6\xbe\xf3\x57\x9c\x65\x53\x9b\x97\xe9", 51 | msg: b"\x00\xce\x97\x86\x03\x22\x97\x10\x34\x5c\x9a\xd7\xc1\xc2\xdb\xa3\x59\x6b\x19\x65\x28\xee\xa2\x5b\xd8\x22\xd4\x3c\xa8\xf7\x6a\x02\x4e\x29\x21\x77\x03\xdd\x06\x52\xc8\xa6\x15\x28\x4f\xc3\xed\xcc\x1c\x5a\xd1\xc8\xd5\xa8\x52\x1c\x8e\x10\x4c\x01\x6a\x24\xe5\x0c\x2e\x25\x06\x6d\xcb\x56\x59\x6f\x91\x3b\x87\x27\x67\xe3\x62\x7a\xa3\xe5\x5e\xc8\x12\xe9\xfd\xac\x7c\x2f\x1b\xea\xde\x83\xae\xf0\x93\xe2\x4c\x9c\x95\x39\x82\xad\xf4\x31\xa7\x76\x88\x0a\xe4\x58\x3b\xe1\x58\xe1\x1c\xda\xb1\xcb\xca\x3a\xd3\xa6\x69\x00\x21\x3d", 52 | sig: b"\xab\xab\x65\x30\x8f\x0b\x79\xc4\xf3\xa9\xff\x28\xdd\x49\x0a\xcb\x0c\x32\x04\x34\x09\x4c\xef\x93\xe7\x5a\xdf\xe1\x7e\x58\x20\xdc\x1f\x77\x54\x4c\xfa\xaa\xcd\xc8\xcf\x9a\xc8\xb3\x8e\x17\x4b\xef\x11\xb7\x83\xd8\x79\xa6\xde\x05\x4b\x31\x6a\xf7\xd5\x6e\x52\x6c\x3d\xce\x96\xc8\x52\x89\x12\x2e\x3a\xd9\x27\xcf\xa7\x7b\xfc\x50\xb4\xa9\x6c\x97\xf8\x5b\x1b\x82\x21\xbe\x2d\xf0\x83\xff\x58\xfb", 53 | }, 54 | TestVector { 55 | sk: b"\xff\xc7\xde\xde\xff\x83\x43\x72\x1f\x72\x04\x6b\xc3\xc1\x26\x62\x6c\x17\x7b\x0e\x48\xe2\x47\xf4\x4f\xd6\x1f\x84\x69\xd4\xd5\xf0\xa7\x41\x47\xfa\xba\xa3\x34\x49\x5c\xc1\xf9\x86\xeb\xc5\xf0\xb1", 56 | pk: b"\x51\xc7\x8c\x97\x94\x52\xed\xd5\x3b\x56\x3f\x63\xeb\x3e\x85\x4a\x5b\x23\xe8\x7f\x1b\x21\x03\x94\x2b\x65\xf7\x7d\x02\x44\x71\xf7\x5c\x8c\xe1\xcc\x0d\xfe\xf8\x32\x92\xb3\x68\x11\x2a\xa5\x12\x6e\x31\x3e\x6a\xaf\x09\xca\xa3\xba\x30\xf1\x30\x72\xb2\x13\x48\x78\xf1\x4a\x4a\x01\xee\x86\x32\x6c\xcc\xbf\xf3\xd0\x79\xb4\xdf\x09\x7d\xc5\x79\x85\xe8\xc8\xc8\x34\xa1\x0c\xb9\xd7\x66\x16\x93\x66", 57 | msg: b"\x54\xa2\x55\xc1\x86\x92\xc6\x16\x2a\x46\xad\xd1\x76\xa0\xae\x83\x61\xdc\xb8\x94\x8f\x09\x2d\x8d\x7b\xac\x83\xe1\x60\x43\x17\x94\xd3\xb9\x81\x28\x49\xbf\x19\x94\xbc\xdc\xfb\xa5\x6e\x85\x40\xc8\xa9\xee\x5b\x93\x41\x45\x48\xf2\xa6\x53\x19\x1b\x6b\xb2\x8b\xda\x8d\xc7\x0d\x45\xcc\x1b\x92\xa4\x89\xf5\x8a\x2d\x54\xf8\x57\x66\xcb\x3c\x90\xde\x7d\xd8\x8e\x69\x0d\x8e\xbc\x9a\x79\x98\x7e\xee\x19\x89\xdf\x35\xaf\x5e\x35\x52\x2f\x83\xd8\x5c\x48\xdd\xa8\x98\x63\x17\x1c\x8b\x0b\xf4\x85\x3a\xe2\x8c\x2a\xc4\x5c\x76\x44\x16", 58 | sig: b"\xf4\xf4\x77\x85\x58\x19\xad\x8b\x17\x63\xf5\x36\x91\xb7\x6a\xfb\xc4\xa3\x1a\x63\x8b\x1e\x08\xc2\x93\xf9\xbc\xd5\x5d\xec\xf7\x97\xf9\x91\x3c\xa1\x28\xd4\xb4\x5b\x2e\x2e\xa3\xe8\x2c\x6c\xf5\x65\x7c\x26\xbe\x29\x56\x9e\xf9\x54\x80\xa6\xd0\xc1\xaf\x49\xdc\x10\xa5\x1a\x0a\x89\x31\x34\x5e\x48\xc0\xc3\x94\x98\xbf\xb9\x4d\x62\x96\x29\x80\xb5\x61\x43\xa7\xb4\x1a\x2f\xdd\xc8\x79\x4c\x1b\x7f", 59 | }, 60 | TestVector { 61 | sk: b"\xad\xca\x36\x4e\xf1\x44\xa2\x1d\xf6\x4b\x16\x36\x15\xe8\x34\x9c\xf7\x4e\xe9\xdb\xf7\x28\x10\x42\x15\xc5\x32\x07\x3a\x7f\x74\xe2\xf6\x73\x85\x77\x9f\x7f\x74\xab\x34\x4c\xc3\xc7\xda\x06\x1c\xf6", 62 | pk: b"\xef\x94\x8d\xaa\xe6\x82\x42\x33\x0a\x73\x58\xef\x73\xf2\x3b\x56\xc0\x7e\x37\x12\x62\x66\xdb\x3f\xa6\xee\xa2\x33\xa0\x4a\x9b\x3e\x49\x15\x23\x3d\xd6\x75\x44\x27\xcd\x4b\x71\xb7\x58\x54\x07\x7d\x00\x94\x53\xef\x18\x28\xea\xff\x9e\x17\xc8\x56\xd4\xfc\x18\x95\xab\x60\x05\x13\x12\xc3\xe1\xdb\x1e\x37\x66\x56\x64\x38\xb2\x99\x0c\xbf\x99\x45\xc2\x54\x56\x19\xe3\xe0\x14\x5b\xc6\xa7\x90\x04", 63 | msg: b"\x69\x2a\x78\xf9\x0d\x4f\x9d\x5a\xee\x5d\xa5\x36\x31\x4a\x78\xd6\x8c\x1f\xea\xbb\xfe\x5d\x1c\xce\xa7\xf6\x05\x9a\x66\xc4\xb3\x10\xf8\x05\x1c\x41\x1c\x40\x9c\xcf\x6e\x19\xa0\xcb\xd8\xb8\xe1\x00\xc4\x83\x17\xfe\x8c\x6d\x4f\x8a\x63\x8b\x95\x51\xce\x7e\xe1\x78\x02\x0f\x04\xf7\xda\x30\x01\xa0\xe6\x85\x52\x25\xfb\x3c\x9b\x37\x5e\x4e\xd9\x64\x58\x8a\x1a\x41\xa0\x95\xf3\xf4\x76\xc4\x2d\x52\xff\xd2\x3c\xe1\x70\x2c\x93\xb5\x6d\x44\x25\xd3\xbe\xfc\xf7\x5d\x09\x51\xb6\xfd\x5c\x05\xb0\x54\x55\xbd\xaf\x20\x5f\xe7\x0c\xa2", 64 | sig: b"\xdd\xa9\x94\xb9\xc4\x28\xb5\x7e\x9f\x8b\xba\xeb\xba\x0d\x68\x2e\x3a\xac\x6e\xd8\x28\xe3\xa1\xe9\x9a\x7f\xc4\xc8\x04\xbf\xf8\xdf\x15\x11\x37\xf5\x39\xc7\x38\x9d\x80\xe2\x3d\x9f\x3e\xe4\x97\xbf\xa0\xd6\xb1\x0c\xef\xfd\x0e\x1b\x29\xcf\x78\x44\x76\xf9\x17\x3b\xa6\xec\xd2\xcf\xc7\x92\x97\x25\xf2\xd6\xe2\x4e\x0d\xb5\xa4\x72\x16\x83\x64\x0e\xaa\x2b\xbe\x15\x1f\xb5\x75\x60\xf9\xce\x59\x4b", 65 | }, 66 | TestVector { 67 | sk: b"\x39\xbe\xa0\x08\xec\x8a\x21\x78\x66\xdc\xbd\xb1\xb9\x3d\xa3\x4d\x1d\x3e\x85\x1d\x01\x1d\xf9\xef\x44\xb7\x82\x8b\x34\x53\xa5\x4a\xa7\x0f\x1d\xf9\x93\x21\x70\x80\x4e\xac\xd2\x07\xe4\xf7\xe9\x1d", 68 | pk: b"\x57\x09\xec\x43\x05\xa9\xc3\x27\x1c\x30\x4f\xac\xe6\xc1\x48\x14\x24\x90\xb8\x27\xa7\x3a\x4c\x17\xaf\xfc\xfd\x01\xff\xfd\x7e\xaa\x65\xd2\xfd\xed\xfa\x24\x19\xfc\x64\xed\x91\x08\x23\x51\x3f\xaf\xb0\x83\xcd\xa1\xcf\x3b\xe6\x37\x1b\x6c\x06\xe7\x29\xea\x62\x99\x21\x34\x28\xdb\x57\x11\x93\x47\x24\x7e\xc1\xfc\xd4\x42\x04\x38\x6c\xc0\xbc\xa3\xf4\x52\xd9\xd8\x64\xb3\x9e\xfb\xfc\x89\xd6\xb2", 69 | msg: b"\x3b\x30\x9b\xb9\x12\xab\x2a\x51\x68\x14\x51\xed\x18\xad\x79\xe9\x5d\x96\x8a\xbc\x35\x42\x3a\x67\x03\x6a\x02\xaf\x92\xf5\x75\xa0\xc8\x9f\x1b\x66\x8a\xfe\x22\xc7\x03\x7a\xd1\x19\x9e\x75\x7a\x8f\x06\xb2\x81\xc3\x3e\x9a\x40\xba\xb6\x9c\x98\x74\xe0\xbb\x68\x0b\x90\x5d\x90\x9b\x9d\xc2\x4a\x9f\xe8\x9b\xb3\xd7\xf7\xd4\x70\x82\xb2\x50\x93\xc5\x97\x54\xf8\xc1\x9d\x1f\x81\xf3\x03\x34\xa8\xcd\xd5\x0a\x3c\xb7\x2f\x96\xd4\xb3\xc3\x05\xe6\x0a\x43\x9a\x7e\x93\xae\xb6\x40\xdd\x3c\x8d\xe3\x7d\x63\xc6\x0f\xb4\x69\xc2\xd3\xed", 70 | sig: b"\xd1\x36\x46\x89\x5a\xfb\x1b\xfd\x19\x53\x55\x1b\xb9\x22\x80\x9c\x95\xad\x65\xd6\xab\xe9\x4e\xb3\x71\x9c\x89\x9a\xa1\xf6\xdb\xa6\xb0\x12\x22\xc7\xf2\x83\x90\x0f\xe9\x86\x28\xb7\x59\x7b\x6e\xa6\x4a\x9a\x38\xaf\xda\x04\xc0\xa6\xb0\x05\x89\x43\xb6\x79\xbd\x02\x20\x5b\x14\xd0\xf3\xd4\x9b\x8f\x31\xaa\xc2\x89\x12\x97\x80\xcd\xb1\xc5\x55\xde\xf8\xc3\xf9\x10\x6b\x47\x87\x29\xe0\xc7\xef\xaa", 71 | }, 72 | TestVector { 73 | sk: b"\xe8\x49\xcf\x94\x8b\x24\x13\x62\xe3\xe2\x0c\x45\x8b\x52\xdf\x04\x4f\x2a\x72\xde\xb0\xf4\x1c\x1b\xb0\x67\x3e\x7c\x04\xcd\xd7\x08\x11\x21\x50\x59\x03\x2b\x5c\xa3\xcc\x69\xc3\x45\xdc\xce\x4c\xf7", 74 | pk: b"\x06\xc0\x37\xa0\xcb\xf4\x3f\xdf\x33\x5d\xff\x33\xde\x06\xd3\x43\x48\x40\x53\x53\xf9\xfd\xf2\xce\x13\x61\xef\xba\x30\xfb\x20\x4a\xea\x9d\xbd\x2e\x30\xda\x0a\x10\xfd\x2d\x87\x61\x88\x37\x1b\xe6\x36\x0d\x38\xf3\x94\x0e\x34\x67\x92\x04\xb9\x8f\xbf\x70\xb8\xa4\xd9\x7f\x25\x44\x3e\x46\xd0\x80\x7a\xb6\x34\xed\x58\x91\xad\x86\x4d\xd7\x70\x35\x57\xaa\x93\x3c\xd3\x80\xe2\x6e\xea\x66\x2a\x43", 75 | msg: b"\xf0\x72\xb7\x2b\x87\x83\x28\x94\x63\xda\x11\x86\x13\xc4\x38\x24\xd1\x14\x41\xdb\xa3\x64\xc2\x89\xde\x03\xff\x5f\xab\x3a\x6f\x60\xe8\x59\x57\xd8\xff\x21\x1f\x1c\xb6\x2f\xa9\x02\x16\xfb\x72\x71\x06\xf6\x92\xe5\xae\x08\x44\xb1\x1b\x71\x0e\x5a\x12\xc6\x9d\xf3\xed\x89\x5b\x94\xe8\x76\x9e\xcd\x15\xff\x43\x37\x62\xd6\xe8\xe9\x4d\x8e\x6a\x72\x64\x5b\x21\x3b\x02\x31\x34\x4e\x2c\x96\x80\x56\x76\x6c\x5d\xd6\xb5\xa5\xdf\x41\x97\x18\x58\xb8\x5e\x99\xaf\xbf\x85\x94\x00\xf8\x39\xb4\x2c\xd1\x29\x06\x8e\xfa\xbe\xea\x4a\x26", 76 | sig: b"\x58\x86\x07\x8d\x34\x95\x76\x7e\x33\x0c\x75\x07\xb7\xca\x0f\xa0\x7a\x50\xe5\x99\x12\xa4\x16\xd8\x9f\x0a\xb1\xaa\x4e\x88\x15\x3d\x6e\xaf\x00\x88\x2d\x1b\x4a\xa6\x41\x53\x15\x33\x52\xd8\x53\xb5\x2c\xc1\x00\x23\xbf\x1b\xf8\xcc\xfd\x14\xb0\x6b\x82\xcc\x21\x14\x44\x9a\x35\x23\x89\xc8\xff\x9f\x6f\x78\xcd\xc4\xe3\x2b\xde\x69\xf3\x86\x9d\xa0\xe1\x7f\x69\x1b\x32\x96\x82\xae\x7a\x36\xe1\xaa", 77 | }, 78 | TestVector { 79 | sk: b"\xd8\x96\x07\x47\x5d\x50\x9e\xf2\x3d\xc9\xf4\x76\xea\xe4\x28\x0c\x98\x6d\xe7\x41\xb6\x35\x60\x67\x0f\xa2\xbd\x60\x5f\x50\x49\xf1\x97\x27\x92\xc0\x41\x3a\x5b\x3b\x4b\x34\xe7\xa3\x8b\x70\xb7\xca", 80 | pk: b"\x49\xa1\xc6\x31\xf3\x1c\xf5\xc4\x5b\x26\x76\xb1\xf1\x30\xcb\xf9\xbe\x68\x3d\x0a\x50\xdf\xfa\xe0\xd1\x47\xc1\xe9\x91\x3a\xb1\x09\x0c\x65\x29\xa8\x4f\x47\xdd\xc7\xcf\x02\x59\x21\xb7\x71\x35\x5a\x1e\x20\x7e\xec\xe6\x2f\x2b\xcc\x6b\xda\xbc\x11\x13\x15\x81\x45\x17\x0b\xe9\x74\x69\xa2\x90\x4e\xaa\xa9\x3a\xad\x85\xb8\x6a\x19\x71\x92\x07\xf3\xe4\x23\x05\x1f\x5b\x9c\xbb\xe2\x75\x4e\xef\xcb", 81 | msg: b"\xcf\x49\x45\x35\x0b\xe8\x13\x3b\x57\x5c\x4a\xd6\xc9\x58\x5e\x0b\x83\xff\x1e\xd1\x79\x89\xb6\xcd\x6c\x71\xb4\x1b\x52\x64\xe8\x28\xb4\xe1\x15\x99\x5b\x1a\xe7\x75\x28\xe7\xe9\x00\x2a\xc1\xb5\x66\x90\x64\x44\x26\x45\x92\x9f\x9d\x7d\xd7\x09\x27\xcb\x93\xf9\x5e\xde\xb7\x3e\x86\x24\xf4\xbc\x89\x7e\xc4\xc2\xc7\x58\x1c\xb6\x26\x91\x6f\x29\xb2\xd6\xe6\xc2\xfb\xa8\xc5\x9a\x71\xe3\x07\x54\xb4\x59\xd8\x1b\x91\x2a\x12\x79\x81\x82\xbc\xff\x40\x19\xc7\xbd\xfe\x92\x9c\xc7\x69\xbc\xc2\x41\x4b\xef\xe7\xd2\x90\x6a\xdd\x42\x71", 82 | sig: b"\x66\xf9\x2b\x39\xaa\x3f\x4a\xeb\x9e\x2d\xc0\x3a\xc3\x85\x54\x06\xfa\x3e\xbb\xab\x0a\x6c\x88\xa7\x8d\x7a\x03\x48\x2f\x0c\x98\x68\xd7\xb7\x8b\xc0\x81\xed\xe0\x94\x7c\x7f\x37\xbf\x19\x30\x74\xba\xe5\xc6\x4e\xd9\x8d\x7f\x37\x01\x19\x3f\x25\xdd\x23\x7d\x59\xc9\x1c\x0d\xa6\xe2\x62\x15\xe0\x88\x9d\x82\xe6\xd3\xe4\x16\x69\x3f\x8d\x58\x84\x3c\xf3\x0a\xb1\x0a\xb8\xd0\xed\xd9\x17\x0b\x53\xad", 83 | }, 84 | TestVector { 85 | sk: b"\x08\x3e\x71\x52\x73\x4a\xdf\x34\x25\x20\xae\x37\x70\x87\xa2\x23\x68\x8d\xe2\x89\x9b\x10\xcf\xcb\x34\xa0\xb3\x6b\xca\x50\x0a\x4d\xfa\x53\x0e\x23\x43\xe6\xa3\x9d\xa7\xae\x1e\xb0\x86\x2b\x4a\x0d", 86 | pk: b"\x70\xa0\xf1\x6b\x6c\x61\x17\x26\x59\xb0\x27\xed\x19\xb1\x8f\xd8\xf5\x7b\xd2\x8d\xc0\x50\x1f\x20\x7b\xd6\xb0\xbb\x06\x5b\x56\x71\xcf\x3d\xd1\xed\x13\xd3\x88\xdc\xf6\xcc\xc7\x66\x59\x7a\xa6\x04\x4f\x84\x5b\xf0\x1c\x3c\x3f\x61\x26\xa7\x36\x8c\x34\x54\xf5\x14\x25\x80\x1e\xe0\xb7\x2e\x63\xfb\x67\x99\xb4\x42\x0b\xfd\xeb\xe3\xe3\x7c\x72\x46\xdb\x62\x7c\xc8\x2c\x09\x65\x49\x79\xc7\x00\xbb", 87 | msg: b"\xd9\xb5\xcf\x0b\x50\x41\x65\x73\xff\x3c\x63\x13\x32\x75\xa1\x83\x94\xdd\x43\x26\xbe\x20\x41\xe8\xd9\x7e\x6e\x4e\x38\x55\xa4\xa1\x77\xe9\xd2\x6d\xfd\x22\x3f\xe8\xaa\x74\x56\x4e\xdb\x49\xbd\x72\xde\x19\x91\x6f\xb6\xf0\x01\xf4\x45\x30\xd5\xc1\x8e\x2c\x33\x2b\xce\x1b\x74\x15\xdf\x59\x27\xec\xe5\xf3\x82\x4f\x34\xd1\x74\xb9\x63\x13\x6b\x53\xae\xf1\xfb\x78\xfb\x0c\x06\xa2\x01\xa4\x0b\x2d\xb3\x8e\x4d\x82\x16\xfc\x1e\x39\x2a\x79\x8c\x8a\xb4\xb3\xa3\x14\x49\x6b\x7f\x10\x87\x80\x4e\xbf\xa8\x9b\xf9\x6e\x9c\xdb\x80\xc0", 88 | sig: b"\xee\x29\x23\xf9\xb9\x99\x9e\xa0\x5b\x5e\x57\xf5\x05\xbe\xd5\xc6\xba\x04\x20\xde\xf4\x2c\x6f\xa9\x0e\xef\x7a\x6e\xf7\x70\x78\x65\x25\x54\x6d\xe2\x7c\xde\xb2\xf8\x58\x6f\x8f\x29\xfb\x4e\xe6\x7c\x50\xef\x92\x3f\xb2\x17\xc4\xcf\x65\xa4\x8b\x94\x41\x2f\xda\x43\x0f\xac\x68\x5f\x0d\xa7\xbd\x57\x45\x57\xc6\xc5\x0f\x5b\x22\xe0\xc8\x35\x4d\x99\xf2\xc2\xf2\xc2\x69\x1f\x25\x2f\x93\xc7\xd8\x4a", 89 | }, 90 | TestVector { 91 | sk: b"\x63\x57\x8d\x41\x62\x15\xaf\xf2\xcc\x78\xf9\xb9\x26\xd4\xc7\x74\x0a\x77\xc1\x42\x94\x4e\x10\x4a\xa7\x42\x2b\x19\xa6\x16\x89\x82\x62\xd4\x6a\x8a\x94\x2d\x5e\x8d\x5d\xb1\x35\xee\x8b\x09\xa3\x68", 92 | pk: b"\xca\xdb\xac\xef\x44\x06\x09\x93\x16\xdb\x2c\xe3\x20\x6a\xdc\x63\x6c\x2b\xb0\xa8\x35\x84\x7e\xd7\x94\x1e\xfb\x02\x86\x24\x72\xf3\x15\x03\x38\xf1\x3f\x48\x60\xd4\x7f\x39\xb7\xe0\x98\xf0\xa3\x90\x75\x2a\xd0\xf2\x2c\x9c\x26\x43\x36\xcd\xe1\x1b\xbc\x95\xd1\x81\x6e\xd4\xd1\xb1\x50\x0d\xb6\xb8\xdc\xe2\x59\xa4\x28\x32\xe6\x13\xc3\x11\x78\xc2\xc7\x99\x52\x06\xa6\x2e\x20\x1b\xa1\x08\xf5\x70", 93 | msg: b"\x9e\x40\x42\xd8\x43\x8a\x40\x54\x75\xb7\xda\xb1\xcd\x78\x3e\xb6\xce\x1d\x1b\xff\xa4\x6a\xc9\xdf\xda\x62\x2b\x23\xac\x31\x05\x7b\x92\x2e\xce\xd8\xe2\xed\x7b\x32\x41\xef\xea\xfd\x7c\x9a\xb3\x72\xbf\x16\x23\x0f\x71\x34\x64\x7f\x29\x56\xfb\x79\x39\x89\xd3\xc8\x85\xa5\xae\x06\x4e\x85\xed\x97\x1b\x64\xf5\xf5\x61\xe7\xdd\xb7\x9d\x49\xaa\x6e\xbe\x72\x7c\x67\x1c\x67\x87\x9b\x79\x45\x54\xc0\x4d\xe0\xe0\x5d\x68\x26\x48\x55\x74\x5e\xf3\xc9\x56\x7b\xd6\x46\xd5\xc5\xf8\x72\x8b\x79\x7c\x18\x1b\x6b\x6a\x87\x6e\x16\x76\x63", 94 | sig: b"\xdb\x05\x4a\xdd\xb6\x16\x1e\xe4\x9c\x6c\xe2\xe4\xd6\x46\xd7\x67\x07\x54\x74\x7b\x67\x37\xca\x85\x16\xe9\xd1\xe8\x78\x59\x93\x7c\x3e\xf9\xb1\xd2\x66\x3e\x10\xd7\xe4\xbd\x00\xec\x85\xb7\xa9\x7a\xfc\xc5\x04\xe0\xf0\x0e\xf2\x95\x87\xe4\xbc\x22\xfa\xad\xa4\xdb\x30\xe2\xcb\x1a\xc5\x52\x68\x0a\x65\x78\x5a\xe8\x7b\xeb\x66\x6c\x79\x25\x13\xf2\xbe\x7a\x31\x80\xfc\x54\x42\x96\x84\x1a\x0e\x27", 95 | }, 96 | TestVector { 97 | sk: b"\xed\x4d\xf1\x99\x71\x65\x8b\x74\x86\x88\x00\xb3\xb8\x1b\xc8\x77\x80\x77\x43\xb2\x5c\x65\x74\x0f\x1d\x63\x77\x54\x2a\xfe\x2c\x64\x27\x61\x2c\x84\x0a\xda\x31\xa8\xeb\x79\x47\x18\xf3\x7c\x72\x83", 98 | pk: b"\x33\x09\x3a\x05\x68\x75\x7e\x8b\x58\xdf\x5b\x72\xea\x5f\xe5\xbf\x26\xe6\xf7\xae\xb5\x41\xb4\xc6\xa8\xc1\x89\xc9\x37\x21\x74\x9b\xca\xce\xcc\xf2\x98\x2a\x2f\x07\x02\x58\x6a\x9f\x81\x2f\xc6\x6f\xeb\xe3\x20\xd0\x9e\x1f\x06\x62\x18\x9d\x50\xb8\x5a\x20\x40\x3b\x82\x1a\xc0\xd0\x00\xaf\xdb\xf6\x6a\x0a\x33\xf3\x04\x72\x6c\x69\xe3\x54\xd8\x1c\x50\xb9\x4b\xa3\xa5\x25\x0e\xfc\x31\x31\x9c\xd1", 99 | msg: b"\x0b\x14\xa7\x48\x4a\x40\xb6\x8a\x3c\xe1\x27\x3b\x8a\x48\xb8\xfd\xb6\x5b\xa9\x00\xd9\x85\x41\xc4\xbb\xd0\x7b\x97\xe3\x1b\xcc\x4c\x85\x54\x5a\x03\xe9\xde\xab\x3c\x56\x3f\x47\xa0\x36\xff\x60\xd0\x36\x16\x84\xba\x24\x1b\x5a\xa6\x8b\xb4\x6f\x44\x0d\xa2\x21\x81\xee\x32\x8a\x01\x1d\xe9\x8e\xff\x34\xba\x23\x5e\xc1\x06\x12\xb0\x7b\xdf\xa6\xb3\xdc\x4c\xcc\x5e\x82\xd3\xa8\xd0\x57\xe1\x86\x2f\xef\x3d\xef\x5a\x18\x04\x69\x6f\x84\x69\x9f\xda\x2e\xc4\x17\x5a\x54\xa4\xd0\x8b\xcb\x4f\x04\x06\xfd\xac\x4e\xdd\xad\xf5\xe2\x9b", 100 | sig: b"\x00\x9c\x74\x06\x3e\x20\x6a\x42\x59\xb5\x3d\xec\xff\x54\x45\x68\x3a\x03\xf4\x4f\xa6\x72\x52\xb7\x6b\xd3\x58\x10\x81\xc7\x14\xf8\x82\xf8\x82\xdf\x91\x5e\x97\xdb\xea\xb0\x61\xfa\x8b\x3c\xc4\xe7\xd4\x0e\x09\xd3\x46\x8b\x46\x69\x99\x48\x00\x7e\x8f\x59\x84\x57\x66\xdb\xf6\x94\xb9\xc6\x20\x66\x89\x0d\xd0\x55\xc0\xcb\x9a\x0c\xaf\x0a\xa6\x11\xfb\x9f\x46\x6a\xd0\xbb\xb0\x0d\xbe\x29\xd7\xeb", 101 | }, 102 | TestVector { 103 | sk: b"\xe9\xc7\xe9\xa7\x96\x18\xd6\xff\x32\x74\xda\x1a\xbd\x0f\xf3\xed\x0e\xc1\xae\x3b\x54\xc3\xa4\xfd\x8d\x68\xd9\x8f\xb0\x43\x26\xb7\x63\x3f\xc6\x37\xe0\xb1\x95\x22\x8d\x0e\xdb\xa6\xbb\x14\x68\xfb", 104 | pk: b"\xa3\x9a\xc3\x53\xca\x78\x79\x82\xc5\x77\xaf\xf1\xe8\x60\x1c\xe1\x92\xaa\x90\xfd\x0d\xe4\xc0\xed\x62\x7f\x66\xa8\xb6\xf0\x2a\xe5\x13\x15\x54\x3f\x72\xff\xc1\xc4\x8a\x72\x69\xb2\x5e\x7c\x28\x9a\x90\x64\xa5\x07\xb6\x6b\x34\x0b\x6e\x0e\x0d\x5f\xfa\xa6\x7d\xd2\x0e\x6d\xaf\xc0\xea\x6a\x6f\xae\xe1\x63\x51\x77\xaf\x25\x6f\x91\x08\xa2\x2e\x9e\xdf\x73\x6a\xb4\xae\x8e\x96\xdc\x20\x7b\x1f\xa9", 105 | msg: b"\x0e\x64\x6c\x6c\x3c\xc0\xf9\xfd\xed\xef\x93\x4b\x71\x95\xfe\x38\x37\x83\x6a\x9f\x6f\x26\x39\x68\xaf\x95\xef\x84\xcd\x03\x57\x50\xf3\xcd\xb6\x49\xde\x74\x5c\x87\x4a\x6e\xf6\x6b\x3d\xd8\x3b\x66\x06\x8b\x43\x35\xbc\x0a\x97\x18\x41\x82\xe3\x96\x5c\x72\x2b\x3b\x1a\xee\x48\x8c\x36\x20\xad\xb8\x35\xa8\x14\x0e\x19\x9f\x4f\xc8\x3a\x88\xb0\x28\x81\x81\x6b\x36\x6a\x09\x31\x6e\x25\x68\x52\x17\xf9\x22\x11\x57\xfc\x05\xb2\xd8\xd2\xbc\x85\x53\x72\x18\x3d\xa7\xaf\x3f\x0a\x14\x14\x8a\x09\xde\xf3\x7a\x33\x2f\x8e\xb4\x0d\xc9", 106 | sig: b"\xee\x82\xc0\xf9\x05\x01\x13\x6e\xb0\xdc\x0e\x45\x9a\xd1\x7b\xf3\xbe\x1b\x1c\x8b\x8d\x05\xc6\x00\x68\xa9\x30\x6a\x34\x63\x26\xff\x73\x44\x77\x6a\x95\xf1\xf7\xe2\xe2\xcf\x94\x77\x13\x0e\x73\x5c\xaf\x10\xb9\x0f\x20\x3a\xf2\x3b\x75\x00\xe0\x70\x53\x6e\x64\x62\x9b\xa1\x92\x45\xd6\xef\x39\xaa\xb5\x7f\xcd\xb1\xb7\x3c\x4c\x6b\xf7\x07\x0c\x62\x63\x54\x46\x33\xd3\xd3\x58\xc1\x2a\x17\x81\x38", 107 | }, 108 | ]; 109 | -------------------------------------------------------------------------------- /tests/signature/ed25519.rs: -------------------------------------------------------------------------------- 1 | //! Ed25519 tests 2 | 3 | use super::TestVector; 4 | use hex_literal::hex; 5 | use ring_compat::signature::{ 6 | ed25519::{Signature, SigningKey, VerifyingKey}, 7 | Signer, Verifier, 8 | }; 9 | 10 | #[test] 11 | fn sign_rfc8032_test_vectors() { 12 | for vector in TEST_VECTORS { 13 | let signing_key = SigningKey::from_slice(vector.sk).unwrap(); 14 | assert_eq!(signing_key.sign(vector.msg).to_bytes(), vector.sig); 15 | } 16 | } 17 | 18 | #[test] 19 | fn verify_rfc8032_test_vectors() { 20 | for vector in TEST_VECTORS { 21 | let verifying_key = VerifyingKey::from_slice(vector.pk).unwrap(); 22 | let sig = Signature::try_from(vector.sig).unwrap(); 23 | assert!(verifying_key.verify(vector.msg, &sig).is_ok()); 24 | } 25 | } 26 | 27 | #[test] 28 | fn rejects_tweaked_rfc8032_test_vectors() { 29 | for vector in TEST_VECTORS { 30 | let verifying_key = VerifyingKey::from_slice(vector.pk).unwrap(); 31 | 32 | let mut tweaked_sig = [0u8; Signature::BYTE_SIZE]; 33 | tweaked_sig.copy_from_slice(vector.sig); 34 | tweaked_sig[0] ^= 0x42; 35 | 36 | let sig = Signature::try_from(&tweaked_sig[..]).unwrap(); 37 | assert!(verifying_key.verify(vector.msg, &sig).is_err()); 38 | } 39 | } 40 | 41 | /// Ed25519 test vectors (from RFC 8032) 42 | const TEST_VECTORS: &[TestVector] = &[ 43 | TestVector { 44 | sk: &hex!("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60"), 45 | pk: &hex!("d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a"), 46 | msg: b"", 47 | sig: &hex!("e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b") 48 | }, 49 | TestVector { 50 | sk: &hex!("4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb"), 51 | pk: &hex!("3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c"), 52 | msg: &hex!("72"), 53 | sig: &hex!("92a009a9f0d4cab8720e820b5f642540a2b27b5416503f8fb3762223ebdb69da085ac1e43e15996e458f3613d0f11d8c387b2eaeb4302aeeb00d291612bb0c00"), 54 | }, 55 | TestVector { 56 | sk: &hex!("c5aa8df43f9f837bedb7442f31dcb7b166d38535076f094b85ce3a2e0b4458f7"), 57 | pk: &hex!("fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025"), 58 | msg: &hex!("AF82"), 59 | sig: &hex!("6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac18ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027beceea1ec40a"), 60 | }, 61 | TestVector { 62 | sk: &hex!("f5e5767cf153319517630f226876b86c8160cc583bc013744c6bf255f5cc0ee5"), 63 | pk: &hex!("278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e"), 64 | msg: &hex!("08b8b2b733424243760fe426a4b54908632110a66c2f6591eabd3345e3e4eb98fa6e264bf09efe12ee50f8f54e9f77b1e355f6c50544e23fb1433ddf73be84d879de7c0046dc4996d9e773f4bc9efe5738829adb26c81b37c93a1b270b20329d658675fc6ea534e0810a4432826bf58c941efb65d57a338bbd2e26640f89ffbc1a858efcb8550ee3a5e1998bd177e93a7363c344fe6b199ee5d02e82d522c4feba15452f80288a821a579116ec6dad2b3b310da903401aa62100ab5d1a36553e06203b33890cc9b832f79ef80560ccb9a39ce767967ed628c6ad573cb116dbefefd75499da96bd68a8a97b928a8bbc103b6621fcde2beca1231d206be6cd9ec7aff6f6c94fcd7204ed3455c68c83f4a41da4af2b74ef5c53f1d8ac70bdcb7ed185ce81bd84359d44254d95629e9855a94a7c1958d1f8ada5d0532ed8a5aa3fb2d17ba70eb6248e594e1a2297acbbb39d502f1a8c6eb6f1ce22b3de1a1f40cc24554119a831a9aad6079cad88425de6bde1a9187ebb6092cf67bf2b13fd65f27088d78b7e883c8759d2c4f5c65adb7553878ad575f9fad878e80a0c9ba63bcbcc2732e69485bbc9c90bfbd62481d9089beccf80cfe2df16a2cf65bd92dd597b0707e0917af48bbb75fed413d238f5555a7a569d80c3414a8d0859dc65a46128bab27af87a71314f318c782b23ebfe808b82b0ce26401d2e22f04d83d1255dc51addd3b75a2b1ae0784504df543af8969be3ea7082ff7fc9888c144da2af58429ec96031dbcad3dad9af0dcbaaaf268cb8fcffead94f3c7ca495e056a9b47acdb751fb73e666c6c655ade8297297d07ad1ba5e43f1bca32301651339e22904cc8c42f58c30c04aafdb038dda0847dd988dcda6f3bfd15c4b4c4525004aa06eeff8ca61783aacec57fb3d1f92b0fe2fd1a85f6724517b65e614ad6808d6f6ee34dff7310fdc82aebfd904b01e1dc54b2927094b2db68d6f903b68401adebf5a7e08d78ff4ef5d63653a65040cf9bfd4aca7984a74d37145986780fc0b16ac451649de6188a7dbdf191f64b5fc5e2ab47b57f7f7276cd419c17a3ca8e1b939ae49e488acba6b965610b5480109c8b17b80e1b7b750dfc7598d5d5011fd2dcc5600a32ef5b52a1ecc820e308aa342721aac0943bf6686b64b2579376504ccc493d97e6aed3fb0f9cd71a43dd497f01f17c0e2cb3797aa2a2f256656168e6c496afc5fb93246f6b1116398a346f1a641f3b041e989f7914f90cc2c7fff357876e506b50d334ba77c225bc307ba537152f3f1610e4eafe595f6d9d90d11faa933a15ef1369546868a7f3a45a96768d40fd9d03412c091c6315cf4fde7cb68606937380db2eaaa707b4c4185c32eddcdd306705e4dc1ffc872eeee475a64dfac86aba41c0618983f8741c5ef68d3a101e8a3b8cac60c905c15fc910840b94c00a0b9d0"), 65 | sig: &hex!("0aab4c900501b3e24d7cdf4663326a3a87df5e4843b2cbdb67cbf6e460fec350aa5371b1508f9f4528ecea23c436d94b5e8fcd4f681e30a6ac00a9704a188a03"), 66 | }, 67 | TestVector { 68 | sk: &hex!("833fe62409237b9d62ec77587520911e9a759cec1d19755b7da901b96dca3d42"), 69 | pk: &hex!("ec172b93ad5e563bf4932c70e1245034c35467ef2efd4d64ebf819683467e2bf"), 70 | msg: &hex!("ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f"), 71 | sig: &hex!("dc2a4459e7369633a52b1bf277839a00201009a3efbf3ecb69bea2186c26b58909351fc9ac90b3ecfdfbc7c66431e0303dca179c138ac17ad9bef1177331a704"), 72 | }, 73 | ]; 74 | -------------------------------------------------------------------------------- /tests/signature/mod.rs: -------------------------------------------------------------------------------- 1 | //! Digital signature tests 2 | 3 | mod ecdsa; 4 | mod ed25519; 5 | 6 | /// Signature test vector 7 | #[derive(Copy, Clone, Debug)] 8 | struct TestVector { 9 | /// Secret key (ECDSA: secret scalar, Ed25519: unexpanded "seed") 10 | sk: &'static [u8], 11 | 12 | /// Public key (ECDSA: SEC1-encoded, Ed25519: compressed Edwards-y) 13 | pk: &'static [u8], 14 | 15 | /// Message to be signed 16 | msg: &'static [u8], 17 | 18 | /// Expected signature 19 | sig: &'static [u8], 20 | } 21 | --------------------------------------------------------------------------------