1
1
#![ no_std]
2
- use core:: { mem , ptr} ;
2
+ use core:: ptr;
3
3
4
- /// Write a u64 into a vector, which must be 8 bytes long. The value is written
5
- /// in big-endian format.
6
- pub fn write_u64_be ( dst : & mut [ u8 ] , mut input : u64 ) {
7
- assert ! ( dst. len( ) == 8 ) ;
8
- input = input. to_be ( ) ;
9
- unsafe {
10
- let tmp = & input as * const _ as * const u8 ;
11
- ptr:: copy_nonoverlapping ( tmp, dst. get_unchecked_mut ( 0 ) , 8 ) ;
12
- }
13
- }
14
-
15
- /// Write a u64 into a vector, which must be 8 bytes long. The value is written
16
- /// in little-endian format.
17
- pub fn write_u64_le ( dst : & mut [ u8 ] , mut input : u64 ) {
18
- assert ! ( dst. len( ) == 8 ) ;
19
- input = input. to_le ( ) ;
20
- unsafe {
21
- let tmp = & input as * const _ as * const u8 ;
22
- ptr:: copy_nonoverlapping ( tmp, dst. get_unchecked_mut ( 0 ) , 8 ) ;
23
- }
24
- }
25
-
26
- /// Write a vector of u64s into a vector of bytes. The values are written in
27
- /// little-endian format.
28
- pub fn write_u64v_be ( dst : & mut [ u8 ] , input : & [ u64 ] ) {
29
- assert ! ( dst. len( ) == 8 * input. len( ) ) ;
30
- unsafe {
31
- let mut x: * mut u8 = dst. get_unchecked_mut ( 0 ) ;
32
- let mut y: * const u64 = input. get_unchecked ( 0 ) ;
33
- for _ in 0 ..input. len ( ) {
34
- let tmp = ( * y) . to_be ( ) ;
35
- ptr:: copy_nonoverlapping ( & tmp as * const _ as * const u8 , x, 8 ) ;
36
- x = x. offset ( 8 ) ;
37
- y = y. offset ( 1 ) ;
38
- }
39
- }
40
- }
41
-
42
- /// Write a vector of u64s into a vector of bytes. The values are written in
43
- /// little-endian format.
44
- pub fn write_u64v_le ( dst : & mut [ u8 ] , input : & [ u64 ] ) {
45
- assert ! ( dst. len( ) == 8 * input. len( ) ) ;
46
- unsafe {
47
- let mut x: * mut u8 = dst. get_unchecked_mut ( 0 ) ;
48
- let mut y: * const u64 = input. get_unchecked ( 0 ) ;
49
- for _ in 0 ..input. len ( ) {
50
- let tmp = ( * y) . to_le ( ) ;
51
- ptr:: copy_nonoverlapping ( & tmp as * const _ as * const u8 , x, 8 ) ;
52
- x = x. offset ( 8 ) ;
53
- y = y. offset ( 1 ) ;
54
- }
55
- }
56
- }
4
+ mod read_single;
5
+ mod write_single;
6
+ mod read_slice;
7
+ mod write_slice;
57
8
58
- /// Write a u32 into a vector, which must be 4 bytes long. The value is written
59
- /// in big-endian format.
60
- pub fn write_u32_be ( dst : & mut [ u8 ] , mut input : u32 ) {
61
- assert ! ( dst. len( ) == 4 ) ;
62
- input = input. to_be ( ) ;
63
- unsafe {
64
- let tmp = & input as * const _ as * const u8 ;
65
- ptr:: copy_nonoverlapping ( tmp, dst. get_unchecked_mut ( 0 ) , 4 ) ;
66
- }
67
- }
68
-
69
- /// Write a u32 into a vector, which must be 4 bytes long. The value is written
70
- /// in little-endian format.
71
- pub fn write_u32_le ( dst : & mut [ u8 ] , mut input : u32 ) {
72
- assert ! ( dst. len( ) == 4 ) ;
73
- input = input. to_le ( ) ;
74
- unsafe {
75
- let tmp = & input as * const _ as * const u8 ;
76
- ptr:: copy_nonoverlapping ( tmp, dst. get_unchecked_mut ( 0 ) , 4 ) ;
77
- }
78
- }
79
-
80
- /// Write a vector of u32s into a vector of bytes. The values are written in
81
- /// little-endian format.
82
- pub fn write_u32v_le ( dst : & mut [ u8 ] , input : & [ u32 ] ) {
83
- assert ! ( dst. len( ) == 4 * input. len( ) ) ;
84
- unsafe {
85
- let mut x: * mut u8 = dst. get_unchecked_mut ( 0 ) ;
86
- let mut y: * const u32 = input. get_unchecked ( 0 ) ;
87
- for _ in 0 ..input. len ( ) {
88
- let tmp = ( * y) . to_le ( ) ;
89
- ptr:: copy_nonoverlapping ( & tmp as * const _ as * const u8 , x, 4 ) ;
90
- x = x. offset ( 4 ) ;
91
- y = y. offset ( 1 ) ;
92
- }
93
- }
94
- }
95
-
96
- /// Write a vector of u32s into a vector of bytes. The values are written in
97
- /// big-endian format.
98
- pub fn write_u32v_be ( dst : & mut [ u8 ] , input : & [ u32 ] ) {
99
- assert ! ( dst. len( ) == 4 * input. len( ) ) ;
100
- unsafe {
101
- let mut x: * mut u8 = dst. get_unchecked_mut ( 0 ) ;
102
- let mut y: * const u32 = input. get_unchecked ( 0 ) ;
103
- for _ in 0 ..input. len ( ) {
104
- let tmp = ( * y) . to_be ( ) ;
105
- ptr:: copy_nonoverlapping ( & tmp as * const _ as * const u8 , x, 4 ) ;
106
- x = x. offset ( 4 ) ;
107
- y = y. offset ( 1 ) ;
108
- }
109
- }
110
- }
111
-
112
- /// Read a vector of bytes into a vector of u64s. The values are read in
113
- /// big-endian format.
114
- pub fn read_u64v_be ( dst : & mut [ u64 ] , input : & [ u8 ] ) {
115
- assert ! ( dst. len( ) * 8 == input. len( ) ) ;
116
- unsafe {
117
- let mut x: * mut u64 = dst. get_unchecked_mut ( 0 ) ;
118
- let mut y: * const u8 = input. get_unchecked ( 0 ) ;
119
- for _ in 0 ..dst. len ( ) {
120
- let mut tmp: u64 = mem:: uninitialized ( ) ;
121
- ptr:: copy_nonoverlapping ( y, & mut tmp as * mut _ as * mut u8 , 8 ) ;
122
- * x = u64:: from_be ( tmp) ;
123
- x = x. offset ( 1 ) ;
124
- y = y. offset ( 8 ) ;
125
- }
126
- }
127
- }
128
-
129
- /// Read a vector of bytes into a vector of u64s. The values are read in
130
- /// little-endian format.
131
- pub fn read_u64v_le ( dst : & mut [ u64 ] , input : & [ u8 ] ) {
132
- assert ! ( dst. len( ) * 8 == input. len( ) ) ;
133
- unsafe {
134
- let mut x: * mut u64 = dst. get_unchecked_mut ( 0 ) ;
135
- let mut y: * const u8 = input. get_unchecked ( 0 ) ;
136
- for _ in 0 ..dst. len ( ) {
137
- let mut tmp: u64 = mem:: uninitialized ( ) ;
138
- ptr:: copy_nonoverlapping ( y, & mut tmp as * mut _ as * mut u8 , 8 ) ;
139
- * x = u64:: from_le ( tmp) ;
140
- x = x. offset ( 1 ) ;
141
- y = y. offset ( 8 ) ;
142
- }
143
- }
144
- }
145
-
146
- /// Read a vector of bytes into a vector of u32s. The values are read in
147
- /// big-endian format.
148
- pub fn read_u32v_be ( dst : & mut [ u32 ] , input : & [ u8 ] ) {
149
- assert ! ( dst. len( ) * 4 == input. len( ) ) ;
150
- unsafe {
151
- let mut x: * mut u32 = dst. get_unchecked_mut ( 0 ) ;
152
- let mut y: * const u8 = input. get_unchecked ( 0 ) ;
153
- for _ in 0 ..dst. len ( ) {
154
- let mut tmp: u32 = mem:: uninitialized ( ) ;
155
- ptr:: copy_nonoverlapping ( y, & mut tmp as * mut _ as * mut u8 , 4 ) ;
156
- * x = u32:: from_be ( tmp) ;
157
- x = x. offset ( 1 ) ;
158
- y = y. offset ( 4 ) ;
159
- }
160
- }
161
- }
162
-
163
- /// Read a vector of bytes into a vector of u32s. The values are read in
164
- /// little-endian format.
165
- pub fn read_u32v_le ( dst : & mut [ u32 ] , input : & [ u8 ] ) {
166
- assert ! ( dst. len( ) * 4 == input. len( ) ) ;
167
- unsafe {
168
- let mut x: * mut u32 = dst. get_unchecked_mut ( 0 ) ;
169
- let mut y: * const u8 = input. get_unchecked ( 0 ) ;
170
- for _ in 0 ..dst. len ( ) {
171
- let mut tmp: u32 = mem:: uninitialized ( ) ;
172
- ptr:: copy_nonoverlapping ( y, & mut tmp as * mut _ as * mut u8 , 4 ) ;
173
- * x = u32:: from_le ( tmp) ;
174
- x = x. offset ( 1 ) ;
175
- y = y. offset ( 4 ) ;
176
- }
177
- }
178
- }
179
-
180
- /// Read the value of a vector of bytes as a u32 value in little-endian format.
181
- pub fn read_u32_le ( input : & [ u8 ] ) -> u32 {
182
- assert ! ( input. len( ) == 4 ) ;
183
- unsafe {
184
- let mut tmp: u32 = mem:: uninitialized ( ) ;
185
- ptr:: copy_nonoverlapping ( input. get_unchecked ( 0 ) ,
186
- & mut tmp as * mut _ as * mut u8 ,
187
- 4 ) ;
188
- u32:: from_le ( tmp)
189
- }
190
- }
191
-
192
- /// Read the value of a vector of bytes as a u64 value in little-endian format.
193
- pub fn read_u64_le ( input : & [ u8 ] ) -> u64 {
194
- assert ! ( input. len( ) == 8 ) ;
195
- unsafe {
196
- let mut tmp: u64 = mem:: uninitialized ( ) ;
197
- ptr:: copy_nonoverlapping ( input. get_unchecked ( 0 ) ,
198
- & mut tmp as * mut _ as * mut u8 ,
199
- 8 ) ;
200
- u64:: from_le ( tmp)
201
- }
202
- }
203
-
204
- /// Read the value of a vector of bytes as a u32 value in big-endian format.
205
- pub fn read_u32_be ( input : & [ u8 ] ) -> u32 {
206
- assert ! ( input. len( ) == 4 ) ;
207
- unsafe {
208
- let mut tmp: u32 = mem:: uninitialized ( ) ;
209
- ptr:: copy_nonoverlapping ( input. get_unchecked ( 0 ) ,
210
- & mut tmp as * mut _ as * mut u8 ,
211
- 4 ) ;
212
- u32:: from_be ( tmp)
213
- }
214
- }
215
-
216
- /// Read the value of a vector of bytes as a u64 value in big-endian format.
217
- pub fn read_u64_be ( input : & [ u8 ] ) -> u64 {
218
- assert ! ( input. len( ) == 8 ) ;
219
- unsafe {
220
- let mut tmp: u64 = mem:: uninitialized ( ) ;
221
- ptr:: copy_nonoverlapping ( input. get_unchecked ( 0 ) ,
222
- & mut tmp as * mut _ as * mut u8 ,
223
- 8 ) ;
224
- u64:: from_be ( tmp)
225
- }
226
- }
227
-
228
- /// XOR plaintext and keystream, storing the result in dst.
229
- pub fn xor_keystream ( dst : & mut [ u8 ] , plaintext : & [ u8 ] , keystream : & [ u8 ] ) {
230
- assert ! ( dst. len( ) == plaintext. len( ) ) ;
231
- assert ! ( plaintext. len( ) <= keystream. len( ) ) ;
232
-
233
- // Do one byte at a time, using unsafe to skip bounds checking.
234
- let p = plaintext. as_ptr ( ) ;
235
- let k = keystream. as_ptr ( ) ;
236
- let d = dst. as_mut_ptr ( ) ;
237
- for i in 0isize ..plaintext. len ( ) as isize {
238
- unsafe { * d. offset ( i) = * p. offset ( i) ^ * k. offset ( i) } ;
239
- }
240
- }
9
+ pub use read_single:: * ;
10
+ pub use write_single:: * ;
11
+ pub use read_slice:: * ;
12
+ pub use write_slice:: * ;
241
13
242
14
/// Copy bytes from src to dest
243
15
#[ inline]
@@ -257,69 +29,3 @@ pub fn zero(dst: &mut [u8]) {
257
29
ptr:: write_bytes ( dst. as_mut_ptr ( ) , 0 , dst. len ( ) ) ;
258
30
}
259
31
}
260
-
261
- /// Convert the value in bytes to the number of bits, a tuple where the 1st
262
- /// item is the high-order value and the 2nd item is the low order value.
263
- fn to_bits ( x : u64 ) -> ( u64 , u64 ) { ( x >> 61 , x << 3 ) }
264
-
265
- /// Adds the specified number of bytes to the bit count. panic!() if this
266
- /// would cause numeric overflow.
267
- pub fn add_bytes_to_bits ( bits : u64 , bytes : u64 ) -> u64 {
268
- let ( new_high_bits, new_low_bits) = to_bits ( bytes) ;
269
-
270
- if new_high_bits > 0 {
271
- panic ! ( "Numeric overflow occured." )
272
- }
273
-
274
- bits. checked_add ( new_low_bits) . expect ( "Numeric overflow occured." )
275
- }
276
-
277
- /// Adds the specified number of bytes to the bit count, which is a tuple where
278
- /// the first element is the high order value. panic!() if this would cause
279
- /// numeric overflow.
280
- pub fn add_bytes_to_bits_tuple ( bits : ( u64 , u64 ) , bytes : u64 ) -> ( u64 , u64 ) {
281
- let ( new_high_bits, new_low_bits) = to_bits ( bytes) ;
282
- let ( hi, low) = bits;
283
-
284
- // Add the low order value - if there is no overflow, then add the high
285
- // order values. If the addition of the low order values causes overflow,
286
- // add one to the high order values before adding them.
287
- match low. checked_add ( new_low_bits) {
288
- Some ( x) => {
289
- if new_high_bits == 0 {
290
- // This is the fast path - every other alternative will rarely
291
- // occur in practice considering how large an input would need
292
- // to be for those paths to be used.
293
- ( hi, x)
294
- } else {
295
- match hi. checked_add ( new_high_bits) {
296
- Some ( y) => ( y, x) ,
297
- None => panic ! ( "Numeric overflow occured." ) ,
298
- }
299
- }
300
- } ,
301
- None => {
302
- let z = match new_high_bits. checked_add ( 1 ) {
303
- Some ( w) => w,
304
- None => panic ! ( "Numeric overflow occured." ) ,
305
- } ;
306
- match hi. checked_add ( z) {
307
- // This re-executes the addition that was already performed
308
- // earlier when overflow occured, this time allowing the
309
- // overflow to happen. Technically, this could be avoided by
310
- // using the checked add intrinsic directly, but that involves
311
- // using unsafe code and is not really worthwhile considering
312
- // how infrequently code will run in practice. This is the
313
- // reason that this function requires that the type T be
314
- // UnsignedInt - overflow is not defined for Signed types.
315
- // This function could be implemented for signed types as well
316
- // if that were needed.
317
- Some ( y) => ( y, low. wrapping_add ( new_low_bits) ) ,
318
- None => panic ! ( "Numeric overflow occured." ) ,
319
- }
320
- } ,
321
- }
322
- }
323
-
324
- #[ cfg( test) ]
325
- pub mod tests;
0 commit comments