1
-
2
-
3
1
/*
4
2
* A SHA-1 implementation derived from Paul E. Jones's reference
5
3
* implementation, which is written for clarity, not speed. At some
8
6
export sha1;
9
7
export mk_sha1;
10
8
11
- type sha1 =
9
+ type sha1 = obj {
12
10
// Provide message input as bytes
13
-
14
-
11
+ fn input ( & [ u8 ] ) ;
15
12
// Provide message input as string
16
-
17
- // Read the digest as a vector of 20 bytes. After
18
- // calling this no further input may provided
19
- // until reset is called
20
-
21
-
13
+ fn input_str ( & str ) ;
14
+ // Read the digest as a vector of 20 bytes. After calling this no further
15
+ // input may provided until reset is called
16
+ fn result ( ) -> [ u8 ] ;
22
17
// Same as above, just a hex-string version.
23
-
18
+ fn result_str ( ) -> str ;
24
19
// Reset the sha1 state for reuse. This is called
25
20
// automatically during construction
26
- obj {
27
- fn input ( & [ u8 ] ) ;
28
- fn input_str ( & str ) ;
29
- fn result ( ) -> [ u8 ] ;
30
- fn result_str ( ) -> str ;
31
- fn reset ( ) ;
32
- } ;
21
+ fn reset ( ) ;
22
+ } ;
33
23
34
24
35
25
// Some unexported constants
36
26
const digest_buf_len: uint = 5 u;
37
-
38
27
const msg_block_len: uint = 64 u;
39
-
40
28
const work_buf_len: uint = 80 u;
41
-
42
29
const k0: u32 = 0x5A827999u32 ;
43
-
44
30
const k1: u32 = 0x6ED9EBA1u32 ;
45
-
46
31
const k2: u32 = 0x8F1BBCDCu32 ;
47
-
48
32
const k3: u32 = 0xCA62C1D6u32 ;
49
33
50
34
@@ -61,7 +45,6 @@ fn mk_sha1() -> sha1 {
61
45
62
46
fn add_input ( st : & sha1state , msg : & [ u8 ] ) {
63
47
// FIXME: Should be typestate precondition
64
-
65
48
assert ( !st. computed ) ;
66
49
for element: u8 in msg {
67
50
st. msg_block [ st. msg_block_idx ] = element;
@@ -80,14 +63,12 @@ fn mk_sha1() -> sha1 {
80
63
}
81
64
fn process_msg_block ( st : & sha1state ) {
82
65
// FIXME: Make precondition
83
-
84
66
assert ( vec:: len ( st. h ) == digest_buf_len) ;
85
67
assert ( vec:: len ( st. work_buf ) == work_buf_len) ;
86
68
let t: int ; // Loop counter
87
-
88
69
let w = st. work_buf ;
89
- // Initialize the first 16 words of the vector w
90
70
71
+ // Initialize the first 16 words of the vector w
91
72
t = 0 ;
92
73
while t < 16 {
93
74
let tmp;
@@ -98,8 +79,8 @@ fn mk_sha1() -> sha1 {
98
79
w[ t] = tmp;
99
80
t += 1 ;
100
81
}
101
- // Initialize the rest of vector w
102
82
83
+ // Initialize the rest of vector w
103
84
while t < 80 {
104
85
let val = w[ t - 3 ] ^ w[ t - 8 ] ^ w[ t - 14 ] ^ w[ t - 16 ] ;
105
86
w[ t] = circular_shift ( 1u32 , val) ;
@@ -172,6 +153,7 @@ fn mk_sha1() -> sha1 {
172
153
}
173
154
ret rs;
174
155
}
156
+
175
157
/*
176
158
* According to the standard, the message must be padded to an even
177
159
* 512 bits. The first padding bit must be a '1'. The last 64 bits
@@ -181,17 +163,15 @@ fn mk_sha1() -> sha1 {
181
163
* call process_msg_block() appropriately. When it returns, it
182
164
* can be assumed that the message digest has been computed.
183
165
*/
184
-
185
166
fn pad_msg ( st : & sha1state ) {
186
167
// FIXME: Should be a precondition
187
-
188
168
assert ( vec:: len ( st. msg_block ) == msg_block_len) ;
169
+
189
170
/*
190
171
* Check to see if the current message block is too small to hold
191
172
* the initial padding bits and length. If so, we will pad the
192
173
* block, process it, and then continue padding into a second block.
193
174
*/
194
-
195
175
if st. msg_block_idx > 55 u {
196
176
st. msg_block [ st. msg_block_idx ] = 0x80u8 ;
197
177
st. msg_block_idx += 1 u;
@@ -208,8 +188,8 @@ fn mk_sha1() -> sha1 {
208
188
st. msg_block [ st. msg_block_idx ] = 0u8 ;
209
189
st. msg_block_idx += 1 u;
210
190
}
211
- // Store the message length as the last 8 octets
212
191
192
+ // Store the message length as the last 8 octets
213
193
st. msg_block [ 56 ] = st. len_high >> 24u32 & 0xFFu32 as u8 ;
214
194
st. msg_block [ 57 ] = st. len_high >> 16u32 & 0xFFu32 as u8 ;
215
195
st. msg_block [ 58 ] = st. len_high >> 8u32 & 0xFFu32 as u8 ;
@@ -223,7 +203,6 @@ fn mk_sha1() -> sha1 {
223
203
obj sha1( st: sha1state) {
224
204
fn reset ( ) {
225
205
// FIXME: Should be typestate precondition
226
-
227
206
assert ( vec:: len ( st. h ) == digest_buf_len) ;
228
207
st. len_low = 0u32 ;
229
208
st. len_high = 0u32 ;
@@ -257,6 +236,7 @@ fn mk_sha1() -> sha1 {
257
236
sh. reset ( ) ;
258
237
ret sh;
259
238
}
239
+
260
240
// Local Variables:
261
241
// mode: rust;
262
242
// fill-column: 78;
0 commit comments