First commit

This commit is contained in:
Артём Павлов [Artyom Pavlov]
2016-10-14 17:55:45 +03:00
commit 36523ad3ed
3285 changed files with 11037 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
*/target/
*/*/target/
Cargo.lock

25
README.md Normal file
View 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
View 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
View File

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

27
blake2/LICENSE-MIT Normal file
View 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
View 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;
}

View 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(), "-");
}
}

View 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
View 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, &param_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
View 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, &param_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
View 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
View 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;

View File

View File

@@ -0,0 +1 @@
xj÷BYÆÆý…%RÒr/G@áXGaІâ÷TÒ^1¯îXS‰dD“N°K<C2B0>:h[H·UÕopþ›âÎ

View File

@@ -0,0 +1 @@
The quick brown fox jumps over the lazy dog

View File

@@ -0,0 +1 @@
¨­Ô½Ýý“ä‡}'Fæ(±6J§¼<14> Ç3;6sø$Ïz¢äËÍ<>)n?ËTøíw¾s[LÜÖ©

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,2 @@
' Ö.(üÌЯ—úÐøF[— Å 7*¤>HKáÁç;¡ ÕÑ…=¶¤n
{ù€

View File

@@ -0,0 +1 @@


Binary file not shown.

View File

@@ -0,0 +1 @@
ŽÆËqÄ\<<3C>Њ7¨]Á"µÈâÙåqB¿ïÎB×¼ø°1'ˆ.Q©!Dbö£X©à}5;ÓApb¬Õ9Nîs®

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1 @@
?╥5╪Q²Ч≈·TаН[Зп╘ьXЁ1[╜4╫И≥Ов$щ

View File

@@ -0,0 +1 @@


Binary file not shown.

View File

@@ -0,0 +1 @@
ˆöŠª\NØ÷í(øEœ~ùv+Oñ­~[¨ÈžâI

35
blake2/tests/lib.rs Normal file
View 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
View 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
View 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
View File

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

25
md4/LICENSE-MIT Normal file
View 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
View 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
View 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
View 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
}
}

View File

@@ -0,0 +1 @@
»Î€Ìk¶^\gEã

View File

View File

@@ -0,0 +1 @@
1ÖÏàÑjé1·<Y×àÀ‰À

View File

@@ -0,0 +1 @@
a

View File

@@ -0,0 +1 @@
½å,³ã>F$^ûÛÖû$

View File

@@ -0,0 +1 @@
abc

View File

@@ -0,0 +1,2 @@
、Hzッ!リR_チ
閊ヲr<EFBFBD>

View File

@@ -0,0 +1 @@
message digest

View File

@@ -0,0 +1,2 @@

‥T溯K

View File

@@ -0,0 +1 @@
abcdefghijklmnopqrstuvwxyz

View File

@@ -0,0 +1 @@
׳<EFBFBD>0<>¥»ֽמ¨םc<D79D>A-©

View File

@@ -0,0 +1 @@
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789

View File

@@ -0,0 +1 @@
?…עA<D7A2>5ז'בSחנה

View File

@@ -0,0 +1 @@
12345678901234567890123456789012345678901234567890123456789012345678901234567890

View File

@@ -0,0 +1 @@
<EFBFBD>;Mܜ8<DC9C><19>>{O<>6

View File

@@ -0,0 +1 @@
The quick brown fox jumps over the lazy dog

View File

@@ -0,0 +1 @@
<1B>i<EFBFBD>k<EFBFBD>\Gb<47><62><EFBFBD><EFBFBD>

View File

@@ -0,0 +1 @@
The quick brown fox jumps over the lazy cog

View File

@@ -0,0 +1 @@
Έn η<02>¥<EFBFBD>g-V­ί

19
md4/tests/lib.rs Normal file
View 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
View 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
View File

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

27
md5/LICENSE-MIT Normal file
View 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
View 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
View 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
View 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
View 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
}
}

View File

@@ -0,0 +1 @@
wÖ®N|p5Â)o!

View File

Binary file not shown.

View File

@@ -0,0 +1 @@
The quick brown fox jumps over the lazy dog

View File

@@ -0,0 +1 @@
<EFBFBD>}<7D>7+<2B><>k<EFBFBD>5B<35><19>

View File

@@ -0,0 +1 @@
The quick brown fox jumps over the lazy dog.

View File

@@ -0,0 +1 @@
<09><>冥"刵

19
md5/tests/lib.rs Normal file
View 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
View 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
View File

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

27
ripemd160/LICENSE-MIT Normal file
View 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
View 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
View 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
}
}

View File

@@ -0,0 +1 @@
Rx2Cチi{ロ疥7<E796A5>h<7F>%ワ(

View File

@@ -0,0 +1 @@
abc

View File

@@ -0,0 +1 @@
޲÷à]˜z˜Æ°‡ñZ ü

View File

@@ -0,0 +1 @@
abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq

View File

@@ -0,0 +1 @@
<12>S8J<38> <0C><><05>l'<27><><EFBFBD><EFBFBD>b<EFBFBD>+

View File

@@ -0,0 +1 @@
The quick brown fox jumps over the lazy dog

View File

@@ -0,0 +1 @@
7<EFBFBD>2<EFBFBD><EFBFBD><EFBFBD>{<7B><><EFBFBD>Ԗ<EFBFBD>q<EFBFBD>g<1C><>;

View File

@@ -0,0 +1 @@
The quick brown fox jumps over the lazy cog

View File

@@ -0,0 +1 @@
 r゚i 3タクカュ w邯<77>ハラ

19
ripemd160/tests/lib.rs Normal file
View 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
View 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
View File

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

27
sha1/LICENSE-MIT Normal file
View 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
View 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
View 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
View 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
View 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
View 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);
}

View File

@@ -0,0 +1 @@
4ª—<ÔÄÚ¤öë+Û­'1e4o

View File

@@ -0,0 +1 @@
abc

View File

@@ -0,0 +1 @@
<EFBFBD><EFBFBD>>6G<06>j<EFBFBD>>%qxP<78>l<EFBFBD><6C>؝

View File

@@ -0,0 +1 @@
abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq

View File

@@ -0,0 +1 @@
<EFBFBD><EFBFBD>>D;<3B>n<EFBFBD><6E>J<EFBFBD><4A>Q)<29><>Fp<46>

View 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