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

1
vendor/poly1305/.cargo-checksum.json vendored Normal file
View File

@@ -0,0 +1 @@
{"files":{".cargo_vcs_info.json":"e3a6cf308ae94b1a37a0fb3749db061949c032593bf2663faf1a3ffd153ae74e","CHANGELOG.md":"cf306e150f4bd6fa59b38f85ba4c4ab9910f66e7e5d7daa0e6789d715b7ff574","Cargo.toml":"520a3d1c97ba2b3ce028a4f95615052f0f69622c00642bed52de3b8fc3eb2c31","Cargo.toml.orig":"dcb816b721df8189798561bfdba7033d73b4d726c9c3205be8de2a3903aa4c4b","LICENSE-APACHE":"a9040321c3712d8fd0b09cf52b17445de04a23a10165049ae187cd39e5c86be5","LICENSE-MIT":"6d99fffea918d1f7dfe567029c7bd21d6fcaf310ad28c44e6511a0e1f68c79ea","README.md":"7fd9f808a9b2aee03a8f25e2f4df23b7c13a7b9150dc146225e5aa49f7a83fd5","benches/poly1305.rs":"942f14f22b5fd2188ef0c32549d811d4f380092100511aae0fb67d594782791a","fuzz/main.rs":"b22f1f9e6a36bf906441aa1671c8e5d09c18cc3418d7dfba69511b5aa7a8651a","src/backend.rs":"f3fea20ab26a6e14d7e5654a117b7e5c408610568a81982589f16ad3651511ea","src/backend/autodetect.rs":"7c1f9bbe82f27f506f1995ba1e2c12f6eb766e075ea71ebc203e6a57a8b0df57","src/backend/avx2.rs":"7a35d104eaad1f89d13bf0ddd31e15891b0307b2cb18df6f8451b28faebc6c42","src/backend/avx2/helpers.rs":"b4cd4da81f4074105f49269dc49cf5c9e4bd0de20c0c92739a298d82d8638cf8","src/backend/soft.rs":"fd77a8c9b0b35bb1514d8ce812caa2c89b8a1ccccb2394558e8471fb3201bf74","src/fuzz.rs":"a1ca27a2e74a24ed5b664753600d4fe5e3ed7943a7fb0d61cb86d298319f737e","src/fuzz/id=000000,sig=06,src=000014,op=flip4,pos=11":"f9ef3408882b7c64bb813c67fb248bce286624d0a8dbd898433fd84799020d05","src/fuzz/id=000001,sig=06,src=000006+000014,op=splice,rep=64":"73ccc1be61e0c8ad3bd361a97cbcd81cc6e0a0012331dd3e0e4e4478b95e52c8","src/fuzz/id=000002,sig=06,src=000008+000014,op=splice,rep=32":"d43015681b873ba9409a64a1964c0986ddf4ea3aa6145d11089fcf97bb204cb5","src/fuzz/id=000003,sig=06,src=000003,op=havoc,rep=64":"b114b0d3ddd239d2f4e77ac73a7e5e0fc8404e64d409130d0576cfd92618b16e","src/fuzz/id=000004,sig=06,src=000022+000005,op=splice,rep=32":"88a597e4d4cf06ffef326bcf3491c31430122f9b1d07eb1d7c67c8883c778b57","src/fuzz/id=000005,sig=06,src=000008+000007,op=splice,rep=128":"d2d9488d422fa05bc26d18170e32a18abf86fb25aeade898e3e2c891bb4e38b3","src/fuzz/id=000006,sig=06,src=000005,op=havoc,rep=8":"f386adafea81cf4f0260cf3908cf847f0b3343f7a8655132c66a66edcae72092","src/fuzz/id=000007,sig=06,src=000024+000000,op=splice,rep=64":"f12e407dac96dc72556ed964e2697aa3599d25074efadfd0a4215b359dedc19a","src/fuzz/id=000008,sig=06,src=000019,time=165655+000011,op=splice,rep=128":"19d7ecaa013bd2d7cbd3c9f0a98b63755c83b699392fc1c5b4622adc741f69f7","src/lib.rs":"e693562b539dc9a080041692c1300782b8ca0b671aa50367c177573ab91286d8","tests/lib.rs":"805a8b2a307da3b02ae56d030e917f74b470c47fb0d4e52d1b6102994d51fc4e"},"package":"8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf"}

6
vendor/poly1305/.cargo_vcs_info.json vendored Normal file
View File

@@ -0,0 +1,6 @@
{
"git": {
"sha1": "47a72962e8898fc70ab79d4ab40949efe61a23d2"
},
"path_in_vcs": "poly1305"
}

123
vendor/poly1305/CHANGELOG.md vendored Normal file
View File

@@ -0,0 +1,123 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## 0.8.0 (2022-07-31)
### Changed
- Relax `zeroize` constraints ([#147])
- Upgrade to Rust 2021 edition ([#147])
- Use stable `aarch64_target_feature` ([#154])
- Bump `universal-hash` to v0.5 ([#155], [#162])
- Replace `armv8`/`force-soft` features with `cfg` attributes ([#159])
### Removed
- `armv8`/`force-soft` features ([#159])
[#147]: https://github.com/RustCrypto/universal-hashes/pull/147
[#154]: https://github.com/RustCrypto/universal-hashes/pull/154
[#155]: https://github.com/RustCrypto/universal-hashes/pull/155
[#159]: https://github.com/RustCrypto/universal-hashes/pull/159
[#162]: https://github.com/RustCrypto/universal-hashes/pull/162
## 0.7.2 (2021-08-27)
### Changed
- Bump `cpufeatures` dependency to v0.2 ([#136])
[#136]: https://github.com/RustCrypto/universal-hashes/pull/136
## 0.7.1 (2021-07-20)
### Changed
- Pin `zeroize` dependency to v1.3 ([#134])
[#134]: https://github.com/RustCrypto/universal-hashes/pull/134
## 0.7.0 (2021-04-29)
### Changed
- Use `ManuallyDrop` unions; MSRV 1.49+ ([#114])
- Use `cpufeatures` v0.1 crate release ([#116])
[#114]: https://github.com/RustCrypto/universal-hashes/pull/114
[#116]: https://github.com/RustCrypto/universal-hashes/pull/116
## 0.6.2 (2020-12-09)
### Added
- Runtime AVX2 detection ([#97])
[#97]: https://github.com/RustCrypto/universal-hashes/pull/97
## 0.6.1 (2020-09-29)
### Added
- AVX2 backend ([#49])
[#49]: https://github.com/RustCrypto/universal-hashes/pull/49
## 0.6.0 (2020-06-06)
### Added
- `Poly1305::compute_unpadded` for XSalsa20Poly1305 ([#55])
### Changed
- Bump `universal-hash` dependency to v0.4; MSRV 1.41 ([#52], [#57])
- Rename `result` methods to to `finalize` ([#56])
### Fixed
- Build with `zeroize` enabled ([#48])
[#57]: https://github.com/RustCrypto/universal-hashes/pull/57
[#56]: https://github.com/RustCrypto/universal-hashes/pull/56
[#55]: https://github.com/RustCrypto/universal-hashes/pull/55
[#52]: https://github.com/RustCrypto/universal-hashes/pull/52
[#48]: https://github.com/RustCrypto/universal-hashes/pull/48
## 0.5.2 (2019-11-14)
### Changed
- Upgrade to `zeroize` 1.0 ([#33])
[#33]: https://github.com/RustCrypto/universal-hashes/pull/33
## 0.5.1 (2019-10-04)
### Added
- Link to `chacha20poly1305` and `xsalsa20poly1305` crates from README.md ([#26])
[#26]: https://github.com/RustCrypto/universal-hashes/pull/26
## 0.5.0 (2019-10-04)
### Changed
- Upgrade to `universal-hash` crate v0.3 ([#22])
[#22]: https://github.com/RustCrypto/universal-hashes/pull/22
## 0.4.1 (2019-10-01)
### Changed
- Upgrade to `zeroize` v1.0.0-pre ([#19])
[#19]: https://github.com/RustCrypto/universal-hashes/pull/19
## 0.4.0 (2019-09-29)
### Changed
- Update to Rust 2018 edition ([#3])
- Use `UniversalHash` trait ([#5])
[#3]: https://github.com/RustCrypto/universal-hashes/pull/3
[#5]: https://github.com/RustCrypto/universal-hashes/pull/5
## 0.3.0 (2019-08-26)
### Changed
- Switch from `MacResult` to built-in `Tag` type ([RustCrypto/MACs#13])
[RustCrypto/MACs#13]: https://github.com/RustCrypto/MACs/pull/13
## 0.2.0 (2019-08-19)
### Added
- `Poly1305::input_padded()` ([#16])
### Changed
- Change output to be a `MacResult` ([RustCrypto/MACs#16])
[RustCrypto/MACs#16]: https://github.com/RustCrypto/MACs/pull/16
## 0.1.0 (2019-08-15)
- Initial release

55
vendor/poly1305/Cargo.toml vendored Normal file
View File

@@ -0,0 +1,55 @@
# 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.56"
name = "poly1305"
version = "0.8.0"
authors = ["RustCrypto Developers"]
description = "The Poly1305 universal hash function and message authentication code"
documentation = "https://docs.rs/poly1305"
readme = "README.md"
keywords = [
"crypto",
"chacha20",
"mac",
"salsa20",
"universal-hashing",
]
categories = [
"cryptography",
"no-std",
]
license = "Apache-2.0 OR MIT"
repository = "https://github.com/RustCrypto/universal-hashes"
resolver = "2"
[dependencies.opaque-debug]
version = "0.3"
[dependencies.universal-hash]
version = "0.5"
default-features = false
[dependencies.zeroize]
version = "1"
optional = true
default-features = false
[dev-dependencies.hex-literal]
version = "0.3"
[features]
std = ["universal-hash/std"]
[target."cfg(any(target_arch = \"x86_64\", target_arch = \"x86\"))".dependencies.cpufeatures]
version = "0.2"

201
vendor/poly1305/LICENSE-APACHE vendored Normal file
View File

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

25
vendor/poly1305/LICENSE-MIT vendored Normal file
View File

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

69
vendor/poly1305/README.md vendored Normal file
View File

@@ -0,0 +1,69 @@
# RustCrypto: Poly1305
[![crate][crate-image]][crate-link]
[![Docs][docs-image]][docs-link]
![Apache2/MIT licensed][license-image]
![Rust Version][rustc-image]
[![Build Status][build-image]][build-link]
[Poly1305][1] is a [universal hash function][2] which, when combined with a cipher,
can be used as a [Message Authentication Code (MAC)][3].
In practice, Poly1305 is primarily combined with ciphers from the
[Salsa20 Family][4] such as in [ChaCha20Poly1305][5] and [XSalsa20Poly1305][6]
(a.k.a. NaCl `crypto_secretbox`).
[Documentation][docs-link]
## Security Notes
This crate has received one [security audit by NCC Group][7], with no significant
findings. We would like to thank [MobileCoin][8] for funding the audit.
NOTE: the audit predates the AVX2 backend, which has not yet been audited.
All implementations contained in the crate are designed to execute in constant
time, either by relying on hardware intrinsics (e.g. AVX2 on x86/x86_64), or
using a portable implementation which is only constant time on processors which
implement constant-time multiplication.
It is not suitable for use on processors with a variable-time multiplication
operation (e.g. short circuit on multiply-by-zero / multiply-by-one, such as
certain 32-bit PowerPC CPUs and some non-ARM microcontrollers).
## License
Licensed under either of:
* [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)
* [MIT license](http://opensource.org/licenses/MIT)
at your option.
### Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
dual licensed as above, without any additional terms or conditions.
[//]: # (badges)
[crate-image]: https://img.shields.io/crates/v/poly1305.svg
[crate-link]: https://crates.io/crates/poly1305
[docs-image]: https://docs.rs/poly1305/badge.svg
[docs-link]: https://docs.rs/poly1305/
[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg
[rustc-image]: https://img.shields.io/badge/rustc-1.56+-blue.svg
[build-image]: https://github.com/RustCrypto/universal-hashes/workflows/poly1305/badge.svg?branch=master&event=push
[build-link]: https://github.com/RustCrypto/universal-hashes/actions?query=workflow%3Apoly1305
[//]: # (footnotes)
[1]: https://en.wikipedia.org/wiki/Poly1305
[2]: https://en.wikipedia.org/wiki/Universal_hashing
[3]: https://en.wikipedia.org/wiki/Message_authentication_code
[4]: https://cr.yp.to/snuffle/salsafamily-20071225.pdf
[5]: https://github.com/RustCrypto/AEADs/tree/master/chacha20poly1305
[6]: https://github.com/RustCrypto/AEADs/tree/master/xsalsa20poly1305
[7]: https://research.nccgroup.com/2020/02/26/public-report-rustcrypto-aes-gcm-and-chacha20poly1305-implementation-review/
[8]: https://www.mobilecoin.com/

32
vendor/poly1305/benches/poly1305.rs vendored Normal file
View File

@@ -0,0 +1,32 @@
#![feature(test)]
extern crate test;
use poly1305::{
universal_hash::{KeyInit, UniversalHash},
Poly1305,
};
use test::Bencher;
// TODO(tarcieri): move this into the `universal-hash` crate
macro_rules! bench {
($name:ident, $bs:expr) => {
#[bench]
fn $name(b: &mut Bencher) {
let key = Default::default();
let mut m = Poly1305::new(&key);
let data = [0; $bs];
b.iter(|| {
m.update_padded(&data);
});
b.bytes = $bs;
}
};
}
bench!(bench1_10, 10);
bench!(bench2_100, 100);
bench!(bench3_1000, 1000);
bench!(bench3_10000, 10000);

11
vendor/poly1305/fuzz/main.rs vendored Normal file
View File

@@ -0,0 +1,11 @@
#[macro_use]
extern crate afl;
fn main() {
fuzz!(|data: &[u8]| {
// Use first 32 bytes of data as key.
if data.len() >= 32 {
poly1305::fuzz_avx2((&data[0..32]).into(), &data[32..]);
}
});
}

15
vendor/poly1305/src/backend.rs vendored Normal file
View File

@@ -0,0 +1,15 @@
//! Poly1305 backends
#[cfg(all(
any(target_arch = "x86", target_arch = "x86_64"),
not(poly1305_force_soft)
))]
pub(crate) mod avx2;
#[cfg(all(
any(target_arch = "x86", target_arch = "x86_64"),
not(poly1305_force_soft)
))]
pub(crate) mod autodetect;
pub(crate) mod soft;

View File

@@ -0,0 +1,105 @@
//! Autodetection support for AVX2 CPU intrinsics on x86 CPUs, with fallback
//! to the "soft" backend when it's unavailable.
use universal_hash::{consts::U16, crypto_common::BlockSizeUser, UniversalHash};
use crate::{backend, Block, Key, Tag};
use core::mem::ManuallyDrop;
cpufeatures::new!(avx2_cpuid, "avx2");
pub struct State {
inner: Inner,
token: avx2_cpuid::InitToken,
}
union Inner {
avx2: ManuallyDrop<backend::avx2::State>,
soft: ManuallyDrop<backend::soft::State>,
}
impl BlockSizeUser for State {
type BlockSize = U16;
}
impl State {
/// Initialize Poly1305 [`State`] with the given key
#[inline]
pub(crate) fn new(key: &Key) -> State {
let (token, avx2_present) = avx2_cpuid::init_get();
let inner = if avx2_present {
Inner {
avx2: ManuallyDrop::new(backend::avx2::State::new(key)),
}
} else {
Inner {
soft: ManuallyDrop::new(backend::soft::State::new(key)),
}
};
Self { inner, token }
}
/// Compute a Poly1305 block
#[inline]
pub(crate) fn compute_block(&mut self, block: &Block, partial: bool) {
if self.token.get() {
unsafe { (*self.inner.avx2).compute_block(block, partial) }
} else {
unsafe { (*self.inner.soft).compute_block(block, partial) }
}
}
}
impl UniversalHash for State {
fn update_with_backend(
&mut self,
f: impl universal_hash::UhfClosure<BlockSize = Self::BlockSize>,
) {
if self.token.get() {
unsafe { f.call(&mut *self.inner.avx2) }
} else {
unsafe { f.call(&mut *self.inner.soft) }
}
}
/// Finalize output producing a [`Tag`]
#[inline]
fn finalize(mut self) -> Tag {
if self.token.get() {
unsafe { (*self.inner.avx2).finalize() }
} else {
unsafe { (*self.inner.soft).finalize_mut() }
}
}
}
impl Clone for State {
fn clone(&self) -> Self {
let inner = if self.token.get() {
Inner {
avx2: ManuallyDrop::new(unsafe { (*self.inner.avx2).clone() }),
}
} else {
Inner {
soft: ManuallyDrop::new(unsafe { (*self.inner.soft).clone() }),
}
};
Self {
inner,
token: self.token,
}
}
}
#[cfg(feature = "zeroize")]
impl Drop for State {
fn drop(&mut self) {
use zeroize::Zeroize;
const SIZE: usize = core::mem::size_of::<State>();
let state = unsafe { &mut *(self as *mut State as *mut [u8; SIZE]) };
state.zeroize();
}
}

209
vendor/poly1305/src/backend/avx2.rs vendored Normal file
View File

@@ -0,0 +1,209 @@
//! AVX2 implementation of the Poly1305 state machine.
// The State struct and its logic was originally derived from Goll and Gueron's AVX2 C
// code:
// [Vectorization of Poly1305 message authentication code](https://ieeexplore.ieee.org/document/7113463)
//
// which was sourced from Bhattacharyya and Sarkar's modified variant:
// [Improved SIMD Implementation of Poly1305](https://eprint.iacr.org/2019/842)
// https://github.com/Sreyosi/Improved-SIMD-Implementation-of-Poly1305
//
// The logic has been extensively rewritten and documented, and several bugs in the
// original C code were fixed.
//
// Note that State only implements the original Goll-Gueron algorithm, not the
// optimisations provided by Bhattacharyya and Sarkar. The latter require the message
// length to be known, which is incompatible with the streaming API of UniversalHash.
use universal_hash::{
consts::{U16, U4},
crypto_common::{BlockSizeUser, ParBlocksSizeUser},
generic_array::GenericArray,
UhfBackend,
};
use crate::{Block, Key, Tag};
mod helpers;
use self::helpers::*;
/// Four Poly1305 blocks (64-bytes)
type ParBlocks = universal_hash::ParBlocks<State>;
#[derive(Copy, Clone)]
struct Initialized {
p: Aligned4x130,
m: SpacedMultiplier4x130,
r4: PrecomputedMultiplier,
}
#[derive(Clone)]
pub(crate) struct State {
k: AdditionKey,
r1: PrecomputedMultiplier,
r2: PrecomputedMultiplier,
initialized: Option<Initialized>,
cached_blocks: [Block; 4],
num_cached_blocks: usize,
partial_block: Option<Block>,
}
impl State {
/// Initialize Poly1305 [`State`] with the given key
pub(crate) fn new(key: &Key) -> Self {
// Prepare addition key and polynomial key.
let (k, r1) = unsafe { prepare_keys(key) };
// Precompute R^2.
let r2 = (r1 * r1).reduce();
State {
k,
r1,
r2: r2.into(),
initialized: None,
cached_blocks: [Block::default(); 4],
num_cached_blocks: 0,
partial_block: None,
}
}
/// Process four Poly1305 blocks at once.
#[target_feature(enable = "avx2")]
pub(crate) unsafe fn compute_par_blocks(&mut self, blocks: &ParBlocks) {
assert!(self.partial_block.is_none());
assert_eq!(self.num_cached_blocks, 0);
self.process_blocks(Aligned4x130::from_par_blocks(blocks));
}
/// Compute a Poly1305 block
#[target_feature(enable = "avx2")]
pub(crate) unsafe fn compute_block(&mut self, block: &Block, partial: bool) {
// We can cache a single partial block.
if partial {
assert!(self.partial_block.is_none());
self.partial_block = Some(*block);
return;
}
self.cached_blocks[self.num_cached_blocks].copy_from_slice(block);
if self.num_cached_blocks < 3 {
self.num_cached_blocks += 1;
return;
} else {
self.num_cached_blocks = 0;
}
self.process_blocks(Aligned4x130::from_blocks(&self.cached_blocks));
}
/// Compute a Poly1305 block
#[target_feature(enable = "avx2")]
unsafe fn process_blocks(&mut self, blocks: Aligned4x130) {
if let Some(inner) = &mut self.initialized {
// P <-- R^4 * P + blocks
inner.p = (&inner.p * inner.r4).reduce() + blocks;
} else {
// Initialize the polynomial.
let p = blocks;
// Initialize the multiplier (used to merge down the polynomial during
// finalization).
let (m, r4) = SpacedMultiplier4x130::new(self.r1, self.r2);
self.initialized = Some(Initialized { p, m, r4 })
}
}
/// Finalize output producing a [`Tag`]
#[target_feature(enable = "avx2")]
pub(crate) unsafe fn finalize(&mut self) -> Tag {
assert!(self.num_cached_blocks < 4);
let mut data = &self.cached_blocks[..];
// T ← R◦T
// P = T_0 + T_1 + T_2 + T_3
let mut p = self
.initialized
.take()
.map(|inner| (inner.p * inner.m).sum().reduce());
if self.num_cached_blocks >= 2 {
// Compute 32 byte block (remaining data < 64 bytes)
let mut c = Aligned2x130::from_blocks(data[..2].try_into().unwrap());
if let Some(p) = p {
c = c + p;
}
p = Some(c.mul_and_sum(self.r1, self.r2).reduce());
data = &data[2..];
self.num_cached_blocks -= 2;
}
if self.num_cached_blocks == 1 {
// Compute 16 byte block (remaining data < 32 bytes)
let mut c = Aligned130::from_block(&data[0]);
if let Some(p) = p {
c = c + p;
}
p = Some((c * self.r1).reduce());
self.num_cached_blocks -= 1;
}
if let Some(block) = &self.partial_block {
// Compute last block (remaining data < 16 bytes)
let mut c = Aligned130::from_partial_block(block);
if let Some(p) = p {
c = c + p;
}
p = Some((c * self.r1).reduce());
}
// Compute tag: p + k mod 2^128
let mut tag = GenericArray::<u8, _>::default();
let tag_int = if let Some(p) = p {
self.k + p
} else {
self.k.into()
};
tag_int.write(tag.as_mut_slice());
tag
}
}
impl BlockSizeUser for State {
type BlockSize = U16;
}
impl ParBlocksSizeUser for State {
type ParBlocksSize = U4;
}
impl UhfBackend for State {
fn proc_block(&mut self, block: &Block) {
unsafe { self.compute_block(block, false) };
}
fn proc_par_blocks(&mut self, blocks: &ParBlocks) {
if self.num_cached_blocks == 0 {
// Fast path.
unsafe { self.compute_par_blocks(blocks) };
} else {
// We are unaligned; use the slow fallback.
for block in blocks {
self.proc_block(block);
}
}
}
fn blocks_needed_to_align(&self) -> usize {
if self.num_cached_blocks == 0 {
// There are no cached blocks; fast path is available.
0
} else {
// There are cached blocks; report how many more we need.
self.cached_blocks.len() - self.num_cached_blocks
}
}
}

File diff suppressed because it is too large Load Diff

271
vendor/poly1305/src/backend/soft.rs vendored Normal file
View File

@@ -0,0 +1,271 @@
//! Software implementation of the Poly1305 state machine.
// 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. This file may not be copied, modified, or distributed
// except according to those terms.
//
// This code originates from the rust-crypto project:
// <https://github.com/DaGenix/rust-crypto>
//
// ...and was originally a port of Andrew Moons poly1305-donna
// https://github.com/floodyberry/poly1305-donna
use universal_hash::{
consts::{U1, U16},
crypto_common::{BlockSizeUser, ParBlocksSizeUser},
UhfBackend, UniversalHash,
};
use crate::{Block, Key, Tag};
#[derive(Clone, Default)]
pub(crate) struct State {
r: [u32; 5],
h: [u32; 5],
pad: [u32; 4],
}
impl State {
/// Initialize Poly1305 [`State`] with the given key
pub(crate) fn new(key: &Key) -> State {
let mut poly = State::default();
// r &= 0xffffffc0ffffffc0ffffffc0fffffff
poly.r[0] = (u32::from_le_bytes(key[0..4].try_into().unwrap())) & 0x3ff_ffff;
poly.r[1] = (u32::from_le_bytes(key[3..7].try_into().unwrap()) >> 2) & 0x3ff_ff03;
poly.r[2] = (u32::from_le_bytes(key[6..10].try_into().unwrap()) >> 4) & 0x3ff_c0ff;
poly.r[3] = (u32::from_le_bytes(key[9..13].try_into().unwrap()) >> 6) & 0x3f0_3fff;
poly.r[4] = (u32::from_le_bytes(key[12..16].try_into().unwrap()) >> 8) & 0x00f_ffff;
poly.pad[0] = u32::from_le_bytes(key[16..20].try_into().unwrap());
poly.pad[1] = u32::from_le_bytes(key[20..24].try_into().unwrap());
poly.pad[2] = u32::from_le_bytes(key[24..28].try_into().unwrap());
poly.pad[3] = u32::from_le_bytes(key[28..32].try_into().unwrap());
poly
}
/// Compute a Poly1305 block
pub(crate) fn compute_block(&mut self, block: &Block, partial: bool) {
let hibit = if partial { 0 } else { 1 << 24 };
let r0 = self.r[0];
let r1 = self.r[1];
let r2 = self.r[2];
let r3 = self.r[3];
let r4 = self.r[4];
let s1 = r1 * 5;
let s2 = r2 * 5;
let s3 = r3 * 5;
let s4 = r4 * 5;
let mut h0 = self.h[0];
let mut h1 = self.h[1];
let mut h2 = self.h[2];
let mut h3 = self.h[3];
let mut h4 = self.h[4];
// h += m
h0 += (u32::from_le_bytes(block[0..4].try_into().unwrap())) & 0x3ff_ffff;
h1 += (u32::from_le_bytes(block[3..7].try_into().unwrap()) >> 2) & 0x3ff_ffff;
h2 += (u32::from_le_bytes(block[6..10].try_into().unwrap()) >> 4) & 0x3ff_ffff;
h3 += (u32::from_le_bytes(block[9..13].try_into().unwrap()) >> 6) & 0x3ff_ffff;
h4 += (u32::from_le_bytes(block[12..16].try_into().unwrap()) >> 8) | hibit;
// h *= r
let d0 = (u64::from(h0) * u64::from(r0))
+ (u64::from(h1) * u64::from(s4))
+ (u64::from(h2) * u64::from(s3))
+ (u64::from(h3) * u64::from(s2))
+ (u64::from(h4) * u64::from(s1));
let mut d1 = (u64::from(h0) * u64::from(r1))
+ (u64::from(h1) * u64::from(r0))
+ (u64::from(h2) * u64::from(s4))
+ (u64::from(h3) * u64::from(s3))
+ (u64::from(h4) * u64::from(s2));
let mut d2 = (u64::from(h0) * u64::from(r2))
+ (u64::from(h1) * u64::from(r1))
+ (u64::from(h2) * u64::from(r0))
+ (u64::from(h3) * u64::from(s4))
+ (u64::from(h4) * u64::from(s3));
let mut d3 = (u64::from(h0) * u64::from(r3))
+ (u64::from(h1) * u64::from(r2))
+ (u64::from(h2) * u64::from(r1))
+ (u64::from(h3) * u64::from(r0))
+ (u64::from(h4) * u64::from(s4));
let mut d4 = (u64::from(h0) * u64::from(r4))
+ (u64::from(h1) * u64::from(r3))
+ (u64::from(h2) * u64::from(r2))
+ (u64::from(h3) * u64::from(r1))
+ (u64::from(h4) * u64::from(r0));
// (partial) h %= p
let mut c: u32;
c = (d0 >> 26) as u32;
h0 = d0 as u32 & 0x3ff_ffff;
d1 += u64::from(c);
c = (d1 >> 26) as u32;
h1 = d1 as u32 & 0x3ff_ffff;
d2 += u64::from(c);
c = (d2 >> 26) as u32;
h2 = d2 as u32 & 0x3ff_ffff;
d3 += u64::from(c);
c = (d3 >> 26) as u32;
h3 = d3 as u32 & 0x3ff_ffff;
d4 += u64::from(c);
c = (d4 >> 26) as u32;
h4 = d4 as u32 & 0x3ff_ffff;
h0 += c * 5;
c = h0 >> 26;
h0 &= 0x3ff_ffff;
h1 += c;
self.h[0] = h0;
self.h[1] = h1;
self.h[2] = h2;
self.h[3] = h3;
self.h[4] = h4;
}
/// Finalize output producing a [`Tag`]
pub(crate) fn finalize_mut(&mut self) -> Tag {
// fully carry h
let mut h0 = self.h[0];
let mut h1 = self.h[1];
let mut h2 = self.h[2];
let mut h3 = self.h[3];
let mut h4 = self.h[4];
let mut c: u32;
c = h1 >> 26;
h1 &= 0x3ff_ffff;
h2 += c;
c = h2 >> 26;
h2 &= 0x3ff_ffff;
h3 += c;
c = h3 >> 26;
h3 &= 0x3ff_ffff;
h4 += c;
c = h4 >> 26;
h4 &= 0x3ff_ffff;
h0 += c * 5;
c = h0 >> 26;
h0 &= 0x3ff_ffff;
h1 += c;
// compute h + -p
let mut g0 = h0.wrapping_add(5);
c = g0 >> 26;
g0 &= 0x3ff_ffff;
let mut g1 = h1.wrapping_add(c);
c = g1 >> 26;
g1 &= 0x3ff_ffff;
let mut g2 = h2.wrapping_add(c);
c = g2 >> 26;
g2 &= 0x3ff_ffff;
let mut g3 = h3.wrapping_add(c);
c = g3 >> 26;
g3 &= 0x3ff_ffff;
let mut g4 = h4.wrapping_add(c).wrapping_sub(1 << 26);
// select h if h < p, or h + -p if h >= p
let mut mask = (g4 >> (32 - 1)).wrapping_sub(1);
g0 &= mask;
g1 &= mask;
g2 &= mask;
g3 &= mask;
g4 &= mask;
mask = !mask;
h0 = (h0 & mask) | g0;
h1 = (h1 & mask) | g1;
h2 = (h2 & mask) | g2;
h3 = (h3 & mask) | g3;
h4 = (h4 & mask) | g4;
// h = h % (2^128)
h0 |= h1 << 26;
h1 = (h1 >> 6) | (h2 << 20);
h2 = (h2 >> 12) | (h3 << 14);
h3 = (h3 >> 18) | (h4 << 8);
// h = mac = (h + pad) % (2^128)
let mut f: u64;
f = u64::from(h0) + u64::from(self.pad[0]);
h0 = f as u32;
f = u64::from(h1) + u64::from(self.pad[1]) + (f >> 32);
h1 = f as u32;
f = u64::from(h2) + u64::from(self.pad[2]) + (f >> 32);
h2 = f as u32;
f = u64::from(h3) + u64::from(self.pad[3]) + (f >> 32);
h3 = f as u32;
let mut tag = Block::default();
tag[0..4].copy_from_slice(&h0.to_le_bytes());
tag[4..8].copy_from_slice(&h1.to_le_bytes());
tag[8..12].copy_from_slice(&h2.to_le_bytes());
tag[12..16].copy_from_slice(&h3.to_le_bytes());
tag
}
}
#[cfg(feature = "zeroize")]
impl Drop for State {
fn drop(&mut self) {
use zeroize::Zeroize;
self.r.zeroize();
self.h.zeroize();
self.pad.zeroize();
}
}
impl BlockSizeUser for State {
type BlockSize = U16;
}
impl ParBlocksSizeUser for State {
type ParBlocksSize = U1;
}
impl UhfBackend for State {
fn proc_block(&mut self, block: &Block) {
self.compute_block(block, false);
}
}
impl UniversalHash for State {
fn update_with_backend(
&mut self,
f: impl universal_hash::UhfClosure<BlockSize = Self::BlockSize>,
) {
f.call(self);
}
/// Finalize output producing a [`Tag`]
fn finalize(mut self) -> Tag {
self.finalize_mut()
}
}

190
vendor/poly1305/src/fuzz.rs vendored Normal file
View File

@@ -0,0 +1,190 @@
use universal_hash::{generic_array::GenericArray, UniversalHash};
use crate::{backend, Block, Key, BLOCK_SIZE};
/// Helper function for fuzzing the AVX2 backend.
pub fn fuzz_avx2(key: &Key, data: &[u8]) {
let mut avx2 = backend::avx2::State::new(key);
let mut soft = backend::soft::State::new(key);
for (_i, chunk) in data.chunks(BLOCK_SIZE).enumerate() {
if chunk.len() == BLOCK_SIZE {
let block = GenericArray::from_slice(chunk);
unsafe {
avx2.compute_block(block, false);
}
soft.compute_block(block, false);
} else {
let mut block = Block::default();
block[..chunk.len()].copy_from_slice(chunk);
block[chunk.len()] = 1;
unsafe {
avx2.compute_block(&block, true);
}
soft.compute_block(&block, true);
}
// Check that the same tag would be derived after each chunk.
// We add the chunk number to the assertion for debugging.
// When fuzzing, we skip this check, and just look at the end.
#[cfg(test)]
assert_eq!(
(_i + 1, unsafe { avx2.clone().finalize() }),
(_i + 1, soft.clone().finalize()),
);
}
assert_eq!(unsafe { avx2.finalize() }, soft.finalize());
}
fn avx2_fuzzer_test_case(data: &[u8]) {
fuzz_avx2(data[0..32].into(), &data[32..]);
}
#[test]
fn crash_0() {
avx2_fuzzer_test_case(include_bytes!(
"fuzz/id=000000,sig=06,src=000014,op=flip4,pos=11"
));
}
#[test]
fn crash_1() {
avx2_fuzzer_test_case(include_bytes!(
"fuzz/id=000001,sig=06,src=000006+000014,op=splice,rep=64"
));
}
#[test]
fn crash_2() {
avx2_fuzzer_test_case(include_bytes!(
"fuzz/id=000002,sig=06,src=000008+000014,op=splice,rep=32"
));
}
#[test]
fn crash_3() {
// This input corresponds to a key of:
// r = 0x0f245bfc0f7fe5fc0fffff3400fb1c2b
// s = 0xffffff000001000040f6fff5ffffffff
//
// and input blocks:
// [0x01ea0010000a00ff108b72ffffffffffff, 0x01ffffffff245b74ff7fe5ffffff0040ff,
// 0x01000a00ff108b7200ff04000002ffffff, 0x01ffffffffffffffffffff0000ffea0010,
// 0x0180ffffffffffffffffffffffe3ffffff, 0x01ffffffffffffffffffffffffffffffff,
// 0x01ffffffffffffffffffdfffff03ffffff, 0x01ffffffffff245b74ff7fe5ffffe4ffff,
// 0x0112118b7d00ffeaffffffffffffffffff, 0x010e40eb10ffffffff1edd7f0010000a00]
//
// When this crash occurred, the software and AVX2 backends would generate the same
// tags given the first seven blocks as input. Given the first eight blocks, the
// following tags were generated:
//
// | tag | low 128 bits of final accumulator
// soft | 0x0004d01b9168ded528a9b541cc461988 - s = 0x0004d11b9167ded4e7b2b54bcc461989
// avx2 | 0x0004d01b9168ded528a9b540cc461988 - s = 0x0004d11b9167ded4e7b2b54acc461989
// difference = 0x0100000000
//
// This discrepancy was due to Unreduced130::reduce (as called during finalization)
// not correctly reducing. During the reduction step, the upper limb's upper bits
// (beyond 2^130) are added into the lower limb multiplied by 5 (for reduction modulo
// 2^130 - 5). This is computed like so:
//
// b = t_4 >> 26
// t_0 += b + (b << 2)
//
// It is possible for the upper limb to be 57+ bits; thus b << 2 can be 33+ bits.
// However, the original reduction code was using _mm256_slli_epi32, which shifts
// packed 32-bit integers; this was causing the upper bits of b to be lost. Switching
// to _mm256_slli_epi64 (correctly treating b as a 64-bit field) solves the problem.
avx2_fuzzer_test_case(include_bytes!(
"fuzz/id=000003,sig=06,src=000003,op=havoc,rep=64"
));
}
#[test]
fn crash_4() {
avx2_fuzzer_test_case(include_bytes!(
"fuzz/id=000004,sig=06,src=000022+000005,op=splice,rep=32"
));
}
#[test]
fn crash_5() {
avx2_fuzzer_test_case(include_bytes!(
"fuzz/id=000005,sig=06,src=000008+000007,op=splice,rep=128"
));
}
#[test]
fn crash_6() {
// This input corresponds to a key of:
// r = 0x04040404040404040404040404040404
// s = 0x0404040403ef04040404040404040404
//
// and input:
// [0x04, 0x04, 0x04, 0xf2]
//
// The input fits into a single short block:
// m = 0x01f2040404
//
// and we should have the following computation:
// tag = ((m * r) % p) + s
// = ((0x01f2040404 * 0x04040404040404040404040404040404) % p) + s
// = (0x7cfdfeffffffffffffffffffffffffff8302010 % ((1 << 130) - 5)) + s
// = 0x1f3f7fc + 0x0404040403ef04040404040404040404
// = 0x0404040403ef04040404040405f7fc00
//
// or in bytes:
// tag = [
// 0x00, 0xfc, 0xf7, 0x05, 0x04, 0x04, 0x04, 0x04,
// 0x04, 0x04, 0xef, 0x03, 0x04, 0x04, 0x04, 0x04,
// ];
//
// The crash was caused by the final modular reduction (in the `addkey` method of the
// Goll-Gueron implementation, and `impl Add<Aligned130> for AdditionKey` here) not
// fully carrying all bits. `Aligned130` is guaranteed to be a 130-bit integer, but is
// not guaranteed to be an integer modulo 2^130 - 5.
avx2_fuzzer_test_case(include_bytes!(
"fuzz/id=000006,sig=06,src=000005,op=havoc,rep=8"
));
}
#[test]
fn crash_7() {
avx2_fuzzer_test_case(include_bytes!(
"fuzz/id=000007,sig=06,src=000024+000000,op=splice,rep=64"
));
}
#[test]
fn crash_8() {
// This input corresponds to a key of:
// r = 0x0fff00fc0000000000000000006f91ab
// s = 0xffffffffffffffffffffffffffffffff
//
// and a single input block:
// 0x01d4d4ffffffffffffffffffffffffffff
//
// We should have the following computation:
// tag = ((m * r) % p) + s
// = ((0x01d4d4ffffffffffffffffffffffffffff * 0x0fff00fc0000000000000000006f91ab) % p) + s
// = (0x1d4b7cf881ac00000000000000cc5320bf47ff03ffffffffffffffffff906e55 % ((1 << 130) - 5)) + s
// = 0xe3e65b3aa217000000000000008fd63d + 0xffffffffffffffffffffffffffffffff
// = 0x01e3e65b3aa217000000000000008fd63c mod 128
//
// or in bytes:
// tag = [
// 0x3c, 0xd6, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00,
// 0x00, 0x00, 0x17, 0xa2, 0x3a, 0x5b, 0xe6, 0xe3,
// ];
//
// The crash was caused by the final modular reduction (in the `addkey` method of the
// Goll-Gueron implementation, and `impl Add<Aligned130> for AdditionKey` here). After
// adding s, limbs 0 and 2 have carries, while limb 1 is 0xffffffff. The original
// implementation only carried once, after which limb 1 has a carry, which was then
// discarded. The fix was to always carry three times, to ensure that all potential
// carry bits are carried.
avx2_fuzzer_test_case(include_bytes!(
"fuzz/id=000008,sig=06,src=000019,time=165655+000011,op=splice,rep=128"
));
}

View File

@@ -0,0 +1 @@
<01><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>

View File

@@ -0,0 +1 @@
ος

171
vendor/poly1305/src/lib.rs vendored Normal file
View File

@@ -0,0 +1,171 @@
//! The Poly1305 universal hash function and message authentication code.
//!
//! # About
//!
//! Poly1305 is a universal hash function suitable for use as a one-time
//! authenticator and, when combined with a cipher, a message authentication
//! code (MAC).
//!
//! It takes a 32-byte one-time key and a message and produces a 16-byte tag,
//! which can be used to authenticate the message.
//!
//! Poly1305 is primarily notable for its use in the [`ChaCha20Poly1305`] and
//! [`XSalsa20Poly1305`] authenticated encryption algorithms.
//!
//! # Minimum Supported Rust Version
//!
//! Rust **1.56** or higher.
//!
//! Minimum supported Rust version may be changed in the future, but such
//! changes will be accompanied with a minor version bump.
//!
//! # Security Notes
//!
//! This crate has received one [security audit by NCC Group][audit], with no
//! significant findings. We would like to thank [MobileCoin] for funding the
//! audit.
//!
//! NOTE: the audit predates the AVX2 backend, which has not yet been audited.
//!
//! All implementations contained in the crate are designed to execute in constant
//! time, either by relying on hardware intrinsics (e.g. AVX2 on x86/x86_64), or
//! using a portable implementation which is only constant time on processors which
//! implement constant-time multiplication.
//!
//! It is not suitable for use on processors with a variable-time multiplication
//! operation (e.g. short circuit on multiply-by-zero / multiply-by-one, such as
//! certain 32-bit PowerPC CPUs and some non-ARM microcontrollers).
//!
//! [`ChaCha20Poly1305`]: https://docs.rs/chacha20poly1305
//! [`XSalsa20Poly1305`]: https://docs.rs/xsalsa20poly1305
//! [audit]: https://research.nccgroup.com/2020/02/26/public-report-rustcrypto-aes-gcm-and-chacha20poly1305-implementation-review/
//! [MobileCoin]: https://mobilecoin.com
#![no_std]
#![doc(
html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg",
html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg"
)]
#![warn(missing_docs, rust_2018_idioms)]
#[cfg(feature = "std")]
extern crate std;
pub use universal_hash;
use universal_hash::{
consts::{U16, U32},
crypto_common::{BlockSizeUser, KeySizeUser},
generic_array::GenericArray,
KeyInit, UniversalHash,
};
mod backend;
#[cfg(all(
any(target_arch = "x86", target_arch = "x86_64"),
not(poly1305_force_soft),
target_feature = "avx2", // Fuzz tests bypass AVX2 autodetection code
any(fuzzing, test)
))]
mod fuzz;
#[cfg(all(
any(target_arch = "x86", target_arch = "x86_64"),
not(poly1305_force_soft)
))]
use crate::backend::autodetect::State;
#[cfg(not(all(
any(target_arch = "x86", target_arch = "x86_64"),
not(poly1305_force_soft)
)))]
use crate::backend::soft::State;
/// Size of a Poly1305 key
pub const KEY_SIZE: usize = 32;
/// Size of the blocks Poly1305 acts upon
pub const BLOCK_SIZE: usize = 16;
/// Poly1305 keys (32-bytes)
pub type Key = universal_hash::Key<Poly1305>;
/// Poly1305 blocks (16-bytes)
pub type Block = universal_hash::Block<Poly1305>;
/// Poly1305 tags (16-bytes)
pub type Tag = universal_hash::Block<Poly1305>;
/// The Poly1305 universal hash function.
///
/// Note that Poly1305 is not a traditional MAC and is single-use only
/// (a.k.a. "one-time authenticator").
///
/// For this reason it doesn't impl the `crypto_mac::Mac` trait.
#[derive(Clone)]
pub struct Poly1305 {
state: State,
}
impl KeySizeUser for Poly1305 {
type KeySize = U32;
}
impl KeyInit for Poly1305 {
/// Initialize Poly1305 with the given key
fn new(key: &Key) -> Poly1305 {
Poly1305 {
state: State::new(key),
}
}
}
impl BlockSizeUser for Poly1305 {
type BlockSize = U16;
}
impl UniversalHash for Poly1305 {
fn update_with_backend(
&mut self,
f: impl universal_hash::UhfClosure<BlockSize = Self::BlockSize>,
) {
self.state.update_with_backend(f);
}
/// Get the hashed output
fn finalize(self) -> Tag {
self.state.finalize()
}
}
impl Poly1305 {
/// Compute unpadded Poly1305 for the given input data.
///
/// The main use case for this is XSalsa20Poly1305.
pub fn compute_unpadded(mut self, data: &[u8]) -> Tag {
for chunk in data.chunks(BLOCK_SIZE) {
if chunk.len() == BLOCK_SIZE {
let block = GenericArray::from_slice(chunk);
self.state.compute_block(block, false);
} else {
let mut block = Block::default();
block[..chunk.len()].copy_from_slice(chunk);
block[chunk.len()] = 1;
self.state.compute_block(&block, true)
}
}
self.state.finalize()
}
}
opaque_debug::implement!(Poly1305);
#[cfg(all(
any(target_arch = "x86", target_arch = "x86_64"),
not(poly1305_force_soft),
target_feature = "avx2", // Fuzz tests bypass AVX2 autodetection code
any(fuzzing, test)
))]
pub use crate::fuzz::fuzz_avx2;

Binary file not shown.

View File

@@ -0,0 +1 @@
{"name":"poly1305","vers":"0.8.0","deps":[{"name":"opaque-debug","req":"^0.3","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":"universal-hash","req":"^0.5","features":[],"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":"zeroize","req":"^1","features":[],"optional":true,"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":"hex-literal","req":"^0.3","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},{"name":"cpufeatures","req":"^0.2","features":[],"optional":false,"default_features":true,"target":"cfg(any(target_arch = \"x86_64\", target_arch = \"x86\"))","kind":"normal","registry":"https://github.com/rust-lang/crates.io-index","package":null,"public":null,"artifact":null,"bindep_target":null,"lib":false}],"features":{"std":["universal-hash/std"]},"features2":null,"cksum":"d81be9ac82bfb169b4f90d197f79cf29e49f8af3863e21caf885d4f8cee30749","yanked":null,"links":null,"rust_version":null,"v":2}

Binary file not shown.

108
vendor/poly1305/tests/lib.rs vendored Normal file
View File

@@ -0,0 +1,108 @@
use hex_literal::hex;
use poly1305::{
universal_hash::{KeyInit, UniversalHash},
Block, Poly1305, BLOCK_SIZE, KEY_SIZE,
};
use std::iter::repeat;
#[test]
fn test_nacl_vector() {
let key = hex!("eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa4c8cff880");
let msg = hex!(
"8e993b9f48681273c29650ba32fc76ce
48332ea7164d96a4476fb8c531a1186a
c0dfc17c98dce87b4da7f011ec48c972
71d2c20f9b928fe2270d6fb863d51738
b48eeee314a7cc8ab932164548e526ae
90224368517acfeabd6bb3732bc0e9da
99832b61ca01b6de56244a9e88d5f9b3
7973f622a43d14a6599b1f654cb45a74
e355a5"
);
let expected = hex!("f3ffc7703f9400e52a7dfb4b3d3305d9");
let result1 = Poly1305::new(key.as_ref().into()).compute_unpadded(&msg);
assert_eq!(&expected[..], result1.as_slice());
}
#[test]
fn donna_self_test1() {
// This gives r = 2 and s = 0.
let key = hex!("0200000000000000000000000000000000000000000000000000000000000000");
// This results in a 130-bit integer with the lower 129 bits all set: m = (1 << 129) - 1
let msg = hex!("ffffffffffffffffffffffffffffffff");
// The input is a single block, so we should have the following computation:
// tag = ((m * r) % p) + s
// = ((((1 << 129) - 1) * 2) % p) + 0
// = ((1 << 130) - 2) % (1 << 130) - 5
// = 3
let expected = hex!("03000000000000000000000000000000");
let mut poly = Poly1305::new(key.as_ref().into());
poly.update(&[Block::clone_from_slice(msg.as_ref())]);
assert_eq!(&expected[..], poly.finalize().as_slice());
}
#[test]
fn donna_self_test2() {
let total_key = hex!("01020304050607fffefdfcfbfaf9ffffffffffffffffffffffffffff00000000");
let total_mac = hex!("64afe2e8d6ad7bbdd287f97c44623d39");
let mut tpoly = Poly1305::new(total_key.as_ref().into());
for i in 0..256 {
let mut key = [0u8; KEY_SIZE];
key.copy_from_slice(&repeat(i as u8).take(KEY_SIZE).collect::<Vec<_>>());
let msg: Vec<u8> = repeat(i as u8).take(256).collect();
let tag = Poly1305::new(key.as_ref().into()).compute_unpadded(&msg[..i]);
tpoly.update(&[tag.into()]);
}
assert_eq!(&total_mac[..], tpoly.finalize().as_slice());
}
#[test]
fn test_tls_vectors() {
// from http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-04
let key = b"this is 32-byte key for Poly1305";
let msg = [0u8; 32];
let expected = hex!("49ec78090e481ec6c26b33b91ccc0307");
let mut poly = Poly1305::new(key.as_ref().into());
let blocks = msg
.chunks(BLOCK_SIZE)
.map(|chunk| Block::clone_from_slice(chunk))
.collect::<Vec<_>>();
poly.update(&blocks);
assert_eq!(&expected[..], poly.finalize().as_slice());
}
#[test]
fn test_rfc7539_vector() {
// From <https://tools.ietf.org/html/rfc7539#section-2.5.2>
let key = hex!("85d6be7857556d337f4452fe42d506a80103808afb0db2fd4abff6af4149f51b");
let msg = hex!("43727970746f6772617068696320466f72756d2052657365617263682047726f7570");
let expected = hex!("a8061dc1305136c6c22b8baf0c0127a9");
let result = Poly1305::new(key.as_ref().into()).compute_unpadded(&msg);
assert_eq!(&expected[..], result.as_slice());
}
#[test]
fn padded_input() {
// poly1305 key and AAD from <https://tools.ietf.org/html/rfc8439#section-2.8.2>
let key = hex!("7bac2b252db447af09b67a55a4e955840ae1d6731075d9eb2a9375783ed553ff");
let msg = hex!("50515253c0c1c2c3c4c5c6c7");
let expected = hex!("ada56caa480fe6f5067039244a3d76ba");
let mut poly = Poly1305::new(key.as_ref().into());
poly.update_padded(&msg);
assert_eq!(&expected[..], poly.finalize().as_slice());
}