/* ==========================================================================
* siphash . h - SipHash - 2 - 4 in a single header file
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* Derived by William Ahern from the reference implementation [ 1 ] published [ 2 ]
* by Jean - Philippe Aumasson and Daniel J . Berstein .
* Minimal changes by Sebastian Pipping and Victor Stinner on top , see below .
* Licensed under the CC0 Public Domain Dedication license .
*
* 1 . https : //www.131002.net/siphash/siphash24.c
* 2 . https : //www.131002.net/siphash/
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* HISTORY :
*
* 2020 - 10 - 03 ( Sebastian Pipping )
* - Drop support for Visual Studio 9 . 0 / 2008 and earlier
*
* 2019 - 08 - 03 ( Sebastian Pipping )
* - Mark part of sip24_valid as to be excluded from clang - format
* - Re - format code using clang - format 9
*
* 2018 - 07 - 08 ( Anton Maklakov )
* - Add " fall through " markers for GCC ' s - Wimplicit - fallthrough
*
* 2017 - 11 - 03 ( Sebastian Pipping )
* - Hide sip_tobin and sip_binof unless SIPHASH_TOBIN macro is defined
*
* 2017 - 07 - 25 ( Vadim Zeitlin )
* - Fix use of SIPHASH_MAIN macro
*
* 2017 - 07 - 05 ( Sebastian Pipping )
* - Use _ SIP_ULL macro to not require a C + + 11 compiler if compiled as C + +
* - Add const qualifiers at two places
* - Ensure < = 80 characters line length ( assuming tab width 4 )
*
* 2017 - 06 - 23 ( Victor Stinner )
* - Address Win64 compile warnings
*
* 2017 - 06 - 18 ( Sebastian Pipping )
* - Clarify license note in the header
* - Address C89 issues :
* - Stop using inline keyword ( and let compiler decide )
* - Replace _ Bool by int
* - Turn macro siphash24 into a function
* - Address invalid conversion ( void pointer ) by explicit cast
* - Address lack of stdint . h for Visual Studio 2003 to 2008
* - Always expose sip24_valid ( for self - tests )
*
* 2012 - 11 - 04 - Born . ( William Ahern )
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* USAGE :
*
* SipHash - 2 - 4 takes as input two 64 - bit words as the key , some number of
* message bytes , and outputs a 64 - bit word as the message digest . This
* implementation employs two data structures : a struct sipkey for
* representing the key , and a struct siphash for representing the hash
* state .
*
* For converting a 16 - byte unsigned char array to a key , use either the
* macro sip_keyof or the routine sip_tokey . The former instantiates a
* compound literal key , while the latter requires a key object as a
* parameter .
*
* unsigned char secret [ 16 ] ;
* arc4random_buf ( secret , sizeof secret ) ;
* struct sipkey * key = sip_keyof ( secret ) ;
*
* For hashing a message , use either the convenience macro siphash24 or the
* routines sip24_init , sip24_update , and sip24_final .
*
* struct siphash state ;
* void * msg ;
* size_t len ;
* uint64_t hash ;
*
* sip24_init ( & state , key ) ;
* sip24_update ( & state , msg , len ) ;
* hash = sip24_final ( & state ) ;
*
* or
*
* hash = siphash24 ( msg , len , key ) ;
*
* To convert the 64 - bit hash value to a canonical 8 - byte little - endian
* binary representation , use either the macro sip_binof or the routine
* sip_tobin . The former instantiates and returns a compound literal array ,
* while the latter requires an array object as a parameter .
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* NOTES :
*
* o Neither sip_keyof , sip_binof , nor siphash24 will work with compilers
* lacking compound literal support . Instead , you must use the lower - level
* interfaces which take as parameters the temporary state objects .
*
* o Uppercase macros may evaluate parameters more than once . Lowercase
* macros should not exhibit any such side effects .
* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
#ifndef SIPHASH_H
#define SIPHASH_H
#include <stddef.h> /* size_t */
#include <stdint.h> /* uint64_t uint32_t uint8_t */
/*
* Workaround to not require a C + + 11 compiler for using ULL suffix
* if this code is included and compiled as C + + ; related GCC warning is :
* warning : use of C + + 11 long long integer constant [ - Wlong - long ]
*/
#define SIP_ULL(high, low) ((((uint64_t)high) << 32 ) | (low))
#define SIP_ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b))))
#define SIP_U32TO8_LE(p, v) \
(p)[0 ] = (uint8_t)((v) >> 0 ); \
(p)[1 ] = (uint8_t)((v) >> 8 ); \
(p)[2 ] = (uint8_t)((v) >> 16 ); \
(p)[3 ] = (uint8_t)((v) >> 24 );
#define SIP_U64TO8_LE(p, v) \
SIP_U32TO8_LE((p) + 0 , (uint32_t)((v) >> 0 )); \
SIP_U32TO8_LE((p) + 4 , (uint32_t)((v) >> 32 ));
#define SIP_U8TO64_LE(p) \
(((uint64_t)((p)[0 ]) << 0 ) | ((uint64_t)((p)[1 ]) << 8 ) \
| ((uint64_t)((p)[2 ]) << 16 ) | ((uint64_t)((p)[3 ]) << 24 ) \
| ((uint64_t)((p)[4 ]) << 32 ) | ((uint64_t)((p)[5 ]) << 40 ) \
| ((uint64_t)((p)[6 ]) << 48 ) | ((uint64_t)((p)[7 ]) << 56 ))
#define SIPHASH_INITIALIZER {0 , 0 , 0 , 0 , {0 }, 0 , 0 }
struct siphash {
uint64_t v0, v1, v2, v3;
unsigned char buf[8 ], *p;
uint64_t c;
}; /* struct siphash */
#define SIP_KEYLEN 16
struct sipkey {
uint64_t k[2 ];
}; /* struct sipkey */
#define sip_keyof(k) sip_tokey(&(struct sipkey){{0 }}, (k))
static struct sipkey *
sip_tokey(struct sipkey *key, const void *src) {
key->k[0 ] = SIP_U8TO64_LE((const unsigned char *)src);
key->k[1 ] = SIP_U8TO64_LE((const unsigned char *)src + 8 );
return key;
} /* sip_tokey() */
#ifdef SIPHASH_TOBIN
# define sip_binof(v) sip_tobin((unsigned char [8 ]){0 }, (v))
static void *
sip_tobin(void *dst, uint64_t u64) {
SIP_U64TO8_LE((unsigned char *)dst, u64);
return dst;
} /* sip_tobin() */
#endif /* SIPHASH_TOBIN */
static void
sip_round(struct siphash *H, const int rounds) {
int i;
for (i = 0 ; i < rounds; i++) {
H->v0 += H->v1;
H->v1 = SIP_ROTL(H->v1, 13 );
H->v1 ^= H->v0;
H->v0 = SIP_ROTL(H->v0, 32 );
H->v2 += H->v3;
H->v3 = SIP_ROTL(H->v3, 16 );
H->v3 ^= H->v2;
H->v0 += H->v3;
H->v3 = SIP_ROTL(H->v3, 21 );
H->v3 ^= H->v0;
H->v2 += H->v1;
H->v1 = SIP_ROTL(H->v1, 17 );
H->v1 ^= H->v2;
H->v2 = SIP_ROTL(H->v2, 32 );
}
} /* sip_round() */
static struct siphash *
sip24_init(struct siphash *H, const struct sipkey *key) {
H->v0 = SIP_ULL(0 x736f6d65U, 0 x70736575U) ^ key->k[0 ];
H->v1 = SIP_ULL(0 x646f7261U, 0 x6e646f6dU) ^ key->k[1 ];
H->v2 = SIP_ULL(0 x6c796765U, 0 x6e657261U) ^ key->k[0 ];
H->v3 = SIP_ULL(0 x74656462U, 0 x79746573U) ^ key->k[1 ];
H->p = H->buf;
H->c = 0 ;
return H;
} /* sip24_init() */
#define sip_endof(a) (&(a)[sizeof (a) / sizeof *(a)])
static struct siphash *
sip24_update(struct siphash *H, const void *src, size_t len) {
const unsigned char *p = (const unsigned char *)src, *pe = p + len;
uint64_t m;
do {
while (p < pe && H->p < sip_endof(H->buf))
*H->p++ = *p++;
if (H->p < sip_endof(H->buf))
break ;
m = SIP_U8TO64_LE(H->buf);
H->v3 ^= m;
sip_round(H, 2 );
H->v0 ^= m;
H->p = H->buf;
H->c += 8 ;
} while (p < pe);
return H;
} /* sip24_update() */
static uint64_t
sip24_final(struct siphash *H) {
const char left = (char )(H->p - H->buf);
uint64_t b = (H->c + left) << 56 ;
switch (left) {
case 7 :
b |= (uint64_t)H->buf[6 ] << 48 ;
/* fall through */
case 6 :
b |= (uint64_t)H->buf[5 ] << 40 ;
/* fall through */
case 5 :
b |= (uint64_t)H->buf[4 ] << 32 ;
/* fall through */
case 4 :
b |= (uint64_t)H->buf[3 ] << 24 ;
/* fall through */
case 3 :
b |= (uint64_t)H->buf[2 ] << 16 ;
/* fall through */
case 2 :
b |= (uint64_t)H->buf[1 ] << 8 ;
/* fall through */
case 1 :
b |= (uint64_t)H->buf[0 ] << 0 ;
/* fall through */
case 0 :
break ;
}
H->v3 ^= b;
sip_round(H, 2 );
H->v0 ^= b;
H->v2 ^= 0 xff;
sip_round(H, 4 );
return H->v0 ^ H->v1 ^ H->v2 ^ H->v3;
} /* sip24_final() */
static uint64_t
siphash24(const void *src, size_t len, const struct sipkey *key) {
struct siphash state = SIPHASH_INITIALIZER;
return sip24_final(sip24_update(sip24_init(&state, key), src, len));
} /* siphash24() */
/*
* SipHash - 2 - 4 output with
* k = 00 01 02 . . .
* and
* in = ( empty string )
* in = 00 ( 1 byte )
* in = 00 01 ( 2 bytes )
* in = 00 01 02 ( 3 bytes )
* . . .
* in = 00 01 02 . . . 3 e ( 63 bytes )
*/
static int
sip24_valid(void ) {
/* clang-format off */
static const unsigned char vectors[64 ][8 ] = {
{ 0 x31, 0 x0e, 0 x0e, 0 xdd, 0 x47, 0 xdb, 0 x6f, 0 x72, },
{ 0 xfd, 0 x67, 0 xdc, 0 x93, 0 xc5, 0 x39, 0 xf8, 0 x74, },
{ 0 x5a, 0 x4f, 0 xa9, 0 xd9, 0 x09, 0 x80, 0 x6c, 0 x0d, },
{ 0 x2d, 0 x7e, 0 xfb, 0 xd7, 0 x96, 0 x66, 0 x67, 0 x85, },
{ 0 xb7, 0 x87, 0 x71, 0 x27, 0 xe0, 0 x94, 0 x27, 0 xcf, },
{ 0 x8d, 0 xa6, 0 x99, 0 xcd, 0 x64, 0 x55, 0 x76, 0 x18, },
{ 0 xce, 0 xe3, 0 xfe, 0 x58, 0 x6e, 0 x46, 0 xc9, 0 xcb, },
{ 0 x37, 0 xd1, 0 x01, 0 x8b, 0 xf5, 0 x00, 0 x02, 0 xab, },
{ 0 x62, 0 x24, 0 x93, 0 x9a, 0 x79, 0 xf5, 0 xf5, 0 x93, },
{ 0 xb0, 0 xe4, 0 xa9, 0 x0b, 0 xdf, 0 x82, 0 x00, 0 x9e, },
{ 0 xf3, 0 xb9, 0 xdd, 0 x94, 0 xc5, 0 xbb, 0 x5d, 0 x7a, },
{ 0 xa7, 0 xad, 0 x6b, 0 x22, 0 x46, 0 x2f, 0 xb3, 0 xf4, },
{ 0 xfb, 0 xe5, 0 x0e, 0 x86, 0 xbc, 0 x8f, 0 x1e, 0 x75, },
{ 0 x90, 0 x3d, 0 x84, 0 xc0, 0 x27, 0 x56, 0 xea, 0 x14, },
{ 0 xee, 0 xf2, 0 x7a, 0 x8e, 0 x90, 0 xca, 0 x23, 0 xf7, },
{ 0 xe5, 0 x45, 0 xbe, 0 x49, 0 x61, 0 xca, 0 x29, 0 xa1, },
{ 0 xdb, 0 x9b, 0 xc2, 0 x57, 0 x7f, 0 xcc, 0 x2a, 0 x3f, },
{ 0 x94, 0 x47, 0 xbe, 0 x2c, 0 xf5, 0 xe9, 0 x9a, 0 x69, },
{ 0 x9c, 0 xd3, 0 x8d, 0 x96, 0 xf0, 0 xb3, 0 xc1, 0 x4b, },
{ 0 xbd, 0 x61, 0 x79, 0 xa7, 0 x1d, 0 xc9, 0 x6d, 0 xbb, },
{ 0 x98, 0 xee, 0 xa2, 0 x1a, 0 xf2, 0 x5c, 0 xd6, 0 xbe, },
{ 0 xc7, 0 x67, 0 x3b, 0 x2e, 0 xb0, 0 xcb, 0 xf2, 0 xd0, },
{ 0 x88, 0 x3e, 0 xa3, 0 xe3, 0 x95, 0 x67, 0 x53, 0 x93, },
{ 0 xc8, 0 xce, 0 x5c, 0 xcd, 0 x8c, 0 x03, 0 x0c, 0 xa8, },
{ 0 x94, 0 xaf, 0 x49, 0 xf6, 0 xc6, 0 x50, 0 xad, 0 xb8, },
{ 0 xea, 0 xb8, 0 x85, 0 x8a, 0 xde, 0 x92, 0 xe1, 0 xbc, },
{ 0 xf3, 0 x15, 0 xbb, 0 x5b, 0 xb8, 0 x35, 0 xd8, 0 x17, },
{ 0 xad, 0 xcf, 0 x6b, 0 x07, 0 x63, 0 x61, 0 x2e, 0 x2f, },
{ 0 xa5, 0 xc9, 0 x1d, 0 xa7, 0 xac, 0 xaa, 0 x4d, 0 xde, },
{ 0 x71, 0 x65, 0 x95, 0 x87, 0 x66, 0 x50, 0 xa2, 0 xa6, },
{ 0 x28, 0 xef, 0 x49, 0 x5c, 0 x53, 0 xa3, 0 x87, 0 xad, },
{ 0 x42, 0 xc3, 0 x41, 0 xd8, 0 xfa, 0 x92, 0 xd8, 0 x32, },
{ 0 xce, 0 x7c, 0 xf2, 0 x72, 0 x2f, 0 x51, 0 x27, 0 x71, },
{ 0 xe3, 0 x78, 0 x59, 0 xf9, 0 x46, 0 x23, 0 xf3, 0 xa7, },
{ 0 x38, 0 x12, 0 x05, 0 xbb, 0 x1a, 0 xb0, 0 xe0, 0 x12, },
{ 0 xae, 0 x97, 0 xa1, 0 x0f, 0 xd4, 0 x34, 0 xe0, 0 x15, },
{ 0 xb4, 0 xa3, 0 x15, 0 x08, 0 xbe, 0 xff, 0 x4d, 0 x31, },
{ 0 x81, 0 x39, 0 x62, 0 x29, 0 xf0, 0 x90, 0 x79, 0 x02, },
{ 0 x4d, 0 x0c, 0 xf4, 0 x9e, 0 xe5, 0 xd4, 0 xdc, 0 xca, },
{ 0 x5c, 0 x73, 0 x33, 0 x6a, 0 x76, 0 xd8, 0 xbf, 0 x9a, },
{ 0 xd0, 0 xa7, 0 x04, 0 x53, 0 x6b, 0 xa9, 0 x3e, 0 x0e, },
{ 0 x92, 0 x59, 0 x58, 0 xfc, 0 xd6, 0 x42, 0 x0c, 0 xad, },
{ 0 xa9, 0 x15, 0 xc2, 0 x9b, 0 xc8, 0 x06, 0 x73, 0 x18, },
{ 0 x95, 0 x2b, 0 x79, 0 xf3, 0 xbc, 0 x0a, 0 xa6, 0 xd4, },
{ 0 xf2, 0 x1d, 0 xf2, 0 xe4, 0 x1d, 0 x45, 0 x35, 0 xf9, },
{ 0 x87, 0 x57, 0 x75, 0 x19, 0 x04, 0 x8f, 0 x53, 0 xa9, },
{ 0 x10, 0 xa5, 0 x6c, 0 xf5, 0 xdf, 0 xcd, 0 x9a, 0 xdb, },
{ 0 xeb, 0 x75, 0 x09, 0 x5c, 0 xcd, 0 x98, 0 x6c, 0 xd0, },
{ 0 x51, 0 xa9, 0 xcb, 0 x9e, 0 xcb, 0 xa3, 0 x12, 0 xe6, },
{ 0 x96, 0 xaf, 0 xad, 0 xfc, 0 x2c, 0 xe6, 0 x66, 0 xc7, },
{ 0 x72, 0 xfe, 0 x52, 0 x97, 0 x5a, 0 x43, 0 x64, 0 xee, },
{ 0 x5a, 0 x16, 0 x45, 0 xb2, 0 x76, 0 xd5, 0 x92, 0 xa1, },
{ 0 xb2, 0 x74, 0 xcb, 0 x8e, 0 xbf, 0 x87, 0 x87, 0 x0a, },
{ 0 x6f, 0 x9b, 0 xb4, 0 x20, 0 x3d, 0 xe7, 0 xb3, 0 x81, },
{ 0 xea, 0 xec, 0 xb2, 0 xa3, 0 x0b, 0 x22, 0 xa8, 0 x7f, },
{ 0 x99, 0 x24, 0 xa4, 0 x3c, 0 xc1, 0 x31, 0 x57, 0 x24, },
{ 0 xbd, 0 x83, 0 x8d, 0 x3a, 0 xaf, 0 xbf, 0 x8d, 0 xb7, },
{ 0 x0b, 0 x1a, 0 x2a, 0 x32, 0 x65, 0 xd5, 0 x1a, 0 xea, },
{ 0 x13, 0 x50, 0 x79, 0 xa3, 0 x23, 0 x1c, 0 xe6, 0 x60, },
{ 0 x93, 0 x2b, 0 x28, 0 x46, 0 xe4, 0 xd7, 0 x06, 0 x66, },
{ 0 xe1, 0 x91, 0 x5f, 0 x5c, 0 xb1, 0 xec, 0 xa4, 0 x6c, },
{ 0 xf3, 0 x25, 0 x96, 0 x5c, 0 xa1, 0 x6d, 0 x62, 0 x9f, },
{ 0 x57, 0 x5f, 0 xf2, 0 x8e, 0 x60, 0 x38, 0 x1b, 0 xe5, },
{ 0 x72, 0 x45, 0 x06, 0 xeb, 0 x4c, 0 x32, 0 x8a, 0 x95, }
};
/* clang-format on */
unsigned char in[64 ];
struct sipkey k;
size_t i;
sip_tokey(&k, "\000\001\002\003\004\005\006\007\010\011"
"\012\013\014\015\016\017" );
for (i = 0 ; i < sizeof in; ++i) {
in[i] = (unsigned char )i;
if (siphash24(in, i, &k) != SIP_U8TO64_LE(vectors[i]))
return 0 ;
}
return 1 ;
} /* sip24_valid() */
#ifdef SIPHASH_MAIN
# include <stdio.h>
int
main(void ) {
const int ok = sip24_valid();
if (ok)
puts("OK" );
else
puts("FAIL" );
return ! ok;
} /* main() */
#endif /* SIPHASH_MAIN */
#endif /* SIPHASH_H */
Messung V0.5 in Prozent C=96 H=94 G=94
¤ Dauer der Verarbeitung: 0.10 Sekunden
¤
*© Formatika GbR, Deutschland