(index<- )        ./libextra/crypto/cryptoutil.rs

   1  // Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
   2  // file at the top-level directory of this distribution and at
   3  // http://rust-lang.org/COPYRIGHT.
   4  //
   5  // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
   6  // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
   7  // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
   8  // option. This file may not be copied, modified, or distributed
   9  // except according to those terms.
  10  
  11  use std::num::{One, Zero, CheckedAdd};
  12  use std::vec::bytes::{MutableByteVector, copy_memory};
  13  
  14  
  15  /// Write a u64 into a vector, which must be 8 bytes long. The value is written in big-endian
  16  /// format.
  17  pub fn write_u64_be(dst&mut[u8], inputu64) {
  18      use std::cast::transmute;
  19      use std::unstable::intrinsics::to_be64;
  20      assert!(dst.len() == 8);
  21      unsafe {
  22          let x*mut i64 = transmute(dst.unsafe_mut_ref(0));
  23          *x = to_be64(input as i64);
  24      }
  25  }
  26  
  27  /// Write a u32 into a vector, which must be 4 bytes long. The value is written in big-endian
  28  /// format.
  29  pub fn write_u32_be(dst&mut[u8], inputu32) {
  30      use std::cast::transmute;
  31      use std::unstable::intrinsics::to_be32;
  32      assert!(dst.len() == 4);
  33      unsafe {
  34          let x*mut i32 = transmute(dst.unsafe_mut_ref(0));
  35          *x = to_be32(input as i32);
  36      }
  37  }
  38  
  39  /// Write a u32 into a vector, which must be 4 bytes long. The value is written in little-endian
  40  /// format.
  41  pub fn write_u32_le(dst&mut[u8], inputu32) {
  42      use std::cast::transmute;
  43      use std::unstable::intrinsics::to_le32;
  44      assert!(dst.len() == 4);
  45      unsafe {
  46          let x*mut i32 = transmute(dst.unsafe_mut_ref(0));
  47          *x = to_le32(input as i32);
  48      }
  49  }
  50  
  51  /// Read a vector of bytes into a vector of u64s. The values are read in big-endian format.
  52  pub fn read_u64v_be(dst&mut[u64], input&[u8]) {
  53      use std::cast::transmute;
  54      use std::unstable::intrinsics::to_be64;
  55      assert!(dst.len() * 8 == input.len());
  56      unsafe {
  57          let mut x*mut i64 = transmute(dst.unsafe_mut_ref(0));
  58          let mut y*i64 = transmute(input.unsafe_ref(0));
  59          do dst.len().times() {
  60              *x = to_be64(*y);
  61              x = x.offset(1);
  62              y = y.offset(1);
  63          }
  64      }
  65  }
  66  
  67  /// Read a vector of bytes into a vector of u32s. The values are read in big-endian format.
  68  pub fn read_u32v_be(dst&mut[u32], input&[u8]) {
  69      use std::cast::transmute;
  70      use std::unstable::intrinsics::to_be32;
  71      assert!(dst.len() * 4 == input.len());
  72      unsafe {
  73          let mut x*mut i32 = transmute(dst.unsafe_mut_ref(0));
  74          let mut y*i32 = transmute(input.unsafe_ref(0));
  75          do dst.len().times() {
  76              *x = to_be32(*y);
  77              x = x.offset(1);
  78              y = y.offset(1);
  79          }
  80      }
  81  }
  82  
  83  /// Read a vector of bytes into a vector of u32s. The values are read in little-endian format.
  84  pub fn read_u32v_le(dst&mut[u32], input&[u8]) {
  85      use std::cast::transmute;
  86      use std::unstable::intrinsics::to_le32;
  87      assert!(dst.len() * 4 == input.len());
  88      unsafe {
  89          let mut x*mut i32 = transmute(dst.unsafe_mut_ref(0));
  90          let mut y*i32 = transmute(input.unsafe_ref(0));
  91          do dst.len().times() {
  92              *x = to_le32(*y);
  93              x = x.offset(1);
  94              y = y.offset(1);
  95          }
  96      }
  97  }
  98  
  99  
 100  trait ToBits {
 101      /// Convert the value in bytes to the number of bits, a tuple where the 1st item is the
 102      /// high-order value and the 2nd item is the low order value.
 103      fn to_bits(self) -> (Self, Self);
 104  }
 105  
 106  impl ToBits for u64 {
 107      fn to_bits(self) -> (u64, u64) {
 108          return (self >> 61, self << 3);
 109      }
 110  }
 111  
 112  /// Adds the specified number of bytes to the bit count. fail!() if this would cause numeric
 113  /// overflow.
 114  pub fn add_bytes_to_bits<T: Int + CheckedAdd + ToBits>(bitsT, bytesT) -> T {
 115      let (new_high_bits, new_low_bits) = bytes.to_bits();
 116  
 117      if new_high_bits > Zero::zero() {
 118          fail!("Numeric overflow occured.")
 119      }
 120  
 121      match bits.checked_add(&new_low_bits) {
 122          Some(x) => return x,
 123          None => fail!("Numeric overflow occured.")
 124      }
 125  }
 126  
 127  /// Adds the specified number of bytes to the bit count, which is a tuple where the first element is
 128  /// the high order value. fail!() if this would cause numeric overflow.
 129  pub fn add_bytes_to_bits_tuple
 130          <T: Int + Unsigned + CheckedAdd + ToBits>
 131          (bits(T, T), bytesT) -> (T, T) {
 132      let (new_high_bits, new_low_bits) = bytes.to_bits();
 133      let (hi, low) = bits;
 134  
 135      // Add the low order value - if there is no overflow, then add the high order values
 136      // If the addition of the low order values causes overflow, add one to the high order values
 137      // before adding them.
 138      match low.checked_add(&new_low_bits) {
 139          Some(x) => {
 140              if new_high_bits == Zero::zero() {
 141                  // This is the fast path - every other alternative will rarely occur in practice
 142                  // considering how large an input would need to be for those paths to be used.
 143                  return (hi, x);
 144              } else {
 145                  match hi.checked_add(&new_high_bits) {
 146                      Some(y) => return (y, x),
 147                      None => fail!("Numeric overflow occured.")
 148                  }
 149              }
 150          },
 151          None => {
 152              let oneT = One::one();
 153              let z = match new_high_bits.checked_add(&one) {
 154                  Some(w) => w,
 155                  None => fail!("Numeric overflow occured.")
 156              };
 157              match hi.checked_add(&z) {
 158                  // This re-executes the addition that was already performed earlier when overflow
 159                  // occured, this time allowing the overflow to happen. Technically, this could be
 160                  // avoided by using the checked add intrinsic directly, but that involves using
 161                  // unsafe code and is not really worthwhile considering how infrequently code will
 162                  // run in practice. This is the reason that this function requires that the type T
 163                  // be Unsigned - overflow is not defined for Signed types. This function could be
 164                  // implemented for signed types as well if that were needed.
 165                  Some(y) => return (y, low + new_low_bits),
 166                  None => fail!("Numeric overflow occured.")
 167              }
 168          }
 169      }
 170  }
 171  
 172  
 173  /// A FixedBuffer, likes its name implies, is a fixed size buffer. When the buffer becomes full, it
 174  /// must be processed. The input() method takes care of processing and then clearing the buffer
 175  /// automatically. However, other methods do not and require the caller to process the buffer. Any
 176  /// method that modifies the buffer directory or provides the caller with bytes that can be modifies
 177  /// results in those bytes being marked as used by the buffer.
 178  pub trait FixedBuffer {
 179      /// Input a vector of bytes. If the buffer becomes full, process it with the provided
 180      /// function and then clear the buffer.
 181      fn input(&mut self, input: &[u8], func: &fn(&[u8]));
 182  
 183      /// Reset the buffer.
 184      fn reset(&mut self);
 185  
 186      /// Zero the buffer up until the specified index. The buffer position currently must not be
 187      /// greater than that index.
 188      fn zero_until(&mut self, idx: uint);
 189  
 190      /// Get a slice of the buffer of the specified size. There must be at least that many bytes
 191      /// remaining in the buffer.
 192      fn next<'s>(&'s mut self, len: uint) -> &'s mut [u8];
 193  
 194      /// Get the current buffer. The buffer must already be full. This clears the buffer as well.
 195      fn full_buffer<'s>(&'s mut self) -> &'s [u8];
 196  
 197      /// Get the current position of the buffer.
 198      fn position(&self) -> uint;
 199  
 200      /// Get the number of bytes remaining in the buffer until it is full.
 201      fn remaining(&self) -> uint;
 202  
 203      /// Get the size of the buffer
 204      fn size(&self) -> uint;
 205  }
 206  
 207  macro_rules! impl_fixed_buffer( ($name:ident, $size:expr) => (
 208      impl FixedBuffer for $name {
 209          fn input(&mut self, input&[u8], func&fn(&[u8])) {
 210              let mut i = 0;
 211  
 212              // FIXME: #6304 - This local variable shouldn't be necessary.
 213              let size = $size;
 214  
 215              // If there is already data in the buffer, copy as much as we can into it and process
 216              // the data if the buffer becomes full.
 217              if self.buffer_idx != 0 {
 218                  let buffer_remaining = size - self.buffer_idx;
 219                  if input.len() >= buffer_remaining {
 220                          copy_memory(
 221                              self.buffer.mut_slice(self.buffer_idx, size),
 222                              input.slice_to(buffer_remaining),
 223                              buffer_remaining);
 224                      self.buffer_idx = 0;
 225                      func(self.buffer);
 226                      i += buffer_remaining;
 227                  } else {
 228                      copy_memory(
 229                          self.buffer.mut_slice(self.buffer_idx, self.buffer_idx + input.len()),
 230                          input,
 231                          input.len());
 232                      self.buffer_idx += input.len();
 233                      return;
 234                  }
 235              }
 236  
 237              // While we have at least a full buffer size chunks's worth of data, process that data
 238              // without copying it into the buffer
 239              while input.len() - i >= size {
 240                  func(input.slice(i, i + size));
 241                  i += size;
 242              }
 243  
 244              // Copy any input data into the buffer. At this point in the method, the ammount of
 245              // data left in the input vector will be less than the buffer size and the buffer will
 246              // be empty.
 247              let input_remaining = input.len() - i;
 248              copy_memory(
 249                  self.buffer.mut_slice(0, input_remaining),
 250                  input.slice_from(i),
 251                  input.len() - i);
 252              self.buffer_idx += input_remaining;
 253          }
 254  
 255          fn reset(&mut self) {
 256              self.buffer_idx = 0;
 257          }
 258  
 259          fn zero_until(&mut self, idxuint) {
 260              assert!(idx >= self.buffer_idx);
 261              self.buffer.mut_slice(self.buffer_idx, idx).set_memory(0);
 262              self.buffer_idx = idx;
 263          }
 264  
 265          fn next<'s>(&'s mut self, lenuint) -> &'s mut [u8] {
 266              self.buffer_idx += len;
 267              return self.buffer.mut_slice(self.buffer_idx - len, self.buffer_idx);
 268          }
 269  
 270          fn full_buffer<'s>(&'s mut self) -> &'s [u8] {
 271              assert!(self.buffer_idx == $size);
 272              self.buffer_idx = 0;
 273              return self.buffer.slice_to($size);
 274          }
 275  
 276          fn position(&self) -> uint { self.buffer_idx }
 277  
 278          fn remaining(&self) -> uint { $size - self.buffer_idx }
 279  
 280          fn size(&self) -> uint { $size }
 281      }
 282  ))
 283  
 284  
 285  /// A fixed size buffer of 64 bytes useful for cryptographic operations.
 286  pub struct FixedBuffer64 {
 287      priv buffer: [u8, ..64],
 288      priv buffer_idx: uint,
 289  }
 290  
 291  impl FixedBuffer64 {
 292      /// Create a new buffer
 293      pub fn new() -> FixedBuffer64 {
 294          return FixedBuffer64 {
 295              buffer: [0u8, ..64],
 296              buffer_idx: 0
 297          };
 298      }
 299  }
 300  
 301  impl_fixed_buffer!(FixedBuffer64, 64)
 302  
 303  /// A fixed size buffer of 128 bytes useful for cryptographic operations.
 304  pub struct FixedBuffer128 {
 305      priv buffer: [u8, ..128],
 306      priv buffer_idx: uint,
 307  }
 308  
 309  impl FixedBuffer128 {
 310      /// Create a new buffer
 311      pub fn new() -> FixedBuffer128 {
 312          return FixedBuffer128 {
 313              buffer: [0u8, ..128],
 314              buffer_idx: 0
 315          };
 316      }
 317  }
 318  
 319  impl_fixed_buffer!(FixedBuffer128, 128)
 320  
 321  
 322  /// The StandardPadding trait adds a method useful for various hash algorithms to a FixedBuffer
 323  /// struct.
 324  pub trait StandardPadding {
 325      /// Add standard padding to the buffer. The buffer must not be full when this method is called
 326      /// and is guaranteed to have exactly rem remaining bytes when it returns. If there are not at
 327      /// least rem bytes available, the buffer will be zero padded, processed, cleared, and then
 328      /// filled with zeros again until only rem bytes are remaining.
 329      fn standard_padding(&mut self, rem: uint, func: &fn(&[u8]));
 330  }
 331  
 332  impl <T: FixedBuffer> StandardPadding for T {
 333      fn standard_padding(&mut self, remuint, func&fn(&[u8])) {
 334          let size = self.size();
 335  
 336          self.next(1)[0] = 128;
 337  
 338          if self.remaining() < rem {
 339              self.zero_until(size);
 340              func(self.full_buffer());
 341          }
 342  
 343          self.zero_until(size - rem);
 344      }
 345  }
 346  
 347  
 348  #[cfg(test)]
 349  mod test {
 350      use std::rand::{IsaacRng, Rng};
 351      use std::vec;
 352  
 353      use cryptoutil::{add_bytes_to_bits, add_bytes_to_bits_tuple};
 354      use digest::Digest;
 355  
 356      /// Feed 1,000,000 'a's into the digest with varying input sizes and check that the result is
 357      /// correct.
 358      pub fn test_digest_1million_random<D: Digest>(digest: &mut D, blocksize: uint, expected: &str) {
 359          let total_size = 1000000;
 360          let buffer = vec::from_elem(blocksize * 2, 'a' as u8);
 361          let mut rng = IsaacRng::new_unseeded();
 362          let mut count = 0;
 363  
 364          digest.reset();
 365  
 366          while count < total_size {
 367              let next: uint = rng.gen_integer_range(0, 2 * blocksize + 1);
 368              let remaining = total_size - count;
 369              let size = if next > remaining { remaining } else { next };
 370              digest.input(buffer.slice_to(size));
 371              count += size;
 372          }
 373  
 374          let result_str = digest.result_str();
 375  
 376          assert!(expected == result_str);
 377      }
 378  
 379      // A normal addition - no overflow occurs
 380      #[test]
 381      fn test_add_bytes_to_bits_ok() {
 382          assert!(add_bytes_to_bits::<u64>(100, 10) == 180);
 383      }
 384  
 385      // A simple failure case - adding 1 to the max value
 386      #[test]
 387      #[should_fail]
 388      fn test_add_bytes_to_bits_overflow() {
 389          add_bytes_to_bits::<u64>(Bounded::max_value(), 1);
 390      }
 391  
 392      // A normal addition - no overflow occurs (fast path)
 393      #[test]
 394      fn test_add_bytes_to_bits_tuple_ok() {
 395          assert!(add_bytes_to_bits_tuple::<u64>((5, 100), 10) == (5, 180));
 396      }
 397  
 398      // The low order value overflows into the high order value
 399      #[test]
 400      fn test_add_bytes_to_bits_tuple_ok2() {
 401          assert!(add_bytes_to_bits_tuple::<u64>((5, Bounded::max_value()), 1) == (6, 7));
 402      }
 403  
 404      // The value to add is too large to be converted into bits without overflowing its type
 405      #[test]
 406      fn test_add_bytes_to_bits_tuple_ok3() {
 407          assert!(add_bytes_to_bits_tuple::<u64>((5, 0), 0x4000000000000001) == (7, 8));
 408      }
 409  
 410      // A simple failure case - adding 1 to the max value
 411      #[test]
 412      #[should_fail]
 413      fn test_add_bytes_to_bits_tuple_overflow() {
 414          add_bytes_to_bits_tuple::<u64>((Bounded::max_value(), Bounded::max_value()), 1);
 415      }
 416  
 417      // The value to add is too large to convert to bytes without overflowing its type, but the high
 418      // order value from this conversion overflows when added to the existing high order value
 419      #[test]
 420      #[should_fail]
 421      fn test_add_bytes_to_bits_tuple_overflow2() {
 422          let value: u64 = Bounded::max_value();
 423          add_bytes_to_bits_tuple::<u64>((value - 1, 0), 0x8000000000000000);
 424      }
 425  }

libextra/crypto/cryptoutil.rs:51:92-51:92 -fn- definition:
/// Read a vector of bytes into a vector of u64s. The values are read in big-endian format.
pub fn read_u64v_be(dst: &mut[u64], input: &[u8]) {
references:-
libextra/crypto/sha2.rs:
110:         read_u64v_be(W.mut_slice(0, 16), data);


libextra/crypto/cryptoutil.rs:285:73-285:73 -struct- definition:
/// A fixed size buffer of 64 bytes useful for cryptographic operations.
pub struct FixedBuffer64 {
references:-
294:         return FixedBuffer64 {
293:     pub fn new() -> FixedBuffer64 {
208:     impl FixedBuffer for $name {
291: impl FixedBuffer64 {
libextra/crypto/md5.rs:
161:     priv buffer: FixedBuffer64,
libextra/crypto/sha1.rs:
48:     priv buffer: FixedBuffer64,
libextra/crypto/sha2.rs:
594:     buffer: FixedBuffer64,


libextra/crypto/cryptoutil.rs:28:12-28:12 -fn- definition:
/// format.
pub fn write_u32_be(dst: &mut[u8], input: u32) {
references:-
libextra/crypto/sha1.rs:
134:         write_u32_be(st.buffer.next(4), st.length_bits as u32);
143:     write_u32_be(rs.mut_slice(12, 16), st.h[3]);
133:         write_u32_be(st.buffer.next(4), (st.length_bits >> 32) as u32 );
142:     write_u32_be(rs.mut_slice(8, 12), st.h[2]);
144:     write_u32_be(rs.mut_slice(16, 20), st.h[4]);
140:     write_u32_be(rs.mut_slice(0, 4), st.h[0]);
141:     write_u32_be(rs.mut_slice(4, 8), st.h[1]);
libextra/crypto/sha2.rs:
664:         write_u32_be(out.mut_slice(12, 16), self.engine.state.H3);
661:         write_u32_be(out.mut_slice(0, 4), self.engine.state.H0);
667:         write_u32_be(out.mut_slice(24, 28), self.engine.state.H6);
662:         write_u32_be(out.mut_slice(4, 8), self.engine.state.H1);
717:         write_u32_be(out.mut_slice(20, 24), self.engine.state.H5);
718:         write_u32_be(out.mut_slice(24, 28), self.engine.state.H6);
712:         write_u32_be(out.mut_slice(0, 4), self.engine.state.H0);
716:         write_u32_be(out.mut_slice(16, 20), self.engine.state.H4);
630:         write_u32_be(self.buffer.next(4), self.length_bits as u32);
629:         write_u32_be(self.buffer.next(4), (self.length_bits >> 32) as u32 );
668:         write_u32_be(out.mut_slice(28, 32), self.engine.state.H7);
409:         write_u32_be(out.mut_slice(24, 28), (self.engine.state.H3 >> 32) as u32);
713:         write_u32_be(out.mut_slice(4, 8), self.engine.state.H1);
714:         write_u32_be(out.mut_slice(8, 12), self.engine.state.H2);
666:         write_u32_be(out.mut_slice(20, 24), self.engine.state.H5);
715:         write_u32_be(out.mut_slice(12, 16), self.engine.state.H3);
665:         write_u32_be(out.mut_slice(16, 20), self.engine.state.H4);
663:         write_u32_be(out.mut_slice(8, 12), self.engine.state.H2);


libextra/crypto/cryptoutil.rs:40:12-40:12 -fn- definition:
/// format.
pub fn write_u32_le(dst: &mut[u8], input: u32) {
references:-
libextra/crypto/md5.rs:
198:             write_u32_le(self.buffer.next(4), (self.length_bytes >> 29) as u32);
206:         write_u32_le(out.mut_slice(12, 16), self.state.s3);
204:         write_u32_le(out.mut_slice(4, 8), self.state.s1);
203:         write_u32_le(out.mut_slice(0, 4), self.state.s0);
205:         write_u32_le(out.mut_slice(8, 12), self.state.s2);
197:             write_u32_le(self.buffer.next(4), (self.length_bytes << 3) as u32);


libextra/crypto/cryptoutil.rs:128:72-128:72 -fn- definition:
/// the high order value. fail!() if this would cause numeric overflow.
pub fn add_bytes_to_bits_tuple
references:-
libextra/crypto/sha2.rs:
210:         self.length_bits = add_bytes_to_bits_tuple(self.length_bits, input.len() as u64);


libextra/crypto/cryptoutil.rs:67:92-67:92 -fn- definition:
/// Read a vector of bytes into a vector of u32s. The values are read in big-endian format.
pub fn read_u32v_be(dst: &mut[u32], input: &[u8]) {
references:-
libextra/crypto/sha1.rs:
65:     read_u32v_be(w.mut_slice(0, 16), data);
libextra/crypto/sha2.rs:
524:         read_u32v_be(W.mut_slice(0, 16), data);


libextra/crypto/cryptoutil.rs:99:1-99:1 -trait- definition:

trait ToBits {
references:-
103:     fn to_bits(self) -> (Self, Self);
103:     fn to_bits(self) -> (Self, Self);
106: impl ToBits for u64 {
130:         <T: Int + Unsigned + CheckedAdd + ToBits>
114: pub fn add_bytes_to_bits<T: Int + CheckedAdd + ToBits>(bits: T, bytes: T) -> T {


libextra/crypto/cryptoutil.rs:16:12-16:12 -fn- definition:
/// format.
pub fn write_u64_be(dst: &mut[u8], input: u64) {
references:-
libextra/crypto/sha2.rs:
259:         write_u64_be(out.mut_slice(24, 32), self.engine.state.H3);
260:         write_u64_be(out.mut_slice(32, 40), self.engine.state.H4);
359:         write_u64_be(out.mut_slice(8, 16), self.engine.state.H1);
261:         write_u64_be(out.mut_slice(40, 48), self.engine.state.H5);
223:                 write_u64_be(self.buffer.next(8), low);
311:         write_u64_be(out.mut_slice(24, 32), self.engine.state.H3);
258:         write_u64_be(out.mut_slice(16, 24), self.engine.state.H2);
313:         write_u64_be(out.mut_slice(40, 48), self.engine.state.H5);
257:         write_u64_be(out.mut_slice(8, 16), self.engine.state.H1);
360:         write_u64_be(out.mut_slice(16, 24), self.engine.state.H2);
222:                 write_u64_be(self.buffer.next(8), hi);
310:         write_u64_be(out.mut_slice(16, 24), self.engine.state.H2);
263:         write_u64_be(out.mut_slice(56, 64), self.engine.state.H7);
312:         write_u64_be(out.mut_slice(32, 40), self.engine.state.H4);
256:         write_u64_be(out.mut_slice(0, 8), self.engine.state.H0);
262:         write_u64_be(out.mut_slice(48, 56), self.engine.state.H6);
408:         write_u64_be(out.mut_slice(16, 24), self.engine.state.H2);
361:         write_u64_be(out.mut_slice(24, 32), self.engine.state.H3);
407:         write_u64_be(out.mut_slice(8, 16), self.engine.state.H1);
406:         write_u64_be(out.mut_slice(0, 8), self.engine.state.H0);
358:         write_u64_be(out.mut_slice(0, 8), self.engine.state.H0);
308:         write_u64_be(out.mut_slice(0, 8), self.engine.state.H0);
309:         write_u64_be(out.mut_slice(8, 16), self.engine.state.H1);


libextra/crypto/cryptoutil.rs:113:14-113:14 -fn- definition:
/// overflow.
pub fn add_bytes_to_bits<T: Int + CheckedAdd + ToBits>(bits: T, bytes: T) -> T {
references:-
libextra/crypto/sha1.rs:
55:     st.length_bits = add_bytes_to_bits(st.length_bits, msg.len() as u64);
libextra/crypto/sha2.rs:
619:         self.length_bits = add_bytes_to_bits(self.length_bits, input.len() as u64);


libextra/crypto/cryptoutil.rs:83:95-83:95 -fn- definition:
/// Read a vector of bytes into a vector of u32s. The values are read in little-endian format.
pub fn read_u32v_le(dst: &mut[u32], input: &[u8]) {
references:-
libextra/crypto/md5.rs:
86:         read_u32v_le(data, input);


libextra/crypto/cryptoutil.rs:303:74-303:74 -struct- definition:
/// A fixed size buffer of 128 bytes useful for cryptographic operations.
pub struct FixedBuffer128 {
references:-
311:     pub fn new() -> FixedBuffer128 {
309: impl FixedBuffer128 {
208:     impl FixedBuffer for $name {
312:         return FixedBuffer128 {
libextra/crypto/sha2.rs:
185:     buffer: FixedBuffer128,


libextra/crypto/cryptoutil.rs:323:12-323:12 -trait- definition:
/// struct.
pub trait StandardPadding {
references:-
332: impl <T: FixedBuffer> StandardPadding for T {


libextra/crypto/cryptoutil.rs:177:63-177:63 -trait- definition:
/// results in those bytes being marked as used by the buffer.
pub trait FixedBuffer {
references:-
208:     impl FixedBuffer for $name {
208:     impl FixedBuffer for $name {
332: impl <T: FixedBuffer> StandardPadding for T {