Fix accidental use of C99 for loop.
[gd/nettle] / chacha-core-internal.c
1 /* chacha-core-internal.c
2
3    Core functionality of the ChaCha stream cipher.
4    Heavily based on the Salsa20 implementation in Nettle.
5
6    Copyright (C) 2013 Joachim Strömbergson
7    Copyright (C) 2012 Simon Josefsson, Niels Möller
8
9    This file is part of GNU Nettle.
10
11    GNU Nettle is free software: you can redistribute it and/or
12    modify it under the terms of either:
13
14      * the GNU Lesser General Public License as published by the Free
15        Software Foundation; either version 3 of the License, or (at your
16        option) any later version.
17
18    or
19
20      * the GNU General Public License as published by the Free
21        Software Foundation; either version 2 of the License, or (at your
22        option) any later version.
23
24    or both in parallel, as here.
25
26    GNU Nettle is distributed in the hope that it will be useful,
27    but WITHOUT ANY WARRANTY; without even the implied warranty of
28    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
29    General Public License for more details.
30
31    You should have received copies of the GNU General Public License and
32    the GNU Lesser General Public License along with this program.  If
33    not, see http://www.gnu.org/licenses/.
34 */
35
36 /* Based on:
37    chacha-ref.c version 2008.01.20.
38    D. J. Bernstein
39    Public domain.
40 */
41
42 #if HAVE_CONFIG_H
43 # include "config.h"
44 #endif
45
46 #include <assert.h>
47 #include <string.h>
48
49 #include "chacha.h"
50
51 #include "macros.h"
52
53 #ifndef CHACHA_DEBUG
54 # define CHACHA_DEBUG 0
55 #endif
56
57 #if CHACHA_DEBUG
58 # include <stdio.h>
59 # define DEBUG(i) do {                          \
60     unsigned debug_j;                           \
61     for (debug_j = 0; debug_j < 16; debug_j++)  \
62       {                                         \
63         if (debug_j == 0)                       \
64           fprintf(stderr, "%2d:", (i));         \
65         else if (debug_j % 4 == 0)              \
66           fprintf(stderr, "\n   ");             \
67         fprintf(stderr, " %8x", x[debug_j]);    \
68       }                                         \
69     fprintf(stderr, "\n");                      \
70   } while (0)
71 #else
72 # define DEBUG(i)
73 #endif
74
75 #ifdef WORDS_BIGENDIAN
76 #define LE_SWAP32(v)                            \
77   ((ROTL32(8,  v) & 0x00FF00FFUL) |             \
78    (ROTL32(24, v) & 0xFF00FF00UL))
79 #else
80 #define LE_SWAP32(v) (v)
81 #endif
82
83 #define QROUND(x0, x1, x2, x3) do { \
84   x0 = x0 + x1; x3 = ROTL32(16, (x0 ^ x3)); \
85   x2 = x2 + x3; x1 = ROTL32(12, (x1 ^ x2)); \
86   x0 = x0 + x1; x3 = ROTL32(8,  (x0 ^ x3)); \
87   x2 = x2 + x3; x1 = ROTL32(7,  (x1 ^ x2)); \
88   } while(0)
89
90 void
91 _chacha_core(uint32_t *dst, const uint32_t *src, unsigned rounds)
92 {
93   uint32_t x[_CHACHA_STATE_LENGTH];
94   unsigned i;
95
96   assert ( (rounds & 1) == 0);
97
98   memcpy (x, src, sizeof(x));
99   for (i = 0; i < rounds;i += 2)
100     {
101       DEBUG (i);
102       QROUND(x[0], x[4], x[8],  x[12]);
103       QROUND(x[1], x[5], x[9],  x[13]);
104       QROUND(x[2], x[6], x[10], x[14]);
105       QROUND(x[3], x[7], x[11], x[15]);
106
107       DEBUG (i+1);
108       QROUND(x[0], x[5], x[10], x[15]);
109       QROUND(x[1], x[6], x[11], x[12]);
110       QROUND(x[2], x[7], x[8],  x[13]);
111       QROUND(x[3], x[4], x[9],  x[14]);
112     }
113   DEBUG (i);
114
115   for (i = 0; i < _CHACHA_STATE_LENGTH; i++)
116     {
117       uint32_t t = x[i] + src[i];
118       dst[i] = LE_SWAP32 (t);
119     }
120 }
121
122
123
124
125
126
127