Score:0

How to test Salsa20/8 Core RFC 7914 implementation with the test vectors?

in flag

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...

hardyrama avatar
sd flag
have you checked big/little endian of implementation ? I think implementation questions do not belong here.
Score:1
in flag

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/.

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.