xref: /freebsd/sys/crypto/skein/skein_block.c (revision 685dc743dc3b5645e34836464128e1c0558b404b)
1*b468a9ffSAllan Jude /***********************************************************************
2*b468a9ffSAllan Jude **
3*b468a9ffSAllan Jude ** Implementation of the Skein block functions.
4*b468a9ffSAllan Jude **
5*b468a9ffSAllan Jude ** Source code author: Doug Whiting, 2008.
6*b468a9ffSAllan Jude **
7*b468a9ffSAllan Jude ** This algorithm and source code is released to the public domain.
8*b468a9ffSAllan Jude **
9*b468a9ffSAllan Jude ** Compile-time switches:
10*b468a9ffSAllan Jude **
11*b468a9ffSAllan Jude **  SKEIN_USE_ASM  -- set bits (256/512/1024) to select which
12*b468a9ffSAllan Jude **                    versions use ASM code for block processing
13*b468a9ffSAllan Jude **                    [default: use C for all block sizes]
14*b468a9ffSAllan Jude **
15*b468a9ffSAllan Jude ************************************************************************/
16*b468a9ffSAllan Jude 
17*b468a9ffSAllan Jude #include <sys/cdefs.h>
18*b468a9ffSAllan Jude #include <sys/endian.h>
19*b468a9ffSAllan Jude #include <sys/types.h>
20*b468a9ffSAllan Jude 
21*b468a9ffSAllan Jude #ifdef _KERNEL
22*b468a9ffSAllan Jude #include <sys/systm.h>
23*b468a9ffSAllan Jude #else
24*b468a9ffSAllan Jude #include <string.h>
25*b468a9ffSAllan Jude #endif
26*b468a9ffSAllan Jude 
27*b468a9ffSAllan Jude #include "skein.h"
28*b468a9ffSAllan Jude 
29*b468a9ffSAllan Jude #ifndef SKEIN_USE_ASM
30*b468a9ffSAllan Jude #define SKEIN_USE_ASM   (0)                     /* default is all C code (no ASM) */
31*b468a9ffSAllan Jude #endif
32*b468a9ffSAllan Jude 
33*b468a9ffSAllan Jude #ifndef SKEIN_LOOP
34*b468a9ffSAllan Jude #define SKEIN_LOOP 001                          /* default: unroll 256 and 512, but not 1024 */
35*b468a9ffSAllan Jude #endif
36*b468a9ffSAllan Jude 
37*b468a9ffSAllan Jude #define BLK_BITS        (WCNT*64)               /* some useful definitions for code here */
38*b468a9ffSAllan Jude #define KW_TWK_BASE     (0)
39*b468a9ffSAllan Jude #define KW_KEY_BASE     (3)
40*b468a9ffSAllan Jude #define ks              (kw + KW_KEY_BASE)
41*b468a9ffSAllan Jude #define ts              (kw + KW_TWK_BASE)
42*b468a9ffSAllan Jude 
43*b468a9ffSAllan Jude #ifdef SKEIN_DEBUG
44*b468a9ffSAllan Jude #define DebugSaveTweak(ctx) { ctx->h.T[0] = ts[0]; ctx->h.T[1] = ts[1]; }
45*b468a9ffSAllan Jude #else
46*b468a9ffSAllan Jude #define DebugSaveTweak(ctx)
47*b468a9ffSAllan Jude #endif
48*b468a9ffSAllan Jude 
49*b468a9ffSAllan Jude /*****************************************************************/
50*b468a9ffSAllan Jude /* functions to process blkCnt (nonzero) full block(s) of data. */
51*b468a9ffSAllan Jude void    Skein_256_Process_Block(Skein_256_Ctxt_t *ctx,const u08b_t *blkPtr,size_t blkCnt,size_t byteCntAdd);
52*b468a9ffSAllan Jude void    Skein_512_Process_Block(Skein_512_Ctxt_t *ctx,const u08b_t *blkPtr,size_t blkCnt,size_t byteCntAdd);
53*b468a9ffSAllan Jude void    Skein1024_Process_Block(Skein1024_Ctxt_t *ctx,const u08b_t *blkPtr,size_t blkCnt,size_t byteCntAdd);
54*b468a9ffSAllan Jude 
55*b468a9ffSAllan Jude /*****************************  Skein_256 ******************************/
56*b468a9ffSAllan Jude #if !(SKEIN_USE_ASM & 256)
Skein_256_Process_Block(Skein_256_Ctxt_t * ctx,const u08b_t * blkPtr,size_t blkCnt,size_t byteCntAdd)57*b468a9ffSAllan Jude void Skein_256_Process_Block(Skein_256_Ctxt_t *ctx,const u08b_t *blkPtr,size_t blkCnt,size_t byteCntAdd)
58*b468a9ffSAllan Jude     { /* do it in C */
59*b468a9ffSAllan Jude     enum
60*b468a9ffSAllan Jude         {
61*b468a9ffSAllan Jude         WCNT = SKEIN_256_STATE_WORDS
62*b468a9ffSAllan Jude         };
63*b468a9ffSAllan Jude #undef  RCNT
64*b468a9ffSAllan Jude #define RCNT  (SKEIN_256_ROUNDS_TOTAL/8)
65*b468a9ffSAllan Jude 
66*b468a9ffSAllan Jude #ifdef  SKEIN_LOOP                              /* configure how much to unroll the loop */
67*b468a9ffSAllan Jude #define SKEIN_UNROLL_256 (((SKEIN_LOOP)/100)%10)
68*b468a9ffSAllan Jude #else
69*b468a9ffSAllan Jude #define SKEIN_UNROLL_256 (0)
70*b468a9ffSAllan Jude #endif
71*b468a9ffSAllan Jude 
72*b468a9ffSAllan Jude #if SKEIN_UNROLL_256
73*b468a9ffSAllan Jude #if (RCNT % SKEIN_UNROLL_256)
74*b468a9ffSAllan Jude #error "Invalid SKEIN_UNROLL_256"               /* sanity check on unroll count */
75*b468a9ffSAllan Jude #endif
76*b468a9ffSAllan Jude     size_t  r;
77*b468a9ffSAllan Jude     u64b_t  kw[WCNT+4+RCNT*2];                  /* key schedule words : chaining vars + tweak + "rotation"*/
78*b468a9ffSAllan Jude #else
79*b468a9ffSAllan Jude     u64b_t  kw[WCNT+4];                         /* key schedule words : chaining vars + tweak */
80*b468a9ffSAllan Jude #endif
81*b468a9ffSAllan Jude     u64b_t  X0,X1,X2,X3;                        /* local copy of context vars, for speed */
82*b468a9ffSAllan Jude     u64b_t  w [WCNT];                           /* local copy of input block */
83*b468a9ffSAllan Jude #ifdef SKEIN_DEBUG
84*b468a9ffSAllan Jude     const u64b_t *Xptr[4];                      /* use for debugging (help compiler put Xn in registers) */
85*b468a9ffSAllan Jude     Xptr[0] = &X0;  Xptr[1] = &X1;  Xptr[2] = &X2;  Xptr[3] = &X3;
86*b468a9ffSAllan Jude #endif
87*b468a9ffSAllan Jude     Skein_assert(blkCnt != 0);                  /* never call with blkCnt == 0! */
88*b468a9ffSAllan Jude     ts[0] = ctx->h.T[0];
89*b468a9ffSAllan Jude     ts[1] = ctx->h.T[1];
90*b468a9ffSAllan Jude     do  {
91*b468a9ffSAllan Jude         /* this implementation only supports 2**64 input bytes (no carry out here) */
92*b468a9ffSAllan Jude         ts[0] += byteCntAdd;                    /* update processed length */
93*b468a9ffSAllan Jude 
94*b468a9ffSAllan Jude         /* precompute the key schedule for this block */
95*b468a9ffSAllan Jude         ks[0] = ctx->X[0];
96*b468a9ffSAllan Jude         ks[1] = ctx->X[1];
97*b468a9ffSAllan Jude         ks[2] = ctx->X[2];
98*b468a9ffSAllan Jude         ks[3] = ctx->X[3];
99*b468a9ffSAllan Jude         ks[4] = ks[0] ^ ks[1] ^ ks[2] ^ ks[3] ^ SKEIN_KS_PARITY;
100*b468a9ffSAllan Jude 
101*b468a9ffSAllan Jude         ts[2] = ts[0] ^ ts[1];
102*b468a9ffSAllan Jude 
103*b468a9ffSAllan Jude         Skein_Get64_LSB_First(w,blkPtr,WCNT);   /* get input block in little-endian format */
104*b468a9ffSAllan Jude         DebugSaveTweak(ctx);
105*b468a9ffSAllan Jude         Skein_Show_Block(BLK_BITS,&ctx->h,ctx->X,blkPtr,w,ks,ts);
106*b468a9ffSAllan Jude 
107*b468a9ffSAllan Jude         X0 = w[0] + ks[0];                      /* do the first full key injection */
108*b468a9ffSAllan Jude         X1 = w[1] + ks[1] + ts[0];
109*b468a9ffSAllan Jude         X2 = w[2] + ks[2] + ts[1];
110*b468a9ffSAllan Jude         X3 = w[3] + ks[3];
111*b468a9ffSAllan Jude 
112*b468a9ffSAllan Jude         Skein_Show_R_Ptr(BLK_BITS,&ctx->h,SKEIN_RND_KEY_INITIAL,Xptr);    /* show starting state values */
113*b468a9ffSAllan Jude 
114*b468a9ffSAllan Jude         blkPtr += SKEIN_256_BLOCK_BYTES;
115*b468a9ffSAllan Jude 
116*b468a9ffSAllan Jude         /* run the rounds */
117*b468a9ffSAllan Jude 
118*b468a9ffSAllan Jude #define Round256(p0,p1,p2,p3,ROT,rNum)                              \
119*b468a9ffSAllan Jude     X##p0 += X##p1; X##p1 = RotL_64(X##p1,ROT##_0); X##p1 ^= X##p0; \
120*b468a9ffSAllan Jude     X##p2 += X##p3; X##p3 = RotL_64(X##p3,ROT##_1); X##p3 ^= X##p2; \
121*b468a9ffSAllan Jude 
122*b468a9ffSAllan Jude #if SKEIN_UNROLL_256 == 0
123*b468a9ffSAllan Jude #define R256(p0,p1,p2,p3,ROT,rNum)           /* fully unrolled */   \
124*b468a9ffSAllan Jude     Round256(p0,p1,p2,p3,ROT,rNum)                                  \
125*b468a9ffSAllan Jude     Skein_Show_R_Ptr(BLK_BITS,&ctx->h,rNum,Xptr);
126*b468a9ffSAllan Jude 
127*b468a9ffSAllan Jude #define I256(R)                                                     \
128*b468a9ffSAllan Jude     X0   += ks[((R)+1) % 5];    /* inject the key schedule value */ \
129*b468a9ffSAllan Jude     X1   += ks[((R)+2) % 5] + ts[((R)+1) % 3];                      \
130*b468a9ffSAllan Jude     X2   += ks[((R)+3) % 5] + ts[((R)+2) % 3];                      \
131*b468a9ffSAllan Jude     X3   += ks[((R)+4) % 5] +     (R)+1;                            \
132*b468a9ffSAllan Jude     Skein_Show_R_Ptr(BLK_BITS,&ctx->h,SKEIN_RND_KEY_INJECT,Xptr);
133*b468a9ffSAllan Jude #else                                       /* looping version */
134*b468a9ffSAllan Jude #define R256(p0,p1,p2,p3,ROT,rNum)                                  \
135*b468a9ffSAllan Jude     Round256(p0,p1,p2,p3,ROT,rNum)                                  \
136*b468a9ffSAllan Jude     Skein_Show_R_Ptr(BLK_BITS,&ctx->h,4*(r-1)+rNum,Xptr);
137*b468a9ffSAllan Jude 
138*b468a9ffSAllan Jude #define I256(R)                                                     \
139*b468a9ffSAllan Jude     X0   += ks[r+(R)+0];        /* inject the key schedule value */ \
140*b468a9ffSAllan Jude     X1   += ks[r+(R)+1] + ts[r+(R)+0];                              \
141*b468a9ffSAllan Jude     X2   += ks[r+(R)+2] + ts[r+(R)+1];                              \
142*b468a9ffSAllan Jude     X3   += ks[r+(R)+3] +    r+(R)   ;                              \
143*b468a9ffSAllan Jude     ks[r + (R)+4    ]   = ks[r+(R)-1];     /* rotate key schedule */\
144*b468a9ffSAllan Jude     ts[r + (R)+2    ]   = ts[r+(R)-1];                              \
145*b468a9ffSAllan Jude     Skein_Show_R_Ptr(BLK_BITS,&ctx->h,SKEIN_RND_KEY_INJECT,Xptr);
146*b468a9ffSAllan Jude 
147*b468a9ffSAllan Jude     for (r=1;r < 2*RCNT;r+=2*SKEIN_UNROLL_256)  /* loop thru it */
148*b468a9ffSAllan Jude #endif
149*b468a9ffSAllan Jude         {
150*b468a9ffSAllan Jude #define R256_8_rounds(R)                  \
151*b468a9ffSAllan Jude         R256(0,1,2,3,R_256_0,8*(R) + 1);  \
152*b468a9ffSAllan Jude         R256(0,3,2,1,R_256_1,8*(R) + 2);  \
153*b468a9ffSAllan Jude         R256(0,1,2,3,R_256_2,8*(R) + 3);  \
154*b468a9ffSAllan Jude         R256(0,3,2,1,R_256_3,8*(R) + 4);  \
155*b468a9ffSAllan Jude         I256(2*(R));                      \
156*b468a9ffSAllan Jude         R256(0,1,2,3,R_256_4,8*(R) + 5);  \
157*b468a9ffSAllan Jude         R256(0,3,2,1,R_256_5,8*(R) + 6);  \
158*b468a9ffSAllan Jude         R256(0,1,2,3,R_256_6,8*(R) + 7);  \
159*b468a9ffSAllan Jude         R256(0,3,2,1,R_256_7,8*(R) + 8);  \
160*b468a9ffSAllan Jude         I256(2*(R)+1);
161*b468a9ffSAllan Jude 
162*b468a9ffSAllan Jude         R256_8_rounds( 0);
163*b468a9ffSAllan Jude 
164*b468a9ffSAllan Jude #define R256_Unroll_R(NN) ((SKEIN_UNROLL_256 == 0 && SKEIN_256_ROUNDS_TOTAL/8 > (NN)) || (SKEIN_UNROLL_256 > (NN)))
165*b468a9ffSAllan Jude 
166*b468a9ffSAllan Jude   #if   R256_Unroll_R( 1)
167*b468a9ffSAllan Jude         R256_8_rounds( 1);
168*b468a9ffSAllan Jude   #endif
169*b468a9ffSAllan Jude   #if   R256_Unroll_R( 2)
170*b468a9ffSAllan Jude         R256_8_rounds( 2);
171*b468a9ffSAllan Jude   #endif
172*b468a9ffSAllan Jude   #if   R256_Unroll_R( 3)
173*b468a9ffSAllan Jude         R256_8_rounds( 3);
174*b468a9ffSAllan Jude   #endif
175*b468a9ffSAllan Jude   #if   R256_Unroll_R( 4)
176*b468a9ffSAllan Jude         R256_8_rounds( 4);
177*b468a9ffSAllan Jude   #endif
178*b468a9ffSAllan Jude   #if   R256_Unroll_R( 5)
179*b468a9ffSAllan Jude         R256_8_rounds( 5);
180*b468a9ffSAllan Jude   #endif
181*b468a9ffSAllan Jude   #if   R256_Unroll_R( 6)
182*b468a9ffSAllan Jude         R256_8_rounds( 6);
183*b468a9ffSAllan Jude   #endif
184*b468a9ffSAllan Jude   #if   R256_Unroll_R( 7)
185*b468a9ffSAllan Jude         R256_8_rounds( 7);
186*b468a9ffSAllan Jude   #endif
187*b468a9ffSAllan Jude   #if   R256_Unroll_R( 8)
188*b468a9ffSAllan Jude         R256_8_rounds( 8);
189*b468a9ffSAllan Jude   #endif
190*b468a9ffSAllan Jude   #if   R256_Unroll_R( 9)
191*b468a9ffSAllan Jude         R256_8_rounds( 9);
192*b468a9ffSAllan Jude   #endif
193*b468a9ffSAllan Jude   #if   R256_Unroll_R(10)
194*b468a9ffSAllan Jude         R256_8_rounds(10);
195*b468a9ffSAllan Jude   #endif
196*b468a9ffSAllan Jude   #if   R256_Unroll_R(11)
197*b468a9ffSAllan Jude         R256_8_rounds(11);
198*b468a9ffSAllan Jude   #endif
199*b468a9ffSAllan Jude   #if   R256_Unroll_R(12)
200*b468a9ffSAllan Jude         R256_8_rounds(12);
201*b468a9ffSAllan Jude   #endif
202*b468a9ffSAllan Jude   #if   R256_Unroll_R(13)
203*b468a9ffSAllan Jude         R256_8_rounds(13);
204*b468a9ffSAllan Jude   #endif
205*b468a9ffSAllan Jude   #if   R256_Unroll_R(14)
206*b468a9ffSAllan Jude         R256_8_rounds(14);
207*b468a9ffSAllan Jude   #endif
208*b468a9ffSAllan Jude   #if  (SKEIN_UNROLL_256 > 14)
209*b468a9ffSAllan Jude #error  "need more unrolling in Skein_256_Process_Block"
210*b468a9ffSAllan Jude   #endif
211*b468a9ffSAllan Jude         }
212*b468a9ffSAllan Jude         /* do the final "feedforward" xor, update context chaining vars */
213*b468a9ffSAllan Jude         ctx->X[0] = X0 ^ w[0];
214*b468a9ffSAllan Jude         ctx->X[1] = X1 ^ w[1];
215*b468a9ffSAllan Jude         ctx->X[2] = X2 ^ w[2];
216*b468a9ffSAllan Jude         ctx->X[3] = X3 ^ w[3];
217*b468a9ffSAllan Jude 
218*b468a9ffSAllan Jude         Skein_Show_Round(BLK_BITS,&ctx->h,SKEIN_RND_FEED_FWD,ctx->X);
219*b468a9ffSAllan Jude 
220*b468a9ffSAllan Jude         ts[1] &= ~SKEIN_T1_FLAG_FIRST;
221*b468a9ffSAllan Jude         }
222*b468a9ffSAllan Jude     while (--blkCnt);
223*b468a9ffSAllan Jude     ctx->h.T[0] = ts[0];
224*b468a9ffSAllan Jude     ctx->h.T[1] = ts[1];
225*b468a9ffSAllan Jude     }
226*b468a9ffSAllan Jude 
227*b468a9ffSAllan Jude #if defined(SKEIN_CODE_SIZE) || defined(SKEIN_PERF)
Skein_256_Process_Block_CodeSize(void)228*b468a9ffSAllan Jude size_t Skein_256_Process_Block_CodeSize(void)
229*b468a9ffSAllan Jude     {
230*b468a9ffSAllan Jude     return ((u08b_t *) Skein_256_Process_Block_CodeSize) -
231*b468a9ffSAllan Jude            ((u08b_t *) Skein_256_Process_Block);
232*b468a9ffSAllan Jude     }
Skein_256_Unroll_Cnt(void)233*b468a9ffSAllan Jude uint_t Skein_256_Unroll_Cnt(void)
234*b468a9ffSAllan Jude     {
235*b468a9ffSAllan Jude     return SKEIN_UNROLL_256;
236*b468a9ffSAllan Jude     }
237*b468a9ffSAllan Jude #endif
238*b468a9ffSAllan Jude #endif
239*b468a9ffSAllan Jude 
240*b468a9ffSAllan Jude /*****************************  Skein_512 ******************************/
241*b468a9ffSAllan Jude #if !(SKEIN_USE_ASM & 512)
Skein_512_Process_Block(Skein_512_Ctxt_t * ctx,const u08b_t * blkPtr,size_t blkCnt,size_t byteCntAdd)242*b468a9ffSAllan Jude void Skein_512_Process_Block(Skein_512_Ctxt_t *ctx,const u08b_t *blkPtr,size_t blkCnt,size_t byteCntAdd)
243*b468a9ffSAllan Jude     { /* do it in C */
244*b468a9ffSAllan Jude     enum
245*b468a9ffSAllan Jude         {
246*b468a9ffSAllan Jude         WCNT = SKEIN_512_STATE_WORDS
247*b468a9ffSAllan Jude         };
248*b468a9ffSAllan Jude #undef  RCNT
249*b468a9ffSAllan Jude #define RCNT  (SKEIN_512_ROUNDS_TOTAL/8)
250*b468a9ffSAllan Jude 
251*b468a9ffSAllan Jude #ifdef  SKEIN_LOOP                              /* configure how much to unroll the loop */
252*b468a9ffSAllan Jude #define SKEIN_UNROLL_512 (((SKEIN_LOOP)/10)%10)
253*b468a9ffSAllan Jude #else
254*b468a9ffSAllan Jude #define SKEIN_UNROLL_512 (0)
255*b468a9ffSAllan Jude #endif
256*b468a9ffSAllan Jude 
257*b468a9ffSAllan Jude #if SKEIN_UNROLL_512
258*b468a9ffSAllan Jude #if (RCNT % SKEIN_UNROLL_512)
259*b468a9ffSAllan Jude #error "Invalid SKEIN_UNROLL_512"               /* sanity check on unroll count */
260*b468a9ffSAllan Jude #endif
261*b468a9ffSAllan Jude     size_t  r;
262*b468a9ffSAllan Jude     u64b_t  kw[WCNT+4+RCNT*2];                  /* key schedule words : chaining vars + tweak + "rotation"*/
263*b468a9ffSAllan Jude #else
264*b468a9ffSAllan Jude     u64b_t  kw[WCNT+4];                         /* key schedule words : chaining vars + tweak */
265*b468a9ffSAllan Jude #endif
266*b468a9ffSAllan Jude     u64b_t  X0,X1,X2,X3,X4,X5,X6,X7;            /* local copy of vars, for speed */
267*b468a9ffSAllan Jude     u64b_t  w [WCNT];                           /* local copy of input block */
268*b468a9ffSAllan Jude #ifdef SKEIN_DEBUG
269*b468a9ffSAllan Jude     const u64b_t *Xptr[8];                      /* use for debugging (help compiler put Xn in registers) */
270*b468a9ffSAllan Jude     Xptr[0] = &X0;  Xptr[1] = &X1;  Xptr[2] = &X2;  Xptr[3] = &X3;
271*b468a9ffSAllan Jude     Xptr[4] = &X4;  Xptr[5] = &X5;  Xptr[6] = &X6;  Xptr[7] = &X7;
272*b468a9ffSAllan Jude #endif
273*b468a9ffSAllan Jude 
274*b468a9ffSAllan Jude     Skein_assert(blkCnt != 0);                  /* never call with blkCnt == 0! */
275*b468a9ffSAllan Jude     ts[0] = ctx->h.T[0];
276*b468a9ffSAllan Jude     ts[1] = ctx->h.T[1];
277*b468a9ffSAllan Jude     do  {
278*b468a9ffSAllan Jude         /* this implementation only supports 2**64 input bytes (no carry out here) */
279*b468a9ffSAllan Jude         ts[0] += byteCntAdd;                    /* update processed length */
280*b468a9ffSAllan Jude 
281*b468a9ffSAllan Jude         /* precompute the key schedule for this block */
282*b468a9ffSAllan Jude         ks[0] = ctx->X[0];
283*b468a9ffSAllan Jude         ks[1] = ctx->X[1];
284*b468a9ffSAllan Jude         ks[2] = ctx->X[2];
285*b468a9ffSAllan Jude         ks[3] = ctx->X[3];
286*b468a9ffSAllan Jude         ks[4] = ctx->X[4];
287*b468a9ffSAllan Jude         ks[5] = ctx->X[5];
288*b468a9ffSAllan Jude         ks[6] = ctx->X[6];
289*b468a9ffSAllan Jude         ks[7] = ctx->X[7];
290*b468a9ffSAllan Jude         ks[8] = ks[0] ^ ks[1] ^ ks[2] ^ ks[3] ^
291*b468a9ffSAllan Jude                 ks[4] ^ ks[5] ^ ks[6] ^ ks[7] ^ SKEIN_KS_PARITY;
292*b468a9ffSAllan Jude 
293*b468a9ffSAllan Jude         ts[2] = ts[0] ^ ts[1];
294*b468a9ffSAllan Jude 
295*b468a9ffSAllan Jude         Skein_Get64_LSB_First(w,blkPtr,WCNT); /* get input block in little-endian format */
296*b468a9ffSAllan Jude         DebugSaveTweak(ctx);
297*b468a9ffSAllan Jude         Skein_Show_Block(BLK_BITS,&ctx->h,ctx->X,blkPtr,w,ks,ts);
298*b468a9ffSAllan Jude 
299*b468a9ffSAllan Jude         X0   = w[0] + ks[0];                    /* do the first full key injection */
300*b468a9ffSAllan Jude         X1   = w[1] + ks[1];
301*b468a9ffSAllan Jude         X2   = w[2] + ks[2];
302*b468a9ffSAllan Jude         X3   = w[3] + ks[3];
303*b468a9ffSAllan Jude         X4   = w[4] + ks[4];
304*b468a9ffSAllan Jude         X5   = w[5] + ks[5] + ts[0];
305*b468a9ffSAllan Jude         X6   = w[6] + ks[6] + ts[1];
306*b468a9ffSAllan Jude         X7   = w[7] + ks[7];
307*b468a9ffSAllan Jude 
308*b468a9ffSAllan Jude         blkPtr += SKEIN_512_BLOCK_BYTES;
309*b468a9ffSAllan Jude 
310*b468a9ffSAllan Jude         Skein_Show_R_Ptr(BLK_BITS,&ctx->h,SKEIN_RND_KEY_INITIAL,Xptr);
311*b468a9ffSAllan Jude         /* run the rounds */
312*b468a9ffSAllan Jude #define Round512(p0,p1,p2,p3,p4,p5,p6,p7,ROT,rNum)                  \
313*b468a9ffSAllan Jude     X##p0 += X##p1; X##p1 = RotL_64(X##p1,ROT##_0); X##p1 ^= X##p0; \
314*b468a9ffSAllan Jude     X##p2 += X##p3; X##p3 = RotL_64(X##p3,ROT##_1); X##p3 ^= X##p2; \
315*b468a9ffSAllan Jude     X##p4 += X##p5; X##p5 = RotL_64(X##p5,ROT##_2); X##p5 ^= X##p4; \
316*b468a9ffSAllan Jude     X##p6 += X##p7; X##p7 = RotL_64(X##p7,ROT##_3); X##p7 ^= X##p6; \
317*b468a9ffSAllan Jude 
318*b468a9ffSAllan Jude #if SKEIN_UNROLL_512 == 0
319*b468a9ffSAllan Jude #define R512(p0,p1,p2,p3,p4,p5,p6,p7,ROT,rNum)      /* unrolled */  \
320*b468a9ffSAllan Jude     Round512(p0,p1,p2,p3,p4,p5,p6,p7,ROT,rNum)                      \
321*b468a9ffSAllan Jude     Skein_Show_R_Ptr(BLK_BITS,&ctx->h,rNum,Xptr);
322*b468a9ffSAllan Jude 
323*b468a9ffSAllan Jude #define I512(R)                                                     \
324*b468a9ffSAllan Jude     X0   += ks[((R)+1) % 9];   /* inject the key schedule value */  \
325*b468a9ffSAllan Jude     X1   += ks[((R)+2) % 9];                                        \
326*b468a9ffSAllan Jude     X2   += ks[((R)+3) % 9];                                        \
327*b468a9ffSAllan Jude     X3   += ks[((R)+4) % 9];                                        \
328*b468a9ffSAllan Jude     X4   += ks[((R)+5) % 9];                                        \
329*b468a9ffSAllan Jude     X5   += ks[((R)+6) % 9] + ts[((R)+1) % 3];                      \
330*b468a9ffSAllan Jude     X6   += ks[((R)+7) % 9] + ts[((R)+2) % 3];                      \
331*b468a9ffSAllan Jude     X7   += ks[((R)+8) % 9] +     (R)+1;                            \
332*b468a9ffSAllan Jude     Skein_Show_R_Ptr(BLK_BITS,&ctx->h,SKEIN_RND_KEY_INJECT,Xptr);
333*b468a9ffSAllan Jude #else                                       /* looping version */
334*b468a9ffSAllan Jude #define R512(p0,p1,p2,p3,p4,p5,p6,p7,ROT,rNum)                      \
335*b468a9ffSAllan Jude     Round512(p0,p1,p2,p3,p4,p5,p6,p7,ROT,rNum)                      \
336*b468a9ffSAllan Jude     Skein_Show_R_Ptr(BLK_BITS,&ctx->h,4*(r-1)+rNum,Xptr);
337*b468a9ffSAllan Jude 
338*b468a9ffSAllan Jude #define I512(R)                                                     \
339*b468a9ffSAllan Jude     X0   += ks[r+(R)+0];        /* inject the key schedule value */ \
340*b468a9ffSAllan Jude     X1   += ks[r+(R)+1];                                            \
341*b468a9ffSAllan Jude     X2   += ks[r+(R)+2];                                            \
342*b468a9ffSAllan Jude     X3   += ks[r+(R)+3];                                            \
343*b468a9ffSAllan Jude     X4   += ks[r+(R)+4];                                            \
344*b468a9ffSAllan Jude     X5   += ks[r+(R)+5] + ts[r+(R)+0];                              \
345*b468a9ffSAllan Jude     X6   += ks[r+(R)+6] + ts[r+(R)+1];                              \
346*b468a9ffSAllan Jude     X7   += ks[r+(R)+7] +    r+(R)   ;                              \
347*b468a9ffSAllan Jude     ks[r +       (R)+8] = ks[r+(R)-1];  /* rotate key schedule */   \
348*b468a9ffSAllan Jude     ts[r +       (R)+2] = ts[r+(R)-1];                              \
349*b468a9ffSAllan Jude     Skein_Show_R_Ptr(BLK_BITS,&ctx->h,SKEIN_RND_KEY_INJECT,Xptr);
350*b468a9ffSAllan Jude 
351*b468a9ffSAllan Jude     for (r=1;r < 2*RCNT;r+=2*SKEIN_UNROLL_512)   /* loop thru it */
352*b468a9ffSAllan Jude #endif                         /* end of looped code definitions */
353*b468a9ffSAllan Jude         {
354*b468a9ffSAllan Jude #define R512_8_rounds(R)  /* do 8 full rounds */  \
355*b468a9ffSAllan Jude         R512(0,1,2,3,4,5,6,7,R_512_0,8*(R)+ 1);   \
356*b468a9ffSAllan Jude         R512(2,1,4,7,6,5,0,3,R_512_1,8*(R)+ 2);   \
357*b468a9ffSAllan Jude         R512(4,1,6,3,0,5,2,7,R_512_2,8*(R)+ 3);   \
358*b468a9ffSAllan Jude         R512(6,1,0,7,2,5,4,3,R_512_3,8*(R)+ 4);   \
359*b468a9ffSAllan Jude         I512(2*(R));                              \
360*b468a9ffSAllan Jude         R512(0,1,2,3,4,5,6,7,R_512_4,8*(R)+ 5);   \
361*b468a9ffSAllan Jude         R512(2,1,4,7,6,5,0,3,R_512_5,8*(R)+ 6);   \
362*b468a9ffSAllan Jude         R512(4,1,6,3,0,5,2,7,R_512_6,8*(R)+ 7);   \
363*b468a9ffSAllan Jude         R512(6,1,0,7,2,5,4,3,R_512_7,8*(R)+ 8);   \
364*b468a9ffSAllan Jude         I512(2*(R)+1);        /* and key injection */
365*b468a9ffSAllan Jude 
366*b468a9ffSAllan Jude         R512_8_rounds( 0);
367*b468a9ffSAllan Jude 
368*b468a9ffSAllan Jude #define R512_Unroll_R(NN) ((SKEIN_UNROLL_512 == 0 && SKEIN_512_ROUNDS_TOTAL/8 > (NN)) || (SKEIN_UNROLL_512 > (NN)))
369*b468a9ffSAllan Jude 
370*b468a9ffSAllan Jude   #if   R512_Unroll_R( 1)
371*b468a9ffSAllan Jude         R512_8_rounds( 1);
372*b468a9ffSAllan Jude   #endif
373*b468a9ffSAllan Jude   #if   R512_Unroll_R( 2)
374*b468a9ffSAllan Jude         R512_8_rounds( 2);
375*b468a9ffSAllan Jude   #endif
376*b468a9ffSAllan Jude   #if   R512_Unroll_R( 3)
377*b468a9ffSAllan Jude         R512_8_rounds( 3);
378*b468a9ffSAllan Jude   #endif
379*b468a9ffSAllan Jude   #if   R512_Unroll_R( 4)
380*b468a9ffSAllan Jude         R512_8_rounds( 4);
381*b468a9ffSAllan Jude   #endif
382*b468a9ffSAllan Jude   #if   R512_Unroll_R( 5)
383*b468a9ffSAllan Jude         R512_8_rounds( 5);
384*b468a9ffSAllan Jude   #endif
385*b468a9ffSAllan Jude   #if   R512_Unroll_R( 6)
386*b468a9ffSAllan Jude         R512_8_rounds( 6);
387*b468a9ffSAllan Jude   #endif
388*b468a9ffSAllan Jude   #if   R512_Unroll_R( 7)
389*b468a9ffSAllan Jude         R512_8_rounds( 7);
390*b468a9ffSAllan Jude   #endif
391*b468a9ffSAllan Jude   #if   R512_Unroll_R( 8)
392*b468a9ffSAllan Jude         R512_8_rounds( 8);
393*b468a9ffSAllan Jude   #endif
394*b468a9ffSAllan Jude   #if   R512_Unroll_R( 9)
395*b468a9ffSAllan Jude         R512_8_rounds( 9);
396*b468a9ffSAllan Jude   #endif
397*b468a9ffSAllan Jude   #if   R512_Unroll_R(10)
398*b468a9ffSAllan Jude         R512_8_rounds(10);
399*b468a9ffSAllan Jude   #endif
400*b468a9ffSAllan Jude   #if   R512_Unroll_R(11)
401*b468a9ffSAllan Jude         R512_8_rounds(11);
402*b468a9ffSAllan Jude   #endif
403*b468a9ffSAllan Jude   #if   R512_Unroll_R(12)
404*b468a9ffSAllan Jude         R512_8_rounds(12);
405*b468a9ffSAllan Jude   #endif
406*b468a9ffSAllan Jude   #if   R512_Unroll_R(13)
407*b468a9ffSAllan Jude         R512_8_rounds(13);
408*b468a9ffSAllan Jude   #endif
409*b468a9ffSAllan Jude   #if   R512_Unroll_R(14)
410*b468a9ffSAllan Jude         R512_8_rounds(14);
411*b468a9ffSAllan Jude   #endif
412*b468a9ffSAllan Jude   #if  (SKEIN_UNROLL_512 > 14)
413*b468a9ffSAllan Jude #error  "need more unrolling in Skein_512_Process_Block"
414*b468a9ffSAllan Jude   #endif
415*b468a9ffSAllan Jude         }
416*b468a9ffSAllan Jude 
417*b468a9ffSAllan Jude         /* do the final "feedforward" xor, update context chaining vars */
418*b468a9ffSAllan Jude         ctx->X[0] = X0 ^ w[0];
419*b468a9ffSAllan Jude         ctx->X[1] = X1 ^ w[1];
420*b468a9ffSAllan Jude         ctx->X[2] = X2 ^ w[2];
421*b468a9ffSAllan Jude         ctx->X[3] = X3 ^ w[3];
422*b468a9ffSAllan Jude         ctx->X[4] = X4 ^ w[4];
423*b468a9ffSAllan Jude         ctx->X[5] = X5 ^ w[5];
424*b468a9ffSAllan Jude         ctx->X[6] = X6 ^ w[6];
425*b468a9ffSAllan Jude         ctx->X[7] = X7 ^ w[7];
426*b468a9ffSAllan Jude         Skein_Show_Round(BLK_BITS,&ctx->h,SKEIN_RND_FEED_FWD,ctx->X);
427*b468a9ffSAllan Jude 
428*b468a9ffSAllan Jude         ts[1] &= ~SKEIN_T1_FLAG_FIRST;
429*b468a9ffSAllan Jude         }
430*b468a9ffSAllan Jude     while (--blkCnt);
431*b468a9ffSAllan Jude     ctx->h.T[0] = ts[0];
432*b468a9ffSAllan Jude     ctx->h.T[1] = ts[1];
433*b468a9ffSAllan Jude     }
434*b468a9ffSAllan Jude 
435*b468a9ffSAllan Jude #if defined(SKEIN_CODE_SIZE) || defined(SKEIN_PERF)
Skein_512_Process_Block_CodeSize(void)436*b468a9ffSAllan Jude size_t Skein_512_Process_Block_CodeSize(void)
437*b468a9ffSAllan Jude     {
438*b468a9ffSAllan Jude     return ((u08b_t *) Skein_512_Process_Block_CodeSize) -
439*b468a9ffSAllan Jude            ((u08b_t *) Skein_512_Process_Block);
440*b468a9ffSAllan Jude     }
Skein_512_Unroll_Cnt(void)441*b468a9ffSAllan Jude uint_t Skein_512_Unroll_Cnt(void)
442*b468a9ffSAllan Jude     {
443*b468a9ffSAllan Jude     return SKEIN_UNROLL_512;
444*b468a9ffSAllan Jude     }
445*b468a9ffSAllan Jude #endif
446*b468a9ffSAllan Jude #endif
447*b468a9ffSAllan Jude 
448*b468a9ffSAllan Jude /*****************************  Skein1024 ******************************/
449*b468a9ffSAllan Jude #if !(SKEIN_USE_ASM & 1024)
Skein1024_Process_Block(Skein1024_Ctxt_t * ctx,const u08b_t * blkPtr,size_t blkCnt,size_t byteCntAdd)450*b468a9ffSAllan Jude void Skein1024_Process_Block(Skein1024_Ctxt_t *ctx,const u08b_t *blkPtr,size_t blkCnt,size_t byteCntAdd)
451*b468a9ffSAllan Jude     { /* do it in C, always looping (unrolled is bigger AND slower!) */
452*b468a9ffSAllan Jude     enum
453*b468a9ffSAllan Jude         {
454*b468a9ffSAllan Jude         WCNT = SKEIN1024_STATE_WORDS
455*b468a9ffSAllan Jude         };
456*b468a9ffSAllan Jude #undef  RCNT
457*b468a9ffSAllan Jude #define RCNT  (SKEIN1024_ROUNDS_TOTAL/8)
458*b468a9ffSAllan Jude 
459*b468a9ffSAllan Jude #ifdef  SKEIN_LOOP                              /* configure how much to unroll the loop */
460*b468a9ffSAllan Jude #define SKEIN_UNROLL_1024 ((SKEIN_LOOP)%10)
461*b468a9ffSAllan Jude #else
462*b468a9ffSAllan Jude #define SKEIN_UNROLL_1024 (0)
463*b468a9ffSAllan Jude #endif
464*b468a9ffSAllan Jude 
465*b468a9ffSAllan Jude #if (SKEIN_UNROLL_1024 != 0)
466*b468a9ffSAllan Jude #if (RCNT % SKEIN_UNROLL_1024)
467*b468a9ffSAllan Jude #error "Invalid SKEIN_UNROLL_1024"              /* sanity check on unroll count */
468*b468a9ffSAllan Jude #endif
469*b468a9ffSAllan Jude     size_t  r;
470*b468a9ffSAllan Jude     u64b_t  kw[WCNT+4+RCNT*2];                  /* key schedule words : chaining vars + tweak + "rotation"*/
471*b468a9ffSAllan Jude #else
472*b468a9ffSAllan Jude     u64b_t  kw[WCNT+4];                         /* key schedule words : chaining vars + tweak */
473*b468a9ffSAllan Jude #endif
474*b468a9ffSAllan Jude 
475*b468a9ffSAllan Jude     u64b_t  X00,X01,X02,X03,X04,X05,X06,X07,    /* local copy of vars, for speed */
476*b468a9ffSAllan Jude             X08,X09,X10,X11,X12,X13,X14,X15;
477*b468a9ffSAllan Jude     u64b_t  w [WCNT];                           /* local copy of input block */
478*b468a9ffSAllan Jude #ifdef SKEIN_DEBUG
479*b468a9ffSAllan Jude     const u64b_t *Xptr[16];                     /* use for debugging (help compiler put Xn in registers) */
480*b468a9ffSAllan Jude     Xptr[ 0] = &X00;  Xptr[ 1] = &X01;  Xptr[ 2] = &X02;  Xptr[ 3] = &X03;
481*b468a9ffSAllan Jude     Xptr[ 4] = &X04;  Xptr[ 5] = &X05;  Xptr[ 6] = &X06;  Xptr[ 7] = &X07;
482*b468a9ffSAllan Jude     Xptr[ 8] = &X08;  Xptr[ 9] = &X09;  Xptr[10] = &X10;  Xptr[11] = &X11;
483*b468a9ffSAllan Jude     Xptr[12] = &X12;  Xptr[13] = &X13;  Xptr[14] = &X14;  Xptr[15] = &X15;
484*b468a9ffSAllan Jude #endif
485*b468a9ffSAllan Jude 
486*b468a9ffSAllan Jude     Skein_assert(blkCnt != 0);                  /* never call with blkCnt == 0! */
487*b468a9ffSAllan Jude     ts[0] = ctx->h.T[0];
488*b468a9ffSAllan Jude     ts[1] = ctx->h.T[1];
489*b468a9ffSAllan Jude     do  {
490*b468a9ffSAllan Jude         /* this implementation only supports 2**64 input bytes (no carry out here) */
491*b468a9ffSAllan Jude         ts[0] += byteCntAdd;                    /* update processed length */
492*b468a9ffSAllan Jude 
493*b468a9ffSAllan Jude         /* precompute the key schedule for this block */
494*b468a9ffSAllan Jude         ks[ 0] = ctx->X[ 0];
495*b468a9ffSAllan Jude         ks[ 1] = ctx->X[ 1];
496*b468a9ffSAllan Jude         ks[ 2] = ctx->X[ 2];
497*b468a9ffSAllan Jude         ks[ 3] = ctx->X[ 3];
498*b468a9ffSAllan Jude         ks[ 4] = ctx->X[ 4];
499*b468a9ffSAllan Jude         ks[ 5] = ctx->X[ 5];
500*b468a9ffSAllan Jude         ks[ 6] = ctx->X[ 6];
501*b468a9ffSAllan Jude         ks[ 7] = ctx->X[ 7];
502*b468a9ffSAllan Jude         ks[ 8] = ctx->X[ 8];
503*b468a9ffSAllan Jude         ks[ 9] = ctx->X[ 9];
504*b468a9ffSAllan Jude         ks[10] = ctx->X[10];
505*b468a9ffSAllan Jude         ks[11] = ctx->X[11];
506*b468a9ffSAllan Jude         ks[12] = ctx->X[12];
507*b468a9ffSAllan Jude         ks[13] = ctx->X[13];
508*b468a9ffSAllan Jude         ks[14] = ctx->X[14];
509*b468a9ffSAllan Jude         ks[15] = ctx->X[15];
510*b468a9ffSAllan Jude         ks[16] = ks[ 0] ^ ks[ 1] ^ ks[ 2] ^ ks[ 3] ^
511*b468a9ffSAllan Jude                  ks[ 4] ^ ks[ 5] ^ ks[ 6] ^ ks[ 7] ^
512*b468a9ffSAllan Jude                  ks[ 8] ^ ks[ 9] ^ ks[10] ^ ks[11] ^
513*b468a9ffSAllan Jude                  ks[12] ^ ks[13] ^ ks[14] ^ ks[15] ^ SKEIN_KS_PARITY;
514*b468a9ffSAllan Jude 
515*b468a9ffSAllan Jude         ts[2]  = ts[0] ^ ts[1];
516*b468a9ffSAllan Jude 
517*b468a9ffSAllan Jude         Skein_Get64_LSB_First(w,blkPtr,WCNT); /* get input block in little-endian format */
518*b468a9ffSAllan Jude         DebugSaveTweak(ctx);
519*b468a9ffSAllan Jude         Skein_Show_Block(BLK_BITS,&ctx->h,ctx->X,blkPtr,w,ks,ts);
520*b468a9ffSAllan Jude 
521*b468a9ffSAllan Jude         X00    = w[ 0] + ks[ 0];                 /* do the first full key injection */
522*b468a9ffSAllan Jude         X01    = w[ 1] + ks[ 1];
523*b468a9ffSAllan Jude         X02    = w[ 2] + ks[ 2];
524*b468a9ffSAllan Jude         X03    = w[ 3] + ks[ 3];
525*b468a9ffSAllan Jude         X04    = w[ 4] + ks[ 4];
526*b468a9ffSAllan Jude         X05    = w[ 5] + ks[ 5];
527*b468a9ffSAllan Jude         X06    = w[ 6] + ks[ 6];
528*b468a9ffSAllan Jude         X07    = w[ 7] + ks[ 7];
529*b468a9ffSAllan Jude         X08    = w[ 8] + ks[ 8];
530*b468a9ffSAllan Jude         X09    = w[ 9] + ks[ 9];
531*b468a9ffSAllan Jude         X10    = w[10] + ks[10];
532*b468a9ffSAllan Jude         X11    = w[11] + ks[11];
533*b468a9ffSAllan Jude         X12    = w[12] + ks[12];
534*b468a9ffSAllan Jude         X13    = w[13] + ks[13] + ts[0];
535*b468a9ffSAllan Jude         X14    = w[14] + ks[14] + ts[1];
536*b468a9ffSAllan Jude         X15    = w[15] + ks[15];
537*b468a9ffSAllan Jude 
538*b468a9ffSAllan Jude         Skein_Show_R_Ptr(BLK_BITS,&ctx->h,SKEIN_RND_KEY_INITIAL,Xptr);
539*b468a9ffSAllan Jude 
540*b468a9ffSAllan Jude #define Round1024(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,pA,pB,pC,pD,pE,pF,ROT,rNum) \
541*b468a9ffSAllan Jude     X##p0 += X##p1; X##p1 = RotL_64(X##p1,ROT##_0); X##p1 ^= X##p0;   \
542*b468a9ffSAllan Jude     X##p2 += X##p3; X##p3 = RotL_64(X##p3,ROT##_1); X##p3 ^= X##p2;   \
543*b468a9ffSAllan Jude     X##p4 += X##p5; X##p5 = RotL_64(X##p5,ROT##_2); X##p5 ^= X##p4;   \
544*b468a9ffSAllan Jude     X##p6 += X##p7; X##p7 = RotL_64(X##p7,ROT##_3); X##p7 ^= X##p6;   \
545*b468a9ffSAllan Jude     X##p8 += X##p9; X##p9 = RotL_64(X##p9,ROT##_4); X##p9 ^= X##p8;   \
546*b468a9ffSAllan Jude     X##pA += X##pB; X##pB = RotL_64(X##pB,ROT##_5); X##pB ^= X##pA;   \
547*b468a9ffSAllan Jude     X##pC += X##pD; X##pD = RotL_64(X##pD,ROT##_6); X##pD ^= X##pC;   \
548*b468a9ffSAllan Jude     X##pE += X##pF; X##pF = RotL_64(X##pF,ROT##_7); X##pF ^= X##pE;   \
549*b468a9ffSAllan Jude 
550*b468a9ffSAllan Jude #if SKEIN_UNROLL_1024 == 0
551*b468a9ffSAllan Jude #define R1024(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,pA,pB,pC,pD,pE,pF,ROT,rn) \
552*b468a9ffSAllan Jude     Round1024(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,pA,pB,pC,pD,pE,pF,ROT,rn) \
553*b468a9ffSAllan Jude     Skein_Show_R_Ptr(BLK_BITS,&ctx->h,rn,Xptr);
554*b468a9ffSAllan Jude 
555*b468a9ffSAllan Jude #define I1024(R)                                                      \
556*b468a9ffSAllan Jude     X00   += ks[((R)+ 1) % 17]; /* inject the key schedule value */   \
557*b468a9ffSAllan Jude     X01   += ks[((R)+ 2) % 17];                                       \
558*b468a9ffSAllan Jude     X02   += ks[((R)+ 3) % 17];                                       \
559*b468a9ffSAllan Jude     X03   += ks[((R)+ 4) % 17];                                       \
560*b468a9ffSAllan Jude     X04   += ks[((R)+ 5) % 17];                                       \
561*b468a9ffSAllan Jude     X05   += ks[((R)+ 6) % 17];                                       \
562*b468a9ffSAllan Jude     X06   += ks[((R)+ 7) % 17];                                       \
563*b468a9ffSAllan Jude     X07   += ks[((R)+ 8) % 17];                                       \
564*b468a9ffSAllan Jude     X08   += ks[((R)+ 9) % 17];                                       \
565*b468a9ffSAllan Jude     X09   += ks[((R)+10) % 17];                                       \
566*b468a9ffSAllan Jude     X10   += ks[((R)+11) % 17];                                       \
567*b468a9ffSAllan Jude     X11   += ks[((R)+12) % 17];                                       \
568*b468a9ffSAllan Jude     X12   += ks[((R)+13) % 17];                                       \
569*b468a9ffSAllan Jude     X13   += ks[((R)+14) % 17] + ts[((R)+1) % 3];                     \
570*b468a9ffSAllan Jude     X14   += ks[((R)+15) % 17] + ts[((R)+2) % 3];                     \
571*b468a9ffSAllan Jude     X15   += ks[((R)+16) % 17] +     (R)+1;                           \
572*b468a9ffSAllan Jude     Skein_Show_R_Ptr(BLK_BITS,&ctx->h,SKEIN_RND_KEY_INJECT,Xptr);
573*b468a9ffSAllan Jude #else                                       /* looping version */
574*b468a9ffSAllan Jude #define R1024(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,pA,pB,pC,pD,pE,pF,ROT,rn) \
575*b468a9ffSAllan Jude     Round1024(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,pA,pB,pC,pD,pE,pF,ROT,rn) \
576*b468a9ffSAllan Jude     Skein_Show_R_Ptr(BLK_BITS,&ctx->h,4*(r-1)+rn,Xptr);
577*b468a9ffSAllan Jude 
578*b468a9ffSAllan Jude #define I1024(R)                                                      \
579*b468a9ffSAllan Jude     X00   += ks[r+(R)+ 0];    /* inject the key schedule value */     \
580*b468a9ffSAllan Jude     X01   += ks[r+(R)+ 1];                                            \
581*b468a9ffSAllan Jude     X02   += ks[r+(R)+ 2];                                            \
582*b468a9ffSAllan Jude     X03   += ks[r+(R)+ 3];                                            \
583*b468a9ffSAllan Jude     X04   += ks[r+(R)+ 4];                                            \
584*b468a9ffSAllan Jude     X05   += ks[r+(R)+ 5];                                            \
585*b468a9ffSAllan Jude     X06   += ks[r+(R)+ 6];                                            \
586*b468a9ffSAllan Jude     X07   += ks[r+(R)+ 7];                                            \
587*b468a9ffSAllan Jude     X08   += ks[r+(R)+ 8];                                            \
588*b468a9ffSAllan Jude     X09   += ks[r+(R)+ 9];                                            \
589*b468a9ffSAllan Jude     X10   += ks[r+(R)+10];                                            \
590*b468a9ffSAllan Jude     X11   += ks[r+(R)+11];                                            \
591*b468a9ffSAllan Jude     X12   += ks[r+(R)+12];                                            \
592*b468a9ffSAllan Jude     X13   += ks[r+(R)+13] + ts[r+(R)+0];                              \
593*b468a9ffSAllan Jude     X14   += ks[r+(R)+14] + ts[r+(R)+1];                              \
594*b468a9ffSAllan Jude     X15   += ks[r+(R)+15] +    r+(R)   ;                              \
595*b468a9ffSAllan Jude     ks[r  +       (R)+16] = ks[r+(R)-1];  /* rotate key schedule */   \
596*b468a9ffSAllan Jude     ts[r  +       (R)+ 2] = ts[r+(R)-1];                              \
597*b468a9ffSAllan Jude     Skein_Show_R_Ptr(BLK_BITS,&ctx->h,SKEIN_RND_KEY_INJECT,Xptr);
598*b468a9ffSAllan Jude 
599*b468a9ffSAllan Jude     for (r=1;r <= 2*RCNT;r+=2*SKEIN_UNROLL_1024)    /* loop thru it */
600*b468a9ffSAllan Jude #endif
601*b468a9ffSAllan Jude         {
602*b468a9ffSAllan Jude #define R1024_8_rounds(R)    /* do 8 full rounds */                               \
603*b468a9ffSAllan Jude         R1024(00,01,02,03,04,05,06,07,08,09,10,11,12,13,14,15,R1024_0,8*(R) + 1); \
604*b468a9ffSAllan Jude         R1024(00,09,02,13,06,11,04,15,10,07,12,03,14,05,08,01,R1024_1,8*(R) + 2); \
605*b468a9ffSAllan Jude         R1024(00,07,02,05,04,03,06,01,12,15,14,13,08,11,10,09,R1024_2,8*(R) + 3); \
606*b468a9ffSAllan Jude         R1024(00,15,02,11,06,13,04,09,14,01,08,05,10,03,12,07,R1024_3,8*(R) + 4); \
607*b468a9ffSAllan Jude         I1024(2*(R));                                                             \
608*b468a9ffSAllan Jude         R1024(00,01,02,03,04,05,06,07,08,09,10,11,12,13,14,15,R1024_4,8*(R) + 5); \
609*b468a9ffSAllan Jude         R1024(00,09,02,13,06,11,04,15,10,07,12,03,14,05,08,01,R1024_5,8*(R) + 6); \
610*b468a9ffSAllan Jude         R1024(00,07,02,05,04,03,06,01,12,15,14,13,08,11,10,09,R1024_6,8*(R) + 7); \
611*b468a9ffSAllan Jude         R1024(00,15,02,11,06,13,04,09,14,01,08,05,10,03,12,07,R1024_7,8*(R) + 8); \
612*b468a9ffSAllan Jude         I1024(2*(R)+1);
613*b468a9ffSAllan Jude 
614*b468a9ffSAllan Jude         R1024_8_rounds( 0);
615*b468a9ffSAllan Jude 
616*b468a9ffSAllan Jude #define R1024_Unroll_R(NN) ((SKEIN_UNROLL_1024 == 0 && SKEIN1024_ROUNDS_TOTAL/8 > (NN)) || (SKEIN_UNROLL_1024 > (NN)))
617*b468a9ffSAllan Jude 
618*b468a9ffSAllan Jude   #if   R1024_Unroll_R( 1)
619*b468a9ffSAllan Jude         R1024_8_rounds( 1);
620*b468a9ffSAllan Jude   #endif
621*b468a9ffSAllan Jude   #if   R1024_Unroll_R( 2)
622*b468a9ffSAllan Jude         R1024_8_rounds( 2);
623*b468a9ffSAllan Jude   #endif
624*b468a9ffSAllan Jude   #if   R1024_Unroll_R( 3)
625*b468a9ffSAllan Jude         R1024_8_rounds( 3);
626*b468a9ffSAllan Jude   #endif
627*b468a9ffSAllan Jude   #if   R1024_Unroll_R( 4)
628*b468a9ffSAllan Jude         R1024_8_rounds( 4);
629*b468a9ffSAllan Jude   #endif
630*b468a9ffSAllan Jude   #if   R1024_Unroll_R( 5)
631*b468a9ffSAllan Jude         R1024_8_rounds( 5);
632*b468a9ffSAllan Jude   #endif
633*b468a9ffSAllan Jude   #if   R1024_Unroll_R( 6)
634*b468a9ffSAllan Jude         R1024_8_rounds( 6);
635*b468a9ffSAllan Jude   #endif
636*b468a9ffSAllan Jude   #if   R1024_Unroll_R( 7)
637*b468a9ffSAllan Jude         R1024_8_rounds( 7);
638*b468a9ffSAllan Jude   #endif
639*b468a9ffSAllan Jude   #if   R1024_Unroll_R( 8)
640*b468a9ffSAllan Jude         R1024_8_rounds( 8);
641*b468a9ffSAllan Jude   #endif
642*b468a9ffSAllan Jude   #if   R1024_Unroll_R( 9)
643*b468a9ffSAllan Jude         R1024_8_rounds( 9);
644*b468a9ffSAllan Jude   #endif
645*b468a9ffSAllan Jude   #if   R1024_Unroll_R(10)
646*b468a9ffSAllan Jude         R1024_8_rounds(10);
647*b468a9ffSAllan Jude   #endif
648*b468a9ffSAllan Jude   #if   R1024_Unroll_R(11)
649*b468a9ffSAllan Jude         R1024_8_rounds(11);
650*b468a9ffSAllan Jude   #endif
651*b468a9ffSAllan Jude   #if   R1024_Unroll_R(12)
652*b468a9ffSAllan Jude         R1024_8_rounds(12);
653*b468a9ffSAllan Jude   #endif
654*b468a9ffSAllan Jude   #if   R1024_Unroll_R(13)
655*b468a9ffSAllan Jude         R1024_8_rounds(13);
656*b468a9ffSAllan Jude   #endif
657*b468a9ffSAllan Jude   #if   R1024_Unroll_R(14)
658*b468a9ffSAllan Jude         R1024_8_rounds(14);
659*b468a9ffSAllan Jude   #endif
660*b468a9ffSAllan Jude   #if  (SKEIN_UNROLL_1024 > 14)
661*b468a9ffSAllan Jude #error  "need more unrolling in Skein_1024_Process_Block"
662*b468a9ffSAllan Jude   #endif
663*b468a9ffSAllan Jude         }
664*b468a9ffSAllan Jude         /* do the final "feedforward" xor, update context chaining vars */
665*b468a9ffSAllan Jude 
666*b468a9ffSAllan Jude         ctx->X[ 0] = X00 ^ w[ 0];
667*b468a9ffSAllan Jude         ctx->X[ 1] = X01 ^ w[ 1];
668*b468a9ffSAllan Jude         ctx->X[ 2] = X02 ^ w[ 2];
669*b468a9ffSAllan Jude         ctx->X[ 3] = X03 ^ w[ 3];
670*b468a9ffSAllan Jude         ctx->X[ 4] = X04 ^ w[ 4];
671*b468a9ffSAllan Jude         ctx->X[ 5] = X05 ^ w[ 5];
672*b468a9ffSAllan Jude         ctx->X[ 6] = X06 ^ w[ 6];
673*b468a9ffSAllan Jude         ctx->X[ 7] = X07 ^ w[ 7];
674*b468a9ffSAllan Jude         ctx->X[ 8] = X08 ^ w[ 8];
675*b468a9ffSAllan Jude         ctx->X[ 9] = X09 ^ w[ 9];
676*b468a9ffSAllan Jude         ctx->X[10] = X10 ^ w[10];
677*b468a9ffSAllan Jude         ctx->X[11] = X11 ^ w[11];
678*b468a9ffSAllan Jude         ctx->X[12] = X12 ^ w[12];
679*b468a9ffSAllan Jude         ctx->X[13] = X13 ^ w[13];
680*b468a9ffSAllan Jude         ctx->X[14] = X14 ^ w[14];
681*b468a9ffSAllan Jude         ctx->X[15] = X15 ^ w[15];
682*b468a9ffSAllan Jude 
683*b468a9ffSAllan Jude         Skein_Show_Round(BLK_BITS,&ctx->h,SKEIN_RND_FEED_FWD,ctx->X);
684*b468a9ffSAllan Jude 
685*b468a9ffSAllan Jude         ts[1] &= ~SKEIN_T1_FLAG_FIRST;
686*b468a9ffSAllan Jude         blkPtr += SKEIN1024_BLOCK_BYTES;
687*b468a9ffSAllan Jude         }
688*b468a9ffSAllan Jude     while (--blkCnt);
689*b468a9ffSAllan Jude     ctx->h.T[0] = ts[0];
690*b468a9ffSAllan Jude     ctx->h.T[1] = ts[1];
691*b468a9ffSAllan Jude     }
692*b468a9ffSAllan Jude 
693*b468a9ffSAllan Jude #if defined(SKEIN_CODE_SIZE) || defined(SKEIN_PERF)
Skein1024_Process_Block_CodeSize(void)694*b468a9ffSAllan Jude size_t Skein1024_Process_Block_CodeSize(void)
695*b468a9ffSAllan Jude     {
696*b468a9ffSAllan Jude     return ((u08b_t *) Skein1024_Process_Block_CodeSize) -
697*b468a9ffSAllan Jude            ((u08b_t *) Skein1024_Process_Block);
698*b468a9ffSAllan Jude     }
Skein1024_Unroll_Cnt(void)699*b468a9ffSAllan Jude uint_t Skein1024_Unroll_Cnt(void)
700*b468a9ffSAllan Jude     {
701*b468a9ffSAllan Jude     return SKEIN_UNROLL_1024;
702*b468a9ffSAllan Jude     }
703*b468a9ffSAllan Jude #endif
704*b468a9ffSAllan Jude #endif
705