_INLINE_ ret_t sha_update()

in src/random/sha.c [52:122]


_INLINE_ ret_t sha_update(IN OUT sha512_dgst_t *dgst,
                          IN const uint8_t *msg,
                          IN size_t         n)
{
  uint64_t a, b, c, d, e, f, g, h;
  uint64_t s0, s1, S0, S1, maj, ch, t1, t2;
  uint64_t w[80];

  uint64_t k[] = K;

  if(NULL == dgst || NULL == msg) {
    return FAIL;
  }

  while(n > 0) {
    a = dgst->u.qw[0];
    b = dgst->u.qw[1];
    c = dgst->u.qw[2];
    d = dgst->u.qw[3];
    e = dgst->u.qw[4];
    f = dgst->u.qw[5];
    g = dgst->u.qw[6];
    h = dgst->u.qw[7];

    for(size_t i = 0; i < 80; i++) {
      if(i < 16) {
        // memcpy is used to pass alignment issue.
        bike_memcpy(&w[i], &msg[8 * i], 8);
        w[i] = bswap_64(w[i]);
      } else {
        S0 = ROTR64(w[(i - 15)], 1) ^ ROTR64(w[(i - 15)], 8) ^ (w[(i - 15)] >> 7);
        S1 = ROTR64(w[(i - 2)], 19) ^ ROTR64(w[(i - 2)], 61) ^ (w[(i - 2)] >> 6);
        w[i] = w[(i - 16)] + S0 + w[(i - 7)] + S1;
      }

      s0 = ROTR64(a, 28) ^ ROTR64(a, 34) ^ ROTR64(a, 39);
      s1 = ROTR64(e, 14) ^ ROTR64(e, 18) ^ ROTR64(e, 41);

      maj = (b & c) | (a & (b ^ c));
      ch  = g ^ (e & (f ^ g));

      t2 = s0 + maj;
      t1 = h + s1 + ch + k[i] + w[i];

      h = g;
      g = f;
      f = e;
      e = d + t1;
      d = c;
      c = b;
      b = a;
      a = t1 + t2;
    }

    dgst->u.qw[0] += a;
    dgst->u.qw[1] += b;
    dgst->u.qw[2] += c;
    dgst->u.qw[3] += d;
    dgst->u.qw[4] += e;
    dgst->u.qw[5] += f;
    dgst->u.qw[6] += g;
    dgst->u.qw[7] += h;

    n--;
    msg += (16 * 8);
  }

  secure_clean((uint8_t *)w, sizeof(w));

  return SUCCESS;
}