0
$\begingroup$

I wanted to test the implementation of the Salsa20/8 Core function provided in the RFC 7914, with the test vectors provided, and I do not get the expected output from provided input. I guess that I am not using the input properly, but I am afraid I need help... Here is my code:

#include <stdio.h>

int main() {

  unsigned int in[16];
  unsigned int x[16];
  unsigned int out[16];

  /*
  <https://datatracker.ietf.org/doc/html/rfc7914#section-8>
  INPUT:
  7e 87 9a 21 4f 3e c9 86 7c a9 40 e6 41 71 8f 26
  ba ee 55 5b 8c 61 c1 b5 0d f8 46 11 6d cd 3b 1d
  ee 24 f3 19 df 9b 3d 85 14 12 1e 4b 5a c5 aa 32
  76 02 1d 29 09 c7 48 29 ed eb c6 8d b8 b8 c2 5e
  */

  in[ 0] = 0x7e879a21;
  in[ 1] = 0x4f3ec986;
  in[ 2] = 0x7ca940e6;
  in[ 3] = 0x41718f26;
  in[ 4] = 0xbaee555b;
  in[ 5] = 0x8c61c1b5;
  in[ 6] = 0x0df84611;
  in[ 7] = 0x6dcd3b1d;
  in[ 8] = 0xee24f319;
  in[ 9] = 0xdf9b3d85;
  in[10] = 0x14121e4b;
  in[11] = 0x5ac5aa32;
  in[12] = 0x76021d29;
  in[13] = 0x09c74829;
  in[14] = 0xedebc68d;
  in[15] = 0xb8b8c25e;


  /* <https://datatracker.ietf.org/doc/html/rfc7914#section-3> */
  #define R(a,b) (((a) << (b)) | ((a) >> (32 - (b))))
  int i;
  for (i = 0;i < 16;++i) x[i] = in[i];
  for (i = 8;i > 0;i -= 2) {
   x[ 4] ^= R(x[ 0]+x[12], 7);  x[ 8] ^= R(x[ 4]+x[ 0], 9);
   x[12] ^= R(x[ 8]+x[ 4],13);  x[ 0] ^= R(x[12]+x[ 8],18);
   x[ 9] ^= R(x[ 5]+x[ 1], 7);  x[13] ^= R(x[ 9]+x[ 5], 9);
   x[ 1] ^= R(x[13]+x[ 9],13);  x[ 5] ^= R(x[ 1]+x[13],18);
   x[14] ^= R(x[10]+x[ 6], 7);  x[ 2] ^= R(x[14]+x[10], 9);
   x[ 6] ^= R(x[ 2]+x[14],13);  x[10] ^= R(x[ 6]+x[ 2],18);
   x[ 3] ^= R(x[15]+x[11], 7);  x[ 7] ^= R(x[ 3]+x[15], 9);
   x[11] ^= R(x[ 7]+x[ 3],13);  x[15] ^= R(x[11]+x[ 7],18);
   x[ 1] ^= R(x[ 0]+x[ 3], 7);  x[ 2] ^= R(x[ 1]+x[ 0], 9);
   x[ 3] ^= R(x[ 2]+x[ 1],13);  x[ 0] ^= R(x[ 3]+x[ 2],18);
   x[ 6] ^= R(x[ 5]+x[ 4], 7);  x[ 7] ^= R(x[ 6]+x[ 5], 9);
   x[ 4] ^= R(x[ 7]+x[ 6],13);  x[ 5] ^= R(x[ 4]+x[ 7],18);
   x[11] ^= R(x[10]+x[ 9], 7);  x[ 8] ^= R(x[11]+x[10], 9);
   x[ 9] ^= R(x[ 8]+x[11],13);  x[10] ^= R(x[ 9]+x[ 8],18);
   x[12] ^= R(x[15]+x[14], 7);  x[13] ^= R(x[12]+x[15], 9);
   x[14] ^= R(x[13]+x[12],13);  x[15] ^= R(x[14]+x[13],18);
  }
  for (i = 0;i < 16;++i) out[i] = x[i] + in[i];

  printf("in[ 0] = 0x%08x | out[ 0] = 0x%08x\n", in[ 0], out[ 0]);
  printf("in[ 1] = 0x%08x | out[ 1] = 0x%08x\n", in[ 1], out[ 1]);
  printf("in[ 2] = 0x%08x | out[ 2] = 0x%08x\n", in[ 2], out[ 2]);
  printf("in[ 3] = 0x%08x | out[ 3] = 0x%08x\n", in[ 3], out[ 3]);
  printf("in[ 4] = 0x%08x | out[ 4] = 0x%08x\n", in[ 4], out[ 4]);
  printf("in[ 5] = 0x%08x | out[ 5] = 0x%08x\n", in[ 5], out[ 5]);
  printf("in[ 6] = 0x%08x | out[ 6] = 0x%08x\n", in[ 6], out[ 6]);
  printf("in[ 7] = 0x%08x | out[ 7] = 0x%08x\n", in[ 7], out[ 7]);
  printf("in[ 8] = 0x%08x | out[ 8] = 0x%08x\n", in[ 8], out[ 8]);
  printf("in[ 9] = 0x%08x | out[ 9] = 0x%08x\n", in[ 9], out[ 9]);
  printf("in[10] = 0x%08x | out[10] = 0x%08x\n", in[10], out[10]);
  printf("in[11] = 0x%08x | out[11] = 0x%08x\n", in[11], out[11]);
  printf("in[12] = 0x%08x | out[12] = 0x%08x\n", in[12], out[12]);
  printf("in[13] = 0x%08x | out[13] = 0x%08x\n", in[13], out[13]);
  printf("in[14] = 0x%08x | out[14] = 0x%08x\n", in[14], out[14]);
  printf("in[15] = 0x%08x | out[15] = 0x%08x\n", in[15], out[15]);

  return 0;
}

/*
RESULT:
in[ 0] = 0x7e879a21 | out[ 0] = 0x4f027d2d
in[ 1] = 0x4f3ec986 | out[ 1] = 0x4d5b0cd1
in[ 2] = 0x7ca940e6 | out[ 2] = 0x3ee27bc6
in[ 3] = 0x41718f26 | out[ 3] = 0xcfbc626d
in[ 4] = 0xbaee555b | out[ 4] = 0xb577900a
in[ 5] = 0x8c61c1b5 | out[ 5] = 0x034adb4a
in[ 6] = 0x0df84611 | out[ 6] = 0x45cc3314
in[ 7] = 0x6dcd3b1d | out[ 7] = 0x3bdc106b
in[ 8] = 0xee24f319 | out[ 8] = 0x7fac24dd
in[ 9] = 0xdf9b3d85 | out[ 9] = 0x9a53c287
in[10] = 0x14121e4b | out[10] = 0x719eb5c5
in[11] = 0x5ac5aa32 | out[11] = 0x291ded16
in[12] = 0x76021d29 | out[12] = 0x2e3a5184
in[13] = 0x09c74829 | out[13] = 0xa4d4d61a
in[14] = 0xedebc68d | out[14] = 0x191ff4df
in[15] = 0xb8b8c25e | out[15] = 0xef2671d8

<https://datatracker.ietf.org/doc/html/rfc7914#section-8>
INPUT:
7e 87 9a 21 4f 3e c9 86 7c a9 40 e6 41 71 8f 26
ba ee 55 5b 8c 61 c1 b5 0d f8 46 11 6d cd 3b 1d
ee 24 f3 19 df 9b 3d 85 14 12 1e 4b 5a c5 aa 32
76 02 1d 29 09 c7 48 29 ed eb c6 8d b8 b8 c2 5e
OUTPUT:
a4 1f 85 9c 66 08 cc 99 3b 81 ca cb 02 0c ef 05
04 4b 21 81 a2 fd 33 7d fd 7b 1c 63 96 68 2f 29
b4 39 31 68 e3 c9 e6 bc fe 6b c5 b7 a0 6d 96 ba
e4 24 cc 10 2c 91 74 5c 24 ad 67 3d c7 61 8f 81
*/

I am simply running my code with https://www.programiz.com/c-programming/online-compiler/ to get the output. I hope you can help to spot my mistake...

$\endgroup$
1
  • $\begingroup$ have you checked big/little endian of implementation ? I think implementation questions do not belong here. $\endgroup$
    – hardyrama
    Commented Oct 10, 2021 at 4:06

1 Answer 1

1
$\begingroup$

OK, as expected it was an "endianness issue". By using the following SHIFT(x) macro on both input and output, I do retrieve the test vectors:

#define SHIFT(x) ((x) << 24 | ((x) & 0x0000ff00) << 8 | ((x) & 0x00ff0000) >> 8 | ((x) & 0xff000000) >> 24)

Here is the complete code:

#include <stdio.h>

int main() {

  unsigned int in[16];
  unsigned int x[16];
  unsigned int out[16];

  /*
  <https://datatracker.ietf.org/doc/html/rfc7914#section-8>
  INPUT:
  7e 87 9a 21 4f 3e c9 86 7c a9 40 e6 41 71 8f 26
  ba ee 55 5b 8c 61 c1 b5 0d f8 46 11 6d cd 3b 1d
  ee 24 f3 19 df 9b 3d 85 14 12 1e 4b 5a c5 aa 32
  76 02 1d 29 09 c7 48 29 ed eb c6 8d b8 b8 c2 5e
  */

  #define SHIFT(x) ((x) << 24 | ((x) & 0x0000ff00) << 8 | ((x) & 0x00ff0000) >> 8 | ((x) & 0xff000000) >> 24)

  in[ 0] = SHIFT(0x7e879a21);
  in[ 1] = SHIFT(0x4f3ec986);
  in[ 2] = SHIFT(0x7ca940e6);
  in[ 3] = SHIFT(0x41718f26);
  in[ 4] = SHIFT(0xbaee555b);
  in[ 5] = SHIFT(0x8c61c1b5);
  in[ 6] = SHIFT(0x0df84611);
  in[ 7] = SHIFT(0x6dcd3b1d);
  in[ 8] = SHIFT(0xee24f319);
  in[ 9] = SHIFT(0xdf9b3d85);
  in[10] = SHIFT(0x14121e4b);
  in[11] = SHIFT(0x5ac5aa32);
  in[12] = SHIFT(0x76021d29);
  in[13] = SHIFT(0x09c74829);
  in[14] = SHIFT(0xedebc68d);
  in[15] = SHIFT(0xb8b8c25e);

  /* <https://datatracker.ietf.org/doc/html/rfc7914#section-3> */
  #define R(a,b) (((a) << (b)) | ((a) >> (32 - (b))))
  int i;
  for (i = 0;i < 16;++i) x[i] = in[i];
  for (i = 8;i > 0;i -= 2) {
   x[ 4] ^= R(x[ 0]+x[12], 7);  x[ 8] ^= R(x[ 4]+x[ 0], 9);
   x[12] ^= R(x[ 8]+x[ 4],13);  x[ 0] ^= R(x[12]+x[ 8],18);
   x[ 9] ^= R(x[ 5]+x[ 1], 7);  x[13] ^= R(x[ 9]+x[ 5], 9);
   x[ 1] ^= R(x[13]+x[ 9],13);  x[ 5] ^= R(x[ 1]+x[13],18);
   x[14] ^= R(x[10]+x[ 6], 7);  x[ 2] ^= R(x[14]+x[10], 9);
   x[ 6] ^= R(x[ 2]+x[14],13);  x[10] ^= R(x[ 6]+x[ 2],18);
   x[ 3] ^= R(x[15]+x[11], 7);  x[ 7] ^= R(x[ 3]+x[15], 9);
   x[11] ^= R(x[ 7]+x[ 3],13);  x[15] ^= R(x[11]+x[ 7],18);
   x[ 1] ^= R(x[ 0]+x[ 3], 7);  x[ 2] ^= R(x[ 1]+x[ 0], 9);
   x[ 3] ^= R(x[ 2]+x[ 1],13);  x[ 0] ^= R(x[ 3]+x[ 2],18);
   x[ 6] ^= R(x[ 5]+x[ 4], 7);  x[ 7] ^= R(x[ 6]+x[ 5], 9);
   x[ 4] ^= R(x[ 7]+x[ 6],13);  x[ 5] ^= R(x[ 4]+x[ 7],18);
   x[11] ^= R(x[10]+x[ 9], 7);  x[ 8] ^= R(x[11]+x[10], 9);
   x[ 9] ^= R(x[ 8]+x[11],13);  x[10] ^= R(x[ 9]+x[ 8],18);
   x[12] ^= R(x[15]+x[14], 7);  x[13] ^= R(x[12]+x[15], 9);
   x[14] ^= R(x[13]+x[12],13);  x[15] ^= R(x[14]+x[13],18);
  }
  for (i = 0;i < 16;++i) out[i] = x[i] + in[i];

  printf("in[ 0] = 0x%08x | out[ 0] = 0x%08x\n", in[ 0], SHIFT(out[ 0]));
  printf("in[ 1] = 0x%08x | out[ 1] = 0x%08x\n", in[ 1], SHIFT(out[ 1]));
  printf("in[ 2] = 0x%08x | out[ 2] = 0x%08x\n", in[ 2], SHIFT(out[ 2]));
  printf("in[ 3] = 0x%08x | out[ 3] = 0x%08x\n", in[ 3], SHIFT(out[ 3]));
  printf("in[ 4] = 0x%08x | out[ 4] = 0x%08x\n", in[ 4], SHIFT(out[ 4]));
  printf("in[ 5] = 0x%08x | out[ 5] = 0x%08x\n", in[ 5], SHIFT(out[ 5]));
  printf("in[ 6] = 0x%08x | out[ 6] = 0x%08x\n", in[ 6], SHIFT(out[ 6]));
  printf("in[ 7] = 0x%08x | out[ 7] = 0x%08x\n", in[ 7], SHIFT(out[ 7]));
  printf("in[ 8] = 0x%08x | out[ 8] = 0x%08x\n", in[ 8], SHIFT(out[ 8]));
  printf("in[ 9] = 0x%08x | out[ 9] = 0x%08x\n", in[ 9], SHIFT(out[ 9]));
  printf("in[10] = 0x%08x | out[10] = 0x%08x\n", in[10], SHIFT(out[10]));
  printf("in[11] = 0x%08x | out[11] = 0x%08x\n", in[11], SHIFT(out[11]));
  printf("in[12] = 0x%08x | out[12] = 0x%08x\n", in[12], SHIFT(out[12]));
  printf("in[13] = 0x%08x | out[13] = 0x%08x\n", in[13], SHIFT(out[13]));
  printf("in[14] = 0x%08x | out[14] = 0x%08x\n", in[14], SHIFT(out[14]));
  printf("in[15] = 0x%08x | out[15] = 0x%08x\n", in[15], SHIFT(out[15]));

  return 0;
}

/*
OUTPUT:
in[ 0] = 0x219a877e | out[ 0] = 0xa41f859c
in[ 1] = 0x86c93e4f | out[ 1] = 0x6608cc99
in[ 2] = 0xe640a97c | out[ 2] = 0x3b81cacb
in[ 3] = 0x268f7141 | out[ 3] = 0x020cef05
in[ 4] = 0x5b55eeba | out[ 4] = 0x044b2181
in[ 5] = 0xb5c1618c | out[ 5] = 0xa2fd337d
in[ 6] = 0x1146f80d | out[ 6] = 0xfd7b1c63
in[ 7] = 0x1d3bcd6d | out[ 7] = 0x96682f29
in[ 8] = 0x19f324ee | out[ 8] = 0xb4393168
in[ 9] = 0x853d9bdf | out[ 9] = 0xe3c9e6bc
in[10] = 0x4b1e1214 | out[10] = 0xfe6bc5b7
in[11] = 0x32aac55a | out[11] = 0xa06d96ba
in[12] = 0x291d0276 | out[12] = 0xe424cc10
in[13] = 0x2948c709 | out[13] = 0x2c91745c
in[14] = 0x8dc6ebed | out[14] = 0x24ad673d
in[15] = 0x5ec2b8b8 | out[15] = 0xc7618f81

<https://datatracker.ietf.org/doc/html/rfc7914#section-8>
INPUT:
7e 87 9a 21 4f 3e c9 86 7c a9 40 e6 41 71 8f 26
ba ee 55 5b 8c 61 c1 b5 0d f8 46 11 6d cd 3b 1d
ee 24 f3 19 df 9b 3d 85 14 12 1e 4b 5a c5 aa 32
76 02 1d 29 09 c7 48 29 ed eb c6 8d b8 b8 c2 5e
OUTPUT:
a4 1f 85 9c 66 08 cc 99 3b 81 ca cb 02 0c ef 05
04 4b 21 81 a2 fd 33 7d fd 7b 1c 63 96 68 2f 29
b4 39 31 68 e3 c9 e6 bc fe 6b c5 b7 a0 6d 96 ba
e4 24 cc 10 2c 91 74 5c 24 ad 67 3d c7 61 8f 81
*/

that can be run on https://www.programiz.com/c-programming/online-compiler/.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.