45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens/*
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens * Platform-specific definitions for Skein hash function.
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens *
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens * Source code author: Doug Whiting, 2008.
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens *
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens * This algorithm and source code is released to the public domain.
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens *
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens * Many thanks to Brian Gladman for his portable header files.
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens *
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens * To port Skein to an "unsupported" platform, change the definitions
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens * in this file appropriately.
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens */
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens/* Copyright 2013 Doug Whiting. This code is released to the public domain. */
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens#ifndef _SKEIN_PORT_H_
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens#define _SKEIN_PORT_H_
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens#include <sys/types.h> /* get integer type definitions */
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens#include <sys/systm.h> /* for bcopy() */
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens#ifndef RotL_64
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens#define RotL_64(x, N) (((x) << (N)) | ((x) >> (64 - (N))))
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens#endif
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens/*
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens * Skein is "natively" little-endian (unlike SHA-xxx), for optimal
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens * performance on x86 CPUs. The Skein code requires the following
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens * definitions for dealing with endianness:
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens *
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens * SKEIN_NEED_SWAP: 0 for little-endian, 1 for big-endian
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens * Skein_Put64_LSB_First
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens * Skein_Get64_LSB_First
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens * Skein_Swap64
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens *
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens * If SKEIN_NEED_SWAP is defined at compile time, it is used here
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens * along with the portable versions of Put64/Get64/Swap64, which
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens * are slow in general.
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens *
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens * Otherwise, an "auto-detect" of endianness is attempted below.
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens * If the default handling doesn't work well, the user may insert
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens * platform-specific code instead (e.g., for big-endian CPUs).
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens *
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens */
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens#ifndef SKEIN_NEED_SWAP /* compile-time "override" for endianness? */
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens#include <sys/isa_defs.h> /* get endianness selection */
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens#define PLATFORM_MUST_ALIGN _ALIGNMENT_REQUIRED
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens#if defined(_BIG_ENDIAN)
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens/* here for big-endian CPUs */
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens#define SKEIN_NEED_SWAP (1)
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens#else
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens/* here for x86 and x86-64 CPUs (and other detected little-endian CPUs) */
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens#define SKEIN_NEED_SWAP (0)
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens#if PLATFORM_MUST_ALIGN == 0 /* ok to use "fast" versions? */
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens#define Skein_Put64_LSB_First(dst08, src64, bCnt) bcopy(src64, dst08, bCnt)
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens#define Skein_Get64_LSB_First(dst64, src08, wCnt) \
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens bcopy(src08, dst64, 8 * (wCnt))
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens#endif
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens#endif
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens#endif /* ifndef SKEIN_NEED_SWAP */
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens/*
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens * Provide any definitions still needed.
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens */
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens#ifndef Skein_Swap64 /* swap for big-endian, nop for little-endian */
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens#if SKEIN_NEED_SWAP
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens#define Skein_Swap64(w64) \
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens (((((uint64_t)(w64)) & 0xFF) << 56) | \
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens (((((uint64_t)(w64)) >> 8) & 0xFF) << 48) | \
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens (((((uint64_t)(w64)) >> 16) & 0xFF) << 40) | \
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens (((((uint64_t)(w64)) >> 24) & 0xFF) << 32) | \
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens (((((uint64_t)(w64)) >> 32) & 0xFF) << 24) | \
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens (((((uint64_t)(w64)) >> 40) & 0xFF) << 16) | \
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens (((((uint64_t)(w64)) >> 48) & 0xFF) << 8) | \
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens (((((uint64_t)(w64)) >> 56) & 0xFF)))
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens#else
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens#define Skein_Swap64(w64) (w64)
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens#endif
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens#endif /* ifndef Skein_Swap64 */
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens#ifndef Skein_Put64_LSB_First
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrensvoid
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew AhrensSkein_Put64_LSB_First(uint8_t *dst, const uint64_t *src, size_t bCnt)
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens#ifdef SKEIN_PORT_CODE /* instantiate the function code here? */
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens{
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens /*
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens * this version is fully portable (big-endian or little-endian),
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens * but slow
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens */
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens size_t n;
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens for (n = 0; n < bCnt; n++)
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens dst[n] = (uint8_t)(src[n >> 3] >> (8 * (n & 7)));
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens}
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens#else
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens; /* output only the function prototype */
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens#endif
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens#endif /* ifndef Skein_Put64_LSB_First */
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens#ifndef Skein_Get64_LSB_First
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrensvoid
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew AhrensSkein_Get64_LSB_First(uint64_t *dst, const uint8_t *src, size_t wCnt)
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens#ifdef SKEIN_PORT_CODE /* instantiate the function code here? */
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens{
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens /*
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens * this version is fully portable (big-endian or little-endian),
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens * but slow
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens */
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens size_t n;
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens for (n = 0; n < 8 * wCnt; n += 8)
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens dst[n / 8] = (((uint64_t)src[n])) +
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens (((uint64_t)src[n + 1]) << 8) +
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens (((uint64_t)src[n + 2]) << 16) +
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens (((uint64_t)src[n + 3]) << 24) +
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens (((uint64_t)src[n + 4]) << 32) +
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens (((uint64_t)src[n + 5]) << 40) +
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens (((uint64_t)src[n + 6]) << 48) +
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens (((uint64_t)src[n + 7]) << 56);
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens}
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens#else
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens; /* output only the function prototype */
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens#endif
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens#endif /* ifndef Skein_Get64_LSB_First */
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens
45818ee124adeaaf947698996b4f4c722afc6d1fMatthew Ahrens#endif /* _SKEIN_PORT_H_ */