speck3264.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. #include <stdio.h>
  2. #include <stdint.h>
  3. #include "speck.h"
  4. #include "helper.h"
  5. u8 random_seed[8] = {0x00};
  6. // This function is only used for the "x86" Speck compilation and as reference
  7. void FuncER16(u16 *x, u16 *y, u16 k)
  8. {
  9. u16 tmp_x = *x;
  10. u16 tmp_y = *y;
  11. *x = (((tmp_x)>>(7)) | ((tmp_x)<<(16-(7))));
  12. *x += *y;
  13. //*x = *x ^ k;
  14. *x = XOR(*x, k, random_seed[*x & 0x07]);
  15. *y = (((tmp_y)<<(2)) | (tmp_y>>(16-(2))));
  16. *y = XOR(*y, *x, *y);
  17. //*y = *y ^ *x;
  18. }
  19. #ifdef ARM
  20. // This function is used when running on the CW
  21. void FuncER16_ASM(u16 *x, u16 *y, u16 k)
  22. {
  23. asm volatile (
  24. "nop\n\t"
  25. "push {r4, r5, lr}\n\t"
  26. "ldrh r5, [r0, #0]\n\t"
  27. "ldrh r4, [r1, #0]\n\t"
  28. "lsls r3, r5, #9\n\t"
  29. "orr.w r3, r3, r5, lsr #7\n\t"
  30. "uxth r3, r3\n\t"
  31. "strh r3, [r0, #0]\n\t"
  32. "ldrh r5, [r1, #0]\n\t"
  33. "add r3, r5\n\t"
  34. "eors r2, r3\n\t"
  35. "lsls r3, r4, #2\n\t"
  36. "orr.w r3, r3, r4, lsr #14\n\t"
  37. "uxth r3, r3\n\t"
  38. "strh r2, [r0, #0]\n\t"
  39. "strh r3, [r1, #0]\n\t"
  40. "ldrh r2, [r0, #0]\n\t"
  41. "eors r3, r2\n\t"
  42. "strh r3, [r1, #0]\n\t"
  43. "pop {r4, r5, pc}\n\t"
  44. );
  45. }
  46. #endif
  47. void Words16ToBytes(u16 words[],u8 bytes[],int numwords)
  48. {
  49. int i,j=0;
  50. for(i=0;i<numwords;i++){
  51. bytes[j]=(u8)words[i];
  52. bytes[j+1]=(u8)(words[i]>>8);
  53. j+=2;
  54. }
  55. }
  56. void BytesToWords16(u8 bytes[],u16 words[],int numbytes)
  57. {
  58. int i,j=0; for(i=0;i<numbytes/2;i++){
  59. words[i]=(u16)bytes[j] | ((u16)bytes[j+1]<<8);
  60. j+=2;
  61. }
  62. }
  63. void Speck3264KeySchedule(u16 K[],u16 rk[])
  64. {
  65. u16 i,D=K[3],C=K[2],B=K[1],A=K[0];
  66. #ifdef ARM
  67. for(i=0;i<22;){
  68. rk[i]=A;
  69. //ER16(B,A,i++);
  70. FuncER16(&B,&A,i++);
  71. rk[i]=A;
  72. //ER16(C,A,i++);
  73. FuncER16(&C,&A,i++);
  74. rk[i]=A;
  75. //ER16(D,A,i++);
  76. FuncER16(&D,&A,i++);
  77. }
  78. #endif
  79. #ifndef ARM
  80. for(i=0;i<22;){
  81. printf("A = 0x%x ; B = 0x%x ; C = 0x%x ; D = 0x%x\n", A, B, C, D);
  82. rk[i]=A;
  83. //ER16(B,A,i++);
  84. FuncER16(&B, &A, i++);
  85. printf("rk[%d] = 0x%x\n", i-1, A);
  86. printf("A = 0x%x ; B = 0x%x ; C = 0x%x ; D = 0x%x\n", A, B, C, D);
  87. rk[i]=A;
  88. //ER16(C,A,i++);
  89. FuncER16(&C, &A, i++);
  90. printf("rk[%d] = 0x%x\n", i-1, A);
  91. printf("A = 0x%x ; B = 0x%x ; C = 0x%x ; D = 0x%x\n", A, B, C, D);
  92. rk[i]=A;
  93. //ER16(D,A,i++);
  94. FuncER16(&D, &A, i++);
  95. printf("rk[%d] = 0x%x\n <- D = 0x%x", i-1, A, D);
  96. printf("----------------------\n");
  97. }
  98. #endif
  99. }
  100. void Speck3264Encrypt(u16 Pt[],u16 Ct[],u16 rk[])
  101. {
  102. u16 i;
  103. Ct[0]=Pt[0]; Ct[1]=Pt[1];
  104. // full 22 rounds
  105. for(i=0;i<22;) {
  106. //ER16(Ct[1],Ct[0],rk[i++]);
  107. #ifdef ARM
  108. //FuncER16_ASM(&Ct[1], &Ct[0],rk[i++]);
  109. FuncER16(&Ct[1], &Ct[0], rk[i++]);
  110. #else
  111. FuncER16(&Ct[1], &Ct[0], rk[i++]);
  112. //ER16(Ct[1],Ct[0],rk[i++]);
  113. #endif
  114. }
  115. }
  116. void Speck3264Decrypt(u16 Pt[],u16 Ct[],u16 rk[])
  117. {
  118. int i;
  119. Pt[0]=Ct[0]; Pt[1]=Ct[1];
  120. for(i=21;i>=0;) DR16(Pt[1],Pt[0],rk[i--]);
  121. }
  122. // Add a random byte array
  123. void Speck3264_EncryptBlock(u8 pt[], u8 k[], u8 ct[], u8 rand[]) {
  124. u16 Pt[2] = {0};
  125. u16 K[4] = {0};
  126. u16 rk[34] = {0};
  127. u16 Ct[2] = {0};
  128. BytesToWords16(pt,Pt,8);
  129. BytesToWords16(k,K,16);
  130. // copy the random data to the global variable
  131. memcpy(random_seed, rand, 8);
  132. Speck3264KeySchedule(K,rk);
  133. #ifndef ARM
  134. // DEBUG Purposes
  135. for (int i=0; i < 16; i++)
  136. {
  137. printf("Key: 0x%x\n", rk[i]);
  138. }
  139. #endif
  140. Speck3264Encrypt(Pt,Ct,rk);
  141. Words16ToBytes(Ct,ct,2);
  142. }
  143. #ifndef ARM
  144. int main() {
  145. // test are from https://github.com/inmcm/Simon_Speck_Ciphers
  146. //u8 key[8] = {0x00, 0x01, 0x08, 0x09, 0x10, 0x11, 0x18, 0x19};
  147. u8 pt[4] = {0x4c, 0x69, 0x74, 0x65};
  148. u8 key[8] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88};
  149. u8 ct[4] = {0x0};
  150. Speck3264_EncryptBlock(pt, key, ct);
  151. printf("[[ Speck 32/64 ]]\n");
  152. printf("The output: \n");
  153. for (int i = 0; i < 4; i++) {
  154. printf("- %08x\n", ct[i]);
  155. }
  156. return 0;
  157. }
  158. #endif