mirror of
https://github.com/RustCrypto/hashes.git
synced 2026-01-25 04:18:20 +00:00
First commit
This commit is contained in:
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
*/target/
|
||||
*/*/target/
|
||||
Cargo.lock
|
||||
25
README.md
Normal file
25
README.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# rust-crypto's hashes
|
||||
Collection of cryptographic hash functions written in pure Rust. This is the part
|
||||
of the rust-crypto project.
|
||||
|
||||
## Contributions
|
||||
|
||||
Contributions are extremely welcome. The most significant needs are help adding
|
||||
documentation, implementing new algorithms, and general cleanup and improvement
|
||||
of the code. By submitting a pull request you are agreeing to make you work
|
||||
available under the license terms of the Rust-Crypto project.
|
||||
|
||||
## License
|
||||
|
||||
Rust-Crypto is dual licensed under the MIT and Apache 2.0 licenses, the same licenses
|
||||
as the Rust compiler.
|
||||
|
||||
## Supported algorithms
|
||||
* BLAKE2
|
||||
* MD4
|
||||
* MD5
|
||||
* SHA-1
|
||||
* SHA-2
|
||||
* SHA-3
|
||||
* RIPEMD-160
|
||||
* Whirlpool
|
||||
19
blake2/Cargo.toml
Normal file
19
blake2/Cargo.toml
Normal file
@@ -0,0 +1,19 @@
|
||||
[package]
|
||||
name = "blake2"
|
||||
version = "0.2.0"
|
||||
authors = ["The Rust-Crypto Project Developers"]
|
||||
license = "MIT/Apache-2.0"
|
||||
description = "BLAKE2 hash functions"
|
||||
documentation = "https://docs.rs/blake2"
|
||||
repository = "https://github.com/RustCrypto/hashes"
|
||||
keywords = ["crypto", "blake2", "hash", "digest"]
|
||||
|
||||
[dependencies]
|
||||
byte-tools = "0.1"
|
||||
digest = "0.2"
|
||||
generic-array = "0.5"
|
||||
crypto-ops = "0.1"
|
||||
#crypto-mac = {path = "../../../rust-crypto-decoupled/utils/crypto-mac/"}
|
||||
|
||||
[dev-dependencies]
|
||||
crypto-tests = "0.1"
|
||||
201
blake2/LICENSE-APACHE
Normal file
201
blake2/LICENSE-APACHE
Normal 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.
|
||||
27
blake2/LICENSE-MIT
Normal file
27
blake2/LICENSE-MIT
Normal file
@@ -0,0 +1,27 @@
|
||||
Copyright (c) 2006-2009 Graydon Hoare
|
||||
Copyright (c) 2009-2013 Mozilla Foundation
|
||||
Copyright (c) 2016 Artyom Pavlov
|
||||
|
||||
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
blake2/benches/lib.rs
Normal file
69
blake2/benches/lib.rs
Normal file
@@ -0,0 +1,69 @@
|
||||
#![no_std]
|
||||
#![feature(test)]
|
||||
extern crate test;
|
||||
extern crate blake2;
|
||||
extern crate digest;
|
||||
|
||||
use test::Bencher;
|
||||
use digest::Digest;
|
||||
use blake2::{Blake2b512, Blake2s256};
|
||||
|
||||
#[bench]
|
||||
pub fn blake2b_10(bh: &mut Bencher) {
|
||||
let mut sh = Blake2b512::new();
|
||||
let bytes = [1u8; 10];
|
||||
bh.iter(|| {
|
||||
sh.input(&bytes);
|
||||
});
|
||||
bh.bytes = bytes.len() as u64;
|
||||
}
|
||||
|
||||
#[bench]
|
||||
pub fn blake2b_1k(bh: &mut Bencher) {
|
||||
let mut sh = Blake2b512::new();
|
||||
let bytes = [1u8; 1024];
|
||||
bh.iter(|| {
|
||||
sh.input(&bytes);
|
||||
});
|
||||
bh.bytes = bytes.len() as u64;
|
||||
}
|
||||
|
||||
#[bench]
|
||||
pub fn blake2b_64k(bh: &mut Bencher) {
|
||||
let mut sh = Blake2b512::new();
|
||||
let bytes = [1u8; 65536];
|
||||
bh.iter(|| {
|
||||
sh.input(&bytes);
|
||||
});
|
||||
bh.bytes = bytes.len() as u64;
|
||||
}
|
||||
|
||||
#[bench]
|
||||
pub fn blake2s_10(bh: &mut Bencher) {
|
||||
let mut sh = Blake2s256::new();
|
||||
let bytes = [1u8; 10];
|
||||
bh.iter(|| {
|
||||
sh.input(&bytes);
|
||||
});
|
||||
bh.bytes = bytes.len() as u64;
|
||||
}
|
||||
|
||||
#[bench]
|
||||
pub fn blake2s_1k(bh: &mut Bencher) {
|
||||
let mut sh = Blake2s256::new();
|
||||
let bytes = [1u8; 1024];
|
||||
bh.iter(|| {
|
||||
sh.input(&bytes);
|
||||
});
|
||||
bh.bytes = bytes.len() as u64;
|
||||
}
|
||||
|
||||
#[bench]
|
||||
pub fn blake2s_64k(bh: &mut Bencher) {
|
||||
let mut sh = Blake2s256::new();
|
||||
let bytes = [1u8; 65536];
|
||||
bh.iter(|| {
|
||||
sh.input(&bytes);
|
||||
});
|
||||
bh.bytes = bytes.len() as u64;
|
||||
}
|
||||
49
blake2/examples/blake2b512sum.rs
Normal file
49
blake2/examples/blake2b512sum.rs
Normal file
@@ -0,0 +1,49 @@
|
||||
extern crate blake2;
|
||||
|
||||
use blake2::{Blake2b512, Digest};
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use std::io::{self, Read};
|
||||
|
||||
const BUFFER_SIZE: usize = 1024;
|
||||
|
||||
/// Print digest result as hex string and name pair
|
||||
fn print_result(sum: &[u8], name: &str) {
|
||||
for byte in sum {
|
||||
print!("{:02x}", byte);
|
||||
}
|
||||
println!("\t{}", name);
|
||||
}
|
||||
|
||||
/// Compute digest value for given `Reader` and print it
|
||||
/// On any error simply return without doing anything
|
||||
fn process<D: Digest, R: Read>(reader: &mut R, name: &str) {
|
||||
let mut sh = D::new();
|
||||
let mut buffer = [0u8; BUFFER_SIZE];
|
||||
loop {
|
||||
let n = match reader.read(&mut buffer) {
|
||||
Ok(n) => n,
|
||||
Err(_) => return,
|
||||
};
|
||||
sh.input(&buffer[..n]);
|
||||
if n == 0 || n < BUFFER_SIZE {
|
||||
break;
|
||||
}
|
||||
}
|
||||
print_result(&sh.result(), name);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let args = env::args();
|
||||
// Process files listed in command line arguments one by one
|
||||
// If no files provided process input from stdin
|
||||
if args.len() > 1 {
|
||||
for path in args.skip(1) {
|
||||
if let Ok(mut file) = fs::File::open(&path) {
|
||||
process::<Blake2b512, _>(&mut file, &path);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
process::<Blake2b512, _>(&mut io::stdin(), "-");
|
||||
}
|
||||
}
|
||||
49
blake2/examples/blake2s256sum.rs
Normal file
49
blake2/examples/blake2s256sum.rs
Normal file
@@ -0,0 +1,49 @@
|
||||
extern crate blake2;
|
||||
|
||||
use blake2::{Blake2s256, Digest};
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use std::io::{self, Read};
|
||||
|
||||
const BUFFER_SIZE: usize = 1024;
|
||||
|
||||
/// Print digest result as hex string and name pair
|
||||
fn print_result(sum: &[u8], name: &str) {
|
||||
for byte in sum {
|
||||
print!("{:02x}", byte);
|
||||
}
|
||||
println!("\t{}", name);
|
||||
}
|
||||
|
||||
/// Compute digest value for given `Reader` and print it
|
||||
/// On any error simply return without doing anything
|
||||
fn process<D: Digest, R: Read>(reader: &mut R, name: &str) {
|
||||
let mut sh = D::new();
|
||||
let mut buffer = [0u8; BUFFER_SIZE];
|
||||
loop {
|
||||
let n = match reader.read(&mut buffer) {
|
||||
Ok(n) => n,
|
||||
Err(_) => return,
|
||||
};
|
||||
sh.input(&buffer[..n]);
|
||||
if n == 0 || n < BUFFER_SIZE {
|
||||
break;
|
||||
}
|
||||
}
|
||||
print_result(&sh.result(), name);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let args = env::args();
|
||||
// Process files listed in command line arguments one by one
|
||||
// If no files provided process input from stdin
|
||||
if args.len() > 1 {
|
||||
for path in args.skip(1) {
|
||||
if let Ok(mut file) = fs::File::open(&path) {
|
||||
process::<Blake2s256, _>(&mut file, &path);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
process::<Blake2s256, _>(&mut io::stdin(), "-");
|
||||
}
|
||||
}
|
||||
294
blake2/src/blake2b.rs
Normal file
294
blake2/src/blake2b.rs
Normal file
@@ -0,0 +1,294 @@
|
||||
use byte_tools::{copy_memory, read_u64v_le, write_u64v_le,
|
||||
write_u32_le, write_u64_le};
|
||||
use crypto_ops::secure_memset;
|
||||
use digest::Digest;
|
||||
// use crypto_mac::{Mac, MacResult512};
|
||||
use generic_array::{GenericArray, ArrayLength};
|
||||
// use generic_array::typenum::{U64, Unsigned};
|
||||
use generic_array::typenum::U64;
|
||||
|
||||
use consts::BLAKE2B_IV as IV;
|
||||
use consts::{SIGMA, BLAKE2B_BLOCKBYTES, BLAKE2B_OUTBYTES, BLAKE2B_KEYBYTES,
|
||||
BLAKE2B_SALTBYTES, BLAKE2B_PERSONALBYTES};
|
||||
|
||||
use core::marker::PhantomData;
|
||||
|
||||
#[derive(Copy)]
|
||||
pub struct Blake2b<N> where N: ArrayLength<u8> + Copy {
|
||||
h: [u64; 8],
|
||||
t: [u64; 2],
|
||||
f: [u64; 2],
|
||||
buf: [u8; 2*BLAKE2B_BLOCKBYTES],
|
||||
buflen: usize,
|
||||
key: [u8; BLAKE2B_KEYBYTES],
|
||||
key_length: u8,
|
||||
last_node: u8,
|
||||
param: Blake2bParam,
|
||||
// Phantom data to tie digest length to this struct
|
||||
phantom: PhantomData<N>,
|
||||
}
|
||||
|
||||
pub type Blake2b512 = Blake2b<U64>;
|
||||
|
||||
impl<N> Clone for Blake2b<N> where N: ArrayLength<u8> + Copy {
|
||||
fn clone(&self) -> Blake2b<N> { *self }
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
struct Blake2bParam {
|
||||
key_length: u8,
|
||||
fanout: u8,
|
||||
depth: u8,
|
||||
leaf_length: u32,
|
||||
node_offset: u64,
|
||||
node_depth: u8,
|
||||
inner_length: u8,
|
||||
reserved: [u8; 14],
|
||||
salt: [u8; BLAKE2B_SALTBYTES],
|
||||
personal: [u8; BLAKE2B_PERSONALBYTES],
|
||||
}
|
||||
|
||||
macro_rules! G( ($r:expr, $i:expr, $a:expr, $b:expr, $c:expr, $d:expr, $m:expr) => ({
|
||||
$a = $a.wrapping_add($b).wrapping_add($m[SIGMA[$r][2*$i+0]]);
|
||||
$d = ($d ^ $a).rotate_right(32);
|
||||
$c = $c.wrapping_add($d);
|
||||
$b = ($b ^ $c).rotate_right(24);
|
||||
$a = $a.wrapping_add($b).wrapping_add($m[SIGMA[$r][2*$i+1]]);
|
||||
$d = ($d ^ $a).rotate_right(16);
|
||||
$c = $c .wrapping_add($d);
|
||||
$b = ($b ^ $c).rotate_right(63);
|
||||
}));
|
||||
|
||||
macro_rules! round( ($r:expr, $v:expr, $m:expr) => ( {
|
||||
G!($r,0,$v[ 0],$v[ 4],$v[ 8],$v[12], $m);
|
||||
G!($r,1,$v[ 1],$v[ 5],$v[ 9],$v[13], $m);
|
||||
G!($r,2,$v[ 2],$v[ 6],$v[10],$v[14], $m);
|
||||
G!($r,3,$v[ 3],$v[ 7],$v[11],$v[15], $m);
|
||||
G!($r,4,$v[ 0],$v[ 5],$v[10],$v[15], $m);
|
||||
G!($r,5,$v[ 1],$v[ 6],$v[11],$v[12], $m);
|
||||
G!($r,6,$v[ 2],$v[ 7],$v[ 8],$v[13], $m);
|
||||
G!($r,7,$v[ 3],$v[ 4],$v[ 9],$v[14], $m);
|
||||
}
|
||||
));
|
||||
|
||||
impl<N> Blake2b<N> where N: ArrayLength<u8> + Copy {
|
||||
fn set_lastnode(&mut self) {
|
||||
self.f[1] = 0xFFFFFFFFFFFFFFFF;
|
||||
}
|
||||
|
||||
fn set_lastblock(&mut self) {
|
||||
if self.last_node!=0 {
|
||||
self.set_lastnode();
|
||||
}
|
||||
self.f[0] = 0xFFFFFFFFFFFFFFFF;
|
||||
}
|
||||
|
||||
fn increment_counter(&mut self, inc : u64) {
|
||||
self.t[0] += inc;
|
||||
self.t[1] += if self.t[0] < inc { 1 } else { 0 };
|
||||
}
|
||||
|
||||
fn apply_param(&mut self) {
|
||||
let mut param_bytes = [0u8; 64];
|
||||
|
||||
param_bytes[0] = N::to_u8();
|
||||
param_bytes[1] = self.param.key_length;
|
||||
param_bytes[2] = self.param.fanout;
|
||||
param_bytes[3] = self.param.depth;
|
||||
write_u32_le(&mut param_bytes[4..8], self.param.leaf_length);
|
||||
write_u64_le(&mut param_bytes[8..16], self.param.node_offset);
|
||||
param_bytes[16] = self.param.node_depth;
|
||||
param_bytes[17] = self.param.inner_length;
|
||||
param_bytes[18..32].copy_from_slice(&self.param.reserved);
|
||||
param_bytes[32..48].copy_from_slice(&self.param.salt);
|
||||
param_bytes[48..].copy_from_slice(&self.param.personal);
|
||||
|
||||
let mut param_words : [u64; 8] = [0; 8];
|
||||
read_u64v_le(&mut param_words, ¶m_bytes);
|
||||
for (h, param_word) in self.h.iter_mut().zip(param_words.iter()) {
|
||||
*h = *h ^ *param_word;
|
||||
}
|
||||
}
|
||||
|
||||
// init xors IV with input parameter block
|
||||
fn init(param: Blake2bParam, key: &[u8]) -> Blake2b<N> {
|
||||
assert!(key.len() <= BLAKE2B_KEYBYTES);
|
||||
let mut b = Blake2b {
|
||||
h: IV,
|
||||
t: [0,0],
|
||||
f: [0,0],
|
||||
buf: [0; 2*BLAKE2B_BLOCKBYTES],
|
||||
buflen: 0,
|
||||
last_node: 0,
|
||||
key: [0; BLAKE2B_KEYBYTES],
|
||||
key_length: key.len() as u8,
|
||||
param: param,
|
||||
phantom: PhantomData,
|
||||
};
|
||||
copy_memory(key, &mut b.key);
|
||||
b.apply_param();
|
||||
b
|
||||
}
|
||||
|
||||
fn apply_key(&mut self) {
|
||||
let mut block : [u8; BLAKE2B_BLOCKBYTES] = [0; BLAKE2B_BLOCKBYTES];
|
||||
copy_memory(&self.key[..self.key_length as usize], &mut block);
|
||||
self.update(&block);
|
||||
secure_memset(&mut block[..], 0);
|
||||
}
|
||||
|
||||
pub fn new_keyed(key: &[u8] ) -> Blake2b<N> {
|
||||
assert!(N::to_usize() > 0 && N::to_usize() <= BLAKE2B_OUTBYTES);
|
||||
assert!(key.len() > 0 && key.len() <= BLAKE2B_KEYBYTES);
|
||||
|
||||
let param = Blake2bParam {
|
||||
key_length: key.len() as u8,
|
||||
fanout: 1,
|
||||
depth: 1,
|
||||
leaf_length: 0,
|
||||
node_offset: 0,
|
||||
node_depth: 0,
|
||||
inner_length: 0,
|
||||
reserved: [0; 14],
|
||||
salt: [0; BLAKE2B_SALTBYTES],
|
||||
personal: [0; BLAKE2B_PERSONALBYTES],
|
||||
};
|
||||
|
||||
let mut b = Blake2b::init(param, key);
|
||||
b.apply_key();
|
||||
b
|
||||
}
|
||||
|
||||
fn compress(&mut self) {
|
||||
let mut ms: [u64; 16] = [0; 16];
|
||||
let mut vs: [u64; 16] = [0; 16];
|
||||
|
||||
read_u64v_le(&mut ms, &self.buf[0..BLAKE2B_BLOCKBYTES]);
|
||||
|
||||
for (v, h) in vs.iter_mut().zip(self.h.iter()) {
|
||||
*v = *h;
|
||||
}
|
||||
|
||||
vs[ 8] = IV[0];
|
||||
vs[ 9] = IV[1];
|
||||
vs[10] = IV[2];
|
||||
vs[11] = IV[3];
|
||||
vs[12] = self.t[0] ^ IV[4];
|
||||
vs[13] = self.t[1] ^ IV[5];
|
||||
vs[14] = self.f[0] ^ IV[6];
|
||||
vs[15] = self.f[1] ^ IV[7];
|
||||
round!( 0, vs, ms );
|
||||
round!( 1, vs, ms );
|
||||
round!( 2, vs, ms );
|
||||
round!( 3, vs, ms );
|
||||
round!( 4, vs, ms );
|
||||
round!( 5, vs, ms );
|
||||
round!( 6, vs, ms );
|
||||
round!( 7, vs, ms );
|
||||
round!( 8, vs, ms );
|
||||
round!( 9, vs, ms );
|
||||
round!( 10, vs, ms );
|
||||
round!( 11, vs, ms );
|
||||
|
||||
let iter = self.h.iter_mut().zip(vs[0..8].iter().zip(vs[8..16].iter()));
|
||||
for (h_elem, (v_low, v_high)) in iter {
|
||||
*h_elem = *h_elem ^ *v_low ^ *v_high;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn update(&mut self, input: &[u8]) {
|
||||
let mut input = input;
|
||||
while input.len() > 0 {
|
||||
let left = self.buflen;
|
||||
let fill = 2 * BLAKE2B_BLOCKBYTES - left;
|
||||
|
||||
if input.len() > fill {
|
||||
copy_memory(&input[0..fill], &mut self.buf[left..]); // Fill buffer
|
||||
self.buflen += fill;
|
||||
self.increment_counter( BLAKE2B_BLOCKBYTES as u64);
|
||||
self.compress();
|
||||
|
||||
let mut halves = self.buf.chunks_mut(BLAKE2B_BLOCKBYTES);
|
||||
let first_half = halves.next().unwrap();
|
||||
let second_half = halves.next().unwrap();
|
||||
copy_memory(second_half, first_half);
|
||||
|
||||
self.buflen -= BLAKE2B_BLOCKBYTES;
|
||||
input = &input[fill..input.len()];
|
||||
} else { // inlen <= fill
|
||||
copy_memory(input, &mut self.buf[left..]);
|
||||
self.buflen += input.len();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn finalize(mut self) -> GenericArray<u8, N> {
|
||||
if self.buflen > BLAKE2B_BLOCKBYTES {
|
||||
self.increment_counter(BLAKE2B_BLOCKBYTES as u64);
|
||||
self.compress();
|
||||
self.buflen -= BLAKE2B_BLOCKBYTES;
|
||||
|
||||
let mut halves = self.buf.chunks_mut(BLAKE2B_BLOCKBYTES);
|
||||
let first_half = halves.next().unwrap();
|
||||
let second_half = halves.next().unwrap();
|
||||
copy_memory(second_half, first_half);
|
||||
}
|
||||
|
||||
let incby = self.buflen as u64;
|
||||
self.increment_counter(incby);
|
||||
self.set_lastblock();
|
||||
for b in self.buf[self.buflen..].iter_mut() {
|
||||
*b = 0;
|
||||
}
|
||||
self.compress();
|
||||
|
||||
write_u64v_le(&mut self.buf[0..64], &self.h);
|
||||
|
||||
let mut out = GenericArray::new();
|
||||
copy_memory(&self.buf[..N::to_usize()], &mut out);
|
||||
out
|
||||
}
|
||||
}
|
||||
|
||||
impl<N> Digest for Blake2b<N> where N: ArrayLength<u8> + Copy {
|
||||
type R = N;
|
||||
type B = U64;
|
||||
|
||||
fn new() -> Blake2b<N> {
|
||||
assert!(N::to_usize() > 0 && N::to_usize() <= BLAKE2B_OUTBYTES);
|
||||
let param = Blake2bParam {
|
||||
key_length: 0,
|
||||
fanout: 1,
|
||||
depth: 1,
|
||||
leaf_length: 0,
|
||||
node_offset: 0,
|
||||
node_depth: 0,
|
||||
inner_length: 0,
|
||||
reserved: [0; 14],
|
||||
salt: [0; BLAKE2B_SALTBYTES],
|
||||
personal: [0; BLAKE2B_PERSONALBYTES],
|
||||
};
|
||||
|
||||
Blake2b::init(param, &[])
|
||||
}
|
||||
|
||||
fn input(&mut self, input: &[u8]) { self.update(input); }
|
||||
|
||||
fn result(self) -> GenericArray<u8, Self::R> { self.finalize() }
|
||||
}
|
||||
|
||||
/*
|
||||
impl<N> Mac for Blake2b<N> {
|
||||
type R = N;
|
||||
|
||||
fn input(&mut self, data: &[u8]) {
|
||||
self.update(data);
|
||||
}
|
||||
|
||||
fn result(&mut self) -> MacResult<N> {
|
||||
MacResult::new(self.result())
|
||||
}
|
||||
}
|
||||
*/
|
||||
279
blake2/src/blake2s.rs
Normal file
279
blake2/src/blake2s.rs
Normal file
@@ -0,0 +1,279 @@
|
||||
use byte_tools::{copy_memory, read_u32v_le, write_u32v_le, write_u32_le};
|
||||
use crypto_ops::secure_memset;
|
||||
use digest::Digest;
|
||||
//use crypto_mac::{Mac, MacResult256};
|
||||
use generic_array::{GenericArray, ArrayLength};
|
||||
// use generic_array::typenum::{U32, Unsigned};
|
||||
use generic_array::typenum::{U32, U128};
|
||||
|
||||
use consts::BLAKE2S_IV as IV;
|
||||
use consts::{SIGMA, BLAKE2S_BLOCKBYTES, BLAKE2S_OUTBYTES, BLAKE2S_KEYBYTES,
|
||||
BLAKE2S_SALTBYTES, BLAKE2S_PERSONALBYTES};
|
||||
|
||||
use core::marker::PhantomData;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Blake2s<N> where N: ArrayLength<u8> + Copy {
|
||||
h: [u32; 8],
|
||||
t: [u32; 2],
|
||||
f: [u32; 2],
|
||||
buf: GenericArray<u8, U128>,
|
||||
buflen: usize,
|
||||
key: [u8; BLAKE2S_KEYBYTES],
|
||||
key_length: u8,
|
||||
last_node: u8,
|
||||
param: Blake2sParam,
|
||||
// Phantom data to tie digest length to this struct
|
||||
phantom: PhantomData<N>,
|
||||
}
|
||||
|
||||
pub type Blake2s256 = Blake2s<U32>;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
struct Blake2sParam {
|
||||
key_length: u8,
|
||||
fanout: u8,
|
||||
depth: u8,
|
||||
leaf_length: u32,
|
||||
node_offset: [u8; 6],
|
||||
node_depth: u8,
|
||||
inner_length: u8,
|
||||
salt: [u8; BLAKE2S_SALTBYTES],
|
||||
personal: [u8; BLAKE2S_PERSONALBYTES],
|
||||
}
|
||||
|
||||
macro_rules! G( ($r:expr, $i:expr, $a:expr, $b:expr, $c:expr, $d:expr, $m:expr) => ({
|
||||
$a = $a.wrapping_add($b).wrapping_add($m[SIGMA[$r][2*$i+0]]);
|
||||
$d = ($d ^ $a).rotate_right(16);
|
||||
$c = $c.wrapping_add($d);
|
||||
$b = ($b ^ $c).rotate_right(12);
|
||||
$a = $a.wrapping_add($b).wrapping_add($m[SIGMA[$r][2*$i+1]]);
|
||||
$d = ($d ^ $a).rotate_right(8);
|
||||
$c = $c.wrapping_add($d);
|
||||
$b = ($b ^ $c).rotate_right(7);
|
||||
}));
|
||||
|
||||
macro_rules! round( ($r:expr, $v:expr, $m:expr) => ( {
|
||||
G!($r,0,$v[ 0],$v[ 4],$v[ 8],$v[12], $m);
|
||||
G!($r,1,$v[ 1],$v[ 5],$v[ 9],$v[13], $m);
|
||||
G!($r,2,$v[ 2],$v[ 6],$v[10],$v[14], $m);
|
||||
G!($r,3,$v[ 3],$v[ 7],$v[11],$v[15], $m);
|
||||
G!($r,4,$v[ 0],$v[ 5],$v[10],$v[15], $m);
|
||||
G!($r,5,$v[ 1],$v[ 6],$v[11],$v[12], $m);
|
||||
G!($r,6,$v[ 2],$v[ 7],$v[ 8],$v[13], $m);
|
||||
G!($r,7,$v[ 3],$v[ 4],$v[ 9],$v[14], $m);
|
||||
}
|
||||
));
|
||||
|
||||
impl<N> Blake2s<N> where N: ArrayLength<u8> + Copy {
|
||||
fn set_lastnode(&mut self) {
|
||||
self.f[1] = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
fn set_lastblock(&mut self) {
|
||||
if self.last_node!=0 {
|
||||
self.set_lastnode();
|
||||
}
|
||||
self.f[0] = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
fn increment_counter(&mut self, inc : u32) {
|
||||
self.t[0] += inc;
|
||||
self.t[1] += if self.t[0] < inc { 1 } else { 0 };
|
||||
}
|
||||
|
||||
fn apply_param(&mut self) {
|
||||
let mut param_bytes = [0u8; 32];
|
||||
|
||||
param_bytes[0] = N::to_u8();
|
||||
param_bytes[1] = self.param.key_length;
|
||||
param_bytes[2] = self.param.fanout;
|
||||
param_bytes[3] = self.param.depth;
|
||||
write_u32_le(&mut param_bytes[4..8], self.param.leaf_length);
|
||||
param_bytes[8..14].copy_from_slice(&self.param.node_offset);
|
||||
param_bytes[15] = self.param.node_depth;
|
||||
param_bytes[16] = self.param.inner_length;
|
||||
param_bytes[16..24].copy_from_slice(&self.param.salt);
|
||||
param_bytes[24..].copy_from_slice(&self.param.personal);
|
||||
|
||||
let mut param_words : [u32; 8] = [0; 8];
|
||||
read_u32v_le(&mut param_words, ¶m_bytes);
|
||||
for (h, param_word) in self.h.iter_mut().zip(param_words.iter()) {
|
||||
*h = *h ^ *param_word;
|
||||
}
|
||||
}
|
||||
|
||||
// init xors IV with input parameter block
|
||||
fn init( param: Blake2sParam, key: &[u8] ) -> Blake2s<N> {
|
||||
assert!(key.len() <= BLAKE2S_KEYBYTES);
|
||||
let mut b = Blake2s {
|
||||
h: IV,
|
||||
t: [0,0],
|
||||
f: [0,0],
|
||||
buf: GenericArray::new(),
|
||||
buflen: 0,
|
||||
last_node: 0,
|
||||
key: [0; BLAKE2S_KEYBYTES],
|
||||
key_length: key.len() as u8,
|
||||
param: param,
|
||||
phantom: PhantomData,
|
||||
};
|
||||
copy_memory(key, &mut b.key);
|
||||
b.apply_param();
|
||||
b
|
||||
}
|
||||
|
||||
fn apply_key(&mut self) {
|
||||
let mut block : [u8; BLAKE2S_BLOCKBYTES] = [0; BLAKE2S_BLOCKBYTES];
|
||||
copy_memory(&self.key[..self.key_length as usize], &mut block);
|
||||
self.update(&block);
|
||||
secure_memset(&mut block[..], 0);
|
||||
}
|
||||
|
||||
pub fn new_keyed(key: &[u8] ) -> Blake2s<N> {
|
||||
assert!(N::to_usize() > 0 && N::to_usize() <= BLAKE2S_OUTBYTES);
|
||||
assert!(key.len() > 0 && key.len() <= BLAKE2S_KEYBYTES);
|
||||
|
||||
let param = Blake2sParam {
|
||||
key_length: key.len() as u8,
|
||||
fanout: 1,
|
||||
depth: 1,
|
||||
leaf_length: 0,
|
||||
node_offset: [0; 6],
|
||||
node_depth: 0,
|
||||
inner_length: 0,
|
||||
salt: [0; BLAKE2S_SALTBYTES],
|
||||
personal: [0; BLAKE2S_PERSONALBYTES],
|
||||
};
|
||||
|
||||
let mut b = Blake2s::init(param, key);
|
||||
b.apply_key();
|
||||
b
|
||||
}
|
||||
|
||||
fn compress(&mut self) {
|
||||
let mut ms: [u32; 16] = [0; 16];
|
||||
let mut vs: [u32; 16] = [0; 16];
|
||||
|
||||
read_u32v_le(&mut ms, &self.buf[0..BLAKE2S_BLOCKBYTES]);
|
||||
|
||||
for (v, h) in vs.iter_mut().zip(self.h.iter()) {
|
||||
*v = *h;
|
||||
}
|
||||
|
||||
vs[ 8] = IV[0];
|
||||
vs[ 9] = IV[1];
|
||||
vs[10] = IV[2];
|
||||
vs[11] = IV[3];
|
||||
vs[12] = self.t[0] ^ IV[4];
|
||||
vs[13] = self.t[1] ^ IV[5];
|
||||
vs[14] = self.f[0] ^ IV[6];
|
||||
vs[15] = self.f[1] ^ IV[7];
|
||||
round!( 0, vs, ms );
|
||||
round!( 1, vs, ms );
|
||||
round!( 2, vs, ms );
|
||||
round!( 3, vs, ms );
|
||||
round!( 4, vs, ms );
|
||||
round!( 5, vs, ms );
|
||||
round!( 6, vs, ms );
|
||||
round!( 7, vs, ms );
|
||||
round!( 8, vs, ms );
|
||||
round!( 9, vs, ms );
|
||||
|
||||
for (h_elem, (v_low, v_high)) in self.h.iter_mut().zip( vs[0..8].iter().zip(vs[8..16].iter()) ) {
|
||||
*h_elem = *h_elem ^ *v_low ^ *v_high;
|
||||
}
|
||||
}
|
||||
|
||||
fn update( &mut self, mut input: &[u8] ) {
|
||||
while input.len() > 0 {
|
||||
let left = self.buflen;
|
||||
let fill = 2 * BLAKE2S_BLOCKBYTES - left;
|
||||
|
||||
if input.len() > fill {
|
||||
copy_memory(&input[0..fill], &mut self.buf[left..]); // Fill buffer
|
||||
self.buflen += fill;
|
||||
self.increment_counter( BLAKE2S_BLOCKBYTES as u32);
|
||||
self.compress();
|
||||
|
||||
let mut halves = self.buf.chunks_mut(BLAKE2S_BLOCKBYTES);
|
||||
let first_half = halves.next().unwrap();
|
||||
let second_half = halves.next().unwrap();
|
||||
copy_memory(second_half, first_half);
|
||||
|
||||
self.buflen -= BLAKE2S_BLOCKBYTES;
|
||||
input = &input[fill..input.len()];
|
||||
} else { // inlen <= fill
|
||||
copy_memory(input, &mut self.buf[left..]);
|
||||
self.buflen += input.len();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn finalize(mut self) -> GenericArray<u8, N> {
|
||||
if self.buflen > BLAKE2S_BLOCKBYTES {
|
||||
self.increment_counter(BLAKE2S_BLOCKBYTES as u32);
|
||||
self.compress();
|
||||
self.buflen -= BLAKE2S_BLOCKBYTES;
|
||||
|
||||
let mut halves = self.buf.chunks_mut(BLAKE2S_BLOCKBYTES);
|
||||
let first_half = halves.next().unwrap();
|
||||
let second_half = halves.next().unwrap();
|
||||
copy_memory(second_half, first_half);
|
||||
}
|
||||
|
||||
let incby = self.buflen as u32;
|
||||
self.increment_counter(incby);
|
||||
self.set_lastblock();
|
||||
for b in self.buf[self.buflen..].iter_mut() {
|
||||
*b = 0;
|
||||
}
|
||||
self.compress();
|
||||
|
||||
write_u32v_le(&mut self.buf[0..32], &self.h);
|
||||
|
||||
let mut out = GenericArray::new();
|
||||
copy_memory(&self.buf[..N::to_usize()], &mut out);
|
||||
out
|
||||
}
|
||||
}
|
||||
|
||||
impl<N> Digest for Blake2s<N> where N: ArrayLength<u8> + Copy {
|
||||
type R = N;
|
||||
type B = U32;
|
||||
|
||||
fn new() -> Blake2s<N> {
|
||||
assert!(N::to_usize() > 0 && N::to_usize() <= BLAKE2S_OUTBYTES);
|
||||
let default_param = Blake2sParam {
|
||||
key_length: 0,
|
||||
fanout: 1,
|
||||
depth: 1,
|
||||
leaf_length: 0,
|
||||
node_offset: [0; 6],
|
||||
node_depth: 0,
|
||||
inner_length: 0,
|
||||
salt: [0; BLAKE2S_SALTBYTES],
|
||||
personal: [0; BLAKE2S_PERSONALBYTES],
|
||||
};
|
||||
Blake2s::init(default_param, &[])
|
||||
}
|
||||
|
||||
fn input(&mut self, input: &[u8]) { self.update(input); }
|
||||
|
||||
fn result(self) -> GenericArray<u8, Self::R> { self.finalize() }
|
||||
}
|
||||
|
||||
/*
|
||||
impl<N> Mac for Blake2s<N> {
|
||||
type R = N;
|
||||
|
||||
fn input(&mut self, data: &[u8]) {
|
||||
self.update(data);
|
||||
}
|
||||
|
||||
fn result(&mut self) -> MacResult<N> {
|
||||
MacResult::new(self.result())
|
||||
}
|
||||
}
|
||||
*/
|
||||
38
blake2/src/consts.rs
Normal file
38
blake2/src/consts.rs
Normal file
@@ -0,0 +1,38 @@
|
||||
pub static SIGMA : [[usize; 16]; 12] = [
|
||||
[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ],
|
||||
[ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 ],
|
||||
[ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 ],
|
||||
[ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 ],
|
||||
[ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 ],
|
||||
[ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 ],
|
||||
[ 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 ],
|
||||
[ 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 ],
|
||||
[ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 ],
|
||||
[ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 ],
|
||||
[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ],
|
||||
[ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 ],
|
||||
];
|
||||
|
||||
pub static BLAKE2B_IV : [u64; 8] = [
|
||||
0x6a09e667f3bcc908, 0xbb67ae8584caa73b,
|
||||
0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1,
|
||||
0x510e527fade682d1, 0x9b05688c2b3e6c1f,
|
||||
0x1f83d9abfb41bd6b, 0x5be0cd19137e2179,
|
||||
];
|
||||
|
||||
pub const BLAKE2B_BLOCKBYTES : usize = 128;
|
||||
pub const BLAKE2B_OUTBYTES : usize = 64;
|
||||
pub const BLAKE2B_KEYBYTES : usize = 64;
|
||||
pub const BLAKE2B_SALTBYTES : usize = 16;
|
||||
pub const BLAKE2B_PERSONALBYTES : usize = 16;
|
||||
|
||||
pub static BLAKE2S_IV : [u32; 8] = [
|
||||
0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
|
||||
0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19
|
||||
];
|
||||
|
||||
pub const BLAKE2S_BLOCKBYTES : usize = 64;
|
||||
pub const BLAKE2S_OUTBYTES : usize = 32;
|
||||
pub const BLAKE2S_KEYBYTES : usize = 32;
|
||||
pub const BLAKE2S_SALTBYTES : usize = 8;
|
||||
pub const BLAKE2S_PERSONALBYTES : usize = 8;
|
||||
16
blake2/src/lib.rs
Normal file
16
blake2/src/lib.rs
Normal file
@@ -0,0 +1,16 @@
|
||||
#![no_std]
|
||||
extern crate byte_tools;
|
||||
extern crate digest;
|
||||
// extern crate crypto_mac;
|
||||
extern crate crypto_ops;
|
||||
extern crate generic_array;
|
||||
|
||||
mod consts;
|
||||
|
||||
mod blake2b;
|
||||
pub use blake2b::{Blake2b, Blake2b512};
|
||||
|
||||
mod blake2s;
|
||||
pub use blake2s::{Blake2s, Blake2s256};
|
||||
|
||||
pub use digest::Digest;
|
||||
0
blake2/tests/data/blake2b/1.input.bin
Normal file
0
blake2/tests/data/blake2b/1.input.bin
Normal file
1
blake2/tests/data/blake2b/1.output.bin
Normal file
1
blake2/tests/data/blake2b/1.output.bin
Normal file
@@ -0,0 +1 @@
|
||||
xj÷BYÆÆý…%RÒr‘/G@áXGaІâ÷TÒ^1¯îXS‰dD“N°K<C2B0>:h[H·UÕopþ›âÎ
|
||||
1
blake2/tests/data/blake2b/2.input.bin
Normal file
1
blake2/tests/data/blake2b/2.input.bin
Normal file
@@ -0,0 +1 @@
|
||||
The quick brown fox jumps over the lazy dog
|
||||
1
blake2/tests/data/blake2b/2.output.bin
Normal file
1
blake2/tests/data/blake2b/2.output.bin
Normal file
@@ -0,0 +1 @@
|
||||
¨Ô½Ýý“ä‡}'Fæ(±6J§¼<14>• Ç3;6sø$Ïz¢äËÍ<>)n?ËTøíw¾s[‘LÜÖ©
|
||||
BIN
blake2/tests/data/blake2b/3.input.bin
Normal file
BIN
blake2/tests/data/blake2b/3.input.bin
Normal file
Binary file not shown.
BIN
blake2/tests/data/blake2b/3.key.bin
Normal file
BIN
blake2/tests/data/blake2b/3.key.bin
Normal file
Binary file not shown.
2
blake2/tests/data/blake2b/3.output.bin
Normal file
2
blake2/tests/data/blake2b/3.output.bin
Normal file
@@ -0,0 +1,2 @@
|
||||
' Ö.(üÌЯ—úÐøF[—‚ Åpú 7*¤>’HKáÁç;¡ ÕÑ…=¶¤n
|
||||
{ù€
|
||||
1
blake2/tests/data/blake2b/mac.input.bin
Normal file
1
blake2/tests/data/blake2b/mac.input.bin
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
BIN
blake2/tests/data/blake2b/mac.key.bin
Normal file
BIN
blake2/tests/data/blake2b/mac.key.bin
Normal file
Binary file not shown.
1
blake2/tests/data/blake2b/mac.output.bin
Normal file
1
blake2/tests/data/blake2b/mac.output.bin
Normal file
@@ -0,0 +1 @@
|
||||
ŽÆËqÄ\<<3C>‘Њ7¨]Á"µÈâÙåqB¿ïÎB×¼ø‹°1'ˆ.Q©!Dbö£X©à}5;ÓApb¬Õ9Nîs®
|
||||
BIN
blake2/tests/data/blake2s/1.input.bin
Normal file
BIN
blake2/tests/data/blake2s/1.input.bin
Normal file
Binary file not shown.
BIN
blake2/tests/data/blake2s/1.key.bin
Normal file
BIN
blake2/tests/data/blake2s/1.key.bin
Normal file
Binary file not shown.
1
blake2/tests/data/blake2s/1.output.bin
Normal file
1
blake2/tests/data/blake2s/1.output.bin
Normal file
@@ -0,0 +1 @@
|
||||
?╥5╪Q²Ч≈·TаН[Зп╘ьXЁ1[╜4╫И≥Ов$щ
|
||||
1
blake2/tests/data/blake2s/mac.input.bin
Normal file
1
blake2/tests/data/blake2s/mac.input.bin
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
BIN
blake2/tests/data/blake2s/mac.key.bin
Normal file
BIN
blake2/tests/data/blake2s/mac.key.bin
Normal file
Binary file not shown.
1
blake2/tests/data/blake2s/mac.output.bin
Normal file
1
blake2/tests/data/blake2s/mac.output.bin
Normal file
@@ -0,0 +1 @@
|
||||
ˆöŠª\NØ÷í(øEœ~ùv+Oñ~[¨È‚žâI
|
||||
35
blake2/tests/lib.rs
Normal file
35
blake2/tests/lib.rs
Normal file
@@ -0,0 +1,35 @@
|
||||
#![no_std]
|
||||
#[macro_use]
|
||||
extern crate crypto_tests;
|
||||
extern crate blake2;
|
||||
extern crate digest;
|
||||
|
||||
use blake2::{Blake2b512, Blake2s256};
|
||||
use crypto_tests::hash::{Test, main_test};
|
||||
use digest::Digest;
|
||||
|
||||
#[test]
|
||||
fn blake2b() {
|
||||
let tests = new_tests!("blake2b/1", "blake2b/2");
|
||||
// Tests without key
|
||||
main_test::<Blake2b512>(&tests);
|
||||
// Test with key
|
||||
let input = include_bytes!("data/blake2b/3.input.bin");
|
||||
let output = include_bytes!("data/blake2b/3.output.bin");
|
||||
let key = include_bytes!("data/blake2b/3.key.bin");
|
||||
|
||||
let mut sh = Blake2b512::new_keyed(key);
|
||||
sh.input(input);
|
||||
assert_eq!(&sh.result()[..], &output[..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn blake2s() {
|
||||
let input = include_bytes!("data/blake2s/1.input.bin");
|
||||
let output = include_bytes!("data/blake2s/1.output.bin");
|
||||
let key = include_bytes!("data/blake2s/1.key.bin");
|
||||
|
||||
let mut sh = Blake2s256::new_keyed(key);
|
||||
sh.input(input);
|
||||
assert_eq!(&sh.result()[..], output);
|
||||
}
|
||||
29
blake2/tests/mac.rs
Normal file
29
blake2/tests/mac.rs
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
#![no_std]
|
||||
#[macro_use]
|
||||
extern crate blake2;
|
||||
extern crate crypto_mac;
|
||||
|
||||
use blake2::{Blake2b512, Blake2s256};
|
||||
use crypto_mac::Mac;
|
||||
|
||||
#[test]
|
||||
fn blake2b_mac() {
|
||||
let key = include_bytes!("data/blake2b/mac.key.bin");
|
||||
let input = include_bytes!("data/blake2b/mac.input.bin");
|
||||
let output = include_bytes!("data/blake2b/mac.output.bin");
|
||||
let mut d = Blake2b512::new_keyed(key);
|
||||
d.input(input);
|
||||
assert_eq!(d.result().code(), &output[..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn blake2s_mac() {
|
||||
let key = include_bytes!("data/blake2s/mac.key.bin");
|
||||
let input = include_bytes!("data/blake2s/mac.input.bin");
|
||||
let output = include_bytes!("data/blake2s/mac.output.bin");
|
||||
let mut d = Blake2s256::new_keyed(key);
|
||||
d.input(input);
|
||||
assert_eq!(d.result().code(), &output[..]);
|
||||
}
|
||||
*/
|
||||
19
md4/Cargo.toml
Normal file
19
md4/Cargo.toml
Normal file
@@ -0,0 +1,19 @@
|
||||
[package]
|
||||
name = "md4"
|
||||
version = "0.2.0"
|
||||
authors = ["The Rust-Crypto Project Developers"]
|
||||
license = "MIT/Apache-2.0"
|
||||
description = "MD4 hash function"
|
||||
documentation = "https://docs.rs/md4"
|
||||
repository = "https://github.com/RustCrypto/hashes"
|
||||
keywords = ["crypto", "md4", "hash", "digest"]
|
||||
|
||||
[dependencies]
|
||||
fake-simd = "0.1"
|
||||
byte-tools = "0.1"
|
||||
digest = "0.2"
|
||||
digest-buffer = "0.1"
|
||||
generic-array = "0.5"
|
||||
|
||||
[dev-dependencies]
|
||||
crypto-tests = "0.1"
|
||||
201
md4/LICENSE-APACHE
Normal file
201
md4/LICENSE-APACHE
Normal 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
md4/LICENSE-MIT
Normal file
25
md4/LICENSE-MIT
Normal file
@@ -0,0 +1,25 @@
|
||||
Copyright (c) 2016 bacher09, Artyom Pavlov
|
||||
|
||||
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.
|
||||
40
md4/benches/lib.rs
Normal file
40
md4/benches/lib.rs
Normal file
@@ -0,0 +1,40 @@
|
||||
#![no_std]
|
||||
#![feature(test)]
|
||||
extern crate test;
|
||||
extern crate md4;
|
||||
extern crate digest;
|
||||
|
||||
use test::Bencher;
|
||||
use digest::Digest;
|
||||
use md4::Md4;
|
||||
|
||||
|
||||
#[bench]
|
||||
pub fn md4_10(bh: &mut Bencher) {
|
||||
let mut sh = Md4::new();
|
||||
let bytes = [1u8; 10];
|
||||
bh.iter(|| {
|
||||
sh.input(&bytes);
|
||||
});
|
||||
bh.bytes = bytes.len() as u64;
|
||||
}
|
||||
|
||||
#[bench]
|
||||
pub fn md4_1k(bh: &mut Bencher) {
|
||||
let mut sh = Md4::new();
|
||||
let bytes = [1u8; 1024];
|
||||
bh.iter(|| {
|
||||
sh.input(&bytes);
|
||||
});
|
||||
bh.bytes = bytes.len() as u64;
|
||||
}
|
||||
|
||||
#[bench]
|
||||
pub fn md4_64k(bh: &mut Bencher) {
|
||||
let mut sh = Md4::new();
|
||||
let bytes = [1u8; 65536];
|
||||
bh.iter(|| {
|
||||
sh.input(&bytes);
|
||||
});
|
||||
bh.bytes = bytes.len() as u64;
|
||||
}
|
||||
49
md4/examples/md4sum.rs
Normal file
49
md4/examples/md4sum.rs
Normal file
@@ -0,0 +1,49 @@
|
||||
extern crate md4;
|
||||
|
||||
use md4::{Md4, Digest};
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use std::io::{self, Read};
|
||||
|
||||
const BUFFER_SIZE: usize = 1024;
|
||||
|
||||
/// Print digest result as hex string and name pair
|
||||
fn print_result(sum: &[u8], name: &str) {
|
||||
for byte in sum {
|
||||
print!("{:02x}", byte);
|
||||
}
|
||||
println!("\t{}", name);
|
||||
}
|
||||
|
||||
/// Compute digest value for given `Reader` and print it
|
||||
/// On any error simply return without doing anything
|
||||
fn process<D: Digest, R: Read>(reader: &mut R, name: &str) {
|
||||
let mut sh = D::new();
|
||||
let mut buffer = [0u8; BUFFER_SIZE];
|
||||
loop {
|
||||
let n = match reader.read(&mut buffer) {
|
||||
Ok(n) => n,
|
||||
Err(_) => return,
|
||||
};
|
||||
sh.input(&buffer[..n]);
|
||||
if n == 0 || n < BUFFER_SIZE {
|
||||
break;
|
||||
}
|
||||
}
|
||||
print_result(&sh.result(), name);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let args = env::args();
|
||||
// Process files listed in command line arguments one by one
|
||||
// If no files provided process input from stdin
|
||||
if args.len() > 1 {
|
||||
for path in args.skip(1) {
|
||||
if let Ok(mut file) = fs::File::open(&path) {
|
||||
process::<Md4, _>(&mut file, &path);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
process::<Md4, _>(&mut io::stdin(), "-");
|
||||
}
|
||||
}
|
||||
147
md4/src/lib.rs
Normal file
147
md4/src/lib.rs
Normal file
@@ -0,0 +1,147 @@
|
||||
//! The [MD4][1] hash function.
|
||||
//!
|
||||
//! [1]: https://en.wikipedia.org/wiki/MD4
|
||||
|
||||
#![no_std]
|
||||
extern crate generic_array;
|
||||
extern crate fake_simd as simd;
|
||||
extern crate byte_tools;
|
||||
extern crate digest;
|
||||
extern crate digest_buffer;
|
||||
|
||||
pub use digest::Digest;
|
||||
use byte_tools::{write_u32_le, read_u32v_le};
|
||||
use digest_buffer::{DigestBuffer};
|
||||
use simd::u32x4;
|
||||
use generic_array::GenericArray;
|
||||
use generic_array::typenum::{U16, U64};
|
||||
|
||||
// initial values for Md4State
|
||||
const S: u32x4 = u32x4(0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476);
|
||||
|
||||
type BlockSize = U64;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
struct Md4State {
|
||||
s: u32x4,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Md4 {
|
||||
length_bytes: u64,
|
||||
buffer: DigestBuffer<BlockSize>,
|
||||
state: Md4State,
|
||||
}
|
||||
|
||||
|
||||
impl Md4State {
|
||||
fn new() -> Md4State {
|
||||
Md4State { s: S }
|
||||
}
|
||||
|
||||
fn process_block(&mut self, input: &[u8]) {
|
||||
fn f(x: u32, y: u32, z: u32) -> u32 {
|
||||
(x & y) | (!x & z)
|
||||
}
|
||||
|
||||
fn g(x: u32, y: u32, z: u32) -> u32 {
|
||||
(x & y) | (x & z) | (y & z)
|
||||
}
|
||||
|
||||
fn h(x: u32, y: u32, z: u32) -> u32 {
|
||||
x ^ y ^ z
|
||||
}
|
||||
|
||||
fn op1(a: u32, b: u32, c: u32, d: u32, k: u32, s: u32) -> u32 {
|
||||
a.wrapping_add(f(b, c, d)).wrapping_add(k).rotate_left(s)
|
||||
}
|
||||
|
||||
fn op2(a: u32, b: u32, c: u32, d: u32, k: u32, s: u32) -> u32 {
|
||||
a.wrapping_add(g(b, c, d)).wrapping_add(k).wrapping_add(0x5a827999).rotate_left(s)
|
||||
}
|
||||
|
||||
fn op3(a: u32, b: u32, c: u32, d: u32, k: u32, s: u32) -> u32 {
|
||||
a.wrapping_add(h(b, c, d)).wrapping_add(k).wrapping_add(0x6ED9EBA1).rotate_left(s)
|
||||
}
|
||||
|
||||
let mut a = self.s.0;
|
||||
let mut b = self.s.1;
|
||||
let mut c = self.s.2;
|
||||
let mut d = self.s.3;
|
||||
|
||||
// load block to data
|
||||
let mut data = [0u32; 16];
|
||||
read_u32v_le(&mut data, input);
|
||||
|
||||
// FIXME: replace [0, 4, 8, 12] with (0..16).step_by(4)
|
||||
// after stabilization
|
||||
|
||||
// round 1
|
||||
for &i in [0, 4, 8, 12].iter() {
|
||||
a = op1(a, b, c, d, data[i], 3);
|
||||
d = op1(d, a, b, c, data[i + 1], 7);
|
||||
c = op1(c, d, a, b, data[i + 2], 11);
|
||||
b = op1(b, c, d, a, data[i + 3], 19);
|
||||
}
|
||||
|
||||
// round 2
|
||||
for i in 0..4 {
|
||||
a = op2(a, b, c, d, data[i], 3);
|
||||
d = op2(d, a, b, c, data[i + 4], 5);
|
||||
c = op2(c, d, a, b, data[i + 8], 9);
|
||||
b = op2(b, c, d, a, data[i + 12], 13);
|
||||
}
|
||||
|
||||
// round 3
|
||||
for &i in [0, 2, 1, 3].iter() {
|
||||
a = op3(a, b, c, d, data[i], 3);
|
||||
d = op3(d, a, b, c, data[i + 8], 9);
|
||||
c = op3(c, d, a, b, data[i + 4], 11);
|
||||
b = op3(b, c, d, a, data[i + 12], 15);
|
||||
}
|
||||
|
||||
self.s = self.s + u32x4(a, b, c, d);
|
||||
}
|
||||
}
|
||||
|
||||
impl Md4 {
|
||||
fn finalize(&mut self) {
|
||||
let self_state = &mut self.state;
|
||||
self.buffer.standard_padding(8, |d: &[u8]| { self_state.process_block(d); });
|
||||
write_u32_le(self.buffer.next(4), (self.length_bytes << 3) as u32);
|
||||
write_u32_le(self.buffer.next(4), (self.length_bytes >> 29) as u32);
|
||||
self_state.process_block(self.buffer.full_buffer());
|
||||
}
|
||||
}
|
||||
|
||||
impl Digest for Md4 {
|
||||
type R = U16;
|
||||
type B = BlockSize;
|
||||
|
||||
fn new() -> Md4 {
|
||||
Md4 {
|
||||
length_bytes: 0,
|
||||
buffer: Default::default(),
|
||||
state: Md4State::new()
|
||||
}
|
||||
}
|
||||
|
||||
fn input(&mut self, input: &[u8]) {
|
||||
// 2^64 - ie: integer overflow is OK.
|
||||
self.length_bytes += input.len() as u64;
|
||||
let self_state = &mut self.state;
|
||||
self.buffer.input(input, |d: &[u8]| { self_state.process_block(d);}
|
||||
);
|
||||
}
|
||||
|
||||
fn result(mut self) -> GenericArray<u8, Self::R> {
|
||||
self.finalize();
|
||||
|
||||
let mut out = GenericArray::new();
|
||||
write_u32_le(&mut out[0..4], self.state.s.0);
|
||||
write_u32_le(&mut out[4..8], self.state.s.1);
|
||||
write_u32_le(&mut out[8..12], self.state.s.2);
|
||||
write_u32_le(&mut out[12..16], self.state.s.3);
|
||||
out
|
||||
}
|
||||
}
|
||||
1
md4/tests/data/one_million_a.output.bin
Normal file
1
md4/tests/data/one_million_a.output.bin
Normal file
@@ -0,0 +1 @@
|
||||
»Î€Ìk¶^\gEã
|
||||
0
md4/tests/data/test1.input.bin
Normal file
0
md4/tests/data/test1.input.bin
Normal file
1
md4/tests/data/test1.output.bin
Normal file
1
md4/tests/data/test1.output.bin
Normal file
@@ -0,0 +1 @@
|
||||
1ÖÏàÑjé1·<Y×àÀ‰À
|
||||
1
md4/tests/data/test2.input.bin
Normal file
1
md4/tests/data/test2.input.bin
Normal file
@@ -0,0 +1 @@
|
||||
a
|
||||
1
md4/tests/data/test2.output.bin
Normal file
1
md4/tests/data/test2.output.bin
Normal file
@@ -0,0 +1 @@
|
||||
½å,³ã>F$^ûÛÖû$
|
||||
1
md4/tests/data/test3.input.bin
Normal file
1
md4/tests/data/test3.input.bin
Normal file
@@ -0,0 +1 @@
|
||||
abc
|
||||
2
md4/tests/data/test3.output.bin
Normal file
2
md4/tests/data/test3.output.bin
Normal file
@@ -0,0 +1,2 @@
|
||||
、Hzッ!リR_チ
|
||||
閊ヲr<EFBFBD>
|
||||
1
md4/tests/data/test4.input.bin
Normal file
1
md4/tests/data/test4.input.bin
Normal file
@@ -0,0 +1 @@
|
||||
message digest
|
||||
2
md4/tests/data/test4.output.bin
Normal file
2
md4/tests/data/test4.output.bin
Normal file
@@ -0,0 +1,2 @@
|
||||
ル
|
||||
‥T溯⑨睇K
|
||||
1
md4/tests/data/test5.input.bin
Normal file
1
md4/tests/data/test5.input.bin
Normal file
@@ -0,0 +1 @@
|
||||
abcdefghijklmnopqrstuvwxyz
|
||||
1
md4/tests/data/test5.output.bin
Normal file
1
md4/tests/data/test5.output.bin
Normal file
@@ -0,0 +1 @@
|
||||
׳<EFBFBD>0<>¥»ֽמ¨םc<D79D>A-©
|
||||
1
md4/tests/data/test6.input.bin
Normal file
1
md4/tests/data/test6.input.bin
Normal file
@@ -0,0 +1 @@
|
||||
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
|
||||
1
md4/tests/data/test6.output.bin
Normal file
1
md4/tests/data/test6.output.bin
Normal file
@@ -0,0 +1 @@
|
||||
?…‚עA<D7A2>5ז'בSחנה
|
||||
1
md4/tests/data/test7.input.bin
Normal file
1
md4/tests/data/test7.input.bin
Normal file
@@ -0,0 +1 @@
|
||||
12345678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
1
md4/tests/data/test7.output.bin
Normal file
1
md4/tests/data/test7.output.bin
Normal file
@@ -0,0 +1 @@
|
||||
<EFBFBD>;Mܜ8<DC9C><19>>{O<>6
|
||||
1
md4/tests/data/test8.input.bin
Normal file
1
md4/tests/data/test8.input.bin
Normal file
@@ -0,0 +1 @@
|
||||
The quick brown fox jumps over the lazy dog
|
||||
1
md4/tests/data/test8.output.bin
Normal file
1
md4/tests/data/test8.output.bin
Normal file
@@ -0,0 +1 @@
|
||||
<1B>i<EFBFBD>k<EFBFBD>\Gb<47><62><EFBFBD><EFBFBD>
|
||||
1
md4/tests/data/test9.input.bin
Normal file
1
md4/tests/data/test9.input.bin
Normal file
@@ -0,0 +1 @@
|
||||
The quick brown fox jumps over the lazy cog
|
||||
1
md4/tests/data/test9.output.bin
Normal file
1
md4/tests/data/test9.output.bin
Normal file
@@ -0,0 +1 @@
|
||||
Έnη<02>¥<EFBFBD>g-Vί
|
||||
19
md4/tests/lib.rs
Normal file
19
md4/tests/lib.rs
Normal file
@@ -0,0 +1,19 @@
|
||||
#![no_std]
|
||||
#[macro_use]
|
||||
extern crate crypto_tests;
|
||||
extern crate md4;
|
||||
|
||||
use crypto_tests::hash::{Test, main_test, one_million_a};
|
||||
|
||||
#[test]
|
||||
fn md4_main() {
|
||||
// Examples from wikipedia
|
||||
let tests = new_tests!("test1", "test2", "test3");
|
||||
main_test::<md4::Md4>(&tests);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn md4_1million_a() {
|
||||
let output = include_bytes!("data/one_million_a.output.bin");
|
||||
one_million_a::<md4::Md4>(output);
|
||||
}
|
||||
19
md5/Cargo.toml
Normal file
19
md5/Cargo.toml
Normal file
@@ -0,0 +1,19 @@
|
||||
[package]
|
||||
name = "md5"
|
||||
version = "0.3.0"
|
||||
authors = ["The Rust-Crypto Project Developers"]
|
||||
license = "MIT/Apache-2.0"
|
||||
description = "MD5 hash function"
|
||||
documentation = "https://docs.rs/md5"
|
||||
repository = "https://github.com/RustCrypto/rust-crypto-decoupled"
|
||||
keywords = ["crypto", "md5", "hash", "digest"]
|
||||
|
||||
[dependencies]
|
||||
fake-simd = "0.1"
|
||||
byte-tools = "0.1"
|
||||
digest = "0.2"
|
||||
digest-buffer = "0.1"
|
||||
generic-array = "0.5"
|
||||
|
||||
[dev-dependencies]
|
||||
crypto-tests = "0.1"
|
||||
201
md5/LICENSE-APACHE
Normal file
201
md5/LICENSE-APACHE
Normal 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.
|
||||
27
md5/LICENSE-MIT
Normal file
27
md5/LICENSE-MIT
Normal file
@@ -0,0 +1,27 @@
|
||||
Copyright (c) 2006-2009 Graydon Hoare
|
||||
Copyright (c) 2009-2013 Mozilla Foundation
|
||||
Copyright (c) 2016 Artyom Pavlov
|
||||
|
||||
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.
|
||||
40
md5/benches/lib.rs
Normal file
40
md5/benches/lib.rs
Normal file
@@ -0,0 +1,40 @@
|
||||
#![no_std]
|
||||
#![feature(test)]
|
||||
extern crate test;
|
||||
extern crate md5;
|
||||
extern crate digest;
|
||||
|
||||
use test::Bencher;
|
||||
use digest::Digest;
|
||||
use md5::Md5;
|
||||
|
||||
|
||||
#[bench]
|
||||
pub fn md5_10(bh: &mut Bencher) {
|
||||
let mut sh = Md5::new();
|
||||
let bytes = [1u8; 10];
|
||||
bh.iter(|| {
|
||||
sh.input(&bytes);
|
||||
});
|
||||
bh.bytes = bytes.len() as u64;
|
||||
}
|
||||
|
||||
#[bench]
|
||||
pub fn md5_1k(bh: &mut Bencher) {
|
||||
let mut sh = Md5::new();
|
||||
let bytes = [1u8; 1024];
|
||||
bh.iter(|| {
|
||||
sh.input(&bytes);
|
||||
});
|
||||
bh.bytes = bytes.len() as u64;
|
||||
}
|
||||
|
||||
#[bench]
|
||||
pub fn md5_64k(bh: &mut Bencher) {
|
||||
let mut sh = Md5::new();
|
||||
let bytes = [1u8; 65536];
|
||||
bh.iter(|| {
|
||||
sh.input(&bytes);
|
||||
});
|
||||
bh.bytes = bytes.len() as u64;
|
||||
}
|
||||
49
md5/examples/md5sum.rs
Normal file
49
md5/examples/md5sum.rs
Normal file
@@ -0,0 +1,49 @@
|
||||
extern crate md5;
|
||||
|
||||
use md5::{Md5, Digest};
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use std::io::{self, Read};
|
||||
|
||||
const BUFFER_SIZE: usize = 1024;
|
||||
|
||||
/// Print digest result as hex string and name pair
|
||||
fn print_result(sum: &[u8], name: &str) {
|
||||
for byte in sum {
|
||||
print!("{:02x}", byte);
|
||||
}
|
||||
println!("\t{}", name);
|
||||
}
|
||||
|
||||
/// Compute digest value for given `Reader` and print it
|
||||
/// On any error simply return without doing anything
|
||||
fn process<D: Digest, R: Read>(reader: &mut R, name: &str) {
|
||||
let mut sh = D::new();
|
||||
let mut buffer = [0u8; BUFFER_SIZE];
|
||||
loop {
|
||||
let n = match reader.read(&mut buffer) {
|
||||
Ok(n) => n,
|
||||
Err(_) => return,
|
||||
};
|
||||
sh.input(&buffer[..n]);
|
||||
if n == 0 || n < BUFFER_SIZE {
|
||||
break;
|
||||
}
|
||||
}
|
||||
print_result(&sh.result(), name);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let args = env::args();
|
||||
// Process files listed in command line arguments one by one
|
||||
// If no files provided process input from stdin
|
||||
if args.len() > 1 {
|
||||
for path in args.skip(1) {
|
||||
if let Ok(mut file) = fs::File::open(&path) {
|
||||
process::<Md5, _>(&mut file, &path);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
process::<Md5, _>(&mut io::stdin(), "-");
|
||||
}
|
||||
}
|
||||
27
md5/src/consts.rs
Normal file
27
md5/src/consts.rs
Normal file
@@ -0,0 +1,27 @@
|
||||
use simd::u32x4;
|
||||
|
||||
// Round 1 constants
|
||||
pub static C1: [u32; 16] = [0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
|
||||
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
|
||||
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
|
||||
0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821];
|
||||
|
||||
// Round 2 constants
|
||||
pub static C2: [u32; 16] = [0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
|
||||
0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
|
||||
0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
|
||||
0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a];
|
||||
|
||||
// Round 3 constants
|
||||
pub static C3: [u32; 16] = [0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
|
||||
0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
|
||||
0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
|
||||
0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665];
|
||||
|
||||
// Round 4 constants
|
||||
pub static C4: [u32; 16] = [0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
|
||||
0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
|
||||
0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
|
||||
0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391];
|
||||
|
||||
pub const S: u32x4 = u32x4(0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476);
|
||||
189
md5/src/lib.rs
Normal file
189
md5/src/lib.rs
Normal file
@@ -0,0 +1,189 @@
|
||||
//! The [MD5][1] hash function.
|
||||
//!
|
||||
//! [1]: https://en.wikipedia.org/wiki/MD5
|
||||
|
||||
#![no_std]
|
||||
extern crate generic_array;
|
||||
extern crate fake_simd as simd;
|
||||
extern crate byte_tools;
|
||||
extern crate digest;
|
||||
extern crate digest_buffer;
|
||||
|
||||
pub use digest::Digest;
|
||||
use byte_tools::{write_u32_le, read_u32v_le};
|
||||
use digest_buffer::{DigestBuffer};
|
||||
use simd::u32x4;
|
||||
use generic_array::GenericArray;
|
||||
use generic_array::typenum::{U16, U64};
|
||||
|
||||
|
||||
mod consts;
|
||||
use consts::{C1, C2, C3, C4, S};
|
||||
|
||||
type BlockSize = U64;
|
||||
|
||||
/// A structure that represents that state of a digest computation for the MD5
|
||||
/// digest function
|
||||
#[derive(Copy, Clone)]
|
||||
struct Md5State {
|
||||
s: u32x4,
|
||||
}
|
||||
|
||||
impl Md5State {
|
||||
fn new() -> Md5State {
|
||||
Md5State { s: S }
|
||||
}
|
||||
|
||||
fn process_block(&mut self, input: &[u8]) {
|
||||
fn f(u: u32, v: u32, w: u32) -> u32 { (u & v) | (!u & w) }
|
||||
|
||||
fn g(u: u32, v: u32, w: u32) -> u32 { (u & w) | (v & !w) }
|
||||
|
||||
fn h(u: u32, v: u32, w: u32) -> u32 { u ^ v ^ w }
|
||||
|
||||
fn i(u: u32, v: u32, w: u32) -> u32 { v ^ (u | !w) }
|
||||
|
||||
fn op_f(w: u32, x: u32, y: u32, z: u32, m: u32, s: u32) -> u32 {
|
||||
w.wrapping_add(f(x, y, z))
|
||||
.wrapping_add(m)
|
||||
.rotate_left(s)
|
||||
.wrapping_add(x)
|
||||
}
|
||||
|
||||
fn op_g(w: u32, x: u32, y: u32, z: u32, m: u32, s: u32) -> u32 {
|
||||
w.wrapping_add(g(x, y, z))
|
||||
.wrapping_add(m)
|
||||
.rotate_left(s)
|
||||
.wrapping_add(x)
|
||||
}
|
||||
|
||||
fn op_h(w: u32, x: u32, y: u32, z: u32, m: u32, s: u32) -> u32 {
|
||||
w.wrapping_add(h(x, y, z))
|
||||
.wrapping_add(m)
|
||||
.rotate_left(s)
|
||||
.wrapping_add(x)
|
||||
}
|
||||
|
||||
fn op_i(w: u32, x: u32, y: u32, z: u32, m: u32, s: u32) -> u32 {
|
||||
w.wrapping_add(i(x, y, z))
|
||||
.wrapping_add(m)
|
||||
.rotate_left(s)
|
||||
.wrapping_add(x)
|
||||
}
|
||||
|
||||
let u32x4(mut a, mut b, mut c, mut d) = self.s;
|
||||
|
||||
let mut data = [0u32; 16];
|
||||
|
||||
read_u32v_le(&mut data, input);
|
||||
|
||||
// FIXME: replace [0, 4, 8, 12] with (0..16).step_by(4)
|
||||
// after stabilization
|
||||
|
||||
// round 1
|
||||
for i in [0, 4, 8, 12].iter().cloned() {
|
||||
a = op_f(a, b, c, d, data[i].wrapping_add(C1[i]), 7);
|
||||
d = op_f(d, a, b, c, data[i + 1].wrapping_add(C1[i + 1]), 12);
|
||||
c = op_f(c, d, a, b, data[i + 2].wrapping_add(C1[i + 2]), 17);
|
||||
b = op_f(b, c, d, a, data[i + 3].wrapping_add(C1[i + 3]), 22);
|
||||
}
|
||||
|
||||
// round 2
|
||||
let mut t = 1;
|
||||
for i in [0, 4, 8, 12].iter().cloned() {
|
||||
let q = data[t & 0x0f].wrapping_add(C2[i]);
|
||||
a = op_g(a, b, c, d, q, 5);
|
||||
let q = data[(t + 5) & 0x0f].wrapping_add(C2[i + 1]);
|
||||
d = op_g(d, a, b, c, q, 9);
|
||||
let q = data[(t + 10) & 0x0f].wrapping_add(C2[i + 2]);
|
||||
c = op_g(c, d, a, b, q, 14);
|
||||
let q = data[(t + 15) & 0x0f].wrapping_add(C2[i + 3]);
|
||||
b = op_g(b, c, d, a, q, 20);
|
||||
t += 20;
|
||||
}
|
||||
|
||||
// round 3
|
||||
t = 5;
|
||||
for i in [0, 4, 8, 12].iter().cloned() {
|
||||
let q = data[t & 0x0f].wrapping_add(C3[i]);
|
||||
a = op_h(a, b, c, d, q, 4);
|
||||
let q = data[(t + 3) & 0x0f].wrapping_add(C3[i + 1]);
|
||||
d = op_h(d, a, b, c, q, 11);
|
||||
let q = data[(t + 6) & 0x0f].wrapping_add(C3[i + 2]);
|
||||
c = op_h(c, d, a, b, q, 16);
|
||||
let q = data[(t + 9) & 0x0f].wrapping_add(C3[i + 3]);
|
||||
b = op_h(b, c, d, a, q, 23);
|
||||
t += 12;
|
||||
}
|
||||
|
||||
// round 4
|
||||
t = 0;
|
||||
for i in [0, 4, 8, 12].iter().cloned() {
|
||||
let q = data[t & 0x0f].wrapping_add(C4[i]);
|
||||
a = op_i(a, b, c, d, q, 6);
|
||||
let q = data[(t + 7) & 0x0f].wrapping_add(C4[i + 1]);
|
||||
d = op_i(d, a, b, c, q, 10);
|
||||
let q = data[(t + 14) & 0x0f].wrapping_add(C4[i + 2]);
|
||||
c = op_i(c, d, a, b, q, 15);
|
||||
let q = data[(t + 21) & 0x0f].wrapping_add(C4[i + 3]);
|
||||
b = op_i(b, c, d, a, q, 21);
|
||||
t += 28;
|
||||
}
|
||||
|
||||
self.s = self.s + u32x4(a, b, c, d);
|
||||
}
|
||||
}
|
||||
|
||||
/// The MD5 Digest algorithm
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Md5 {
|
||||
length_bytes: u64,
|
||||
buffer: DigestBuffer<BlockSize>,
|
||||
state: Md5State,
|
||||
}
|
||||
|
||||
impl Md5 {
|
||||
fn finalize(&mut self) {
|
||||
let self_state = &mut self.state;
|
||||
self.buffer.standard_padding(8, |d: &[u8]| {
|
||||
self_state.process_block(d);
|
||||
});
|
||||
write_u32_le(self.buffer.next(4), (self.length_bytes << 3) as u32);
|
||||
write_u32_le(self.buffer.next(4), (self.length_bytes >> 29) as u32);
|
||||
self_state.process_block(self.buffer.full_buffer());
|
||||
}
|
||||
}
|
||||
|
||||
impl Digest for Md5 {
|
||||
type R = U16;
|
||||
type B = BlockSize;
|
||||
|
||||
fn new() -> Md5 {
|
||||
Md5 {
|
||||
length_bytes: 0,
|
||||
buffer: Default::default(),
|
||||
state: Md5State::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn input(&mut self, input: &[u8]) {
|
||||
// Unlike Sha1 and Sha2, the length value in MD5 is defined as
|
||||
// the length of the message mod 2^64 - ie: integer overflow is OK.
|
||||
self.length_bytes += input.len() as u64;
|
||||
let self_state = &mut self.state;
|
||||
self.buffer.input(input, |d: &[u8]| {
|
||||
self_state.process_block(d);
|
||||
});
|
||||
}
|
||||
|
||||
fn result(mut self) -> GenericArray<u8, Self::R> {
|
||||
self.finalize();
|
||||
|
||||
let mut out = GenericArray::new();
|
||||
write_u32_le(&mut out[0..4], self.state.s.0);
|
||||
write_u32_le(&mut out[4..8], self.state.s.1);
|
||||
write_u32_le(&mut out[8..12], self.state.s.2);
|
||||
write_u32_le(&mut out[12..16], self.state.s.3);
|
||||
out
|
||||
}
|
||||
}
|
||||
1
md5/tests/data/one_million_a.output.bin
Normal file
1
md5/tests/data/one_million_a.output.bin
Normal file
@@ -0,0 +1 @@
|
||||
wÖ®N|p5Â)o!
|
||||
0
md5/tests/data/test1.input.bin
Normal file
0
md5/tests/data/test1.input.bin
Normal file
BIN
md5/tests/data/test1.output.bin
Normal file
BIN
md5/tests/data/test1.output.bin
Normal file
Binary file not shown.
1
md5/tests/data/test2.input.bin
Normal file
1
md5/tests/data/test2.input.bin
Normal file
@@ -0,0 +1 @@
|
||||
The quick brown fox jumps over the lazy dog
|
||||
1
md5/tests/data/test2.output.bin
Normal file
1
md5/tests/data/test2.output.bin
Normal file
@@ -0,0 +1 @@
|
||||
<EFBFBD>}<7D>7+<2B><>k<EFBFBD>5B<35><19>
|
||||
1
md5/tests/data/test3.input.bin
Normal file
1
md5/tests/data/test3.input.bin
Normal file
@@ -0,0 +1 @@
|
||||
The quick brown fox jumps over the lazy dog.
|
||||
1
md5/tests/data/test3.output.bin
Normal file
1
md5/tests/data/test3.output.bin
Normal file
@@ -0,0 +1 @@
|
||||
駇 <09>哫㗖<>冥"刵
|
||||
19
md5/tests/lib.rs
Normal file
19
md5/tests/lib.rs
Normal file
@@ -0,0 +1,19 @@
|
||||
#![no_std]
|
||||
#[macro_use]
|
||||
extern crate crypto_tests;
|
||||
extern crate md5;
|
||||
|
||||
use crypto_tests::hash::{Test, main_test, one_million_a};
|
||||
|
||||
#[test]
|
||||
fn md5_main() {
|
||||
// Examples from wikipedia
|
||||
let tests = new_tests!("test1", "test2", "test3");
|
||||
main_test::<md5::Md5>(&tests);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn md5_1million_a() {
|
||||
let output = include_bytes!("data/one_million_a.output.bin");
|
||||
one_million_a::<md5::Md5>(output);
|
||||
}
|
||||
18
ripemd160/Cargo.toml
Normal file
18
ripemd160/Cargo.toml
Normal file
@@ -0,0 +1,18 @@
|
||||
[package]
|
||||
name = "ripemd160"
|
||||
version = "0.2.0"
|
||||
authors = ["The Rust-Crypto Project Developers"]
|
||||
license = "MIT/Apache-2.0"
|
||||
description = "RIPEMD-160 hash function"
|
||||
documentation = "https://docs.rs/ripemd160"
|
||||
repository = "https://github.com/RustCrypto/hashes"
|
||||
keywords = ["crypto", "ripemd160", "hash", "digest"]
|
||||
|
||||
[dependencies]
|
||||
byte-tools = "0.1"
|
||||
digest = "0.2"
|
||||
digest-buffer = "0.1"
|
||||
generic-array = "0.5"
|
||||
|
||||
[dev-dependencies]
|
||||
crypto-tests = "0.1"
|
||||
201
ripemd160/LICENSE-APACHE
Normal file
201
ripemd160/LICENSE-APACHE
Normal 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.
|
||||
27
ripemd160/LICENSE-MIT
Normal file
27
ripemd160/LICENSE-MIT
Normal file
@@ -0,0 +1,27 @@
|
||||
Copyright (c) 2006-2009 Graydon Hoare
|
||||
Copyright (c) 2009-2013 Mozilla Foundation
|
||||
Copyright (c) 2016 Artyom Pavlov
|
||||
|
||||
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.
|
||||
38
ripemd160/benches/lib.rs
Normal file
38
ripemd160/benches/lib.rs
Normal file
@@ -0,0 +1,38 @@
|
||||
#![no_std]
|
||||
#![feature(test)]
|
||||
extern crate test;
|
||||
extern crate ripemd160;
|
||||
|
||||
use test::Bencher;
|
||||
use ripemd160::{Ripemd160, Digest};
|
||||
|
||||
|
||||
#[bench]
|
||||
pub fn ripemd160_10(bh: &mut Bencher) {
|
||||
let mut sh = Ripemd160::new();
|
||||
let bytes = [1u8; 10];
|
||||
bh.iter(|| {
|
||||
sh.input(&bytes);
|
||||
});
|
||||
bh.bytes = bytes.len() as u64;
|
||||
}
|
||||
|
||||
#[bench]
|
||||
pub fn ripemd160_1k(bh: &mut Bencher) {
|
||||
let mut sh = Ripemd160::new();
|
||||
let bytes = [1u8; 1024];
|
||||
bh.iter(|| {
|
||||
sh.input(&bytes);
|
||||
});
|
||||
bh.bytes = bytes.len() as u64;
|
||||
}
|
||||
|
||||
#[bench]
|
||||
pub fn ripemd160_64k(bh: &mut Bencher) {
|
||||
let mut sh = Ripemd160::new();
|
||||
let bytes = [1u8; 65536];
|
||||
bh.iter(|| {
|
||||
sh.input(&bytes);
|
||||
});
|
||||
bh.bytes = bytes.len() as u64;
|
||||
}
|
||||
375
ripemd160/src/lib.rs
Normal file
375
ripemd160/src/lib.rs
Normal file
@@ -0,0 +1,375 @@
|
||||
//! An implementation of the RIPEMD-160 cryptographic hash.
|
||||
//!
|
||||
//! First create a `Ripemd160` object using the `Ripemd160` constructor,
|
||||
//! then feed it input using the `input` or `input_str` methods, which
|
||||
//! may be called any number of times.
|
||||
//!
|
||||
//! After the entire input has been fed to the hash read the result using
|
||||
//! the `result` or `result_str` methods.
|
||||
//!
|
||||
//! The `Ripemd160` object may be reused to create multiple hashes by
|
||||
//! calling the `reset` method.
|
||||
|
||||
#![no_std]
|
||||
extern crate generic_array;
|
||||
extern crate byte_tools;
|
||||
extern crate digest;
|
||||
extern crate digest_buffer;
|
||||
|
||||
pub use digest::Digest;
|
||||
use byte_tools::{write_u32_le, read_u32v_le, add_bytes_to_bits};
|
||||
use digest_buffer::{DigestBuffer};
|
||||
use generic_array::GenericArray;
|
||||
use generic_array::typenum::{U20, U64};
|
||||
|
||||
// Some unexported constants
|
||||
const DIGEST_BUF_LEN: usize = 5;
|
||||
const WORK_BUF_LEN: usize = 16;
|
||||
|
||||
type BlockSize = U64;
|
||||
|
||||
/// Structure representing the state of a Ripemd160 computation
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Ripemd160 {
|
||||
h: [u32; DIGEST_BUF_LEN],
|
||||
length_bits: u64,
|
||||
buffer: DigestBuffer<BlockSize>,
|
||||
}
|
||||
|
||||
fn circular_shift(bits: u32, word: u32) -> u32 {
|
||||
word << bits as usize | word >> (32u32 - bits) as usize
|
||||
}
|
||||
|
||||
macro_rules! round(
|
||||
($a:expr, $b:expr, $c:expr, $d:expr, $e:expr,
|
||||
$x:expr, $bits:expr, $add:expr, $round:expr) => ({
|
||||
$a = $a.wrapping_add($round).wrapping_add($x).wrapping_add($add);
|
||||
$a = circular_shift($bits, $a).wrapping_add($e);
|
||||
$c = circular_shift(10, $c);
|
||||
});
|
||||
);
|
||||
|
||||
macro_rules! process_block(
|
||||
($h:ident, $data:expr,
|
||||
$( round1: h_ordering $f0:expr, $f1:expr, $f2:expr, $f3:expr, $f4:expr;
|
||||
data_index $data_index1:expr; roll_shift $bits1:expr )*;
|
||||
$( round2: h_ordering $g0:expr, $g1:expr, $g2:expr, $g3:expr, $g4:expr;
|
||||
data_index $data_index2:expr; roll_shift $bits2:expr )*;
|
||||
$( round3: h_ordering $h0:expr, $h1:expr, $h2:expr, $h3:expr, $h4:expr;
|
||||
data_index $data_index3:expr; roll_shift $bits3:expr )*;
|
||||
$( round4: h_ordering $i0:expr, $i1:expr, $i2:expr, $i3:expr, $i4:expr;
|
||||
data_index $data_index4:expr; roll_shift $bits4:expr )*;
|
||||
$( round5: h_ordering $j0:expr, $j1:expr, $j2:expr, $j3:expr, $j4:expr;
|
||||
data_index $data_index5:expr; roll_shift $bits5:expr )*;
|
||||
$( par_round1: h_ordering $pj0:expr, $pj1:expr, $pj2:expr, $pj3:expr, $pj4:expr;
|
||||
data_index $pdata_index1:expr; roll_shift $pbits1:expr )*;
|
||||
$( par_round2: h_ordering $pi0:expr, $pi1:expr, $pi2:expr, $pi3:expr, $pi4:expr;
|
||||
data_index $pdata_index2:expr; roll_shift $pbits2:expr )*;
|
||||
$( par_round3: h_ordering $ph0:expr, $ph1:expr, $ph2:expr, $ph3:expr, $ph4:expr;
|
||||
data_index $pdata_index3:expr; roll_shift $pbits3:expr )*;
|
||||
$( par_round4: h_ordering $pg0:expr, $pg1:expr, $pg2:expr, $pg3:expr, $pg4:expr;
|
||||
data_index $pdata_index4:expr; roll_shift $pbits4:expr )*;
|
||||
$( par_round5: h_ordering $pf0:expr, $pf1:expr, $pf2:expr, $pf3:expr, $pf4:expr;
|
||||
data_index $pdata_index5:expr; roll_shift $pbits5:expr )*;
|
||||
) => ({
|
||||
let mut bb = *$h;
|
||||
let mut bbb = *$h;
|
||||
|
||||
// Round 1
|
||||
$( round!(bb[$f0], bb[$f1], bb[$f2], bb[$f3], bb[$f4],
|
||||
$data[$data_index1], $bits1, 0x00000000,
|
||||
bb[$f1] ^ bb[$f2] ^ bb[$f3]); )*
|
||||
|
||||
// Round 2
|
||||
$( round!(bb[$g0], bb[$g1], bb[$g2], bb[$g3], bb[$g4],
|
||||
$data[$data_index2], $bits2, 0x5a827999,
|
||||
(bb[$g1] & bb[$g2]) | (!bb[$g1] & bb[$g3])); )*
|
||||
|
||||
// Round 3
|
||||
$( round!(bb[$h0], bb[$h1], bb[$h2], bb[$h3], bb[$h4],
|
||||
$data[$data_index3], $bits3, 0x6ed9eba1,
|
||||
(bb[$h1] | !bb[$h2]) ^ bb[$h3]); )*
|
||||
|
||||
// Round 4
|
||||
$( round!(bb[$i0], bb[$i1], bb[$i2], bb[$i3], bb[$i4],
|
||||
$data[$data_index4], $bits4, 0x8f1bbcdc,
|
||||
(bb[$i1] & bb[$i3]) | (bb[$i2] & !bb[$i3])); )*
|
||||
|
||||
// Round 5
|
||||
$( round!(bb[$j0], bb[$j1], bb[$j2], bb[$j3], bb[$j4],
|
||||
$data[$data_index5], $bits5, 0xa953fd4e,
|
||||
bb[$j1] ^ (bb[$j2] | !bb[$j3])); )*
|
||||
|
||||
// Parallel rounds: these are the same as the previous five
|
||||
// rounds except that the constants have changed, we work
|
||||
// with the other buffer, and they are applied in reverse
|
||||
// order.
|
||||
|
||||
// Parallel Round 1
|
||||
$( round!(bbb[$pj0], bbb[$pj1], bbb[$pj2], bbb[$pj3], bbb[$pj4],
|
||||
$data[$pdata_index1], $pbits1, 0x50a28be6,
|
||||
bbb[$pj1] ^ (bbb[$pj2] | !bbb[$pj3])); )*
|
||||
|
||||
// Parallel Round 2
|
||||
$( round!(bbb[$pi0], bbb[$pi1], bbb[$pi2], bbb[$pi3], bbb[$pi4],
|
||||
$data[$pdata_index2], $pbits2, 0x5c4dd124,
|
||||
(bbb[$pi1] & bbb[$pi3]) | (bbb[$pi2] & !bbb[$pi3])); )*
|
||||
|
||||
// Parallel Round 3
|
||||
$( round!(bbb[$ph0], bbb[$ph1], bbb[$ph2], bbb[$ph3], bbb[$ph4],
|
||||
$data[$pdata_index3], $pbits3, 0x6d703ef3,
|
||||
(bbb[$ph1] | !bbb[$ph2]) ^ bbb[$ph3]); )*
|
||||
|
||||
// Parallel Round 4
|
||||
$( round!(bbb[$pg0], bbb[$pg1], bbb[$pg2], bbb[$pg3], bbb[$pg4],
|
||||
$data[$pdata_index4], $pbits4, 0x7a6d76e9,
|
||||
(bbb[$pg1] & bbb[$pg2]) | (!bbb[$pg1] & bbb[$pg3])); )*
|
||||
|
||||
// Parallel Round 5
|
||||
$( round!(bbb[$pf0], bbb[$pf1], bbb[$pf2], bbb[$pf3], bbb[$pf4],
|
||||
$data[$pdata_index5], $pbits5, 0x00000000,
|
||||
bbb[$pf1] ^ bbb[$pf2] ^ bbb[$pf3]); )*
|
||||
|
||||
// Combine results
|
||||
bbb[3] = bbb[3].wrapping_add($h[1]).wrapping_add(bb[2]);
|
||||
$h[1] = $h[2].wrapping_add(bb[3]).wrapping_add(bbb[4]);
|
||||
$h[2] = $h[3].wrapping_add(bb[4]).wrapping_add(bbb[0]);
|
||||
$h[3] = $h[4].wrapping_add(bb[0]).wrapping_add(bbb[1]);
|
||||
$h[4] = $h[0].wrapping_add(bb[1]).wrapping_add(bbb[2]);
|
||||
$h[0] = bbb[3];
|
||||
});
|
||||
);
|
||||
|
||||
fn process_msg_block(data: &[u8], h: &mut [u32; DIGEST_BUF_LEN]) {
|
||||
let mut w = [0u32; WORK_BUF_LEN];
|
||||
read_u32v_le(&mut w[0..16], data);
|
||||
process_block!(h, w[..],
|
||||
// Round 1
|
||||
round1: h_ordering 0, 1, 2, 3, 4; data_index 0; roll_shift 11
|
||||
round1: h_ordering 4, 0, 1, 2, 3; data_index 1; roll_shift 14
|
||||
round1: h_ordering 3, 4, 0, 1, 2; data_index 2; roll_shift 15
|
||||
round1: h_ordering 2, 3, 4, 0, 1; data_index 3; roll_shift 12
|
||||
round1: h_ordering 1, 2, 3, 4, 0; data_index 4; roll_shift 5
|
||||
round1: h_ordering 0, 1, 2, 3, 4; data_index 5; roll_shift 8
|
||||
round1: h_ordering 4, 0, 1, 2, 3; data_index 6; roll_shift 7
|
||||
round1: h_ordering 3, 4, 0, 1, 2; data_index 7; roll_shift 9
|
||||
round1: h_ordering 2, 3, 4, 0, 1; data_index 8; roll_shift 11
|
||||
round1: h_ordering 1, 2, 3, 4, 0; data_index 9; roll_shift 13
|
||||
round1: h_ordering 0, 1, 2, 3, 4; data_index 10; roll_shift 14
|
||||
round1: h_ordering 4, 0, 1, 2, 3; data_index 11; roll_shift 15
|
||||
round1: h_ordering 3, 4, 0, 1, 2; data_index 12; roll_shift 6
|
||||
round1: h_ordering 2, 3, 4, 0, 1; data_index 13; roll_shift 7
|
||||
round1: h_ordering 1, 2, 3, 4, 0; data_index 14; roll_shift 9
|
||||
round1: h_ordering 0, 1, 2, 3, 4; data_index 15; roll_shift 8;
|
||||
|
||||
// Round 2
|
||||
round2: h_ordering 4, 0, 1, 2, 3; data_index 7; roll_shift 7
|
||||
round2: h_ordering 3, 4, 0, 1, 2; data_index 4; roll_shift 6
|
||||
round2: h_ordering 2, 3, 4, 0, 1; data_index 13; roll_shift 8
|
||||
round2: h_ordering 1, 2, 3, 4, 0; data_index 1; roll_shift 13
|
||||
round2: h_ordering 0, 1, 2, 3, 4; data_index 10; roll_shift 11
|
||||
round2: h_ordering 4, 0, 1, 2, 3; data_index 6; roll_shift 9
|
||||
round2: h_ordering 3, 4, 0, 1, 2; data_index 15; roll_shift 7
|
||||
round2: h_ordering 2, 3, 4, 0, 1; data_index 3; roll_shift 15
|
||||
round2: h_ordering 1, 2, 3, 4, 0; data_index 12; roll_shift 7
|
||||
round2: h_ordering 0, 1, 2, 3, 4; data_index 0; roll_shift 12
|
||||
round2: h_ordering 4, 0, 1, 2, 3; data_index 9; roll_shift 15
|
||||
round2: h_ordering 3, 4, 0, 1, 2; data_index 5; roll_shift 9
|
||||
round2: h_ordering 2, 3, 4, 0, 1; data_index 2; roll_shift 11
|
||||
round2: h_ordering 1, 2, 3, 4, 0; data_index 14; roll_shift 7
|
||||
round2: h_ordering 0, 1, 2, 3, 4; data_index 11; roll_shift 13
|
||||
round2: h_ordering 4, 0, 1, 2, 3; data_index 8; roll_shift 12;
|
||||
|
||||
// Round 3
|
||||
round3: h_ordering 3, 4, 0, 1, 2; data_index 3; roll_shift 11
|
||||
round3: h_ordering 2, 3, 4, 0, 1; data_index 10; roll_shift 13
|
||||
round3: h_ordering 1, 2, 3, 4, 0; data_index 14; roll_shift 6
|
||||
round3: h_ordering 0, 1, 2, 3, 4; data_index 4; roll_shift 7
|
||||
round3: h_ordering 4, 0, 1, 2, 3; data_index 9; roll_shift 14
|
||||
round3: h_ordering 3, 4, 0, 1, 2; data_index 15; roll_shift 9
|
||||
round3: h_ordering 2, 3, 4, 0, 1; data_index 8; roll_shift 13
|
||||
round3: h_ordering 1, 2, 3, 4, 0; data_index 1; roll_shift 15
|
||||
round3: h_ordering 0, 1, 2, 3, 4; data_index 2; roll_shift 14
|
||||
round3: h_ordering 4, 0, 1, 2, 3; data_index 7; roll_shift 8
|
||||
round3: h_ordering 3, 4, 0, 1, 2; data_index 0; roll_shift 13
|
||||
round3: h_ordering 2, 3, 4, 0, 1; data_index 6; roll_shift 6
|
||||
round3: h_ordering 1, 2, 3, 4, 0; data_index 13; roll_shift 5
|
||||
round3: h_ordering 0, 1, 2, 3, 4; data_index 11; roll_shift 12
|
||||
round3: h_ordering 4, 0, 1, 2, 3; data_index 5; roll_shift 7
|
||||
round3: h_ordering 3, 4, 0, 1, 2; data_index 12; roll_shift 5;
|
||||
|
||||
// Round 4
|
||||
round4: h_ordering 2, 3, 4, 0, 1; data_index 1; roll_shift 11
|
||||
round4: h_ordering 1, 2, 3, 4, 0; data_index 9; roll_shift 12
|
||||
round4: h_ordering 0, 1, 2, 3, 4; data_index 11; roll_shift 14
|
||||
round4: h_ordering 4, 0, 1, 2, 3; data_index 10; roll_shift 15
|
||||
round4: h_ordering 3, 4, 0, 1, 2; data_index 0; roll_shift 14
|
||||
round4: h_ordering 2, 3, 4, 0, 1; data_index 8; roll_shift 15
|
||||
round4: h_ordering 1, 2, 3, 4, 0; data_index 12; roll_shift 9
|
||||
round4: h_ordering 0, 1, 2, 3, 4; data_index 4; roll_shift 8
|
||||
round4: h_ordering 4, 0, 1, 2, 3; data_index 13; roll_shift 9
|
||||
round4: h_ordering 3, 4, 0, 1, 2; data_index 3; roll_shift 14
|
||||
round4: h_ordering 2, 3, 4, 0, 1; data_index 7; roll_shift 5
|
||||
round4: h_ordering 1, 2, 3, 4, 0; data_index 15; roll_shift 6
|
||||
round4: h_ordering 0, 1, 2, 3, 4; data_index 14; roll_shift 8
|
||||
round4: h_ordering 4, 0, 1, 2, 3; data_index 5; roll_shift 6
|
||||
round4: h_ordering 3, 4, 0, 1, 2; data_index 6; roll_shift 5
|
||||
round4: h_ordering 2, 3, 4, 0, 1; data_index 2; roll_shift 12;
|
||||
|
||||
// Round 5
|
||||
round5: h_ordering 1, 2, 3, 4, 0; data_index 4; roll_shift 9
|
||||
round5: h_ordering 0, 1, 2, 3, 4; data_index 0; roll_shift 15
|
||||
round5: h_ordering 4, 0, 1, 2, 3; data_index 5; roll_shift 5
|
||||
round5: h_ordering 3, 4, 0, 1, 2; data_index 9; roll_shift 11
|
||||
round5: h_ordering 2, 3, 4, 0, 1; data_index 7; roll_shift 6
|
||||
round5: h_ordering 1, 2, 3, 4, 0; data_index 12; roll_shift 8
|
||||
round5: h_ordering 0, 1, 2, 3, 4; data_index 2; roll_shift 13
|
||||
round5: h_ordering 4, 0, 1, 2, 3; data_index 10; roll_shift 12
|
||||
round5: h_ordering 3, 4, 0, 1, 2; data_index 14; roll_shift 5
|
||||
round5: h_ordering 2, 3, 4, 0, 1; data_index 1; roll_shift 12
|
||||
round5: h_ordering 1, 2, 3, 4, 0; data_index 3; roll_shift 13
|
||||
round5: h_ordering 0, 1, 2, 3, 4; data_index 8; roll_shift 14
|
||||
round5: h_ordering 4, 0, 1, 2, 3; data_index 11; roll_shift 11
|
||||
round5: h_ordering 3, 4, 0, 1, 2; data_index 6; roll_shift 8
|
||||
round5: h_ordering 2, 3, 4, 0, 1; data_index 15; roll_shift 5
|
||||
round5: h_ordering 1, 2, 3, 4, 0; data_index 13; roll_shift 6;
|
||||
|
||||
// Parallel Round 1
|
||||
par_round1: h_ordering 0, 1, 2, 3, 4; data_index 5; roll_shift 8
|
||||
par_round1: h_ordering 4, 0, 1, 2, 3; data_index 14; roll_shift 9
|
||||
par_round1: h_ordering 3, 4, 0, 1, 2; data_index 7; roll_shift 9
|
||||
par_round1: h_ordering 2, 3, 4, 0, 1; data_index 0; roll_shift 11
|
||||
par_round1: h_ordering 1, 2, 3, 4, 0; data_index 9; roll_shift 13
|
||||
par_round1: h_ordering 0, 1, 2, 3, 4; data_index 2; roll_shift 15
|
||||
par_round1: h_ordering 4, 0, 1, 2, 3; data_index 11; roll_shift 15
|
||||
par_round1: h_ordering 3, 4, 0, 1, 2; data_index 4; roll_shift 5
|
||||
par_round1: h_ordering 2, 3, 4, 0, 1; data_index 13; roll_shift 7
|
||||
par_round1: h_ordering 1, 2, 3, 4, 0; data_index 6; roll_shift 7
|
||||
par_round1: h_ordering 0, 1, 2, 3, 4; data_index 15; roll_shift 8
|
||||
par_round1: h_ordering 4, 0, 1, 2, 3; data_index 8; roll_shift 11
|
||||
par_round1: h_ordering 3, 4, 0, 1, 2; data_index 1; roll_shift 14
|
||||
par_round1: h_ordering 2, 3, 4, 0, 1; data_index 10; roll_shift 14
|
||||
par_round1: h_ordering 1, 2, 3, 4, 0; data_index 3; roll_shift 12
|
||||
par_round1: h_ordering 0, 1, 2, 3, 4; data_index 12; roll_shift 6;
|
||||
|
||||
// Parallel Round 2
|
||||
par_round2: h_ordering 4, 0, 1, 2, 3; data_index 6; roll_shift 9
|
||||
par_round2: h_ordering 3, 4, 0, 1, 2; data_index 11; roll_shift 13
|
||||
par_round2: h_ordering 2, 3, 4, 0, 1; data_index 3; roll_shift 15
|
||||
par_round2: h_ordering 1, 2, 3, 4, 0; data_index 7; roll_shift 7
|
||||
par_round2: h_ordering 0, 1, 2, 3, 4; data_index 0; roll_shift 12
|
||||
par_round2: h_ordering 4, 0, 1, 2, 3; data_index 13; roll_shift 8
|
||||
par_round2: h_ordering 3, 4, 0, 1, 2; data_index 5; roll_shift 9
|
||||
par_round2: h_ordering 2, 3, 4, 0, 1; data_index 10; roll_shift 11
|
||||
par_round2: h_ordering 1, 2, 3, 4, 0; data_index 14; roll_shift 7
|
||||
par_round2: h_ordering 0, 1, 2, 3, 4; data_index 15; roll_shift 7
|
||||
par_round2: h_ordering 4, 0, 1, 2, 3; data_index 8; roll_shift 12
|
||||
par_round2: h_ordering 3, 4, 0, 1, 2; data_index 12; roll_shift 7
|
||||
par_round2: h_ordering 2, 3, 4, 0, 1; data_index 4; roll_shift 6
|
||||
par_round2: h_ordering 1, 2, 3, 4, 0; data_index 9; roll_shift 15
|
||||
par_round2: h_ordering 0, 1, 2, 3, 4; data_index 1; roll_shift 13
|
||||
par_round2: h_ordering 4, 0, 1, 2, 3; data_index 2; roll_shift 11;
|
||||
|
||||
// Parallel Round 3
|
||||
par_round3: h_ordering 3, 4, 0, 1, 2; data_index 15; roll_shift 9
|
||||
par_round3: h_ordering 2, 3, 4, 0, 1; data_index 5; roll_shift 7
|
||||
par_round3: h_ordering 1, 2, 3, 4, 0; data_index 1; roll_shift 15
|
||||
par_round3: h_ordering 0, 1, 2, 3, 4; data_index 3; roll_shift 11
|
||||
par_round3: h_ordering 4, 0, 1, 2, 3; data_index 7; roll_shift 8
|
||||
par_round3: h_ordering 3, 4, 0, 1, 2; data_index 14; roll_shift 6
|
||||
par_round3: h_ordering 2, 3, 4, 0, 1; data_index 6; roll_shift 6
|
||||
par_round3: h_ordering 1, 2, 3, 4, 0; data_index 9; roll_shift 14
|
||||
par_round3: h_ordering 0, 1, 2, 3, 4; data_index 11; roll_shift 12
|
||||
par_round3: h_ordering 4, 0, 1, 2, 3; data_index 8; roll_shift 13
|
||||
par_round3: h_ordering 3, 4, 0, 1, 2; data_index 12; roll_shift 5
|
||||
par_round3: h_ordering 2, 3, 4, 0, 1; data_index 2; roll_shift 14
|
||||
par_round3: h_ordering 1, 2, 3, 4, 0; data_index 10; roll_shift 13
|
||||
par_round3: h_ordering 0, 1, 2, 3, 4; data_index 0; roll_shift 13
|
||||
par_round3: h_ordering 4, 0, 1, 2, 3; data_index 4; roll_shift 7
|
||||
par_round3: h_ordering 3, 4, 0, 1, 2; data_index 13; roll_shift 5;
|
||||
|
||||
// Parallel Round 4
|
||||
par_round4: h_ordering 2, 3, 4, 0, 1; data_index 8; roll_shift 15
|
||||
par_round4: h_ordering 1, 2, 3, 4, 0; data_index 6; roll_shift 5
|
||||
par_round4: h_ordering 0, 1, 2, 3, 4; data_index 4; roll_shift 8
|
||||
par_round4: h_ordering 4, 0, 1, 2, 3; data_index 1; roll_shift 11
|
||||
par_round4: h_ordering 3, 4, 0, 1, 2; data_index 3; roll_shift 14
|
||||
par_round4: h_ordering 2, 3, 4, 0, 1; data_index 11; roll_shift 14
|
||||
par_round4: h_ordering 1, 2, 3, 4, 0; data_index 15; roll_shift 6
|
||||
par_round4: h_ordering 0, 1, 2, 3, 4; data_index 0; roll_shift 14
|
||||
par_round4: h_ordering 4, 0, 1, 2, 3; data_index 5; roll_shift 6
|
||||
par_round4: h_ordering 3, 4, 0, 1, 2; data_index 12; roll_shift 9
|
||||
par_round4: h_ordering 2, 3, 4, 0, 1; data_index 2; roll_shift 12
|
||||
par_round4: h_ordering 1, 2, 3, 4, 0; data_index 13; roll_shift 9
|
||||
par_round4: h_ordering 0, 1, 2, 3, 4; data_index 9; roll_shift 12
|
||||
par_round4: h_ordering 4, 0, 1, 2, 3; data_index 7; roll_shift 5
|
||||
par_round4: h_ordering 3, 4, 0, 1, 2; data_index 10; roll_shift 15
|
||||
par_round4: h_ordering 2, 3, 4, 0, 1; data_index 14; roll_shift 8;
|
||||
|
||||
// Parallel Round 5
|
||||
par_round5: h_ordering 1, 2, 3, 4, 0; data_index 12; roll_shift 8
|
||||
par_round5: h_ordering 0, 1, 2, 3, 4; data_index 15; roll_shift 5
|
||||
par_round5: h_ordering 4, 0, 1, 2, 3; data_index 10; roll_shift 12
|
||||
par_round5: h_ordering 3, 4, 0, 1, 2; data_index 4; roll_shift 9
|
||||
par_round5: h_ordering 2, 3, 4, 0, 1; data_index 1; roll_shift 12
|
||||
par_round5: h_ordering 1, 2, 3, 4, 0; data_index 5; roll_shift 5
|
||||
par_round5: h_ordering 0, 1, 2, 3, 4; data_index 8; roll_shift 14
|
||||
par_round5: h_ordering 4, 0, 1, 2, 3; data_index 7; roll_shift 6
|
||||
par_round5: h_ordering 3, 4, 0, 1, 2; data_index 6; roll_shift 8
|
||||
par_round5: h_ordering 2, 3, 4, 0, 1; data_index 2; roll_shift 13
|
||||
par_round5: h_ordering 1, 2, 3, 4, 0; data_index 13; roll_shift 6
|
||||
par_round5: h_ordering 0, 1, 2, 3, 4; data_index 14; roll_shift 5
|
||||
par_round5: h_ordering 4, 0, 1, 2, 3; data_index 0; roll_shift 15
|
||||
par_round5: h_ordering 3, 4, 0, 1, 2; data_index 3; roll_shift 13
|
||||
par_round5: h_ordering 2, 3, 4, 0, 1; data_index 9; roll_shift 11
|
||||
par_round5: h_ordering 1, 2, 3, 4, 0; data_index 11; roll_shift 11;
|
||||
);
|
||||
}
|
||||
|
||||
impl Ripemd160 {
|
||||
fn finalize(&mut self) {
|
||||
let st_h = &mut self.h;
|
||||
self.buffer.standard_padding(8, |d: &[u8]| {
|
||||
process_msg_block(d, &mut *st_h)
|
||||
});
|
||||
|
||||
write_u32_le(self.buffer.next(4), self.length_bits as u32);
|
||||
write_u32_le(self.buffer.next(4), (self.length_bits >> 32) as u32);
|
||||
process_msg_block(self.buffer.full_buffer(), st_h);
|
||||
}
|
||||
}
|
||||
|
||||
impl Digest for Ripemd160 {
|
||||
type R = U20;
|
||||
type B = BlockSize;
|
||||
|
||||
fn new() -> Ripemd160 {
|
||||
Ripemd160 {
|
||||
h: [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0],
|
||||
length_bits: 0,
|
||||
buffer: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
fn input(&mut self, input: &[u8]) {
|
||||
// Assumes that input.len() can be converted to u64 without overflow
|
||||
self.length_bits = add_bytes_to_bits(self.length_bits,
|
||||
input.len() as u64);
|
||||
let st_h = &mut self.h;
|
||||
self.buffer.input(input, |d: &[u8]| {
|
||||
process_msg_block(d, &mut *st_h);
|
||||
});
|
||||
}
|
||||
|
||||
fn result(mut self) -> GenericArray<u8, Self::R> {
|
||||
self.finalize();
|
||||
|
||||
let mut out = GenericArray::new();
|
||||
write_u32_le(&mut out[0..4], self.h[0]);
|
||||
write_u32_le(&mut out[4..8], self.h[1]);
|
||||
write_u32_le(&mut out[8..12], self.h[2]);
|
||||
write_u32_le(&mut out[12..16], self.h[3]);
|
||||
write_u32_le(&mut out[16..20], self.h[4]);
|
||||
out
|
||||
}
|
||||
}
|
||||
1
ripemd160/tests/data/one_million_a.output.bin
Normal file
1
ripemd160/tests/data/one_million_a.output.bin
Normal file
@@ -0,0 +1 @@
|
||||
Rx2Cチi{ロ疥7<E796A5>h<7F>%ワ(
|
||||
1
ripemd160/tests/data/test1.input.bin
Normal file
1
ripemd160/tests/data/test1.input.bin
Normal file
@@ -0,0 +1 @@
|
||||
abc
|
||||
1
ripemd160/tests/data/test1.output.bin
Normal file
1
ripemd160/tests/data/test1.output.bin
Normal file
@@ -0,0 +1 @@
|
||||
޲÷à]˜z›JŽ˜Æ°‡ñZü
|
||||
1
ripemd160/tests/data/test2.input.bin
Normal file
1
ripemd160/tests/data/test2.input.bin
Normal file
@@ -0,0 +1 @@
|
||||
abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq
|
||||
1
ripemd160/tests/data/test2.output.bin
Normal file
1
ripemd160/tests/data/test2.output.bin
Normal file
@@ -0,0 +1 @@
|
||||
<12>S8J<38><0C><><05>l'<27><><EFBFBD><EFBFBD>b<EFBFBD>+
|
||||
1
ripemd160/tests/data/test3.input.bin
Normal file
1
ripemd160/tests/data/test3.input.bin
Normal file
@@ -0,0 +1 @@
|
||||
The quick brown fox jumps over the lazy dog
|
||||
1
ripemd160/tests/data/test3.output.bin
Normal file
1
ripemd160/tests/data/test3.output.bin
Normal file
@@ -0,0 +1 @@
|
||||
7<EFBFBD>2<EFBFBD><EFBFBD><EFBFBD>{<7B><><EFBFBD>Ԗ<EFBFBD>q<EFBFBD>g<1C><>;
|
||||
1
ripemd160/tests/data/test4.input.bin
Normal file
1
ripemd160/tests/data/test4.input.bin
Normal file
@@ -0,0 +1 @@
|
||||
The quick brown fox jumps over the lazy cog
|
||||
1
ripemd160/tests/data/test4.output.bin
Normal file
1
ripemd160/tests/data/test4.output.bin
Normal file
@@ -0,0 +1 @@
|
||||
r゚i 3タクカュw邯<77>ハラ
|
||||
19
ripemd160/tests/lib.rs
Normal file
19
ripemd160/tests/lib.rs
Normal file
@@ -0,0 +1,19 @@
|
||||
#![no_std]
|
||||
#[macro_use]
|
||||
extern crate crypto_tests;
|
||||
extern crate ripemd160;
|
||||
|
||||
use crypto_tests::hash::{Test, main_test, one_million_a};
|
||||
|
||||
#[test]
|
||||
fn ripemd160_main() {
|
||||
// Test messages from FIPS 180-1
|
||||
let tests = new_tests!("test1", "test2", "test3", "test4");
|
||||
main_test::<ripemd160::Ripemd160>(&tests);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ripemd160_1million_a() {
|
||||
let output = include_bytes!("data/one_million_a.output.bin");
|
||||
one_million_a::<ripemd160::Ripemd160>(output);
|
||||
}
|
||||
19
sha1/Cargo.toml
Normal file
19
sha1/Cargo.toml
Normal file
@@ -0,0 +1,19 @@
|
||||
[package]
|
||||
name = "sha1"
|
||||
version = "0.1.0"
|
||||
authors = ["The Rust-Crypto Project Developers"]
|
||||
license = "MIT/Apache-2.0"
|
||||
description = "SHA-1 hash function"
|
||||
#documentation = "https://docs.rs/sha1"
|
||||
repository = "https://github.com/RustCrypto/hashes"
|
||||
keywords = ["crypto", "sha1", "hash", "digest"]
|
||||
|
||||
[dependencies]
|
||||
fake-simd = "0.1"
|
||||
byte-tools = "0.1"
|
||||
digest = "0.2"
|
||||
digest-buffer = "0.1"
|
||||
generic-array = "0.5"
|
||||
|
||||
[dev-dependencies]
|
||||
crypto-tests = "0.1"
|
||||
201
sha1/LICENSE-APACHE
Normal file
201
sha1/LICENSE-APACHE
Normal 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.
|
||||
27
sha1/LICENSE-MIT
Normal file
27
sha1/LICENSE-MIT
Normal file
@@ -0,0 +1,27 @@
|
||||
Copyright (c) 2006-2009 Graydon Hoare
|
||||
Copyright (c) 2009-2013 Mozilla Foundation
|
||||
Copyright (c) 2016 Artyom Pavlov
|
||||
|
||||
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.
|
||||
37
sha1/benches/lib.rs
Normal file
37
sha1/benches/lib.rs
Normal file
@@ -0,0 +1,37 @@
|
||||
#![no_std]
|
||||
#![feature(test)]
|
||||
extern crate test;
|
||||
extern crate sha1;
|
||||
|
||||
use test::Bencher;
|
||||
use sha1::{Sha1, Digest};
|
||||
|
||||
#[bench]
|
||||
pub fn sha1_10(bh: &mut Bencher) {
|
||||
let mut sh = Sha1::new();
|
||||
let bytes = [1u8; 10];
|
||||
bh.iter(|| {
|
||||
sh.input(&bytes);
|
||||
});
|
||||
bh.bytes = bytes.len() as u64;
|
||||
}
|
||||
|
||||
#[bench]
|
||||
pub fn sha1_1k(bh: &mut Bencher) {
|
||||
let mut sh = Sha1::new();
|
||||
let bytes = [1u8; 1024];
|
||||
bh.iter(|| {
|
||||
sh.input(&bytes);
|
||||
});
|
||||
bh.bytes = bytes.len() as u64;
|
||||
}
|
||||
|
||||
#[bench]
|
||||
pub fn sha1_64k(bh: &mut Bencher) {
|
||||
let mut sh = Sha1::new();
|
||||
let bytes = [1u8; 65536];
|
||||
bh.iter(|| {
|
||||
sh.input(&bytes);
|
||||
});
|
||||
bh.bytes = bytes.len() as u64;
|
||||
}
|
||||
49
sha1/examples/sha1sum.rs
Normal file
49
sha1/examples/sha1sum.rs
Normal file
@@ -0,0 +1,49 @@
|
||||
extern crate sha1;
|
||||
|
||||
use sha1::{Sha1, Digest};
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use std::io::{self, Read};
|
||||
|
||||
const BUFFER_SIZE: usize = 1024;
|
||||
|
||||
/// Print digest result as hex string and name pair
|
||||
fn print_result(sum: &[u8], name: &str) {
|
||||
for byte in sum {
|
||||
print!("{:02x}", byte);
|
||||
}
|
||||
println!("\t{}", name);
|
||||
}
|
||||
|
||||
/// Compute digest value for given `Reader` and print it
|
||||
/// On any error simply return without doing anything
|
||||
fn process<D: Digest, R: Read>(reader: &mut R, name: &str) {
|
||||
let mut sh = D::new();
|
||||
let mut buffer = [0u8; BUFFER_SIZE];
|
||||
loop {
|
||||
let n = match reader.read(&mut buffer) {
|
||||
Ok(n) => n,
|
||||
Err(_) => return,
|
||||
};
|
||||
sh.input(&buffer[..n]);
|
||||
if n == 0 || n < BUFFER_SIZE {
|
||||
break;
|
||||
}
|
||||
}
|
||||
print_result(&sh.result(), name);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let args = env::args();
|
||||
// Process files listed in command line arguments one by one
|
||||
// If no files provided process input from stdin
|
||||
if args.len() > 1 {
|
||||
for path in args.skip(1) {
|
||||
if let Ok(mut file) = fs::File::open(&path) {
|
||||
process::<Sha1, _>(&mut file, &path);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
process::<Sha1, _>(&mut io::stdin(), "-");
|
||||
}
|
||||
}
|
||||
10
sha1/src/consts.rs
Normal file
10
sha1/src/consts.rs
Normal file
@@ -0,0 +1,10 @@
|
||||
pub const STATE_LEN: usize = 5;
|
||||
pub const BLOCK_LEN: usize = 16;
|
||||
|
||||
pub const K0: u32 = 0x5A827999u32;
|
||||
pub const K1: u32 = 0x6ED9EBA1u32;
|
||||
pub const K2: u32 = 0x8F1BBCDCu32;
|
||||
pub const K3: u32 = 0xCA62C1D6u32;
|
||||
|
||||
pub const H: [u32; STATE_LEN] = [0x67452301, 0xEFCDAB89, 0x98BADCFE,
|
||||
0x10325476, 0xC3D2E1F0];
|
||||
127
sha1/src/lib.rs
Normal file
127
sha1/src/lib.rs
Normal file
@@ -0,0 +1,127 @@
|
||||
//! An implementation of the SHA-1 cryptographic hash algorithm.
|
||||
|
||||
//! To use this module, first create a `Sha1` object using the `Sha1` constructor,
|
||||
//! then feed it an input message using the `input` or `input_str` methods,
|
||||
//! which may be called any number of times; they will buffer the input until
|
||||
//! there is enough to call the block algorithm.
|
||||
//!
|
||||
//! After the entire input has been fed to the hash read the result using
|
||||
//! the `result` or `result_str` methods. The first will return bytes, and
|
||||
//! the second will return a `String` object of the same bytes represented
|
||||
//! in hexadecimal form.
|
||||
//!
|
||||
//! The `Sha1` object may be reused to create multiple hashes by calling
|
||||
//! the `reset()` method. These traits are implemented by all hash digest
|
||||
//! algorithms that implement the `Digest` trait. An example of use is:
|
||||
//!
|
||||
//! ```rust
|
||||
//! use sha1::{Sha1, Digest};
|
||||
//!
|
||||
//! // create a Sha1 object
|
||||
//! let mut sh = Sha1::new();
|
||||
//!
|
||||
//! // write input message
|
||||
//! sh.input(b"hello world");
|
||||
//!
|
||||
//! // read hash digest in the form of GenericArray which is in this case
|
||||
//! // equivalent to [u8; 20]
|
||||
//! let output = sh.result();
|
||||
//! assert_eq!(output[..], [0x2a, 0xae, 0x6c, 0x35, 0xc9, 0x4f, 0xcf, 0xb4, 0x15, 0xdb,
|
||||
//! 0xe9, 0x5f, 0x40, 0x8b, 0x9c, 0xe9, 0x1e, 0xe8, 0x46, 0xed]);
|
||||
//! ```
|
||||
//!
|
||||
//! # Mathematics
|
||||
//!
|
||||
//! The mathematics of the SHA-1 algorithm are quite interesting. In its
|
||||
//! definition, The SHA-1 algorithm uses:
|
||||
//!
|
||||
//! * 1 binary operation on bit-arrays:
|
||||
//! * "exclusive or" (XOR)
|
||||
//! * 2 binary operations on integers:
|
||||
//! * "addition" (ADD)
|
||||
//! * "rotate left" (ROL)
|
||||
//! * 3 ternary operations on bit-arrays:
|
||||
//! * "choose" (CH)
|
||||
//! * "parity" (PAR)
|
||||
//! * "majority" (MAJ)
|
||||
//!
|
||||
//! Some of these functions are commonly found in all hash digest
|
||||
//! algorithms, but some, like "parity" is only found in SHA-1.
|
||||
|
||||
#![no_std]
|
||||
extern crate generic_array;
|
||||
extern crate byte_tools;
|
||||
extern crate digest;
|
||||
extern crate digest_buffer;
|
||||
extern crate fake_simd as simd;
|
||||
|
||||
pub use digest::Digest;
|
||||
use byte_tools::{write_u32_be, add_bytes_to_bits};
|
||||
use digest_buffer::DigestBuffer;
|
||||
use generic_array::GenericArray;
|
||||
use generic_array::typenum::{U20, U64};
|
||||
|
||||
mod consts;
|
||||
mod utils;
|
||||
|
||||
use consts::{STATE_LEN, H};
|
||||
use utils::{sha1_digest_block};
|
||||
|
||||
type BlockSize = U64;
|
||||
|
||||
/// Structure representing the state of a Sha1 computation
|
||||
#[derive(Clone)]
|
||||
pub struct Sha1 {
|
||||
h: [u32; STATE_LEN],
|
||||
length_bits: u64,
|
||||
buffer: DigestBuffer<BlockSize>,
|
||||
}
|
||||
|
||||
impl Sha1 {
|
||||
fn finalize(&mut self) {
|
||||
let st_h = &mut self.h;
|
||||
self.buffer
|
||||
.standard_padding(8, |d: &[u8]| sha1_digest_block(&mut *st_h, d));
|
||||
write_u32_be(self.buffer.next(4), (self.length_bits >> 32) as u32);
|
||||
write_u32_be(self.buffer.next(4), self.length_bits as u32);
|
||||
sha1_digest_block(st_h, self.buffer.full_buffer());
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Sha1 {
|
||||
fn default() -> Self { Self::new() }
|
||||
}
|
||||
|
||||
impl Digest for Sha1 {
|
||||
type R = U20;
|
||||
type B = BlockSize;
|
||||
|
||||
fn new() -> Sha1 {
|
||||
Sha1 {
|
||||
h: H,
|
||||
length_bits: 0u64,
|
||||
buffer: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
fn input(&mut self, msg: &[u8]) {
|
||||
// Assumes that msg.len() can be converted to u64 without overflow
|
||||
self.length_bits = add_bytes_to_bits(self.length_bits, msg.len() as u64);
|
||||
let st_h = &mut self.h;
|
||||
self.buffer.input(msg, |d: &[u8]| {
|
||||
sha1_digest_block(st_h, d);
|
||||
});
|
||||
}
|
||||
|
||||
fn result(mut self) -> GenericArray<u8, Self::R> {
|
||||
self.finalize();
|
||||
|
||||
let mut out = GenericArray::new();
|
||||
write_u32_be(&mut out[0..4], self.h[0]);
|
||||
write_u32_be(&mut out[4..8], self.h[1]);
|
||||
write_u32_be(&mut out[8..12], self.h[2]);
|
||||
write_u32_be(&mut out[12..16], self.h[3]);
|
||||
write_u32_be(&mut out[16..20], self.h[4]);
|
||||
out
|
||||
}
|
||||
}
|
||||
295
sha1/src/utils.rs
Normal file
295
sha1/src/utils.rs
Normal file
@@ -0,0 +1,295 @@
|
||||
use consts::{BLOCK_LEN, K0, K1, K2, K3};
|
||||
use byte_tools::{read_u32v_be};
|
||||
use simd::u32x4;
|
||||
|
||||
/// Not an intrinsic, but gets the first element of a vector.
|
||||
#[inline]
|
||||
pub fn sha1_first(w0: u32x4) -> u32 {
|
||||
w0.0
|
||||
}
|
||||
|
||||
/// Not an intrinsic, but adds a word to the first element of a vector.
|
||||
#[inline]
|
||||
pub fn sha1_first_add(e: u32, w0: u32x4) -> u32x4 {
|
||||
let u32x4(a, b, c, d) = w0;
|
||||
u32x4(e.wrapping_add(a), b, c, d)
|
||||
}
|
||||
|
||||
/// Emulates `llvm.x86.sha1msg1` intrinsic.
|
||||
fn sha1msg1(a: u32x4, b: u32x4) -> u32x4 {
|
||||
let u32x4(_, _, w2, w3) = a;
|
||||
let u32x4(w4, w5, _, _) = b;
|
||||
a ^ u32x4(w2, w3, w4, w5)
|
||||
}
|
||||
|
||||
/// Emulates `llvm.x86.sha1msg2` intrinsic.
|
||||
fn sha1msg2(a: u32x4, b: u32x4) -> u32x4 {
|
||||
let u32x4(x0, x1, x2, x3) = a;
|
||||
let u32x4(_, w13, w14, w15) = b;
|
||||
|
||||
let w16 = (x0 ^ w13).rotate_left(1);
|
||||
let w17 = (x1 ^ w14).rotate_left(1);
|
||||
let w18 = (x2 ^ w15).rotate_left(1);
|
||||
let w19 = (x3 ^ w16).rotate_left(1);
|
||||
|
||||
u32x4(w16, w17, w18, w19)
|
||||
}
|
||||
|
||||
/// Performs 4 rounds of the message schedule update.
|
||||
/*
|
||||
pub fn sha1_schedule_x4(v0: u32x4, v1: u32x4, v2: u32x4, v3: u32x4) -> u32x4 {
|
||||
sha1msg2(sha1msg1(v0, v1) ^ v2, v3)
|
||||
}
|
||||
*/
|
||||
|
||||
/// Emulates `llvm.x86.sha1nexte` intrinsic.
|
||||
#[inline]
|
||||
fn sha1_first_half(abcd: u32x4, msg: u32x4) -> u32x4 {
|
||||
sha1_first_add(sha1_first(abcd).rotate_left(30), msg)
|
||||
}
|
||||
|
||||
/// Emulates `llvm.x86.sha1rnds4` intrinsic.
|
||||
/// Performs 4 rounds of the message block digest.
|
||||
fn sha1_digest_round_x4(abcd: u32x4, work: u32x4, i: i8) -> u32x4 {
|
||||
const K0V: u32x4 = u32x4(K0, K0, K0, K0);
|
||||
const K1V: u32x4 = u32x4(K1, K1, K1, K1);
|
||||
const K2V: u32x4 = u32x4(K2, K2, K2, K2);
|
||||
const K3V: u32x4 = u32x4(K3, K3, K3, K3);
|
||||
|
||||
match i {
|
||||
0 => sha1rnds4c(abcd, work + K0V),
|
||||
1 => sha1rnds4p(abcd, work + K1V),
|
||||
2 => sha1rnds4m(abcd, work + K2V),
|
||||
3 => sha1rnds4p(abcd, work + K3V),
|
||||
_ => panic!("unknown icosaround index"),
|
||||
}
|
||||
}
|
||||
|
||||
/// Not an intrinsic, but helps emulate `llvm.x86.sha1rnds4` intrinsic.
|
||||
fn sha1rnds4c(abcd: u32x4, msg: u32x4) -> u32x4 {
|
||||
let u32x4(mut a, mut b, mut c, mut d) = abcd;
|
||||
let u32x4(t, u, v, w) = msg;
|
||||
let mut e = 0u32;
|
||||
|
||||
macro_rules! bool3ary_202 {
|
||||
($a:expr, $b:expr, $c:expr) => (($c ^ ($a & ($b ^ $c))))
|
||||
} // Choose, MD5F, SHA1C
|
||||
|
||||
e = e.wrapping_add(a.rotate_left(5))
|
||||
.wrapping_add(bool3ary_202!(b, c, d))
|
||||
.wrapping_add(t);
|
||||
b = b.rotate_left(30);
|
||||
|
||||
d = d.wrapping_add(e.rotate_left(5))
|
||||
.wrapping_add(bool3ary_202!(a, b, c))
|
||||
.wrapping_add(u);
|
||||
a = a.rotate_left(30);
|
||||
|
||||
c = c.wrapping_add(d.rotate_left(5))
|
||||
.wrapping_add(bool3ary_202!(e, a, b))
|
||||
.wrapping_add(v);
|
||||
e = e.rotate_left(30);
|
||||
|
||||
b = b.wrapping_add(c.rotate_left(5))
|
||||
.wrapping_add(bool3ary_202!(d, e, a))
|
||||
.wrapping_add(w);
|
||||
d = d.rotate_left(30);
|
||||
|
||||
u32x4(b, c, d, e)
|
||||
}
|
||||
|
||||
/// Not an intrinsic, but helps emulate `llvm.x86.sha1rnds4` intrinsic.
|
||||
fn sha1rnds4p(abcd: u32x4, msg: u32x4) -> u32x4 {
|
||||
let u32x4(mut a, mut b, mut c, mut d) = abcd;
|
||||
let u32x4(t, u, v, w) = msg;
|
||||
let mut e = 0u32;
|
||||
|
||||
macro_rules! bool3ary_150 {
|
||||
($a:expr, $b:expr, $c:expr) => (($a ^ $b ^ $c))
|
||||
} // Parity, XOR, MD5H, SHA1P
|
||||
|
||||
e = e.wrapping_add(a.rotate_left(5))
|
||||
.wrapping_add(bool3ary_150!(b, c, d))
|
||||
.wrapping_add(t);
|
||||
b = b.rotate_left(30);
|
||||
|
||||
d = d.wrapping_add(e.rotate_left(5))
|
||||
.wrapping_add(bool3ary_150!(a, b, c))
|
||||
.wrapping_add(u);
|
||||
a = a.rotate_left(30);
|
||||
|
||||
c = c.wrapping_add(d.rotate_left(5))
|
||||
.wrapping_add(bool3ary_150!(e, a, b))
|
||||
.wrapping_add(v);
|
||||
e = e.rotate_left(30);
|
||||
|
||||
b = b.wrapping_add(c.rotate_left(5))
|
||||
.wrapping_add(bool3ary_150!(d, e, a))
|
||||
.wrapping_add(w);
|
||||
d = d.rotate_left(30);
|
||||
|
||||
u32x4(b, c, d, e)
|
||||
}
|
||||
|
||||
/// Not an intrinsic, but helps emulate `llvm.x86.sha1rnds4` intrinsic.
|
||||
fn sha1rnds4m(abcd: u32x4, msg: u32x4) -> u32x4 {
|
||||
let u32x4(mut a, mut b, mut c, mut d) = abcd;
|
||||
let u32x4(t, u, v, w) = msg;
|
||||
let mut e = 0u32;
|
||||
|
||||
macro_rules! bool3ary_232 {
|
||||
($a:expr, $b:expr, $c:expr) => (($a & $b) ^ ($a & $c) ^ ($b & $c))
|
||||
} // Majority, SHA1M
|
||||
|
||||
e = e.wrapping_add(a.rotate_left(5))
|
||||
.wrapping_add(bool3ary_232!(b, c, d))
|
||||
.wrapping_add(t);
|
||||
b = b.rotate_left(30);
|
||||
|
||||
d = d.wrapping_add(e.rotate_left(5))
|
||||
.wrapping_add(bool3ary_232!(a, b, c))
|
||||
.wrapping_add(u);
|
||||
a = a.rotate_left(30);
|
||||
|
||||
c = c.wrapping_add(d.rotate_left(5))
|
||||
.wrapping_add(bool3ary_232!(e, a, b))
|
||||
.wrapping_add(v);
|
||||
e = e.rotate_left(30);
|
||||
|
||||
b = b.wrapping_add(c.rotate_left(5))
|
||||
.wrapping_add(bool3ary_232!(d, e, a))
|
||||
.wrapping_add(w);
|
||||
d = d.rotate_left(30);
|
||||
|
||||
u32x4(b, c, d, e)
|
||||
}
|
||||
|
||||
/// Process a block with the SHA-1 algorithm.
|
||||
fn sha1_digest_block_u32(state: &mut [u32; 5], block: &[u32; 16]) {
|
||||
|
||||
macro_rules! schedule {
|
||||
($v0:expr, $v1:expr, $v2:expr, $v3:expr) => (
|
||||
sha1msg2(sha1msg1($v0, $v1) ^ $v2, $v3)
|
||||
)
|
||||
}
|
||||
|
||||
macro_rules! rounds4 {
|
||||
($h0:ident, $h1:ident, $wk:expr, $i:expr) => (
|
||||
sha1_digest_round_x4($h0, sha1_first_half($h1, $wk), $i)
|
||||
)
|
||||
}
|
||||
|
||||
// Rounds 0..20
|
||||
// TODO: replace with `u32x4::load`
|
||||
let mut h0 = u32x4(state[0], state[1], state[2], state[3]);
|
||||
let mut w0 = u32x4(block[0], block[1], block[2], block[3]);
|
||||
let mut h1 = sha1_digest_round_x4(h0, sha1_first_add(state[4], w0), 0);
|
||||
let mut w1 = u32x4(block[4], block[5], block[6], block[7]);
|
||||
h0 = rounds4!(h1, h0, w1, 0);
|
||||
let mut w2 = u32x4(block[8], block[9], block[10], block[11]);
|
||||
h1 = rounds4!(h0, h1, w2, 0);
|
||||
let mut w3 = u32x4(block[12], block[13], block[14], block[15]);
|
||||
h0 = rounds4!(h1, h0, w3, 0);
|
||||
let mut w4 = schedule!(w0, w1, w2, w3);
|
||||
h1 = rounds4!(h0, h1, w4, 0);
|
||||
|
||||
// Rounds 20..40
|
||||
w0 = schedule!(w1, w2, w3, w4);
|
||||
h0 = rounds4!(h1, h0, w0, 1);
|
||||
w1 = schedule!(w2, w3, w4, w0);
|
||||
h1 = rounds4!(h0, h1, w1, 1);
|
||||
w2 = schedule!(w3, w4, w0, w1);
|
||||
h0 = rounds4!(h1, h0, w2, 1);
|
||||
w3 = schedule!(w4, w0, w1, w2);
|
||||
h1 = rounds4!(h0, h1, w3, 1);
|
||||
w4 = schedule!(w0, w1, w2, w3);
|
||||
h0 = rounds4!(h1, h0, w4, 1);
|
||||
|
||||
// Rounds 40..60
|
||||
w0 = schedule!(w1, w2, w3, w4);
|
||||
h1 = rounds4!(h0, h1, w0, 2);
|
||||
w1 = schedule!(w2, w3, w4, w0);
|
||||
h0 = rounds4!(h1, h0, w1, 2);
|
||||
w2 = schedule!(w3, w4, w0, w1);
|
||||
h1 = rounds4!(h0, h1, w2, 2);
|
||||
w3 = schedule!(w4, w0, w1, w2);
|
||||
h0 = rounds4!(h1, h0, w3, 2);
|
||||
w4 = schedule!(w0, w1, w2, w3);
|
||||
h1 = rounds4!(h0, h1, w4, 2);
|
||||
|
||||
// Rounds 60..80
|
||||
w0 = schedule!(w1, w2, w3, w4);
|
||||
h0 = rounds4!(h1, h0, w0, 3);
|
||||
w1 = schedule!(w2, w3, w4, w0);
|
||||
h1 = rounds4!(h0, h1, w1, 3);
|
||||
w2 = schedule!(w3, w4, w0, w1);
|
||||
h0 = rounds4!(h1, h0, w2, 3);
|
||||
w3 = schedule!(w4, w0, w1, w2);
|
||||
h1 = rounds4!(h0, h1, w3, 3);
|
||||
w4 = schedule!(w0, w1, w2, w3);
|
||||
h0 = rounds4!(h1, h0, w4, 3);
|
||||
|
||||
let e = sha1_first(h1).rotate_left(30);
|
||||
let u32x4(a, b, c, d) = h0;
|
||||
|
||||
state[0] = state[0].wrapping_add(a);
|
||||
state[1] = state[1].wrapping_add(b);
|
||||
state[2] = state[2].wrapping_add(c);
|
||||
state[3] = state[3].wrapping_add(d);
|
||||
state[4] = state[4].wrapping_add(e);
|
||||
}
|
||||
|
||||
/// Process a block with the SHA-1 algorithm. (See more...)
|
||||
///
|
||||
/// SHA-1 is a cryptographic hash function, and as such, it operates
|
||||
/// on an arbitrary number of bytes. This function operates on a fixed
|
||||
/// number of bytes. If you call this function with anything other than
|
||||
/// 64 bytes, then it will panic! This function takes two arguments:
|
||||
///
|
||||
/// * `state` is reference to an **array** of 5 words.
|
||||
/// * `block` is reference to a **slice** of 64 bytes.
|
||||
///
|
||||
/// If you want the function that performs a message digest on an arbitrary
|
||||
/// number of bytes, then see also the `Sha1` struct above.
|
||||
///
|
||||
/// # Implementation
|
||||
///
|
||||
/// First, some background. Both ARM and Intel are releasing documentation
|
||||
/// that they plan to include instruction set extensions for SHA1 and SHA256
|
||||
/// sometime in the near future. Second, LLVM won't lower these intrinsics yet,
|
||||
/// so these functions were written emulate these instructions. Finally,
|
||||
/// the block function implemented with these emulated intrinsics turned out
|
||||
/// to be quite fast! What follows is a discussion of this CPU-level view
|
||||
/// of the SHA-1 algorithm and how it relates to the mathematical definition.
|
||||
///
|
||||
/// The SHA instruction set extensions can be divided up into two categories:
|
||||
///
|
||||
/// * message work schedule update calculation ("schedule" v., "work" n.)
|
||||
/// * message block 80-round digest calculation ("digest" v., "block" n.)
|
||||
///
|
||||
/// The schedule-related functions can be used to easily perform 4 rounds
|
||||
/// of the message work schedule update calculation, as shown below:
|
||||
///
|
||||
/// ```ignore
|
||||
/// macro_rules! schedule_x4 {
|
||||
/// ($v0:expr, $v1:expr, $v2:expr, $v3:expr) => (
|
||||
/// sha1msg2(sha1msg1($v0, $v1) ^ $v2, $v3)
|
||||
/// )
|
||||
/// }
|
||||
///
|
||||
/// macro_rules! round_x4 {
|
||||
/// ($h0:ident, $h1:ident, $wk:expr, $i:expr) => (
|
||||
/// sha1rnds4($h0, sha1_first_half($h1, $wk), $i)
|
||||
/// )
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// and also shown above is how the digest-related functions can be used to
|
||||
/// perform 4 rounds of the message block digest calculation.
|
||||
///
|
||||
pub fn sha1_digest_block(state: &mut [u32; 5], block: &[u8]) {
|
||||
assert_eq!(block.len(), BLOCK_LEN * 4);
|
||||
let mut block2 = [0u32; BLOCK_LEN];
|
||||
read_u32v_be(&mut block2[..], block);
|
||||
sha1_digest_block_u32(state, &block2);
|
||||
}
|
||||
1
sha1/tests/data/one_million_a.output.bin
Normal file
1
sha1/tests/data/one_million_a.output.bin
Normal file
@@ -0,0 +1 @@
|
||||
4ª—<ÔÄÚ¤öë+Û'1e4o
|
||||
1
sha1/tests/data/test1.input.bin
Normal file
1
sha1/tests/data/test1.input.bin
Normal file
@@ -0,0 +1 @@
|
||||
abc
|
||||
1
sha1/tests/data/test1.output.bin
Normal file
1
sha1/tests/data/test1.output.bin
Normal file
@@ -0,0 +1 @@
|
||||
<EFBFBD><EFBFBD>>6G<06>j<EFBFBD>>%qxP<78>l<EFBFBD><6C>؝
|
||||
1
sha1/tests/data/test2.input.bin
Normal file
1
sha1/tests/data/test2.input.bin
Normal file
@@ -0,0 +1 @@
|
||||
abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq
|
||||
1
sha1/tests/data/test2.output.bin
Normal file
1
sha1/tests/data/test2.output.bin
Normal file
@@ -0,0 +1 @@
|
||||
<EFBFBD><EFBFBD>>D;<3B>n<EFBFBD><6E>J<EFBFBD><4A>Q)<29><>Fp<46>
|
||||
1
sha1/tests/data/test3.input.bin
Normal file
1
sha1/tests/data/test3.input.bin
Normal file
@@ -0,0 +1 @@
|
||||
The quick brown fox jumps over the lazy dog
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user