/*********************************************************************** ** ** Debug output functions for Skein hashing. ** ** Source code author: Doug Whiting, 2008. ** ** This algorithm and source code is released to the public domain. ** ************************************************************************/ #include #ifdef SKEIN_DEBUG /* only instantiate this code if SKEIN_DEBUG is on */ #include "skein.h" static const char *INDENT = " "; /* how much to indent on new line */ uint_t skein_DebugFlag = 0; /* off by default. Must be set externally */ static void Show64(size_t cnt,const u64b_t *X) { size_t i; for (i=0;i < cnt;i++) { if (i % 4 == 0) printf(INDENT); printf(" %08X.%08X ",(uint_32t)(X[i] >> 32),(uint_32t)X[i]); if (i % 4 == 3 || i==cnt-1) printf("\n"); } } static void Show08(size_t cnt,const u08b_t *b) { size_t i; for (i=0;i < cnt;i++) { if (i %16 == 0) printf(INDENT); else if (i % 4 == 0) printf(" "); printf(" %02X",b[i]); if (i %16 == 15 || i==cnt-1) printf("\n"); } } static const char *AlgoHeader(uint_t bits) { if (skein_DebugFlag & SKEIN_DEBUG_THREEFISH) switch (bits) { case 256: return ":Threefish-256: "; case 512: return ":Threefish-512: "; case 1024: return ":Threefish-1024:"; } else switch (bits) { case 256: return ":Skein-256: "; case 512: return ":Skein-512: "; case 1024: return ":Skein-1024:"; } return NULL; } void Skein_Show_Final(uint_t bits,const Skein_Ctxt_Hdr_t *h,size_t cnt,const u08b_t *outPtr) { if (skein_DebugFlag & SKEIN_DEBUG_CONFIG || ((h->T[1] & SKEIN_T1_BLK_TYPE_MASK) != SKEIN_T1_BLK_TYPE_CFG)) if (skein_DebugFlag & SKEIN_DEBUG_FINAL) { printf("\n%s Final output=\n",AlgoHeader(bits)); Show08(cnt,outPtr); printf(" ++++++++++\n"); } } /* show state after a round (or "pseudo-round") */ void Skein_Show_Round(uint_t bits,const Skein_Ctxt_Hdr_t *h,size_t r,const u64b_t *X) { static uint_t injectNum=0; /* not multi-thread safe! */ if (skein_DebugFlag & SKEIN_DEBUG_CONFIG || ((h->T[1] & SKEIN_T1_BLK_TYPE_MASK) != SKEIN_T1_BLK_TYPE_CFG)) if (skein_DebugFlag) { if (r >= SKEIN_RND_SPECIAL) { /* a key injection (or feedforward) point */ injectNum = (r == SKEIN_RND_KEY_INITIAL) ? 0 : injectNum+1; if ( skein_DebugFlag & SKEIN_DEBUG_INJECT || ((skein_DebugFlag & SKEIN_DEBUG_FINAL) && r == SKEIN_RND_FEED_FWD)) { printf("\n%s",AlgoHeader(bits)); switch (r) { case SKEIN_RND_KEY_INITIAL: printf(" [state after initial key injection]"); break; case SKEIN_RND_KEY_INJECT: printf(" [state after key injection #%02d]",injectNum); break; case SKEIN_RND_FEED_FWD: printf(" [state after plaintext feedforward]"); injectNum = 0; break; } printf("=\n"); Show64(bits/64,X); if (r== SKEIN_RND_FEED_FWD) printf(" ----------\n"); } } else if (skein_DebugFlag & SKEIN_DEBUG_ROUNDS) { uint_t j; u64b_t p[SKEIN_MAX_STATE_WORDS]; const u08b_t *perm; const static u08b_t PERM_256 [4][ 4] = { { 0,1,2,3 }, { 0,3,2,1 }, { 0,1,2,3 }, { 0,3,2,1 } }; const static u08b_t PERM_512 [4][ 8] = { { 0,1,2,3,4,5,6,7 }, { 2,1,4,7,6,5,0,3 }, { 4,1,6,3,0,5,2,7 }, { 6,1,0,7,2,5,4,3 } }; const static u08b_t PERM_1024[4][16] = { { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 }, { 0, 9, 2,13, 6,11, 4,15,10, 7,12, 3,14, 5, 8, 1 }, { 0, 7, 2, 5, 4, 3, 6, 1,12,15,14,13, 8,11,10, 9 }, { 0,15, 2,11, 6,13, 4, 9,14, 1, 8, 5,10, 3,12, 7 } }; if ((skein_DebugFlag & SKEIN_DEBUG_PERMUTE) && (r & 3)) { printf("\n%s [state after round %2d (permuted)]=\n",AlgoHeader(bits),r); switch (bits) { case 256: perm = PERM_256 [r&3]; break; case 512: perm = PERM_512 [r&3]; break; default: perm = PERM_1024[r&3]; break; } for (j=0;jT[1] & SKEIN_T1_BLK_TYPE_MASK) != SKEIN_T1_BLK_TYPE_CFG)) if (skein_DebugFlag) { if (skein_DebugFlag & SKEIN_DEBUG_HDR) { printf("\n%s Block: outBits=%4d. T0=%06X.",AlgoHeader(bits),(uint_t) h->hashBitLen,(uint_t)h->T[0]); printf(" Type="); n = (uint_t) ((h->T[1] & SKEIN_T1_BLK_TYPE_MASK) >> SKEIN_T1_POS_BLK_TYPE); switch (n) { case SKEIN_BLK_TYPE_KEY: printf("KEY. "); break; case SKEIN_BLK_TYPE_CFG: printf("CFG. "); break; case SKEIN_BLK_TYPE_PERS: printf("PERS."); break; case SKEIN_BLK_TYPE_PK : printf("PK. "); break; case SKEIN_BLK_TYPE_KDF: printf("KDF. "); break; case SKEIN_BLK_TYPE_MSG: printf("MSG. "); break; case SKEIN_BLK_TYPE_OUT: printf("OUT. "); break; default: printf("0x%02X.",n); break; } printf(" Flags="); printf((h->T[1] & SKEIN_T1_FLAG_FIRST) ? " First":" "); printf((h->T[1] & SKEIN_T1_FLAG_FINAL) ? " Final":" "); printf((h->T[1] & SKEIN_T1_FLAG_BIT_PAD) ? " Pad" :" "); n = (uint_t) ((h->T[1] & SKEIN_T1_TREE_LVL_MASK) >> SKEIN_T1_POS_TREE_LVL); if (n) printf(" TreeLevel = %02X",n); printf("\n"); } if (skein_DebugFlag & SKEIN_DEBUG_TWEAK) { printf(" Tweak:\n"); Show64(2,h->T); } if (skein_DebugFlag & SKEIN_DEBUG_STATE) { printf(" %s words:\n",(skein_DebugFlag & SKEIN_DEBUG_THREEFISH)?"Key":"State"); Show64(bits/64,X); } if (skein_DebugFlag & SKEIN_DEBUG_KEYSCHED) { printf(" Tweak schedule:\n"); Show64(3,tsPtr); printf(" Key schedule:\n"); Show64((bits/64)+1,ksPtr); } if (skein_DebugFlag & SKEIN_DEBUG_INPUT_64) { printf(" Input block (words):\n"); Show64(bits/64,wPtr); } if (skein_DebugFlag & SKEIN_DEBUG_INPUT_08) { printf(" Input block (bytes):\n"); Show08(bits/8,blkPtr); } } } void Skein_Show_Key(uint_t bits,const Skein_Ctxt_Hdr_t *h,const u08b_t *key,size_t keyBytes) { if (keyBytes) if (skein_DebugFlag & SKEIN_DEBUG_CONFIG || ((h->T[1] & SKEIN_T1_BLK_TYPE_MASK) != SKEIN_T1_BLK_TYPE_CFG)) if (skein_DebugFlag & SKEIN_DEBUG_KEY) { printf("\n%s MAC key = %4u bytes\n",AlgoHeader(bits),keyBytes); Show08(keyBytes,key); } } #endif