chore: checkpoint before Python removal

This commit is contained in:
2026-03-26 22:33:59 +00:00
parent 683cec9307
commit e568ddf82a
29972 changed files with 11269302 additions and 2 deletions

View File

@@ -0,0 +1 @@
{"files":{".cargo_vcs_info.json":"7ba9b51f1f94aa2f9bdb8b5202a69f8ae495be4fa46b63ac2ac72f9496494ee7","CHANGELOG.md":"102f114ebb898692dee1abe1e9debdf5ced6e7def8774d739043bb5afd8709b9","COPYRIGHT":"90eb64f0279b0d9432accfa6023ff803bc4965212383697eee27a0f426d5f8d5","Cargo.lock":"87cfa1755f12538b04d4d98ebd45997b2fd53a1d1fdf315f787d182f76c0b2cd","Cargo.toml":"f413a8d1156cb6c7271427e5f406ed65e3056e2422224ad5d13f7d40a0c35803","Cargo.toml.orig":"1acccaeba470188c3a0286b17efe27e001f41ef8c9cb0041aa9e9113f894fe5c","LICENSE-APACHE":"35242e7a83f69875e6edeff02291e688c97caafe2f8902e4e19b49d3e78b4cab","LICENSE-MIT":"209fbbe0ad52d9235e37badf9cadfe4dbdc87203179c0899e738b39ade42177b","README.md":"13c20fa16d5cd5abf47d10cbec09ef3e488f4b2cce4c63711b8e4c021d2d97c4","src/chacha.rs":"8b7fb696f491afe9ca5830e5ed66f418f0cb6bee40dafb4e4d2404c50523a33a","src/guts.rs":"33d284279f5bacc5951a46de693a77758b662c341ef05bd8a4bcda84f34863a6","src/lib.rs":"a3eddc972be141f04118957200d23ec8b783ca53b382c0d886a9436229c8bec4"},"package":"d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"}

View File

@@ -0,0 +1,6 @@
{
"git": {
"sha1": "96f8df65ee6b4368d91a006f9c5b4a8050abae49"
},
"path_in_vcs": "rand_chacha"
}

46
vendor/rand_chacha/CHANGELOG.md vendored Normal file
View File

@@ -0,0 +1,46 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [0.9.0] - 2025-01-27
### Dependencies and features
- Update to `rand_core` v0.9.0 (#1558)
- Feature `std` now implies feature `rand_core/std` (#1153)
- Rename feature `serde1` to `serde` (#1477)
- Rename feature `getrandom` to `os_rng` (#1537)
### Other changes
- Remove usage of `unsafe` in `fn generate` (#1181) then optimise for AVX2 (~4-7%) (#1192)
- Revise crate docs (#1454)
## [0.3.1] - 2021-06-09
- add getters corresponding to existing setters: `get_seed`, `get_stream` (#1124)
- add serde support, gated by the `serde1` feature (#1124)
- ensure expected layout via `repr(transparent)` (#1120)
## [0.3.0] - 2020-12-08
- Bump `rand_core` version to 0.6.0
- Bump MSRV to 1.36 (#1011)
- Remove usage of deprecated feature "simd" of `ppv-lite86` (#979), then revert
this change (#1023) since SIMD is only enabled by default from `ppv-lite86 v0.2.10`
- impl PartialEq+Eq for ChaChaXRng and ChaChaXCore (#979)
- Fix panic on block counter wrap that was occurring in debug builds (#980)
## [0.2.2] - 2020-03-09
- Integrate `c2-chacha`, reducing dependency count (#931)
- Add CryptoRng to ChaChaXCore (#944)
## [0.2.1] - 2019-07-22
- Force enable the `simd` feature of `c2-chacha` (#845)
## [0.2.0] - 2019-06-06
- Rewrite based on the much faster `c2-chacha` crate (#789)
## [0.1.1] - 2019-01-04
- Disable `i128` and `u128` if the `target_os` is `emscripten` (#671: work-around Emscripten limitation)
- Update readme and doc links
## [0.1.0] - 2018-10-17
- Pulled out of the Rand crate

12
vendor/rand_chacha/COPYRIGHT vendored Normal file
View File

@@ -0,0 +1,12 @@
Copyrights in the Rand project are retained by their contributors. No
copyright assignment is required to contribute to the Rand project.
For full authorship information, see the version control history.
Except as otherwise noted (below and/or in individual files), Rand is
licensed under the Apache License, Version 2.0 <LICENSE-APACHE> or
<http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
<LICENSE-MIT> or <http://opensource.org/licenses/MIT>, at your option.
The Rand project includes code from the Rust project
published under these same licenses.

232
vendor/rand_chacha/Cargo.lock generated vendored Normal file
View File

@@ -0,0 +1,232 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "bitflags"
version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "getrandom"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71393ecc86efbf00e4ca13953979ba8b94cfe549a4b74cc26d8b62f4d8feac2b"
dependencies = [
"cfg-if",
"libc",
"wasi",
"windows-targets",
]
[[package]]
name = "itoa"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
[[package]]
name = "libc"
version = "0.2.169"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
[[package]]
name = "ppv-lite86"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "proc-macro2"
version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rand_chacha"
version = "0.9.0"
dependencies = [
"ppv-lite86",
"rand_core",
"serde",
"serde_json",
]
[[package]]
name = "rand_core"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b08f3c9802962f7e1b25113931d94f43ed9725bebc59db9d0c3e9a23b67e15ff"
dependencies = [
"getrandom",
"zerocopy",
]
[[package]]
name = "ryu"
version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1"
[[package]]
name = "serde"
version = "1.0.197"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.197"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.114"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0"
dependencies = [
"itoa",
"ryu",
"serde",
]
[[package]]
name = "syn"
version = "2.0.53"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7383cd0e49fff4b6b90ca5670bfd3e9d6a733b3f90c686605aa7eec8c4996032"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "wasi"
version = "0.13.3+wasi-0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2"
dependencies = [
"wit-bindgen-rt",
]
[[package]]
name = "windows-targets"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675"
[[package]]
name = "windows_i686_gnu"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3"
[[package]]
name = "windows_i686_msvc"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8"
[[package]]
name = "wit-bindgen-rt"
version = "0.33.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c"
dependencies = [
"bitflags",
]
[[package]]
name = "zerocopy"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a65238aacd5fb83fb03fcaf94823e71643e937000ec03c46e7da94234b10c870"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ca22c4ad176b37bd81a565f66635bde3d654fe6832730c3e52e1018ae1655ee"
dependencies = [
"proc-macro2",
"quote",
"syn",
]

81
vendor/rand_chacha/Cargo.toml vendored Normal file
View File

@@ -0,0 +1,81 @@
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
#
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g., crates.io) dependencies.
#
# If you are reading this file be aware that the original Cargo.toml
# will likely look very different (and much more reasonable).
# See Cargo.toml.orig for the original contents.
[package]
edition = "2021"
rust-version = "1.63"
name = "rand_chacha"
version = "0.9.0"
authors = [
"The Rand Project Developers",
"The Rust Project Developers",
"The CryptoCorrosion Contributors",
]
build = false
autolib = false
autobins = false
autoexamples = false
autotests = false
autobenches = false
description = """
ChaCha random number generator
"""
homepage = "https://rust-random.github.io/book"
documentation = "https://docs.rs/rand_chacha"
readme = "README.md"
keywords = [
"random",
"rng",
"chacha",
]
categories = [
"algorithms",
"no-std",
]
license = "MIT OR Apache-2.0"
repository = "https://github.com/rust-random/rand"
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--generate-link-to-definition"]
[features]
default = ["std"]
os_rng = ["rand_core/os_rng"]
serde = ["dep:serde"]
std = [
"ppv-lite86/std",
"rand_core/std",
]
[lib]
name = "rand_chacha"
path = "src/lib.rs"
[dependencies.ppv-lite86]
version = "0.2.14"
features = ["simd"]
default-features = false
[dependencies.rand_core]
version = "0.9.0"
[dependencies.serde]
version = "1.0"
features = ["derive"]
optional = true
[dev-dependencies.rand_core]
version = "0.9.0"
features = ["os_rng"]
[dev-dependencies.serde_json]
version = "1.0"

176
vendor/rand_chacha/LICENSE-APACHE vendored Normal file
View File

@@ -0,0 +1,176 @@
Apache License
Version 2.0, January 2004
https://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS

26
vendor/rand_chacha/LICENSE-MIT vendored Normal file
View File

@@ -0,0 +1,26 @@
Copyright 2018 Developers of the Rand project
Copyright (c) 2014 The Rust Project Developers
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

48
vendor/rand_chacha/README.md vendored Normal file
View File

@@ -0,0 +1,48 @@
# rand_chacha
[![Test Status](https://github.com/rust-random/rand/actions/workflows/test.yml/badge.svg?event=push)](https://github.com/rust-random/rand/actions)
[![Latest version](https://img.shields.io/crates/v/rand_chacha.svg)](https://crates.io/crates/rand_chacha)
[![Book](https://img.shields.io/badge/book-master-yellow.svg)](https://rust-random.github.io/book/)
[![API](https://img.shields.io/badge/api-master-yellow.svg)](https://rust-random.github.io/rand/rand_chacha)
[![API](https://docs.rs/rand_chacha/badge.svg)](https://docs.rs/rand_chacha)
A cryptographically secure random number generator that uses the ChaCha
algorithm.
ChaCha is a stream cipher designed by Daniel J. Bernstein[^1], that we use
as an RNG. It is an improved variant of the Salsa20 cipher family, which was
selected as one of the "stream ciphers suitable for widespread adoption" by
eSTREAM[^2].
The RNGs provided by this crate are implemented via the fast stream ciphers of
the [`c2-chacha`](https://crates.io/crates/c2-chacha) crate.
Links:
- [API documentation (master)](https://rust-random.github.io/rand/rand_chacha)
- [API documentation (docs.rs)](https://docs.rs/rand_chacha)
- [Changelog](https://github.com/rust-random/rand/blob/master/rand_chacha/CHANGELOG.md)
[rand]: https://crates.io/crates/rand
[^1]: D. J. Bernstein, [*ChaCha, a variant of Salsa20*](
https://cr.yp.to/chacha.html)
[^2]: [eSTREAM: the ECRYPT Stream Cipher Project](
http://www.ecrypt.eu.org/stream/)
## Crate Features
`rand_chacha` is `no_std` compatible when disabling default features; the `std`
feature can be explicitly required to re-enable `std` support. Using `std`
allows detection of CPU features and thus better optimisation. Using `std`
also enables `os_rng` functionality, such as `ChaCha20Rng::from_os_rng()`.
# License
`rand_chacha` is distributed under the terms of both the MIT license and the
Apache License (Version 2.0).
See [LICENSE-APACHE](LICENSE-APACHE) and [LICENSE-MIT](LICENSE-MIT), and
[COPYRIGHT](COPYRIGHT) for details.

651
vendor/rand_chacha/src/chacha.rs vendored Normal file
View File

@@ -0,0 +1,651 @@
// Copyright 2018 Developers of the Rand project.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! The ChaCha random number generator.
use crate::guts::ChaCha;
use core::fmt;
use rand_core::block::{BlockRng, BlockRngCore, CryptoBlockRng};
use rand_core::{CryptoRng, RngCore, SeedableRng};
#[cfg(feature = "serde")]
use serde::{Deserialize, Deserializer, Serialize, Serializer};
// NB. this must remain consistent with some currently hard-coded numbers in this module
const BUF_BLOCKS: u8 = 4;
// number of 32-bit words per ChaCha block (fixed by algorithm definition)
const BLOCK_WORDS: u8 = 16;
#[repr(transparent)]
pub struct Array64<T>([T; 64]);
impl<T> Default for Array64<T>
where
T: Default,
{
#[rustfmt::skip]
fn default() -> Self {
Self([
T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(),
T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(),
T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(),
T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(),
T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(),
T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(),
T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(),
T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(), T::default(),
])
}
}
impl<T> AsRef<[T]> for Array64<T> {
fn as_ref(&self) -> &[T] {
&self.0
}
}
impl<T> AsMut<[T]> for Array64<T> {
fn as_mut(&mut self) -> &mut [T] {
&mut self.0
}
}
impl<T> Clone for Array64<T>
where
T: Copy + Default,
{
fn clone(&self) -> Self {
let mut new = Self::default();
new.0.copy_from_slice(&self.0);
new
}
}
impl<T> fmt::Debug for Array64<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Array64 {{}}")
}
}
macro_rules! chacha_impl {
($ChaChaXCore:ident, $ChaChaXRng:ident, $rounds:expr, $doc:expr, $abst:ident,) => {
#[doc=$doc]
#[derive(Clone, PartialEq, Eq)]
pub struct $ChaChaXCore {
state: ChaCha,
}
// Custom Debug implementation that does not expose the internal state
impl fmt::Debug for $ChaChaXCore {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "ChaChaXCore {{}}")
}
}
impl BlockRngCore for $ChaChaXCore {
type Item = u32;
type Results = Array64<u32>;
#[inline]
fn generate(&mut self, r: &mut Self::Results) {
self.state.refill4($rounds, &mut r.0);
}
}
impl SeedableRng for $ChaChaXCore {
type Seed = [u8; 32];
#[inline]
fn from_seed(seed: Self::Seed) -> Self {
$ChaChaXCore {
state: ChaCha::new(&seed, &[0u8; 8]),
}
}
}
impl CryptoBlockRng for $ChaChaXCore {}
/// A cryptographically secure random number generator that uses the ChaCha algorithm.
///
/// ChaCha is a stream cipher designed by Daniel J. Bernstein[^1], that we use as an RNG. It is
/// an improved variant of the Salsa20 cipher family, which was selected as one of the "stream
/// ciphers suitable for widespread adoption" by eSTREAM[^2].
///
/// ChaCha uses add-rotate-xor (ARX) operations as its basis. These are safe against timing
/// attacks, although that is mostly a concern for ciphers and not for RNGs. We provide a SIMD
/// implementation to support high throughput on a variety of common hardware platforms.
///
/// With the ChaCha algorithm it is possible to choose the number of rounds the core algorithm
/// should run. The number of rounds is a tradeoff between performance and security, where 8
/// rounds is the minimum potentially secure configuration, and 20 rounds is widely used as a
/// conservative choice.
///
/// We use a 64-bit counter and 64-bit stream identifier as in Bernstein's implementation[^1]
/// except that we use a stream identifier in place of a nonce. A 64-bit counter over 64-byte
/// (16 word) blocks allows 1 ZiB of output before cycling, and the stream identifier allows
/// 2<sup>64</sup> unique streams of output per seed. Both counter and stream are initialized
/// to zero but may be set via the `set_word_pos` and `set_stream` methods.
///
/// The word layout is:
///
/// ```text
/// constant constant constant constant
/// seed seed seed seed
/// seed seed seed seed
/// counter counter stream_id stream_id
/// ```
///
/// This implementation uses an output buffer of sixteen `u32` words, and uses
/// [`BlockRng`] to implement the [`RngCore`] methods.
///
/// [^1]: D. J. Bernstein, [*ChaCha, a variant of Salsa20*](
/// https://cr.yp.to/chacha.html)
///
/// [^2]: [eSTREAM: the ECRYPT Stream Cipher Project](
/// http://www.ecrypt.eu.org/stream/)
#[derive(Clone, Debug)]
pub struct $ChaChaXRng {
rng: BlockRng<$ChaChaXCore>,
}
impl SeedableRng for $ChaChaXRng {
type Seed = [u8; 32];
#[inline]
fn from_seed(seed: Self::Seed) -> Self {
let core = $ChaChaXCore::from_seed(seed);
Self {
rng: BlockRng::new(core),
}
}
}
impl RngCore for $ChaChaXRng {
#[inline]
fn next_u32(&mut self) -> u32 {
self.rng.next_u32()
}
#[inline]
fn next_u64(&mut self) -> u64 {
self.rng.next_u64()
}
#[inline]
fn fill_bytes(&mut self, bytes: &mut [u8]) {
self.rng.fill_bytes(bytes)
}
}
impl $ChaChaXRng {
// The buffer is a 4-block window, i.e. it is always at a block-aligned position in the
// stream but if the stream has been sought it may not be self-aligned.
/// Get the offset from the start of the stream, in 32-bit words.
///
/// Since the generated blocks are 16 words (2<sup>4</sup>) long and the
/// counter is 64-bits, the offset is a 68-bit number. Sub-word offsets are
/// not supported, hence the result can simply be multiplied by 4 to get a
/// byte-offset.
#[inline]
pub fn get_word_pos(&self) -> u128 {
let buf_start_block = {
let buf_end_block = self.rng.core.state.get_block_pos();
u64::wrapping_sub(buf_end_block, BUF_BLOCKS.into())
};
let (buf_offset_blocks, block_offset_words) = {
let buf_offset_words = self.rng.index() as u64;
let blocks_part = buf_offset_words / u64::from(BLOCK_WORDS);
let words_part = buf_offset_words % u64::from(BLOCK_WORDS);
(blocks_part, words_part)
};
let pos_block = u64::wrapping_add(buf_start_block, buf_offset_blocks);
let pos_block_words = u128::from(pos_block) * u128::from(BLOCK_WORDS);
pos_block_words + u128::from(block_offset_words)
}
/// Set the offset from the start of the stream, in 32-bit words.
///
/// As with `get_word_pos`, we use a 68-bit number. Since the generator
/// simply cycles at the end of its period (1 ZiB), we ignore the upper
/// 60 bits.
#[inline]
pub fn set_word_pos(&mut self, word_offset: u128) {
let block = (word_offset / u128::from(BLOCK_WORDS)) as u64;
self.rng.core.state.set_block_pos(block);
self.rng
.generate_and_set((word_offset % u128::from(BLOCK_WORDS)) as usize);
}
/// Set the stream number.
///
/// This is initialized to zero; 2<sup>64</sup> unique streams of output
/// are available per seed/key.
///
/// Note that in order to reproduce ChaCha output with a specific 64-bit
/// nonce, one can convert that nonce to a `u64` in little-endian fashion
/// and pass to this function. In theory a 96-bit nonce can be used by
/// passing the last 64-bits to this function and using the first 32-bits as
/// the most significant half of the 64-bit counter (which may be set
/// indirectly via `set_word_pos`), but this is not directly supported.
#[inline]
pub fn set_stream(&mut self, stream: u64) {
self.rng.core.state.set_nonce(stream);
if self.rng.index() != 64 {
let wp = self.get_word_pos();
self.set_word_pos(wp);
}
}
/// Get the stream number.
#[inline]
pub fn get_stream(&self) -> u64 {
self.rng.core.state.get_nonce()
}
/// Get the seed.
#[inline]
pub fn get_seed(&self) -> [u8; 32] {
self.rng.core.state.get_seed()
}
}
impl CryptoRng for $ChaChaXRng {}
impl From<$ChaChaXCore> for $ChaChaXRng {
fn from(core: $ChaChaXCore) -> Self {
$ChaChaXRng {
rng: BlockRng::new(core),
}
}
}
impl PartialEq<$ChaChaXRng> for $ChaChaXRng {
fn eq(&self, rhs: &$ChaChaXRng) -> bool {
let a: $abst::$ChaChaXRng = self.into();
let b: $abst::$ChaChaXRng = rhs.into();
a == b
}
}
impl Eq for $ChaChaXRng {}
#[cfg(feature = "serde")]
impl Serialize for $ChaChaXRng {
fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
$abst::$ChaChaXRng::from(self).serialize(s)
}
}
#[cfg(feature = "serde")]
impl<'de> Deserialize<'de> for $ChaChaXRng {
fn deserialize<D>(d: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
$abst::$ChaChaXRng::deserialize(d).map(|x| Self::from(&x))
}
}
mod $abst {
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
// The abstract state of a ChaCha stream, independent of implementation choices. The
// comparison and serialization of this object is considered a semver-covered part of
// the API.
#[derive(Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub(crate) struct $ChaChaXRng {
seed: [u8; 32],
stream: u64,
word_pos: u128,
}
impl From<&super::$ChaChaXRng> for $ChaChaXRng {
// Forget all information about the input except what is necessary to determine the
// outputs of any sequence of pub API calls.
fn from(r: &super::$ChaChaXRng) -> Self {
Self {
seed: r.get_seed(),
stream: r.get_stream(),
word_pos: r.get_word_pos(),
}
}
}
impl From<&$ChaChaXRng> for super::$ChaChaXRng {
// Construct one of the possible concrete RNGs realizing an abstract state.
fn from(a: &$ChaChaXRng) -> Self {
use rand_core::SeedableRng;
let mut r = Self::from_seed(a.seed);
r.set_stream(a.stream);
r.set_word_pos(a.word_pos);
r
}
}
}
};
}
chacha_impl!(
ChaCha20Core,
ChaCha20Rng,
10,
"ChaCha with 20 rounds",
abstract20,
);
chacha_impl!(
ChaCha12Core,
ChaCha12Rng,
6,
"ChaCha with 12 rounds",
abstract12,
);
chacha_impl!(
ChaCha8Core,
ChaCha8Rng,
4,
"ChaCha with 8 rounds",
abstract8,
);
#[cfg(test)]
mod test {
use rand_core::{RngCore, SeedableRng};
#[cfg(feature = "serde")]
use super::{ChaCha12Rng, ChaCha20Rng, ChaCha8Rng};
type ChaChaRng = super::ChaCha20Rng;
#[cfg(feature = "serde")]
#[test]
fn test_chacha_serde_roundtrip() {
let seed = [
1, 0, 52, 0, 0, 0, 0, 0, 1, 0, 10, 0, 22, 32, 0, 0, 2, 0, 55, 49, 0, 11, 0, 0, 3, 0, 0,
0, 0, 0, 2, 92,
];
let mut rng1 = ChaCha20Rng::from_seed(seed);
let mut rng2 = ChaCha12Rng::from_seed(seed);
let mut rng3 = ChaCha8Rng::from_seed(seed);
let encoded1 = serde_json::to_string(&rng1).unwrap();
let encoded2 = serde_json::to_string(&rng2).unwrap();
let encoded3 = serde_json::to_string(&rng3).unwrap();
let mut decoded1: ChaCha20Rng = serde_json::from_str(&encoded1).unwrap();
let mut decoded2: ChaCha12Rng = serde_json::from_str(&encoded2).unwrap();
let mut decoded3: ChaCha8Rng = serde_json::from_str(&encoded3).unwrap();
assert_eq!(rng1, decoded1);
assert_eq!(rng2, decoded2);
assert_eq!(rng3, decoded3);
assert_eq!(rng1.next_u32(), decoded1.next_u32());
assert_eq!(rng2.next_u32(), decoded2.next_u32());
assert_eq!(rng3.next_u32(), decoded3.next_u32());
}
// This test validates that:
// 1. a hard-coded serialization demonstrating the format at time of initial release can still
// be deserialized to a ChaChaRng
// 2. re-serializing the resultant object produces exactly the original string
//
// Condition 2 is stronger than necessary: an equivalent serialization (e.g. with field order
// permuted, or whitespace differences) would also be admissible, but would fail this test.
// However testing for equivalence of serialized data is difficult, and there shouldn't be any
// reason we need to violate the stronger-than-needed condition, e.g. by changing the field
// definition order.
#[cfg(feature = "serde")]
#[test]
fn test_chacha_serde_format_stability() {
let j = r#"{"seed":[4,8,15,16,23,42,4,8,15,16,23,42,4,8,15,16,23,42,4,8,15,16,23,42,4,8,15,16,23,42,4,8],"stream":27182818284,"word_pos":314159265359}"#;
let r: ChaChaRng = serde_json::from_str(j).unwrap();
let j1 = serde_json::to_string(&r).unwrap();
assert_eq!(j, j1);
}
#[test]
fn test_chacha_construction() {
let seed = [
0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0,
0, 0, 0,
];
let mut rng1 = ChaChaRng::from_seed(seed);
assert_eq!(rng1.next_u32(), 137206642);
let mut rng2 = ChaChaRng::from_rng(&mut rng1);
assert_eq!(rng2.next_u32(), 1325750369);
}
#[test]
fn test_chacha_true_values_a() {
// Test vectors 1 and 2 from
// https://tools.ietf.org/html/draft-nir-cfrg-chacha20-poly1305-04
let seed = [0u8; 32];
let mut rng = ChaChaRng::from_seed(seed);
let mut results = [0u32; 16];
for i in results.iter_mut() {
*i = rng.next_u32();
}
let expected = [
0xade0b876, 0x903df1a0, 0xe56a5d40, 0x28bd8653, 0xb819d2bd, 0x1aed8da0, 0xccef36a8,
0xc70d778b, 0x7c5941da, 0x8d485751, 0x3fe02477, 0x374ad8b8, 0xf4b8436a, 0x1ca11815,
0x69b687c3, 0x8665eeb2,
];
assert_eq!(results, expected);
for i in results.iter_mut() {
*i = rng.next_u32();
}
let expected = [
0xbee7079f, 0x7a385155, 0x7c97ba98, 0x0d082d73, 0xa0290fcb, 0x6965e348, 0x3e53c612,
0xed7aee32, 0x7621b729, 0x434ee69c, 0xb03371d5, 0xd539d874, 0x281fed31, 0x45fb0a51,
0x1f0ae1ac, 0x6f4d794b,
];
assert_eq!(results, expected);
}
#[test]
fn test_chacha_true_values_b() {
// Test vector 3 from
// https://tools.ietf.org/html/draft-nir-cfrg-chacha20-poly1305-04
let seed = [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1,
];
let mut rng = ChaChaRng::from_seed(seed);
// Skip block 0
for _ in 0..16 {
rng.next_u32();
}
let mut results = [0u32; 16];
for i in results.iter_mut() {
*i = rng.next_u32();
}
let expected = [
0x2452eb3a, 0x9249f8ec, 0x8d829d9b, 0xddd4ceb1, 0xe8252083, 0x60818b01, 0xf38422b8,
0x5aaa49c9, 0xbb00ca8e, 0xda3ba7b4, 0xc4b592d1, 0xfdf2732f, 0x4436274e, 0x2561b3c8,
0xebdd4aa6, 0xa0136c00,
];
assert_eq!(results, expected);
}
#[test]
fn test_chacha_true_values_c() {
// Test vector 4 from
// https://tools.ietf.org/html/draft-nir-cfrg-chacha20-poly1305-04
let seed = [
0, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0,
];
let expected = [
0xfb4dd572, 0x4bc42ef1, 0xdf922636, 0x327f1394, 0xa78dea8f, 0x5e269039, 0xa1bebbc1,
0xcaf09aae, 0xa25ab213, 0x48a6b46c, 0x1b9d9bcb, 0x092c5be6, 0x546ca624, 0x1bec45d5,
0x87f47473, 0x96f0992e,
];
let expected_end = 3 * 16;
let mut results = [0u32; 16];
// Test block 2 by skipping block 0 and 1
let mut rng1 = ChaChaRng::from_seed(seed);
for _ in 0..32 {
rng1.next_u32();
}
for i in results.iter_mut() {
*i = rng1.next_u32();
}
assert_eq!(results, expected);
assert_eq!(rng1.get_word_pos(), expected_end);
// Test block 2 by using `set_word_pos`
let mut rng2 = ChaChaRng::from_seed(seed);
rng2.set_word_pos(2 * 16);
for i in results.iter_mut() {
*i = rng2.next_u32();
}
assert_eq!(results, expected);
assert_eq!(rng2.get_word_pos(), expected_end);
// Test skipping behaviour with other types
let mut buf = [0u8; 32];
rng2.fill_bytes(&mut buf[..]);
assert_eq!(rng2.get_word_pos(), expected_end + 8);
rng2.fill_bytes(&mut buf[0..25]);
assert_eq!(rng2.get_word_pos(), expected_end + 15);
rng2.next_u64();
assert_eq!(rng2.get_word_pos(), expected_end + 17);
rng2.next_u32();
rng2.next_u64();
assert_eq!(rng2.get_word_pos(), expected_end + 20);
rng2.fill_bytes(&mut buf[0..1]);
assert_eq!(rng2.get_word_pos(), expected_end + 21);
}
#[test]
fn test_chacha_multiple_blocks() {
let seed = [
0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 7,
0, 0, 0,
];
let mut rng = ChaChaRng::from_seed(seed);
// Store the 17*i-th 32-bit word,
// i.e., the i-th word of the i-th 16-word block
let mut results = [0u32; 16];
for i in results.iter_mut() {
*i = rng.next_u32();
for _ in 0..16 {
rng.next_u32();
}
}
let expected = [
0xf225c81a, 0x6ab1be57, 0x04d42951, 0x70858036, 0x49884684, 0x64efec72, 0x4be2d186,
0x3615b384, 0x11cfa18e, 0xd3c50049, 0x75c775f6, 0x434c6530, 0x2c5bad8f, 0x898881dc,
0x5f1c86d9, 0xc1f8e7f4,
];
assert_eq!(results, expected);
}
#[test]
fn test_chacha_true_bytes() {
let seed = [0u8; 32];
let mut rng = ChaChaRng::from_seed(seed);
let mut results = [0u8; 32];
rng.fill_bytes(&mut results);
let expected = [
118, 184, 224, 173, 160, 241, 61, 144, 64, 93, 106, 229, 83, 134, 189, 40, 189, 210,
25, 184, 160, 141, 237, 26, 168, 54, 239, 204, 139, 119, 13, 199,
];
assert_eq!(results, expected);
}
#[test]
fn test_chacha_nonce() {
// Test vector 5 from
// https://tools.ietf.org/html/draft-nir-cfrg-chacha20-poly1305-04
// Although we do not support setting a nonce, we try it here anyway so
// we can use this test vector.
let seed = [0u8; 32];
let mut rng = ChaChaRng::from_seed(seed);
// 96-bit nonce in LE order is: 0,0,0,0, 0,0,0,0, 0,0,0,2
rng.set_stream(2u64 << (24 + 32));
let mut results = [0u32; 16];
for i in results.iter_mut() {
*i = rng.next_u32();
}
let expected = [
0x374dc6c2, 0x3736d58c, 0xb904e24a, 0xcd3f93ef, 0x88228b1a, 0x96a4dfb3, 0x5b76ab72,
0xc727ee54, 0x0e0e978a, 0xf3145c95, 0x1b748ea8, 0xf786c297, 0x99c28f5f, 0x628314e8,
0x398a19fa, 0x6ded1b53,
];
assert_eq!(results, expected);
}
#[test]
fn test_chacha_clone_streams() {
let seed = [
0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 7,
0, 0, 0,
];
let mut rng = ChaChaRng::from_seed(seed);
let mut clone = rng.clone();
for _ in 0..16 {
assert_eq!(rng.next_u64(), clone.next_u64());
}
rng.set_stream(51);
for _ in 0..7 {
assert!(rng.next_u32() != clone.next_u32());
}
clone.set_stream(51); // switch part way through block
for _ in 7..16 {
assert_eq!(rng.next_u32(), clone.next_u32());
}
}
#[test]
fn test_chacha_word_pos_wrap_exact() {
use super::{BLOCK_WORDS, BUF_BLOCKS};
let mut rng = ChaChaRng::from_seed(Default::default());
// refilling the buffer in set_word_pos will wrap the block counter to 0
let last_block = (1 << 68) - u128::from(BUF_BLOCKS * BLOCK_WORDS);
rng.set_word_pos(last_block);
assert_eq!(rng.get_word_pos(), last_block);
}
#[test]
fn test_chacha_word_pos_wrap_excess() {
use super::BLOCK_WORDS;
let mut rng = ChaChaRng::from_seed(Default::default());
// refilling the buffer in set_word_pos will wrap the block counter past 0
let last_block = (1 << 68) - u128::from(BLOCK_WORDS);
rng.set_word_pos(last_block);
assert_eq!(rng.get_word_pos(), last_block);
}
#[test]
fn test_chacha_word_pos_zero() {
let mut rng = ChaChaRng::from_seed(Default::default());
assert_eq!(rng.get_word_pos(), 0);
rng.set_word_pos(0);
assert_eq!(rng.get_word_pos(), 0);
}
#[test]
fn test_trait_objects() {
use rand_core::CryptoRng;
let mut rng1 = ChaChaRng::from_seed(Default::default());
let rng2 = &mut rng1.clone() as &mut dyn CryptoRng;
for _ in 0..1000 {
assert_eq!(rng1.next_u64(), rng2.next_u64());
}
}
}

287
vendor/rand_chacha/src/guts.rs vendored Normal file
View File

@@ -0,0 +1,287 @@
// Copyright 2019 The CryptoCorrosion Contributors
// Copyright 2020 Developers of the Rand project.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! The ChaCha random number generator.
use ppv_lite86::{dispatch, dispatch_light128};
pub use ppv_lite86::Machine;
use ppv_lite86::{
vec128_storage, ArithOps, BitOps32, LaneWords4, MultiLane, StoreBytes, Vec4, Vec4Ext, Vector,
};
pub(crate) const BLOCK: usize = 16;
pub(crate) const BLOCK64: u64 = BLOCK as u64;
const LOG2_BUFBLOCKS: u64 = 2;
const BUFBLOCKS: u64 = 1 << LOG2_BUFBLOCKS;
pub(crate) const BUFSZ64: u64 = BLOCK64 * BUFBLOCKS;
pub(crate) const BUFSZ: usize = BUFSZ64 as usize;
const STREAM_PARAM_NONCE: u32 = 1;
const STREAM_PARAM_BLOCK: u32 = 0;
#[derive(Clone, PartialEq, Eq)]
pub struct ChaCha {
pub(crate) b: vec128_storage,
pub(crate) c: vec128_storage,
pub(crate) d: vec128_storage,
}
#[derive(Clone)]
pub struct State<V> {
pub(crate) a: V,
pub(crate) b: V,
pub(crate) c: V,
pub(crate) d: V,
}
#[inline(always)]
pub(crate) fn round<V: ArithOps + BitOps32>(mut x: State<V>) -> State<V> {
x.a += x.b;
x.d = (x.d ^ x.a).rotate_each_word_right16();
x.c += x.d;
x.b = (x.b ^ x.c).rotate_each_word_right20();
x.a += x.b;
x.d = (x.d ^ x.a).rotate_each_word_right24();
x.c += x.d;
x.b = (x.b ^ x.c).rotate_each_word_right25();
x
}
#[inline(always)]
pub(crate) fn diagonalize<V: LaneWords4>(mut x: State<V>) -> State<V> {
x.b = x.b.shuffle_lane_words3012();
x.c = x.c.shuffle_lane_words2301();
x.d = x.d.shuffle_lane_words1230();
x
}
#[inline(always)]
pub(crate) fn undiagonalize<V: LaneWords4>(mut x: State<V>) -> State<V> {
x.b = x.b.shuffle_lane_words1230();
x.c = x.c.shuffle_lane_words2301();
x.d = x.d.shuffle_lane_words3012();
x
}
impl ChaCha {
#[inline(always)]
pub fn new(key: &[u8; 32], nonce: &[u8]) -> Self {
init_chacha(key, nonce)
}
/// Produce 4 blocks of output, advancing the state
#[inline(always)]
pub fn refill4(&mut self, drounds: u32, out: &mut [u32; BUFSZ]) {
refill_wide(self, drounds, out)
}
#[inline(always)]
pub fn set_block_pos(&mut self, value: u64) {
set_stream_param(self, STREAM_PARAM_BLOCK, value)
}
#[inline(always)]
pub fn get_block_pos(&self) -> u64 {
get_stream_param(self, STREAM_PARAM_BLOCK)
}
#[inline(always)]
pub fn set_nonce(&mut self, value: u64) {
set_stream_param(self, STREAM_PARAM_NONCE, value)
}
#[inline(always)]
pub fn get_nonce(&self) -> u64 {
get_stream_param(self, STREAM_PARAM_NONCE)
}
#[inline(always)]
pub fn get_seed(&self) -> [u8; 32] {
get_seed(self)
}
}
// This implementation is platform-independent.
#[inline(always)]
#[cfg(target_endian = "big")]
fn add_pos<Mach: Machine>(_m: Mach, d0: Mach::u32x4, i: u64) -> Mach::u32x4 {
let pos0 = ((d0.extract(1) as u64) << 32) | d0.extract(0) as u64;
let pos = pos0.wrapping_add(i);
d0.insert((pos >> 32) as u32, 1).insert(pos as u32, 0)
}
#[inline(always)]
#[cfg(target_endian = "big")]
fn d0123<Mach: Machine>(m: Mach, d: vec128_storage) -> Mach::u32x4x4 {
let d0: Mach::u32x4 = m.unpack(d);
let mut pos = ((d0.extract(1) as u64) << 32) | d0.extract(0) as u64;
pos = pos.wrapping_add(1);
let d1 = d0.insert((pos >> 32) as u32, 1).insert(pos as u32, 0);
pos = pos.wrapping_add(1);
let d2 = d0.insert((pos >> 32) as u32, 1).insert(pos as u32, 0);
pos = pos.wrapping_add(1);
let d3 = d0.insert((pos >> 32) as u32, 1).insert(pos as u32, 0);
Mach::u32x4x4::from_lanes([d0, d1, d2, d3])
}
// Pos is packed into the state vectors as a little-endian u64,
// so on LE platforms we can use native vector ops to increment it.
#[inline(always)]
#[cfg(target_endian = "little")]
fn add_pos<Mach: Machine>(m: Mach, d: Mach::u32x4, i: u64) -> Mach::u32x4 {
let d0: Mach::u64x2 = m.unpack(d.into());
let incr = m.vec([i, 0]);
m.unpack((d0 + incr).into())
}
#[inline(always)]
#[cfg(target_endian = "little")]
fn d0123<Mach: Machine>(m: Mach, d: vec128_storage) -> Mach::u32x4x4 {
let d0: Mach::u64x2 = m.unpack(d);
let incr =
Mach::u64x2x4::from_lanes([m.vec([0, 0]), m.vec([1, 0]), m.vec([2, 0]), m.vec([3, 0])]);
m.unpack((Mach::u64x2x4::from_lanes([d0, d0, d0, d0]) + incr).into())
}
#[allow(clippy::many_single_char_names)]
#[inline(always)]
fn refill_wide_impl<Mach: Machine>(
m: Mach,
state: &mut ChaCha,
drounds: u32,
out: &mut [u32; BUFSZ],
) {
let k = m.vec([0x6170_7865, 0x3320_646e, 0x7962_2d32, 0x6b20_6574]);
let b = m.unpack(state.b);
let c = m.unpack(state.c);
let mut x = State {
a: Mach::u32x4x4::from_lanes([k, k, k, k]),
b: Mach::u32x4x4::from_lanes([b, b, b, b]),
c: Mach::u32x4x4::from_lanes([c, c, c, c]),
d: d0123(m, state.d),
};
for _ in 0..drounds {
x = round(x);
x = undiagonalize(round(diagonalize(x)));
}
let kk = Mach::u32x4x4::from_lanes([k, k, k, k]);
let sb = m.unpack(state.b);
let sb = Mach::u32x4x4::from_lanes([sb, sb, sb, sb]);
let sc = m.unpack(state.c);
let sc = Mach::u32x4x4::from_lanes([sc, sc, sc, sc]);
let sd = d0123(m, state.d);
let results = Mach::u32x4x4::transpose4(x.a + kk, x.b + sb, x.c + sc, x.d + sd);
out[0..16].copy_from_slice(&results.0.to_scalars());
out[16..32].copy_from_slice(&results.1.to_scalars());
out[32..48].copy_from_slice(&results.2.to_scalars());
out[48..64].copy_from_slice(&results.3.to_scalars());
state.d = add_pos(m, sd.to_lanes()[0], 4).into();
}
dispatch!(m, Mach, {
fn refill_wide(state: &mut ChaCha, drounds: u32, out: &mut [u32; BUFSZ]) {
refill_wide_impl(m, state, drounds, out);
}
});
// Single-block, rounds-only; shared by try_apply_keystream for tails shorter than BUFSZ
// and XChaCha's setup step.
dispatch!(m, Mach, {
fn refill_narrow_rounds(state: &mut ChaCha, drounds: u32) -> State<vec128_storage> {
let k: Mach::u32x4 = m.vec([0x6170_7865, 0x3320_646e, 0x7962_2d32, 0x6b20_6574]);
let mut x = State {
a: k,
b: m.unpack(state.b),
c: m.unpack(state.c),
d: m.unpack(state.d),
};
for _ in 0..drounds {
x = round(x);
x = undiagonalize(round(diagonalize(x)));
}
State {
a: x.a.into(),
b: x.b.into(),
c: x.c.into(),
d: x.d.into(),
}
}
});
dispatch_light128!(m, Mach, {
fn set_stream_param(state: &mut ChaCha, param: u32, value: u64) {
let d: Mach::u32x4 = m.unpack(state.d);
state.d = d
.insert((value >> 32) as u32, (param << 1) | 1)
.insert(value as u32, param << 1)
.into();
}
});
dispatch_light128!(m, Mach, {
fn get_stream_param(state: &ChaCha, param: u32) -> u64 {
let d: Mach::u32x4 = m.unpack(state.d);
((d.extract((param << 1) | 1) as u64) << 32) | d.extract(param << 1) as u64
}
});
dispatch_light128!(m, Mach, {
fn get_seed(state: &ChaCha) -> [u8; 32] {
let b: Mach::u32x4 = m.unpack(state.b);
let c: Mach::u32x4 = m.unpack(state.c);
let mut key = [0u8; 32];
b.write_le(&mut key[..16]);
c.write_le(&mut key[16..]);
key
}
});
fn read_u32le(xs: &[u8]) -> u32 {
assert_eq!(xs.len(), 4);
u32::from(xs[0]) | (u32::from(xs[1]) << 8) | (u32::from(xs[2]) << 16) | (u32::from(xs[3]) << 24)
}
dispatch_light128!(m, Mach, {
fn init_chacha(key: &[u8; 32], nonce: &[u8]) -> ChaCha {
let ctr_nonce = [
0,
if nonce.len() == 12 {
read_u32le(&nonce[0..4])
} else {
0
},
read_u32le(&nonce[nonce.len() - 8..nonce.len() - 4]),
read_u32le(&nonce[nonce.len() - 4..]),
];
let key0: Mach::u32x4 = m.read_le(&key[..16]);
let key1: Mach::u32x4 = m.read_le(&key[16..]);
ChaCha {
b: key0.into(),
c: key1.into(),
d: ctr_nonce.into(),
}
}
});
dispatch_light128!(m, Mach, {
fn init_chacha_x(key: &[u8; 32], nonce: &[u8; 24], rounds: u32) -> ChaCha {
let key0: Mach::u32x4 = m.read_le(&key[..16]);
let key1: Mach::u32x4 = m.read_le(&key[16..]);
let nonce0: Mach::u32x4 = m.read_le(&nonce[..16]);
let mut state = ChaCha {
b: key0.into(),
c: key1.into(),
d: nonce0.into(),
};
let x = refill_narrow_rounds(&mut state, rounds);
let ctr_nonce1 = [0, 0, read_u32le(&nonce[16..20]), read_u32le(&nonce[20..24])];
state.b = x.a;
state.c = x.d;
state.d = ctr_nonce1.into();
state
}
});

106
vendor/rand_chacha/src/lib.rs vendored Normal file
View File

@@ -0,0 +1,106 @@
// Copyright 2018 Developers of the Rand project.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! The ChaCha random number generators.
//!
//! These are native Rust implementations of RNGs derived from the
//! [ChaCha stream ciphers] by D J Bernstein.
//!
//! ## Generators
//!
//! This crate provides 8-, 12- and 20-round variants of generators via a "core"
//! implementation (of [`BlockRngCore`]), each with an associated "RNG" type
//! (implementing [`RngCore`]).
//!
//! These generators are all deterministic and portable (see [Reproducibility]
//! in the book), with testing against reference vectors.
//!
//! ## Cryptographic (secure) usage
//!
//! Where secure unpredictable generators are required, it is suggested to use
//! [`ChaCha12Rng`] or [`ChaCha20Rng`] and to seed via
//! [`SeedableRng::from_os_rng`].
//!
//! See also the [Security] chapter in the rand book. The crate is provided
//! "as is", without any form of guarantee, and without a security audit.
//!
//! ## Seeding (construction)
//!
//! Generators implement the [`SeedableRng`] trait. Any method may be used,
//! but note that `seed_from_u64` is not suitable for usage where security is
//! important. Some suggestions:
//!
//! 1. With a fresh seed, **direct from the OS** (implies a syscall):
//! ```
//! # use {rand_core::SeedableRng, rand_chacha::ChaCha12Rng};
//! let rng = ChaCha12Rng::from_os_rng();
//! # let _: ChaCha12Rng = rng;
//! ```
//! 2. **From a master generator.** This could be [`rand::rng`]
//! (effectively a fresh seed without the need for a syscall on each usage)
//! or a deterministic generator such as [`ChaCha20Rng`].
//! Beware that should a weak master generator be used, correlations may be
//! detectable between the outputs of its child generators.
//! ```ignore
//! let rng = ChaCha12Rng::from_rng(&mut rand::rng());
//! ```
//!
//! See also [Seeding RNGs] in the book.
//!
//! ## Generation
//!
//! Generators implement [`RngCore`], whose methods may be used directly to
//! generate unbounded integer or byte values.
//! ```
//! use rand_core::{SeedableRng, RngCore};
//! use rand_chacha::ChaCha12Rng;
//!
//! let mut rng = ChaCha12Rng::from_seed(Default::default());
//! let x = rng.next_u64();
//! assert_eq!(x, 0x53f955076a9af49b);
//! ```
//!
//! It is often more convenient to use the [`rand::Rng`] trait, which provides
//! further functionality. See also the [Random Values] chapter in the book.
//!
//! [ChaCha stream ciphers]: https://cr.yp.to/chacha.html
//! [Reproducibility]: https://rust-random.github.io/book/crate-reprod.html
//! [Seeding RNGs]: https://rust-random.github.io/book/guide-seeding.html
//! [Security]: https://rust-random.github.io/book/guide-rngs.html#security
//! [Random Values]: https://rust-random.github.io/book/guide-values.html
//! [`BlockRngCore`]: rand_core::block::BlockRngCore
//! [`RngCore`]: rand_core::RngCore
//! [`SeedableRng`]: rand_core::SeedableRng
//! [`SeedableRng::from_os_rng`]: rand_core::SeedableRng::from_os_rng
//! [`rand::rng`]: https://docs.rs/rand/latest/rand/fn.rng.html
//! [`rand::Rng`]: https://docs.rs/rand/latest/rand/trait.Rng.html
#![doc(
html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
html_favicon_url = "https://www.rust-lang.org/favicon.ico",
html_root_url = "https://rust-random.github.io/rand/"
)]
#![forbid(unsafe_code)]
#![deny(missing_docs)]
#![deny(missing_debug_implementations)]
#![doc(test(attr(allow(unused_variables), deny(warnings))))]
#![cfg_attr(not(feature = "std"), no_std)]
pub use rand_core;
mod chacha;
mod guts;
pub use crate::chacha::{
ChaCha12Core, ChaCha12Rng, ChaCha20Core, ChaCha20Rng, ChaCha8Core, ChaCha8Rng,
};
/// ChaCha with 20 rounds
pub type ChaChaRng = ChaCha20Rng;
/// ChaCha with 20 rounds, low-level interface
pub type ChaChaCore = ChaCha20Core;

Binary file not shown.

View File

@@ -0,0 +1 @@
{"name":"rand_chacha","vers":"0.9.0","deps":[{"name":"ppv-lite86","req":"^0.2.14","features":["simd"],"optional":false,"default_features":false,"target":null,"kind":"normal","registry":"https://github.com/rust-lang/crates.io-index","package":null,"public":null,"artifact":null,"bindep_target":null,"lib":false},{"name":"rand_core","req":"^0.9.0","features":[],"optional":false,"default_features":true,"target":null,"kind":"normal","registry":"https://github.com/rust-lang/crates.io-index","package":null,"public":null,"artifact":null,"bindep_target":null,"lib":false},{"name":"serde","req":"^1.0","features":["derive"],"optional":true,"default_features":true,"target":null,"kind":"normal","registry":"https://github.com/rust-lang/crates.io-index","package":null,"public":null,"artifact":null,"bindep_target":null,"lib":false},{"name":"rand_core","req":"^0.9.0","features":["os_rng"],"optional":false,"default_features":true,"target":null,"kind":"dev","registry":"https://github.com/rust-lang/crates.io-index","package":null,"public":null,"artifact":null,"bindep_target":null,"lib":false},{"name":"serde_json","req":"^1.0","features":[],"optional":false,"default_features":true,"target":null,"kind":"dev","registry":"https://github.com/rust-lang/crates.io-index","package":null,"public":null,"artifact":null,"bindep_target":null,"lib":false}],"features":{"default":["std"],"os_rng":["rand_core/os_rng"],"serde":["dep:serde"],"std":["ppv-lite86/std","rand_core/std"]},"features2":null,"cksum":"ad9d109af9e10d3cb6c5a49c7b7547adcae92fa173a2abd9d45fff62c3a2c38f","yanked":null,"links":null,"rust_version":null,"v":2}