#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 < 18; 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 < 18; 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; 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] = 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 < 18; 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 < 56; 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];

}





Generated on Fri Sep 24 10:39:12 CEST 2010
Home