|
| 1 | +/* LibTomCrypt, modular cryptographic library -- Tom St Denis |
| 2 | + * |
| 3 | + * LibTomCrypt is a library that provides various cryptographic |
| 4 | + * algorithms in a highly modular and flexible manner. |
| 5 | + * |
| 6 | + * The library is free for all purposes without any express |
| 7 | + * guarantee it works. |
| 8 | + */ |
| 9 | + |
| 10 | +/****************************************************************************** |
| 11 | + * This Rabbit C source code was morphed fm the EU eSTREAM ECRYPT submission |
| 12 | + * and should run on any conforming C implementation (C90 or later). |
| 13 | + * |
| 14 | + * This implementation supports any key length up to 128 bits (16 bytes) and |
| 15 | + * works in increments of 8-bit bytes. Keys must be submitted as whole bytes |
| 16 | + * and shorter keys will be right-null-padded to 16 bytes. Likewise, an iv |
| 17 | + * may be any length up to 8 bytes and will be padded out to 8 bytes. |
| 18 | + * |
| 19 | + * The eSTREAM submission was rather picky about the calling sequence of |
| 20 | + * ECRYPT_process_blocks() and ECRYPT_process_bytes(). That version allowed |
| 21 | + * calling ECRYPT_process_blocks() multiple times for a multiple of whole |
| 22 | + * 16-byte blocks, but once ECRYPT_process_bytes() was called. no more calls |
| 23 | + * were supported correctly. This implementation handles the keystream |
| 24 | + * differently and rabbit_crypt() may be called as many times as desired, |
| 25 | + * crypting any number of bytes each time. |
| 26 | + * |
| 27 | + * http://www.ecrypt.eu.org/stream/e2-rabbit.html |
| 28 | + * |
| 29 | + * NB: One of the test vectors distributed by the eSTREAM site in the file |
| 30 | + * "rabbit_p3source.zip" is in error. Referring to "test-vectors.txt" |
| 31 | + * in that ZIP file, the 3rd line in "out1" should be |
| 32 | + * "96 D6 73 16 88 D1 68 DA 51 D4 0C 70 C3 A1 16 F4". |
| 33 | + * |
| 34 | + * Here is the original legal notice accompanying the Rabbit submission |
| 35 | + * to the EU eSTREAM competition. |
| 36 | + *--------------------------------------------------------------------------- |
| 37 | + * Copyright (C) Cryptico A/S. All rights reserved. |
| 38 | + * |
| 39 | + * YOU SHOULD CAREFULLY READ THIS LEGAL NOTICE BEFORE USING THIS SOFTWARE. |
| 40 | + * |
| 41 | + * This software is developed by Cryptico A/S and/or its suppliers. |
| 42 | + * All title and intellectual property rights in and to the software, |
| 43 | + * including but not limited to patent rights and copyrights, are owned |
| 44 | + * by Cryptico A/S and/or its suppliers. |
| 45 | + * |
| 46 | + * The software may be used solely for non-commercial purposes |
| 47 | + * without the prior written consent of Cryptico A/S. For further |
| 48 | + * information on licensing terms and conditions please contact |
| 49 | + * Cryptico A/S at [email protected] |
| 50 | + * |
| 51 | + * Cryptico, CryptiCore, the Cryptico logo and "Re-thinking encryption" |
| 52 | + * are either trademarks or registered trademarks of Cryptico A/S. |
| 53 | + * |
| 54 | + * Cryptico A/S shall not in any way be liable for any use of this |
| 55 | + * software. The software is provided "as is" without any express or |
| 56 | + * implied warranty. |
| 57 | + *--------------------------------------------------------------------------- |
| 58 | + * On October 6, 2008, Rabbit was "released into the public domain and |
| 59 | + * may be used freely for any purpose." |
| 60 | + * http://www.ecrypt.eu.org/stream/rabbitpf.html |
| 61 | + * https://web.archive.org/web/20090630021733/http://www.ecrypt.eu.org/stream/phorum/read.php?1,1244 |
| 62 | + ******************************************************************************/ |
| 63 | + |
| 64 | + |
| 65 | +#ifdef LTC_RABBIT |
| 66 | + |
| 67 | +/* local/private prototypes (NB: rabbit_ctx and rabbit_state are different) */ |
| 68 | +static LTC_INLINE ulong32 _rabbit_g_func(ulong32 x); |
| 69 | +static LTC_INLINE void _rabbit_next_state(rabbit_ctx *p_instance); |
| 70 | +static LTC_INLINE void _rabbit_gen_1_block(rabbit_state* st, unsigned char *out); |
| 71 | + |
| 72 | +/* -------------------------------------------------------------------------- */ |
| 73 | + |
| 74 | +/* Square a 32-bit unsigned integer to obtain the 64-bit result and return */ |
| 75 | +/* the upper 32 bits XOR the lower 32 bits */ |
| 76 | +static LTC_INLINE ulong32 _rabbit_g_func(ulong32 x) |
| 77 | +{ |
| 78 | + ulong32 a, b, h, l; |
| 79 | + |
| 80 | + /* Construct high and low argument for squaring */ |
| 81 | + a = x & 0xFFFF; |
| 82 | + b = x >> 16; |
| 83 | + |
| 84 | + /* Calculate high and low result of squaring */ |
| 85 | + h = ((((ulong32)(a*a)>>17) + (ulong32)(a*b))>>15) + b*b; |
| 86 | + l = x * x; |
| 87 | + |
| 88 | + /* Return high XOR low */ |
| 89 | + return (ulong32)(h^l); |
| 90 | +} |
| 91 | + |
| 92 | +/* -------------------------------------------------------------------------- */ |
| 93 | + |
| 94 | +/* Calculate the next internal state */ |
| 95 | +static LTC_INLINE void _rabbit_next_state(rabbit_ctx *p_instance) |
| 96 | +{ |
| 97 | + ulong32 g[8], c_old[8], i; |
| 98 | + |
| 99 | + /* Save old counter values */ |
| 100 | + for (i=0; i<8; i++) { |
| 101 | + c_old[i] = p_instance->c[i]; |
| 102 | + } |
| 103 | + |
| 104 | + /* Calculate new counter values */ |
| 105 | + p_instance->c[0] = (ulong32)(p_instance->c[0] + 0x4D34D34D + p_instance->carry); |
| 106 | + p_instance->c[1] = (ulong32)(p_instance->c[1] + 0xD34D34D3 + (p_instance->c[0] < c_old[0])); |
| 107 | + p_instance->c[2] = (ulong32)(p_instance->c[2] + 0x34D34D34 + (p_instance->c[1] < c_old[1])); |
| 108 | + p_instance->c[3] = (ulong32)(p_instance->c[3] + 0x4D34D34D + (p_instance->c[2] < c_old[2])); |
| 109 | + p_instance->c[4] = (ulong32)(p_instance->c[4] + 0xD34D34D3 + (p_instance->c[3] < c_old[3])); |
| 110 | + p_instance->c[5] = (ulong32)(p_instance->c[5] + 0x34D34D34 + (p_instance->c[4] < c_old[4])); |
| 111 | + p_instance->c[6] = (ulong32)(p_instance->c[6] + 0x4D34D34D + (p_instance->c[5] < c_old[5])); |
| 112 | + p_instance->c[7] = (ulong32)(p_instance->c[7] + 0xD34D34D3 + (p_instance->c[6] < c_old[6])); |
| 113 | + p_instance->carry = (p_instance->c[7] < c_old[7]); |
| 114 | + |
| 115 | + /* Calculate the g-values */ |
| 116 | + for (i=0;i<8;i++) { |
| 117 | + g[i] = _rabbit_g_func((ulong32)(p_instance->x[i] + p_instance->c[i])); |
| 118 | + } |
| 119 | + |
| 120 | + /* Calculate new state values */ |
| 121 | + p_instance->x[0] = (ulong32)(g[0] + ROLc(g[7],16) + ROLc(g[6], 16)); |
| 122 | + p_instance->x[1] = (ulong32)(g[1] + ROLc(g[0], 8) + g[7]); |
| 123 | + p_instance->x[2] = (ulong32)(g[2] + ROLc(g[1],16) + ROLc(g[0], 16)); |
| 124 | + p_instance->x[3] = (ulong32)(g[3] + ROLc(g[2], 8) + g[1]); |
| 125 | + p_instance->x[4] = (ulong32)(g[4] + ROLc(g[3],16) + ROLc(g[2], 16)); |
| 126 | + p_instance->x[5] = (ulong32)(g[5] + ROLc(g[4], 8) + g[3]); |
| 127 | + p_instance->x[6] = (ulong32)(g[6] + ROLc(g[5],16) + ROLc(g[4], 16)); |
| 128 | + p_instance->x[7] = (ulong32)(g[7] + ROLc(g[6], 8) + g[5]); |
| 129 | +} |
| 130 | + |
| 131 | +/* ------------------------------------------------------------------------- */ |
| 132 | + |
| 133 | +static LTC_INLINE void _rabbit_gen_1_block(rabbit_state* st, unsigned char *out) |
| 134 | +{ |
| 135 | + ulong32 *ptr; |
| 136 | + |
| 137 | + /* Iterate the work context once */ |
| 138 | + _rabbit_next_state(&(st->work_ctx)); |
| 139 | + |
| 140 | + /* Generate 16 bytes of pseudo-random data */ |
| 141 | + ptr = (ulong32*)&(st->work_ctx.x); |
| 142 | + STORE32L((ptr[0] ^ (ptr[5]>>16) ^ (ulong32)(ptr[3]<<16)), out+ 0); |
| 143 | + STORE32L((ptr[2] ^ (ptr[7]>>16) ^ (ulong32)(ptr[5]<<16)), out+ 4); |
| 144 | + STORE32L((ptr[4] ^ (ptr[1]>>16) ^ (ulong32)(ptr[7]<<16)), out+ 8); |
| 145 | + STORE32L((ptr[6] ^ (ptr[3]>>16) ^ (ulong32)(ptr[1]<<16)), out+12); |
| 146 | +} |
| 147 | + |
| 148 | +/* -------------------------------------------------------------------------- */ |
| 149 | + |
| 150 | +#endif |
| 151 | + |
| 152 | +/* ref: $Format:%D$ */ |
| 153 | +/* git commit: $Format:%H$ */ |
| 154 | +/* commit time: $Format:%ai$ */ |
0 commit comments