#include#include #include #include uint64_t xor(uint64_t x, uint64_t y); void permix1(uint64_t P[]); void permix2(uint64_t P[]); void subkey(uint64_t P[], uint64_t K[], uint64_t T[], unsigned short int s); int main(void) { unsigned short int first, final, tmsg, tout, s, filler, digit; //uint64_t first, final, tmsg, tout, s, filler, digit; uint64_t P[4], G0[4], G[4], out[4]; uint64_t K[5], M[4], Min[4]; uint64_t T[3], pcarry; FILE *stimuli, *expresp; stimuli = fopen("skein256_stimuli.asc","w"); expresp = fopen("skein256_expresp.asc","w"); srand(time(0)); // initialization G0[0] = 0x388512680E660046; G0[1] = 0x4B72D5DEC5A8FF01; G0[2] = 0x281A9298CA5EB3A5; G0[3] = 0x54CA5249F46070C4; /* M[0] = 0; M[1] = 0; M[2] = 0; M[3] = 0; M[0] = 0xF8F9FAFBFCFDFEFF; M[1] = 0xF0F1F2F3F4F5F6F7; M[2] = 0xE8E9EAEBECEDEEEF; M[3] = 0xE0E1E2E3E4E5E6E7; M[0] = 0xE1821AB6267CD1FB; M[1] = 0xC9969B450D5F122E; M[2] = 0x9BB322FF7D83B41A; M[3] = 0xC85DFCCD30944378; */ int coe = 12; int add = 2; M[0] = 0xFFFFFFFFFFFFFFFF; // *coe + 0x0101010101010101*add; M[1] = 0xFFFFFFFFFFFFFFFF; // *coe + 0x0101010101010101*add; M[2] = 0xFFFFFFFFFFFFFFFF; // *coe + 0x0101010101010101*add; M[3] = 0xFFFFFFFFFFFFFFFF; // *coe + 0x0101010101010101*add; printf("\n%016llX \n", M[0]); printf("%016llX \n", M[1]); printf("%016llX \n", M[2]); printf("%016llX \n\n", M[3]); char buf[65]; sprintf(buf,"%016llX%016llX%016llX%016llX", M[0], M[1], M[2], M[3]); fprintf(stimuli,"0 0 0 %064X\n", 0); fprintf(stimuli,"0 0 0 %064X\n", 0); fprintf(stimuli,"1 0 0 %064X\n", 0); fprintf(stimuli,"1 0 0 %064X\n", 0); fprintf(stimuli,"1 1 0 %016llX%016llX%016llX%016llX\n", M[0], M[1], M[2], M[3]); //fprintf(stimuli,"1 1 0 1 1 0 1 %c%c\n", buf[0], buf[1]); //fprintf(stimuli,"1 1 0 1 1 0 1 %c%c\n", buf[0], buf[1]); //fprintf(stimuli,"1 1 0 1 1 0 1 %c%c\n", buf[0], buf[1]); // START // fprintf(stimuli,"1 0 1 0 0 1 1 00\n"); for (filler = 0; filler < (19*8-1); filler +=1) { //fprintf(stimuli,"1 0 0 1 1 0 1 00\n"); fprintf(stimuli,"1 0 0 %064X\n", 0); } Min[0] = M[0]; Min[1] = M[1]; Min[2] = M[2]; Min[3] = M[3]; K[0] = G0[0]; K[1] = G0[1]; K[2] = G0[2]; K[3] = G0[3]; // +++++++++++++++++++++++++++++++++++++++++++ // ++++++++++++ FIRST BLOCK ++++++++++++++++++ // +++++++++++++++++++++++++++++++++++++++++++ // set the tweak for the message part first = 1; final = 0; tmsg = 1; tout = 0; pcarry = 0; T[0]=0; T[1]=0; T[2]=0; T[0] = 32; // only position T[1] = pow(2,63)*final + pow(2,62)*first + (pow(2,61)+pow(2,60)+pow(2,59)+pow(2,58)+pow(2,57)+pow(2,56))*tout + (pow(2,61)+pow(2,60))*tmsg + pcarry; printf("First:\nT[0] = %016llX\nT[1] = %016llX\n\n", T[0], T[1]); // run UBI for (s = 0; s < 18; s +=1) { subkey(M, K, T, s); if ((s % 2) == 0) permix1(M); else permix2(M); //printf("after s=%d\n%llX \n", s,M[0]); //printf("%llX \n", M[1]); //printf("%llX \n", M[2]); //printf("%llX \n\n", M[3]); } subkey(M, K, T, 18); G[0] = xor(Min[0], M[0]); G[1] = xor(Min[1], M[1]); G[2] = xor(Min[2], M[2]); G[3] = xor(Min[3], M[3]); // +++++++++++++++++++++++++++++++++++++++++++ // ++++++++++++ SECOND BLOCK +++++++++++++++++ // +++++++++++++++++++++++++++++++++++++++++++ K[0] = G[0]; K[1] = G[1]; K[2] = G[2]; K[3] = G[3]; M[0] = 0xFFFFFFFFFFFFFFFF; // *coe + 0x0101010101010101*add; M[1] = 0xFFFFFFFFFFFFFFFF; // *coe + 0x0101010101010101*add; M[2] = 0xFFFFFFFFFFFFFFFF; // *coe + 0x0101010101010101*add; M[3] = 0xFFFFFFFFFFFFFFFF; // *coe + 0x0101010101010101*add; Min[0] = M[0]; Min[1] = M[1]; Min[2] = M[2]; Min[3] = M[3]; fprintf(stimuli,"1 1 0 %016llX%016llX%016llX%016llX\n", M[0], M[1], M[2], M[3]); for (filler = 0; filler < (19*8-1); filler +=1) { fprintf(stimuli,"1 0 0 %064llX\n", 0); } // set the tweak for the message part first = 0; final = 0; tmsg = 1; tout = 0; pcarry = 0; T[0] = 64; // only position T[1] = pow(2,63)*final + pow(2,62)*first + (pow(2,61)+pow(2,60)+pow(2,59)+pow(2,58)+pow(2,57)+pow(2,56))*tout + (pow(2,61)+pow(2,60))*tmsg + pcarry; printf("Second:\nT[0] = %016llX\nT[1] = %016llX\n\n", T[0], T[1]); // run UBI for (s = 0; s < 18; s +=1) { subkey(M, K, T, s); if ((s % 2) == 0) permix1(M); else permix2(M); //printf("after s=%d\n%llX \n", s,M[0]); //printf("%llX \n", M[1]); //printf("%llX \n", M[2]); //printf("%llX \n\n", M[3]); } subkey(M, K, T, 18); G[0] = xor(Min[0], M[0]); G[1] = xor(Min[1], M[1]); G[2] = xor(Min[2], M[2]); G[3] = xor(Min[3], M[3]); // +++++++++++++++++++++++++++++++++++++++++++ // ++++++++++++ THIRD BLOCK ++++++++++++++++++ // +++++++++++++++++++++++++++++++++++++++++++ K[0] = G[0]; K[1] = G[1]; K[2] = G[2]; K[3] = G[3]; M[0] = 0xFFFFFFFFFFFFFFFF; // *coe + 0x0101010101010101*add; M[1] = 0xFFFFFFFFFFFFFFFF; // *coe + 0x0101010101010101*add; M[2] = 0xFFFFFFFFFFFFFFFF; // *coe + 0x0101010101010101*add; M[3] = 0xFFFFFFFFFFFFFFFF; // *coe + 0x0101010101010101*add; Min[0] = M[0]; Min[1] = M[1]; Min[2] = M[2]; Min[3] = M[3]; fprintf(stimuli,"1 1 0 %016llX%016llX%016llX%016llX\n", M[0], M[1], M[2], M[3]); for (filler = 0; filler < (18*8); filler +=1) { fprintf(stimuli,"1 0 0 %064llX\n", 0); } for (filler = 0; filler < 7; filler +=1) { fprintf(stimuli,"1 0 1 %064llX\n", 0); } // set the tweak for the message part first = 0; final = 0; tmsg = 1; tout = 0; pcarry = 0; T[0] = 96; // only position T[1] = pow(2,63)*final + pow(2,62)*first + (pow(2,61)+pow(2,60)+pow(2,59)+pow(2,58)+pow(2,57)+pow(2,56))*tout + (pow(2,61)+pow(2,60))*tmsg + pcarry; printf("Third:\nT[0] = %016llX\nT[1] = %016llX\n\n", T[0], T[1]); // run UBI for (s = 0; s < 18; s +=1) { subkey(M, K, T, s); if ((s % 2) == 0) permix1(M); else permix2(M); //printf("after s=%d\n%llX \n", s,M[0]); //printf("%llX \n", M[1]); //printf("%llX \n", M[2]); //printf("%llX \n\n", M[3]); } subkey(M, K, T, 18); G[0] = xor(Min[0], M[0]); G[1] = xor(Min[1], M[1]); G[2] = xor(Min[2], M[2]); G[3] = xor(Min[3], M[3]); // +++++++++++++++++++++++++++++++++++++++++++ // ++++++++++++ FOURTH BLOCK +++++++++++++++++ // +++++++++++++++++++++++++++++++++++++++++++ K[0] = G[0]; K[1] = G[1]; K[2] = G[2]; K[3] = G[3]; M[0] = 0xFFFFFFFFFFFFFFFF; // *coe + 0x0101010101010101*add; M[1] = 0xFFFFFFFFFFFFFFFF; // *coe + 0x0101010101010101*add; M[2] = 0xFFFFFFFFFFFFFFFF; // *coe + 0x0101010101010101*add; M[3] = 0xFFFFFFFFFFFFFFFF; // *coe + 0x0101010101010101*add; Min[0] = M[0]; Min[1] = M[1]; Min[2] = M[2]; Min[3] = M[3]; fprintf(stimuli,"1 1 1 %016llX%016llX%016llX%016llX\n", M[0], M[1], M[2], M[3]); for (filler = 0; filler < (19*8-1); filler +=1) { fprintf(stimuli,"1 0 1 %064llX\n", 0); } // set the tweak for the message part first = 0; final = 1; tmsg = 1; tout = 0; pcarry = 0; T[0] = 128; // only position T[1] = pow(2,63)*final + pow(2,62)*first + (pow(2,61)+pow(2,60)+pow(2,59)+pow(2,58)+pow(2,57)+pow(2,56))*tout + (pow(2,61)+pow(2,60))*tmsg + pcarry; printf("Fourth:\nT[0] = %016llX\nT[1] = %016llX\n\n", T[0], T[1]); // run UBI for (s = 0; s < 18; s +=1) { subkey(M, K, T, s); if ((s % 2) == 0) permix1(M); else permix2(M); //printf("after s=%d\n%llX \n", s,M[0]); //printf("%llX \n", M[1]); //printf("%llX \n", M[2]); //printf("%llX \n\n", M[3]); } subkey(M, K, T, 18); G[0] = xor(Min[0], M[0]); G[1] = xor(Min[1], M[1]); G[2] = xor(Min[2], M[2]); G[3] = xor(Min[3], M[3]); // +++++++++++++++++++++++++++++++++++++++++++ // ++++++++++++ FINALIZATION +++++++++++++++++ // +++++++++++++++++++++++++++++++++++++++++++ // set the tweak for the output transformation first = 1; final = 1; tmsg = 0; tout = 1; pcarry = 0; T[0] = 8; T[1] = pow(2,63)*final + pow(2,62)*first + (pow(2,61)+pow(2,60)+pow(2,59)+pow(2,58)+pow(2,57)+pow(2,56))*tout + (pow(2,61)+pow(2,60))*tmsg + pcarry; printf("Last:\nT[0] = %016llX\nT[1] = %016llX\n\n", T[0], T[1]); // swap variables K[0] = G[0]; K[1] = G[1]; K[2] = G[2]; K[3] = G[3]; Min[0] = 0; Min[1] = 0; Min[2] = 0; Min[3] = 0; M[0] = 0; M[1] = 0; M[2] = 0; M[3] = 0; // re-run UBI for (s = 0; s < 18; s +=1) { subkey(M, K, T, s); if ((s % 2) == 0) permix1(M); else permix2(M); } subkey(M, K, T, 18); G[0] = xor(Min[0], M[0]); G[1] = xor(Min[1], M[1]); G[2] = xor(Min[2], M[2]); G[3] = xor(Min[3], M[3]); //printf("after XOR\n%llX \n", G[0]); //printf("%llX \n", G[1]); //printf("%llX \n", G[2]); //printf("%llX \n\n", G[3]); for (filler = 0; filler < (19*8+40); filler +=1) { //fprintf(stimuli,"1 0 0 1 1 0 1 00\n"); fprintf(stimuli,"1 0 1 %064X\n", 0); } fprintf(expresp,"%016llX%016llX%016llX%016llX\n", G[0], G[1], G[2], G[3]); // WRITE EXPRESP char bufout[65]; sprintf(bufout,"%016llX%016llX%016llX%016llX", G[0], G[1], G[2], G[3]); /*for (digit = 0; digit < 32; digit +=1){ fprintf(expresp,"%c%c\n", bufout[digit*2], bufout[digit*2+1]); } */ fclose(stimuli); fclose(expresp); return 0; } // function definitions are below... uint64_t xor(uint64_t x, uint64_t y) { //printf("%016llX %016llX %016llX\n", x, y, x^y); return x^y; } void subkey(uint64_t P[], uint64_t K[], uint64_t T[], unsigned short int s) { uint64_t Ks[4]; K[4] = xor(xor(xor(xor(0x5555555555555555, K[0]), K[1]), K[2]), K[3]); T[2] = xor(T[0], T[1]); //printf("Check:\nT[0] = %016llX\nT[1] = %016llX\nT[2] = %016llX\n", T[0], T[1], T[2]); Ks[0] = K[(s+0) % 5]; Ks[1] = (K[(s+1) % 5] + T[s % 3]); // % 18446744073709551616; Ks[2] = (K[(s+2) % 5] + T[(s+1) % 3]); // % 18446744073709551616; Ks[3] = (K[(s+3) % 5] + s); // % 18446744073709551616; /* printf("subkey sum %d\n", s); printf("%016llX %016llX %016llX\n", P[0], Ks[0], P[0]+Ks[0]); printf("%016llX %016llX %016llX\n", P[1], Ks[1], P[1]+Ks[1]); printf("%016llX %016llX %016llX\n", P[2], Ks[2], P[2]+Ks[2]); printf("%016llX %016llX %016llX\n\n", P[3], Ks[3], P[3]+Ks[3]); */ P[0] += Ks[0]; P[1] += Ks[1]; P[2] += Ks[2]; P[3] += Ks[3]; /* printf("subkey %d\n", s); printf("%llX\n", P[0]); printf("%llX\n", P[1]); printf("%llX\n", P[2]); printf("%llX\n\n", P[3]); */ } void permix1(uint64_t P[]) { int r; uint64_t Pout[4]; // Round 0 Pout[0] = (P[0] + P[1]); // % 18446744073709551616; r = 5; Pout[1] = P[1] << r; Pout[1] |= P[1] >> ((8 * sizeof(uint64_t)) - r); Pout[1] = xor(Pout[1], Pout[0]); Pout[2] = (P[2] + P[3]); // % 18446744073709551616; r = 56; Pout[3] = P[3] << r; Pout[3] |= P[3] >> ((8 * sizeof(uint64_t)) - r); Pout[3] = xor(Pout[3], Pout[2]); P[0] = Pout[0]; P[1] = Pout[3]; P[2] = Pout[2]; P[3] = Pout[1]; // Round 1 Pout[0] = (P[0] + P[1]); // % 18446744073709551616; r = 36; Pout[1] = P[1] << r; Pout[1] |= P[1] >> ((8 * sizeof(uint64_t)) - r); Pout[1] = xor(Pout[1], Pout[0]); Pout[2] = (P[2] + P[3]); // % 18446744073709551616; r = 28; Pout[3] = P[3] << r; Pout[3] |= P[3] >> ((8 * sizeof(uint64_t)) - r); Pout[3] = xor(Pout[3], Pout[2]); P[0] = Pout[0]; P[1] = Pout[3]; P[2] = Pout[2]; P[3] = Pout[1]; // Round 2 Pout[0] = (P[0] + P[1]); // % 18446744073709551616; r = 13; Pout[1] = P[1] << r; Pout[1] |= P[1] >> ((8 * sizeof(uint64_t)) - r); Pout[1] = xor(Pout[1], Pout[0]); Pout[2] = (P[2] + P[3]); // % 18446744073709551616; r = 46; Pout[3] = P[3] << r; Pout[3] |= P[3] >> ((8 * sizeof(uint64_t)) - r); Pout[3] = xor(Pout[3], Pout[2]); P[0] = Pout[0]; P[1] = Pout[3]; P[2] = Pout[2]; P[3] = Pout[1]; // Round 3 Pout[0] = (P[0] + P[1]); // % 18446744073709551616; r = 58; Pout[1] = P[1] << r; Pout[1] |= P[1] >> ((8 * sizeof(uint64_t)) - r); Pout[1] = xor(Pout[1], Pout[0]); Pout[2] = (P[2] + P[3]); // % 18446744073709551616; r = 44; Pout[3] = P[3] << r; Pout[3] |= P[3] >> ((8 * sizeof(uint64_t)) - r); Pout[3] = xor(Pout[3], Pout[2]); P[0] = Pout[0]; P[1] = Pout[3]; P[2] = Pout[2]; P[3] = Pout[1]; } void permix2(uint64_t P[]) { int r; uint64_t Pout[4]; // Round 4 Pout[0] = (P[0] + P[1]); // % 18446744073709551616; r = 26; Pout[1] = P[1] << r; Pout[1] |= P[1] >> ((8 * sizeof(uint64_t)) - r); Pout[1] = xor(Pout[1], Pout[0]); Pout[2] = (P[2] + P[3]); // % 18446744073709551616; r = 20; Pout[3] = P[3] << r; Pout[3] |= P[3] >> ((8 * sizeof(uint64_t)) - r); Pout[3] = xor(Pout[3], Pout[2]); P[0] = Pout[0]; P[1] = Pout[3]; P[2] = Pout[2]; P[3] = Pout[1]; // Round 5 Pout[0] = (P[0] + P[1]); // % 18446744073709551616; r = 53; Pout[1] = P[1] << r; Pout[1] |= P[1] >> ((8 * sizeof(uint64_t)) - r); Pout[1] = xor(Pout[1], Pout[0]); Pout[2] = (P[2] + P[3]); // % 18446744073709551616; r = 35; Pout[3] = P[3] << r; Pout[3] |= P[3] >> ((8 * sizeof(uint64_t)) - r); Pout[3] = xor(Pout[3], Pout[2]); P[0] = Pout[0]; P[1] = Pout[3]; P[2] = Pout[2]; P[3] = Pout[1]; // Round 6 Pout[0] = (P[0] + P[1]); // % 18446744073709551616; r = 11; Pout[1] = P[1] << r; Pout[1] |= P[1] >> ((8 * sizeof(uint64_t)) - r); Pout[1] = xor(Pout[1], Pout[0]); Pout[2] = (P[2] + P[3]); // % 18446744073709551616; r = 42; Pout[3] = P[3] << r; Pout[3] |= P[3] >> ((8 * sizeof(uint64_t)) - r); Pout[3] = xor(Pout[3], Pout[2]); P[0] = Pout[0]; P[1] = Pout[3]; P[2] = Pout[2]; P[3] = Pout[1]; // Round 7 Pout[0] = (P[0] + P[1]); // % 18446744073709551616; r = 59; Pout[1] = P[1] << r; Pout[1] |= P[1] >> ((8 * sizeof(uint64_t)) - r); Pout[1] = xor(Pout[1], Pout[0]); Pout[2] = (P[2] + P[3]); // % 18446744073709551616; r = 50; Pout[3] = P[3] << r; Pout[3] |= P[3] >> ((8 * sizeof(uint64_t)) - r); Pout[3] = xor(Pout[3], Pout[2]); P[0] = Pout[0]; P[1] = Pout[3]; P[2] = Pout[2]; P[3] = Pout[1]; }