1*b468a9ffSAllan Jude /***********************************************************************
2*b468a9ffSAllan Jude **
3*b468a9ffSAllan Jude ** Debug output functions for Skein hashing.
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 ************************************************************************/
10*b468a9ffSAllan Jude #include <stdio.h>
11*b468a9ffSAllan Jude
12*b468a9ffSAllan Jude #ifdef SKEIN_DEBUG /* only instantiate this code if SKEIN_DEBUG is on */
13*b468a9ffSAllan Jude #include "skein.h"
14*b468a9ffSAllan Jude
15*b468a9ffSAllan Jude static const char INDENT[] = " "; /* how much to indent on new line */
16*b468a9ffSAllan Jude
17*b468a9ffSAllan Jude uint_t skein_DebugFlag = 0; /* off by default. Must be set externally */
18*b468a9ffSAllan Jude
Show64_step(size_t cnt,const u64b_t * X,size_t step)19*b468a9ffSAllan Jude static void Show64_step(size_t cnt,const u64b_t *X,size_t step)
20*b468a9ffSAllan Jude {
21*b468a9ffSAllan Jude size_t i,j;
22*b468a9ffSAllan Jude for (i=j=0;i < cnt;i++,j+=step)
23*b468a9ffSAllan Jude {
24*b468a9ffSAllan Jude if (i % 4 == 0) printf(INDENT);
25*b468a9ffSAllan Jude printf(" %08X.%08X ",(uint_32t)(X[j] >> 32),(uint_32t)X[j]);
26*b468a9ffSAllan Jude if (i % 4 == 3 || i==cnt-1) printf("\n");
27*b468a9ffSAllan Jude fflush(stdout);
28*b468a9ffSAllan Jude }
29*b468a9ffSAllan Jude }
30*b468a9ffSAllan Jude
31*b468a9ffSAllan Jude #define Show64(cnt,X) Show64_step(cnt,X,1)
32*b468a9ffSAllan Jude
Show64_flag(size_t cnt,const u64b_t * X)33*b468a9ffSAllan Jude static void Show64_flag(size_t cnt,const u64b_t *X)
34*b468a9ffSAllan Jude {
35*b468a9ffSAllan Jude size_t xptr = (size_t) X;
36*b468a9ffSAllan Jude size_t step = (xptr & 1) ? 2 : 1;
37*b468a9ffSAllan Jude if (step != 1)
38*b468a9ffSAllan Jude {
39*b468a9ffSAllan Jude X = (const u64b_t *) (xptr & ~1);
40*b468a9ffSAllan Jude }
41*b468a9ffSAllan Jude Show64_step(cnt,X,step);
42*b468a9ffSAllan Jude }
43*b468a9ffSAllan Jude
Show08(size_t cnt,const u08b_t * b)44*b468a9ffSAllan Jude static void Show08(size_t cnt,const u08b_t *b)
45*b468a9ffSAllan Jude {
46*b468a9ffSAllan Jude size_t i;
47*b468a9ffSAllan Jude for (i=0;i < cnt;i++)
48*b468a9ffSAllan Jude {
49*b468a9ffSAllan Jude if (i %16 == 0) printf(INDENT);
50*b468a9ffSAllan Jude else if (i % 4 == 0) printf(" ");
51*b468a9ffSAllan Jude printf(" %02X",b[i]);
52*b468a9ffSAllan Jude if (i %16 == 15 || i==cnt-1) printf("\n");
53*b468a9ffSAllan Jude fflush(stdout);
54*b468a9ffSAllan Jude }
55*b468a9ffSAllan Jude }
56*b468a9ffSAllan Jude
AlgoHeader(uint_t bits)57*b468a9ffSAllan Jude static const char *AlgoHeader(uint_t bits)
58*b468a9ffSAllan Jude {
59*b468a9ffSAllan Jude if (skein_DebugFlag & SKEIN_DEBUG_THREEFISH)
60*b468a9ffSAllan Jude switch (bits)
61*b468a9ffSAllan Jude {
62*b468a9ffSAllan Jude case 256: return ":Threefish-256: ";
63*b468a9ffSAllan Jude case 512: return ":Threefish-512: ";
64*b468a9ffSAllan Jude case 1024: return ":Threefish-1024:";
65*b468a9ffSAllan Jude }
66*b468a9ffSAllan Jude else
67*b468a9ffSAllan Jude switch (bits)
68*b468a9ffSAllan Jude {
69*b468a9ffSAllan Jude case 256: return ":Skein-256: ";
70*b468a9ffSAllan Jude case 512: return ":Skein-512: ";
71*b468a9ffSAllan Jude case 1024: return ":Skein-1024:";
72*b468a9ffSAllan Jude }
73*b468a9ffSAllan Jude return NULL;
74*b468a9ffSAllan Jude }
75*b468a9ffSAllan Jude
Skein_Show_Final(uint_t bits,const Skein_Ctxt_Hdr_t * h,size_t cnt,const u08b_t * outPtr)76*b468a9ffSAllan Jude void Skein_Show_Final(uint_t bits,const Skein_Ctxt_Hdr_t *h,size_t cnt,const u08b_t *outPtr)
77*b468a9ffSAllan Jude {
78*b468a9ffSAllan Jude if (skein_DebugFlag & SKEIN_DEBUG_CONFIG || ((h->T[1] & SKEIN_T1_BLK_TYPE_MASK) != SKEIN_T1_BLK_TYPE_CFG))
79*b468a9ffSAllan Jude if (skein_DebugFlag & SKEIN_DEBUG_FINAL)
80*b468a9ffSAllan Jude {
81*b468a9ffSAllan Jude printf("\n%s Final output=\n",AlgoHeader(bits));
82*b468a9ffSAllan Jude Show08(cnt,outPtr);
83*b468a9ffSAllan Jude printf(" ++++++++++\n");
84*b468a9ffSAllan Jude fflush(stdout);
85*b468a9ffSAllan Jude }
86*b468a9ffSAllan Jude }
87*b468a9ffSAllan Jude
88*b468a9ffSAllan Jude /* show state after a round (or "pseudo-round") */
Skein_Show_Round(uint_t bits,const Skein_Ctxt_Hdr_t * h,size_t r,const u64b_t * X)89*b468a9ffSAllan Jude void Skein_Show_Round(uint_t bits,const Skein_Ctxt_Hdr_t *h,size_t r,const u64b_t *X)
90*b468a9ffSAllan Jude {
91*b468a9ffSAllan Jude static uint_t injectNum=0; /* not multi-thread safe! */
92*b468a9ffSAllan Jude
93*b468a9ffSAllan Jude if (skein_DebugFlag & SKEIN_DEBUG_CONFIG || ((h->T[1] & SKEIN_T1_BLK_TYPE_MASK) != SKEIN_T1_BLK_TYPE_CFG))
94*b468a9ffSAllan Jude if (skein_DebugFlag)
95*b468a9ffSAllan Jude {
96*b468a9ffSAllan Jude if (r >= SKEIN_RND_SPECIAL)
97*b468a9ffSAllan Jude { /* a key injection (or feedforward) point */
98*b468a9ffSAllan Jude injectNum = (r == SKEIN_RND_KEY_INITIAL) ? 0 : injectNum+1;
99*b468a9ffSAllan Jude if ( skein_DebugFlag & SKEIN_DEBUG_INJECT ||
100*b468a9ffSAllan Jude ((skein_DebugFlag & SKEIN_DEBUG_FINAL) && r == SKEIN_RND_FEED_FWD))
101*b468a9ffSAllan Jude {
102*b468a9ffSAllan Jude printf("\n%s",AlgoHeader(bits));
103*b468a9ffSAllan Jude switch (r)
104*b468a9ffSAllan Jude {
105*b468a9ffSAllan Jude case SKEIN_RND_KEY_INITIAL:
106*b468a9ffSAllan Jude printf(" [state after initial key injection]");
107*b468a9ffSAllan Jude break;
108*b468a9ffSAllan Jude case SKEIN_RND_KEY_INJECT:
109*b468a9ffSAllan Jude printf(" [state after key injection #%02d]",injectNum);
110*b468a9ffSAllan Jude break;
111*b468a9ffSAllan Jude case SKEIN_RND_FEED_FWD:
112*b468a9ffSAllan Jude printf(" [state after plaintext feedforward]");
113*b468a9ffSAllan Jude injectNum = 0;
114*b468a9ffSAllan Jude break;
115*b468a9ffSAllan Jude }
116*b468a9ffSAllan Jude printf("=\n");
117*b468a9ffSAllan Jude Show64(bits/64,X);
118*b468a9ffSAllan Jude if (r== SKEIN_RND_FEED_FWD)
119*b468a9ffSAllan Jude printf(" ----------\n");
120*b468a9ffSAllan Jude }
121*b468a9ffSAllan Jude }
122*b468a9ffSAllan Jude else if (skein_DebugFlag & SKEIN_DEBUG_ROUNDS)
123*b468a9ffSAllan Jude {
124*b468a9ffSAllan Jude uint_t j;
125*b468a9ffSAllan Jude u64b_t p[SKEIN_MAX_STATE_WORDS];
126*b468a9ffSAllan Jude const u08b_t *perm;
127*b468a9ffSAllan Jude const static u08b_t PERM_256 [4][ 4] = { { 0,1,2,3 }, { 0,3,2,1 }, { 0,1,2,3 }, { 0,3,2,1 } };
128*b468a9ffSAllan Jude const static u08b_t PERM_512 [4][ 8] = { { 0,1,2,3,4,5,6,7 },
129*b468a9ffSAllan Jude { 2,1,4,7,6,5,0,3 },
130*b468a9ffSAllan Jude { 4,1,6,3,0,5,2,7 },
131*b468a9ffSAllan Jude { 6,1,0,7,2,5,4,3 }
132*b468a9ffSAllan Jude };
133*b468a9ffSAllan Jude const static u08b_t PERM_1024[4][16] = { { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 },
134*b468a9ffSAllan Jude { 0, 9, 2,13, 6,11, 4,15,10, 7,12, 3,14, 5, 8, 1 },
135*b468a9ffSAllan Jude { 0, 7, 2, 5, 4, 3, 6, 1,12,15,14,13, 8,11,10, 9 },
136*b468a9ffSAllan Jude { 0,15, 2,11, 6,13, 4, 9,14, 1, 8, 5,10, 3,12, 7 }
137*b468a9ffSAllan Jude };
138*b468a9ffSAllan Jude
139*b468a9ffSAllan Jude if ((skein_DebugFlag & SKEIN_DEBUG_PERMUTE) && (r & 3))
140*b468a9ffSAllan Jude {
141*b468a9ffSAllan Jude printf("\n%s [state after round %2d (permuted)]=\n",AlgoHeader(bits),(int)r);
142*b468a9ffSAllan Jude switch (bits)
143*b468a9ffSAllan Jude {
144*b468a9ffSAllan Jude case 256: perm = PERM_256 [r&3]; break;
145*b468a9ffSAllan Jude case 512: perm = PERM_512 [r&3]; break;
146*b468a9ffSAllan Jude default: perm = PERM_1024[r&3]; break;
147*b468a9ffSAllan Jude }
148*b468a9ffSAllan Jude for (j=0;j<bits/64;j++)
149*b468a9ffSAllan Jude p[j] = X[perm[j]];
150*b468a9ffSAllan Jude Show64(bits/64,p);
151*b468a9ffSAllan Jude }
152*b468a9ffSAllan Jude else
153*b468a9ffSAllan Jude {
154*b468a9ffSAllan Jude printf("\n%s [state after round %2d]=\n",AlgoHeader(bits),(int)r);
155*b468a9ffSAllan Jude Show64(bits/64,X);
156*b468a9ffSAllan Jude }
157*b468a9ffSAllan Jude }
158*b468a9ffSAllan Jude }
159*b468a9ffSAllan Jude }
160*b468a9ffSAllan Jude
161*b468a9ffSAllan Jude /* show state after a round (or "pseudo-round"), given a list of pointers */
Skein_Show_R_Ptr(uint_t bits,const Skein_Ctxt_Hdr_t * h,size_t r,const u64b_t * X_ptr[])162*b468a9ffSAllan Jude void Skein_Show_R_Ptr(uint_t bits,const Skein_Ctxt_Hdr_t *h,size_t r,const u64b_t *X_ptr[])
163*b468a9ffSAllan Jude {
164*b468a9ffSAllan Jude uint_t i;
165*b468a9ffSAllan Jude u64b_t X[SKEIN_MAX_STATE_WORDS];
166*b468a9ffSAllan Jude
167*b468a9ffSAllan Jude for (i=0;i<bits/64;i++) /* copy over the words */
168*b468a9ffSAllan Jude X[i] = X_ptr[i][0];
169*b468a9ffSAllan Jude Skein_Show_Round(bits,h,r,X);
170*b468a9ffSAllan Jude }
171*b468a9ffSAllan Jude
172*b468a9ffSAllan Jude
173*b468a9ffSAllan Jude /* show the state at the start of a block */
Skein_Show_Block(uint_t bits,const Skein_Ctxt_Hdr_t * h,const u64b_t * X,const u08b_t * blkPtr,const u64b_t * wPtr,const u64b_t * ksPtr,const u64b_t * tsPtr)174*b468a9ffSAllan Jude void Skein_Show_Block(uint_t bits,const Skein_Ctxt_Hdr_t *h,const u64b_t *X,const u08b_t *blkPtr,
175*b468a9ffSAllan Jude const u64b_t *wPtr, const u64b_t *ksPtr, const u64b_t *tsPtr)
176*b468a9ffSAllan Jude {
177*b468a9ffSAllan Jude uint_t n;
178*b468a9ffSAllan Jude if (skein_DebugFlag & SKEIN_DEBUG_CONFIG || ((h->T[1] & SKEIN_T1_BLK_TYPE_MASK) != SKEIN_T1_BLK_TYPE_CFG))
179*b468a9ffSAllan Jude if (skein_DebugFlag)
180*b468a9ffSAllan Jude {
181*b468a9ffSAllan Jude if (skein_DebugFlag & SKEIN_DEBUG_HDR)
182*b468a9ffSAllan Jude {
183*b468a9ffSAllan Jude printf("\n%s Block: outBits=%4d. T0=%06X.",AlgoHeader(bits),(uint_t) h->hashBitLen,(uint_t)h->T[0]);
184*b468a9ffSAllan Jude printf(" Type=");
185*b468a9ffSAllan Jude n = (uint_t) ((h->T[1] & SKEIN_T1_BLK_TYPE_MASK) >> SKEIN_T1_POS_BLK_TYPE);
186*b468a9ffSAllan Jude switch (n)
187*b468a9ffSAllan Jude {
188*b468a9ffSAllan Jude case SKEIN_BLK_TYPE_KEY: printf("KEY. "); break;
189*b468a9ffSAllan Jude case SKEIN_BLK_TYPE_CFG: printf("CFG. "); break;
190*b468a9ffSAllan Jude case SKEIN_BLK_TYPE_PERS: printf("PERS."); break;
191*b468a9ffSAllan Jude case SKEIN_BLK_TYPE_PK : printf("PK. "); break;
192*b468a9ffSAllan Jude case SKEIN_BLK_TYPE_KDF: printf("KDF. "); break;
193*b468a9ffSAllan Jude case SKEIN_BLK_TYPE_MSG: printf("MSG. "); break;
194*b468a9ffSAllan Jude case SKEIN_BLK_TYPE_OUT: printf("OUT. "); break;
195*b468a9ffSAllan Jude default: printf("0x%02X.",n); break;
196*b468a9ffSAllan Jude }
197*b468a9ffSAllan Jude printf(" Flags=");
198*b468a9ffSAllan Jude printf((h->T[1] & SKEIN_T1_FLAG_FIRST) ? " First":" ");
199*b468a9ffSAllan Jude printf((h->T[1] & SKEIN_T1_FLAG_FINAL) ? " Final":" ");
200*b468a9ffSAllan Jude printf((h->T[1] & SKEIN_T1_FLAG_BIT_PAD) ? " Pad" :" ");
201*b468a9ffSAllan Jude n = (uint_t) ((h->T[1] & SKEIN_T1_TREE_LVL_MASK) >> SKEIN_T1_POS_TREE_LVL);
202*b468a9ffSAllan Jude if (n)
203*b468a9ffSAllan Jude printf(" TreeLevel = %02X",n);
204*b468a9ffSAllan Jude printf("\n");
205*b468a9ffSAllan Jude fflush(stdout);
206*b468a9ffSAllan Jude }
207*b468a9ffSAllan Jude if (skein_DebugFlag & SKEIN_DEBUG_TWEAK)
208*b468a9ffSAllan Jude {
209*b468a9ffSAllan Jude printf(" Tweak:\n");
210*b468a9ffSAllan Jude Show64(2,h->T);
211*b468a9ffSAllan Jude }
212*b468a9ffSAllan Jude if (skein_DebugFlag & SKEIN_DEBUG_STATE)
213*b468a9ffSAllan Jude {
214*b468a9ffSAllan Jude printf(" %s words:\n",(skein_DebugFlag & SKEIN_DEBUG_THREEFISH)?"Key":"State");
215*b468a9ffSAllan Jude Show64(bits/64,X);
216*b468a9ffSAllan Jude }
217*b468a9ffSAllan Jude if (skein_DebugFlag & SKEIN_DEBUG_KEYSCHED)
218*b468a9ffSAllan Jude {
219*b468a9ffSAllan Jude printf(" Tweak schedule:\n");
220*b468a9ffSAllan Jude Show64_flag(3,tsPtr);
221*b468a9ffSAllan Jude printf(" Key schedule:\n");
222*b468a9ffSAllan Jude Show64_flag((bits/64)+1,ksPtr);
223*b468a9ffSAllan Jude }
224*b468a9ffSAllan Jude if (skein_DebugFlag & SKEIN_DEBUG_INPUT_64)
225*b468a9ffSAllan Jude {
226*b468a9ffSAllan Jude printf(" Input block (words):\n");
227*b468a9ffSAllan Jude Show64(bits/64,wPtr);
228*b468a9ffSAllan Jude }
229*b468a9ffSAllan Jude if (skein_DebugFlag & SKEIN_DEBUG_INPUT_08)
230*b468a9ffSAllan Jude {
231*b468a9ffSAllan Jude printf(" Input block (bytes):\n");
232*b468a9ffSAllan Jude Show08(bits/8,blkPtr);
233*b468a9ffSAllan Jude }
234*b468a9ffSAllan Jude }
235*b468a9ffSAllan Jude }
236*b468a9ffSAllan Jude
Skein_Show_Key(uint_t bits,const Skein_Ctxt_Hdr_t * h,const u08b_t * key,size_t keyBytes)237*b468a9ffSAllan Jude void Skein_Show_Key(uint_t bits,const Skein_Ctxt_Hdr_t *h,const u08b_t *key,size_t keyBytes)
238*b468a9ffSAllan Jude {
239*b468a9ffSAllan Jude if (keyBytes)
240*b468a9ffSAllan Jude if (skein_DebugFlag & SKEIN_DEBUG_CONFIG || ((h->T[1] & SKEIN_T1_BLK_TYPE_MASK) != SKEIN_T1_BLK_TYPE_CFG))
241*b468a9ffSAllan Jude if (skein_DebugFlag & SKEIN_DEBUG_KEY)
242*b468a9ffSAllan Jude {
243*b468a9ffSAllan Jude printf("\n%s MAC key = %4u bytes\n",AlgoHeader(bits),(unsigned) keyBytes);
244*b468a9ffSAllan Jude Show08(keyBytes,key);
245*b468a9ffSAllan Jude }
246*b468a9ffSAllan Jude }
247*b468a9ffSAllan Jude #endif
248