LCOV - code coverage report
Current view: top level - util - shake.c (source / functions) Hit Total Coverage
Test: test-37de7e7-dirty-coverage.info Lines: 51 53 96.2 %
Date: 2019-04-16 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /**
       2             :  * @ingroup sha3
       3             :  *
       4             :  * @file sha3.c
       5             :  *
       6             :  * @{
       7             :  */
       8             : 
       9             : #include "../firmware.h"
      10             : 
      11             : /*
      12             :  * Copyright (c) 2015 Markku-Juhani O. Saarinen
      13             :  * The MIT License (MIT)
      14             :  */
      15             : 
      16             : #ifndef KECCAKF_ROUNDS
      17             : #define KECCAKF_ROUNDS 24
      18             : #endif
      19             : 
      20             : #ifndef ROTL64
      21             : #define ROTL64(x, y) (((x) << (y)) | ((x) >> (64 - (y))))
      22             : #endif
      23             : 
      24             : // update the state with given number of rounds
      25             : 
      26           9 : static void sha3_keccakf(uint64_t st[25])
      27             : {
      28             :     // constants
      29           9 :     const uint64_t keccakf_rndc[24] = {
      30             :         0x0000000000000001, 0x0000000000008082, 0x800000000000808a,
      31             :         0x8000000080008000, 0x000000000000808b, 0x0000000080000001,
      32             :         0x8000000080008081, 0x8000000000008009, 0x000000000000008a,
      33             :         0x0000000000000088, 0x0000000080008009, 0x000000008000000a,
      34             :         0x000000008000808b, 0x800000000000008b, 0x8000000000008089,
      35             :         0x8000000000008003, 0x8000000000008002, 0x8000000000000080,
      36             :         0x000000000000800a, 0x800000008000000a, 0x8000000080008081,
      37             :         0x8000000000008080, 0x0000000080000001, 0x8000000080008008
      38             :     };
      39           9 :     const int keccakf_rotc[24] = {
      40             :         1,  3,  6,  10, 15, 21, 28, 36, 45, 55, 2,  14,
      41             :         27, 41, 56, 8,  25, 43, 62, 18, 39, 61, 20, 44
      42             :     };
      43           9 :     const int keccakf_piln[24] = {
      44             :         10, 7,  11, 17, 18, 3, 5,  16, 8,  21, 24, 4,
      45             :         15, 23, 19, 13, 12, 2, 20, 14, 22, 9,  6,  1
      46             :     };
      47             : 
      48             :     // variables
      49             :     int i, j, r;
      50             :     uint64_t t, bc[5];
      51             : 
      52             : #if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__
      53             :     uint8_t *v;
      54             : 
      55             :     // endianess conversion. this is redundant on little-endian targets
      56             :     for (i = 0; i < 25; i++) {
      57             :         v = (uint8_t *) &st[i];
      58             :         st[i] = ((uint64_t) v[0])     | (((uint64_t) v[1]) << 8) |
      59             :             (((uint64_t) v[2]) << 16) | (((uint64_t) v[3]) << 24) |
      60             :             (((uint64_t) v[4]) << 32) | (((uint64_t) v[5]) << 40) |
      61             :             (((uint64_t) v[6]) << 48) | (((uint64_t) v[7]) << 56);
      62             :     }
      63             : #endif
      64             : 
      65             :     // actual iteration
      66         225 :     for (r = 0; r < KECCAKF_ROUNDS; r++) {
      67             : 
      68             :         // Theta
      69        1296 :         for (i = 0; i < 5; i++)
      70        1080 :             bc[i] = st[i] ^ st[i + 5] ^ st[i + 10] ^ st[i + 15] ^ st[i + 20];
      71             : 
      72        1296 :         for (i = 0; i < 5; i++) {
      73        1080 :             t = bc[(i + 4) % 5] ^ ROTL64(bc[(i + 1) % 5], 1);
      74        6480 :             for (j = 0; j < 25; j += 5)
      75        5400 :                 st[j + i] ^= t;
      76             :         }
      77             : 
      78             :         // Rho Pi
      79         216 :         t = st[1];
      80        5400 :         for (i = 0; i < 24; i++) {
      81        5184 :             j = keccakf_piln[i];
      82        5184 :             bc[0] = st[j];
      83        5184 :             st[j] = ROTL64(t, keccakf_rotc[i]);
      84        5184 :             t = bc[0];
      85             :         }
      86             : 
      87             :         //  Chi
      88        1296 :         for (j = 0; j < 25; j += 5) {
      89        6480 :             for (i = 0; i < 5; i++)
      90        5400 :                 bc[i] = st[j + i];
      91        6480 :             for (i = 0; i < 5; i++)
      92        5400 :                 st[j + i] ^= (~bc[(i + 1) % 5]) & bc[(i + 2) % 5];
      93             :         }
      94             : 
      95             :         //  Iota
      96         216 :         st[0] ^= keccakf_rndc[r];
      97             :     }
      98             : 
      99             : #if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__
     100             :     // endianess conversion. this is redundant on little-endian targets
     101             :     for (i = 0; i < 25; i++) {
     102             :         v = (uint8_t *) &st[i];
     103             :         t = st[i];
     104             :         v[0] = t & 0xFF;
     105             :         v[1] = (t >> 8) & 0xFF;
     106             :         v[2] = (t >> 16) & 0xFF;
     107             :         v[3] = (t >> 24) & 0xFF;
     108             :         v[4] = (t >> 32) & 0xFF;
     109             :         v[5] = (t >> 40) & 0xFF;
     110             :         v[6] = (t >> 48) & 0xFF;
     111             :         v[7] = (t >> 56) & 0xFF;
     112             :     }
     113             : #endif
     114           9 : }
     115             : 
     116           7 : void Util_shake_init(util_shake_ctx_t *c, uint8_t output_length)
     117             : {
     118             :     uint8_t i;
     119             : 
     120         182 :     for (i = 0; i < 25; i++)
     121             :     {
     122         175 :         c->st.q[i] = 0;
     123             :     }
     124           7 :     c->mdlen = output_length;
     125           7 :     c->rsiz = 200 - 2 * output_length;
     126           7 :     c->pt = 0;
     127           7 : }
     128             : 
     129          11 : void Util_shake_update(util_shake_ctx_t *c, const uint8_t *data, uint32_t data_length)
     130             : {
     131             :     uint32_t i;
     132             :     int32_t j;
     133             : 
     134          11 :     j = c->pt;
     135         859 :     for (i = 0; i < data_length; i++)
     136             :     {
     137         848 :         c->st.b[j++] ^= data[i];
     138         848 :         if (j >= c->rsiz)
     139             :         {
     140           2 :             sha3_keccakf(c->st.q);
     141           2 :             j = 0;
     142             :         }
     143             :     }
     144          11 :     c->pt = j;
     145          11 : }
     146             : 
     147           7 : void Util_shake_out(util_shake_ctx_t *c, uint8_t *output)
     148             : {
     149             :     uint32_t i;
     150             :     int32_t j;
     151             : 
     152             :     /* XOF function */
     153           7 :     c->st.b[c->pt] ^= 0x1F;
     154           7 :     c->st.b[c->rsiz - 1] ^= 0x80;
     155           7 :     sha3_keccakf(c->st.q);
     156           7 :     c->pt = 0;
     157             : 
     158             :     /* Export output */
     159           7 :     j = c->pt;
     160         119 :     for (i = 0; i < c->mdlen; i++)
     161             :     {
     162         112 :         if (j >= c->rsiz)
     163             :         {
     164           0 :             sha3_keccakf(c->st.q);
     165           0 :             j = 0;
     166             :         }
     167         112 :         output[i] = c->st.b[j++];
     168             :     }
     169           7 :     c->pt = j;
     170           7 : }
     171             : 
     172             : /**
     173             :  * @}
     174             :  */

Generated by: LCOV version 1.10