(index<- )        ./libextra/crypto/sha2.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::iter::range_step;
   12  
   13  use cryptoutil::{write_u64_be, write_u32_be, read_u64v_be, read_u32v_be, add_bytes_to_bits,
   14      add_bytes_to_bits_tuple, FixedBuffer, FixedBuffer128, FixedBuffer64, StandardPadding};
   15  use digest::Digest;
   16  
   17  // A structure that represents that state of a digest computation for the SHA-2 512 family
   18  // of digest functions
   19  struct Engine512State {
   20      H0: u64,
   21      H1: u64,
   22      H2: u64,
   23      H3: u64,
   24      H4: u64,
   25      H5: u64,
   26      H6: u64,
   27      H7: u64,
   28  }
   29  
   30  impl Engine512State {
   31      fn new(h&[u64, ..8]) -> Engine512State {
   32          return Engine512State {
   33              H0: h[0],
   34              H1: h[1],
   35              H2: h[2],
   36              H3: h[3],
   37              H4: h[4],
   38              H5: h[5],
   39              H6: h[6],
   40              H7: h[7]
   41          };
   42      }
   43  
   44      fn reset(&mut self, h&[u64, ..8]) {
   45          self.H0 = h[0];
   46          self.H1 = h[1];
   47          self.H2 = h[2];
   48          self.H3 = h[3];
   49          self.H4 = h[4];
   50          self.H5 = h[5];
   51          self.H6 = h[6];
   52          self.H7 = h[7];
   53      }
   54  
   55      fn process_block(&mut self, data&[u8]) {
   56          fn ch(xu64, yu64, zu64) -> u64 {
   57              ((x & y) ^ ((!x) & z))
   58          }
   59  
   60          fn maj(xu64, yu64, zu64) -> u64 {
   61              ((x & y) ^ (x & z) ^ (y & z))
   62          }
   63  
   64          fn sum0(xu64) -> u64 {
   65              ((x << 36) | (x >> 28)) ^ ((x << 30) | (x >> 34)) ^ ((x << 25) | (x >> 39))
   66          }
   67  
   68          fn sum1(xu64) -> u64 {
   69              ((x << 50) | (x >> 14)) ^ ((x << 46) | (x >> 18)) ^ ((x << 23) | (x >> 41))
   70          }
   71  
   72          fn sigma0(xu64) -> u64 {
   73              ((x << 63) | (x >> 1)) ^ ((x << 56) | (x >> 8)) ^ (x >> 7)
   74          }
   75  
   76          fn sigma1(xu64) -> u64 {
   77              ((x << 45) | (x >> 19)) ^ ((x << 3) | (x >> 61)) ^ (x >> 6)
   78          }
   79  
   80          let mut a = self.H0;
   81          let mut b = self.H1;
   82          let mut c = self.H2;
   83          let mut d = self.H3;
   84          let mut e = self.H4;
   85          let mut f = self.H5;
   86          let mut g = self.H6;
   87          let mut h = self.H7;
   88  
   89          let mut W = [0u64, ..80];
   90  
   91          // Sha-512 and Sha-256 use basically the same calculations which are implemented by
   92          // these macros. Inlining the calculations seems to result in better generated code.
   93          macro_rules! schedule_round( ($t:expr) => (
   94                  W[$t] = sigma1(W[$t - 2]) + W[$t - 7] + sigma0(W[$t - 15]) + W[$t - 16];
   95                  )
   96          )
   97  
   98          macro_rules! sha2_round(
   99              ($A:ident, $B:ident, $C:ident, $D:ident,
  100               $E:ident, $F:ident, $G:ident, $H:ident, $K:ident, $t:expr) => (
  101                  {
  102                      $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
  103                      $D += $H;
  104                      $H += sum0($A) + maj($A, $B, $C);
  105                  }
  106               )
  107          )
  108  
  109  
  110          read_u64v_be(W.mut_slice(0, 16), data);
  111  
  112          // Putting the message schedule inside the same loop as the round calculations allows for
  113          // the compiler to generate better code.
  114          for t in range_step(0u, 64, 8) {
  115              schedule_round!(t + 16);
  116              schedule_round!(t + 17);
  117              schedule_round!(t + 18);
  118              schedule_round!(t + 19);
  119              schedule_round!(t + 20);
  120              schedule_round!(t + 21);
  121              schedule_round!(t + 22);
  122              schedule_round!(t + 23);
  123  
  124              sha2_round!(a, b, c, d, e, f, g, h, K64, t);
  125              sha2_round!(h, a, b, c, d, e, f, g, K64, t + 1);
  126              sha2_round!(g, h, a, b, c, d, e, f, K64, t + 2);
  127              sha2_round!(f, g, h, a, b, c, d, e, K64, t + 3);
  128              sha2_round!(e, f, g, h, a, b, c, d, K64, t + 4);
  129              sha2_round!(d, e, f, g, h, a, b, c, K64, t + 5);
  130              sha2_round!(c, d, e, f, g, h, a, b, K64, t + 6);
  131              sha2_round!(b, c, d, e, f, g, h, a, K64, t + 7);
  132          }
  133  
  134          for t in range_step(64u, 80, 8) {
  135              sha2_round!(a, b, c, d, e, f, g, h, K64, t);
  136              sha2_round!(h, a, b, c, d, e, f, g, K64, t + 1);
  137              sha2_round!(g, h, a, b, c, d, e, f, K64, t + 2);
  138              sha2_round!(f, g, h, a, b, c, d, e, K64, t + 3);
  139              sha2_round!(e, f, g, h, a, b, c, d, K64, t + 4);
  140              sha2_round!(d, e, f, g, h, a, b, c, K64, t + 5);
  141              sha2_round!(c, d, e, f, g, h, a, b, K64, t + 6);
  142              sha2_round!(b, c, d, e, f, g, h, a, K64, t + 7);
  143          }
  144  
  145          self.H0 += a;
  146          self.H1 += b;
  147          self.H2 += c;
  148          self.H3 += d;
  149          self.H4 += e;
  150          self.H5 += f;
  151          self.H6 += g;
  152          self.H7 += h;
  153      }
  154  }
  155  
  156  // Constants necessary for SHA-2 512 family of digests.
  157  static K64: [u64, ..80] = [
  158      0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc,
  159      0x3956c25bf348b538, 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118,
  160      0xd807aa98a3030242, 0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,
  161      0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235, 0xc19bf174cf692694,
  162      0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65,
  163      0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,
  164      0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4,
  165      0xc6e00bf33da88fc2, 0xd5a79147930aa725, 0x06ca6351e003826f, 0x142929670a0e6e70,
  166      0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df,
  167      0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b,
  168      0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30,
  169      0xd192e819d6ef5218, 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8,
  170      0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8,
  171      0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3,
  172      0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
  173      0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b,
  174      0xca273eceea26619c, 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178,
  175      0x06f067aa72176fba, 0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b,
  176      0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c,
  177      0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817
  178  ];
  179  
  180  
  181  // A structure that keeps track of the state of the Sha-512 operation and contains the logic
  182  // necessary to perform the final calculations.
  183  struct Engine512 {
  184      length_bits: (u64, u64),
  185      buffer: FixedBuffer128,
  186      state: Engine512State,
  187      finished: bool,
  188  }
  189  
  190  impl Engine512 {
  191      fn new(h&[u64, ..8]) -> Engine512 {
  192          return Engine512 {
  193              length_bits: (0, 0),
  194              buffer: FixedBuffer128::new(),
  195              state: Engine512State::new(h),
  196              finished: false
  197          }
  198      }
  199  
  200      fn reset(&mut self, h&[u64, ..8]) {
  201          self.length_bits = (0, 0);
  202          self.buffer.reset();
  203          self.state.reset(h);
  204          self.finished = false;
  205      }
  206  
  207      fn input(&mut self, input&[u8]) {
  208          assert!(!self.finished)
  209          // Assumes that input.len() can be converted to u64 without overflow
  210          self.length_bits = add_bytes_to_bits_tuple(self.length_bits, input.len() as u64);
  211          self.buffer.input(input, |input&[u8]{ self.state.process_block(input) });
  212      }
  213  
  214      fn finish(&mut self) {
  215          if self.finished {
  216              return;
  217          }
  218  
  219          self.buffer.standard_padding(16, |input&[u8]{ self.state.process_block(input) });
  220          match self.length_bits {
  221              (hi, low) => {
  222                  write_u64_be(self.buffer.next(8), hi);
  223                  write_u64_be(self.buffer.next(8), low);
  224              }
  225          }
  226          self.state.process_block(self.buffer.full_buffer());
  227  
  228          self.finished = true;
  229      }
  230  }
  231  
  232  
  233  struct Sha512 {
  234      priv engine: Engine512
  235  }
  236  
  237  impl Sha512 {
  238      /**
  239       * Construct an new instance of a SHA-512 digest.
  240       */
  241      pub fn new() -> Sha512 {
  242          return Sha512 {
  243              engine: Engine512::new(&H512)
  244          };
  245      }
  246  }
  247  
  248  impl Digest for Sha512 {
  249      fn input(&mut self, d&[u8]) {
  250          self.engine.input(d);
  251      }
  252  
  253      fn result(&mut self, out&mut [u8]) {
  254          self.engine.finish();
  255  
  256          write_u64_be(out.mut_slice(0, 8), self.engine.state.H0);
  257          write_u64_be(out.mut_slice(8, 16), self.engine.state.H1);
  258          write_u64_be(out.mut_slice(16, 24), self.engine.state.H2);
  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);
  261          write_u64_be(out.mut_slice(40, 48), self.engine.state.H5);
  262          write_u64_be(out.mut_slice(48, 56), self.engine.state.H6);
  263          write_u64_be(out.mut_slice(56, 64), self.engine.state.H7);
  264      }
  265  
  266      fn reset(&mut self) {
  267          self.engine.reset(&H512);
  268      }
  269  
  270      fn output_bits(&self) -> uint { 512 }
  271  }
  272  
  273  static H512: [u64, ..8] = [
  274      0x6a09e667f3bcc908,
  275      0xbb67ae8584caa73b,
  276      0x3c6ef372fe94f82b,
  277      0xa54ff53a5f1d36f1,
  278      0x510e527fade682d1,
  279      0x9b05688c2b3e6c1f,
  280      0x1f83d9abfb41bd6b,
  281      0x5be0cd19137e2179
  282  ];
  283  
  284  
  285  struct Sha384 {
  286      priv engine: Engine512
  287  }
  288  
  289  impl Sha384 {
  290      /**
  291       * Construct an new instance of a SHA-384 digest.
  292       */
  293      pub fn new() -> Sha384 {
  294          Sha384 {
  295              engine: Engine512::new(&H384)
  296          }
  297      }
  298  }
  299  
  300  impl Digest for Sha384 {
  301      fn input(&mut self, d&[u8]) {
  302          self.engine.input(d);
  303      }
  304  
  305      fn result(&mut self, out&mut [u8]) {
  306          self.engine.finish();
  307  
  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);
  310          write_u64_be(out.mut_slice(16, 24), self.engine.state.H2);
  311          write_u64_be(out.mut_slice(24, 32), self.engine.state.H3);
  312          write_u64_be(out.mut_slice(32, 40), self.engine.state.H4);
  313          write_u64_be(out.mut_slice(40, 48), self.engine.state.H5);
  314      }
  315  
  316      fn reset(&mut self) {
  317          self.engine.reset(&H384);
  318      }
  319  
  320      fn output_bits(&self) -> uint { 384 }
  321  }
  322  
  323  static H384: [u64, ..8] = [
  324      0xcbbb9d5dc1059ed8,
  325      0x629a292a367cd507,
  326      0x9159015a3070dd17,
  327      0x152fecd8f70e5939,
  328      0x67332667ffc00b31,
  329      0x8eb44a8768581511,
  330      0xdb0c2e0d64f98fa7,
  331      0x47b5481dbefa4fa4
  332  ];
  333  
  334  
  335  struct Sha512Trunc256 {
  336      priv engine: Engine512
  337  }
  338  
  339  impl Sha512Trunc256 {
  340      /**
  341       * Construct an new instance of a SHA-512/256 digest.
  342       */
  343      pub fn new() -> Sha512Trunc256 {
  344          Sha512Trunc256 {
  345              engine: Engine512::new(&H512_TRUNC_256)
  346          }
  347      }
  348  }
  349  
  350  impl Digest for Sha512Trunc256 {
  351      fn input(&mut self, d&[u8]) {
  352          self.engine.input(d);
  353      }
  354  
  355      fn result(&mut self, out&mut [u8]) {
  356          self.engine.finish();
  357  
  358          write_u64_be(out.mut_slice(0, 8), self.engine.state.H0);
  359          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);
  361          write_u64_be(out.mut_slice(24, 32), self.engine.state.H3);
  362      }
  363  
  364      fn reset(&mut self) {
  365          self.engine.reset(&H512_TRUNC_256);
  366      }
  367  
  368      fn output_bits(&self) -> uint { 256 }
  369  }
  370  
  371  static H512_TRUNC_256: [u64, ..8] = [
  372      0x22312194fc2bf72c,
  373      0x9f555fa3c84c64c2,
  374      0x2393b86b6f53b151,
  375      0x963877195940eabd,
  376      0x96283ee2a88effe3,
  377      0xbe5e1e2553863992,
  378      0x2b0199fc2c85b8aa,
  379      0x0eb72ddc81c52ca2
  380  ];
  381  
  382  
  383  struct Sha512Trunc224 {
  384      priv engine: Engine512
  385  }
  386  
  387  impl Sha512Trunc224 {
  388      /**
  389       * Construct an new instance of a SHA-512/224 digest.
  390       */
  391      pub fn new() -> Sha512Trunc224 {
  392          Sha512Trunc224 {
  393              engine: Engine512::new(&H512_TRUNC_224)
  394          }
  395      }
  396  }
  397  
  398  impl Digest for Sha512Trunc224 {
  399      fn input(&mut self, d&[u8]) {
  400          self.engine.input(d);
  401      }
  402  
  403      fn result(&mut self, out&mut [u8]) {
  404          self.engine.finish();
  405  
  406          write_u64_be(out.mut_slice(0, 8), self.engine.state.H0);
  407          write_u64_be(out.mut_slice(8, 16), self.engine.state.H1);
  408          write_u64_be(out.mut_slice(16, 24), self.engine.state.H2);
  409          write_u32_be(out.mut_slice(24, 28), (self.engine.state.H3 >> 32) as u32);
  410      }
  411  
  412      fn reset(&mut self) {
  413          self.engine.reset(&H512_TRUNC_224);
  414      }
  415  
  416      fn output_bits(&self) -> uint { 224 }
  417  }
  418  
  419  static H512_TRUNC_224: [u64, ..8] = [
  420      0x8c3d37c819544da2,
  421      0x73e1996689dcd4d6,
  422      0x1dfab7ae32ff9c82,
  423      0x679dd514582f9fcf,
  424      0x0f6d2b697bd44da8,
  425      0x77e36f7304c48942,
  426      0x3f9d85a86a1d36c8,
  427      0x1112e6ad91d692a1,
  428  ];
  429  
  430  
  431  // A structure that represents that state of a digest computation for the SHA-2 512 family of digest
  432  // functions
  433  struct Engine256State {
  434      H0: u32,
  435      H1: u32,
  436      H2: u32,
  437      H3: u32,
  438      H4: u32,
  439      H5: u32,
  440      H6: u32,
  441      H7: u32,
  442  }
  443  
  444  impl Engine256State {
  445      fn new(h&[u32, ..8]) -> Engine256State {
  446          return Engine256State {
  447              H0: h[0],
  448              H1: h[1],
  449              H2: h[2],
  450              H3: h[3],
  451              H4: h[4],
  452              H5: h[5],
  453              H6: h[6],
  454              H7: h[7]
  455          };
  456      }
  457  
  458      fn reset(&mut self, h&[u32, ..8]) {
  459          self.H0 = h[0];
  460          self.H1 = h[1];
  461          self.H2 = h[2];
  462          self.H3 = h[3];
  463          self.H4 = h[4];
  464          self.H5 = h[5];
  465          self.H6 = h[6];
  466          self.H7 = h[7];
  467      }
  468  
  469      fn process_block(&mut self, data&[u8]) {
  470          fn ch(xu32, yu32, zu32) -> u32 {
  471              ((x & y) ^ ((!x) & z))
  472          }
  473  
  474          fn maj(xu32, yu32, zu32) -> u32 {
  475              ((x & y) ^ (x & z) ^ (y & z))
  476          }
  477  
  478          fn sum0(xu32) -> u32 {
  479              ((x >> 2) | (x << 30)) ^ ((x >> 13) | (x << 19)) ^ ((x >> 22) | (x << 10))
  480          }
  481  
  482          fn sum1(xu32) -> u32 {
  483              ((x >> 6) | (x << 26)) ^ ((x >> 11) | (x << 21)) ^ ((x >> 25) | (x << 7))
  484          }
  485  
  486          fn sigma0(xu32) -> u32 {
  487              ((x >> 7) | (x << 25)) ^ ((x >> 18) | (x << 14)) ^ (x >> 3)
  488          }
  489  
  490          fn sigma1(xu32) -> u32 {
  491              ((x >> 17) | (x << 15)) ^ ((x >> 19) | (x << 13)) ^ (x >> 10)
  492          }
  493  
  494          let mut a = self.H0;
  495          let mut b = self.H1;
  496          let mut c = self.H2;
  497          let mut d = self.H3;
  498          let mut e = self.H4;
  499          let mut f = self.H5;
  500          let mut g = self.H6;
  501          let mut h = self.H7;
  502  
  503          let mut W = [0u32, ..64];
  504  
  505          // Sha-512 and Sha-256 use basically the same calculations which are implemented
  506          // by these macros. Inlining the calculations seems to result in better generated code.
  507          macro_rules! schedule_round( ($t:expr) => (
  508                  W[$t] = sigma1(W[$t - 2]) + W[$t - 7] + sigma0(W[$t - 15]) + W[$t - 16];
  509                  )
  510          )
  511  
  512          macro_rules! sha2_round(
  513              ($A:ident, $B:ident, $C:ident, $D:ident,
  514               $E:ident, $F:ident, $G:ident, $H:ident, $K:ident, $t:expr) => (
  515                  {
  516                      $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
  517                      $D += $H;
  518                      $H += sum0($A) + maj($A, $B, $C);
  519                  }
  520               )
  521          )
  522  
  523  
  524          read_u32v_be(W.mut_slice(0, 16), data);
  525  
  526          // Putting the message schedule inside the same loop as the round calculations allows for
  527          // the compiler to generate better code.
  528          for t in range_step(0u, 48, 8) {
  529              schedule_round!(t + 16);
  530              schedule_round!(t + 17);
  531              schedule_round!(t + 18);
  532              schedule_round!(t + 19);
  533              schedule_round!(t + 20);
  534              schedule_round!(t + 21);
  535              schedule_round!(t + 22);
  536              schedule_round!(t + 23);
  537  
  538              sha2_round!(a, b, c, d, e, f, g, h, K32, t);
  539              sha2_round!(h, a, b, c, d, e, f, g, K32, t + 1);
  540              sha2_round!(g, h, a, b, c, d, e, f, K32, t + 2);
  541              sha2_round!(f, g, h, a, b, c, d, e, K32, t + 3);
  542              sha2_round!(e, f, g, h, a, b, c, d, K32, t + 4);
  543              sha2_round!(d, e, f, g, h, a, b, c, K32, t + 5);
  544              sha2_round!(c, d, e, f, g, h, a, b, K32, t + 6);
  545              sha2_round!(b, c, d, e, f, g, h, a, K32, t + 7);
  546          }
  547  
  548          for t in range_step(48u, 64, 8) {
  549              sha2_round!(a, b, c, d, e, f, g, h, K32, t);
  550              sha2_round!(h, a, b, c, d, e, f, g, K32, t + 1);
  551              sha2_round!(g, h, a, b, c, d, e, f, K32, t + 2);
  552              sha2_round!(f, g, h, a, b, c, d, e, K32, t + 3);
  553              sha2_round!(e, f, g, h, a, b, c, d, K32, t + 4);
  554              sha2_round!(d, e, f, g, h, a, b, c, K32, t + 5);
  555              sha2_round!(c, d, e, f, g, h, a, b, K32, t + 6);
  556              sha2_round!(b, c, d, e, f, g, h, a, K32, t + 7);
  557          }
  558  
  559          self.H0 += a;
  560          self.H1 += b;
  561          self.H2 += c;
  562          self.H3 += d;
  563          self.H4 += e;
  564          self.H5 += f;
  565          self.H6 += g;
  566          self.H7 += h;
  567      }
  568  }
  569  
  570  static K32: [u32, ..64] = [
  571      0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
  572      0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
  573      0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
  574      0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
  575      0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
  576      0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
  577      0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
  578      0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
  579      0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
  580      0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
  581      0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
  582      0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
  583      0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
  584      0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
  585      0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
  586      0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
  587  ];
  588  
  589  
  590  // A structure that keeps track of the state of the Sha-256 operation and contains the logic
  591  // necessary to perform the final calculations.
  592  struct Engine256 {
  593      length_bits: u64,
  594      buffer: FixedBuffer64,
  595      state: Engine256State,
  596      finished: bool,
  597  }
  598  
  599  impl Engine256 {
  600      fn new(h&[u32, ..8]) -> Engine256 {
  601          return Engine256 {
  602              length_bits: 0,
  603              buffer: FixedBuffer64::new(),
  604              state: Engine256State::new(h),
  605              finished: false
  606          }
  607      }
  608  
  609      fn reset(&mut self, h&[u32, ..8]) {
  610          self.length_bits = 0;
  611          self.buffer.reset();
  612          self.state.reset(h);
  613          self.finished = false;
  614      }
  615  
  616      fn input(&mut self, input&[u8]) {
  617          assert!(!self.finished)
  618          // Assumes that input.len() can be converted to u64 without overflow
  619          self.length_bits = add_bytes_to_bits(self.length_bits, input.len() as u64);
  620          self.buffer.input(input, |input&[u8]{ self.state.process_block(input) });
  621      }
  622  
  623      fn finish(&mut self) {
  624          if self.finished {
  625              return;
  626          }
  627  
  628          self.buffer.standard_padding(8, |input&[u8]{ self.state.process_block(input) });
  629          write_u32_be(self.buffer.next(4), (self.length_bits >> 32) as u32 );
  630          write_u32_be(self.buffer.next(4), self.length_bits as u32);
  631          self.state.process_block(self.buffer.full_buffer());
  632  
  633          self.finished = true;
  634      }
  635  }
  636  
  637  
  638  struct Sha256 {
  639      priv engine: Engine256
  640  }
  641  
  642  impl Sha256 {
  643      /**
  644       * Construct an new instance of a SHA-256 digest.
  645       */
  646      pub fn new() -> Sha256 {
  647          Sha256 {
  648              engine: Engine256::new(&H256)
  649          }
  650      }
  651  }
  652  
  653  impl Digest for Sha256 {
  654      fn input(&mut self, d&[u8]) {
  655          self.engine.input(d);
  656      }
  657  
  658      fn result(&mut self, out&mut [u8]) {
  659          self.engine.finish();
  660  
  661          write_u32_be(out.mut_slice(0, 4), self.engine.state.H0);
  662          write_u32_be(out.mut_slice(4, 8), self.engine.state.H1);
  663          write_u32_be(out.mut_slice(8, 12), self.engine.state.H2);
  664          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);
  666          write_u32_be(out.mut_slice(20, 24), self.engine.state.H5);
  667          write_u32_be(out.mut_slice(24, 28), self.engine.state.H6);
  668          write_u32_be(out.mut_slice(28, 32), self.engine.state.H7);
  669      }
  670  
  671      fn reset(&mut self) {
  672          self.engine.reset(&H256);
  673      }
  674  
  675      fn output_bits(&self) -> uint { 256 }
  676  }
  677  
  678  static H256: [u32, ..8] = [
  679      0x6a09e667,
  680      0xbb67ae85,
  681      0x3c6ef372,
  682      0xa54ff53a,
  683      0x510e527f,
  684      0x9b05688c,
  685      0x1f83d9ab,
  686      0x5be0cd19
  687  ];
  688  
  689  
  690  struct Sha224 {
  691      priv engine: Engine256
  692  }
  693  
  694  impl Sha224 {
  695      /**
  696       * Construct an new instance of a SHA-224 digest.
  697       */
  698      pub fn new() -> Sha224 {
  699          Sha224 {
  700              engine: Engine256::new(&H224)
  701          }
  702      }
  703  }
  704  
  705  impl Digest for Sha224 {
  706      fn input(&mut self, d&[u8]) {
  707          self.engine.input(d);
  708      }
  709  
  710      fn result(&mut self, out&mut [u8]) {
  711          self.engine.finish();
  712          write_u32_be(out.mut_slice(0, 4), self.engine.state.H0);
  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);
  715          write_u32_be(out.mut_slice(12, 16), self.engine.state.H3);
  716          write_u32_be(out.mut_slice(16, 20), self.engine.state.H4);
  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);
  719      }
  720  
  721      fn reset(&mut self) {
  722          self.engine.reset(&H224);
  723      }
  724  
  725      fn output_bits(&self) -> uint { 224 }
  726  }
  727  
  728  static H224: [u32, ..8] = [
  729      0xc1059ed8,
  730      0x367cd507,
  731      0x3070dd17,
  732      0xf70e5939,
  733      0xffc00b31,
  734      0x68581511,
  735      0x64f98fa7,
  736      0xbefa4fa4
  737  ];
  738  
  739  
  740  #[cfg(test)]
  741  mod tests {
  742      use cryptoutil::test::test_digest_1million_random;
  743      use digest::Digest;
  744      use sha2::{Sha512, Sha384, Sha512Trunc256, Sha512Trunc224, Sha256, Sha224};
  745  
  746      struct Test {
  747          input: ~str,
  748          output_str: ~str,
  749      }
  750  
  751      fn test_hash<D: Digest>(sh: &mut D, tests: &[Test]) {
  752          // Test that it works when accepting the message all at once
  753          for t in tests.iter() {
  754              sh.input_str(t.input);
  755  
  756              let out_str = sh.result_str();
  757              assert!(out_str == t.output_str);
  758  
  759              sh.reset();
  760          }
  761  
  762          // Test that it works when accepting the message in pieces
  763          for t in tests.iter() {
  764              let len = t.input.len();
  765              let mut left = len;
  766              while left > 0u {
  767                  let take = (left + 1u) / 2u;
  768                  sh.input_str(t.input.slice(len - left, take + len - left));
  769                  left = left - take;
  770              }
  771  
  772              let out_str = sh.result_str();
  773              assert!(out_str == t.output_str);
  774  
  775              sh.reset();
  776          }
  777      }
  778  
  779      #[test]
  780      fn test_sha512() {
  781          // Examples from wikipedia
  782          let wikipedia_tests = ~[
  783              Test {
  784                  input: ~"",
  785                  output_str: ~"cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce" +
  786                               "47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e"
  787              },
  788              Test {
  789                  input: ~"The quick brown fox jumps over the lazy dog",
  790                  output_str: ~"07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb64" +
  791                               "2e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6"
  792              },
  793              Test {
  794                  input: ~"The quick brown fox jumps over the lazy dog.",
  795                  output_str: ~"91ea1245f20d46ae9a037a989f54f1f790f0a47607eeb8a14d12890cea77a1bb" +
  796                               "c6c7ed9cf205e67b7f2b8fd4c7dfd3a7a8617e45f3c463d481c7e586c39ac1ed"
  797              },
  798          ];
  799  
  800          let tests = wikipedia_tests;
  801  
  802          let mut sh = ~Sha512::new();
  803  
  804          test_hash(sh, tests);
  805      }
  806  
  807      #[test]
  808      fn test_sha384() {
  809          // Examples from wikipedia
  810          let wikipedia_tests = ~[
  811              Test {
  812                  input: ~"",
  813                  output_str: ~"38b060a751ac96384cd9327eb1b1e36a21fdb71114be0743" +
  814                               "4c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b"
  815              },
  816              Test {
  817                  input: ~"The quick brown fox jumps over the lazy dog",
  818                  output_str: ~"ca737f1014a48f4c0b6dd43cb177b0afd9e5169367544c49" +
  819                               "4011e3317dbf9a509cb1e5dc1e85a941bbee3d7f2afbc9b1"
  820              },
  821              Test {
  822                  input: ~"The quick brown fox jumps over the lazy dog.",
  823                  output_str: ~"ed892481d8272ca6df370bf706e4d7bc1b5739fa2177aae6" +
  824                               "c50e946678718fc67a7af2819a021c2fc34e91bdb63409d7"
  825              },
  826          ];
  827  
  828          let tests = wikipedia_tests;
  829  
  830          let mut sh = ~Sha384::new();
  831  
  832          test_hash(sh, tests);
  833      }
  834  
  835      #[test]
  836      fn test_sha512_256() {
  837          // Examples from wikipedia
  838          let wikipedia_tests = ~[
  839              Test {
  840                  input: ~"",
  841                  output_str: ~"c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967a"
  842              },
  843              Test {
  844                  input: ~"The quick brown fox jumps over the lazy dog",
  845                  output_str: ~"dd9d67b371519c339ed8dbd25af90e976a1eeefd4ad3d889005e532fc5bef04d"
  846              },
  847              Test {
  848                  input: ~"The quick brown fox jumps over the lazy dog.",
  849                  output_str: ~"1546741840f8a492b959d9b8b2344b9b0eb51b004bba35c0aebaac86d45264c3"
  850              },
  851          ];
  852  
  853          let tests = wikipedia_tests;
  854  
  855          let mut sh = ~Sha512Trunc256::new();
  856  
  857          test_hash(sh, tests);
  858      }
  859  
  860      #[test]
  861      fn test_sha512_224() {
  862          // Examples from wikipedia
  863          let wikipedia_tests = ~[
  864              Test {
  865                  input: ~"",
  866                  output_str: ~"6ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4"
  867              },
  868              Test {
  869                  input: ~"The quick brown fox jumps over the lazy dog",
  870                  output_str: ~"944cd2847fb54558d4775db0485a50003111c8e5daa63fe722c6aa37"
  871              },
  872              Test {
  873                  input: ~"The quick brown fox jumps over the lazy dog.",
  874                  output_str: ~"6d6a9279495ec4061769752e7ff9c68b6b0b3c5a281b7917ce0572de"
  875              },
  876          ];
  877  
  878          let tests = wikipedia_tests;
  879  
  880          let mut sh = ~Sha512Trunc224::new();
  881  
  882          test_hash(sh, tests);
  883      }
  884  
  885      #[test]
  886      fn test_sha256() {
  887          // Examples from wikipedia
  888          let wikipedia_tests = ~[
  889              Test {
  890                  input: ~"",
  891                  output_str: ~"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
  892              },
  893              Test {
  894                  input: ~"The quick brown fox jumps over the lazy dog",
  895                  output_str: ~"d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592"
  896              },
  897              Test {
  898                  input: ~"The quick brown fox jumps over the lazy dog.",
  899                  output_str: ~"ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c"
  900              },
  901          ];
  902  
  903          let tests = wikipedia_tests;
  904  
  905          let mut sh = ~Sha256::new();
  906  
  907          test_hash(sh, tests);
  908      }
  909  
  910      #[test]
  911      fn test_sha224() {
  912          // Examples from wikipedia
  913          let wikipedia_tests = ~[
  914              Test {
  915                  input: ~"",
  916                  output_str: ~"d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f"
  917              },
  918              Test {
  919                  input: ~"The quick brown fox jumps over the lazy dog",
  920                  output_str: ~"730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525"
  921              },
  922              Test {
  923                  input: ~"The quick brown fox jumps over the lazy dog.",
  924                  output_str: ~"619cba8e8e05826e9b8c519c0a5c68f4fb653e8a3d8aa04bb2c8cd4c"
  925              },
  926          ];
  927  
  928          let tests = wikipedia_tests;
  929  
  930          let mut sh = ~Sha224::new();
  931  
  932          test_hash(sh, tests);
  933      }
  934  
  935      #[test]
  936      fn test_1million_random_sha512() {
  937          let mut sh = Sha512::new();
  938          test_digest_1million_random(
  939              &mut sh,
  940              128,
  941              "e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973eb" +
  942              "de0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b");
  943          }
  944  
  945      #[test]
  946      fn test_1million_random_sha256() {
  947          let mut sh = Sha256::new();
  948          test_digest_1million_random(
  949              &mut sh,
  950              64,
  951              "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0");
  952      }
  953  }
  954  
  955  
  956  
  957  #[cfg(test)]
  958  mod bench {
  959  
  960      use sha2::{Sha256,Sha512};
  961      use test::BenchHarness;
  962  
  963      #[bench]
  964      pub fn sha256_10(bh: & mut BenchHarness) {
  965          let mut sh = Sha256::new();
  966          let bytes = [1u8, ..10];
  967          do bh.iter {
  968              sh.input(bytes);
  969          }
  970          bh.bytes = bytes.len() as u64;
  971      }
  972  
  973      #[bench]
  974      pub fn sha256_1k(bh: & mut BenchHarness) {
  975          let mut sh = Sha256::new();
  976          let bytes = [1u8, ..1024];
  977          do bh.iter {
  978              sh.input(bytes);
  979          }
  980          bh.bytes = bytes.len() as u64;
  981      }
  982  
  983      #[bench]
  984      pub fn sha256_64k(bh: & mut BenchHarness) {
  985          let mut sh = Sha256::new();
  986          let bytes = [1u8, ..65536];
  987          do bh.iter {
  988              sh.input(bytes);
  989          }
  990          bh.bytes = bytes.len() as u64;
  991      }
  992  
  993  
  994  
  995      #[bench]
  996      pub fn sha512_10(bh: & mut BenchHarness) {
  997          let mut sh = Sha512::new();
  998          let bytes = [1u8, ..10];
  999          do bh.iter {
 1000              sh.input(bytes);
 1001          }
 1002          bh.bytes = bytes.len() as u64;
 1003      }
 1004  
 1005      #[bench]
 1006      pub fn sha512_1k(bh: & mut BenchHarness) {
 1007          let mut sh = Sha512::new();
 1008          let bytes = [1u8, ..1024];
 1009          do bh.iter {
 1010              sh.input(bytes);
 1011          }
 1012          bh.bytes = bytes.len() as u64;
 1013      }
 1014  
 1015      #[bench]
 1016      pub fn sha512_64k(bh: & mut BenchHarness) {
 1017          let mut sh = Sha512::new();
 1018          let bytes = [1u8, ..65536];
 1019          do bh.iter {
 1020              sh.input(bytes);
 1021          }
 1022          bh.bytes = bytes.len() as u64;
 1023      }
 1024  
 1025  }

libextra/crypto/sha2.rs:637:1-637:1 -struct- definition:

struct Sha256 {
references:-
646:     pub fn new() -> Sha256 {
653: impl Digest for Sha256 {
642: impl Sha256 {
647:         Sha256 {


libextra/crypto/sha2.rs:60:8-60:8 -fn- definition:
        fn maj(x: u64, y: u64, z: u64) -> u64 {
            ((x & y) ^ (x & z) ^ (y & z))
references:-
104:                     $H += sum0($A) + maj($A, $B, $C);
104:                     $H += sum0($A) + maj($A, $B, $C);
104:                     $H += sum0($A) + maj($A, $B, $C);
104:                     $H += sum0($A) + maj($A, $B, $C);
104:                     $H += sum0($A) + maj($A, $B, $C);
104:                     $H += sum0($A) + maj($A, $B, $C);
104:                     $H += sum0($A) + maj($A, $B, $C);
104:                     $H += sum0($A) + maj($A, $B, $C);
104:                     $H += sum0($A) + maj($A, $B, $C);
104:                     $H += sum0($A) + maj($A, $B, $C);
104:                     $H += sum0($A) + maj($A, $B, $C);
104:                     $H += sum0($A) + maj($A, $B, $C);
104:                     $H += sum0($A) + maj($A, $B, $C);
104:                     $H += sum0($A) + maj($A, $B, $C);
104:                     $H += sum0($A) + maj($A, $B, $C);
104:                     $H += sum0($A) + maj($A, $B, $C);


libextra/crypto/sha2.rs:470:8-470:8 -fn- definition:
        fn ch(x: u32, y: u32, z: u32) -> u32 {
            ((x & y) ^ ((!x) & z))
references:-
516:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
516:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
516:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
516:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
516:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
516:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
516:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
516:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
516:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
516:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
516:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
516:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
516:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
516:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
516:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
516:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];


libextra/crypto/sha2.rs:482:8-482:8 -fn- definition:
        fn sum1(x: u32) -> u32 {
            ((x >> 6) | (x << 26)) ^ ((x >> 11) | (x << 21)) ^ ((x >> 25) | (x << 7))
references:-
516:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
516:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
516:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
516:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
516:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
516:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
516:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
516:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
516:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
516:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
516:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
516:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
516:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
516:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
516:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
516:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];


libextra/crypto/sha2.rs:382:1-382:1 -struct- definition:

struct Sha512Trunc224 {
references:-
391:     pub fn new() -> Sha512Trunc224 {
392:         Sha512Trunc224 {
387: impl Sha512Trunc224 {
398: impl Digest for Sha512Trunc224 {


libextra/crypto/sha2.rs:232:1-232:1 -struct- definition:

struct Sha512 {
references:-
242:         return Sha512 {
237: impl Sha512 {
248: impl Digest for Sha512 {
241:     pub fn new() -> Sha512 {


libextra/crypto/sha2.rs:689:1-689:1 -struct- definition:

struct Sha224 {
references:-
698:     pub fn new() -> Sha224 {
705: impl Digest for Sha224 {
694: impl Sha224 {
699:         Sha224 {


libextra/crypto/sha2.rs:72:8-72:8 -fn- definition:
        fn sigma0(x: u64) -> u64 {
            ((x << 63) | (x >> 1)) ^ ((x << 56) | (x >> 8)) ^ (x >> 7)
references:-
94:                 W[$t] = sigma1(W[$t - 2]) + W[$t - 7] + sigma0(W[$t - 15]) + W[$t - 16];
94:                 W[$t] = sigma1(W[$t - 2]) + W[$t - 7] + sigma0(W[$t - 15]) + W[$t - 16];
94:                 W[$t] = sigma1(W[$t - 2]) + W[$t - 7] + sigma0(W[$t - 15]) + W[$t - 16];
94:                 W[$t] = sigma1(W[$t - 2]) + W[$t - 7] + sigma0(W[$t - 15]) + W[$t - 16];
94:                 W[$t] = sigma1(W[$t - 2]) + W[$t - 7] + sigma0(W[$t - 15]) + W[$t - 16];
94:                 W[$t] = sigma1(W[$t - 2]) + W[$t - 7] + sigma0(W[$t - 15]) + W[$t - 16];
94:                 W[$t] = sigma1(W[$t - 2]) + W[$t - 7] + sigma0(W[$t - 15]) + W[$t - 16];
94:                 W[$t] = sigma1(W[$t - 2]) + W[$t - 7] + sigma0(W[$t - 15]) + W[$t - 16];


libextra/crypto/sha2.rs:68:8-68:8 -fn- definition:
        fn sum1(x: u64) -> u64 {
            ((x << 50) | (x >> 14)) ^ ((x << 46) | (x >> 18)) ^ ((x << 23) | (x >> 41))
references:-
102:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
102:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
102:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
102:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
102:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
102:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
102:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
102:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
102:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
102:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
102:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
102:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
102:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
102:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
102:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
102:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];


libextra/crypto/sha2.rs:182:48-182:48 -struct- definition:
// necessary to perform the final calculations.
struct Engine512 {
references:-
192:         return Engine512 {
191:     fn new(h: &[u64, ..8]) -> Engine512 {
384:     priv engine: Engine512
190: impl Engine512 {
234:     priv engine: Engine512
286:     priv engine: Engine512
336:     priv engine: Engine512


libextra/crypto/sha2.rs:76:8-76:8 -fn- definition:
        fn sigma1(x: u64) -> u64 {
            ((x << 45) | (x >> 19)) ^ ((x << 3) | (x >> 61)) ^ (x >> 6)
references:-
94:                 W[$t] = sigma1(W[$t - 2]) + W[$t - 7] + sigma0(W[$t - 15]) + W[$t - 16];
94:                 W[$t] = sigma1(W[$t - 2]) + W[$t - 7] + sigma0(W[$t - 15]) + W[$t - 16];
94:                 W[$t] = sigma1(W[$t - 2]) + W[$t - 7] + sigma0(W[$t - 15]) + W[$t - 16];
94:                 W[$t] = sigma1(W[$t - 2]) + W[$t - 7] + sigma0(W[$t - 15]) + W[$t - 16];
94:                 W[$t] = sigma1(W[$t - 2]) + W[$t - 7] + sigma0(W[$t - 15]) + W[$t - 16];
94:                 W[$t] = sigma1(W[$t - 2]) + W[$t - 7] + sigma0(W[$t - 15]) + W[$t - 16];
94:                 W[$t] = sigma1(W[$t - 2]) + W[$t - 7] + sigma0(W[$t - 15]) + W[$t - 16];
94:                 W[$t] = sigma1(W[$t - 2]) + W[$t - 7] + sigma0(W[$t - 15]) + W[$t - 16];


libextra/crypto/sha2.rs:56:8-56:8 -fn- definition:
        fn ch(x: u64, y: u64, z: u64) -> u64 {
            ((x & y) ^ ((!x) & z))
references:-
102:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
102:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
102:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
102:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
102:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
102:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
102:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
102:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
102:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
102:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
102:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
102:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
102:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
102:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
102:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];
102:                     $H += sum1($E) + ch($E, $F, $G) + $K[$t] + W[$t];


libextra/crypto/sha2.rs:334:1-334:1 -struct- definition:

struct Sha512Trunc256 {
references:-
344:         Sha512Trunc256 {
339: impl Sha512Trunc256 {
343:     pub fn new() -> Sha512Trunc256 {
350: impl Digest for Sha512Trunc256 {


libextra/crypto/sha2.rs:474:8-474:8 -fn- definition:
        fn maj(x: u32, y: u32, z: u32) -> u32 {
            ((x & y) ^ (x & z) ^ (y & z))
references:-
518:                     $H += sum0($A) + maj($A, $B, $C);
518:                     $H += sum0($A) + maj($A, $B, $C);
518:                     $H += sum0($A) + maj($A, $B, $C);
518:                     $H += sum0($A) + maj($A, $B, $C);
518:                     $H += sum0($A) + maj($A, $B, $C);
518:                     $H += sum0($A) + maj($A, $B, $C);
518:                     $H += sum0($A) + maj($A, $B, $C);
518:                     $H += sum0($A) + maj($A, $B, $C);
518:                     $H += sum0($A) + maj($A, $B, $C);
518:                     $H += sum0($A) + maj($A, $B, $C);
518:                     $H += sum0($A) + maj($A, $B, $C);
518:                     $H += sum0($A) + maj($A, $B, $C);
518:                     $H += sum0($A) + maj($A, $B, $C);
518:                     $H += sum0($A) + maj($A, $B, $C);
518:                     $H += sum0($A) + maj($A, $B, $C);
518:                     $H += sum0($A) + maj($A, $B, $C);


libextra/crypto/sha2.rs:490:8-490:8 -fn- definition:
        fn sigma1(x: u32) -> u32 {
            ((x >> 17) | (x << 15)) ^ ((x >> 19) | (x << 13)) ^ (x >> 10)
references:-
508:                 W[$t] = sigma1(W[$t - 2]) + W[$t - 7] + sigma0(W[$t - 15]) + W[$t - 16];
508:                 W[$t] = sigma1(W[$t - 2]) + W[$t - 7] + sigma0(W[$t - 15]) + W[$t - 16];
508:                 W[$t] = sigma1(W[$t - 2]) + W[$t - 7] + sigma0(W[$t - 15]) + W[$t - 16];
508:                 W[$t] = sigma1(W[$t - 2]) + W[$t - 7] + sigma0(W[$t - 15]) + W[$t - 16];
508:                 W[$t] = sigma1(W[$t - 2]) + W[$t - 7] + sigma0(W[$t - 15]) + W[$t - 16];
508:                 W[$t] = sigma1(W[$t - 2]) + W[$t - 7] + sigma0(W[$t - 15]) + W[$t - 16];
508:                 W[$t] = sigma1(W[$t - 2]) + W[$t - 7] + sigma0(W[$t - 15]) + W[$t - 16];
508:                 W[$t] = sigma1(W[$t - 2]) + W[$t - 7] + sigma0(W[$t - 15]) + W[$t - 16];


libextra/crypto/sha2.rs:432:13-432:13 -struct- definition:
// functions
struct Engine256State {
references:-
595:     state: Engine256State,
446:         return Engine256State {
444: impl Engine256State {
445:     fn new(h: &[u32, ..8]) -> Engine256State {


libextra/crypto/sha2.rs:284:1-284:1 -struct- definition:

struct Sha384 {
references:-
294:         Sha384 {
300: impl Digest for Sha384 {
289: impl Sha384 {
293:     pub fn new() -> Sha384 {


libextra/crypto/sha2.rs:478:8-478:8 -fn- definition:
        fn sum0(x: u32) -> u32 {
            ((x >> 2) | (x << 30)) ^ ((x >> 13) | (x << 19)) ^ ((x >> 22) | (x << 10))
references:-
518:                     $H += sum0($A) + maj($A, $B, $C);
518:                     $H += sum0($A) + maj($A, $B, $C);
518:                     $H += sum0($A) + maj($A, $B, $C);
518:                     $H += sum0($A) + maj($A, $B, $C);
518:                     $H += sum0($A) + maj($A, $B, $C);
518:                     $H += sum0($A) + maj($A, $B, $C);
518:                     $H += sum0($A) + maj($A, $B, $C);
518:                     $H += sum0($A) + maj($A, $B, $C);
518:                     $H += sum0($A) + maj($A, $B, $C);
518:                     $H += sum0($A) + maj($A, $B, $C);
518:                     $H += sum0($A) + maj($A, $B, $C);
518:                     $H += sum0($A) + maj($A, $B, $C);
518:                     $H += sum0($A) + maj($A, $B, $C);
518:                     $H += sum0($A) + maj($A, $B, $C);
518:                     $H += sum0($A) + maj($A, $B, $C);
518:                     $H += sum0($A) + maj($A, $B, $C);


libextra/crypto/sha2.rs:64:8-64:8 -fn- definition:
        fn sum0(x: u64) -> u64 {
            ((x << 36) | (x >> 28)) ^ ((x << 30) | (x >> 34)) ^ ((x << 25) | (x >> 39))
references:-
104:                     $H += sum0($A) + maj($A, $B, $C);
104:                     $H += sum0($A) + maj($A, $B, $C);
104:                     $H += sum0($A) + maj($A, $B, $C);
104:                     $H += sum0($A) + maj($A, $B, $C);
104:                     $H += sum0($A) + maj($A, $B, $C);
104:                     $H += sum0($A) + maj($A, $B, $C);
104:                     $H += sum0($A) + maj($A, $B, $C);
104:                     $H += sum0($A) + maj($A, $B, $C);
104:                     $H += sum0($A) + maj($A, $B, $C);
104:                     $H += sum0($A) + maj($A, $B, $C);
104:                     $H += sum0($A) + maj($A, $B, $C);
104:                     $H += sum0($A) + maj($A, $B, $C);
104:                     $H += sum0($A) + maj($A, $B, $C);
104:                     $H += sum0($A) + maj($A, $B, $C);
104:                     $H += sum0($A) + maj($A, $B, $C);
104:                     $H += sum0($A) + maj($A, $B, $C);


libextra/crypto/sha2.rs:591:48-591:48 -struct- definition:
// necessary to perform the final calculations.
struct Engine256 {
references:-
601:         return Engine256 {
691:     priv engine: Engine256
599: impl Engine256 {
600:     fn new(h: &[u32, ..8]) -> Engine256 {
639:     priv engine: Engine256


libextra/crypto/sha2.rs:18:23-18:23 -struct- definition:
// of digest functions
struct Engine512State {
references:-
30: impl Engine512State {
32:         return Engine512State {
31:     fn new(h: &[u64, ..8]) -> Engine512State {
186:     state: Engine512State,


libextra/crypto/sha2.rs:486:8-486:8 -fn- definition:
        fn sigma0(x: u32) -> u32 {
            ((x >> 7) | (x << 25)) ^ ((x >> 18) | (x << 14)) ^ (x >> 3)
references:-
508:                 W[$t] = sigma1(W[$t - 2]) + W[$t - 7] + sigma0(W[$t - 15]) + W[$t - 16];
508:                 W[$t] = sigma1(W[$t - 2]) + W[$t - 7] + sigma0(W[$t - 15]) + W[$t - 16];
508:                 W[$t] = sigma1(W[$t - 2]) + W[$t - 7] + sigma0(W[$t - 15]) + W[$t - 16];
508:                 W[$t] = sigma1(W[$t - 2]) + W[$t - 7] + sigma0(W[$t - 15]) + W[$t - 16];
508:                 W[$t] = sigma1(W[$t - 2]) + W[$t - 7] + sigma0(W[$t - 15]) + W[$t - 16];
508:                 W[$t] = sigma1(W[$t - 2]) + W[$t - 7] + sigma0(W[$t - 15]) + W[$t - 16];
508:                 W[$t] = sigma1(W[$t - 2]) + W[$t - 7] + sigma0(W[$t - 15]) + W[$t - 16];
508:                 W[$t] = sigma1(W[$t - 2]) + W[$t - 7] + sigma0(W[$t - 15]) + W[$t - 16];