1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#![no_std]
#![doc(html_logo_url =
"https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png")]
#[cfg(all(feature = "asm-aarch64", target_arch = "aarch64", not(target_os = "linux")))]
compile_error!("Your OS isn’t yet supported for runtime-checking of AArch64 features.");
#[cfg(all(feature = "asm-aarch64", target_os = "linux", not(target_arch = "aarch64")))]
compile_error!("Enable the \"asm\" feature instead of \"asm-aarch64\" on non-AArch64 Linux systems.");
#[cfg(all(not(feature = "asm-aarch64"), feature = "asm", target_arch = "aarch64", target_os = "linux"))]
compile_error!("Enable the \"asm-aarch64\" feature on AArch64 if you want to use asm.");
extern crate block_buffer;
#[macro_use] extern crate opaque_debug;
#[macro_use] pub extern crate digest;
#[cfg(feature = "std")]
extern crate std;
#[cfg(any(not(feature = "asm"), feature = "asm-aarch64"))]
extern crate fake_simd as simd;
#[cfg(feature = "asm-aarch64")]
extern crate libc;
#[cfg(feature = "asm")]
extern crate sha1_asm;
#[cfg(all(feature = "asm", not(feature = "asm-aarch64")))]
#[inline(always)]
fn compress(state: &mut [u32; 5], block: &GenericArray<u8, U64>) {
let block: &[u8; 64] = unsafe { core::mem::transmute(block) };
sha1_asm::compress(state, block);
}
#[cfg(feature = "asm-aarch64")]
mod aarch64;
#[cfg(feature = "asm-aarch64")]
#[inline(always)]
fn compress(state: &mut [u32; 5], block: &GenericArray<u8, U64>) {
if aarch64::sha1_supported() {
let block: &[u8; 64] = unsafe { core::mem::transmute(block) };
sha1_asm::compress(state, block);
} else {
utils::compress(state, block);
}
}
#[cfg(any(not(feature = "asm"), feature = "asm-aarch64"))]
mod utils;
#[cfg(not(feature = "asm"))]
use utils::compress;
pub use digest::Digest;
use digest::{Input, BlockInput, FixedOutput, Reset};
use digest::generic_array::GenericArray;
use digest::generic_array::typenum::{U20, U64};
use block_buffer::BlockBuffer;
use block_buffer::byteorder::{BE, ByteOrder};
mod consts;
use consts::{STATE_LEN, H};
#[derive(Clone)]
pub struct Sha1 {
h: [u32; STATE_LEN],
len: u64,
buffer: BlockBuffer<U64>,
}
impl Default for Sha1 {
fn default() -> Self {
Sha1{ h: H, len: 0u64, buffer: Default::default() }
}
}
impl BlockInput for Sha1 {
type BlockSize = U64;
}
impl Input for Sha1 {
fn input<B: AsRef<[u8]>>(&mut self, input: B) {
let input = input.as_ref();
self.len += input.len() as u64;
let state = &mut self.h;
self.buffer.input(input, |d| compress(state, d));
}
}
impl FixedOutput for Sha1 {
type OutputSize = U20;
fn fixed_result(mut self) -> GenericArray<u8, Self::OutputSize> {
{
let state = &mut self.h;
let l = self.len << 3;
self.buffer.len64_padding::<BE, _>(l, |d| compress(state, d));
}
let mut out = GenericArray::default();
BE::write_u32_into(&self.h,&mut out);
out
}
}
impl Reset for Sha1 {
fn reset(&mut self) {
self.h = H;
self.len = 0;
self.buffer.reset();
}
}
impl_opaque_debug!(Sha1);
impl_write!(Sha1);