1300819Sallanjude/***********************************************************************
2300819Sallanjude**
3300819Sallanjude** Debug output functions for Skein hashing.
4300819Sallanjude**
5300819Sallanjude** Source code author: Doug Whiting, 2008.
6300819Sallanjude**
7300819Sallanjude** This algorithm and source code is released to the public domain.
8300819Sallanjude**
9300819Sallanjude************************************************************************/
10300819Sallanjude#include <stdio.h>
11300819Sallanjude
12300819Sallanjude#ifdef SKEIN_DEBUG  /* only instantiate this code if SKEIN_DEBUG is on */
13300819Sallanjude#include "skein.h"
14300819Sallanjude
15300819Sallanjudestatic const char INDENT[] =  "    ";  /* how much to indent on new line */
16300819Sallanjude
17300819Sallanjudeuint_t skein_DebugFlag = 0;  /* off by default. Must be set externally */
18300819Sallanjude
19300819Sallanjudestatic void Show64_step(size_t cnt,const u64b_t *X,size_t step)
20300819Sallanjude    {
21300819Sallanjude    size_t i,j;
22300819Sallanjude    for (i=j=0;i < cnt;i++,j+=step)
23300819Sallanjude        {
24300819Sallanjude        if (i % 4 ==  0) printf(INDENT);
25300819Sallanjude        printf(" %08X.%08X ",(uint_32t)(X[j] >> 32),(uint_32t)X[j]);
26300819Sallanjude        if (i % 4 ==  3 || i==cnt-1) printf("\n");
27300819Sallanjude        fflush(stdout);
28300819Sallanjude        }
29300819Sallanjude    }
30300819Sallanjude
31300819Sallanjude#define Show64(cnt,X) Show64_step(cnt,X,1)
32300819Sallanjude
33300819Sallanjudestatic void Show64_flag(size_t cnt,const u64b_t *X)
34300819Sallanjude    {
35300819Sallanjude    size_t xptr = (size_t) X;
36300819Sallanjude    size_t step = (xptr & 1) ? 2 : 1;
37300819Sallanjude    if (step != 1)
38300819Sallanjude        {
39300819Sallanjude        X = (const u64b_t *) (xptr & ~1);
40300819Sallanjude        }
41300819Sallanjude    Show64_step(cnt,X,step);
42300819Sallanjude    }
43300819Sallanjude
44300819Sallanjudestatic void Show08(size_t cnt,const u08b_t *b)
45300819Sallanjude    {
46300819Sallanjude    size_t i;
47300819Sallanjude    for (i=0;i < cnt;i++)
48300819Sallanjude        {
49300819Sallanjude        if (i %16 ==  0) printf(INDENT);
50300819Sallanjude        else if (i % 4 == 0) printf(" ");
51300819Sallanjude        printf(" %02X",b[i]);
52300819Sallanjude        if (i %16 == 15 || i==cnt-1) printf("\n");
53300819Sallanjude        fflush(stdout);
54300819Sallanjude        }
55300819Sallanjude    }
56300819Sallanjude
57300819Sallanjudestatic const char *AlgoHeader(uint_t bits)
58300819Sallanjude    {
59300819Sallanjude    if (skein_DebugFlag & SKEIN_DEBUG_THREEFISH)
60300819Sallanjude        switch (bits)
61300819Sallanjude            {
62300819Sallanjude            case  256:  return ":Threefish-256: ";
63300819Sallanjude            case  512:  return ":Threefish-512: ";
64300819Sallanjude            case 1024:  return ":Threefish-1024:";
65300819Sallanjude            }
66300819Sallanjude    else
67300819Sallanjude        switch (bits)
68300819Sallanjude            {
69300819Sallanjude            case  256:  return ":Skein-256: ";
70300819Sallanjude            case  512:  return ":Skein-512: ";
71300819Sallanjude            case 1024:  return ":Skein-1024:";
72300819Sallanjude            }
73300819Sallanjude    return NULL;
74300819Sallanjude    }
75300819Sallanjude
76300819Sallanjudevoid Skein_Show_Final(uint_t bits,const Skein_Ctxt_Hdr_t *h,size_t cnt,const u08b_t *outPtr)
77300819Sallanjude    {
78300819Sallanjude    if (skein_DebugFlag & SKEIN_DEBUG_CONFIG || ((h->T[1] & SKEIN_T1_BLK_TYPE_MASK) != SKEIN_T1_BLK_TYPE_CFG))
79300819Sallanjude    if (skein_DebugFlag & SKEIN_DEBUG_FINAL)
80300819Sallanjude        {
81300819Sallanjude        printf("\n%s Final output=\n",AlgoHeader(bits));
82300819Sallanjude        Show08(cnt,outPtr);
83300819Sallanjude        printf("    ++++++++++\n");
84300819Sallanjude        fflush(stdout);
85300819Sallanjude        }
86300819Sallanjude    }
87300819Sallanjude
88300819Sallanjude/* show state after a round (or "pseudo-round") */
89300819Sallanjudevoid Skein_Show_Round(uint_t bits,const Skein_Ctxt_Hdr_t *h,size_t r,const u64b_t *X)
90300819Sallanjude    {
91300819Sallanjude    static uint_t injectNum=0;  /* not multi-thread safe! */
92300819Sallanjude
93300819Sallanjude    if (skein_DebugFlag & SKEIN_DEBUG_CONFIG || ((h->T[1] & SKEIN_T1_BLK_TYPE_MASK) != SKEIN_T1_BLK_TYPE_CFG))
94300819Sallanjude    if (skein_DebugFlag)
95300819Sallanjude        {
96300819Sallanjude        if (r >= SKEIN_RND_SPECIAL)
97300819Sallanjude            {       /* a key injection (or feedforward) point */
98300819Sallanjude            injectNum = (r == SKEIN_RND_KEY_INITIAL) ? 0 : injectNum+1;
99300819Sallanjude            if (  skein_DebugFlag & SKEIN_DEBUG_INJECT ||
100300819Sallanjude                ((skein_DebugFlag & SKEIN_DEBUG_FINAL) && r == SKEIN_RND_FEED_FWD))
101300819Sallanjude                {
102300819Sallanjude                printf("\n%s",AlgoHeader(bits));
103300819Sallanjude                switch (r)
104300819Sallanjude                    {
105300819Sallanjude                    case SKEIN_RND_KEY_INITIAL:
106300819Sallanjude                        printf(" [state after initial key injection]");
107300819Sallanjude                        break;
108300819Sallanjude                    case SKEIN_RND_KEY_INJECT:
109300819Sallanjude                        printf(" [state after key injection #%02d]",injectNum);
110300819Sallanjude                        break;
111300819Sallanjude                    case SKEIN_RND_FEED_FWD:
112300819Sallanjude                        printf(" [state after plaintext feedforward]");
113300819Sallanjude                        injectNum = 0;
114300819Sallanjude                        break;
115300819Sallanjude                    }
116300819Sallanjude                printf("=\n");
117300819Sallanjude                Show64(bits/64,X);
118300819Sallanjude                if (r== SKEIN_RND_FEED_FWD)
119300819Sallanjude                    printf("    ----------\n");
120300819Sallanjude                }
121300819Sallanjude            }
122300819Sallanjude        else if (skein_DebugFlag & SKEIN_DEBUG_ROUNDS)
123300819Sallanjude            {
124300819Sallanjude            uint_t j;
125300819Sallanjude            u64b_t p[SKEIN_MAX_STATE_WORDS];
126300819Sallanjude            const u08b_t *perm;
127300819Sallanjude            const static u08b_t PERM_256 [4][ 4] = { { 0,1,2,3 }, { 0,3,2,1 }, { 0,1,2,3 }, { 0,3,2,1 } };
128300819Sallanjude            const static u08b_t PERM_512 [4][ 8] = { { 0,1,2,3,4,5,6,7 },
129300819Sallanjude                                                     { 2,1,4,7,6,5,0,3 },
130300819Sallanjude                                                     { 4,1,6,3,0,5,2,7 },
131300819Sallanjude                                                     { 6,1,0,7,2,5,4,3 }
132300819Sallanjude                                                   };
133300819Sallanjude            const static u08b_t PERM_1024[4][16] = { { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 },
134300819Sallanjude                                                     { 0, 9, 2,13, 6,11, 4,15,10, 7,12, 3,14, 5, 8, 1 },
135300819Sallanjude                                                     { 0, 7, 2, 5, 4, 3, 6, 1,12,15,14,13, 8,11,10, 9 },
136300819Sallanjude                                                     { 0,15, 2,11, 6,13, 4, 9,14, 1, 8, 5,10, 3,12, 7 }
137300819Sallanjude                                                   };
138300819Sallanjude
139300819Sallanjude            if ((skein_DebugFlag & SKEIN_DEBUG_PERMUTE) && (r & 3))
140300819Sallanjude                {
141300819Sallanjude                printf("\n%s [state after round %2d (permuted)]=\n",AlgoHeader(bits),(int)r);
142300819Sallanjude                switch (bits)
143300819Sallanjude                    {
144300819Sallanjude                    case  256: perm = PERM_256 [r&3];   break;
145300819Sallanjude                    case  512: perm = PERM_512 [r&3];   break;
146300819Sallanjude                    default:   perm = PERM_1024[r&3];   break;
147300819Sallanjude                    }
148300819Sallanjude                for (j=0;j<bits/64;j++)
149300819Sallanjude                    p[j] = X[perm[j]];
150300819Sallanjude                Show64(bits/64,p);
151300819Sallanjude                }
152300819Sallanjude            else
153300819Sallanjude                {
154300819Sallanjude                printf("\n%s [state after round %2d]=\n",AlgoHeader(bits),(int)r);
155300819Sallanjude                Show64(bits/64,X);
156300819Sallanjude                }
157300819Sallanjude            }
158300819Sallanjude        }
159300819Sallanjude    }
160300819Sallanjude
161300819Sallanjude/* show state after a round (or "pseudo-round"), given a list of pointers */
162300819Sallanjudevoid Skein_Show_R_Ptr(uint_t bits,const Skein_Ctxt_Hdr_t *h,size_t r,const u64b_t *X_ptr[])
163300819Sallanjude    {
164300819Sallanjude    uint_t i;
165300819Sallanjude    u64b_t X[SKEIN_MAX_STATE_WORDS];
166300819Sallanjude
167300819Sallanjude    for (i=0;i<bits/64;i++)     /* copy over the words */
168300819Sallanjude        X[i] = X_ptr[i][0];
169300819Sallanjude    Skein_Show_Round(bits,h,r,X);
170300819Sallanjude    }
171300819Sallanjude
172300819Sallanjude
173300819Sallanjude/* show the state at the start of a block */
174300819Sallanjudevoid Skein_Show_Block(uint_t bits,const Skein_Ctxt_Hdr_t *h,const u64b_t *X,const u08b_t *blkPtr,
175300819Sallanjude                      const u64b_t *wPtr, const u64b_t *ksPtr, const u64b_t *tsPtr)
176300819Sallanjude    {
177300819Sallanjude    uint_t n;
178300819Sallanjude    if (skein_DebugFlag & SKEIN_DEBUG_CONFIG || ((h->T[1] & SKEIN_T1_BLK_TYPE_MASK) != SKEIN_T1_BLK_TYPE_CFG))
179300819Sallanjude    if (skein_DebugFlag)
180300819Sallanjude        {
181300819Sallanjude        if (skein_DebugFlag & SKEIN_DEBUG_HDR)
182300819Sallanjude            {
183300819Sallanjude            printf("\n%s Block: outBits=%4d. T0=%06X.",AlgoHeader(bits),(uint_t) h->hashBitLen,(uint_t)h->T[0]);
184300819Sallanjude            printf(" Type=");
185300819Sallanjude            n = (uint_t) ((h->T[1] & SKEIN_T1_BLK_TYPE_MASK) >> SKEIN_T1_POS_BLK_TYPE);
186300819Sallanjude            switch (n)
187300819Sallanjude                {
188300819Sallanjude                case SKEIN_BLK_TYPE_KEY:  printf("KEY. ");  break;
189300819Sallanjude                case SKEIN_BLK_TYPE_CFG:  printf("CFG. ");  break;
190300819Sallanjude                case SKEIN_BLK_TYPE_PERS: printf("PERS.");  break;
191300819Sallanjude                case SKEIN_BLK_TYPE_PK :  printf("PK.  ");  break;
192300819Sallanjude                case SKEIN_BLK_TYPE_KDF:  printf("KDF. ");  break;
193300819Sallanjude                case SKEIN_BLK_TYPE_MSG:  printf("MSG. ");  break;
194300819Sallanjude                case SKEIN_BLK_TYPE_OUT:  printf("OUT. ");  break;
195300819Sallanjude                default:    printf("0x%02X.",n); break;
196300819Sallanjude                }
197300819Sallanjude            printf(" Flags=");
198300819Sallanjude            printf((h->T[1] & SKEIN_T1_FLAG_FIRST)   ? " First":"      ");
199300819Sallanjude            printf((h->T[1] & SKEIN_T1_FLAG_FINAL)   ? " Final":"      ");
200300819Sallanjude            printf((h->T[1] & SKEIN_T1_FLAG_BIT_PAD) ? " Pad"  :"    ");
201300819Sallanjude            n = (uint_t) ((h->T[1] & SKEIN_T1_TREE_LVL_MASK) >> SKEIN_T1_POS_TREE_LVL);
202300819Sallanjude            if (n)
203300819Sallanjude                printf("  TreeLevel = %02X",n);
204300819Sallanjude            printf("\n");
205300819Sallanjude            fflush(stdout);
206300819Sallanjude            }
207300819Sallanjude        if (skein_DebugFlag & SKEIN_DEBUG_TWEAK)
208300819Sallanjude            {
209300819Sallanjude            printf("  Tweak:\n");
210300819Sallanjude            Show64(2,h->T);
211300819Sallanjude            }
212300819Sallanjude        if (skein_DebugFlag & SKEIN_DEBUG_STATE)
213300819Sallanjude            {
214300819Sallanjude            printf("  %s words:\n",(skein_DebugFlag & SKEIN_DEBUG_THREEFISH)?"Key":"State");
215300819Sallanjude            Show64(bits/64,X);
216300819Sallanjude            }
217300819Sallanjude        if (skein_DebugFlag & SKEIN_DEBUG_KEYSCHED)
218300819Sallanjude            {
219300819Sallanjude            printf("  Tweak schedule:\n");
220300819Sallanjude            Show64_flag(3,tsPtr);
221300819Sallanjude            printf("  Key   schedule:\n");
222300819Sallanjude            Show64_flag((bits/64)+1,ksPtr);
223300819Sallanjude            }
224300819Sallanjude        if (skein_DebugFlag & SKEIN_DEBUG_INPUT_64)
225300819Sallanjude            {
226300819Sallanjude            printf("  Input block (words):\n");
227300819Sallanjude            Show64(bits/64,wPtr);
228300819Sallanjude            }
229300819Sallanjude        if (skein_DebugFlag & SKEIN_DEBUG_INPUT_08)
230300819Sallanjude            {
231300819Sallanjude            printf("  Input block (bytes):\n");
232300819Sallanjude            Show08(bits/8,blkPtr);
233300819Sallanjude            }
234300819Sallanjude        }
235300819Sallanjude    }
236300819Sallanjude
237300819Sallanjudevoid Skein_Show_Key(uint_t bits,const Skein_Ctxt_Hdr_t *h,const u08b_t *key,size_t keyBytes)
238300819Sallanjude    {
239300819Sallanjude    if (keyBytes)
240300819Sallanjude    if (skein_DebugFlag & SKEIN_DEBUG_CONFIG || ((h->T[1] & SKEIN_T1_BLK_TYPE_MASK) != SKEIN_T1_BLK_TYPE_CFG))
241300819Sallanjude    if (skein_DebugFlag & SKEIN_DEBUG_KEY)
242300819Sallanjude        {
243300819Sallanjude        printf("\n%s MAC key = %4u bytes\n",AlgoHeader(bits),(unsigned) keyBytes);
244300819Sallanjude        Show08(keyBytes,key);
245300819Sallanjude        }
246300819Sallanjude    }
247300819Sallanjude#endif
248