salsa20-test.c 12.8 KB
Newer Older
1 2 3
#include "testutils.h"
#include "salsa20.h"

Niels Möller's avatar
Niels Möller committed
4 5 6 7 8 9 10 11 12 13 14 15 16
#include "memxor.h"

static int
memzero_p (const uint8_t *p, size_t n)
{
  size_t i;
  for (i = 0; i < n; i++)
    if (p[i])
      return 0;
  return 1;
}

/* The ecrypt testcases encrypt 512 zero bytes (8 blocks), then give
17
   the xor of all blocks, and the data for block 0 (0-63), 3,4
Niels Möller's avatar
Niels Möller committed
18 19 20 21
   (192-319), 7 (448-511) */

#define STREAM_LENGTH 512
static void
22 23 24 25
test_salsa20_stream(const struct tstring *key,
		    const struct tstring *iv,
		    const struct tstring *ciphertext,
		    const struct tstring *xor_ref)
Niels Möller's avatar
Niels Möller committed
26 27 28
{
  struct salsa20_ctx ctx;
  uint8_t data[STREAM_LENGTH + 1];
29
  uint8_t stream[STREAM_LENGTH + 1];
Niels Möller's avatar
Niels Möller committed
30 31 32
  uint8_t xor[SALSA20_BLOCK_SIZE];
  unsigned j;

33 34 35 36 37 38
  ASSERT (iv->length == SALSA20_IV_SIZE);
  ASSERT (ciphertext->length == 4*SALSA20_BLOCK_SIZE);
  ASSERT (xor_ref->length == SALSA20_BLOCK_SIZE);

  salsa20_set_key(&ctx, key->length, key->data);
  salsa20_set_iv(&ctx, iv->data);
39
  memset(stream, 0, STREAM_LENGTH + 1);
Niels Möller's avatar
Niels Möller committed
40
  salsa20_crypt(&ctx, STREAM_LENGTH, stream, stream);
41 42 43 44 45
  if (stream[STREAM_LENGTH])
    {
      fprintf(stderr, "Stream of %d bytes wrote too much!\n", STREAM_LENGTH);
      FAIL();
    }
46
  if (!MEMEQ (64, stream, ciphertext->data))
Niels Möller's avatar
Niels Möller committed
47 48 49 50 51
    {
      fprintf(stderr, "Error failed, offset 0:\n");
      fprintf(stderr, "\nOutput: ");
      print_hex(64, stream);
      fprintf(stderr, "\nExpected:");
52
      print_hex(64, ciphertext->data);
Niels Möller's avatar
Niels Möller committed
53 54 55
      fprintf(stderr, "\n");
      FAIL();
    }
56
  if (!MEMEQ (128, stream + 192, ciphertext->data + 64))
Niels Möller's avatar
Niels Möller committed
57 58 59 60 61
    {
      fprintf(stderr, "Error failed, offset 192:\n");
      fprintf(stderr, "\nOutput: ");
      print_hex(128, stream + 192);
      fprintf(stderr, "\nExpected:");
62
      print_hex(64, ciphertext->data + 64);
Niels Möller's avatar
Niels Möller committed
63 64 65
      fprintf(stderr, "\n");
      FAIL();
    }
66
  if (!MEMEQ (64, stream + 448, ciphertext->data + 192))
Niels Möller's avatar
Niels Möller committed
67 68 69 70 71
    {
      fprintf(stderr, "Error failed, offset 448:\n");
      fprintf(stderr, "\nOutput: ");
      print_hex(64, stream + 448);
      fprintf(stderr, "\nExpected:");
72
      print_hex(64, ciphertext->data + 192);
Niels Möller's avatar
Niels Möller committed
73 74 75 76 77 78 79 80
      fprintf(stderr, "\n");
      FAIL();
    }

  memxor3 (xor, stream, stream + SALSA20_BLOCK_SIZE, SALSA20_BLOCK_SIZE);
  for (j = 2*SALSA20_BLOCK_SIZE; j < STREAM_LENGTH; j += SALSA20_BLOCK_SIZE)
    memxor (xor, stream + j, SALSA20_BLOCK_SIZE);

81
  if (!MEMEQ (SALSA20_BLOCK_SIZE, xor, xor_ref->data))
Niels Möller's avatar
Niels Möller committed
82 83 84 85 86
    {
      fprintf(stderr, "Error failed, bad xor 448:\n");
      fprintf(stderr, "\nOutput: ");
      print_hex(SALSA20_BLOCK_SIZE, xor);
      fprintf(stderr, "\nExpected:");
87
      print_hex(SALSA20_BLOCK_SIZE, xor_ref->data);
Niels Möller's avatar
Niels Möller committed
88 89 90 91 92 93 94
      fprintf(stderr, "\n");
      FAIL();
    }

  for (j = 1; j <= STREAM_LENGTH; j++)
    {
      memset(data, 0, STREAM_LENGTH + 1);
95
      salsa20_set_iv(&ctx, iv->data);
Niels Möller's avatar
Niels Möller committed
96 97 98 99 100 101 102 103 104 105 106 107 108 109
      salsa20_crypt(&ctx, j, data, data);

      if (!MEMEQ(j, data, stream))
	{
	  fprintf(stderr, "Encrypt failed for length %u:\n", j);
	  fprintf(stderr, "\nOutput: ");
	  print_hex(j, data);
	  fprintf(stderr, "\nExpected:");
	  print_hex(j, stream);
	  fprintf(stderr, "\n");
	  FAIL();
	}
      if (!memzero_p (data + j, STREAM_LENGTH + 1 - j))
	{
110
	  fprintf(stderr, "Encrypt failed for length %u, wrote too much:\n", j);
Niels Möller's avatar
Niels Möller committed
111 112 113 114 115 116 117 118
	  fprintf(stderr, "\nOutput: ");
	  print_hex(STREAM_LENGTH + 1 - j, data + j);
	  fprintf(stderr, "\n");
	  FAIL();
	}
    }
}

Niels Möller's avatar
Niels Möller committed
119
typedef void salsa20_func(struct salsa20_ctx *ctx,
Niels Möller's avatar
Niels Möller committed
120
			  size_t length, uint8_t *dst,
Niels Möller's avatar
Niels Möller committed
121
			  const uint8_t *src);
122
static void
Niels Möller's avatar
Niels Möller committed
123 124 125 126 127
_test_salsa20(salsa20_func *crypt,
	      const struct tstring *key,
	      const struct tstring *iv,
	      const struct tstring *cleartext,
	      const struct tstring *ciphertext)
128 129
{
  struct salsa20_ctx ctx;
130 131 132 133 134 135 136
  uint8_t *data;
  unsigned length;

  ASSERT (cleartext->length == ciphertext->length);
  length = cleartext->length;

  ASSERT (iv->length == SALSA20_IV_SIZE);
137

138 139 140 141
  data = xalloc(length + 1);

  salsa20_set_key(&ctx, key->length, key->data);
  salsa20_set_iv(&ctx, iv->data);
142
  data[length] = 17;
Niels Möller's avatar
Niels Möller committed
143
  crypt(&ctx, length, data, cleartext->data);
144 145 146
  if (data[length] != 17)
    {
      fprintf(stderr, "Encrypt of %u bytes wrote too much!\nInput:", length);
147
      tstring_print_hex(cleartext);
148 149 150
      fprintf(stderr, "\n");
      FAIL();
    }
151
  if (!MEMEQ(length, data, ciphertext->data))
152 153
    {
      fprintf(stderr, "Encrypt failed:\nInput:");
154
      tstring_print_hex(cleartext);
155 156 157
      fprintf(stderr, "\nOutput: ");
      print_hex(length, data);
      fprintf(stderr, "\nExpected:");
158
      tstring_print_hex(ciphertext);
159 160 161
      fprintf(stderr, "\n");
      FAIL();
    }
162 163
  salsa20_set_key(&ctx, key->length, key->data);
  salsa20_set_iv(&ctx, iv->data);
Niels Möller's avatar
Niels Möller committed
164
  crypt(&ctx, length, data, data);
165

166
  if (!MEMEQ(length, data, cleartext->data))
167 168
    {
      fprintf(stderr, "Decrypt failed:\nInput:");
169
      tstring_print_hex(ciphertext);
170 171 172
      fprintf(stderr, "\nOutput: ");
      print_hex(length, data);
      fprintf(stderr, "\nExpected:");
173
      tstring_print_hex(cleartext);
174 175 176 177 178 179
      fprintf(stderr, "\n");
      FAIL();
    }

  free(data);
}
Niels Möller's avatar
Niels Möller committed
180 181 182 183 184 185 186

#define test_salsa20(key, iv, cleartext, ciphertext) \
  _test_salsa20 (salsa20_crypt, (key), (iv), (cleartext), (ciphertext))

#define test_salsa20r12(key, iv, cleartext, ciphertext) \
  _test_salsa20 (salsa20r12_crypt, (key), (iv), (cleartext), (ciphertext))

187
  
188
void
189 190
test_main(void)
{
Niels Möller's avatar
Niels Möller committed
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
  /* http://www.ecrypt.eu.org/stream/svn/viewcvs.cgi/ecrypt/trunk/submissions/salsa20/reduced/12-rounds/verified.test-vectors?logsort=rev&rev=210&view=markup */
  test_salsa20r12(SHEX("80000000 00000000 00000000 00000000"),
		  SHEX("00000000 00000000"),
		  SHEX("00000000 00000000"),
		  SHEX("FC207DBF C76C5E17"));

  test_salsa20r12(SHEX("00400000 00000000 00000000 00000000"),
		  SHEX("00000000 00000000"),
		  SHEX("00000000 00000000"),
		  SHEX("6C11A3F9 5FEC7F48"));

  test_salsa20r12(SHEX("09090909090909090909090909090909"),
		  SHEX("0000000000000000"),
		  SHEX("00000000 00000000"),
		  SHEX("78E11FC3 33DEDE88"));

  test_salsa20r12(SHEX("1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B1B"),
		  SHEX("00000000 00000000"),
		  SHEX("00000000 00000000"),
		  SHEX("A6747461 1DF551FF"));

  test_salsa20r12(SHEX("80000000000000000000000000000000"
		       "00000000000000000000000000000000"),
		  SHEX("00000000 00000000"),
		  SHEX("00000000 00000000"),
		  SHEX("AFE411ED 1C4E07E4"));

  test_salsa20r12(SHEX("0053A6F94C9FF24598EB3E91E4378ADD"
		       "3083D6297CCF2275C81B6EC11467BA0D"),
		  SHEX("0D74DB42A91077DE"),
		  SHEX("00000000 00000000"),
		  SHEX("52E20CF8 775AE882"));

224 225
  /* http://www.ecrypt.eu.org/stream/svn/viewcvs.cgi/ecrypt/trunk/submissions/salsa20/full/verified.test-vectors?logsort=rev&rev=210&view=markup */

226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304
  test_salsa20(SHEX("80000000 00000000 00000000 00000000"),
	       SHEX("00000000 00000000"),
	       SHEX("00000000 00000000"),
	       SHEX("4DFA5E48 1DA23EA0"));

  test_salsa20(SHEX("00000000 00000000 00000000 00000000"),
	       SHEX("80000000 00000000"),
	       SHEX("00000000 00000000"),
	       SHEX("B66C1E44 46DD9557"));

  test_salsa20(SHEX("0053A6F94C9FF24598EB3E91E4378ADD"),
	       SHEX("0D74DB42A91077DE"),
	       SHEX("00000000 00000000"),
	       SHEX("05E1E7BE B697D999"));

  test_salsa20(SHEX("80000000 00000000 00000000 00000000"
		    "00000000 00000000 00000000 00000000"),
	       SHEX("00000000 00000000"),
	       SHEX("00000000 00000000"),
	       SHEX("E3BE8FDD 8BECA2E3"));

  test_salsa20(SHEX("00000000 00000000 00000000 00000000"
		    "00000000 00000000 00000000 00000000"),
	       SHEX("80000000 00000000"),
	       SHEX("00000000 00000000"),
	       SHEX("2ABA3DC45B494700"));

  test_salsa20(SHEX("0053A6F94C9FF24598EB3E91E4378ADD"
		    "3083D6297CCF2275C81B6EC11467BA0D"),
	       SHEX("0D74DB42A91077DE"),
	       SHEX("00000000 00000000"),
	       SHEX("F5FAD53F 79F9DF58"));

  test_salsa20_stream(SHEX("80000000000000000000000000000000"),
		      SHEX("00000000 00000000"),
		      SHEX("4DFA5E481DA23EA09A31022050859936"
			   "DA52FCEE218005164F267CB65F5CFD7F"
			   "2B4F97E0FF16924A52DF269515110A07"
			   "F9E460BC65EF95DA58F740B7D1DBB0AA"
			   "DA9C1581F429E0A00F7D67E23B730676"
			   "783B262E8EB43A25F55FB90B3E753AEF"
			   "8C6713EC66C51881111593CCB3E8CB8F"
			   "8DE124080501EEEB389C4BCB6977CF95"
			   "7D5789631EB4554400E1E025935DFA7B"
			   "3E9039D61BDC58A8697D36815BF1985C"
			   "EFDF7AE112E5BB81E37ECF0616CE7147"
			   "FC08A93A367E08631F23C03B00A8DA2F"
			   "B375703739DACED4DD4059FD71C3C47F"
			   "C2F9939670FAD4A46066ADCC6A564578"
			   "3308B90FFB72BE04A6B147CBE38CC0C3"
			   "B9267C296A92A7C69873F9F263BE9703"),
		      SHEX("F7A274D268316790A67EC058F45C0F2A"
			   "067A99FCDE6236C0CEF8E056349FE54C"
			   "5F13AC74D2539570FD34FEAB06C57205"
			   "3949B59585742181A5A760223AFA22D4"));

  test_salsa20_stream(SHEX("48494A4B4C4D4E4F5051525354555657"
			   "58595A5B5C5D5E5F6061626364656667"),
		      SHEX("0000000000000000"),
		      SHEX("53AD3698A011F779AD71030F3EFBEBA0"
			   "A7EE3C55789681B1591EF33A7BE521ED"
			   "68FC36E58F53FFD6E1369B00E390E973"
			   "F656ACB097E0D603BE59A0B8F7975B98"
			   "A04698274C6AC6EC03F66ED3F94C08B7"
			   "9FFDBF2A1610E6F5814905E73AD6D0D2"
			   "8164EEB8450D8ED0BB4B644761B43512"
			   "52DD5DDF00C31E3DABA0BC17691CCFDC"
			   "B826C7F071E796D34E3BFFB3C96E76A1"
			   "209388392806947C7F19B86D379FA3AE"
			   "DFCD19EBF49803DACC6E577E5B97B0F6"
			   "D2036B6624D8196C96FCF02C865D30C1"
			   "B505D41E2C207FA1C0A0E93413DDCFFC"
			   "9BECA8030AFFAC2466E56482DA0EF428"
			   "E63880B5021D3051F18679505A2B9D4F"
			   "9B2C5A2D271D276DE3F51DBEBA934436"),
		      SHEX("7849651A820B1CDFE36D5D6632716534"
			   "E0635EDEFD538122D80870B60FB055DB"
			   "637C7CA2B78B116F83AFF46E40F8F71D"
			   "4CD6D2E1B750D5E011D1DF2E80F7210A"));
305
}
306

Niels Möller's avatar
Niels Möller committed
307
/* Intermediate values for the first salsa20 test case.
308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392
 0: 61707865       80        0        0
           0 3120646e        0        0
           0        0 79622d36       80
           0        0        0 6b206574
 1: 50e6ebaf 3093463d f190e454 9032fa35
    b83c32b0 7fdf3d47 eff21454 a6bf53f6
    59562a33 90327718 9bc1ab3d 49c5665e
    4b9c6232 a5b70d82 b1169b3c 8273a766
 2: 877140ed bc61b44d 60af1c4e 8a219997
    dfa36b55 9dc00f65 e245efc8 ece54d32
    72a63aac c0dc93d7 a1cd6536 b3d44ccb
    8ebd332b c4022fa0 5d4ff16b  65f222e
 3:  26693f1 c7ef1593  549a3a3 9396e54a
    c899675e  1f815f3  47c648d   ebbc01
    67f6ac0c d03d4afa 810d422e e7fd3e5b
    8cd07539 3eb6917b 54e58e29 ef2c818d
 4: 1dff67e3 39538859 717137d4  b935012
    f279ff60 26098b57 4cc2cc68 752f0a9c
    f62fef8b a3028de7 74c726e7 42bbaa73
    85d7ae1b 36e9c191 791019b1 82263e6a
 5: 5058d8b0 d3e44dcf 10bb47b1 7b673ef0
    19f30031 111e4716 ec0295bc 6fd5bf67
    12ffc7e4  d8b55c8  170d410 dd715714
    dcd50b85 1f2bfff6 bde9be51 dbcb0b76
 6: bc9cffbc 33ef9daa 8057f2b9 896b4878
     705ae8b d14227c3 64a13629 112fc18c
    bfe180ad eaf359a0 68467f43 a365bb13
     6b1e849 e6cc8032 70e6c3fe cb0a55bb
 7: 8d90ced2 54d545b4 85be446e b1632f4f
    a071ac6a 90e0a919 33e1e736 ca25d574
    a2b9cc17 7211ef22 c6d499c3 83fdd462
    69a1c02c 4ee14ab4  33c7598 6c536d35
 8: 27885144 2d2a552b f3f9bf1b 33ebeb6b
    104b8b7a  a96110e 9acb26ae 9dba5b23
    be384f78 4cdf3afc ef04b59d f0b9a6fe
    ae50a69b  6c6ea81 f11fe33a 5abcb2ae
 9: 3b2388b1 a820e0d9 1f008910 88c73d4e
    fc306490 8188ba2d d0cae010 9a65a2e4
    cf53e73f acec2667 4b870ab0 6cbfe29b
    27295feb  2a801ee 16f1c6fe 4f40ae38
10: 6d52785f 5d421f38 d44f5a20 a7ec3b7c
    c6a5c6cb f2a38eca  c45beae  69415ff
    93bbc87e cad09b7b c4627081 55276967
    3e13c4d8 aa4e20f4 2a485bf2 bcdbfc61
11: 5136a836 dd9db9bc 50366ca5 a65edf75
    75bb5d1e 6bd4e822 cb52477c 7323b939
    881133b8 38079a5c 14e61ea3  632aa57
    ac091b61 fc1c6ca1 7e5fcc1a 329a1938
12: 5e0ca897 175e6c47 7a1e9674  609ad5a
    ac25229b 49de7bae  370e70c f8bde5e7
    21f81ab3 e6130800 9e2a3e8f 70eed5f1
    d0fbb239 d78a8ea6 b644390a 2c582e03
13: 99fc90d3 f3e42871 78784440 a5885714
    28084a8c 27900f47 e453b985 39b7ca44
     81e5dbf 7860f2b0 693f4da0 74c5ce19
     5f2d43d a9563322 7bd6f4da 4d2e97f5
14: 25571a99 3197dbee 50a1c7d7 91f0e753
    2528837d 56153f81 287f5022 270918e4
    42764fa3 fea16e5b 9ec649fe a4e5e669
    8734b3d9 6fc1ae8a b79a8a04 af160a85
15: 34b906a6 3f56196a 6b690cbf 6c08907a
    60cfba2b 819592a7 3c9b803a 1a3ce6d2
     fdfc6af 282cd998 ad20e9ec  a0c76a1
    772ffdcc ebf39c76 15579a67 dada9ba0
16: 3d87b380 5f9d893a c676cd97 e6d2b4b8
    7d6ca34a 1dc97a79  e3de94b bccb03cd
    12e2a81b 23b00e62 74d433a6 acedb4cb
    6e34fe34 f4c034e4 b3349639 f6ac0473
17: e014e81d 916efb68 d833f0c9 2a0e2be9
    a334791f 71573537 d5c5cb06 c8abbb8c
    6abb97da 9031d7dc 9bea8440 90030a9c
    6c2bdf8a  2649fbf 3a3aeef8 ee0d66c8
18: e9fb1dd3 80e4f86d 2bf2e408 d1809e73
    20872c8d d93bc116 9012e00c 1c813d8e
    45aa03ae 7136cba6 a6b85fc3 9e2d048a
    48013f9e 1f2853d3  854c21d b9cdfb3c
19: 3d47db86 8392cea8 2cf87621 2cff7d58
    dea99415 5800a055 e3661354 86701443
     cc9d23f 616a0a0b 836c1eb9 6c1e72e7
    24cba2f0 54be11a6 6dcb2586 a5663106
20: e6ee81e8 a03ea19d 2002319a 36998550
    eefc52da e4e51bb3 b67c264f 7ffd5c5f
    e0974f2b 4a9216ff 1bc4b21c  70a1095
    bc60e4f9 da95ef65 b740f758 3f90765d
*/