SlowerPhoton

Untitled

Feb 10th, 2016
235
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include<LiquidCrystal.h>
  2. #include <EEPROM.h>
  3.  
  4. LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
  5.  
  6. void createSubkeys(byte binaryKey[8]);
  7. void encodeMessage(byte binaryMessage[64/8], byte encrypted[64/8]);
  8. void f(byte R[32/8], byte K[48/8], byte outcome[32/8]);
  9. void lookUpInSBox(size_t which, byte *address, byte *binaryOutcome, size_t addressFrom);
  10.  
  11. void setup() {
  12.   Serial.begin( 9600 );
  13.  
  14.   lcd.begin(16, 2);
  15.   Serial.println(F("ready"));
  16.  
  17.   // get a key and make subkeys
  18.   byte *binaryKey;
  19.   binaryKey = new byte[8] {155, 100, 30, 0, 25, 222, 25, 25};
  20.   createSubkeys(binaryKey);
  21.  
  22.   byte *binaryMessage;
  23.   binaryMessage = new byte[8] {155, 100, 30, 0, 25, 222, 25, 25};
  24.   byte *C;
  25.   //C = new byte[8];
  26.   encodeMessage(binaryMessage, C);
  27.  
  28.  
  29.  
  30. }
  31.  
  32. void loop() {
  33.   lcd.setCursor(0,0);
  34.   lcd.print(F("fff"));
  35. }
  36.  
  37. // the real integer pow
  38. int ipow(int base, int exp)
  39. {
  40.     int result = 1;
  41.     while (exp)
  42.     {
  43.         if (exp & 1)
  44.             result *= base;
  45.         exp >>= 1;
  46.         base *= base;
  47.     }
  48.  
  49.     return result;
  50. }
  51.  
  52. // returns the value of n-th int from an array of bytes
  53. bool bitValue ( byte* bytes, size_t n )
  54. {
  55.   size_t byteNum = n / 8;
  56.   n %= 8;
  57.  
  58.   byte Byte = *(bytes + byteNum);
  59.  
  60.   Byte >>= (8-n-1);
  61.   byte mask = 1;
  62.   Byte &= mask;
  63.   return Byte;
  64. }
  65.  
  66. // inserts a bit at a given position
  67. void insertBit ( byte* bytes, size_t n, bool value )
  68. {
  69.   size_t byteNum = n / 8;
  70.   n %= 8;
  71.  
  72.   if ( value )
  73.   {
  74.       byte mask = ipow(2, 8-n-1);
  75.       *(bytes+byteNum) |= mask;
  76.   }
  77.   else
  78.   {
  79.       byte mask = 255-ipow(2, 8-n-1);
  80.       *(bytes+byteNum) &= mask;
  81.   }
  82. }
  83.  
  84. // size of binary is in bytes
  85. void divideBinary(byte binary[], size_t sizeOfBinary, byte LB[], byte RB[]) {
  86.   size_t half = sizeOfBinary / 2;
  87.  
  88.   // LB - first half
  89.   size_t i = 0;
  90.   for (; i < half; i++) {
  91.     LB[i] = binary[i];
  92.   }
  93.  
  94.   // RB - second half
  95.   for (; i < half * 2; i++) {
  96.     RB[i - half] = binary[i];
  97.   }
  98. }
  99.  
  100. // size of binary is in bits
  101. void divideBinaryBit(byte* binary, size_t nmOfBits, byte* LB, byte* RB) {
  102.   size_t half = nmOfBits / 2;
  103.  
  104.   // LB - first half
  105.   size_t i = 0;
  106.   for (; i < half; i++) {
  107.     bool tmp = bitValue(binary, i);
  108.     insertBit(LB, i, tmp);
  109.   }
  110.  
  111.   // RB - second half
  112.   for (; i < half * 2; i++) {
  113.     bool tmp = bitValue(binary, i);
  114.     insertBit(LB, i, tmp);
  115.   }
  116. }
  117.  
  118. void overwrite(byte what[], byte with[], size_t noOfIndexes){
  119.     for (size_t i = 0; i < noOfIndexes; i++)
  120.         what[i] = with[i];
  121. }
  122.  
  123. void overwriteBit(byte *what, byte *with, size_t fromWhat, size_t fromWith, size_t noOfBits){
  124.     for (size_t i = 0; i < noOfBits; i++)
  125.         insertBit( what, fromWhat + i, bitValue( with, fromWith + i ) );
  126. }
  127.  
  128. void overwriteBit(bool what[], byte *with, size_t fromWhat, size_t fromWith, size_t noOfBits){
  129.     for (size_t i = 0; i < noOfBits; i++)
  130.         what[i + fromWhat] = bitValue( with, fromWith + i );
  131. }
  132.  
  133. void overwriteBit(byte *what, bool with[], size_t fromWhat, size_t fromWith, size_t noOfBits){
  134.     for (size_t i = 0; i < noOfBits; i++){
  135.         insertBit( what, fromWhat + i, with[ fromWith + i] );
  136.     }
  137. }
  138.  
  139. /*void overwriteBit(byte *what, byte *with, size_t fromWhat, size_t fromWith, size_t noOfBits){
  140.     for (size_t i = 0; i < noOfBits; i++)
  141.         insertBit( what, fromWhat + i, with[ fromWith + i] );
  142. }*/
  143.  
  144.  
  145. bool XOR(bool a, bool b){
  146.     return a ^ b;
  147. }
  148.  
  149. /*
  150. void XOR(byte where[], byte arr1[], byte arr2[], size_t noOfBits){
  151.     for(size_t i = 0; i < noOfBits; i++){
  152.         where[i] = arr1[i] ^ arr2[i];
  153.     }
  154. }*/
  155.  
  156. int toDecimal(bool binary[], int noOfNumbers){
  157.     int powOf2 = 1;
  158.     int decimal = 0;
  159.  
  160.     for(int i = noOfNumbers-1; i >= 0; i--){
  161.         decimal += powOf2*binary[i];
  162.         powOf2*=2;
  163.     }
  164.  
  165.     return decimal;
  166. }
  167.  
  168. void debugArray(byte *arr, size_t from, size_t to){
  169.     for (size_t i = from; i < to; i++){
  170.       Serial.print('\t');
  171.       Serial.print(i);
  172.       Serial.print(": ");
  173.       Serial.println(bitValue(arr, i));
  174.     }
  175. }
  176.  
  177. void debugArray(bool arr[], size_t from, size_t to){
  178.     for (size_t i = from; i < to; i++){
  179.       Serial.print('\t');
  180.       Serial.print(i);
  181.       Serial.print(": ");
  182.       Serial.println(arr[i]);
  183.     }
  184. }
  185.  
  186. bool encr = true;
  187. int8_t debug = 0;
  188.  
  189. void lookUpInSBox(size_t which, byte *address, byte* binaryOutcome, size_t addressFrom){
  190.  
  191.     size_t* Byte;
  192.     Byte = new size_t {addressFrom/8};
  193.     addressFrom%=8;
  194.     address+=*Byte;
  195.     //if (debug == 0)Serial.println(*Byte);
  196.     delete Byte;
  197.  
  198.     const uint8_t SBoxes[8][4][16] PROGMEM = {
  199.  
  200.                              /*S1*/
  201.  
  202.    { {14,  4,  13,  1,   2, 15,  11,  8,   3, 10,   6, 12,   5,  9,   0,  7},
  203.      { 0, 15,   7,  4,  14,  2,  13,  1,  10,  6,  12, 11,   9,  5,   3,  8},
  204.      { 4,  1,  14,  8,  13,  6,   2, 11,  15, 12,   9,  7,   3, 10,   5,  0},
  205.      {15, 12,   8,  2,   4,  9,   1,  7,   5, 11,   3, 14,  10,  0,   6, 13}    },
  206.  
  207.                              /*S2*/
  208.  
  209.    { {15,  1,   8, 14,   6, 11,   3,  4,   9,  7,   2, 13,  12,  0,   5, 10,},
  210.      { 3, 13,   4,  7,  15,  2,   8, 14,  12,  0,   1, 10,   6,  9,  11,  5,},
  211.      { 0, 14,   7, 11,  10,  4,  13,  1,   5,  8,  12,  6,   9,  3,   2, 15,},
  212.      {13,  8,  10,  1,   3, 15,   4,  2,  11,  6,   7, 12,   0,  5,  14,  9}    },
  213.  
  214.                              /*S3*/
  215.  
  216.    { {10,  0,   9, 14,   6,  3,  15,  5,   1, 13,  12,  7,  11,  4,   2,  8,},
  217.      {13,  7,   0,  9,   3,  4,   6, 10,   2,  8,   5, 14,  12, 11,  15,  1,},
  218.      {13,  6,   4,  9,   8, 15,   3,  0,  11,  1,   2, 12,   5, 10,  14,  7,},
  219.      { 1, 10,  13,  0,   6,  9,   8,  7,   4, 15,  14,  3,  11,  5,   2, 12}     },
  220.  
  221.                              /*S4*/
  222.  
  223.    { { 7, 13,  14,  3,   0,  6,   9, 10,   1,  2,   8,  5,  11, 12,   4, 15,},
  224.      {13,  8,  11,  5,   6, 15,   0,  3,   4,  7,   2, 12,   1, 10,  14,  9,},
  225.      {10,  6,   9,  0,  12, 11,   7, 13,  15,  1,   3, 14,   5,  2,   8,  4,},
  226.      { 3, 15,   0,  6,  10,  1,  13,  8,   9,  4,   5, 11,  12,  7,   2, 14}     },
  227.  
  228.                              /*S5*/
  229.  
  230.    { { 2, 12,   4,  1,   7, 10,  11,  6,   8,  5,   3, 15,  13,  0,  14,  9,},
  231.      {14, 11,   2, 12,   4,  7,  13,  1,   5,  0,  15, 10,   3,  9,   8,  6,},
  232.      { 4,  2,   1, 11,  10, 13,   7,  8,  15,  9,  12,  5,   6,  3,   0, 14,},
  233.      {11,  8,  12,  7,   1, 14,   2, 13,   6, 15,   0,  9,  10,  4,   5,  3}     },
  234.  
  235.                              /*S6*/
  236.  
  237.    { {12,  1,  10, 15,   9,  2,   6,  8,   0, 13,   3,  4,  14,  7,   5, 11,},
  238.      {10, 15,   4,  2,   7, 12,   9,  5,   6,  1,  13, 14,   0, 11,   3,  8,},
  239.      { 9, 14,  15,  5,   2,  8,  12,  3,   7,  0,   4, 10,   1, 13,  11,  6,},
  240.      { 4,  3,   2, 12,   9,  5,  15, 10,  11, 14,   1,  7,   6,  0,   8, 13}     },
  241.  
  242.                              /*S7*/
  243.  
  244.    { { 4, 11,   2, 14,  15,  0,   8, 13,   3, 12,   9,  7,   5, 10,   6,  1,},
  245.      {13,  0,  11,  7,   4,  9,   1, 10,  14,  3,   5, 12,   2, 15,   8,  6,},
  246.      { 1,  4,  11, 13,  12,  3,   7, 14,  10, 15,   6,  8,   0,  5,   9,  2,},
  247.      { 6, 11,  13,  8,   1,  4,  10,  7,   9,  5,   0, 15,  14,  2,   3, 12}     },
  248.  
  249.                              /*S8*/
  250.  
  251.    { {13,  2,   8,  4,   6, 15,  11,  1,  10,  9,   3, 14,   5,  0,  12,  7,},
  252.      { 1, 15,  13,  8,  10,  3,   7,  4,  12,  5,   6, 11,   0, 14,   9,  2,},
  253.      { 7, 11,   4,  1,   9, 12,  14,  2,   0,  6,  10, 13,  15,  3,   5,  8,},
  254.      { 2,  1,  14,  7,   4, 10,   8, 13,  15, 12,   9,  0,   3,  5,   6, 11}     }
  255.  
  256.                         };
  257.  
  258.     // row corresponds to the binary number consisting of the first and last index of address
  259.     bool *row;
  260.     row = new bool[2];
  261.     row[0] = bitValue( address, 0 + addressFrom );
  262.     row[1] = bitValue( address, 5 + addressFrom );
  263.  
  264.      
  265.             /*if (debug == 0){
  266.               //debugArray(&answer, 0, 4);
  267.               Serial.println(*address);
  268.               Serial.println(addressFrom);
  269.               Serial.println(row[0]);
  270.               Serial.println(row[1]);
  271.             }debug++;*/
  272.  
  273.     // column corresponds to the middle 4 bits of address
  274.     bool *column;
  275.     column = new bool[4];
  276.     overwriteBit(column, address, 0, addressFrom + 1, 4);
  277.  
  278.     uint8_t number = SBoxes[which][toDecimal(row, 2)][toDecimal(column, 4)];
  279.     delete[] row; delete[] column;
  280.  
  281.     // convert number to binary number saved in answer
  282.     bool answer[4] = {0,0,0,0};
  283.     uint8_t powOf2 = 8;
  284.     for(short i = 0; i < 4; i++){
  285.         if(number >= powOf2){
  286.             answer[i] = 1;
  287.             number -= powOf2;
  288.         }
  289.  
  290.         powOf2/=2;
  291.     }
  292.  
  293.     // copy answer to binaryOutcome
  294.     overwriteBit(binaryOutcome, answer, 0, 0, 4);
  295. }
  296.  
  297. void f(byte R[32/8], byte K[48/8], byte outcome[32/8]){
  298.    
  299.     // expand each R from 32 to 48 bits to E
  300.     const uint8_t E_BIT[48] PROGMEM = {
  301.                  32,     1,    2,     3,     4,    5,
  302.                   4,     5,    6,     7,     8,    9,
  303.                   8,     9,   10,    11,    12,   13,
  304.                  12,    13,   14,    15,    16,   17,
  305.                  16,    17,   18,    19,    20,   21,
  306.                  20,    21,   22,    23,    24,   25,
  307.                  24,    25,   26,    27,    28,   29,
  308.                  28,    29,   30,    31,    32,    1
  309.     };
  310.  
  311.     byte *E;
  312.     E = new byte[48/8];  
  313.     for(size_t i = 0; i < 48; i++){
  314.         insertBit( E, i, bitValue( R, E_BIT[i]-1 ) );
  315.     }
  316.    
  317.     // XOR Kn and  E(Rn-1)
  318.     byte KxorE[48/8];
  319.     for (size_t i = 0; i < 48; i++){
  320.         insertBit( KxorE, i, bitValue( K, i ) ^ bitValue( E, i ) );
  321.     }
  322.     delete[] E;
  323.  
  324.     // each array of 6 bits from KxorE is used as an address in S boxes, thus obtaining a 4-bit number
  325.     byte S[32/8];
  326.     for(short i = 0; i < 48; i+=6){
  327.         byte answer; // only first 4 bits are always used
  328.         lookUpInSBox(i/6, KxorE, &answer, i); // save what we find in S-boxes into answer (its first 4 bits)  
  329.         overwriteBit(S, &answer, (i/6)*4, 0, 4);
  330.     }
  331.  
  332.     if (debug == 0){
  333.       debugArray(S, 0, 32);
  334.       debug = 3;
  335.     }
  336.  
  337.     // now we use P to permute S[] to finally create the outcome
  338.     const uint8_t P[32] PROGMEM = {
  339.                          16,   7,  20,  21,
  340.                          29,  12,  28,  17,
  341.                           1,  15,  23,  26,
  342.                           5,  18,  31,  10,
  343.                           2,   8,  24,  14,
  344.                          32,  27,   3,   9,
  345.                          19,  13,  30,   6,
  346.                          22,  11,   4,  25
  347.     };
  348.  
  349.     for (size_t i = 0; i < 32; i++){
  350.         //outcome[i] = S[P[i]-1];
  351.         insertBit( outcome, i, bitValue( S, P[i]-1 ) );
  352.     }
  353. }
  354.  
  355. void encodeMessage(byte binaryMessage[64/8], byte encrypted[64/8]){
  356.     // permute binaryMessage by IP to permutedMessage
  357.     const uint8_t IP[64] PROGMEM = {
  358.             58,    50,   42,    34,    26,   18,    10,    2,
  359.             60,    52,   44,    36,    28,   20,    12,    4,
  360.             62,    54,   46,    38,    30,   22,    14,    6,
  361.             64,    56,   48,    40,    32,   24,    16,    8,
  362.             57,    49,   41,    33,    25,   17,     9,    1,
  363.             59,    51,   43,    35,    27,   19,    11,    3,
  364.             61,    53,   45,    37,    29,   21,    13,    5,
  365.             63,    55,   47,    39,    31,   23,    15,    7
  366.     };
  367.  
  368.     byte *permutedMessage;
  369.     permutedMessage = new byte[64/8];
  370.  
  371.     for(int i = 0; i < 64; i++){
  372.         insertBit( permutedMessage, i, bitValue( binaryMessage, IP[i]-1 ) );
  373.     }
  374.     delete[] binaryMessage;
  375.  
  376.     // create L0 and R0 by dividing permutedMessage, the second index represents L [0] for first 4 bytes and  R for last 4
  377.     //byte LR[17][64/8]; // gonna be saved on EEPROM from index 96 to 17*64/8+96 = 232
  378.     for (size_t address = 96; address < 96+8; address++){
  379.       EEPROM.write( address, *(permutedMessage + address - 96) );
  380.     }
  381.     delete[] permutedMessage;
  382.  
  383.     for(short i = 1; i <= 16; i++){
  384.  
  385.         // subkeys are on EEPROM (first 16*48/8 bytes that is first 96) so we need to load the current row first
  386.         byte subkeys[48/8];
  387.         if (encr)
  388.           for (size_t address = (i-1)*6; address < (i-1)*6+6; address++){
  389.             subkeys[address%6] = EEPROM.read( address );
  390.           }
  391.         else
  392.           for (size_t address = (16-i)*6; address < (16-i)*6+6; address++){
  393.             subkeys[address%6] = EEPROM.read( address );
  394.           }
  395.  
  396.          // LR is on EEPROM so we need to load it first (begins at index 96, size is [17][64/8] bytes)
  397.          byte LR[2][8];
  398.          for (size_t address = 96+((i-1)*8); address < 96+((i-1)*8) + 16; address++){
  399.            *(LR[0]+address-96) = EEPROM.read( address );
  400.          }
  401.      
  402.         overwrite(LR[1], LR[0]+4, 64/8/2); // Ln = Rn-1
  403.         // Rn = Ln-1 + f(Rn-1,Kn):
  404.         byte outcome[32/8];
  405.         if(encr == true) // according to the choice of the user: encrypt or decrypt
  406.             f(LR[0]+4, subkeys, outcome); // call the function f for Rn-1,Kn
  407.         else
  408.             f(LR[0]+4, subkeys, outcome); // call the function f for Rn-1,Kn
  409.         //if (i == 1) debugArray(outcome, 0, 32);
  410.  
  411.         //XOR(addition, LR[0][i-1], outcome, 32);
  412.         for (size_t i = 0; i < 32; i++){
  413.             insertBit( outcome, i, bitValue( LR[0], i ) ^ bitValue( outcome, i ) );
  414.         }
  415.  
  416.         // addition, which correspond to Ln-1 + f(Rn-1,Kn) is now copied to Rn
  417.         overwrite(LR[1]+4, outcome, 32/8);
  418.  
  419.         // update LR on EEPROM
  420.         for (size_t address = 96+(i-1)*8; address < 96+(i-1)*8+16; address++){
  421.           EEPROM.write( address, *(LR[0] + address - 96) );
  422.         }
  423.        
  424.     }
  425.     //debugArray(LR[16], 0, 64);
  426.  
  427.     /*// R16L16 after the permutation by IP-1 corresponds to the encrypted/decrypted message C
  428.  
  429.     int IP_1[64] = {
  430.             40,     8,   48,    16,    56,   24,    64,   32,
  431.             39,     7,   47,    15,    55,   23,    63,   31,
  432.             38,     6,   46,    14,    54,   22,    62,   30,
  433.             37,     5,   45,    13,    53,   21,    61,   29,
  434.             36,     4,   44,    12,    52,   20,    60,   28,
  435.             35,     3,   43,    11,    51,   19,    59,   27,
  436.             34,     2,   42,    10,    50,   18,    58,   26,
  437.             33,     1,   41,     9,    49,   17,    57,   25
  438.     };
  439.  
  440.     bool R16L16[64];
  441.     overwrite(R16L16, LR[1][16], 32); // R16
  442.     overwrite(R16L16 + 32, LR[0][16], 32); // L16
  443.  
  444.     bool C[64];
  445.     permutation(IP_1, R16L16, C, 64);
  446.  
  447.     overwrite(encrypted, C, 64);*/
  448. }
  449.  
  450. #include <avr/pgmspace.h>
  451.  
  452. // rotates 28 bits to left
  453. void leftShift(byte *toShift, uint8_t noOfShifts, byte* destination, bool L) {
  454.   size_t fromBit; // because L and R share one byte, we need to consider the initial bit as well
  455.   if (L) fromBit = 0;
  456.   else fromBit = 28%8; // that's 4
  457.  
  458.   for (int i = 0; i < 28; i++) {
  459.     insertBit(destination, fromBit + (i - noOfShifts + 28) % 28, bitValue(toShift, i + fromBit));
  460.   }
  461. }
  462.  
  463. void createSubkeys(byte *binaryKey) {
  464.   const uint8_t pc_1[56] PROGMEM = {
  465.     57, 49, 41, 33, 25, 17,  9,
  466.     1, 58, 50, 42, 34, 26, 18,
  467.     10,  2, 59, 51, 43, 35, 27,
  468.     19, 11,  3, 60, 52, 44, 36,
  469.     63, 55, 47, 39, 31, 23, 15,
  470.     7, 62, 54, 46, 38, 30, 22,
  471.     14,  6, 61, 53, 45, 37, 29,
  472.     21, 13,  5, 28, 20, 12,  4
  473.   };
  474.   byte* keyPermutation;
  475.   keyPermutation = new byte[56/8];
  476.  
  477.  
  478.   // according to pc_1 create from 64-bit key 56-bit keyPermutation
  479.   for (size_t i = 0; i < 56; i++) {
  480.     bool tmp = bitValue(binaryKey, pc_1[i] - 1);
  481.     insertBit(keyPermutation, i, tmp);
  482.   }
  483.   delete[] binaryKey;
  484.    
  485.   // C and D will be saved here: [index] [7 bytes] - first 28 bits are left part, the rest right part
  486.   byte CD[16 + 1][56 / 8];
  487.  
  488.   // divide keyPermutation into halves to C0 a D0 - each consists of 28 bits
  489.   divideBinaryBit(keyPermutation, 56, CD[0], CD[0]+28);
  490.   delete[] keyPermutation;
  491.  
  492.   // from C0, D0 and shifts make C1, D1 -> C16, D16
  493.   const uint8_t shifts[16] PROGMEM = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };
  494.   for (size_t i = 1; i < 17; i++) {
  495.     leftShift(CD[i - 1], shifts[i - 1], CD[i], true);
  496.     leftShift(CD[i - 1]+3, shifts[i - 1], CD[i]+3, false); // we need to start from the beginning of the right half - that is 3 bytes + 4 bits (shift takes care of the bits)
  497.   }
  498.  
  499.   // each subKey out of 16 is made from one out of 16 CD with the use of pc_2
  500.   const uint8_t pc_2[48] PROGMEM = {
  501.     14,    17,   11,    24,     1,    5,
  502.     3,    28,   15,     6,    21,   10,
  503.     23,    19,   12,     4,    26,    8,
  504.     16,     7,   27,    20,    13,    2,
  505.     41,    52,   31,    37,    47,   55,
  506.     30,    40,   51,    45,    33,   48,
  507.     44,    49,   39,    56,    34,   53,
  508.     46,    42,   50,    36,    29,   32
  509.   };
  510.  
  511.   byte subkeys[16][48/8];
  512.   for (int i = 0; i < 16; i++) {
  513.     for (int j = 0; j < 48; j++) {
  514.       insertBit( subkeys[i], j, bitValue( CD[i+1], pc_2[j] - 1 ) );
  515.     }
  516.   }
  517.  
  518.   for (size_t address = 0; address < 16*6; address++){
  519.         EEPROM.write( address, *(subkeys[0] + address) );
  520.   }
  521. }
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×