update.c 1.44 KB
Newer Older
Martin Schlaeffer committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
#include "api.h"
#include "ascon.h"
#include "permutations.h"
#include "printstate.h"

void ascon_update(state_t* s, uint8_t* out, const uint8_t* in, uint64_t len,
                  uint8_t mode) {
  const int nr = (ASCON_RATE == 8) ? 6 : 8;
  word_t tmp0, tmp1;
  /* full blocks */
  while (len >= ASCON_RATE) {
    tmp0 = LOAD(in, 8);
    tmp1 = LOAD(in + 8, 8);
    s->x0 = XOR(s->x0, tmp0);
    s->x1 = XOR(s->x1, tmp1);
    if (mode & ASCON_SQUEEZE) {
      STORE(out, s->x0, 8);
      STORE(out + 8, s->x1, 8);
    }
    if (mode & ASCON_INSERT) {
      s->x0 = tmp0;
      s->x1 = tmp1;
    }
    P(s, nr);
    in += ASCON_RATE;
    out += ASCON_RATE;
    len -= ASCON_RATE;
  }
  /* final block */
  if (len) {
    tmp1 = WORD_T(0);
    if (len >= 8) tmp0 = LOAD(in, 8);
    if (len > 8)
      tmp1 = LOAD(in + 8, len - 8);
    else
      tmp0 = LOAD(in, len);
    s->x0 = XOR(s->x0, tmp0);
    s->x1 = XOR(s->x1, tmp1);
    if (mode & ASCON_SQUEEZE) {
      if (len >= 8) STORE(out, s->x0, 8);
      if (len > 8)
        STORE(out + 8, s->x1, len - 8);
      else
        STORE(out, s->x0, len);
    }
    if (mode & ASCON_INSERT) {
      if (len >= 8) s->x0 = tmp0;
      if (len > 8) {
        s->x1 = CLEAR(s->x1, len - 8);
        s->x1 = XOR(s->x1, tmp1);
      } else {
        s->x0 = CLEAR(s->x0, len);
        s->x0 = XOR(s->x0, tmp0);
      }
    }
  }
  if (len < 8)
    s->x0 = XOR(s->x0, PAD(len % 8));
  else
    s->x1 = XOR(s->x1, PAD(len % 8));
}