Crypt-Komihash
view release on metacpan or search on metacpan
lib/Crypt/komihash.h view on Meta::CPAN
if( MsgLen > 7 )
{
// The following two XOR instructions are equivalent to mixing a
// message with a cryptographic one-time-pad (bitwise modulo 2
// addition). Message's statistics and distribution are thus
// unimportant.
r2h ^= kh_lpu64ec_l3( Msg + 8, MsgLen - 8 );
r1h ^= kh_lu64ec( Msg );
}
else
if( KOMIHASH_LIKELY( MsgLen != 0 ))
{
r1h ^= kh_lpu64ec_nz( Msg, MsgLen );
}
KOMIHASH_HASHFIN();
}
if( KOMIHASH_LIKELY( MsgLen < 32 ))
{
KOMIHASH_HASH16( Msg );
if( MsgLen > 23 )
{
r2h = Seed5 ^ kh_lpu64ec_l4( Msg + 24, MsgLen - 24 );
r1h = Seed1 ^ kh_lu64ec( Msg + 16 );
KOMIHASH_HASHFIN();
}
else
{
r1h = Seed1 ^ kh_lpu64ec_l4( Msg + 16, MsgLen - 16 );
r2h = Seed5;
KOMIHASH_HASHFIN();
}
}
if( KOMIHASH_LIKELY( MsgLen > 63 ))
{
uint64_t Seed2 = 0x13198A2E03707344 ^ Seed1;
uint64_t Seed3 = 0xA4093822299F31D0 ^ Seed1;
uint64_t Seed4 = 0x082EFA98EC4E6C89 ^ Seed1;
uint64_t Seed6 = 0xBE5466CF34E90C6C ^ Seed5;
uint64_t Seed7 = 0xC0AC29B7C97C50DD ^ Seed5;
uint64_t Seed8 = 0x3F84D5B5B5470917 ^ Seed5;
KOMIHASH_HASHLOOP64();
Seed5 ^= Seed6 ^ Seed7 ^ Seed8;
Seed1 ^= Seed2 ^ Seed3 ^ Seed4;
}
return( komihash_epi( Msg, MsgLen, Seed1, Seed5 ));
}
/**
* @brief KOMIRAND 64-bit pseudo-random number generator.
*
* Simple, reliable, self-starting yet efficient PRNG, with 2^64 period.
* 0.62 cycles/byte performance. Self-starts in 4 iterations, which is a
* suggested "warming up" initialization before using its output.
*
* @param[in,out] Seed1 Seed value 1. Can be initialized to any value
* (even 0). This is the usual "PRNG seed" value.
* @param[in,out] Seed2 Seed value 2, a supporting variable. Best initialized
* to the same value as `Seed1`.
* @return The next uniformly-random 64-bit value.
*/
static KOMIHASH_INLINE uint64_t komirand( uint64_t* const Seed1,
uint64_t* const Seed2 )
{
uint64_t s1 = *Seed1;
uint64_t s2 = *Seed2;
kh_m128( s1, s2, &s1, &s2 );
s2 += 0xAAAAAAAAAAAAAAAA;
s1 ^= s2;
*Seed2 = s2;
*Seed1 = s1;
return( s1 );
}
/**
* @def KOMIHASH_BUFSIZE
* @brief Streamed hashing's buffer size, in bytes.
*
* Must be a multiple of 64, and not less than 128. Can be defined externally.
*/
#if !defined( KOMIHASH_BUFSIZE )
#define KOMIHASH_BUFSIZE 768
#endif // !defined( KOMIHASH_BUFSIZE )
/**
* @brief Context structure for the streamed "komihash" hashing.
*
* The komihash_init() function should be called to initalize the structure
* before hashing. Note that the default buffer size is modest, permitting
* placement of this structure on stack. `Seed[ 0 ]` is used as `UseSeed`
* value storage.
*/
typedef struct {
uint8_t pb[ 8 ]; ///< Buffer's padding bytes, to avoid OOB.
uint8_t Buf[ KOMIHASH_BUFSIZE ]; ///< Buffer.
uint64_t Seed[ 8 ]; ///< Hashing state variables.
size_t BufFill; ///< Buffer fill count (position), in bytes.
size_t IsHashing; ///< 0 or 1, equals 1 if the actual hashing was started.
} komihash_stream_t;
/**
* @brief Function initializes the streamed "komihash" hashing session.
*
* @param[out] ctx Pointer to the context structure.
* @param UseSeed Optional value, to use instead of the default seed. To use
( run in 1.217 second using v1.01-cache-2.11-cpan-96521ef73a4 )