1 /***********************************************************************
3 ** Debug output functions for Skein hashing.
5 ** Source code author: Doug Whiting, 2008.
7 ** This algorithm and source code is released to the public domain.
9 ************************************************************************/
12 #ifdef SKEIN_DEBUG /* only instantiate this code if SKEIN_DEBUG is on */
15 static const char INDENT[] = " "; /* how much to indent on new line */
17 uint_t skein_DebugFlag = 0; /* off by default. Must be set externally */
19 static void Show64_step(size_t cnt,const u64b_t *X,size_t step)
22 for (i=j=0;i < cnt;i++,j+=step)
24 if (i % 4 == 0) printf(INDENT);
25 printf(" %08X.%08X ",(uint_32t)(X[j] >> 32),(uint_32t)X[j]);
26 if (i % 4 == 3 || i==cnt-1) printf("\n");
31 #define Show64(cnt,X) Show64_step(cnt,X,1)
33 static void Show64_flag(size_t cnt,const u64b_t *X)
35 size_t xptr = (size_t) X;
36 size_t step = (xptr & 1) ? 2 : 1;
39 X = (const u64b_t *) (xptr & ~1);
41 Show64_step(cnt,X,step);
44 static void Show08(size_t cnt,const u08b_t *b)
49 if (i %16 == 0) printf(INDENT);
50 else if (i % 4 == 0) printf(" ");
52 if (i %16 == 15 || i==cnt-1) printf("\n");
57 static const char *AlgoHeader(uint_t bits)
59 if (skein_DebugFlag & SKEIN_DEBUG_THREEFISH)
62 case 256: return ":Threefish-256: ";
63 case 512: return ":Threefish-512: ";
64 case 1024: return ":Threefish-1024:";
69 case 256: return ":Skein-256: ";
70 case 512: return ":Skein-512: ";
71 case 1024: return ":Skein-1024:";
76 void Skein_Show_Final(uint_t bits,const Skein_Ctxt_Hdr_t *h,size_t cnt,const u08b_t *outPtr)
78 if (skein_DebugFlag & SKEIN_DEBUG_CONFIG || ((h->T[1] & SKEIN_T1_BLK_TYPE_MASK) != SKEIN_T1_BLK_TYPE_CFG))
79 if (skein_DebugFlag & SKEIN_DEBUG_FINAL)
81 printf("\n%s Final output=\n",AlgoHeader(bits));
83 printf(" ++++++++++\n");
88 /* show state after a round (or "pseudo-round") */
89 void Skein_Show_Round(uint_t bits,const Skein_Ctxt_Hdr_t *h,size_t r,const u64b_t *X)
91 static uint_t injectNum=0; /* not multi-thread safe! */
93 if (skein_DebugFlag & SKEIN_DEBUG_CONFIG || ((h->T[1] & SKEIN_T1_BLK_TYPE_MASK) != SKEIN_T1_BLK_TYPE_CFG))
96 if (r >= SKEIN_RND_SPECIAL)
97 { /* a key injection (or feedforward) point */
98 injectNum = (r == SKEIN_RND_KEY_INITIAL) ? 0 : injectNum+1;
99 if ( skein_DebugFlag & SKEIN_DEBUG_INJECT ||
100 ((skein_DebugFlag & SKEIN_DEBUG_FINAL) && r == SKEIN_RND_FEED_FWD))
102 printf("\n%s",AlgoHeader(bits));
105 case SKEIN_RND_KEY_INITIAL:
106 printf(" [state after initial key injection]");
108 case SKEIN_RND_KEY_INJECT:
109 printf(" [state after key injection #%02d]",injectNum);
111 case SKEIN_RND_FEED_FWD:
112 printf(" [state after plaintext feedforward]");
118 if (r== SKEIN_RND_FEED_FWD)
119 printf(" ----------\n");
122 else if (skein_DebugFlag & SKEIN_DEBUG_ROUNDS)
125 u64b_t p[SKEIN_MAX_STATE_WORDS];
127 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 const static u08b_t PERM_512 [4][ 8] = { { 0,1,2,3,4,5,6,7 },
133 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 { 0, 9, 2,13, 6,11, 4,15,10, 7,12, 3,14, 5, 8, 1 },
135 { 0, 7, 2, 5, 4, 3, 6, 1,12,15,14,13, 8,11,10, 9 },
136 { 0,15, 2,11, 6,13, 4, 9,14, 1, 8, 5,10, 3,12, 7 }
139 if ((skein_DebugFlag & SKEIN_DEBUG_PERMUTE) && (r & 3))
141 printf("\n%s [state after round %2d (permuted)]=\n",AlgoHeader(bits),(int)r);
144 case 256: perm = PERM_256 [r&3]; break;
145 case 512: perm = PERM_512 [r&3]; break;
146 default: perm = PERM_1024[r&3]; break;
148 for (j=0;j<bits/64;j++)
154 printf("\n%s [state after round %2d]=\n",AlgoHeader(bits),(int)r);
161 /* show state after a round (or "pseudo-round"), given a list of pointers */
162 void Skein_Show_R_Ptr(uint_t bits,const Skein_Ctxt_Hdr_t *h,size_t r,const u64b_t *X_ptr[])
165 u64b_t X[SKEIN_MAX_STATE_WORDS];
167 for (i=0;i<bits/64;i++) /* copy over the words */
169 Skein_Show_Round(bits,h,r,X);
173 /* show the state at the start of a block */
174 void Skein_Show_Block(uint_t bits,const Skein_Ctxt_Hdr_t *h,const u64b_t *X,const u08b_t *blkPtr,
175 const u64b_t *wPtr, const u64b_t *ksPtr, const u64b_t *tsPtr)
178 if (skein_DebugFlag & SKEIN_DEBUG_CONFIG || ((h->T[1] & SKEIN_T1_BLK_TYPE_MASK) != SKEIN_T1_BLK_TYPE_CFG))
181 if (skein_DebugFlag & SKEIN_DEBUG_HDR)
183 printf("\n%s Block: outBits=%4d. T0=%06X.",AlgoHeader(bits),(uint_t) h->hashBitLen,(uint_t)h->T[0]);
185 n = (uint_t) ((h->T[1] & SKEIN_T1_BLK_TYPE_MASK) >> SKEIN_T1_POS_BLK_TYPE);
188 case SKEIN_BLK_TYPE_KEY: printf("KEY. "); break;
189 case SKEIN_BLK_TYPE_CFG: printf("CFG. "); break;
190 case SKEIN_BLK_TYPE_PERS: printf("PERS."); break;
191 case SKEIN_BLK_TYPE_PK : printf("PK. "); break;
192 case SKEIN_BLK_TYPE_KDF: printf("KDF. "); break;
193 case SKEIN_BLK_TYPE_MSG: printf("MSG. "); break;
194 case SKEIN_BLK_TYPE_OUT: printf("OUT. "); break;
195 default: printf("0x%02X.",n); break;
198 printf((h->T[1] & SKEIN_T1_FLAG_FIRST) ? " First":" ");
199 printf((h->T[1] & SKEIN_T1_FLAG_FINAL) ? " Final":" ");
200 printf((h->T[1] & SKEIN_T1_FLAG_BIT_PAD) ? " Pad" :" ");
201 n = (uint_t) ((h->T[1] & SKEIN_T1_TREE_LVL_MASK) >> SKEIN_T1_POS_TREE_LVL);
203 printf(" TreeLevel = %02X",n);
207 if (skein_DebugFlag & SKEIN_DEBUG_TWEAK)
212 if (skein_DebugFlag & SKEIN_DEBUG_STATE)
214 printf(" %s words:\n",(skein_DebugFlag & SKEIN_DEBUG_THREEFISH)?"Key":"State");
217 if (skein_DebugFlag & SKEIN_DEBUG_KEYSCHED)
219 printf(" Tweak schedule:\n");
220 Show64_flag(3,tsPtr);
221 printf(" Key schedule:\n");
222 Show64_flag((bits/64)+1,ksPtr);
224 if (skein_DebugFlag & SKEIN_DEBUG_INPUT_64)
226 printf(" Input block (words):\n");
227 Show64(bits/64,wPtr);
229 if (skein_DebugFlag & SKEIN_DEBUG_INPUT_08)
231 printf(" Input block (bytes):\n");
232 Show08(bits/8,blkPtr);
237 void Skein_Show_Key(uint_t bits,const Skein_Ctxt_Hdr_t *h,const u08b_t *key,size_t keyBytes)
240 if (skein_DebugFlag & SKEIN_DEBUG_CONFIG || ((h->T[1] & SKEIN_T1_BLK_TYPE_MASK) != SKEIN_T1_BLK_TYPE_CFG))
241 if (skein_DebugFlag & SKEIN_DEBUG_KEY)
243 printf("\n%s MAC key = %4u bytes\n",AlgoHeader(bits),(unsigned) keyBytes);
244 Show08(keyBytes,key);