// Copyright 2017 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the “License”); you may not use this file except in
// compliance with the License.  You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.

#include "common.h"

typedef struct {
    int mdlen;
    char *msgstr;
    uint8_t md[64];
} test_triplet_t;

static const test_triplet_t testvec[4] = {
    {
        28, "Keccak-224 Test Hash", {
            0x30, 0x04, 0x5B, 0x34, 0x94, 0x6E, 0x1B, 0x2E,
            0x09, 0x16, 0x13, 0x36, 0x2F, 0xD2, 0x2A, 0xA0,
            0x8E, 0x2B, 0xEA, 0xFE, 0xC5, 0xE8, 0xDA, 0xEE,
            0x42, 0xC2, 0xE6, 0x65 }
    }, {
        32, "Keccak-256 Test Hash", {
            0xA8, 0xD7, 0x1B, 0x07, 0xF4, 0xAF, 0x26, 0xA4,
            0xFF, 0x21, 0x02, 0x7F, 0x62, 0xFF, 0x60, 0x26,
            0x7F, 0xF9, 0x55, 0xC9, 0x63, 0xF0, 0x42, 0xC4,
            0x6D, 0xA5, 0x2E, 0xE3, 0xCF, 0xAF, 0x3D, 0x3C }
    }, {
        48, "Keccak-384 Test Hash", {
            0xE2, 0x13, 0xFD, 0x74, 0xAF, 0x0C, 0x5F, 0xF9,
            0x1B, 0x42, 0x3C, 0x8B, 0xCE, 0xEC, 0xD7, 0x01,
            0xF8, 0xDD, 0x64, 0xEC, 0x18, 0xFD, 0x6F, 0x92,
            0x60, 0xFC, 0x9E, 0xC1, 0xED, 0xBD, 0x22, 0x30,
            0xA6, 0x90, 0x86, 0x65, 0xBC, 0xD9, 0xFB, 0xF4,
            0x1A, 0x99, 0xA1, 0x8A, 0x7D, 0x9E, 0x44, 0x6E }
    }, {
        64, "Keccak-512 Test Hash", {
            0x96, 0xEE, 0x47, 0x18, 0xDC, 0xBA, 0x3C, 0x74,
            0x61, 0x9B, 0xA1, 0xFA, 0x7F, 0x57, 0xDF, 0xE7,
            0x76, 0x9D, 0x3F, 0x66, 0x98, 0xA8, 0xB3, 0x3F,
            0xA1, 0x01, 0x83, 0x89, 0x70, 0xA1, 0x31, 0xE6,
            0x21, 0xCC, 0xFD, 0x05, 0xFE, 0xFF, 0xBC, 0x11,
            0x80, 0xF2, 0x63, 0xC2, 0x7F, 0x1A, 0xDA, 0xB4,
            0x60, 0x95, 0xD6, 0xF1, 0x25, 0x33, 0x14, 0x72,
            0x4B, 0x5C, 0xBF, 0x78, 0x28, 0x65, 0x8E, 0x6A }
    }
};

uint8_t md0[28] __sram;
uint8_t md1[32] __sram;
uint8_t md2[48] __sram;
uint8_t md3[64] __sram;

uint8_t *md[] __sram = {
  md0, md1, md2, md3
};

extern int do_keccak(const uint8_t *in, int, uint8_t *out, int);

void keccak_test() {
  for (int i = 0; i < 4; i++)
    do_keccak((uint8_t *) testvec[i].msgstr, strlen(testvec[i].msgstr),
               md[i], testvec[i].mdlen);
}

void test_setup() {
}

void test_clear() {
  for (int i = 0; i < 4; i++)
    memset(md[i], 0, testvec[i].mdlen);
}

void test_run() {
  keccak_test();
}

int test_check() {
  for (int i = 0; i < 4; i++)
    if (0 != memcmp(md[i], testvec[i].md, testvec[i].mdlen))
      return 0;
  return 1;
}
