// SPDX-License-Identifier: BSD-3-Clause
/* $OpenBSD: siphash.c,v 1.3 2015/02/20 11:51:03 tedu Exp $ */
/*-
* Copyright ( c ) 2013 Andre Oppermann < andre @ FreeBSD . org >
* All rights reserved .
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions
* are met :
* 1 . Redistributions of source code must retain the above copyright
* notice , this list of conditions and the following disclaimer .
* 2 . Redistributions in binary form must reproduce the above copyright
* notice , this list of conditions and the following disclaimer in the
* documentation and / or other materials provided with the distribution .
* 3 . The name of the author may not be used to endorse or promote
* products derived from this software without specific prior written
* permission .
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ` ` AS IS ' ' AND
* ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED . IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL
* DAMAGES ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES ; LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION )
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT
* LIABILITY , OR TORT ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE .
*/
/*
* SipHash is a family of PRFs SipHash - c - d where the integer parameters c and d
* are the number of compression rounds and the number of finalization rounds .
* A compression round is identical to a finalization round and this round
* function is called SipRound . Given a 128 - bit key k and a ( possibly empty )
* byte string m , SipHash - c - d returns a 64 - bit value SipHash - c - d ( k ; m ) .
*
* Implemented from the paper " SipHash : a fast short - input PRF " , 2012 . 09 . 18 ,
* by Jean - Philippe Aumasson and Daniel J . Bernstein ,
* Permanent Document ID b9a943a805fbfc6fde808af9fc0ecdfa
* https : //131002.net/siphash/siphash.pdf
* https : //131002.net/siphash/
*/
#include <asm /byteorder.h>
#include <linux/unaligned.h>
#include <linux/bitops.h>
#include <linux/string.h>
#include "siphash.h"
static void SipHash_Rounds(SIPHASH_CTX *ctx, int rounds)
{
while (rounds--) {
ctx->v[0 ] += ctx->v[1 ];
ctx->v[2 ] += ctx->v[3 ];
ctx->v[1 ] = rol64(ctx->v[1 ], 13 );
ctx->v[3 ] = rol64(ctx->v[3 ], 16 );
ctx->v[1 ] ^= ctx->v[0 ];
ctx->v[3 ] ^= ctx->v[2 ];
ctx->v[0 ] = rol64(ctx->v[0 ], 32 );
ctx->v[2 ] += ctx->v[1 ];
ctx->v[0 ] += ctx->v[3 ];
ctx->v[1 ] = rol64(ctx->v[1 ], 17 );
ctx->v[3 ] = rol64(ctx->v[3 ], 21 );
ctx->v[1 ] ^= ctx->v[2 ];
ctx->v[3 ] ^= ctx->v[0 ];
ctx->v[2 ] = rol64(ctx->v[2 ], 32 );
}
}
static void SipHash_CRounds(SIPHASH_CTX *ctx, const void *ptr, int rounds)
{
u64 m = get_unaligned_le64(ptr);
ctx->v[3 ] ^= m;
SipHash_Rounds(ctx, rounds);
ctx->v[0 ] ^= m;
}
void SipHash_Init(SIPHASH_CTX *ctx, const SIPHASH_KEY *key)
{
u64 k0, k1;
k0 = le64_to_cpu(key->k0);
k1 = le64_to_cpu(key->k1);
ctx->v[0 ] = 0 x736f6d6570736575ULL ^ k0;
ctx->v[1 ] = 0 x646f72616e646f6dULL ^ k1;
ctx->v[2 ] = 0 x6c7967656e657261ULL ^ k0;
ctx->v[3 ] = 0 x7465646279746573ULL ^ k1;
memset(ctx->buf, 0 , sizeof (ctx->buf));
ctx->bytes = 0 ;
}
void SipHash_Update(SIPHASH_CTX *ctx, int rc, int rf,
const void *src, size_t len)
{
const u8 *ptr = src;
size_t left, used;
if (len == 0 )
return ;
used = ctx->bytes % sizeof (ctx->buf);
ctx->bytes += len;
if (used > 0 ) {
left = sizeof (ctx->buf) - used;
if (len >= left) {
memcpy(&ctx->buf[used], ptr, left);
SipHash_CRounds(ctx, ctx->buf, rc);
len -= left;
ptr += left;
} else {
memcpy(&ctx->buf[used], ptr, len);
return ;
}
}
while (len >= sizeof (ctx->buf)) {
SipHash_CRounds(ctx, ptr, rc);
len -= sizeof (ctx->buf);
ptr += sizeof (ctx->buf);
}
if (len > 0 )
memcpy(&ctx->buf[used], ptr, len);
}
void SipHash_Final(void *dst, SIPHASH_CTX *ctx, int rc, int rf)
{
u64 r;
r = SipHash_End(ctx, rc, rf);
*((__le64 *) dst) = cpu_to_le64(r);
}
u64 SipHash_End(SIPHASH_CTX *ctx, int rc, int rf)
{
u64 r;
size_t left, used;
used = ctx->bytes % sizeof (ctx->buf);
left = sizeof (ctx->buf) - used;
memset(&ctx->buf[used], 0 , left - 1 );
ctx->buf[7 ] = ctx->bytes;
SipHash_CRounds(ctx, ctx->buf, rc);
ctx->v[2 ] ^= 0 xff;
SipHash_Rounds(ctx, rf);
r = (ctx->v[0 ] ^ ctx->v[1 ]) ^ (ctx->v[2 ] ^ ctx->v[3 ]);
memset(ctx, 0 , sizeof (*ctx));
return r;
}
u64 SipHash(const SIPHASH_KEY *key, int rc, int rf, const void *src, size_t len)
{
SIPHASH_CTX ctx;
SipHash_Init(&ctx, key);
SipHash_Update(&ctx, rc, rf, src, len);
return SipHash_End(&ctx, rc, rf);
}
Messung V0.5 in Prozent C=97 H=88 G=92
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-09-29)
¤
*© Formatika GbR, Deutschland