├── Makefile ├── README.txt ├── config.h ├── doc ├── A New Stream Cipher HC-256.pdf ├── Stream Cipher HC-256.pdf └── The Stream Cipher HC-128.pdf ├── hc.h ├── hc256.c ├── hc256.obj ├── hx.asm ├── hx.bin ├── machine.h ├── macros.h ├── portable.h ├── ref ├── ecrypt-config.h ├── ecrypt-machine.h ├── ecrypt-portable.h ├── ecrypt-sync.c ├── ecrypt-sync.h └── testvectors.txt ├── test ├── test.c ├── test.exe └── test.obj /Makefile: -------------------------------------------------------------------------------- 1 | msvc: 2 | cl /nologo /O2 /Ot /DTEST test.c hc256.c 3 | gnu: 4 | gcc -DTEST -Wall -O2 test.c hc256.c -otest 5 | clang: 6 | clang -DTEST -Wall -O2 test.c hc256.c -otest -------------------------------------------------------------------------------- /README.txt: -------------------------------------------------------------------------------- 1 | 2 | HC-256 is a 256-bit symmetric key stream cipher. 3 | 4 | Designers Wu Hongjun 5 | Related to Blowfish, SHA2-256 6 | Certification eSTREAM portfolio 7 | Key sizes 256 bits 8 | State size 65536 bits 9 | 10 | [ license 11 | 12 | Copyright © 2016 Odzhan, Peter Ferrie. All Rights Reserved. 13 | 14 | Redistribution and use in source and binary forms, with or without 15 | modification, are permitted provided that the following conditions are 16 | met: 17 | 18 | 1. Redistributions of source code must retain the above copyright 19 | notice, this list of conditions and the following disclaimer. 20 | 21 | 2. Redistributions in binary form must reproduce the above copyright 22 | notice, this list of conditions and the following disclaimer in the 23 | documentation and/or other materials provided with the distribution. 24 | 25 | 3. The name of the author may not be used to endorse or promote products 26 | derived from this software without specific prior written permission. 27 | 28 | THIS SOFTWARE IS PROVIDED BY AUTHORS "AS IS" AND ANY EXPRESS OR 29 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 30 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 31 | DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 32 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 33 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 34 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 36 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 37 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 38 | POSSIBILITY OF SUCH DAMAGE. 39 | 40 | HC-256 has a 256 bit key and an initialization vector (nonce) of 256 41 | bits. 42 | 43 | Internally, it consists of two secret tables (P and Q). Each table 44 | contains 1024 32-bit words. For each state update one 32-bit word in 45 | each table is updated using a non-linear update function. After 2048 46 | steps all elements of the tables have been updated. 47 | 48 | It generates one 32-bit word for each update step using a 32-bit to 49 | 32-bit mapping function similar to the output function of the Blowfish 50 | cipher. Finally a linear bit-masking function is applied to generate an 51 | output word. It uses the two message schedule functions in the hash 52 | function SHA-256 internally, but with the tables P and Q as S-boxes. 53 | 54 | HC-128 is similar in function, and reduces each of key length, nonce, 55 | number of words in the tables P and Q, and number of table updating 56 | steps by half. 57 | 58 | HC-128 and HC-256 are two software-efficient stream ciphers. In 2008, 59 | HC-128 was selected for the final portfolio of eSTREAM, the stream 60 | cipher project of the European Network of Excellence for Cryptology 61 | (ECRYPT, 2004-2008). HC-256 is the 256-bit companion version of HC-128. 62 | From a 128-bit key and a 128-bit initialization vector, HC-128 generates 63 | keystream with length up to $2^{64}$ bits. From a 256-bit key and a 64 | 256-bit initialization vector, HC-256 generates keystream with length up 65 | to $2^{128}$ bits. 66 | 67 | HC-256 and HC-128 were designed to demonstrate that strong stream cipher 68 | can be built from nonlinear feedback function and nonlinear output 69 | function. The large secret states of the two ciphers are updated in a 70 | nonlinear way, and table lookup (with changing tables) is used in the 71 | generation of keystream. 72 | 73 | HC-128 and HC-256 are very efficient on modern microprocessors. For long 74 | message, the encryption speed of HC-128 is about 2.1 cycles/byte on 75 | 32-bit Intel Core 2 microprocessor, and the encryption speed of HC-256 76 | is about 3.3 cycles/byte on 32-bit Core 2 microprocessor. The encryption 77 | speed of HC-128 is the fastest among the secure stream ciphers being 78 | submitted to eSTREAM proejct. 79 | 80 | HC-256 and HC-128 are not covered by any patent and they are 81 | freely-available. 82 | 83 | 84 | [x] Stream Ciphers HC-128 and HC-256 85 | http://www3.ntu.edu.sg/home/wuhj/research/hc/index.html 86 | 87 | [x] Wu Hongjun 88 | http://www3.ntu.edu.sg/home/wuhj/ -------------------------------------------------------------------------------- /config.h: -------------------------------------------------------------------------------- 1 | /* ecrypt-config.h */ 2 | 3 | /* *** Normally, it should not be necessary to edit this file. *** */ 4 | 5 | #ifndef ECRYPT_CONFIG 6 | #define ECRYPT_CONFIG 7 | 8 | /* ------------------------------------------------------------------------- */ 9 | 10 | /* Guess the endianness of the target architecture. */ 11 | 12 | /* 13 | * The LITTLE endian machines: 14 | */ 15 | #if defined(__ultrix) /* Older MIPS */ 16 | #define ECRYPT_LITTLE_ENDIAN 17 | #elif defined(__alpha) /* Alpha */ 18 | #define ECRYPT_LITTLE_ENDIAN 19 | #elif defined(i386) /* x86 (gcc) */ 20 | #define ECRYPT_LITTLE_ENDIAN 21 | #elif defined(__i386) /* x86 (gcc) */ 22 | #define ECRYPT_LITTLE_ENDIAN 23 | #elif defined(_M_IX86) /* x86 (MSC, Borland) */ 24 | #define ECRYPT_LITTLE_ENDIAN 25 | #elif defined(_MSC_VER) /* x86 (surely MSC) */ 26 | #define ECRYPT_LITTLE_ENDIAN 27 | #elif defined(__INTEL_COMPILER) /* x86 (surely Intel compiler icl.exe) */ 28 | #define ECRYPT_LITTLE_ENDIAN 29 | 30 | /* 31 | * The BIG endian machines: 32 | */ 33 | #elif defined(sun) /* Newer Sparc's */ 34 | #define ECRYPT_BIG_ENDIAN 35 | #elif defined(__ppc__) /* PowerPC */ 36 | #define ECRYPT_BIG_ENDIAN 37 | 38 | /* 39 | * Finally machines with UNKNOWN endianness: 40 | */ 41 | #elif defined (_AIX) /* RS6000 */ 42 | #define ECRYPT_UNKNOWN 43 | #elif defined(__hpux) /* HP-PA */ 44 | #define ECRYPT_UNKNOWN 45 | #elif defined(__aux) /* 68K */ 46 | #define ECRYPT_UNKNOWN 47 | #elif defined(__dgux) /* 88K (but P6 in latest boxes) */ 48 | #define ECRYPT_UNKNOWN 49 | #elif defined(__sgi) /* Newer MIPS */ 50 | #define ECRYPT_UNKNOWN 51 | #else /* Any other processor */ 52 | #define ECRYPT_UNKNOWN 53 | #endif 54 | 55 | /* ------------------------------------------------------------------------- */ 56 | 57 | /* 58 | * Find minimal-width types to store 8-bit, 16-bit, 32-bit, and 64-bit 59 | * integers. 60 | * 61 | * Note: to enable 64-bit types on 32-bit compilers, it might be 62 | * necessary to switch from ISO C90 mode to ISO C99 mode (e.g., gcc 63 | * -std=c99). 64 | */ 65 | 66 | #include 67 | 68 | /* --- check char --- */ 69 | 70 | #if (UCHAR_MAX / 0xFU > 0xFU) 71 | #ifndef I8T 72 | #define I8T char 73 | #define U8C(v) (v##U) 74 | 75 | #if (UCHAR_MAX == 0xFFU) 76 | #define ECRYPT_I8T_IS_BYTE 77 | #endif 78 | 79 | #endif 80 | 81 | #if (UCHAR_MAX / 0xFFU > 0xFFU) 82 | #ifndef I16T 83 | #define I16T char 84 | #define U16C(v) (v##U) 85 | #endif 86 | 87 | #if (UCHAR_MAX / 0xFFFFU > 0xFFFFU) 88 | #ifndef I32T 89 | #define I32T char 90 | #define U32C(v) (v##U) 91 | #endif 92 | 93 | #if (UCHAR_MAX / 0xFFFFFFFFU > 0xFFFFFFFFU) 94 | #ifndef I64T 95 | #define I64T char 96 | #define U64C(v) (v##U) 97 | #define ECRYPT_NATIVE64 98 | #endif 99 | 100 | #endif 101 | #endif 102 | #endif 103 | #endif 104 | 105 | /* --- check short --- */ 106 | 107 | #if (USHRT_MAX / 0xFU > 0xFU) 108 | #ifndef I8T 109 | #define I8T short 110 | #define U8C(v) (v##U) 111 | 112 | #if (USHRT_MAX == 0xFFU) 113 | #define ECRYPT_I8T_IS_BYTE 114 | #endif 115 | 116 | #endif 117 | 118 | #if (USHRT_MAX / 0xFFU > 0xFFU) 119 | #ifndef I16T 120 | #define I16T short 121 | #define U16C(v) (v##U) 122 | #endif 123 | 124 | #if (USHRT_MAX / 0xFFFFU > 0xFFFFU) 125 | #ifndef I32T 126 | #define I32T short 127 | #define U32C(v) (v##U) 128 | #endif 129 | 130 | #if (USHRT_MAX / 0xFFFFFFFFU > 0xFFFFFFFFU) 131 | #ifndef I64T 132 | #define I64T short 133 | #define U64C(v) (v##U) 134 | #define ECRYPT_NATIVE64 135 | #endif 136 | 137 | #endif 138 | #endif 139 | #endif 140 | #endif 141 | 142 | /* --- check int --- */ 143 | 144 | #if (UINT_MAX / 0xFU > 0xFU) 145 | #ifndef I8T 146 | #define I8T int 147 | #define U8C(v) (v##U) 148 | 149 | #if (ULONG_MAX == 0xFFU) 150 | #define ECRYPT_I8T_IS_BYTE 151 | #endif 152 | 153 | #endif 154 | 155 | #if (UINT_MAX / 0xFFU > 0xFFU) 156 | #ifndef I16T 157 | #define I16T int 158 | #define U16C(v) (v##U) 159 | #endif 160 | 161 | #if (UINT_MAX / 0xFFFFU > 0xFFFFU) 162 | #ifndef I32T 163 | #define I32T int 164 | #define U32C(v) (v##U) 165 | #endif 166 | 167 | #if (UINT_MAX / 0xFFFFFFFFU > 0xFFFFFFFFU) 168 | #ifndef I64T 169 | #define I64T int 170 | #define U64C(v) (v##U) 171 | #define ECRYPT_NATIVE64 172 | #endif 173 | 174 | #endif 175 | #endif 176 | #endif 177 | #endif 178 | 179 | /* --- check long --- */ 180 | 181 | #if (ULONG_MAX / 0xFUL > 0xFUL) 182 | #ifndef I8T 183 | #define I8T long 184 | #define U8C(v) (v##UL) 185 | 186 | #if (ULONG_MAX == 0xFFUL) 187 | #define ECRYPT_I8T_IS_BYTE 188 | #endif 189 | 190 | #endif 191 | 192 | #if (ULONG_MAX / 0xFFUL > 0xFFUL) 193 | #ifndef I16T 194 | #define I16T long 195 | #define U16C(v) (v##UL) 196 | #endif 197 | 198 | #if (ULONG_MAX / 0xFFFFUL > 0xFFFFUL) 199 | #ifndef I32T 200 | #define I32T long 201 | #define U32C(v) (v##UL) 202 | #endif 203 | 204 | #if (ULONG_MAX / 0xFFFFFFFFUL > 0xFFFFFFFFUL) 205 | #ifndef I64T 206 | #define I64T long 207 | #define U64C(v) (v##UL) 208 | #define ECRYPT_NATIVE64 209 | #endif 210 | 211 | #endif 212 | #endif 213 | #endif 214 | #endif 215 | 216 | /* --- check long long --- */ 217 | 218 | #ifdef ULLONG_MAX 219 | 220 | #if (ULLONG_MAX / 0xFULL > 0xFULL) 221 | #ifndef I8T 222 | #define I8T long long 223 | #define U8C(v) (v##ULL) 224 | 225 | #if (ULLONG_MAX == 0xFFULL) 226 | #define ECRYPT_I8T_IS_BYTE 227 | #endif 228 | 229 | #endif 230 | 231 | #if (ULLONG_MAX / 0xFFULL > 0xFFULL) 232 | #ifndef I16T 233 | #define I16T long long 234 | #define U16C(v) (v##ULL) 235 | #endif 236 | 237 | #if (ULLONG_MAX / 0xFFFFULL > 0xFFFFULL) 238 | #ifndef I32T 239 | #define I32T long long 240 | #define U32C(v) (v##ULL) 241 | #endif 242 | 243 | #if (ULLONG_MAX / 0xFFFFFFFFULL > 0xFFFFFFFFULL) 244 | #ifndef I64T 245 | #define I64T long long 246 | #define U64C(v) (v##ULL) 247 | #endif 248 | 249 | #endif 250 | #endif 251 | #endif 252 | #endif 253 | 254 | #endif 255 | 256 | /* --- check __int64 --- */ 257 | 258 | #ifdef _UI64_MAX 259 | 260 | #if (_UI64_MAX / INT64_C(0xFFFFFFFF) > INT64_C(0xFFFFFFFF)) 261 | #ifndef I64T 262 | #define I64T __int64 263 | #define U64C(v) (v##ui64) 264 | #endif 265 | 266 | #endif 267 | 268 | #endif 269 | 270 | /* ------------------------------------------------------------------------- */ 271 | 272 | #endif 273 | -------------------------------------------------------------------------------- /doc/A New Stream Cipher HC-256.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peterferrie/hc256/2023e013e9934b0be56af3396b884e46ec136b47/doc/A New Stream Cipher HC-256.pdf -------------------------------------------------------------------------------- /doc/Stream Cipher HC-256.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peterferrie/hc256/2023e013e9934b0be56af3396b884e46ec136b47/doc/Stream Cipher HC-256.pdf -------------------------------------------------------------------------------- /doc/The Stream Cipher HC-128.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peterferrie/hc256/2023e013e9934b0be56af3396b884e46ec136b47/doc/The Stream Cipher HC-128.pdf -------------------------------------------------------------------------------- /hc.h: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright © 2016 Odzhan. All Rights Reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in the 13 | documentation and/or other materials provided with the distribution. 14 | 15 | 3. The name of the author may not be used to endorse or promote products 16 | derived from this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY AUTHORS "AS IS" AND ANY EXPRESS OR 19 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 22 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 27 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | POSSIBILITY OF SUCH DAMAGE. */ 29 | 30 | #ifndef HC256_H 31 | #define HC256_H 32 | 33 | #include 34 | #include 35 | 36 | #include "macros.h" 37 | 38 | #define SIG0(x)(ROTR32((x), 7) ^ ROTR32((x), 18) ^ ((x) >> 3)) 39 | #define SIG1(x)(ROTR32((x), 17) ^ ROTR32((x), 19) ^ ((x) >> 10)) 40 | 41 | typedef struct hc_ctx_t { 42 | uint32_t ctr; 43 | union { 44 | uint32_t T[2048]; 45 | struct { 46 | uint32_t P[1024]; 47 | uint32_t Q[1024]; 48 | }; 49 | }; 50 | } hc_ctx; 51 | 52 | #ifdef __cplusplus 53 | extern "C" { 54 | #endif 55 | 56 | void hc256_setkeyx(hc_ctx*, void*); 57 | void hc256_cryptx(hc_ctx*, void*, uint32_t); 58 | 59 | void hc256_setkey(hc_ctx*, void*); 60 | void hc256_crypt(hc_ctx*, void*, uint32_t); 61 | 62 | #ifdef __cplusplus 63 | } 64 | #endif 65 | 66 | #endif -------------------------------------------------------------------------------- /hc256.c: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright © 2016 Odzhan. All Rights Reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in the 13 | documentation and/or other materials provided with the distribution. 14 | 15 | 3. The name of the author may not be used to endorse or promote products 16 | derived from this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY AUTHORS "AS IS" AND ANY EXPRESS OR 19 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 22 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 27 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | POSSIBILITY OF SUCH DAMAGE. */ 29 | 30 | #include "hc.h" 31 | 32 | // key stream generation function 33 | uint32_t hc256_generate(hc_ctx* c) 34 | { 35 | uint32_t r, i, i3, i10, i12, i1023; 36 | uint32_t *x0, *x1; 37 | uint32_t w0, w1, t; 38 | 39 | t=c->ctr; 40 | 41 | c->ctr = (c->ctr+1) & 0x7ff; 42 | 43 | x0=c->P; 44 | x1=c->Q; 45 | 46 | if (t > 0x3ff) { 47 | x0=c->Q; 48 | x1=c->P; 49 | } 50 | 51 | i = t & 0x3ff; 52 | i3 = (i - 3) & 0x3ff; 53 | i10 = (i - 10) & 0x3ff; 54 | i1023 = (i - 1023) & 0x3ff; 55 | 56 | x0[i] += x0[i10] + 57 | (ROTR32(x0[i3], 10) ^ ROTL32(x0[i1023], 9)) + 58 | x1[(x0[i3] ^ x0[i1023]) & 0x3ff]; 59 | 60 | i12 = (i - 12) & 0x3ff; 61 | 62 | w0=x0[i]; 63 | w1=x0[i12]; 64 | 65 | for (r=0, t=0; t<4; t++) { 66 | r += x1[w1 & 255]; 67 | w1 >>= 8; 68 | x1 += 1024/4; 69 | } 70 | r ^= w0; 71 | 72 | return r; 73 | } 74 | 75 | // both key and iv must be 32 bytes each / 256-bits! 76 | void hc256_setkey(hc_ctx *c, void *kiv) 77 | { 78 | uint32_t W[4096], i; 79 | 80 | // 1. set counter 81 | c->ctr = 0; 82 | 83 | // 2. copy 512-bit key and iv to local workspace 84 | memcpy (W, kiv, 64); 85 | 86 | // 3. expand buffer using SHA-256 macros 87 | for (i=16; i<4096; i++) { 88 | W[i] = SIG1(W[i- 2]) + W[i- 7] + 89 | SIG0(W[i-15]) + W[i-16] + i; 90 | } 91 | 92 | // 6. set the P and Q tables 93 | memcpy (&c->T[0], &W[512], 2048*4); 94 | 95 | // 5. run cipher 4096 iterations before generating output 96 | for (i=0; i<4096; i++) { 97 | hc256_generate(c); 98 | } 99 | } 100 | 101 | // encrypt/decrypt data in place 102 | void hc256_crypt(hc_ctx *c, void *in, uint32_t inlen) 103 | { 104 | uint32_t i, j, w; 105 | uint8_t *p=(uint8_t*)in; 106 | 107 | // encrypt all bytes 108 | for (i=0; i>= 8; 114 | } 115 | } 116 | } 117 | 118 | -------------------------------------------------------------------------------- /hc256.obj: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peterferrie/hc256/2023e013e9934b0be56af3396b884e46ec136b47/hc256.obj -------------------------------------------------------------------------------- /hx.asm: -------------------------------------------------------------------------------- 1 | ; 2 | ; Copyright © 2016 Odzhan, Peter Ferrie. All Rights Reserved. 3 | ; 4 | ; Redistribution and use in source and binary forms, with or without 5 | ; modification, are permitted provided that the following conditions are 6 | ; met: 7 | ; 8 | ; 1. Redistributions of source code must retain the above copyright 9 | ; notice, this list of conditions and the following disclaimer. 10 | ; 11 | ; 2. Redistributions in binary form must reproduce the above copyright 12 | ; notice, this list of conditions and the following disclaimer in the 13 | ; documentation and/or other materials provided with the distribution. 14 | ; 15 | ; 3. The name of the author may not be used to endorse or promote products 16 | ; derived from this software without specific prior written permission. 17 | ; 18 | ; THIS SOFTWARE IS PROVIDED BY AUTHORS "AS IS" AND ANY EXPRESS OR 19 | ; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | ; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | ; DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 22 | ; INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | ; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | ; SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | ; HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | ; STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 27 | ; ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | ; POSSIBILITY OF SUCH DAMAGE. 29 | ; 30 | ; ----------------------------------------------- 31 | ; HC-256 stream cipher in x86 assembly 32 | ; 33 | ; size: 272 bytes 34 | ; 35 | ; global calls use cdecl convention 36 | ; 37 | ; ----------------------------------------------- 38 | bits 32 39 | 40 | struc pushad_t 41 | _edi resd 1 42 | _esi resd 1 43 | _ebp resd 1 44 | _esp resd 1 45 | _ebx resd 1 46 | _edx resd 1 47 | _ecx resd 1 48 | _eax resd 1 49 | .size: 50 | endstruc 51 | 52 | %ifndef BIN 53 | global hc256_setkeyx 54 | global _hc256_setkeyx 55 | 56 | global hc256_cryptx 57 | global _hc256_cryptx 58 | %endif 59 | 60 | ; expects ctx in edi 61 | hc256_generatex: 62 | _hc256_generatex: 63 | pushad 64 | xor edx, edx 65 | mov dh, 8 ; edx = 2048 66 | mov esi, edi ; esi = c 67 | lodsd ; eax = c->ctr 68 | push eax ; save c->ctr 69 | inc eax ; c->ctr++ 70 | dec edx ; edx = 2047 71 | and eax, edx ; c->ctr &= 2047 72 | stosd ; save new c->ctr 73 | pop eax ; restore old c->ctr 74 | lea edi, [esi+edx*2+2] ; x0 = c->Q 75 | shr edx, 1 ; edx = 1023 76 | push edx ; save 1023 77 | cmp eax, edx ; c->ctr > 1023 78 | jbe gen_l0 79 | xchg esi, edi ; swap Q and P ptrs 80 | gen_l0: 81 | and eax, edx ; i &= 1023 82 | 83 | lea ebx, [eax-3] ; i3 = (i - 3) & 1023; 84 | and ebx, edx 85 | 86 | lea ecx, [eax-10] ; i10 = (i - 10) & 1023; 87 | and ecx, edx 88 | 89 | lea ebp, [eax-12] ; i12 = (i - 12) & 1023; 90 | and ebp, edx 91 | mov ebp, [esi+ebp*4] 92 | push ebp ; save i12 93 | 94 | mov ebp, eax ; i1023 = (i - 1023) & 1023; 95 | sub ebp, edx 96 | and ebp, edx 97 | 98 | push eax ; save i 99 | mov eax, [esi+eax*4] ; eax = x0[i] 100 | add eax, [esi+ecx*4] ; eax += x0[i10] 101 | 102 | mov ebp, [esi+ebp*4] ; ebp = x0[i1023] 103 | mov ebx, [esi+ebx*4] ; ebx = x0[i3] 104 | mov ecx, ebx ; ecx = x0[i3] 105 | xor ecx, ebp ; ecx ^= x0[i1023] 106 | and ecx, edx ; ecx &= 0x3ff 107 | add eax, [edi+ecx*4] ; ecx = x1[(x0[i3] ^ x0[i1023]) & 1023] 108 | ror ebx, 10 ; ebx = ROTR32(x0[i3], 10) 109 | rol ebp, 9 ; ebp = ROTL32(x0[i1023], 9) 110 | xor ebx, ebp ; 111 | add eax, ebx ; 112 | pop ebx ; ebx = i 113 | mov [esi+ebx*4], eax ; eax = (x0[i] += eax) 114 | pop edx ; edx = i12 115 | 116 | pop ebp ; ebp=1023 117 | inc ebp ; ebp=1024 118 | xchg eax, ecx 119 | xor eax, eax ; r=0 120 | gen_l1: 121 | movzx ebx, dl 122 | add eax, [edi+ebx*4] 123 | add edi, ebp ; x1 += 1024/4 124 | shr edx, 8 ; w1 >>= 8 125 | jnz gen_l1 126 | 127 | xor eax, ecx ; r ^= w0; 128 | mov [esp+_eax], eax ; return r; 129 | popad 130 | ret 131 | 132 | hc256_setkeyx: 133 | _hc256_setkeyx: 134 | pushad 135 | mov edi, [esp+32+4] ; edi=c 136 | mov esi, [esp+32+8] ; esi=kiv 137 | ; 138 | xor ecx, ecx ; ecx=0 139 | mul ecx ; eax=0, edx=0 140 | 141 | mov cl, 5 ; ecx=5 142 | mov dh, 16 ; edx=4096 143 | ; allocate stack memory in 4096 byte blocks 144 | ; 4 x 4096 = 16384 bytes, 145 | ; additional 4096 bytes just in case (not needed?) 146 | xalloca: 147 | sub esp, edx ; subtract page size 148 | test [esp], esp ; page probe 149 | ; causes pages of memory to be 150 | ; allocated via the guard page 151 | ; scheme (if possible) 152 | loop xalloca ; raises exception if 153 | ; unable to allocate 154 | mov ebx, esp ; ebx=W 155 | 156 | push edx ; save 4096 157 | push edi ; save ptr to c 158 | stosd ; c->ctr=0 159 | push edx ; save 4096 160 | push edi ; save ptr to c->T 161 | push edx ; save 4096 162 | 163 | ; 2. copy 512-bits of key/iv to workspace 164 | mov cl, 64 165 | mov edi, ebx ; edi=W 166 | rep movsb 167 | 168 | mov esi, ebx ; esi=W 169 | mov cl, 16 170 | expand_key: 171 | ; eax = SIG0(W[i-15]) 172 | mov eax, [edi - 15*4] 173 | mov edx, eax 174 | mov ebp, eax 175 | ror eax, 7 176 | ror edx, 18 177 | shr ebp, 3 178 | xor eax, edx 179 | xor eax, ebp 180 | ; ebx = SIG1(W[i-2]) 181 | mov ebx, [edi - 2*4] 182 | mov edx, ebx 183 | mov ebp, ebx 184 | ror ebx, 17 185 | ror edx, 19 186 | shr ebp, 10 187 | xor ebx, edx 188 | xor ebx, ebp 189 | ; W[i] = ebx + W[i-16] + eax + w[i-7] + i 190 | add eax, [edi - 16*4] 191 | add ebx, [edi - 7*4] 192 | add eax, ebx 193 | add eax, ecx 194 | stosd 195 | inc ecx 196 | cmp ecx, [esp] ; 4096 words 197 | jnz expand_key 198 | 199 | pop ecx ; ecx=4096 200 | pop edi ; edi=c->T 201 | shr ecx, 1 ; /=2 for 2048 words 202 | add esi, ecx ; add 512*4 203 | rep movsd 204 | 205 | pop ecx ; ecx=4096 206 | pop edi ; edi=ctx 207 | sk_l3: 208 | call hc256_generatex 209 | loop sk_l3 210 | 211 | pop eax ; eax=4096 212 | lea esp, [esp+eax*4] ; free stack 213 | add esp, eax 214 | popad 215 | ret 216 | 217 | hc256_cryptx: 218 | _hc256_cryptx: 219 | pushad 220 | lea esi, [esp+32+4] 221 | lodsd 222 | xchg edi, eax ; edi=ctx 223 | lodsd 224 | xchg edx, eax ; edx=in 225 | lodsd 226 | xchg ecx, eax ; ecx=len 227 | hc_l0: ; .repeat 228 | jecxz hc_l2 ; .break .if ecx == 0 229 | call hc256_generatex 230 | hc_l1: 231 | xor [edx], al ; *in ^= (w0 & 0xFF) 232 | inc edx ; in++ 233 | shr eax, 8 ; w0 >>= 8 234 | loopnz hc_l1 ; .while ecx != 0 && eax != 0 235 | jmp hc_l0 236 | hc_l2: 237 | popad 238 | ret 239 | -------------------------------------------------------------------------------- /hx.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peterferrie/hc256/2023e013e9934b0be56af3396b884e46ec136b47/hx.bin -------------------------------------------------------------------------------- /machine.h: -------------------------------------------------------------------------------- 1 | /* ecrypt-machine.h */ 2 | 3 | /* 4 | * This file is included by 'ecrypt-portable.h'. It allows to override 5 | * the default macros for specific platforms. Please carefully check 6 | * the machine code generated by your compiler (with optimisations 7 | * turned on) before deciding to edit this file. 8 | */ 9 | 10 | /* ------------------------------------------------------------------------- */ 11 | 12 | #if (defined(ECRYPT_DEFAULT_ROT) && !defined(ECRYPT_MACHINE_ROT)) 13 | 14 | #define ECRYPT_MACHINE_ROT 15 | 16 | #if (defined(WIN32) && defined(_MSC_VER)) 17 | 18 | #undef ROTL32 19 | #undef ROTR32 20 | #undef ROTL64 21 | #undef ROTR64 22 | 23 | #include 24 | 25 | #define ROTL32(v, n) _lrotl(v, n) 26 | #define ROTR32(v, n) _lrotr(v, n) 27 | #define ROTL64(v, n) _rotl64(v, n) 28 | #define ROTR64(v, n) _rotr64(v, n) 29 | 30 | #endif 31 | 32 | #endif 33 | 34 | /* ------------------------------------------------------------------------- */ 35 | 36 | #if (defined(ECRYPT_DEFAULT_SWAP) && !defined(ECRYPT_MACHINE_SWAP)) 37 | 38 | #define ECRYPT_MACHINE_SWAP 39 | 40 | /* 41 | * If you want to overwrite the default swap macros, put it here. And so on. 42 | */ 43 | 44 | #endif 45 | 46 | /* ------------------------------------------------------------------------- */ 47 | -------------------------------------------------------------------------------- /macros.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef MACROS_H 4 | #define MACROS_H 5 | 6 | #include 7 | #include 8 | 9 | #include "portable.h" 10 | 11 | #define XCHG(x, y) (t) = (x); (x) = (y); (y) = (t); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /portable.h: -------------------------------------------------------------------------------- 1 | /* ecrypt-portable.h */ 2 | 3 | /* 4 | * WARNING: the conversions defined below are implemented as macros, 5 | * and should be used carefully. They should NOT be used with 6 | * parameters which perform some action. E.g., the following two lines 7 | * are not equivalent: 8 | * 9 | * 1) ++x; y = ROTL32(x, n); 10 | * 2) y = ROTL32(++x, n); 11 | */ 12 | 13 | /* 14 | * *** Please do not edit this file. *** 15 | * 16 | * The default macros can be overridden for specific architectures by 17 | * editing 'machine.h'. 18 | */ 19 | 20 | #ifndef ECRYPT_PORTABLE 21 | #define ECRYPT_PORTABLE 22 | 23 | #include "config.h" 24 | 25 | /* ------------------------------------------------------------------------- */ 26 | 27 | /* 28 | * The following types are defined (if available): 29 | * 30 | * u8: unsigned integer type, at least 8 bits 31 | * u16: unsigned integer type, at least 16 bits 32 | * u32: unsigned integer type, at least 32 bits 33 | * u64: unsigned integer type, at least 64 bits 34 | * 35 | * s8, s16, s32, s64 -> signed counterparts of u8, u16, u32, u64 36 | * 37 | * The selection of minimum-width integer types is taken care of by 38 | * 'config.h'. Note: to enable 64-bit types on 32-bit 39 | * compilers, it might be necessary to switch from ISO C90 mode to ISO 40 | * C99 mode (e.g., gcc -std=c99). 41 | */ 42 | 43 | #ifdef I8T 44 | typedef signed I8T s8; 45 | typedef unsigned I8T u8; 46 | #endif 47 | 48 | #ifdef I16T 49 | typedef signed I16T s16; 50 | typedef unsigned I16T u16; 51 | #endif 52 | 53 | #ifdef I32T 54 | typedef signed I32T s32; 55 | typedef unsigned I32T u32; 56 | #endif 57 | 58 | #ifdef I64T 59 | typedef signed I64T s64; 60 | typedef unsigned I64T u64; 61 | #endif 62 | 63 | /* 64 | * The following macros are used to obtain exact-width results. 65 | */ 66 | 67 | #define U8V(v) ((u8)(v) & U8C(0xFF)) 68 | #define U16V(v) ((u16)(v) & U16C(0xFFFF)) 69 | #define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF)) 70 | #define U64V(v) ((u64)(v) & U64C(0xFFFFFFFFFFFFFFFF)) 71 | 72 | /* ------------------------------------------------------------------------- */ 73 | 74 | /* 75 | * The following macros return words with their bits rotated over n 76 | * positions to the left/right. 77 | */ 78 | 79 | #define ECRYPT_DEFAULT_ROT 80 | 81 | #define ROTL8(v, n) \ 82 | (U8V((v) << (n)) | ((v) >> (8 - (n)))) 83 | 84 | #define ROTL16(v, n) \ 85 | (U16V((v) << (n)) | ((v) >> (16 - (n)))) 86 | 87 | #define ROTL32(v, n) \ 88 | (U32V((v) << (n)) | ((v) >> (32 - (n)))) 89 | 90 | #define ROTL64(v, n) \ 91 | (U64V((v) << (n)) | ((v) >> (64 - (n)))) 92 | 93 | #define ROTR8(v, n) ROTL8(v, 8 - (n)) 94 | #define ROTR16(v, n) ROTL16(v, 16 - (n)) 95 | #define ROTR32(v, n) ROTL32(v, 32 - (n)) 96 | #define ROTR64(v, n) ROTL64(v, 64 - (n)) 97 | 98 | #include "machine.h" 99 | 100 | /* ------------------------------------------------------------------------- */ 101 | 102 | /* 103 | * The following macros return a word with bytes in reverse order. 104 | */ 105 | 106 | #define ECRYPT_DEFAULT_SWAP 107 | 108 | #define SWAP16(v) \ 109 | ROTL16(v, 8) 110 | 111 | #define SWAP32(v) \ 112 | ((ROTL32(v, 8) & U32C(0x00FF00FF)) | \ 113 | (ROTL32(v, 24) & U32C(0xFF00FF00))) 114 | 115 | #ifdef ECRYPT_NATIVE64 116 | #define SWAP64(v) \ 117 | ((ROTL64(v, 8) & U64C(0x000000FF000000FF)) | \ 118 | (ROTL64(v, 24) & U64C(0x0000FF000000FF00)) | \ 119 | (ROTL64(v, 40) & U64C(0x00FF000000FF0000)) | \ 120 | (ROTL64(v, 56) & U64C(0xFF000000FF000000))) 121 | #else 122 | #define SWAP64(v) \ 123 | (((u64)SWAP32(U32V(v)) << 32) | (u64)SWAP32(U32V(v >> 32))) 124 | #endif 125 | 126 | #include "machine.h" 127 | 128 | #define ECRYPT_DEFAULT_WTOW 129 | 130 | #ifdef ECRYPT_LITTLE_ENDIAN 131 | #define U16TO16_LITTLE(v) (v) 132 | #define U32TO32_LITTLE(v) (v) 133 | #define U64TO64_LITTLE(v) (v) 134 | 135 | #define U16TO16_BIG(v) SWAP16(v) 136 | #define U32TO32_BIG(v) SWAP32(v) 137 | #define U64TO64_BIG(v) SWAP64(v) 138 | #endif 139 | 140 | #ifdef ECRYPT_BIG_ENDIAN 141 | #define U16TO16_LITTLE(v) SWAP16(v) 142 | #define U32TO32_LITTLE(v) SWAP32(v) 143 | #define U64TO64_LITTLE(v) SWAP64(v) 144 | 145 | #define U16TO16_BIG(v) (v) 146 | #define U32TO32_BIG(v) (v) 147 | #define U64TO64_BIG(v) (v) 148 | #endif 149 | 150 | #include "machine.h" 151 | 152 | /* 153 | * The following macros load words from an array of bytes with 154 | * different types of endianness, and vice versa. 155 | */ 156 | 157 | #define ECRYPT_DEFAULT_BTOW 158 | 159 | #if (!defined(ECRYPT_UNKNOWN) && defined(ECRYPT_I8T_IS_BYTE)) 160 | 161 | #define U8TO16_LITTLE(p) U16TO16_LITTLE(((u16*)(p))[0]) 162 | #define U8TO32_LITTLE(p) U32TO32_LITTLE(((u32*)(p))[0]) 163 | #define U8TO64_LITTLE(p) U64TO64_LITTLE(((u64*)(p))[0]) 164 | 165 | #define U8TO16_BIG(p) U16TO16_BIG(((u16*)(p))[0]) 166 | #define U8TO32_BIG(p) U32TO32_BIG(((u32*)(p))[0]) 167 | #define U8TO64_BIG(p) U64TO64_BIG(((u64*)(p))[0]) 168 | 169 | #define U16TO8_LITTLE(p, v) (((u16*)(p))[0] = U16TO16_LITTLE(v)) 170 | #define U32TO8_LITTLE(p, v) (((u32*)(p))[0] = U32TO32_LITTLE(v)) 171 | #define U64TO8_LITTLE(p, v) (((u64*)(p))[0] = U64TO64_LITTLE(v)) 172 | 173 | #define U16TO8_BIG(p, v) (((u16*)(p))[0] = U16TO16_BIG(v)) 174 | #define U32TO8_BIG(p, v) (((u32*)(p))[0] = U32TO32_BIG(v)) 175 | #define U64TO8_BIG(p, v) (((u64*)(p))[0] = U64TO64_BIG(v)) 176 | 177 | #else 178 | 179 | #define U8TO16_LITTLE(p) \ 180 | (((u16)((p)[0]) ) | \ 181 | ((u16)((p)[1]) << 8)) 182 | 183 | #define U8TO32_LITTLE(p) \ 184 | (((u32)((p)[0]) ) | \ 185 | ((u32)((p)[1]) << 8) | \ 186 | ((u32)((p)[2]) << 16) | \ 187 | ((u32)((p)[3]) << 24)) 188 | 189 | #ifdef ECRYPT_NATIVE64 190 | #define U8TO64_LITTLE(p) \ 191 | (((u64)((p)[0]) ) | \ 192 | ((u64)((p)[1]) << 8) | \ 193 | ((u64)((p)[2]) << 16) | \ 194 | ((u64)((p)[3]) << 24) | \ 195 | ((u64)((p)[4]) << 32) | \ 196 | ((u64)((p)[5]) << 40) | \ 197 | ((u64)((p)[6]) << 48) | \ 198 | ((u64)((p)[7]) << 56)) 199 | #else 200 | #define U8TO64_LITTLE(p) \ 201 | ((u64)U8TO32_LITTLE(p) | ((u64)U8TO32_LITTLE((p) + 4) << 32)) 202 | #endif 203 | 204 | #define U8TO16_BIG(p) \ 205 | (((u16)((p)[0]) << 8) | \ 206 | ((u16)((p)[1]) )) 207 | 208 | #define U8TO32_BIG(p) \ 209 | (((u32)((p)[0]) << 24) | \ 210 | ((u32)((p)[1]) << 16) | \ 211 | ((u32)((p)[2]) << 8) | \ 212 | ((u32)((p)[3]) )) 213 | 214 | #ifdef ECRYPT_NATIVE64 215 | #define U8TO64_BIG(p) \ 216 | (((u64)((p)[0]) << 56) | \ 217 | ((u64)((p)[1]) << 48) | \ 218 | ((u64)((p)[2]) << 40) | \ 219 | ((u64)((p)[3]) << 32) | \ 220 | ((u64)((p)[4]) << 24) | \ 221 | ((u64)((p)[5]) << 16) | \ 222 | ((u64)((p)[6]) << 8) | \ 223 | ((u64)((p)[7]) )) 224 | #else 225 | #define U8TO64_BIG(p) \ 226 | (((u64)U8TO32_BIG(p) << 32) | (u64)U8TO32_BIG((p) + 4)) 227 | #endif 228 | 229 | #define U16TO8_LITTLE(p, v) \ 230 | do { \ 231 | (p)[0] = U8V((v) ); \ 232 | (p)[1] = U8V((v) >> 8); \ 233 | } while (0) 234 | 235 | #define U32TO8_LITTLE(p, v) \ 236 | do { \ 237 | (p)[0] = U8V((v) ); \ 238 | (p)[1] = U8V((v) >> 8); \ 239 | (p)[2] = U8V((v) >> 16); \ 240 | (p)[3] = U8V((v) >> 24); \ 241 | } while (0) 242 | 243 | #ifdef ECRYPT_NATIVE64 244 | #define U64TO8_LITTLE(p, v) \ 245 | do { \ 246 | (p)[0] = U8V((v) ); \ 247 | (p)[1] = U8V((v) >> 8); \ 248 | (p)[2] = U8V((v) >> 16); \ 249 | (p)[3] = U8V((v) >> 24); \ 250 | (p)[4] = U8V((v) >> 32); \ 251 | (p)[5] = U8V((v) >> 40); \ 252 | (p)[6] = U8V((v) >> 48); \ 253 | (p)[7] = U8V((v) >> 56); \ 254 | } while (0) 255 | #else 256 | #define U64TO8_LITTLE(p, v) \ 257 | do { \ 258 | U32TO8_LITTLE((p), U32V((v) )); \ 259 | U32TO8_LITTLE((p) + 4, U32V((v) >> 32)); \ 260 | } while (0) 261 | #endif 262 | 263 | #define U16TO8_BIG(p, v) \ 264 | do { \ 265 | (p)[0] = U8V((v) ); \ 266 | (p)[1] = U8V((v) >> 8); \ 267 | } while (0) 268 | 269 | #define U32TO8_BIG(p, v) \ 270 | do { \ 271 | (p)[0] = U8V((v) >> 24); \ 272 | (p)[1] = U8V((v) >> 16); \ 273 | (p)[2] = U8V((v) >> 8); \ 274 | (p)[3] = U8V((v) ); \ 275 | } while (0) 276 | 277 | #ifdef ECRYPT_NATIVE64 278 | #define U64TO8_BIG(p, v) \ 279 | do { \ 280 | (p)[0] = U8V((v) >> 56); \ 281 | (p)[1] = U8V((v) >> 48); \ 282 | (p)[2] = U8V((v) >> 40); \ 283 | (p)[3] = U8V((v) >> 32); \ 284 | (p)[4] = U8V((v) >> 24); \ 285 | (p)[5] = U8V((v) >> 16); \ 286 | (p)[6] = U8V((v) >> 8); \ 287 | (p)[7] = U8V((v) ); \ 288 | } while (0) 289 | #else 290 | #define U64TO8_BIG(p, v) \ 291 | do { \ 292 | U32TO8_BIG((p), U32V((v) >> 32)); \ 293 | U32TO8_BIG((p) + 4, U32V((v) )); \ 294 | } while (0) 295 | #endif 296 | 297 | #endif 298 | 299 | #include "machine.h" 300 | 301 | /* ------------------------------------------------------------------------- */ 302 | 303 | #endif 304 | -------------------------------------------------------------------------------- /ref/ecrypt-config.h: -------------------------------------------------------------------------------- 1 | /* ecrypt-config.h */ 2 | 3 | /* *** Normally, it should not be necessary to edit this file. *** */ 4 | 5 | #ifndef ECRYPT_CONFIG 6 | #define ECRYPT_CONFIG 7 | 8 | /* ------------------------------------------------------------------------- */ 9 | 10 | /* Guess the endianness of the target architecture. */ 11 | 12 | /* 13 | * The LITTLE endian machines: 14 | */ 15 | #if defined(__ultrix) /* Older MIPS */ 16 | #define ECRYPT_LITTLE_ENDIAN 17 | #elif defined(__alpha) /* Alpha */ 18 | #define ECRYPT_LITTLE_ENDIAN 19 | #elif defined(i386) /* x86 (gcc) */ 20 | #define ECRYPT_LITTLE_ENDIAN 21 | #elif defined(__i386) /* x86 (gcc) */ 22 | #define ECRYPT_LITTLE_ENDIAN 23 | #elif defined(_M_IX86) /* x86 (MSC, Borland) */ 24 | #define ECRYPT_LITTLE_ENDIAN 25 | #elif defined(_MSC_VER) /* x86 (surely MSC) */ 26 | #define ECRYPT_LITTLE_ENDIAN 27 | #elif defined(__INTEL_COMPILER) /* x86 (surely Intel compiler icl.exe) */ 28 | #define ECRYPT_LITTLE_ENDIAN 29 | 30 | /* 31 | * The BIG endian machines: 32 | */ 33 | #elif defined(sun) /* Newer Sparc's */ 34 | #define ECRYPT_BIG_ENDIAN 35 | #elif defined(__ppc__) /* PowerPC */ 36 | #define ECRYPT_BIG_ENDIAN 37 | 38 | /* 39 | * Finally machines with UNKNOWN endianness: 40 | */ 41 | #elif defined (_AIX) /* RS6000 */ 42 | #define ECRYPT_UNKNOWN 43 | #elif defined(__hpux) /* HP-PA */ 44 | #define ECRYPT_UNKNOWN 45 | #elif defined(__aux) /* 68K */ 46 | #define ECRYPT_UNKNOWN 47 | #elif defined(__dgux) /* 88K (but P6 in latest boxes) */ 48 | #define ECRYPT_UNKNOWN 49 | #elif defined(__sgi) /* Newer MIPS */ 50 | #define ECRYPT_UNKNOWN 51 | #else /* Any other processor */ 52 | #define ECRYPT_UNKNOWN 53 | #endif 54 | 55 | /* ------------------------------------------------------------------------- */ 56 | 57 | /* 58 | * Find minimal-width types to store 8-bit, 16-bit, 32-bit, and 64-bit 59 | * integers. 60 | * 61 | * Note: to enable 64-bit types on 32-bit compilers, it might be 62 | * necessary to switch from ISO C90 mode to ISO C99 mode (e.g., gcc 63 | * -std=c99), or to allow compiler-specific extensions. 64 | */ 65 | 66 | #include 67 | 68 | /* --- check char --- */ 69 | 70 | #if (UCHAR_MAX / 0xFU > 0xFU) 71 | #ifndef I8T 72 | #define I8T char 73 | #define U8C(v) (v##U) 74 | 75 | #if (UCHAR_MAX == 0xFFU) 76 | #define ECRYPT_I8T_IS_BYTE 77 | #endif 78 | 79 | #endif 80 | 81 | #if (UCHAR_MAX / 0xFFU > 0xFFU) 82 | #ifndef I16T 83 | #define I16T char 84 | #define U16C(v) (v##U) 85 | #endif 86 | 87 | #if (UCHAR_MAX / 0xFFFFU > 0xFFFFU) 88 | #ifndef I32T 89 | #define I32T char 90 | #define U32C(v) (v##U) 91 | #endif 92 | 93 | #if (UCHAR_MAX / 0xFFFFFFFFU > 0xFFFFFFFFU) 94 | #ifndef I64T 95 | #define I64T char 96 | #define U64C(v) (v##U) 97 | #define ECRYPT_NATIVE64 98 | #endif 99 | 100 | #endif 101 | #endif 102 | #endif 103 | #endif 104 | 105 | /* --- check short --- */ 106 | 107 | #if (USHRT_MAX / 0xFU > 0xFU) 108 | #ifndef I8T 109 | #define I8T short 110 | #define U8C(v) (v##U) 111 | 112 | #if (USHRT_MAX == 0xFFU) 113 | #define ECRYPT_I8T_IS_BYTE 114 | #endif 115 | 116 | #endif 117 | 118 | #if (USHRT_MAX / 0xFFU > 0xFFU) 119 | #ifndef I16T 120 | #define I16T short 121 | #define U16C(v) (v##U) 122 | #endif 123 | 124 | #if (USHRT_MAX / 0xFFFFU > 0xFFFFU) 125 | #ifndef I32T 126 | #define I32T short 127 | #define U32C(v) (v##U) 128 | #endif 129 | 130 | #if (USHRT_MAX / 0xFFFFFFFFU > 0xFFFFFFFFU) 131 | #ifndef I64T 132 | #define I64T short 133 | #define U64C(v) (v##U) 134 | #define ECRYPT_NATIVE64 135 | #endif 136 | 137 | #endif 138 | #endif 139 | #endif 140 | #endif 141 | 142 | /* --- check int --- */ 143 | 144 | #if (UINT_MAX / 0xFU > 0xFU) 145 | #ifndef I8T 146 | #define I8T int 147 | #define U8C(v) (v##U) 148 | 149 | #if (ULONG_MAX == 0xFFU) 150 | #define ECRYPT_I8T_IS_BYTE 151 | #endif 152 | 153 | #endif 154 | 155 | #if (UINT_MAX / 0xFFU > 0xFFU) 156 | #ifndef I16T 157 | #define I16T int 158 | #define U16C(v) (v##U) 159 | #endif 160 | 161 | #if (UINT_MAX / 0xFFFFU > 0xFFFFU) 162 | #ifndef I32T 163 | #define I32T int 164 | #define U32C(v) (v##U) 165 | #endif 166 | 167 | #if (UINT_MAX / 0xFFFFFFFFU > 0xFFFFFFFFU) 168 | #ifndef I64T 169 | #define I64T int 170 | #define U64C(v) (v##U) 171 | #define ECRYPT_NATIVE64 172 | #endif 173 | 174 | #endif 175 | #endif 176 | #endif 177 | #endif 178 | 179 | /* --- check long --- */ 180 | 181 | #if (ULONG_MAX / 0xFUL > 0xFUL) 182 | #ifndef I8T 183 | #define I8T long 184 | #define U8C(v) (v##UL) 185 | 186 | #if (ULONG_MAX == 0xFFUL) 187 | #define ECRYPT_I8T_IS_BYTE 188 | #endif 189 | 190 | #endif 191 | 192 | #if (ULONG_MAX / 0xFFUL > 0xFFUL) 193 | #ifndef I16T 194 | #define I16T long 195 | #define U16C(v) (v##UL) 196 | #endif 197 | 198 | #if (ULONG_MAX / 0xFFFFUL > 0xFFFFUL) 199 | #ifndef I32T 200 | #define I32T long 201 | #define U32C(v) (v##UL) 202 | #endif 203 | 204 | #if (ULONG_MAX / 0xFFFFFFFFUL > 0xFFFFFFFFUL) 205 | #ifndef I64T 206 | #define I64T long 207 | #define U64C(v) (v##UL) 208 | #define ECRYPT_NATIVE64 209 | #endif 210 | 211 | #endif 212 | #endif 213 | #endif 214 | #endif 215 | 216 | /* --- check long long --- */ 217 | 218 | #ifdef ULLONG_MAX 219 | 220 | #if (ULLONG_MAX / 0xFULL > 0xFULL) 221 | #ifndef I8T 222 | #define I8T long long 223 | #define U8C(v) (v##ULL) 224 | 225 | #if (ULLONG_MAX == 0xFFULL) 226 | #define ECRYPT_I8T_IS_BYTE 227 | #endif 228 | 229 | #endif 230 | 231 | #if (ULLONG_MAX / 0xFFULL > 0xFFULL) 232 | #ifndef I16T 233 | #define I16T long long 234 | #define U16C(v) (v##ULL) 235 | #endif 236 | 237 | #if (ULLONG_MAX / 0xFFFFULL > 0xFFFFULL) 238 | #ifndef I32T 239 | #define I32T long long 240 | #define U32C(v) (v##ULL) 241 | #endif 242 | 243 | #if (ULLONG_MAX / 0xFFFFFFFFULL > 0xFFFFFFFFULL) 244 | #ifndef I64T 245 | #define I64T long long 246 | #define U64C(v) (v##ULL) 247 | #endif 248 | 249 | #endif 250 | #endif 251 | #endif 252 | #endif 253 | 254 | #endif 255 | 256 | /* --- check __int64 --- */ 257 | 258 | #if !defined(__STDC__) && defined(_UI64_MAX) 259 | 260 | #ifndef I64T 261 | #define I64T __int64 262 | #define U64C(v) (v##ui64) 263 | #endif 264 | 265 | #endif 266 | 267 | /* ------------------------------------------------------------------------- */ 268 | 269 | #endif 270 | -------------------------------------------------------------------------------- /ref/ecrypt-machine.h: -------------------------------------------------------------------------------- 1 | /* ecrypt-machine.h */ 2 | 3 | /* 4 | * This file is included by 'ecrypt-portable.h'. It allows to override 5 | * the default macros for specific platforms. Please carefully check 6 | * the machine code generated by your compiler (with optimisations 7 | * turned on) before deciding to edit this file. 8 | */ 9 | 10 | /* ------------------------------------------------------------------------- */ 11 | 12 | #if (defined(ECRYPT_DEFAULT_ROT) && !defined(ECRYPT_MACHINE_ROT)) 13 | 14 | #define ECRYPT_MACHINE_ROT 15 | 16 | #if (defined(WIN32) && defined(_MSC_VER)) 17 | 18 | #undef ROTL32 19 | #undef ROTR32 20 | #undef ROTL64 21 | #undef ROTR64 22 | 23 | #include 24 | 25 | #pragma intrinsic(_lrotl) /* compile rotations "inline" */ 26 | #pragma intrinsic(_lrotr) 27 | 28 | #define ROTL32(v, n) _lrotl(v, n) 29 | #define ROTR32(v, n) _lrotr(v, n) 30 | #define ROTL64(v, n) _rotl64(v, n) 31 | #define ROTR64(v, n) _rotr64(v, n) 32 | 33 | #endif 34 | 35 | #endif 36 | 37 | /* ------------------------------------------------------------------------- */ 38 | 39 | #if (defined(ECRYPT_DEFAULT_SWAP) && !defined(ECRYPT_MACHINE_SWAP)) 40 | 41 | #define ECRYPT_MACHINE_SWAP 42 | 43 | /* 44 | * If you want to overwrite the default swap macros, put it here. And so on. 45 | */ 46 | 47 | #endif 48 | 49 | /* ------------------------------------------------------------------------- */ 50 | -------------------------------------------------------------------------------- /ref/ecrypt-portable.h: -------------------------------------------------------------------------------- 1 | /* ecrypt-portable.h */ 2 | 3 | /* 4 | * WARNING: the conversions defined below are implemented as macros, 5 | * and should be used carefully. They should NOT be used with 6 | * parameters which perform some action. E.g., the following two lines 7 | * are not equivalent: 8 | * 9 | * 1) ++x; y = ROTL32(x, n); 10 | * 2) y = ROTL32(++x, n); 11 | */ 12 | 13 | /* 14 | * *** Please do not edit this file. *** 15 | * 16 | * The default macros can be overridden for specific architectures by 17 | * editing 'ecrypt-machine.h'. 18 | */ 19 | 20 | #ifndef ECRYPT_PORTABLE 21 | #define ECRYPT_PORTABLE 22 | 23 | #include "ecrypt-config.h" 24 | 25 | /* ------------------------------------------------------------------------- */ 26 | 27 | /* 28 | * The following types are defined (if available): 29 | * 30 | * u8: unsigned integer type, at least 8 bits 31 | * u16: unsigned integer type, at least 16 bits 32 | * u32: unsigned integer type, at least 32 bits 33 | * u64: unsigned integer type, at least 64 bits 34 | * 35 | * s8, s16, s32, s64 -> signed counterparts of u8, u16, u32, u64 36 | * 37 | * The selection of minimum-width integer types is taken care of by 38 | * 'ecrypt-config.h'. Note: to enable 64-bit types on 32-bit 39 | * compilers, it might be necessary to switch from ISO C90 mode to ISO 40 | * C99 mode (e.g., gcc -std=c99). 41 | */ 42 | 43 | #ifdef I8T 44 | typedef signed I8T s8; 45 | typedef unsigned I8T u8; 46 | #endif 47 | 48 | #ifdef I16T 49 | typedef signed I16T s16; 50 | typedef unsigned I16T u16; 51 | #endif 52 | 53 | #ifdef I32T 54 | typedef signed I32T s32; 55 | typedef unsigned I32T u32; 56 | #endif 57 | 58 | #ifdef I64T 59 | typedef signed I64T s64; 60 | typedef unsigned I64T u64; 61 | #endif 62 | 63 | /* 64 | * The following macros are used to obtain exact-width results. 65 | */ 66 | 67 | #define U8V(v) ((u8)(v) & U8C(0xFF)) 68 | #define U16V(v) ((u16)(v) & U16C(0xFFFF)) 69 | #define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF)) 70 | #define U64V(v) ((u64)(v) & U64C(0xFFFFFFFFFFFFFFFF)) 71 | 72 | /* ------------------------------------------------------------------------- */ 73 | 74 | /* 75 | * The following macros return words with their bits rotated over n 76 | * positions to the left/right. 77 | */ 78 | 79 | #define ECRYPT_DEFAULT_ROT 80 | 81 | #define ROTL8(v, n) \ 82 | (U8V((v) << (n)) | ((v) >> (8 - (n)))) 83 | 84 | #define ROTL16(v, n) \ 85 | (U16V((v) << (n)) | ((v) >> (16 - (n)))) 86 | 87 | #define ROTL32(v, n) \ 88 | (U32V((v) << (n)) | ((v) >> (32 - (n)))) 89 | 90 | #define ROTL64(v, n) \ 91 | (U64V((v) << (n)) | ((v) >> (64 - (n)))) 92 | 93 | #define ROTR8(v, n) ROTL8(v, 8 - (n)) 94 | #define ROTR16(v, n) ROTL16(v, 16 - (n)) 95 | #define ROTR32(v, n) ROTL32(v, 32 - (n)) 96 | #define ROTR64(v, n) ROTL64(v, 64 - (n)) 97 | 98 | #include "ecrypt-machine.h" 99 | 100 | /* ------------------------------------------------------------------------- */ 101 | 102 | /* 103 | * The following macros return a word with bytes in reverse order. 104 | */ 105 | 106 | #define ECRYPT_DEFAULT_SWAP 107 | 108 | #define SWAP16(v) \ 109 | ROTL16(v, 8) 110 | 111 | #define SWAP32(v) \ 112 | ((ROTL32(v, 8) & U32C(0x00FF00FF)) | \ 113 | (ROTL32(v, 24) & U32C(0xFF00FF00))) 114 | 115 | #ifdef ECRYPT_NATIVE64 116 | #define SWAP64(v) \ 117 | ((ROTL64(v, 8) & U64C(0x000000FF000000FF)) | \ 118 | (ROTL64(v, 24) & U64C(0x0000FF000000FF00)) | \ 119 | (ROTL64(v, 40) & U64C(0x00FF000000FF0000)) | \ 120 | (ROTL64(v, 56) & U64C(0xFF000000FF000000))) 121 | #else 122 | #define SWAP64(v) \ 123 | (((u64)SWAP32(U32V(v)) << 32) | (u64)SWAP32(U32V(v >> 32))) 124 | #endif 125 | 126 | #include "ecrypt-machine.h" 127 | 128 | #define ECRYPT_DEFAULT_WTOW 129 | 130 | #ifdef ECRYPT_LITTLE_ENDIAN 131 | #define U16TO16_LITTLE(v) (v) 132 | #define U32TO32_LITTLE(v) (v) 133 | #define U64TO64_LITTLE(v) (v) 134 | 135 | #define U16TO16_BIG(v) SWAP16(v) 136 | #define U32TO32_BIG(v) SWAP32(v) 137 | #define U64TO64_BIG(v) SWAP64(v) 138 | #endif 139 | 140 | #ifdef ECRYPT_BIG_ENDIAN 141 | #define U16TO16_LITTLE(v) SWAP16(v) 142 | #define U32TO32_LITTLE(v) SWAP32(v) 143 | #define U64TO64_LITTLE(v) SWAP64(v) 144 | 145 | #define U16TO16_BIG(v) (v) 146 | #define U32TO32_BIG(v) (v) 147 | #define U64TO64_BIG(v) (v) 148 | #endif 149 | 150 | #include "ecrypt-machine.h" 151 | 152 | /* 153 | * The following macros load words from an array of bytes with 154 | * different types of endianness, and vice versa. 155 | */ 156 | 157 | #define ECRYPT_DEFAULT_BTOW 158 | 159 | #if (!defined(ECRYPT_UNKNOWN) && defined(ECRYPT_I8T_IS_BYTE)) 160 | 161 | #define U8TO16_LITTLE(p) U16TO16_LITTLE(((u16*)(p))[0]) 162 | #define U8TO32_LITTLE(p) U32TO32_LITTLE(((u32*)(p))[0]) 163 | #define U8TO64_LITTLE(p) U64TO64_LITTLE(((u64*)(p))[0]) 164 | 165 | #define U8TO16_BIG(p) U16TO16_BIG(((u16*)(p))[0]) 166 | #define U8TO32_BIG(p) U32TO32_BIG(((u32*)(p))[0]) 167 | #define U8TO64_BIG(p) U64TO64_BIG(((u64*)(p))[0]) 168 | 169 | #define U16TO8_LITTLE(p, v) (((u16*)(p))[0] = U16TO16_LITTLE(v)) 170 | #define U32TO8_LITTLE(p, v) (((u32*)(p))[0] = U32TO32_LITTLE(v)) 171 | #define U64TO8_LITTLE(p, v) (((u64*)(p))[0] = U64TO64_LITTLE(v)) 172 | 173 | #define U16TO8_BIG(p, v) (((u16*)(p))[0] = U16TO16_BIG(v)) 174 | #define U32TO8_BIG(p, v) (((u32*)(p))[0] = U32TO32_BIG(v)) 175 | #define U64TO8_BIG(p, v) (((u64*)(p))[0] = U64TO64_BIG(v)) 176 | 177 | #else 178 | 179 | #define U8TO16_LITTLE(p) \ 180 | (((u16)((p)[0]) ) | \ 181 | ((u16)((p)[1]) << 8)) 182 | 183 | #define U8TO32_LITTLE(p) \ 184 | (((u32)((p)[0]) ) | \ 185 | ((u32)((p)[1]) << 8) | \ 186 | ((u32)((p)[2]) << 16) | \ 187 | ((u32)((p)[3]) << 24)) 188 | 189 | #ifdef ECRYPT_NATIVE64 190 | #define U8TO64_LITTLE(p) \ 191 | (((u64)((p)[0]) ) | \ 192 | ((u64)((p)[1]) << 8) | \ 193 | ((u64)((p)[2]) << 16) | \ 194 | ((u64)((p)[3]) << 24) | \ 195 | ((u64)((p)[4]) << 32) | \ 196 | ((u64)((p)[5]) << 40) | \ 197 | ((u64)((p)[6]) << 48) | \ 198 | ((u64)((p)[7]) << 56)) 199 | #else 200 | #define U8TO64_LITTLE(p) \ 201 | ((u64)U8TO32_LITTLE(p) | ((u64)U8TO32_LITTLE((p) + 4) << 32)) 202 | #endif 203 | 204 | #define U8TO16_BIG(p) \ 205 | (((u16)((p)[0]) << 8) | \ 206 | ((u16)((p)[1]) )) 207 | 208 | #define U8TO32_BIG(p) \ 209 | (((u32)((p)[0]) << 24) | \ 210 | ((u32)((p)[1]) << 16) | \ 211 | ((u32)((p)[2]) << 8) | \ 212 | ((u32)((p)[3]) )) 213 | 214 | #ifdef ECRYPT_NATIVE64 215 | #define U8TO64_BIG(p) \ 216 | (((u64)((p)[0]) << 56) | \ 217 | ((u64)((p)[1]) << 48) | \ 218 | ((u64)((p)[2]) << 40) | \ 219 | ((u64)((p)[3]) << 32) | \ 220 | ((u64)((p)[4]) << 24) | \ 221 | ((u64)((p)[5]) << 16) | \ 222 | ((u64)((p)[6]) << 8) | \ 223 | ((u64)((p)[7]) )) 224 | #else 225 | #define U8TO64_BIG(p) \ 226 | (((u64)U8TO32_BIG(p) << 32) | (u64)U8TO32_BIG((p) + 4)) 227 | #endif 228 | 229 | #define U16TO8_LITTLE(p, v) \ 230 | do { \ 231 | (p)[0] = U8V((v) ); \ 232 | (p)[1] = U8V((v) >> 8); \ 233 | } while (0) 234 | 235 | #define U32TO8_LITTLE(p, v) \ 236 | do { \ 237 | (p)[0] = U8V((v) ); \ 238 | (p)[1] = U8V((v) >> 8); \ 239 | (p)[2] = U8V((v) >> 16); \ 240 | (p)[3] = U8V((v) >> 24); \ 241 | } while (0) 242 | 243 | #ifdef ECRYPT_NATIVE64 244 | #define U64TO8_LITTLE(p, v) \ 245 | do { \ 246 | (p)[0] = U8V((v) ); \ 247 | (p)[1] = U8V((v) >> 8); \ 248 | (p)[2] = U8V((v) >> 16); \ 249 | (p)[3] = U8V((v) >> 24); \ 250 | (p)[4] = U8V((v) >> 32); \ 251 | (p)[5] = U8V((v) >> 40); \ 252 | (p)[6] = U8V((v) >> 48); \ 253 | (p)[7] = U8V((v) >> 56); \ 254 | } while (0) 255 | #else 256 | #define U64TO8_LITTLE(p, v) \ 257 | do { \ 258 | U32TO8_LITTLE((p), U32V((v) )); \ 259 | U32TO8_LITTLE((p) + 4, U32V((v) >> 32)); \ 260 | } while (0) 261 | #endif 262 | 263 | #define U16TO8_BIG(p, v) \ 264 | do { \ 265 | (p)[0] = U8V((v) ); \ 266 | (p)[1] = U8V((v) >> 8); \ 267 | } while (0) 268 | 269 | #define U32TO8_BIG(p, v) \ 270 | do { \ 271 | (p)[0] = U8V((v) >> 24); \ 272 | (p)[1] = U8V((v) >> 16); \ 273 | (p)[2] = U8V((v) >> 8); \ 274 | (p)[3] = U8V((v) ); \ 275 | } while (0) 276 | 277 | #ifdef ECRYPT_NATIVE64 278 | #define U64TO8_BIG(p, v) \ 279 | do { \ 280 | (p)[0] = U8V((v) >> 56); \ 281 | (p)[1] = U8V((v) >> 48); \ 282 | (p)[2] = U8V((v) >> 40); \ 283 | (p)[3] = U8V((v) >> 32); \ 284 | (p)[4] = U8V((v) >> 24); \ 285 | (p)[5] = U8V((v) >> 16); \ 286 | (p)[6] = U8V((v) >> 8); \ 287 | (p)[7] = U8V((v) ); \ 288 | } while (0) 289 | #else 290 | #define U64TO8_BIG(p, v) \ 291 | do { \ 292 | U32TO8_BIG((p), U32V((v) >> 32)); \ 293 | U32TO8_BIG((p) + 4, U32V((v) )); \ 294 | } while (0) 295 | #endif 296 | 297 | #endif 298 | 299 | #include "ecrypt-machine.h" 300 | 301 | /* ------------------------------------------------------------------------- */ 302 | 303 | #endif 304 | -------------------------------------------------------------------------------- /ref/ecrypt-sync.c: -------------------------------------------------------------------------------- 1 | /* ecrypt-sync.c */ 2 | 3 | /* *** Please do not edit this file. *** */ 4 | 5 | #include "ecrypt-sync.h" 6 | 7 | #ifdef ECRYPT_USES_DEFAULT_ALL_IN_ONE 8 | 9 | /* 10 | * Default implementation of all-in-one encryption/decryption of 11 | * (short) packets. 12 | */ 13 | 14 | #ifdef ECRYPT_HAS_SINGLE_PACKET_FUNCTION 15 | 16 | void ECRYPT_process_packet( 17 | int action, 18 | ECRYPT_ctx* ctx, 19 | const u8* iv, 20 | const u8* input, 21 | u8* output, 22 | u32 msglen) 23 | { 24 | ECRYPT_ivsetup(ctx, iv); 25 | 26 | #ifdef ECRYPT_HAS_SINGLE_BYTE_FUNCTION 27 | ECRYPT_process_bytes(action, ctx, input, output, msglen); 28 | #else 29 | if (action == 0) 30 | ECRYPT_encrypt_bytes(ctx, input, output, msglen); 31 | else 32 | ECRYPT_decrypt_bytes(ctx, input, output, msglen); 33 | #endif 34 | } 35 | 36 | #else 37 | 38 | void ECRYPT_encrypt_packet( 39 | ECRYPT_ctx* ctx, 40 | const u8* iv, 41 | const u8* plaintext, 42 | u8* ciphertext, 43 | u32 msglen) 44 | { 45 | ECRYPT_ivsetup(ctx, iv); 46 | ECRYPT_encrypt_bytes(ctx, plaintext, ciphertext, msglen); 47 | } 48 | 49 | void ECRYPT_decrypt_packet( 50 | ECRYPT_ctx* ctx, 51 | const u8* iv, 52 | const u8* ciphertext, 53 | u8* plaintext, 54 | u32 msglen) 55 | { 56 | ECRYPT_ivsetup(ctx, iv); 57 | ECRYPT_decrypt_bytes(ctx, ciphertext, plaintext, msglen); 58 | } 59 | 60 | #endif 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /ref/ecrypt-sync.h: -------------------------------------------------------------------------------- 1 | /* ecrypt-sync.h */ 2 | 3 | /* 4 | * Header file for synchronous stream ciphers without authentication 5 | * mechanism. 6 | * 7 | * *** Please only edit parts marked with "[edit]". *** 8 | */ 9 | 10 | #ifndef ECRYPT_SYNC 11 | #define ECRYPT_SYNC 12 | 13 | #include "ecrypt-portable.h" 14 | 15 | /* ------------------------------------------------------------------------- */ 16 | 17 | /* Cipher parameters */ 18 | 19 | /* 20 | * The name of your cipher. 21 | */ 22 | #define ECRYPT_NAME "ECRYPT Stream Cipher HC-256" /* [edit] */ 23 | 24 | /* 25 | * Specify which key and IV sizes are supported by your cipher. A user 26 | * should be able to enumerate the supported sizes by running the 27 | * following code: 28 | * 29 | * for (i = 0; ECRYPT_KEYSIZE(i) <= ECRYPT_MAXKEYSIZE; ++i) 30 | * { 31 | * keysize = ECRYPT_KEYSIZE(i); 32 | * 33 | * ... 34 | * } 35 | * 36 | * All sizes are in bits. 37 | */ 38 | 39 | #define ECRYPT_MAXKEYSIZE 256 /* [edit] */ 40 | #define ECRYPT_KEYSIZE(i) (128 + (i)*32) /* [edit] */ 41 | 42 | #define ECRYPT_MAXIVSIZE 256 /* [edit] */ 43 | #define ECRYPT_IVSIZE(i) (64 + (i)*64) /* [edit] */ 44 | 45 | /* ------------------------------------------------------------------------- */ 46 | 47 | /* Data structures */ 48 | 49 | /* 50 | * ECRYPT_ctx is the structure containing the representation of the 51 | * internal state of your cipher. 52 | */ 53 | 54 | typedef struct 55 | { 56 | /* 57 | * [edit] 58 | * 59 | * Put here all state variable needed during the encryption process. 60 | */ 61 | u32 P[1024]; 62 | u32 Q[1024]; 63 | u32 counter2048; 64 | u32 key[8]; 65 | u32 iv[8]; 66 | u32 keysize; /* key size in bytes */ 67 | u32 ivsize; /* iv size in bytes */ 68 | } ECRYPT_ctx; 69 | 70 | /* ------------------------------------------------------------------------- */ 71 | 72 | /* Mandatory functions */ 73 | 74 | /* 75 | * Key and message independent initialization. This function will be 76 | * called once when the program starts (e.g., to build expanded S-box 77 | * tables). 78 | */ 79 | void ECRYPT_init(void); 80 | 81 | /* 82 | * Key setup. It is the user's responsibility to select the values of 83 | * keysize and ivsize from the set of supported values specified 84 | * above. 85 | */ 86 | void ECRYPT_keysetup( 87 | ECRYPT_ctx* ctx, 88 | const u8* key, 89 | u32 keysize, /* Key size in bits. */ 90 | u32 ivsize); /* IV size in bits. */ 91 | 92 | /* 93 | * IV setup. After having called ECRYPT_keysetup(), the user is 94 | * allowed to call ECRYPT_ivsetup() different times in order to 95 | * encrypt/decrypt different messages with the same key but different 96 | * IV's. 97 | */ 98 | void ECRYPT_ivsetup( 99 | ECRYPT_ctx* ctx, 100 | const u8* iv); 101 | 102 | /* 103 | * Encryption/decryption of arbitrary length messages. 104 | * 105 | * For efficiency reasons, the API provides two types of 106 | * encrypt/decrypt functions. The ECRYPT_encrypt_bytes() function 107 | * (declared here) encrypts byte strings of arbitrary length, while 108 | * the ECRYPT_encrypt_blocks() function (defined later) only accepts 109 | * lengths which are multiples of ECRYPT_BLOCKLENGTH. 110 | * 111 | * The user is allowed to make multiple calls to 112 | * ECRYPT_encrypt_blocks() to incrementally encrypt a long message, 113 | * but he is NOT allowed to make additional encryption calls once he 114 | * has called ECRYPT_encrypt_bytes() (unless he starts a new message 115 | * of course). For example, this sequence of calls is acceptable: 116 | * 117 | * ECRYPT_keysetup(); 118 | * 119 | * ECRYPT_ivsetup(); 120 | * ECRYPT_encrypt_blocks(); 121 | * ECRYPT_encrypt_blocks(); 122 | * ECRYPT_encrypt_bytes(); 123 | * 124 | * ECRYPT_ivsetup(); 125 | * ECRYPT_encrypt_blocks(); 126 | * ECRYPT_encrypt_blocks(); 127 | * 128 | * ECRYPT_ivsetup(); 129 | * ECRYPT_encrypt_bytes(); 130 | * 131 | * The following sequence is not: 132 | * 133 | * ECRYPT_keysetup(); 134 | * ECRYPT_ivsetup(); 135 | * ECRYPT_encrypt_blocks(); 136 | * ECRYPT_encrypt_bytes(); 137 | * ECRYPT_encrypt_blocks(); 138 | */ 139 | 140 | /* 141 | * By default ECRYPT_encrypt_bytes() and ECRYPT_decrypt_bytes() are 142 | * defined as macros which redirect the call to a single function 143 | * ECRYPT_process_bytes(). If you want to provide separate encryption 144 | * and decryption functions, please undef 145 | * ECRYPT_HAS_SINGLE_BYTE_FUNCTION. 146 | */ 147 | #define ECRYPT_HAS_SINGLE_BYTE_FUNCTION 1 /* [edit] */ 148 | #ifdef ECRYPT_HAS_SINGLE_BYTE_FUNCTION 149 | 150 | #define ECRYPT_encrypt_bytes(ctx, plaintext, ciphertext, msglen) \ 151 | ECRYPT_process_bytes(0, ctx, plaintext, ciphertext, msglen) 152 | 153 | #define ECRYPT_decrypt_bytes(ctx, ciphertext, plaintext, msglen) \ 154 | ECRYPT_process_bytes(1, ctx, ciphertext, plaintext, msglen) 155 | 156 | void ECRYPT_process_bytes( 157 | int action, /* 0 = encrypt; 1 = decrypt; */ 158 | ECRYPT_ctx* ctx, 159 | const u8* input, 160 | u8* output, 161 | u32 msglen); /* Message length in bytes. */ 162 | 163 | #else 164 | 165 | void ECRYPT_encrypt_bytes( 166 | ECRYPT_ctx* ctx, 167 | const u8* plaintext, 168 | u8* ciphertext, 169 | u32 msglen); /* Message length in bytes. */ 170 | 171 | void ECRYPT_decrypt_bytes( 172 | ECRYPT_ctx* ctx, 173 | const u8* ciphertext, 174 | u8* plaintext, 175 | u32 msglen); /* Message length in bytes. */ 176 | 177 | #endif 178 | 179 | /* ------------------------------------------------------------------------- */ 180 | 181 | /* Optional features */ 182 | 183 | /* 184 | * For testing purposes it can sometimes be useful to have a function 185 | * which immediately generates keystream without having to provide it 186 | * with a zero plaintext. If your cipher cannot provide this function 187 | * (e.g., because it is not strictly a synchronous cipher), please 188 | * reset the ECRYPT_GENERATES_KEYSTREAM flag. 189 | */ 190 | 191 | #define ECRYPT_GENERATES_KEYSTREAM 192 | #ifdef ECRYPT_GENERATES_KEYSTREAM 193 | 194 | void ECRYPT_keystream_bytes( 195 | ECRYPT_ctx* ctx, 196 | u8* keystream, 197 | u32 length); /* Length of keystream in bytes. */ 198 | 199 | #endif 200 | 201 | /* ------------------------------------------------------------------------- */ 202 | 203 | /* Optional optimizations */ 204 | 205 | /* 206 | * By default, the functions in this section are implemented using 207 | * calls to functions declared above. However, you might want to 208 | * implement them differently for performance reasons. 209 | */ 210 | 211 | /* 212 | * All-in-one encryption/decryption of (short) packets. 213 | * 214 | * The default definitions of these functions can be found in 215 | * "ecrypt-sync.c". If you want to implement them differently, please 216 | * undef the ECRYPT_USES_DEFAULT_ALL_IN_ONE flag. 217 | */ 218 | #define ECRYPT_USES_DEFAULT_ALL_IN_ONE /* [edit] */ 219 | 220 | /* 221 | * Undef ECRYPT_HAS_SINGLE_PACKET_FUNCTION if you want to provide 222 | * separate packet encryption and decryption functions. 223 | */ 224 | #define ECRYPT_HAS_SINGLE_PACKET_FUNCTION /* [edit] */ 225 | #ifdef ECRYPT_HAS_SINGLE_PACKET_FUNCTION 226 | 227 | #define ECRYPT_encrypt_packet( \ 228 | ctx, iv, plaintext, ciphertext, mglen) \ 229 | ECRYPT_process_packet(0, \ 230 | ctx, iv, plaintext, ciphertext, mglen) 231 | 232 | #define ECRYPT_decrypt_packet( \ 233 | ctx, iv, ciphertext, plaintext, mglen) \ 234 | ECRYPT_process_packet(1, \ 235 | ctx, iv, ciphertext, plaintext, mglen) 236 | 237 | void ECRYPT_process_packet( 238 | int action, /* 0 = encrypt; 1 = decrypt; */ 239 | ECRYPT_ctx* ctx, 240 | const u8* iv, 241 | const u8* input, 242 | u8* output, 243 | u32 msglen); 244 | 245 | #else 246 | 247 | void ECRYPT_encrypt_packet( 248 | ECRYPT_ctx* ctx, 249 | const u8* iv, 250 | const u8* plaintext, 251 | u8* ciphertext, 252 | u32 msglen); 253 | 254 | void ECRYPT_decrypt_packet( 255 | ECRYPT_ctx* ctx, 256 | const u8* iv, 257 | const u8* ciphertext, 258 | u8* plaintext, 259 | u32 msglen); 260 | 261 | #endif 262 | 263 | /* 264 | * Encryption/decryption of blocks. 265 | * 266 | * By default, these functions are defined as macros. If you want to 267 | * provide a different implementation, please undef the 268 | * ECRYPT_USES_DEFAULT_BLOCK_MACROS flag and implement the functions 269 | * declared below. 270 | */ 271 | 272 | #define ECRYPT_BLOCKLENGTH 4 /* [edit] */ 273 | 274 | #define ECRYPT_USES_DEFAULT_BLOCK_MACROS /* [edit] */ 275 | #ifdef ECRYPT_USES_DEFAULT_BLOCK_MACROS 276 | 277 | #define ECRYPT_encrypt_blocks(ctx, plaintext, ciphertext, blocks) \ 278 | ECRYPT_encrypt_bytes(ctx, plaintext, ciphertext, \ 279 | (blocks) * ECRYPT_BLOCKLENGTH) 280 | 281 | #define ECRYPT_decrypt_blocks(ctx, ciphertext, plaintext, blocks) \ 282 | ECRYPT_decrypt_bytes(ctx, ciphertext, plaintext, \ 283 | (blocks) * ECRYPT_BLOCKLENGTH) 284 | 285 | #ifdef ECRYPT_GENERATES_KEYSTREAM 286 | 287 | #define ECRYPT_keystream_blocks(ctx, keystream, blocks) \ 288 | ECRYPT_keystream_bytes(ctx, keystream, \ 289 | (blocks) * ECRYPT_BLOCKLENGTH) 290 | 291 | #endif 292 | 293 | #else 294 | 295 | /* 296 | * Undef ECRYPT_HAS_SINGLE_BLOCK_FUNCTION if you want to provide 297 | * separate block encryption and decryption functions. 298 | */ 299 | #define ECRYPT_HAS_SINGLE_BLOCK_FUNCTION /* [edit] */ 300 | #ifdef ECRYPT_HAS_SINGLE_BLOCK_FUNCTION 301 | 302 | #define ECRYPT_encrypt_blocks(ctx, plaintext, ciphertext, blocks) \ 303 | ECRYPT_process_blocks(0, ctx, plaintext, ciphertext, blocks) 304 | 305 | #define ECRYPT_decrypt_blocks(ctx, ciphertext, plaintext, blocks) \ 306 | ECRYPT_process_blocks(1, ctx, ciphertext, plaintext, blocks) 307 | 308 | void ECRYPT_process_blocks( 309 | int action, /* 0 = encrypt; 1 = decrypt; */ 310 | ECRYPT_ctx* ctx, 311 | const u8* input, 312 | u8* output, 313 | u32 blocks); /* Message length in blocks. */ 314 | 315 | #else 316 | 317 | void ECRYPT_encrypt_blocks( 318 | ECRYPT_ctx* ctx, 319 | const u8* plaintext, 320 | u8* ciphertext, 321 | u32 blocks); /* Message length in blocks. */ 322 | 323 | void ECRYPT_decrypt_blocks( 324 | ECRYPT_ctx* ctx, 325 | const u8* ciphertext, 326 | u8* plaintext, 327 | u32 blocks); /* Message length in blocks. */ 328 | 329 | #endif 330 | 331 | #ifdef ECRYPT_GENERATES_KEYSTREAM 332 | 333 | void ECRYPT_keystream_blocks( 334 | ECRYPT_ctx* ctx, 335 | u8* keystream, 336 | u32 blocks); /* Keystream length in blocks. */ 337 | 338 | #endif 339 | 340 | #endif 341 | 342 | /* 343 | * If your cipher can be implemented in different ways, you can use 344 | * the ECRYPT_VARIANT parameter to allow the user to choose between 345 | * them at compile time (e.g., gcc -DECRYPT_VARIANT=3 ...). Please 346 | * only use this possibility if you really think it could make a 347 | * significant difference and keep the number of variants 348 | * (ECRYPT_MAXVARIANT) as small as possible (definitely not more than 349 | * 10). Note also that all variants should have exactly the same 350 | * external interface (i.e., the same ECRYPT_BLOCKLENGTH, etc.). 351 | */ 352 | #define ECRYPT_MAXVARIANT 1 /* [edit] */ 353 | 354 | #ifndef ECRYPT_VARIANT 355 | #define ECRYPT_VARIANT 1 356 | #endif 357 | 358 | #if (ECRYPT_VARIANT > ECRYPT_MAXVARIANT) 359 | #error this variant does not exist 360 | #endif 361 | 362 | /* ------------------------------------------------------------------------- */ 363 | 364 | #endif 365 | 366 | 367 | /* =========================================================================== 368 | 369 | Added functions: HC-256 Mandatory functions 370 | 371 | ============================================================================== */ 372 | 373 | #define f1(x) (ROTR32((x),7) ^ ROTR32((x),18) ^ ((x) >> 3)) 374 | #define f2(x) (ROTR32((x),17) ^ ROTR32((x),19) ^ ((x) >> 10)) 375 | 376 | 377 | 378 | u32 h1(ECRYPT_ctx* ctx, u32 u) { 379 | u32 tem; 380 | unsigned char a,b,c,d; 381 | a = (unsigned char) ((u)); 382 | b = (unsigned char) ((u) >> 8); 383 | c = (unsigned char) ((u) >> 16); 384 | d = (unsigned char) ((u) >> 24); 385 | tem = ctx->Q[a]+ctx->Q[256+b]+ctx->Q[512+c]+ctx->Q[768+d]; 386 | return (tem); 387 | } 388 | 389 | 390 | 391 | u32 h2(ECRYPT_ctx* ctx, u32 u) { 392 | u32 tem; 393 | unsigned char a,b,c,d; 394 | a = (unsigned char) ((u)); 395 | b = (unsigned char) ((u) >> 8); 396 | c = (unsigned char) ((u) >> 16); 397 | d = (unsigned char) ((u) >> 24); 398 | tem = ctx->P[a]+ctx->P[256+b]+ctx->P[512+c]+ctx->P[768+d]; 399 | return (tem); 400 | } 401 | 402 | 403 | 404 | u32 generate(ECRYPT_ctx* ctx) /*one step of the cipher*/ 405 | { 406 | u32 i,i3, i10, i12, i1023; 407 | u32 output; 408 | 409 | i = ctx->counter2048 & 0x3ff; 410 | i3 = (i - 3) & 0x3ff; 411 | i10 = (i - 10) & 0x3ff; 412 | i12 = (i - 12) & 0x3ff; 413 | i1023 = (i - 1023) & 0x3ff; 414 | 415 | if (ctx->counter2048 < 1024) { 416 | ctx->P[i] = ctx->P[i] + ctx->P[i10] + (ROTR32(ctx->P[i3],10)^ROTR32(ctx->P[i1023],23))+ctx->Q[(ctx->P[i3]^ctx->P[i1023])&0x3ff]; 417 | output = h1(ctx,ctx->P[i12]) ^ ctx->P[i]; 418 | } 419 | else { 420 | ctx->Q[i] = ctx->Q[i] + ctx->Q[i10] + (ROTR32(ctx->Q[i3],10)^ROTR32(ctx->Q[i1023],23))+ctx->P[(ctx->Q[i3]^ctx->Q[i1023])&0x3ff]; 421 | output = h2(ctx, ctx->Q[i12]) ^ ctx->Q[i]; 422 | } 423 | ctx->counter2048 = (ctx->counter2048+1) & 0x7ff; 424 | return (output); 425 | } 426 | 427 | 428 | 429 | 430 | 431 | void ECRYPT_init(void) { 432 | } /* No operation performed */ 433 | 434 | 435 | void ECRYPT_keysetup( 436 | ECRYPT_ctx* ctx, 437 | const u8* key, 438 | u32 keysize, /* Key size in bits. */ 439 | u32 ivsize) /* IV size in bits. */ 440 | { 441 | u32 i; 442 | 443 | ctx->keysize = keysize >> 3; 444 | ctx->ivsize = ivsize >> 3; 445 | 446 | for (i = 0; i < 8; i++) 447 | ctx->key[i] = 0; 448 | 449 | for (i = 0; (i < ctx->keysize) & (i < 32); i++) 450 | { 451 | ctx->key[i >> 2] = ctx->key[i >> 2] | key[i]; 452 | ctx->key[i >> 2] = ROTL32(ctx->key[i >> 2],8); 453 | } 454 | 455 | } /* initialize the key, save the iv size*/ 456 | 457 | 458 | 459 | 460 | void ECRYPT_ivsetup( 461 | ECRYPT_ctx* ctx, 462 | const u8* iv) 463 | { 464 | u32 W[2560],i; 465 | 466 | /* initialize the iv */ 467 | for (i = 0; i < 8; i++) 468 | ctx->iv[i] = 0; 469 | 470 | for (i = 0; (i < ctx->ivsize) & (i < 32); i++) 471 | { 472 | ctx->iv[i >> 2] = ctx->iv[i >> 2] | iv[i]; 473 | ctx->iv[i >> 2] = ROTL32(ctx->iv[i >> 2],8); 474 | } 475 | 476 | /* setup the table P and Q */ 477 | 478 | for (i = 0; i < 8; i++) 479 | W[i] = ctx->key[i]; 480 | 481 | for (i = 8; i < 16; i++) 482 | W[i] = ctx->iv[i-8]; 483 | 484 | for (i = 16; i < 2560; i++) 485 | W[i] = f2(W[i-2]) + W[i-7] + f1(W[i-15]) + W[i-16]+i; 486 | 487 | for (i = 0; i < 1024; i++) 488 | ctx->P[i] = W[i+512]; 489 | 490 | for (i = 0; i < 1024; i++) 491 | ctx->Q[i] = W[i+1536]; 492 | 493 | ctx->counter2048 = 0; 494 | 495 | /* run the cipher 4096 steps before generating the output */ 496 | for (i = 0; i < 4096; i++) 497 | generate(ctx); 498 | } 499 | 500 | 501 | 502 | void ECRYPT_process_bytes( 503 | int action, /* 0 = encrypt; 1 = decrypt; */ 504 | ECRYPT_ctx* ctx, 505 | const u8* input, 506 | u8* output, 507 | u32 msglen) /* Message length in bytes. */ 508 | { 509 | u32 i, j, msglen32, keystreamword; 510 | 511 | msglen32 = msglen >> 2; 512 | 513 | for (i = 0; i < msglen32; i++) { 514 | keystreamword = generate(ctx); /*generate a 32-bit word*/ 515 | for (j = 0; j < 4; j++) { 516 | *output = *input ^ keystreamword; /*encrypt one byte*/ 517 | output += 1; 518 | input +=1; 519 | keystreamword = keystreamword >> 8; 520 | } 521 | } 522 | 523 | keystreamword = generate(ctx); 524 | for (i = 0; i < (msglen & 3); i++) { 525 | *output = *input ^ keystreamword; /*encrypt one byte*/ 526 | output += 1; 527 | input +=1; 528 | keystreamword = keystreamword >> 8; 529 | } 530 | } 531 | 532 | -------------------------------------------------------------------------------- /ref/testvectors.txt: -------------------------------------------------------------------------------- 1 | For 256-bit key and 256-bit IV. 2 | 3 | Let key be an array and with 32 elements, i.e., 4 | Key = Key[0], key[1], key[2], ...., key [30], key[31], 5 | where each key[i] denotes one byte. 6 | Let IV be an array and with 32 elements, i.e., 7 | IV = IV[0], IV[1], IV[2], ...., IV [30], IV[31], 8 | where each IV[i] denotes one byte. 9 | 10 | 11 | 1. If every byte of the key and IV are with value 0, 12 | then the first 32 bytes of the keystream are given as: 13 | 14 | 5b 07 89 85 d8 f6 f3 0d 15 | 42 c5 c0 2f a6 b6 79 51 16 | 53 f0 65 34 80 1f 89 f2 17 | 4e 74 24 8b 72 0b 48 18 18 | 19 | 20 | 2. If every byte of the key and IV are with value 0, 21 | except that IV[0] = 1, then the first 32 bytes of the 22 | keystream are given as: 23 | 24 | af e2 a2 bf 4f 17 ce e9 25 | fe c2 05 8b d1 b1 8b b1 26 | 5f c0 42 ee 71 2b 31 01 27 | dd 50 1f c6 0b 08 2a 50 28 | 29 | 30 | 3. If every byte of the key and IV are with value 0, 31 | except that key[0] = 0x55, then the first 32 bytes of the 32 | keystream are given as: 33 | 34 | 1c 40 4a fe 4f e2 5f ed 35 | 95 8f 9a d1 ae 36 c0 6f 36 | 88 a6 5a 3c c0 ab e2 23 37 | ae b3 90 2f 42 0e d3 a8 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /test: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peterferrie/hc256/2023e013e9934b0be56af3396b884e46ec136b47/test -------------------------------------------------------------------------------- /test.c: -------------------------------------------------------------------------------- 1 | 2 | // test unit for hc-256 3 | // odzhan 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #include "hc.h" 10 | 11 | // 1. If every byte of the key and IV are with value 0, 12 | // then the first 32 bytes of the keystream are given as: 13 | 14 | uint8_t ct1[]= 15 | { 0x5b, 0x07, 0x89, 0x85, 0xd8, 0xf6, 0xf3, 0x0d, 16 | 0x42, 0xc5, 0xc0, 0x2f, 0xa6, 0xb6, 0x79, 0x51, 17 | 0x53, 0xf0, 0x65, 0x34, 0x80, 0x1f, 0x89, 0xf2, 18 | 0x4e, 0x74, 0x24, 0x8b, 0x72, 0x0b, 0x48, 0x18 }; 19 | 20 | // 2. If every byte of the key and IV are with value 0, 21 | // except that IV[0] = 1, then the first 32 bytes of the 22 | // keystream are given as: 23 | 24 | uint8_t ct2[]= 25 | { 0xaf, 0xe2, 0xa2, 0xbf, 0x4f, 0x17, 0xce, 0xe9, 26 | 0xfe, 0xc2, 0x05, 0x8b, 0xd1, 0xb1, 0x8b, 0xb1, 27 | 0x5f, 0xc0, 0x42, 0xee, 0x71, 0x2b, 0x31, 0x01, 28 | 0xdd, 0x50, 0x1f, 0xc6, 0x0b, 0x08, 0x2a, 0x50 }; 29 | 30 | // 3. If every byte of the key and IV are with value 0, 31 | // except that key[0] = 0x55, then the first 32 bytes of the 32 | // keystream are given as: 33 | 34 | uint8_t ct3[]= 35 | { 0x1c, 0x40, 0x4a, 0xfe, 0x4f, 0xe2, 0x5f, 0xed, 36 | 0x95, 0x8f, 0x9a, 0xd1, 0xae, 0x36, 0xc0, 0x6f, 37 | 0x88, 0xa6, 0x5a, 0x3c, 0xc0, 0xab, 0xe2, 0x23, 38 | 0xae, 0xb3, 0x90, 0x2f, 0x42, 0x0e, 0xd3, 0xa8 }; 39 | 40 | uint8_t *ct_tbl[3]={ct1, ct2, ct3}; 41 | 42 | int equ(uint8_t x[], uint8_t y[], int len) { 43 | return memcmp(x, y, len)==0; 44 | } 45 | 46 | void bin2hex(void *in, int len) { 47 | int i; 48 | uint8_t *p=(uint8_t*)in; 49 | 50 | for (i=0; i