core.c 1.79 KB
Newer Older
Christoph Dobraunig 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 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
#include "core.h"

void process_data(state* s, unsigned char* out, const unsigned char* in,
                  unsigned long long len, u8 mode) {
  u64* x;
  u64 i;

  while (len >= RATE) {
    s->x0 ^= U64BIG(*(u64*)in);
    s->x1 ^= U64BIG(*(u64*)(in + 8));
    if (mode != ASCON_AD) {
      *(u64*)out = U64BIG(s->x0);
      *(u64*)(out + 8) = U64BIG(s->x1);
    }
    if (mode == ASCON_DEC) {
      s->x0 = U64BIG(*((u64*)in));
      s->x1 = U64BIG(*((u64*)(in + 8)));
    }
    P(s, PB_ROUNDS);
    in += RATE;
    out += RATE;
    len -= RATE;
  }

  for (i = 0; i < len; ++i, ++out, ++in) {
    if (i < 8)
      x = &(s->x0);
    else
      x = &(s->x1);
    *x ^= INS_BYTE64(*in, i % 8);
    if (mode != ASCON_AD) *out = EXT_BYTE64(*x, i % 8);
    if (mode == ASCON_DEC) {
      *x &= ~INS_BYTE64(0xff, i % 8);
      *x |= INS_BYTE64(*in, i % 8);
    }
  }
  if (len < 8)
    s->x0 ^= INS_BYTE64(0x80, len);
  else
    s->x1 ^= INS_BYTE64(0x80, len % 8);
}

void ascon_core(state* s, unsigned char* out, const unsigned char* in,
                unsigned long long tlen, const unsigned char* ad,
                unsigned long long adlen, const unsigned char* npub,
                const unsigned char* k, u8 mode) {
  const u64 K0 = U64BIG(*(u64*)k);
  const u64 K1 = U64BIG(*(u64*)(k + 8));
  const u64 N0 = U64BIG(*(u64*)npub);
  const u64 N1 = U64BIG(*(u64*)(npub + 8));

  // initialization
  s->x0 = IV;
  s->x1 = K0;
  s->x2 = K1;
  s->x3 = N0;
  s->x4 = N1;
  P(s, PA_ROUNDS);
  s->x3 ^= K0;
  s->x4 ^= K1;

  // process associated data
  if (adlen) {
    process_data(s, (void*)0, ad, adlen, ASCON_AD);
    P(s, PB_ROUNDS);
  }
  s->x4 ^= 1;

  // process plaintext/ciphertext
  process_data(s, out, in, tlen, mode);

  // finalization
  s->x2 ^= K0;
  s->x3 ^= K1;
  P(s, PA_ROUNDS);
  s->x3 ^= K0;
  s->x4 ^= K1;
}