On Tue, 09 Jan 2018 16:47:18 +0100, Daniel Loebenberger wrote:

> Changes have been made to libc, and a suite of sha3 checksum tools
> were added (sha3-224, sha3-256, sha3-384, sha-512), extending the
> existing md5(1) checksum tool.
>
> The SHA3 implementation itself was taken from the reference code written
> by the Keccak Team (https://keccak.team/) which is available under public
> domain (CC0).
>
> We'd be happy to see this in OpenBSD and appreciate any comments.

Looks good in general, some comments inline.

 - todd

> Index: include/sha3.h
> ===================================================================
> RCS file: include/sha3.h
> diff -N include/sha3.h
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ include/sha3.h    9 Jan 2018 15:17:42 -0000
> @@ -0,0 +1,76 @@
> +#ifndef _SHA3_H
> +#define _SHA3_H
> +
> +#define SHA3_224_DIGEST_LENGTH               28
> +#define SHA3_224_DIGEST_STRING_LENGTH        (SHA3_224_DIGEST_LENGTH * 2 + 1
> )
> +
> +#define SHA3_256_DIGEST_LENGTH               32
> +#define SHA3_256_DIGEST_STRING_LENGTH        (SHA3_256_DIGEST_LENGTH * 2 + 1
> )
> +
> +#define SHA3_384_DIGEST_LENGTH               48
> +#define SHA3_384_DIGEST_STRING_LENGTH        (SHA3_384_DIGEST_LENGTH * 2 + 1
> )
> +
> +#define SHA3_512_DIGEST_LENGTH               64
> +#define SHA3_512_DIGEST_STRING_LENGTH        (SHA3_512_DIGEST_LENGTH * 2 + 1
> )
> +
> +#define SHA3_STATE_SIZE              1600 / 8

This should be parenthesized, i.e. (1600 / 8)

> +
> +
> +typedef struct _SHA3_CTX {
> +     unsigned char state[SHA3_STATE_SIZE];
> +     unsigned int rate;
> +     unsigned int byteIOIndex;
> +     unsigned int fixedOutputLength;
> +} SHA3_CTX;
> +
> +
> +void SHA3_224Init(SHA3_CTX *);
> +char *SHA3_224End(SHA3_CTX *, char *)
> +     __attribute__((__bounded__(__minbytes__,2,SHA3_224_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_224File(const char *, char *)
> +     __attribute__((__bounded__(__minbytes__,2,SHA3_224_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_224FileChunk(const char *, char *, off_t, off_t)
> +     __attribute__((__bounded__(__minbytes__,2,SHA3_224_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_224Data(const u_int8_t *, size_t, char *)
> +     __attribute__((__bounded__(__string__,1,2)))
> +     __attribute__((__bounded__(__minbytes__,3,SHA3_224_DIGEST_STRING_LENGTH
> )));
> +
> +void SHA3_256Init(SHA3_CTX *);
> +char *SHA3_256End(SHA3_CTX *, char *)
> +     __attribute__((__bounded__(__minbytes__,2,SHA3_256_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_256File(const char *, char *)
> +     __attribute__((__bounded__(__minbytes__,2,SHA3_256_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_256FileChunk(const char *, char *, off_t, off_t)
> +     __attribute__((__bounded__(__minbytes__,2,SHA3_256_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_256Data(const u_int8_t *, size_t, char *)
> +     __attribute__((__bounded__(__string__,1,2)))
> +     __attribute__((__bounded__(__minbytes__,3,SHA3_256_DIGEST_STRING_LENGTH
> )));
> +
> +void SHA3_384Init(SHA3_CTX *);
> +char *SHA3_384End(SHA3_CTX *, char *)
> +     __attribute__((__bounded__(__minbytes__,2,SHA3_384_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_384File(const char *, char *)
> +     __attribute__((__bounded__(__minbytes__,2,SHA3_384_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_384FileChunk(const char *, char *, off_t, off_t)
> +     __attribute__((__bounded__(__minbytes__,2,SHA3_384_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_384Data(const u_int8_t *, size_t, char *)
> +     __attribute__((__bounded__(__string__,1,2)))
> +     __attribute__((__bounded__(__minbytes__,3,SHA3_384_DIGEST_STRING_LENGTH
> )));
> +
> +void SHA3_512Init(SHA3_CTX *);
> +char *SHA3_512End(SHA3_CTX *, char *)
> +     __attribute__((__bounded__(__minbytes__,2,SHA3_512_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_512File(const char *, char *)
> +     __attribute__((__bounded__(__minbytes__,2,SHA3_512_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_512FileChunk(const char *, char *, off_t, off_t)
> +     __attribute__((__bounded__(__minbytes__,2,SHA3_512_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_512Data(const u_int8_t *, size_t, char *)
> +     __attribute__((__bounded__(__string__,1,2)))
> +     __attribute__((__bounded__(__minbytes__,3,SHA3_512_DIGEST_STRING_LENGTH
> )));
> +
> +void SHA3_Update(SHA3_CTX *, const u_int8_t *, size_t)
> +     __attribute__((__bounded__(__string__,2,3)));
> +void SHA3_Final(u_int8_t [SHA3_224_DIGEST_LENGTH], SHA3_CTX *)
> +     __attribute__((__bounded__(__minbytes__,1,SHA3_224_DIGEST_LENGTH)));
> +
> +#endif /* _SHA3_H */
> Index: lib/libc/hash/sha3.c
> ===================================================================
> RCS file: lib/libc/hash/sha3.c
> diff -N lib/libc/hash/sha3.c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ lib/libc/hash/sha3.c      9 Jan 2018 15:17:42 -0000
> @@ -0,0 +1,756 @@
> +/*
> + * Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido
> Bertoni,
> + * Joan Daemen, Micha´┐Żl Peeters, Gilles Van Assche and Ronny Van Keer,
> hereby
> + * denoted as "the implementer".
> + *
> + * For more information, feedback or questions, please refer to our
> websites:
> + * http://keccak.noekeon.org/
> + * http://keyak.noekeon.org/
> + * http://ketje.noekeon.org/
> + *
> + * Adaptation to OpenBSD in 2017/18 by
> + * Alexander von Gernler, Daniel Loebenberger and Stefan-Lukas Gazdag
> + * https://www.genua.de/
> + * also denoted as "the implementer"
> + *
> + * To the extent possible under law, the implementer has waived all
> copyright
> + * and related or neighboring rights to the source code in this file.
> + * http://creativecommons.org/publicdomain/zero/1.0/
> + */
> +
> +#include <assert.h>
> +#include <sys/types.h>
> +#include <string.h>
> +#include <strings.h>
> +#include <sha3.h>
> +
> +typedef unsigned long long tKeccakLane;
> +
> +#define SHA3_NRROUNDS 24
> +#define SHA3_NRLANES 25
> +#define SHA3_DELIMITER       0x06
> +
> +#define index(x, y) (((x)%5)+5*((y)%5))
> +
> +const tKeccakLane KeccakRoundConstants[SHA3_NRROUNDS] =
> +{
> +     0x0000000000000001,
> +     0x0000000000008082,
> +     0x800000000000808a,
> +     0x8000000080008000,
> +     0x000000000000808b,
> +     0x0000000080000001,
> +     0x8000000080008081,
> +     0x8000000000008009,
> +     0x000000000000008a,
> +     0x0000000000000088,
> +     0x0000000080008009,
> +     0x000000008000000a,
> +     0x000000008000808b,
> +     0x800000000000008b,
> +     0x8000000000008089,
> +     0x8000000000008003,
> +     0x8000000000008002,
> +     0x8000000000000080,
> +     0x000000000000800a,
> +     0x800000008000000a,
> +     0x8000000080008081,
> +     0x8000000000008080,
> +     0x0000000080000001,
> +     0x8000000080008008,
> +};
> +
> +const unsigned int KeccakRhoOffsets[SHA3_NRLANES] =
> +{
> +     0, 1, 62, 28, 27, 36, 44, 6, 55, 20, 3, 10, 43,
> +     25, 39, 41, 45, 15, 21, 8, 18, 2, 61, 56, 14
> +};
> +
> +/*
> + * unused, but these constance denote the one implementation out of the
> + * Keccak Code Package that was taken here
> + */
> +#define KeccakP1600_implementation      "64-bit reference implementation"
> +#define KeccakP1600_stateSizeInBytes    200
> +#define KeccakP1600_stateAlignment      8
> +
> +/* prototypes for local functions */
> +static void KeccakP1600_AddByte(void *state, unsigned char data,
> +    unsigned int offset);
> +static void KeccakP1600_AddBytes(void *state, const unsigned char *data,
> +    unsigned int offset, unsigned int length);
> +static void KeccakP1600_Permute_24rounds(void *state);
> +static void KeccakP1600_ExtractBytes(const void *state, unsigned char *data,
> +    unsigned int offset, unsigned int length);
> +static void Keccak_HashInitialize(SHA3_CTX *, unsigned int, unsigned int);
> +
> +
> +/*
> + * interface functions external use
> + * (rate + capacity) = 1600,
> + * thus the rate specifies the capacity
> + */
> +void
> +SHA3_224Init(SHA3_CTX *context)
> +{
> +     /* rate = 1152, output width 224 bit */
> +     Keccak_HashInitialize(context, 1152, 224);
> +}
> +
> +void
> +SHA3_256Init(SHA3_CTX *context)
> +{
> +     /* rate = 1088, output width 256 bit */
> +     Keccak_HashInitialize(context, 1088, 256);
> +}
> +
> +void
> +SHA3_384Init(SHA3_CTX *context)
> +{
> +     /* rate = 832, output width 384 bit */
> +     Keccak_HashInitialize(context, 832, 384);
> +}
> +
> +void
> +SHA3_512Init(SHA3_CTX *context)
> +{
> +     /* rate = 576, output width 512 bit */
> +     Keccak_HashInitialize(context, 576, 512);
> +}
> +
> +
> +void
> +SHA3_Update(SHA3_CTX *context, const u_int8_t *data, size_t len)
> +{
> +     size_t i, j;
> +     unsigned int partialBlock;
> +     const unsigned char *curData;
> +     unsigned int rateInBytes;
> +     rateInBytes = context->rate/8;
> +
> +     i = 0;
> +     curData = data;
> +     while(i < len) {
> +             if ((context->byteIOIndex == 0) && (len >= (i + rateInBytes))) 
> {
> +#ifdef SnP_FastLoop_Absorb
> +                     /* processing full blocks first */
> +                     if ((rateInBytes % (KeccakP1600_width/200)) == 0) {
> +                             /* fast lane: whole lane rate */
> +                             j = KeccakP1600_FastLoop_Absorb(context->state,
> +                                 rateInBytes/(KeccakP1600_width/200), curDat
> a, len - i);
> +                             i += j;
> +                             curData += j;
> +                     }
> +                     else {
> +#endif
> +                             for(j=len-i; j>=rateInBytes; j-=rateInBytes) {
> +                                     #ifdef KeccakReference
> +                                     displayBytes(1, "Block to be absorbed",
>  curData, rateInBytes);
> +                                     #endif

The '#' for the  #ifdef/#endif should be at the start of the line.

> +                                     KeccakP1600_AddBytes(context->state, cu
> rData, 0, rateInBytes);
> +                                     KeccakP1600_Permute_24rounds(context->s
> tate);
> +                                     curData+=rateInBytes;
> +                             }
> +                             i = len - j;
> +#ifdef SnP_FastLoop_Absorb
> +                     }
> +#endif
> +             }
> +             else {
> +                     /* normal lane: using the message queue */
> +                     partialBlock = (unsigned int)(len - i);
> +                     if (partialBlock+context->byteIOIndex > rateInBytes)
> +                             partialBlock = rateInBytes-context->byteIOIndex
> ;
> +                     #ifdef KeccakReference
> +                     displayBytes(1, "Block to be absorbed (part)", curData,
>  partialBlock);
> +                     #endif

The '#' for the  #ifdef/#endif should be at the start of the line.

> +                     i += partialBlock;
> +
> +                     KeccakP1600_AddBytes(context->state, curData, context->
> byteIOIndex,
> partialBlock);
> +                     curData += partialBlock;
> +                     context->byteIOIndex += partialBlock;
> +                     if (context->byteIOIndex == rateInBytes) {
> +                             KeccakP1600_Permute_24rounds(context->state);
> +                             context->byteIOIndex = 0;
> +                     }
> +             }
> +     }
> +}
> +
> +void
> +SHA3_Final(u_int8_t* digest, SHA3_CTX *context)
> +{
> +     size_t i, j;
> +     unsigned int partialBlock;
> +     unsigned char *curData;
> +     unsigned int rateInBytes;
> +     size_t dataByteLen;
> +
> +     rateInBytes = context->rate/8;
> +     dataByteLen = context->fixedOutputLength/8;
> +
> +     /* Last few bits, whose delimiter coincides with first bit of padding *
> /
> +     KeccakP1600_AddByte(context->state, SHA3_DELIMITER, context->byteIOInde
> x);
> +
> +     /*
> +      * If the first bit of padding is at position rate-1, we need a whole
> +      * new block for the second bit of padding
> +      */
> +     /* Second bit of padding */
> +     KeccakP1600_AddByte(context->state, 0x80, rateInBytes-1);
> +
> +     KeccakP1600_Permute_24rounds(context->state);
> +     context->byteIOIndex = 0;
> +
> +     /* SQUEEZE */
> +     i = 0;
> +     curData = digest;
> +     while(i < dataByteLen) {
> +             if ((context->byteIOIndex == rateInBytes) && (dataByteLen >= (i
>  +
> rateInBytes))) {
> +                     for(j=dataByteLen-i; j>=rateInBytes; j-=rateInBytes) {
> +                             KeccakP1600_Permute_24rounds(context->state);
> +                             KeccakP1600_ExtractBytes(context->state, curDat
> a, 0, rateInBytes);
> +                             curData+=rateInBytes;
> +                     }
> +                     i = dataByteLen - j;
> +             }
> +             else {
> +                     /* normal lane: using the message queue */
> +                     if (context->byteIOIndex == rateInBytes) {
> +                             KeccakP1600_Permute_24rounds(context->state);
> +                             context->byteIOIndex = 0;
> +                     }
> +                     partialBlock = (unsigned int)(dataByteLen - i);
> +                     if (partialBlock+context->byteIOIndex > rateInBytes)
> +                             partialBlock = rateInBytes-context->byteIOIndex
> ;
> +                     i += partialBlock;
> +
> +                     KeccakP1600_ExtractBytes(context->state, curData, conte
> xt->byteIOIndex,
> partialBlock);
> +                     curData += partialBlock;
> +                     context->byteIOIndex += partialBlock;
> +             }
> +     }
> +}
> +
> +/*
> + * internal functions
> + */
> +static void
> +Keccak_HashInitialize(SHA3_CTX *context, unsigned int rate,
> +    unsigned int hashbitlen)
> +{
> +     bzero(context->state, SHA3_STATE_SIZE);
> +     context->rate = rate;
> +     context->byteIOIndex = 0;
> +     context->fixedOutputLength = hashbitlen;
> +}
> +
> +static void
> +KeccakP1600_AddByte(void *state, unsigned char byte, unsigned int offset)
> +{
> +     assert(offset < 200);
> +     ((unsigned char *)state)[offset] ^= byte;
> +}
> +
> +static void
> +KeccakP1600_AddBytes(void *state, const unsigned char *data, unsigned int
> offset, unsigned int length)
> +{
> +     unsigned int i;
> +
> +     assert(offset < 200);
> +     assert(offset+length <= 200);
> +     for(i=0; i<length; i++)
> +             ((unsigned char *)state)[offset+i] ^= data[i];
> +}
> +
> +#if BYTE_ORDER == BIG_ENDIAN
> +static void fromBytesToWords(tKeccakLane *stateAsWords, const unsigned char
> *state);
> +static void fromWordsToBytes(unsigned char *state, const tKeccakLane
> *stateAsWords);
> +#endif
> +static void KeccakP1600OnWords(tKeccakLane *state);
> +#if BYTE_ORDER == LITTLE_ENDIAN
> +static void KeccakP1600QuadRound(tKeccakLane *state, unsigned int
> indexRound);
> +#else
> +static void KeccakP1600RoundSlow(tKeccakLane *state, unsigned int
> indexRound);
> +static void theta(tKeccakLane *A);
> +static void rho(tKeccakLane *A);
> +static void pi(tKeccakLane *A);
> +static void chi(tKeccakLane *A);
> +static void iota(tKeccakLane *A, unsigned int indexRound);
> +#endif
> +
> +static void
> +KeccakP1600_Permute_24rounds(void *state)
> +{
> +#if BYTE_ORDER == LITTLE_ENDIAN
> +     KeccakP1600OnWords((tKeccakLane*)state);
> +#else
> +     tKeccakLane stateAsWords[1600/64];
> +
> +     fromBytesToWords(stateAsWords, (const unsigned char *)state);
> +     KeccakP1600OnWords(stateAsWords);
> +     fromWordsToBytes((unsigned char *)state, stateAsWords);
> +#endif
> +}
> +
> +#if BYTE_ORDER == BIG_ENDIAN
> +static void
> +fromBytesToWords(tKeccakLane *stateAsWords, const unsigned char *state)
> +{
> +     unsigned int i, j;
> +
> +     for(i=0; i<SHA3_NRLANES; i++) {
> +             stateAsWords[i] = 0;
> +             for(j=0; j<(64/8); j++)
> +                     stateAsWords[i] |= (tKeccakLane)(state[i*(64/8)+j]) << 
> (8*j);
> +     }
> +}
> +
> +static void
> +fromWordsToBytes(unsigned char *state, const tKeccakLane *stateAsWords)
> +{
> +     unsigned int i, j;
> +
> +     for(i=0; i<SHA3_NRLANES; i++)
> +             for(j=0; j<(64/8); j++)
> +                     state[i*(64/8)+j] = (unsigned char)((stateAsWords[i] >>
>  (8*j)) & 0xFF);
> +}
> +#endif
> +
> +static void
> +KeccakP1600OnWords(tKeccakLane *state)
> +{
> +     unsigned int i;
> +
> +
> +#if BYTE_ORDER == BIG_ENDIAN
> +     /*
> +      * Use the unoptimized reference implementation when
> +      * on big endian machines
> +      */
> +     for(i=0; i<SHA3_NRROUNDS; i++)
> +             KeccakP1600RoundSlow(state, i);
> +#else
> +     /*
> +      * Use the inplace version from the Keccak optimized reference
> +      * code of KeccakP1600 on little endian machines
> +      * Note that this routine does four rounds in one call.
> +      * */
> +     for(i=0; i<SHA3_NRROUNDS; i+=4)
> +             KeccakP1600QuadRound(state, i);
> +#endif
> +}
> +
> +#define ROL64(a, offset) ((offset != 0) ? ((((tKeccakLane)a) << offset) ^
> (((tKeccakLane)a) >> (64-offset))) : a)
> +
> +#if BYTE_ORDER == LITTLE_ENDIAN
> +static void
> +KeccakP1600QuadRound(tKeccakLane *state, unsigned int indexRound)
> +{
> +        /*
> +      * Inplace implementation by Ronny Van Keer and the designers
> +      * of Keccak from the optimized Keccak reference code
> +      */
> +
> +     tKeccakLane Ba, Be, Bi, Bo, Bu;
> +        tKeccakLane Ca, Ce, Ci, Co, Cu;
> +        tKeccakLane Da, De, Di, Do, Du;
> +
> +        #define Aba state[ 0]
> +        #define Abe state[ 1]
> +        #define Abi state[ 2]
> +        #define Abo state[ 3]
> +        #define Abu state[ 4]
> +        #define Aga state[ 5]
> +        #define Age state[ 6]
> +        #define Agi state[ 7]
> +        #define Ago state[ 8]
> +        #define Agu state[ 9]
> +        #define Aka state[10]
> +        #define Ake state[11]
> +        #define Aki state[12]
> +        #define Ako state[13]
> +        #define Aku state[14]
> +        #define Ama state[15]
> +        #define Ame state[16]
> +        #define Ami state[17]
> +        #define Amo state[18]
> +        #define Amu state[19]
> +        #define Asa state[20]
> +        #define Ase state[21]
> +        #define Asi state[22]
> +        #define Aso state[23]
> +        #define Asu state[24]

The '#' for the  #defines should be at the start of the line.

> +
> +
> +        Ca = Aba^Aga^Aka^Ama^Asa;
> +        Ce = Abe^Age^Ake^Ame^Ase;
> +        Ci = Abi^Agi^Aki^Ami^Asi;
> +        Co = Abo^Ago^Ako^Amo^Aso;
> +        Cu = Abu^Agu^Aku^Amu^Asu;
> +        Da = Cu^ROL64(Ce, 1);
> +        De = Ca^ROL64(Ci, 1);
> +        Di = Ce^ROL64(Co, 1);
> +        Do = Ci^ROL64(Cu, 1);
> +        Du = Co^ROL64(Ca, 1);
> +
> +        Ba = (Aba^Da);
> +        Be = ROL64((Age^De), 44);
> +        Bi = ROL64((Aki^Di), 43);
> +        Bo = ROL64((Amo^Do), 21);
> +        Bu = ROL64((Asu^Du), 14);
> +        Aba =   Ba ^((~Be)&  Bi );
> +        Aba ^= KeccakRoundConstants[indexRound];
> +        Age =   Be ^((~Bi)&  Bo );
> +        Aki =   Bi ^((~Bo)&  Bu );
> +        Amo =   Bo ^((~Bu)&  Ba );
> +        Asu =   Bu ^((~Ba)&  Be );
> +
> +        Bi = ROL64((Aka^Da), 3);
> +        Bo = ROL64((Ame^De), 45);
> +        Bu = ROL64((Asi^Di), 61);
> +        Ba = ROL64((Abo^Do), 28);
> +        Be = ROL64((Agu^Du), 20);
> +        Aka =   Ba ^((~Be)&  Bi );
> +        Ame =   Be ^((~Bi)&  Bo );
> +        Asi =   Bi ^((~Bo)&  Bu );
> +        Abo =   Bo ^((~Bu)&  Ba );
> +        Agu =   Bu ^((~Ba)&  Be );
> +
> +        Bu = ROL64((Asa^Da), 18);
> +        Ba = ROL64((Abe^De), 1);
> +        Be = ROL64((Agi^Di), 6);
> +        Bi = ROL64((Ako^Do), 25);
> +        Bo = ROL64((Amu^Du), 8);
> +        Asa =   Ba ^((~Be)&  Bi );
> +        Abe =   Be ^((~Bi)&  Bo );
> +        Agi =   Bi ^((~Bo)&  Bu );
> +        Ako =   Bo ^((~Bu)&  Ba );
> +        Amu =   Bu ^((~Ba)&  Be );
> +
> +        Be = ROL64((Aga^Da), 36);
> +        Bi = ROL64((Ake^De), 10);
> +        Bo = ROL64((Ami^Di), 15);
> +        Bu = ROL64((Aso^Do), 56);
> +        Ba = ROL64((Abu^Du), 27);
> +        Aga =   Ba ^((~Be)&  Bi );
> +        Ake =   Be ^((~Bi)&  Bo );
> +        Ami =   Bi ^((~Bo)&  Bu );
> +        Aso =   Bo ^((~Bu)&  Ba );
> +        Abu =   Bu ^((~Ba)&  Be );
> +
> +        Bo = ROL64((Ama^Da), 41);
> +        Bu = ROL64((Ase^De), 2);
> +        Ba = ROL64((Abi^Di), 62);
> +        Be = ROL64((Ago^Do), 55);
> +        Bi = ROL64((Aku^Du), 39);
> +        Ama =   Ba ^((~Be)&  Bi );
> +        Ase =   Be ^((~Bi)&  Bo );
> +        Abi =   Bi ^((~Bo)&  Bu );
> +        Ago =   Bo ^((~Bu)&  Ba );
> +        Aku =   Bu ^((~Ba)&  Be );
> +
> +        Ca = Aba^Aka^Asa^Aga^Ama;
> +        Ce = Age^Ame^Abe^Ake^Ase;
> +        Ci = Aki^Asi^Agi^Ami^Abi;
> +        Co = Amo^Abo^Ako^Aso^Ago;
> +        Cu = Asu^Agu^Amu^Abu^Aku;
> +        Da = Cu^ROL64(Ce, 1);
> +        De = Ca^ROL64(Ci, 1);
> +        Di = Ce^ROL64(Co, 1);
> +        Do = Ci^ROL64(Cu, 1);
> +        Du = Co^ROL64(Ca, 1);
> +
> +        Ba = (Aba^Da);
> +        Be = ROL64((Ame^De), 44);
> +        Bi = ROL64((Agi^Di), 43);
> +        Bo = ROL64((Aso^Do), 21);
> +        Bu = ROL64((Aku^Du), 14);
> +        Aba =   Ba ^((~Be)&  Bi );
> +        Aba ^= KeccakRoundConstants[indexRound+1];
> +        Ame =   Be ^((~Bi)&  Bo );
> +        Agi =   Bi ^((~Bo)&  Bu );
> +        Aso =   Bo ^((~Bu)&  Ba );
> +        Aku =   Bu ^((~Ba)&  Be );
> +
> +        Bi = ROL64((Asa^Da), 3);
> +        Bo = ROL64((Ake^De), 45);
> +        Bu = ROL64((Abi^Di), 61);
> +        Ba = ROL64((Amo^Do), 28);
> +        Be = ROL64((Agu^Du), 20);
> +        Asa =   Ba ^((~Be)&  Bi );
> +        Ake =   Be ^((~Bi)&  Bo );
> +        Abi =   Bi ^((~Bo)&  Bu );
> +        Amo =   Bo ^((~Bu)&  Ba );
> +        Agu =   Bu ^((~Ba)&  Be );
> +
> +        Bu = ROL64((Ama^Da), 18);
> +        Ba = ROL64((Age^De), 1);
> +        Be = ROL64((Asi^Di), 6);
> +        Bi = ROL64((Ako^Do), 25);
> +        Bo = ROL64((Abu^Du), 8);
> +        Ama =   Ba ^((~Be)&  Bi );
> +        Age =   Be ^((~Bi)&  Bo );
> +        Asi =   Bi ^((~Bo)&  Bu );
> +        Ako =   Bo ^((~Bu)&  Ba );
> +        Abu =   Bu ^((~Ba)&  Be );
> +
> +        Be = ROL64((Aka^Da), 36);
> +        Bi = ROL64((Abe^De), 10);
> +        Bo = ROL64((Ami^Di), 15);
> +        Bu = ROL64((Ago^Do), 56);
> +        Ba = ROL64((Asu^Du), 27);
> +        Aka =   Ba ^((~Be)&  Bi );
> +        Abe =   Be ^((~Bi)&  Bo );
> +        Ami =   Bi ^((~Bo)&  Bu );
> +        Ago =   Bo ^((~Bu)&  Ba );
> +        Asu =   Bu ^((~Ba)&  Be );
> +
> +        Bo = ROL64((Aga^Da), 41);
> +        Bu = ROL64((Ase^De), 2);
> +        Ba = ROL64((Aki^Di), 62);
> +        Be = ROL64((Abo^Do), 55);
> +        Bi = ROL64((Amu^Du), 39);
> +        Aga =   Ba ^((~Be)&  Bi );
> +        Ase =   Be ^((~Bi)&  Bo );
> +        Aki =   Bi ^((~Bo)&  Bu );
> +        Abo =   Bo ^((~Bu)&  Ba );
> +        Amu =   Bu ^((~Ba)&  Be );
> +
> +        Ca = Aba^Asa^Ama^Aka^Aga;
> +        Ce = Ame^Ake^Age^Abe^Ase;
> +        Ci = Agi^Abi^Asi^Ami^Aki;
> +        Co = Aso^Amo^Ako^Ago^Abo;
> +        Cu = Aku^Agu^Abu^Asu^Amu;
> +        Da = Cu^ROL64(Ce, 1);
> +        De = Ca^ROL64(Ci, 1);
> +        Di = Ce^ROL64(Co, 1);
> +        Do = Ci^ROL64(Cu, 1);
> +        Du = Co^ROL64(Ca, 1);
> +
> +        Ba = (Aba^Da);
> +        Be = ROL64((Ake^De), 44);
> +        Bi = ROL64((Asi^Di), 43);
> +        Bo = ROL64((Ago^Do), 21);
> +        Bu = ROL64((Amu^Du), 14);
> +        Aba =   Ba ^((~Be)&  Bi );
> +        Aba ^= KeccakRoundConstants[indexRound+2];
> +        Ake =   Be ^((~Bi)&  Bo );
> +        Asi =   Bi ^((~Bo)&  Bu );
> +        Ago =   Bo ^((~Bu)&  Ba );
> +        Amu =   Bu ^((~Ba)&  Be );
> +
> +        Bi = ROL64((Ama^Da), 3);
> +        Bo = ROL64((Abe^De), 45);
> +        Bu = ROL64((Aki^Di), 61);
> +        Ba = ROL64((Aso^Do), 28);
> +        Be = ROL64((Agu^Du), 20);
> +        Ama =   Ba ^((~Be)&  Bi );
> +        Abe =   Be ^((~Bi)&  Bo );
> +        Aki =   Bi ^((~Bo)&  Bu );
> +        Aso =   Bo ^((~Bu)&  Ba );
> +        Agu =   Bu ^((~Ba)&  Be );
> +
> +        Bu = ROL64((Aga^Da), 18);
> +        Ba = ROL64((Ame^De), 1);
> +        Be = ROL64((Abi^Di), 6);
> +        Bi = ROL64((Ako^Do), 25);
> +        Bo = ROL64((Asu^Du), 8);
> +        Aga =   Ba ^((~Be)&  Bi );
> +        Ame =   Be ^((~Bi)&  Bo );
> +        Abi =   Bi ^((~Bo)&  Bu );
> +        Ako =   Bo ^((~Bu)&  Ba );
> +        Asu =   Bu ^((~Ba)&  Be );
> +
> +        Be = ROL64((Asa^Da), 36);
> +        Bi = ROL64((Age^De), 10);
> +        Bo = ROL64((Ami^Di), 15);
> +        Bu = ROL64((Abo^Do), 56);
> +        Ba = ROL64((Aku^Du), 27);
> +        Asa =   Ba ^((~Be)&  Bi );
> +        Age =   Be ^((~Bi)&  Bo );
> +        Ami =   Bi ^((~Bo)&  Bu );
> +        Abo =   Bo ^((~Bu)&  Ba );
> +        Aku =   Bu ^((~Ba)&  Be );
> +
> +        Bo = ROL64((Aka^Da), 41);
> +        Bu = ROL64((Ase^De), 2);
> +        Ba = ROL64((Agi^Di), 62);
> +        Be = ROL64((Amo^Do), 55);
> +        Bi = ROL64((Abu^Du), 39);
> +        Aka =   Ba ^((~Be)&  Bi );
> +        Ase =   Be ^((~Bi)&  Bo );
> +        Agi =   Bi ^((~Bo)&  Bu );
> +        Amo =   Bo ^((~Bu)&  Ba );
> +        Abu =   Bu ^((~Ba)&  Be );
> +
> +        Ca = Aba^Ama^Aga^Asa^Aka;
> +        Ce = Ake^Abe^Ame^Age^Ase;
> +        Ci = Asi^Aki^Abi^Ami^Agi;
> +        Co = Ago^Aso^Ako^Abo^Amo;
> +        Cu = Amu^Agu^Asu^Aku^Abu;
> +        Da = Cu^ROL64(Ce, 1);
> +        De = Ca^ROL64(Ci, 1);
> +        Di = Ce^ROL64(Co, 1);
> +        Do = Ci^ROL64(Cu, 1);
> +        Du = Co^ROL64(Ca, 1);
> +
> +        Ba = (Aba^Da);
> +        Be = ROL64((Abe^De), 44);
> +        Bi = ROL64((Abi^Di), 43);
> +        Bo = ROL64((Abo^Do), 21);
> +        Bu = ROL64((Abu^Du), 14);
> +        Aba =   Ba ^((~Be)&  Bi );
> +        Aba ^= KeccakRoundConstants[indexRound+3];
> +        Abe =   Be ^((~Bi)&  Bo );
> +        Abi =   Bi ^((~Bo)&  Bu );
> +        Abo =   Bo ^((~Bu)&  Ba );
> +        Abu =   Bu ^((~Ba)&  Be );
> +
> +        Bi = ROL64((Aga^Da), 3);
> +        Bo = ROL64((Age^De), 45);
> +        Bu = ROL64((Agi^Di), 61);
> +        Ba = ROL64((Ago^Do), 28);
> +        Be = ROL64((Agu^Du), 20);
> +        Aga =   Ba ^((~Be)&  Bi );
> +        Age =   Be ^((~Bi)&  Bo );
> +        Agi =   Bi ^((~Bo)&  Bu );
> +        Ago =   Bo ^((~Bu)&  Ba );
> +        Agu =   Bu ^((~Ba)&  Be );
> +
> +        Bu = ROL64((Aka^Da), 18);
> +        Ba = ROL64((Ake^De), 1);
> +        Be = ROL64((Aki^Di), 6);
> +        Bi = ROL64((Ako^Do), 25);
> +        Bo = ROL64((Aku^Du), 8);
> +        Aka =   Ba ^((~Be)&  Bi );
> +        Ake =   Be ^((~Bi)&  Bo );
> +        Aki =   Bi ^((~Bo)&  Bu );
> +        Ako =   Bo ^((~Bu)&  Ba );
> +        Aku =   Bu ^((~Ba)&  Be );
> +
> +        Be = ROL64((Ama^Da), 36);
> +        Bi = ROL64((Ame^De), 10);
> +        Bo = ROL64((Ami^Di), 15);
> +        Bu = ROL64((Amo^Do), 56);
> +        Ba = ROL64((Amu^Du), 27);
> +        Ama =   Ba ^((~Be)&  Bi );
> +        Ame =   Be ^((~Bi)&  Bo );
> +        Ami =   Bi ^((~Bo)&  Bu );
> +        Amo =   Bo ^((~Bu)&  Ba );
> +        Amu =   Bu ^((~Ba)&  Be );
> +
> +        Bo = ROL64((Asa^Da), 41);
> +        Bu = ROL64((Ase^De), 2);
> +        Ba = ROL64((Asi^Di), 62);
> +        Be = ROL64((Aso^Do), 55);
> +        Bi = ROL64((Asu^Du), 39);
> +        Asa =   Ba ^((~Be)&  Bi );
> +        Ase =   Be ^((~Bi)&  Bo );
> +        Asi =   Bi ^((~Bo)&  Bu );
> +        Aso =   Bo ^((~Bu)&  Ba );
> +        Asu =   Bu ^((~Ba)&  Be );
> +
> +     #undef Aba
> +        #undef Abe
> +        #undef Abi
> +        #undef Abo
> +        #undef Abu
> +        #undef Aga
> +        #undef Age
> +        #undef Agi
> +        #undef Ago
> +        #undef Agu
> +        #undef Aka
> +        #undef Ake
> +        #undef Aki
> +        #undef Ako
> +        #undef Aku
> +        #undef Ama
> +        #undef Ame
> +        #undef Ami
> +        #undef Amo
> +        #undef Amu
> +        #undef Asa
> +        #undef Ase
> +        #undef Asi
> +        #undef Aso
> +        #undef Asu

The '#' for the  #undefs should be at the start of the line.

> +}
> +
> +#else /* BYTE_ORDER != BIG_ENDIAN */
> +void
> +KeccakP1600RoundSlow(tKeccakLane *state, unsigned int indexRound)
> +{
> +     theta(state);
> +     rho(state);
> +     pi(state);
> +     chi(state);
> +     iota(state, indexRound);
> +}
> +
> +#define ROL64(a, offset) ((offset != 0) ? ((((tKeccakLane)a) << offset) ^
> (((tKeccakLane)a) >> (64-offset))) : a)
> +
> +static void theta(tKeccakLane *A)
> +{
> +     unsigned int x, y;
> +     tKeccakLane C[5], D[5];
> +
> +     for(x=0; x<5; x++) {
> +             C[x] = 0;
> +             for(y=0; y<5; y++)
> +                     C[x] ^= A[index(x, y)];
> +     }
> +     for(x=0; x<5; x++)
> +             D[x] = ROL64(C[(x+1)%5], 1) ^ C[(x+4)%5];
> +     for(x=0; x<5; x++)
> +             for(y=0; y<5; y++)
> +                     A[index(x, y)] ^= D[x];
> +}
> +
> +static void rho(tKeccakLane *A)
> +{
> +     unsigned int x, y;
> +
> +     for(x=0; x<5; x++) for(y=0; y<5; y++)
> +             A[index(x, y)] = ROL64(A[index(x, y)], KeccakRhoOffsets[index(x
> , y)]);
> +}
> +
> +static void pi(tKeccakLane *A)
> +{
> +     unsigned int x, y;
> +     tKeccakLane tempA[25];
> +
> +     for(x=0; x<5; x++) for(y=0; y<5; y++)
> +             tempA[index(x, y)] = A[index(x, y)];
> +     for(x=0; x<5; x++) for(y=0; y<5; y++)
> +             A[index(0*x+1*y, 2*x+3*y)] = tempA[index(x, y)];
> +}
> +
> +static void chi(tKeccakLane *A)
> +{
> +     unsigned int x, y;
> +     tKeccakLane C[5];
> +
> +     for(y=0; y<5; y++) {
> +             for(x=0; x<5; x++)
> +                     C[x] = A[index(x, y)] ^ ((~A[index(x+1, y)]) & A[index(
> x+2, y)]);
> +             for(x=0; x<5; x++)
> +                     A[index(x, y)] = C[x];
> +     }
> +}
> +
> +static void iota(tKeccakLane *A, unsigned int indexRound)
> +{
> +     A[index(0, 0)] ^= KeccakRoundConstants[indexRound];
> +}
> +#endif /* BYTE_ORDER != BIG_ENDIAN */
> +
> +static void
> +KeccakP1600_ExtractBytes(const void *state, unsigned char *data, unsigned in
> t
> offset, unsigned int length)
> +{
> +     assert(offset < 200);
> +     assert(offset+length <= 200);
> +     memcpy(data, (unsigned char*)state+offset, length);
> +}
> +
> Index: lib/libc/hidden/sha3.h
> ===================================================================
> RCS file: lib/libc/hidden/sha3.h
> diff -N lib/libc/hidden/sha3.h
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ lib/libc/hidden/sha3.h    9 Jan 2018 15:17:42 -0000
> @@ -0,0 +1,76 @@
> +#ifndef _SHA3_H
> +#define _SHA3_H
> +
> +#define SHA3_224_DIGEST_LENGTH               28
> +#define SHA3_224_DIGEST_STRING_LENGTH        (SHA3_224_DIGEST_LENGTH * 2 + 1
> )
> +
> +#define SHA3_256_DIGEST_LENGTH               32
> +#define SHA3_256_DIGEST_STRING_LENGTH        (SHA3_256_DIGEST_LENGTH * 2 + 1
> )
> +
> +#define SHA3_384_DIGEST_LENGTH               48
> +#define SHA3_384_DIGEST_STRING_LENGTH        (SHA3_384_DIGEST_LENGTH * 2 + 1
> )
> +
> +#define SHA3_512_DIGEST_LENGTH               64
> +#define SHA3_512_DIGEST_STRING_LENGTH        (SHA3_512_DIGEST_LENGTH * 2 + 1
> )
> +
> +#define SHA3_STATE_SIZE              1600 / 8
> +
> +
> +typedef struct _SHA3_CTX {
> +     unsigned char state[SHA3_STATE_SIZE];
> +     unsigned int rate;
> +     unsigned int byteIOIndex;
> +     unsigned int fixedOutputLength;
> +} SHA3_CTX;
> +
> +
> +void SHA3_224Init(SHA3_CTX *);
> +char *SHA3_224End(SHA3_CTX *, char *)
> +     __attribute__((__bounded__(__minbytes__,2,SHA3_224_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_224File(const char *, char *)
> +     __attribute__((__bounded__(__minbytes__,2,SHA3_224_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_224FileChunk(const char *, char *, off_t, off_t)
> +     __attribute__((__bounded__(__minbytes__,2,SHA3_224_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_224Data(const u_int8_t *, size_t, char *)
> +     __attribute__((__bounded__(__string__,1,2)))
> +     __attribute__((__bounded__(__minbytes__,3,SHA3_224_DIGEST_STRING_LENGTH
> )));
> +
> +void SHA3_256Init(SHA3_CTX *);
> +char *SHA3_256End(SHA3_CTX *, char *)
> +     __attribute__((__bounded__(__minbytes__,2,SHA3_256_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_256File(const char *, char *)
> +     __attribute__((__bounded__(__minbytes__,2,SHA3_256_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_256FileChunk(const char *, char *, off_t, off_t)
> +     __attribute__((__bounded__(__minbytes__,2,SHA3_256_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_256Data(const u_int8_t *, size_t, char *)
> +     __attribute__((__bounded__(__string__,1,2)))
> +     __attribute__((__bounded__(__minbytes__,3,SHA3_256_DIGEST_STRING_LENGTH
> )));
> +
> +void SHA3_384Init(SHA3_CTX *);
> +char *SHA3_384End(SHA3_CTX *, char *)
> +     __attribute__((__bounded__(__minbytes__,2,SHA3_384_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_384File(const char *, char *)
> +     __attribute__((__bounded__(__minbytes__,2,SHA3_384_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_384FileChunk(const char *, char *, off_t, off_t)
> +     __attribute__((__bounded__(__minbytes__,2,SHA3_384_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_384Data(const u_int8_t *, size_t, char *)
> +     __attribute__((__bounded__(__string__,1,2)))
> +     __attribute__((__bounded__(__minbytes__,3,SHA3_384_DIGEST_STRING_LENGTH
> )));
> +
> +void SHA3_512Init(SHA3_CTX *);
> +char *SHA3_512End(SHA3_CTX *, char *)
> +     __attribute__((__bounded__(__minbytes__,2,SHA3_512_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_512File(const char *, char *)
> +     __attribute__((__bounded__(__minbytes__,2,SHA3_512_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_512FileChunk(const char *, char *, off_t, off_t)
> +     __attribute__((__bounded__(__minbytes__,2,SHA3_512_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_512Data(const u_int8_t *, size_t, char *)
> +     __attribute__((__bounded__(__string__,1,2)))
> +     __attribute__((__bounded__(__minbytes__,3,SHA3_512_DIGEST_STRING_LENGTH
> )));
> +
> +void SHA3_Update(SHA3_CTX *, const u_int8_t *, size_t)
> +     __attribute__((__bounded__(__string__,2,3)));
> +void SHA3_Final(u_int8_t [SHA3_224_DIGEST_LENGTH], SHA3_CTX *)
> +     __attribute__((__bounded__(__minbytes__,1,SHA3_224_DIGEST_LENGTH)));
> +
> +#endif /* _SHA3_H */

The hidden version of sha3.h should include the real sha3.h and
use the PROTO_NORMAL macro for each exported function.

 - todd

Reply via email to