Path: blob/master/sha3/sph_cubehash.c
1294 views
/* $Id: cubehash.c 227 2010-06-16 17:28:38Z tp $ */1/*2* CubeHash implementation.3*4* ==========================(LICENSE BEGIN)============================5*6* Copyright (c) 2007-2010 Projet RNRT SAPHIR7*8* Permission is hereby granted, free of charge, to any person obtaining9* a copy of this software and associated documentation files (the10* "Software"), to deal in the Software without restriction, including11* without limitation the rights to use, copy, modify, merge, publish,12* distribute, sublicense, and/or sell copies of the Software, and to13* permit persons to whom the Software is furnished to do so, subject to14* the following conditions:15*16* The above copyright notice and this permission notice shall be17* included in all copies or substantial portions of the Software.18*19* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,20* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF21* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.22* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY23* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,24* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE25* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.26*27* ===========================(LICENSE END)=============================28*29* @author Thomas Pornin <[email protected]>30*/3132#include <stddef.h>33#include <string.h>34#include <limits.h>3536#include "sph_cubehash.h"37#ifdef __cplusplus38extern "C"{39#endif4041#if SPH_SMALL_FOOTPRINT && !defined SPH_SMALL_FOOTPRINT_CUBEHASH42#define SPH_SMALL_FOOTPRINT_CUBEHASH 143#endif4445/*46* Some tests were conducted on an Intel Core2 Q6600 (32-bit and 64-bit47* mode), a PowerPC G3, and a MIPS-compatible CPU (Broadcom BCM3302).48* It appears that the optimal settings are:49* -- full unroll, no state copy on the "big" systems (x86, PowerPC)50* -- unroll to 4 or 8, state copy on the "small" system (MIPS)51*/5253#if SPH_SMALL_FOOTPRINT_CUBEHASH5455#if !defined SPH_CUBEHASH_UNROLL56#define SPH_CUBEHASH_UNROLL 457#endif58#if !defined SPH_CUBEHASH_NOCOPY59#define SPH_CUBEHASH_NOCOPY 160#endif6162#else6364#if !defined SPH_CUBEHASH_UNROLL65#define SPH_CUBEHASH_UNROLL 066#endif67#if !defined SPH_CUBEHASH_NOCOPY68#define SPH_CUBEHASH_NOCOPY 069#endif7071#endif7273#ifdef _MSC_VER74#pragma warning (disable: 4146)75#endif7677static const sph_u32 IV224[] = {78SPH_C32(0xB0FC8217), SPH_C32(0x1BEE1A90), SPH_C32(0x829E1A22),79SPH_C32(0x6362C342), SPH_C32(0x24D91C30), SPH_C32(0x03A7AA24),80SPH_C32(0xA63721C8), SPH_C32(0x85B0E2EF), SPH_C32(0xF35D13F3),81SPH_C32(0x41DA807D), SPH_C32(0x21A70CA6), SPH_C32(0x1F4E9774),82SPH_C32(0xB3E1C932), SPH_C32(0xEB0A79A8), SPH_C32(0xCDDAAA66),83SPH_C32(0xE2F6ECAA), SPH_C32(0x0A713362), SPH_C32(0xAA3080E0),84SPH_C32(0xD8F23A32), SPH_C32(0xCEF15E28), SPH_C32(0xDB086314),85SPH_C32(0x7F709DF7), SPH_C32(0xACD228A4), SPH_C32(0x704D6ECE),86SPH_C32(0xAA3EC95F), SPH_C32(0xE387C214), SPH_C32(0x3A6445FF),87SPH_C32(0x9CAB81C3), SPH_C32(0xC73D4B98), SPH_C32(0xD277AEBE),88SPH_C32(0xFD20151C), SPH_C32(0x00CB573E)89};9091static const sph_u32 IV256[] = {92SPH_C32(0xEA2BD4B4), SPH_C32(0xCCD6F29F), SPH_C32(0x63117E71),93SPH_C32(0x35481EAE), SPH_C32(0x22512D5B), SPH_C32(0xE5D94E63),94SPH_C32(0x7E624131), SPH_C32(0xF4CC12BE), SPH_C32(0xC2D0B696),95SPH_C32(0x42AF2070), SPH_C32(0xD0720C35), SPH_C32(0x3361DA8C),96SPH_C32(0x28CCECA4), SPH_C32(0x8EF8AD83), SPH_C32(0x4680AC00),97SPH_C32(0x40E5FBAB), SPH_C32(0xD89041C3), SPH_C32(0x6107FBD5),98SPH_C32(0x6C859D41), SPH_C32(0xF0B26679), SPH_C32(0x09392549),99SPH_C32(0x5FA25603), SPH_C32(0x65C892FD), SPH_C32(0x93CB6285),100SPH_C32(0x2AF2B5AE), SPH_C32(0x9E4B4E60), SPH_C32(0x774ABFDD),101SPH_C32(0x85254725), SPH_C32(0x15815AEB), SPH_C32(0x4AB6AAD6),102SPH_C32(0x9CDAF8AF), SPH_C32(0xD6032C0A)103};104105static const sph_u32 IV384[] = {106SPH_C32(0xE623087E), SPH_C32(0x04C00C87), SPH_C32(0x5EF46453),107SPH_C32(0x69524B13), SPH_C32(0x1A05C7A9), SPH_C32(0x3528DF88),108SPH_C32(0x6BDD01B5), SPH_C32(0x5057B792), SPH_C32(0x6AA7A922),109SPH_C32(0x649C7EEE), SPH_C32(0xF426309F), SPH_C32(0xCB629052),110SPH_C32(0xFC8E20ED), SPH_C32(0xB3482BAB), SPH_C32(0xF89E5E7E),111SPH_C32(0xD83D4DE4), SPH_C32(0x44BFC10D), SPH_C32(0x5FC1E63D),112SPH_C32(0x2104E6CB), SPH_C32(0x17958F7F), SPH_C32(0xDBEAEF70),113SPH_C32(0xB4B97E1E), SPH_C32(0x32C195F6), SPH_C32(0x6184A8E4),114SPH_C32(0x796C2543), SPH_C32(0x23DE176D), SPH_C32(0xD33BBAEC),115SPH_C32(0x0C12E5D2), SPH_C32(0x4EB95A7B), SPH_C32(0x2D18BA01),116SPH_C32(0x04EE475F), SPH_C32(0x1FC5F22E)117};118119static const sph_u32 IV512[] = {120SPH_C32(0x2AEA2A61), SPH_C32(0x50F494D4), SPH_C32(0x2D538B8B),121SPH_C32(0x4167D83E), SPH_C32(0x3FEE2313), SPH_C32(0xC701CF8C),122SPH_C32(0xCC39968E), SPH_C32(0x50AC5695), SPH_C32(0x4D42C787),123SPH_C32(0xA647A8B3), SPH_C32(0x97CF0BEF), SPH_C32(0x825B4537),124SPH_C32(0xEEF864D2), SPH_C32(0xF22090C4), SPH_C32(0xD0E5CD33),125SPH_C32(0xA23911AE), SPH_C32(0xFCD398D9), SPH_C32(0x148FE485),126SPH_C32(0x1B017BEF), SPH_C32(0xB6444532), SPH_C32(0x6A536159),127SPH_C32(0x2FF5781C), SPH_C32(0x91FA7934), SPH_C32(0x0DBADEA9),128SPH_C32(0xD65C8A2B), SPH_C32(0xA5A70E75), SPH_C32(0xB1C62456),129SPH_C32(0xBC796576), SPH_C32(0x1921C8F7), SPH_C32(0xE7989AF1),130SPH_C32(0x7795D246), SPH_C32(0xD43E3B44)131};132133#define T32 SPH_T32134#define ROTL32 SPH_ROTL32135136#if SPH_CUBEHASH_NOCOPY137138#define DECL_STATE139#define READ_STATE(cc)140#define WRITE_STATE(cc)141142#define x0 ((sc)->state[ 0])143#define x1 ((sc)->state[ 1])144#define x2 ((sc)->state[ 2])145#define x3 ((sc)->state[ 3])146#define x4 ((sc)->state[ 4])147#define x5 ((sc)->state[ 5])148#define x6 ((sc)->state[ 6])149#define x7 ((sc)->state[ 7])150#define x8 ((sc)->state[ 8])151#define x9 ((sc)->state[ 9])152#define xa ((sc)->state[10])153#define xb ((sc)->state[11])154#define xc ((sc)->state[12])155#define xd ((sc)->state[13])156#define xe ((sc)->state[14])157#define xf ((sc)->state[15])158#define xg ((sc)->state[16])159#define xh ((sc)->state[17])160#define xi ((sc)->state[18])161#define xj ((sc)->state[19])162#define xk ((sc)->state[20])163#define xl ((sc)->state[21])164#define xm ((sc)->state[22])165#define xn ((sc)->state[23])166#define xo ((sc)->state[24])167#define xp ((sc)->state[25])168#define xq ((sc)->state[26])169#define xr ((sc)->state[27])170#define xs ((sc)->state[28])171#define xt ((sc)->state[29])172#define xu ((sc)->state[30])173#define xv ((sc)->state[31])174175#else176177#define DECL_STATE \178sph_u32 x0, x1, x2, x3, x4, x5, x6, x7; \179sph_u32 x8, x9, xa, xb, xc, xd, xe, xf; \180sph_u32 xg, xh, xi, xj, xk, xl, xm, xn; \181sph_u32 xo, xp, xq, xr, xs, xt, xu, xv;182183#define READ_STATE(cc) do { \184x0 = (cc)->state[ 0]; \185x1 = (cc)->state[ 1]; \186x2 = (cc)->state[ 2]; \187x3 = (cc)->state[ 3]; \188x4 = (cc)->state[ 4]; \189x5 = (cc)->state[ 5]; \190x6 = (cc)->state[ 6]; \191x7 = (cc)->state[ 7]; \192x8 = (cc)->state[ 8]; \193x9 = (cc)->state[ 9]; \194xa = (cc)->state[10]; \195xb = (cc)->state[11]; \196xc = (cc)->state[12]; \197xd = (cc)->state[13]; \198xe = (cc)->state[14]; \199xf = (cc)->state[15]; \200xg = (cc)->state[16]; \201xh = (cc)->state[17]; \202xi = (cc)->state[18]; \203xj = (cc)->state[19]; \204xk = (cc)->state[20]; \205xl = (cc)->state[21]; \206xm = (cc)->state[22]; \207xn = (cc)->state[23]; \208xo = (cc)->state[24]; \209xp = (cc)->state[25]; \210xq = (cc)->state[26]; \211xr = (cc)->state[27]; \212xs = (cc)->state[28]; \213xt = (cc)->state[29]; \214xu = (cc)->state[30]; \215xv = (cc)->state[31]; \216} while (0)217218#define WRITE_STATE(cc) do { \219(cc)->state[ 0] = x0; \220(cc)->state[ 1] = x1; \221(cc)->state[ 2] = x2; \222(cc)->state[ 3] = x3; \223(cc)->state[ 4] = x4; \224(cc)->state[ 5] = x5; \225(cc)->state[ 6] = x6; \226(cc)->state[ 7] = x7; \227(cc)->state[ 8] = x8; \228(cc)->state[ 9] = x9; \229(cc)->state[10] = xa; \230(cc)->state[11] = xb; \231(cc)->state[12] = xc; \232(cc)->state[13] = xd; \233(cc)->state[14] = xe; \234(cc)->state[15] = xf; \235(cc)->state[16] = xg; \236(cc)->state[17] = xh; \237(cc)->state[18] = xi; \238(cc)->state[19] = xj; \239(cc)->state[20] = xk; \240(cc)->state[21] = xl; \241(cc)->state[22] = xm; \242(cc)->state[23] = xn; \243(cc)->state[24] = xo; \244(cc)->state[25] = xp; \245(cc)->state[26] = xq; \246(cc)->state[27] = xr; \247(cc)->state[28] = xs; \248(cc)->state[29] = xt; \249(cc)->state[30] = xu; \250(cc)->state[31] = xv; \251} while (0)252253#endif254255#define INPUT_BLOCK do { \256x0 ^= sph_dec32le_aligned(buf + 0); \257x1 ^= sph_dec32le_aligned(buf + 4); \258x2 ^= sph_dec32le_aligned(buf + 8); \259x3 ^= sph_dec32le_aligned(buf + 12); \260x4 ^= sph_dec32le_aligned(buf + 16); \261x5 ^= sph_dec32le_aligned(buf + 20); \262x6 ^= sph_dec32le_aligned(buf + 24); \263x7 ^= sph_dec32le_aligned(buf + 28); \264} while (0)265266#define ROUND_EVEN do { \267xg = T32(x0 + xg); \268x0 = ROTL32(x0, 7); \269xh = T32(x1 + xh); \270x1 = ROTL32(x1, 7); \271xi = T32(x2 + xi); \272x2 = ROTL32(x2, 7); \273xj = T32(x3 + xj); \274x3 = ROTL32(x3, 7); \275xk = T32(x4 + xk); \276x4 = ROTL32(x4, 7); \277xl = T32(x5 + xl); \278x5 = ROTL32(x5, 7); \279xm = T32(x6 + xm); \280x6 = ROTL32(x6, 7); \281xn = T32(x7 + xn); \282x7 = ROTL32(x7, 7); \283xo = T32(x8 + xo); \284x8 = ROTL32(x8, 7); \285xp = T32(x9 + xp); \286x9 = ROTL32(x9, 7); \287xq = T32(xa + xq); \288xa = ROTL32(xa, 7); \289xr = T32(xb + xr); \290xb = ROTL32(xb, 7); \291xs = T32(xc + xs); \292xc = ROTL32(xc, 7); \293xt = T32(xd + xt); \294xd = ROTL32(xd, 7); \295xu = T32(xe + xu); \296xe = ROTL32(xe, 7); \297xv = T32(xf + xv); \298xf = ROTL32(xf, 7); \299x8 ^= xg; \300x9 ^= xh; \301xa ^= xi; \302xb ^= xj; \303xc ^= xk; \304xd ^= xl; \305xe ^= xm; \306xf ^= xn; \307x0 ^= xo; \308x1 ^= xp; \309x2 ^= xq; \310x3 ^= xr; \311x4 ^= xs; \312x5 ^= xt; \313x6 ^= xu; \314x7 ^= xv; \315xi = T32(x8 + xi); \316x8 = ROTL32(x8, 11); \317xj = T32(x9 + xj); \318x9 = ROTL32(x9, 11); \319xg = T32(xa + xg); \320xa = ROTL32(xa, 11); \321xh = T32(xb + xh); \322xb = ROTL32(xb, 11); \323xm = T32(xc + xm); \324xc = ROTL32(xc, 11); \325xn = T32(xd + xn); \326xd = ROTL32(xd, 11); \327xk = T32(xe + xk); \328xe = ROTL32(xe, 11); \329xl = T32(xf + xl); \330xf = ROTL32(xf, 11); \331xq = T32(x0 + xq); \332x0 = ROTL32(x0, 11); \333xr = T32(x1 + xr); \334x1 = ROTL32(x1, 11); \335xo = T32(x2 + xo); \336x2 = ROTL32(x2, 11); \337xp = T32(x3 + xp); \338x3 = ROTL32(x3, 11); \339xu = T32(x4 + xu); \340x4 = ROTL32(x4, 11); \341xv = T32(x5 + xv); \342x5 = ROTL32(x5, 11); \343xs = T32(x6 + xs); \344x6 = ROTL32(x6, 11); \345xt = T32(x7 + xt); \346x7 = ROTL32(x7, 11); \347xc ^= xi; \348xd ^= xj; \349xe ^= xg; \350xf ^= xh; \351x8 ^= xm; \352x9 ^= xn; \353xa ^= xk; \354xb ^= xl; \355x4 ^= xq; \356x5 ^= xr; \357x6 ^= xo; \358x7 ^= xp; \359x0 ^= xu; \360x1 ^= xv; \361x2 ^= xs; \362x3 ^= xt; \363} while (0)364365#define ROUND_ODD do { \366xj = T32(xc + xj); \367xc = ROTL32(xc, 7); \368xi = T32(xd + xi); \369xd = ROTL32(xd, 7); \370xh = T32(xe + xh); \371xe = ROTL32(xe, 7); \372xg = T32(xf + xg); \373xf = ROTL32(xf, 7); \374xn = T32(x8 + xn); \375x8 = ROTL32(x8, 7); \376xm = T32(x9 + xm); \377x9 = ROTL32(x9, 7); \378xl = T32(xa + xl); \379xa = ROTL32(xa, 7); \380xk = T32(xb + xk); \381xb = ROTL32(xb, 7); \382xr = T32(x4 + xr); \383x4 = ROTL32(x4, 7); \384xq = T32(x5 + xq); \385x5 = ROTL32(x5, 7); \386xp = T32(x6 + xp); \387x6 = ROTL32(x6, 7); \388xo = T32(x7 + xo); \389x7 = ROTL32(x7, 7); \390xv = T32(x0 + xv); \391x0 = ROTL32(x0, 7); \392xu = T32(x1 + xu); \393x1 = ROTL32(x1, 7); \394xt = T32(x2 + xt); \395x2 = ROTL32(x2, 7); \396xs = T32(x3 + xs); \397x3 = ROTL32(x3, 7); \398x4 ^= xj; \399x5 ^= xi; \400x6 ^= xh; \401x7 ^= xg; \402x0 ^= xn; \403x1 ^= xm; \404x2 ^= xl; \405x3 ^= xk; \406xc ^= xr; \407xd ^= xq; \408xe ^= xp; \409xf ^= xo; \410x8 ^= xv; \411x9 ^= xu; \412xa ^= xt; \413xb ^= xs; \414xh = T32(x4 + xh); \415x4 = ROTL32(x4, 11); \416xg = T32(x5 + xg); \417x5 = ROTL32(x5, 11); \418xj = T32(x6 + xj); \419x6 = ROTL32(x6, 11); \420xi = T32(x7 + xi); \421x7 = ROTL32(x7, 11); \422xl = T32(x0 + xl); \423x0 = ROTL32(x0, 11); \424xk = T32(x1 + xk); \425x1 = ROTL32(x1, 11); \426xn = T32(x2 + xn); \427x2 = ROTL32(x2, 11); \428xm = T32(x3 + xm); \429x3 = ROTL32(x3, 11); \430xp = T32(xc + xp); \431xc = ROTL32(xc, 11); \432xo = T32(xd + xo); \433xd = ROTL32(xd, 11); \434xr = T32(xe + xr); \435xe = ROTL32(xe, 11); \436xq = T32(xf + xq); \437xf = ROTL32(xf, 11); \438xt = T32(x8 + xt); \439x8 = ROTL32(x8, 11); \440xs = T32(x9 + xs); \441x9 = ROTL32(x9, 11); \442xv = T32(xa + xv); \443xa = ROTL32(xa, 11); \444xu = T32(xb + xu); \445xb = ROTL32(xb, 11); \446x0 ^= xh; \447x1 ^= xg; \448x2 ^= xj; \449x3 ^= xi; \450x4 ^= xl; \451x5 ^= xk; \452x6 ^= xn; \453x7 ^= xm; \454x8 ^= xp; \455x9 ^= xo; \456xa ^= xr; \457xb ^= xq; \458xc ^= xt; \459xd ^= xs; \460xe ^= xv; \461xf ^= xu; \462} while (0)463464/*465* There is no need to unroll all 16 rounds. The word-swapping permutation466* is an involution, so we need to unroll an even number of rounds. On467* "big" systems, unrolling 4 rounds yields about 97% of the speed468* achieved with full unrolling; and it keeps the code more compact469* for small architectures.470*/471472#if SPH_CUBEHASH_UNROLL == 2473474#define SIXTEEN_ROUNDS do { \475int j; \476for (j = 0; j < 8; j ++) { \477ROUND_EVEN; \478ROUND_ODD; \479} \480} while (0)481482#elif SPH_CUBEHASH_UNROLL == 4483484#define SIXTEEN_ROUNDS do { \485int j; \486for (j = 0; j < 4; j ++) { \487ROUND_EVEN; \488ROUND_ODD; \489ROUND_EVEN; \490ROUND_ODD; \491} \492} while (0)493494#elif SPH_CUBEHASH_UNROLL == 8495496#define SIXTEEN_ROUNDS do { \497int j; \498for (j = 0; j < 2; j ++) { \499ROUND_EVEN; \500ROUND_ODD; \501ROUND_EVEN; \502ROUND_ODD; \503ROUND_EVEN; \504ROUND_ODD; \505ROUND_EVEN; \506ROUND_ODD; \507} \508} while (0)509510#else511512#define SIXTEEN_ROUNDS do { \513ROUND_EVEN; \514ROUND_ODD; \515ROUND_EVEN; \516ROUND_ODD; \517ROUND_EVEN; \518ROUND_ODD; \519ROUND_EVEN; \520ROUND_ODD; \521ROUND_EVEN; \522ROUND_ODD; \523ROUND_EVEN; \524ROUND_ODD; \525ROUND_EVEN; \526ROUND_ODD; \527ROUND_EVEN; \528ROUND_ODD; \529} while (0)530531#endif532533static void534cubehash_init(sph_cubehash_context *sc, const sph_u32 *iv)535{536memcpy(sc->state, iv, sizeof sc->state);537sc->ptr = 0;538}539540static void541cubehash_core(sph_cubehash_context *sc, const void *data, size_t len)542{543unsigned char *buf;544size_t ptr;545DECL_STATE546547buf = sc->buf;548ptr = sc->ptr;549if (len < (sizeof sc->buf) - ptr) {550memcpy(buf + ptr, data, len);551ptr += len;552sc->ptr = ptr;553return;554}555556READ_STATE(sc);557while (len > 0) {558size_t clen;559560clen = (sizeof sc->buf) - ptr;561if (clen > len)562clen = len;563memcpy(buf + ptr, data, clen);564ptr += clen;565data = (const unsigned char *)data + clen;566len -= clen;567if (ptr == sizeof sc->buf) {568INPUT_BLOCK;569SIXTEEN_ROUNDS;570ptr = 0;571}572}573WRITE_STATE(sc);574sc->ptr = ptr;575}576577static void578cubehash_close(sph_cubehash_context *sc, unsigned ub, unsigned n,579void *dst, size_t out_size_w32)580{581unsigned char *buf, *out;582size_t ptr;583unsigned z;584int i;585DECL_STATE586587buf = sc->buf;588ptr = sc->ptr;589z = 0x80 >> n;590buf[ptr ++] = ((ub & -z) | z) & 0xFF;591memset(buf + ptr, 0, (sizeof sc->buf) - ptr);592READ_STATE(sc);593INPUT_BLOCK;594for (i = 0; i < 11; i ++) {595SIXTEEN_ROUNDS;596if (i == 0)597xv ^= SPH_C32(1);598}599WRITE_STATE(sc);600out = dst;601for (z = 0; z < out_size_w32; z ++)602sph_enc32le(out + (z << 2), sc->state[z]);603}604605/* see sph_cubehash.h */606void607sph_cubehash224_init(void *cc)608{609cubehash_init(cc, IV224);610}611612/* see sph_cubehash.h */613void614sph_cubehash224(void *cc, const void *data, size_t len)615{616cubehash_core(cc, data, len);617}618619/* see sph_cubehash.h */620void621sph_cubehash224_close(void *cc, void *dst)622{623sph_cubehash224_addbits_and_close(cc, 0, 0, dst);624}625626/* see sph_cubehash.h */627void628sph_cubehash224_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst)629{630cubehash_close(cc, ub, n, dst, 7);631sph_cubehash224_init(cc);632}633634/* see sph_cubehash.h */635void636sph_cubehash256_init(void *cc)637{638cubehash_init(cc, IV256);639}640641/* see sph_cubehash.h */642void643sph_cubehash256(void *cc, const void *data, size_t len)644{645cubehash_core(cc, data, len);646}647648/* see sph_cubehash.h */649void650sph_cubehash256_close(void *cc, void *dst)651{652sph_cubehash256_addbits_and_close(cc, 0, 0, dst);653}654655/* see sph_cubehash.h */656void657sph_cubehash256_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst)658{659cubehash_close(cc, ub, n, dst, 8);660sph_cubehash256_init(cc);661}662663/* see sph_cubehash.h */664void665sph_cubehash384_init(void *cc)666{667cubehash_init(cc, IV384);668}669670/* see sph_cubehash.h */671void672sph_cubehash384(void *cc, const void *data, size_t len)673{674cubehash_core(cc, data, len);675}676677/* see sph_cubehash.h */678void679sph_cubehash384_close(void *cc, void *dst)680{681sph_cubehash384_addbits_and_close(cc, 0, 0, dst);682}683684/* see sph_cubehash.h */685void686sph_cubehash384_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst)687{688cubehash_close(cc, ub, n, dst, 12);689sph_cubehash384_init(cc);690}691692/* see sph_cubehash.h */693void694sph_cubehash512_init(void *cc)695{696cubehash_init(cc, IV512);697}698699/* see sph_cubehash.h */700void701sph_cubehash512(void *cc, const void *data, size_t len)702{703cubehash_core(cc, data, len);704}705706/* see sph_cubehash.h */707void708sph_cubehash512_close(void *cc, void *dst)709{710sph_cubehash512_addbits_and_close(cc, 0, 0, dst);711}712713/* see sph_cubehash.h */714void715sph_cubehash512_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst)716{717cubehash_close(cc, ub, n, dst, 16);718sph_cubehash512_init(cc);719}720#ifdef __cplusplus721}722#endif723724725