diff --git a/ctaocrypt/src/arc4.c b/ctaocrypt/src/arc4.c deleted file mode 100644 index d4b4bc5b5..000000000 --- a/ctaocrypt/src/arc4.c +++ /dev/null @@ -1,179 +0,0 @@ -/* arc4.c - * - * Copyright (C) 2006-2014 wolfSSL Inc. - * - * This file is part of wolfSSL. (formerly known as CyaSSL) - * - * wolfSSL is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * wolfSSL is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include - -#ifndef NO_RC4 - -#include - - -#ifdef HAVE_CAVIUM - static void Arc4CaviumSetKey(Arc4* arc4, const byte* key, word32 length); - static void Arc4CaviumProcess(Arc4* arc4, byte* out, const byte* in, - word32 length); -#endif - - -void Arc4SetKey(Arc4* arc4, const byte* key, word32 length) -{ - word32 i; - word32 keyIndex = 0, stateIndex = 0; - -#ifdef HAVE_CAVIUM - if (arc4->magic == CYASSL_ARC4_CAVIUM_MAGIC) - return Arc4CaviumSetKey(arc4, key, length); -#endif - - arc4->x = 1; - arc4->y = 0; - - for (i = 0; i < ARC4_STATE_SIZE; i++) - arc4->state[i] = (byte)i; - - for (i = 0; i < ARC4_STATE_SIZE; i++) { - word32 a = arc4->state[i]; - stateIndex += key[keyIndex] + a; - stateIndex &= 0xFF; - arc4->state[i] = arc4->state[stateIndex]; - arc4->state[stateIndex] = (byte)a; - - if (++keyIndex >= length) - keyIndex = 0; - } -} - - -static INLINE byte MakeByte(word32* x, word32* y, byte* s) -{ - word32 a = s[*x], b; - *y = (*y+a) & 0xff; - - b = s[*y]; - s[*x] = (byte)b; - s[*y] = (byte)a; - *x = (*x+1) & 0xff; - - return s[(a+b) & 0xff]; -} - - -void Arc4Process(Arc4* arc4, byte* out, const byte* in, word32 length) -{ - word32 x; - word32 y; - -#ifdef HAVE_CAVIUM - if (arc4->magic == CYASSL_ARC4_CAVIUM_MAGIC) - return Arc4CaviumProcess(arc4, out, in, length); -#endif - - x = arc4->x; - y = arc4->y; - - while(length--) - *out++ = *in++ ^ MakeByte(&x, &y, arc4->state); - - arc4->x = (byte)x; - arc4->y = (byte)y; -} - - -#ifdef HAVE_CAVIUM - -#include -#include "cavium_common.h" - -/* Initiliaze Arc4 for use with Nitrox device */ -int Arc4InitCavium(Arc4* arc4, int devId) -{ - if (arc4 == NULL) - return -1; - - if (CspAllocContext(CONTEXT_SSL, &arc4->contextHandle, devId) != 0) - return -1; - - arc4->devId = devId; - arc4->magic = CYASSL_ARC4_CAVIUM_MAGIC; - - return 0; -} - - -/* Free Arc4 from use with Nitrox device */ -void Arc4FreeCavium(Arc4* arc4) -{ - if (arc4 == NULL) - return; - - if (arc4->magic != CYASSL_ARC4_CAVIUM_MAGIC) - return; - - CspFreeContext(CONTEXT_SSL, arc4->contextHandle, arc4->devId); - arc4->magic = 0; -} - - -static void Arc4CaviumSetKey(Arc4* arc4, const byte* key, word32 length) -{ - word32 requestId; - - if (CspInitializeRc4(CAVIUM_BLOCKING, arc4->contextHandle, length, - (byte*)key, &requestId, arc4->devId) != 0) { - CYASSL_MSG("Bad Cavium Arc4 Init"); - } -} - - -static void Arc4CaviumProcess(Arc4* arc4, byte* out, const byte* in, - word32 length) -{ - cyassl_word offset = 0; - word32 requestId; - - while (length > CYASSL_MAX_16BIT) { - word16 slen = (word16)CYASSL_MAX_16BIT; - if (CspEncryptRc4(CAVIUM_BLOCKING, arc4->contextHandle,CAVIUM_UPDATE, - slen, (byte*)in + offset, out + offset, &requestId, - arc4->devId) != 0) { - CYASSL_MSG("Bad Cavium Arc4 Encrypt"); - } - length -= CYASSL_MAX_16BIT; - offset += CYASSL_MAX_16BIT; - } - if (length) { - word16 slen = (word16)length; - if (CspEncryptRc4(CAVIUM_BLOCKING, arc4->contextHandle,CAVIUM_UPDATE, - slen, (byte*)in + offset, out + offset, &requestId, - arc4->devId) != 0) { - CYASSL_MSG("Bad Cavium Arc4 Encrypt"); - } - } -} - -#endif /* HAVE_CAVIUM */ - -#endif /* NO_ARC4 */ - diff --git a/ctaocrypt/src/camellia.c b/ctaocrypt/src/camellia.c deleted file mode 100644 index fe260b27f..000000000 --- a/ctaocrypt/src/camellia.c +++ /dev/null @@ -1,1621 +0,0 @@ -/* camellia.c ver 1.2.0 - * - * Copyright (c) 2006,2007 - * NTT (Nippon Telegraph and Telephone Corporation) . All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer as - * the first lines of this file unmodified. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY NTT ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL NTT BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* camellia.c - * - * Copyright (C) 2006-2014 wolfSSL Inc. - * - * This file is part of wolfSSL. (formerly known as CyaSSL) - * - * wolfSSL is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * wolfSSL is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -/* - * Algorithm Specification - * http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html - */ - - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include - -#ifdef HAVE_CAMELLIA - -#include -#include -#include -#ifdef NO_INLINE - #include -#else - #include -#endif - - -/* u32 must be 32bit word */ -typedef unsigned int u32; -typedef unsigned char u8; - -/* key constants */ - -#define CAMELLIA_SIGMA1L ((u32)0xA09E667FL) -#define CAMELLIA_SIGMA1R ((u32)0x3BCC908BL) -#define CAMELLIA_SIGMA2L ((u32)0xB67AE858L) -#define CAMELLIA_SIGMA2R ((u32)0x4CAA73B2L) -#define CAMELLIA_SIGMA3L ((u32)0xC6EF372FL) -#define CAMELLIA_SIGMA3R ((u32)0xE94F82BEL) -#define CAMELLIA_SIGMA4L ((u32)0x54FF53A5L) -#define CAMELLIA_SIGMA4R ((u32)0xF1D36F1CL) -#define CAMELLIA_SIGMA5L ((u32)0x10E527FAL) -#define CAMELLIA_SIGMA5R ((u32)0xDE682D1DL) -#define CAMELLIA_SIGMA6L ((u32)0xB05688C2L) -#define CAMELLIA_SIGMA6R ((u32)0xB3E6C1FDL) - -/* - * macros - */ - - -#if defined(_MSC_VER) - -# define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00) -# define GETU32(p) SWAP(*((u32 *)(p))) -# define PUTU32(ct, st) {*((u32 *)(ct)) = SWAP((st));} - -#else /* not MS-VC */ - -# define GETU32(pt) \ - (((u32)(pt)[0] << 24) \ - ^ ((u32)(pt)[1] << 16) \ - ^ ((u32)(pt)[2] << 8) \ - ^ ((u32)(pt)[3])) - -# define PUTU32(ct, st) { \ - (ct)[0] = (u8)((st) >> 24); \ - (ct)[1] = (u8)((st) >> 16); \ - (ct)[2] = (u8)((st) >> 8); \ - (ct)[3] = (u8)(st); } - -#endif - -#define CamelliaSubkeyL(INDEX) (subkey[(INDEX)*2]) -#define CamelliaSubkeyR(INDEX) (subkey[(INDEX)*2 + 1]) - -/* rotation right shift 1byte */ -#define CAMELLIA_RR8(x) (((x) >> 8) + ((x) << 24)) -/* rotation left shift 1bit */ -#define CAMELLIA_RL1(x) (((x) << 1) + ((x) >> 31)) -/* rotation left shift 1byte */ -#define CAMELLIA_RL8(x) (((x) << 8) + ((x) >> 24)) - -#define CAMELLIA_ROLDQ(ll, lr, rl, rr, w0, w1, bits) \ - do { \ - w0 = ll; \ - ll = (ll << bits) + (lr >> (32 - bits)); \ - lr = (lr << bits) + (rl >> (32 - bits)); \ - rl = (rl << bits) + (rr >> (32 - bits)); \ - rr = (rr << bits) + (w0 >> (32 - bits)); \ - } while(0) - -#define CAMELLIA_ROLDQo32(ll, lr, rl, rr, w0, w1, bits) \ - do { \ - w0 = ll; \ - w1 = lr; \ - ll = (lr << (bits - 32)) + (rl >> (64 - bits)); \ - lr = (rl << (bits - 32)) + (rr >> (64 - bits)); \ - rl = (rr << (bits - 32)) + (w0 >> (64 - bits)); \ - rr = (w0 << (bits - 32)) + (w1 >> (64 - bits)); \ - } while(0) - -#define CAMELLIA_SP1110(INDEX) (camellia_sp1110[(INDEX)]) -#define CAMELLIA_SP0222(INDEX) (camellia_sp0222[(INDEX)]) -#define CAMELLIA_SP3033(INDEX) (camellia_sp3033[(INDEX)]) -#define CAMELLIA_SP4404(INDEX) (camellia_sp4404[(INDEX)]) - -#define CAMELLIA_F(xl, xr, kl, kr, yl, yr, il, ir, t0, t1) \ - do { \ - il = xl ^ kl; \ - ir = xr ^ kr; \ - t0 = il >> 16; \ - t1 = ir >> 16; \ - yl = CAMELLIA_SP1110(ir & 0xff) \ - ^ CAMELLIA_SP0222((t1 >> 8) & 0xff) \ - ^ CAMELLIA_SP3033(t1 & 0xff) \ - ^ CAMELLIA_SP4404((ir >> 8) & 0xff); \ - yr = CAMELLIA_SP1110((t0 >> 8) & 0xff) \ - ^ CAMELLIA_SP0222(t0 & 0xff) \ - ^ CAMELLIA_SP3033((il >> 8) & 0xff) \ - ^ CAMELLIA_SP4404(il & 0xff); \ - yl ^= yr; \ - yr = CAMELLIA_RR8(yr); \ - yr ^= yl; \ - } while(0) - - -/* - * for speed up - * - */ -#define CAMELLIA_FLS(ll, lr, rl, rr, kll, klr, krl, krr, t0, t1, t2, t3) \ - do { \ - t0 = kll; \ - t0 &= ll; \ - lr ^= CAMELLIA_RL1(t0); \ - t1 = klr; \ - t1 |= lr; \ - ll ^= t1; \ - \ - t2 = krr; \ - t2 |= rr; \ - rl ^= t2; \ - t3 = krl; \ - t3 &= rl; \ - rr ^= CAMELLIA_RL1(t3); \ - } while(0) - -#define CAMELLIA_ROUNDSM(xl, xr, kl, kr, yl, yr, il, ir, t0, t1) \ - do { \ - ir = CAMELLIA_SP1110(xr & 0xff) \ - ^ CAMELLIA_SP0222((xr >> 24) & 0xff) \ - ^ CAMELLIA_SP3033((xr >> 16) & 0xff) \ - ^ CAMELLIA_SP4404((xr >> 8) & 0xff); \ - il = CAMELLIA_SP1110((xl >> 24) & 0xff) \ - ^ CAMELLIA_SP0222((xl >> 16) & 0xff) \ - ^ CAMELLIA_SP3033((xl >> 8) & 0xff) \ - ^ CAMELLIA_SP4404(xl & 0xff); \ - il ^= kl; \ - ir ^= kr; \ - ir ^= il; \ - il = CAMELLIA_RR8(il); \ - il ^= ir; \ - yl ^= ir; \ - yr ^= il; \ - } while(0) - - -static const u32 camellia_sp1110[256] = { - 0x70707000,0x82828200,0x2c2c2c00,0xececec00, - 0xb3b3b300,0x27272700,0xc0c0c000,0xe5e5e500, - 0xe4e4e400,0x85858500,0x57575700,0x35353500, - 0xeaeaea00,0x0c0c0c00,0xaeaeae00,0x41414100, - 0x23232300,0xefefef00,0x6b6b6b00,0x93939300, - 0x45454500,0x19191900,0xa5a5a500,0x21212100, - 0xededed00,0x0e0e0e00,0x4f4f4f00,0x4e4e4e00, - 0x1d1d1d00,0x65656500,0x92929200,0xbdbdbd00, - 0x86868600,0xb8b8b800,0xafafaf00,0x8f8f8f00, - 0x7c7c7c00,0xebebeb00,0x1f1f1f00,0xcecece00, - 0x3e3e3e00,0x30303000,0xdcdcdc00,0x5f5f5f00, - 0x5e5e5e00,0xc5c5c500,0x0b0b0b00,0x1a1a1a00, - 0xa6a6a600,0xe1e1e100,0x39393900,0xcacaca00, - 0xd5d5d500,0x47474700,0x5d5d5d00,0x3d3d3d00, - 0xd9d9d900,0x01010100,0x5a5a5a00,0xd6d6d600, - 0x51515100,0x56565600,0x6c6c6c00,0x4d4d4d00, - 0x8b8b8b00,0x0d0d0d00,0x9a9a9a00,0x66666600, - 0xfbfbfb00,0xcccccc00,0xb0b0b000,0x2d2d2d00, - 0x74747400,0x12121200,0x2b2b2b00,0x20202000, - 0xf0f0f000,0xb1b1b100,0x84848400,0x99999900, - 0xdfdfdf00,0x4c4c4c00,0xcbcbcb00,0xc2c2c200, - 0x34343400,0x7e7e7e00,0x76767600,0x05050500, - 0x6d6d6d00,0xb7b7b700,0xa9a9a900,0x31313100, - 0xd1d1d100,0x17171700,0x04040400,0xd7d7d700, - 0x14141400,0x58585800,0x3a3a3a00,0x61616100, - 0xdedede00,0x1b1b1b00,0x11111100,0x1c1c1c00, - 0x32323200,0x0f0f0f00,0x9c9c9c00,0x16161600, - 0x53535300,0x18181800,0xf2f2f200,0x22222200, - 0xfefefe00,0x44444400,0xcfcfcf00,0xb2b2b200, - 0xc3c3c300,0xb5b5b500,0x7a7a7a00,0x91919100, - 0x24242400,0x08080800,0xe8e8e800,0xa8a8a800, - 0x60606000,0xfcfcfc00,0x69696900,0x50505000, - 0xaaaaaa00,0xd0d0d000,0xa0a0a000,0x7d7d7d00, - 0xa1a1a100,0x89898900,0x62626200,0x97979700, - 0x54545400,0x5b5b5b00,0x1e1e1e00,0x95959500, - 0xe0e0e000,0xffffff00,0x64646400,0xd2d2d200, - 0x10101000,0xc4c4c400,0x00000000,0x48484800, - 0xa3a3a300,0xf7f7f700,0x75757500,0xdbdbdb00, - 0x8a8a8a00,0x03030300,0xe6e6e600,0xdadada00, - 0x09090900,0x3f3f3f00,0xdddddd00,0x94949400, - 0x87878700,0x5c5c5c00,0x83838300,0x02020200, - 0xcdcdcd00,0x4a4a4a00,0x90909000,0x33333300, - 0x73737300,0x67676700,0xf6f6f600,0xf3f3f300, - 0x9d9d9d00,0x7f7f7f00,0xbfbfbf00,0xe2e2e200, - 0x52525200,0x9b9b9b00,0xd8d8d800,0x26262600, - 0xc8c8c800,0x37373700,0xc6c6c600,0x3b3b3b00, - 0x81818100,0x96969600,0x6f6f6f00,0x4b4b4b00, - 0x13131300,0xbebebe00,0x63636300,0x2e2e2e00, - 0xe9e9e900,0x79797900,0xa7a7a700,0x8c8c8c00, - 0x9f9f9f00,0x6e6e6e00,0xbcbcbc00,0x8e8e8e00, - 0x29292900,0xf5f5f500,0xf9f9f900,0xb6b6b600, - 0x2f2f2f00,0xfdfdfd00,0xb4b4b400,0x59595900, - 0x78787800,0x98989800,0x06060600,0x6a6a6a00, - 0xe7e7e700,0x46464600,0x71717100,0xbababa00, - 0xd4d4d400,0x25252500,0xababab00,0x42424200, - 0x88888800,0xa2a2a200,0x8d8d8d00,0xfafafa00, - 0x72727200,0x07070700,0xb9b9b900,0x55555500, - 0xf8f8f800,0xeeeeee00,0xacacac00,0x0a0a0a00, - 0x36363600,0x49494900,0x2a2a2a00,0x68686800, - 0x3c3c3c00,0x38383800,0xf1f1f100,0xa4a4a400, - 0x40404000,0x28282800,0xd3d3d300,0x7b7b7b00, - 0xbbbbbb00,0xc9c9c900,0x43434300,0xc1c1c100, - 0x15151500,0xe3e3e300,0xadadad00,0xf4f4f400, - 0x77777700,0xc7c7c700,0x80808000,0x9e9e9e00, -}; - -static const u32 camellia_sp0222[256] = { - 0x00e0e0e0,0x00050505,0x00585858,0x00d9d9d9, - 0x00676767,0x004e4e4e,0x00818181,0x00cbcbcb, - 0x00c9c9c9,0x000b0b0b,0x00aeaeae,0x006a6a6a, - 0x00d5d5d5,0x00181818,0x005d5d5d,0x00828282, - 0x00464646,0x00dfdfdf,0x00d6d6d6,0x00272727, - 0x008a8a8a,0x00323232,0x004b4b4b,0x00424242, - 0x00dbdbdb,0x001c1c1c,0x009e9e9e,0x009c9c9c, - 0x003a3a3a,0x00cacaca,0x00252525,0x007b7b7b, - 0x000d0d0d,0x00717171,0x005f5f5f,0x001f1f1f, - 0x00f8f8f8,0x00d7d7d7,0x003e3e3e,0x009d9d9d, - 0x007c7c7c,0x00606060,0x00b9b9b9,0x00bebebe, - 0x00bcbcbc,0x008b8b8b,0x00161616,0x00343434, - 0x004d4d4d,0x00c3c3c3,0x00727272,0x00959595, - 0x00ababab,0x008e8e8e,0x00bababa,0x007a7a7a, - 0x00b3b3b3,0x00020202,0x00b4b4b4,0x00adadad, - 0x00a2a2a2,0x00acacac,0x00d8d8d8,0x009a9a9a, - 0x00171717,0x001a1a1a,0x00353535,0x00cccccc, - 0x00f7f7f7,0x00999999,0x00616161,0x005a5a5a, - 0x00e8e8e8,0x00242424,0x00565656,0x00404040, - 0x00e1e1e1,0x00636363,0x00090909,0x00333333, - 0x00bfbfbf,0x00989898,0x00979797,0x00858585, - 0x00686868,0x00fcfcfc,0x00ececec,0x000a0a0a, - 0x00dadada,0x006f6f6f,0x00535353,0x00626262, - 0x00a3a3a3,0x002e2e2e,0x00080808,0x00afafaf, - 0x00282828,0x00b0b0b0,0x00747474,0x00c2c2c2, - 0x00bdbdbd,0x00363636,0x00222222,0x00383838, - 0x00646464,0x001e1e1e,0x00393939,0x002c2c2c, - 0x00a6a6a6,0x00303030,0x00e5e5e5,0x00444444, - 0x00fdfdfd,0x00888888,0x009f9f9f,0x00656565, - 0x00878787,0x006b6b6b,0x00f4f4f4,0x00232323, - 0x00484848,0x00101010,0x00d1d1d1,0x00515151, - 0x00c0c0c0,0x00f9f9f9,0x00d2d2d2,0x00a0a0a0, - 0x00555555,0x00a1a1a1,0x00414141,0x00fafafa, - 0x00434343,0x00131313,0x00c4c4c4,0x002f2f2f, - 0x00a8a8a8,0x00b6b6b6,0x003c3c3c,0x002b2b2b, - 0x00c1c1c1,0x00ffffff,0x00c8c8c8,0x00a5a5a5, - 0x00202020,0x00898989,0x00000000,0x00909090, - 0x00474747,0x00efefef,0x00eaeaea,0x00b7b7b7, - 0x00151515,0x00060606,0x00cdcdcd,0x00b5b5b5, - 0x00121212,0x007e7e7e,0x00bbbbbb,0x00292929, - 0x000f0f0f,0x00b8b8b8,0x00070707,0x00040404, - 0x009b9b9b,0x00949494,0x00212121,0x00666666, - 0x00e6e6e6,0x00cecece,0x00ededed,0x00e7e7e7, - 0x003b3b3b,0x00fefefe,0x007f7f7f,0x00c5c5c5, - 0x00a4a4a4,0x00373737,0x00b1b1b1,0x004c4c4c, - 0x00919191,0x006e6e6e,0x008d8d8d,0x00767676, - 0x00030303,0x002d2d2d,0x00dedede,0x00969696, - 0x00262626,0x007d7d7d,0x00c6c6c6,0x005c5c5c, - 0x00d3d3d3,0x00f2f2f2,0x004f4f4f,0x00191919, - 0x003f3f3f,0x00dcdcdc,0x00797979,0x001d1d1d, - 0x00525252,0x00ebebeb,0x00f3f3f3,0x006d6d6d, - 0x005e5e5e,0x00fbfbfb,0x00696969,0x00b2b2b2, - 0x00f0f0f0,0x00313131,0x000c0c0c,0x00d4d4d4, - 0x00cfcfcf,0x008c8c8c,0x00e2e2e2,0x00757575, - 0x00a9a9a9,0x004a4a4a,0x00575757,0x00848484, - 0x00111111,0x00454545,0x001b1b1b,0x00f5f5f5, - 0x00e4e4e4,0x000e0e0e,0x00737373,0x00aaaaaa, - 0x00f1f1f1,0x00dddddd,0x00595959,0x00141414, - 0x006c6c6c,0x00929292,0x00545454,0x00d0d0d0, - 0x00787878,0x00707070,0x00e3e3e3,0x00494949, - 0x00808080,0x00505050,0x00a7a7a7,0x00f6f6f6, - 0x00777777,0x00939393,0x00868686,0x00838383, - 0x002a2a2a,0x00c7c7c7,0x005b5b5b,0x00e9e9e9, - 0x00eeeeee,0x008f8f8f,0x00010101,0x003d3d3d, -}; - -static const u32 camellia_sp3033[256] = { - 0x38003838,0x41004141,0x16001616,0x76007676, - 0xd900d9d9,0x93009393,0x60006060,0xf200f2f2, - 0x72007272,0xc200c2c2,0xab00abab,0x9a009a9a, - 0x75007575,0x06000606,0x57005757,0xa000a0a0, - 0x91009191,0xf700f7f7,0xb500b5b5,0xc900c9c9, - 0xa200a2a2,0x8c008c8c,0xd200d2d2,0x90009090, - 0xf600f6f6,0x07000707,0xa700a7a7,0x27002727, - 0x8e008e8e,0xb200b2b2,0x49004949,0xde00dede, - 0x43004343,0x5c005c5c,0xd700d7d7,0xc700c7c7, - 0x3e003e3e,0xf500f5f5,0x8f008f8f,0x67006767, - 0x1f001f1f,0x18001818,0x6e006e6e,0xaf00afaf, - 0x2f002f2f,0xe200e2e2,0x85008585,0x0d000d0d, - 0x53005353,0xf000f0f0,0x9c009c9c,0x65006565, - 0xea00eaea,0xa300a3a3,0xae00aeae,0x9e009e9e, - 0xec00ecec,0x80008080,0x2d002d2d,0x6b006b6b, - 0xa800a8a8,0x2b002b2b,0x36003636,0xa600a6a6, - 0xc500c5c5,0x86008686,0x4d004d4d,0x33003333, - 0xfd00fdfd,0x66006666,0x58005858,0x96009696, - 0x3a003a3a,0x09000909,0x95009595,0x10001010, - 0x78007878,0xd800d8d8,0x42004242,0xcc00cccc, - 0xef00efef,0x26002626,0xe500e5e5,0x61006161, - 0x1a001a1a,0x3f003f3f,0x3b003b3b,0x82008282, - 0xb600b6b6,0xdb00dbdb,0xd400d4d4,0x98009898, - 0xe800e8e8,0x8b008b8b,0x02000202,0xeb00ebeb, - 0x0a000a0a,0x2c002c2c,0x1d001d1d,0xb000b0b0, - 0x6f006f6f,0x8d008d8d,0x88008888,0x0e000e0e, - 0x19001919,0x87008787,0x4e004e4e,0x0b000b0b, - 0xa900a9a9,0x0c000c0c,0x79007979,0x11001111, - 0x7f007f7f,0x22002222,0xe700e7e7,0x59005959, - 0xe100e1e1,0xda00dada,0x3d003d3d,0xc800c8c8, - 0x12001212,0x04000404,0x74007474,0x54005454, - 0x30003030,0x7e007e7e,0xb400b4b4,0x28002828, - 0x55005555,0x68006868,0x50005050,0xbe00bebe, - 0xd000d0d0,0xc400c4c4,0x31003131,0xcb00cbcb, - 0x2a002a2a,0xad00adad,0x0f000f0f,0xca00caca, - 0x70007070,0xff00ffff,0x32003232,0x69006969, - 0x08000808,0x62006262,0x00000000,0x24002424, - 0xd100d1d1,0xfb00fbfb,0xba00baba,0xed00eded, - 0x45004545,0x81008181,0x73007373,0x6d006d6d, - 0x84008484,0x9f009f9f,0xee00eeee,0x4a004a4a, - 0xc300c3c3,0x2e002e2e,0xc100c1c1,0x01000101, - 0xe600e6e6,0x25002525,0x48004848,0x99009999, - 0xb900b9b9,0xb300b3b3,0x7b007b7b,0xf900f9f9, - 0xce00cece,0xbf00bfbf,0xdf00dfdf,0x71007171, - 0x29002929,0xcd00cdcd,0x6c006c6c,0x13001313, - 0x64006464,0x9b009b9b,0x63006363,0x9d009d9d, - 0xc000c0c0,0x4b004b4b,0xb700b7b7,0xa500a5a5, - 0x89008989,0x5f005f5f,0xb100b1b1,0x17001717, - 0xf400f4f4,0xbc00bcbc,0xd300d3d3,0x46004646, - 0xcf00cfcf,0x37003737,0x5e005e5e,0x47004747, - 0x94009494,0xfa00fafa,0xfc00fcfc,0x5b005b5b, - 0x97009797,0xfe00fefe,0x5a005a5a,0xac00acac, - 0x3c003c3c,0x4c004c4c,0x03000303,0x35003535, - 0xf300f3f3,0x23002323,0xb800b8b8,0x5d005d5d, - 0x6a006a6a,0x92009292,0xd500d5d5,0x21002121, - 0x44004444,0x51005151,0xc600c6c6,0x7d007d7d, - 0x39003939,0x83008383,0xdc00dcdc,0xaa00aaaa, - 0x7c007c7c,0x77007777,0x56005656,0x05000505, - 0x1b001b1b,0xa400a4a4,0x15001515,0x34003434, - 0x1e001e1e,0x1c001c1c,0xf800f8f8,0x52005252, - 0x20002020,0x14001414,0xe900e9e9,0xbd00bdbd, - 0xdd00dddd,0xe400e4e4,0xa100a1a1,0xe000e0e0, - 0x8a008a8a,0xf100f1f1,0xd600d6d6,0x7a007a7a, - 0xbb00bbbb,0xe300e3e3,0x40004040,0x4f004f4f, -}; - -static const u32 camellia_sp4404[256] = { - 0x70700070,0x2c2c002c,0xb3b300b3,0xc0c000c0, - 0xe4e400e4,0x57570057,0xeaea00ea,0xaeae00ae, - 0x23230023,0x6b6b006b,0x45450045,0xa5a500a5, - 0xeded00ed,0x4f4f004f,0x1d1d001d,0x92920092, - 0x86860086,0xafaf00af,0x7c7c007c,0x1f1f001f, - 0x3e3e003e,0xdcdc00dc,0x5e5e005e,0x0b0b000b, - 0xa6a600a6,0x39390039,0xd5d500d5,0x5d5d005d, - 0xd9d900d9,0x5a5a005a,0x51510051,0x6c6c006c, - 0x8b8b008b,0x9a9a009a,0xfbfb00fb,0xb0b000b0, - 0x74740074,0x2b2b002b,0xf0f000f0,0x84840084, - 0xdfdf00df,0xcbcb00cb,0x34340034,0x76760076, - 0x6d6d006d,0xa9a900a9,0xd1d100d1,0x04040004, - 0x14140014,0x3a3a003a,0xdede00de,0x11110011, - 0x32320032,0x9c9c009c,0x53530053,0xf2f200f2, - 0xfefe00fe,0xcfcf00cf,0xc3c300c3,0x7a7a007a, - 0x24240024,0xe8e800e8,0x60600060,0x69690069, - 0xaaaa00aa,0xa0a000a0,0xa1a100a1,0x62620062, - 0x54540054,0x1e1e001e,0xe0e000e0,0x64640064, - 0x10100010,0x00000000,0xa3a300a3,0x75750075, - 0x8a8a008a,0xe6e600e6,0x09090009,0xdddd00dd, - 0x87870087,0x83830083,0xcdcd00cd,0x90900090, - 0x73730073,0xf6f600f6,0x9d9d009d,0xbfbf00bf, - 0x52520052,0xd8d800d8,0xc8c800c8,0xc6c600c6, - 0x81810081,0x6f6f006f,0x13130013,0x63630063, - 0xe9e900e9,0xa7a700a7,0x9f9f009f,0xbcbc00bc, - 0x29290029,0xf9f900f9,0x2f2f002f,0xb4b400b4, - 0x78780078,0x06060006,0xe7e700e7,0x71710071, - 0xd4d400d4,0xabab00ab,0x88880088,0x8d8d008d, - 0x72720072,0xb9b900b9,0xf8f800f8,0xacac00ac, - 0x36360036,0x2a2a002a,0x3c3c003c,0xf1f100f1, - 0x40400040,0xd3d300d3,0xbbbb00bb,0x43430043, - 0x15150015,0xadad00ad,0x77770077,0x80800080, - 0x82820082,0xecec00ec,0x27270027,0xe5e500e5, - 0x85850085,0x35350035,0x0c0c000c,0x41410041, - 0xefef00ef,0x93930093,0x19190019,0x21210021, - 0x0e0e000e,0x4e4e004e,0x65650065,0xbdbd00bd, - 0xb8b800b8,0x8f8f008f,0xebeb00eb,0xcece00ce, - 0x30300030,0x5f5f005f,0xc5c500c5,0x1a1a001a, - 0xe1e100e1,0xcaca00ca,0x47470047,0x3d3d003d, - 0x01010001,0xd6d600d6,0x56560056,0x4d4d004d, - 0x0d0d000d,0x66660066,0xcccc00cc,0x2d2d002d, - 0x12120012,0x20200020,0xb1b100b1,0x99990099, - 0x4c4c004c,0xc2c200c2,0x7e7e007e,0x05050005, - 0xb7b700b7,0x31310031,0x17170017,0xd7d700d7, - 0x58580058,0x61610061,0x1b1b001b,0x1c1c001c, - 0x0f0f000f,0x16160016,0x18180018,0x22220022, - 0x44440044,0xb2b200b2,0xb5b500b5,0x91910091, - 0x08080008,0xa8a800a8,0xfcfc00fc,0x50500050, - 0xd0d000d0,0x7d7d007d,0x89890089,0x97970097, - 0x5b5b005b,0x95950095,0xffff00ff,0xd2d200d2, - 0xc4c400c4,0x48480048,0xf7f700f7,0xdbdb00db, - 0x03030003,0xdada00da,0x3f3f003f,0x94940094, - 0x5c5c005c,0x02020002,0x4a4a004a,0x33330033, - 0x67670067,0xf3f300f3,0x7f7f007f,0xe2e200e2, - 0x9b9b009b,0x26260026,0x37370037,0x3b3b003b, - 0x96960096,0x4b4b004b,0xbebe00be,0x2e2e002e, - 0x79790079,0x8c8c008c,0x6e6e006e,0x8e8e008e, - 0xf5f500f5,0xb6b600b6,0xfdfd00fd,0x59590059, - 0x98980098,0x6a6a006a,0x46460046,0xbaba00ba, - 0x25250025,0x42420042,0xa2a200a2,0xfafa00fa, - 0x07070007,0x55550055,0xeeee00ee,0x0a0a000a, - 0x49490049,0x68680068,0x38380038,0xa4a400a4, - 0x28280028,0x7b7b007b,0xc9c900c9,0xc1c100c1, - 0xe3e300e3,0xf4f400f4,0xc7c700c7,0x9e9e009e, -}; - - -/** - * Stuff related to the Camellia key schedule - */ -#define subl(x) subL[(x)] -#define subr(x) subR[(x)] - -static int camellia_setup128(const unsigned char *key, u32 *subkey) -{ - u32 kll, klr, krl, krr; - u32 il, ir, t0, t1, w0, w1; - u32 kw4l, kw4r, dw, tl, tr; - -#ifdef CYASSL_SMALL_STACK - u32* subL; - u32* subR; - - subL = (u32*) XMALLOC(sizeof(u32) * 26, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (subL == NULL) - return MEMORY_E; - - subR = (u32*) XMALLOC(sizeof(u32) * 26, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (subR == NULL) { - XFREE(subL, NULL, DYNAMIC_TYPE_TMP_BUFFER); - return MEMORY_E; - } -#else - u32 subL[26]; - u32 subR[26]; -#endif - - /** - * k == kll || klr || krl || krr (|| is concatination) - */ - kll = GETU32(key ); - klr = GETU32(key + 4); - krl = GETU32(key + 8); - krr = GETU32(key + 12); - /** - * generate KL dependent subkeys - */ - subl(0) = kll; subr(0) = klr; - subl(1) = krl; subr(1) = krr; - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); - subl(4) = kll; subr(4) = klr; - subl(5) = krl; subr(5) = krr; - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30); - subl(10) = kll; subr(10) = klr; - subl(11) = krl; subr(11) = krr; - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); - subl(13) = krl; subr(13) = krr; - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17); - subl(16) = kll; subr(16) = klr; - subl(17) = krl; subr(17) = krr; - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17); - subl(18) = kll; subr(18) = klr; - subl(19) = krl; subr(19) = krr; - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17); - subl(22) = kll; subr(22) = klr; - subl(23) = krl; subr(23) = krr; - - /* generate KA */ - kll = subl(0); klr = subr(0); - krl = subl(1); krr = subr(1); - CAMELLIA_F(kll, klr, - CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R, - w0, w1, il, ir, t0, t1); - krl ^= w0; krr ^= w1; - CAMELLIA_F(krl, krr, - CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R, - kll, klr, il, ir, t0, t1); - CAMELLIA_F(kll, klr, - CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R, - krl, krr, il, ir, t0, t1); - krl ^= w0; krr ^= w1; - CAMELLIA_F(krl, krr, - CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R, - w0, w1, il, ir, t0, t1); - kll ^= w0; klr ^= w1; - - /* generate KA dependent subkeys */ - subl(2) = kll; subr(2) = klr; - subl(3) = krl; subr(3) = krr; - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); - subl(6) = kll; subr(6) = klr; - subl(7) = krl; subr(7) = krr; - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); - subl(8) = kll; subr(8) = klr; - subl(9) = krl; subr(9) = krr; - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); - subl(12) = kll; subr(12) = klr; - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); - subl(14) = kll; subr(14) = klr; - subl(15) = krl; subr(15) = krr; - CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34); - subl(20) = kll; subr(20) = klr; - subl(21) = krl; subr(21) = krr; - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17); - subl(24) = kll; subr(24) = klr; - subl(25) = krl; subr(25) = krr; - - - /* absorb kw2 to other subkeys */ - subl(3) ^= subl(1); subr(3) ^= subr(1); - subl(5) ^= subl(1); subr(5) ^= subr(1); - subl(7) ^= subl(1); subr(7) ^= subr(1); - subl(1) ^= subr(1) & ~subr(9); - dw = subl(1) & subl(9), subr(1) ^= CAMELLIA_RL1(dw); - subl(11) ^= subl(1); subr(11) ^= subr(1); - subl(13) ^= subl(1); subr(13) ^= subr(1); - subl(15) ^= subl(1); subr(15) ^= subr(1); - subl(1) ^= subr(1) & ~subr(17); - dw = subl(1) & subl(17), subr(1) ^= CAMELLIA_RL1(dw); - subl(19) ^= subl(1); subr(19) ^= subr(1); - subl(21) ^= subl(1); subr(21) ^= subr(1); - subl(23) ^= subl(1); subr(23) ^= subr(1); - subl(24) ^= subl(1); subr(24) ^= subr(1); - - /* absorb kw4 to other subkeys */ - kw4l = subl(25); kw4r = subr(25); - subl(22) ^= kw4l; subr(22) ^= kw4r; - subl(20) ^= kw4l; subr(20) ^= kw4r; - subl(18) ^= kw4l; subr(18) ^= kw4r; - kw4l ^= kw4r & ~subr(16); - dw = kw4l & subl(16), kw4r ^= CAMELLIA_RL1(dw); - subl(14) ^= kw4l; subr(14) ^= kw4r; - subl(12) ^= kw4l; subr(12) ^= kw4r; - subl(10) ^= kw4l; subr(10) ^= kw4r; - kw4l ^= kw4r & ~subr(8); - dw = kw4l & subl(8), kw4r ^= CAMELLIA_RL1(dw); - subl(6) ^= kw4l; subr(6) ^= kw4r; - subl(4) ^= kw4l; subr(4) ^= kw4r; - subl(2) ^= kw4l; subr(2) ^= kw4r; - subl(0) ^= kw4l; subr(0) ^= kw4r; - - /* key XOR is end of F-function */ - CamelliaSubkeyL(0) = subl(0) ^ subl(2); - CamelliaSubkeyR(0) = subr(0) ^ subr(2); - CamelliaSubkeyL(2) = subl(3); - CamelliaSubkeyR(2) = subr(3); - CamelliaSubkeyL(3) = subl(2) ^ subl(4); - CamelliaSubkeyR(3) = subr(2) ^ subr(4); - CamelliaSubkeyL(4) = subl(3) ^ subl(5); - CamelliaSubkeyR(4) = subr(3) ^ subr(5); - CamelliaSubkeyL(5) = subl(4) ^ subl(6); - CamelliaSubkeyR(5) = subr(4) ^ subr(6); - CamelliaSubkeyL(6) = subl(5) ^ subl(7); - CamelliaSubkeyR(6) = subr(5) ^ subr(7); - tl = subl(10) ^ (subr(10) & ~subr(8)); - dw = tl & subl(8), tr = subr(10) ^ CAMELLIA_RL1(dw); - CamelliaSubkeyL(7) = subl(6) ^ tl; - CamelliaSubkeyR(7) = subr(6) ^ tr; - CamelliaSubkeyL(8) = subl(8); - CamelliaSubkeyR(8) = subr(8); - CamelliaSubkeyL(9) = subl(9); - CamelliaSubkeyR(9) = subr(9); - tl = subl(7) ^ (subr(7) & ~subr(9)); - dw = tl & subl(9), tr = subr(7) ^ CAMELLIA_RL1(dw); - CamelliaSubkeyL(10) = tl ^ subl(11); - CamelliaSubkeyR(10) = tr ^ subr(11); - CamelliaSubkeyL(11) = subl(10) ^ subl(12); - CamelliaSubkeyR(11) = subr(10) ^ subr(12); - CamelliaSubkeyL(12) = subl(11) ^ subl(13); - CamelliaSubkeyR(12) = subr(11) ^ subr(13); - CamelliaSubkeyL(13) = subl(12) ^ subl(14); - CamelliaSubkeyR(13) = subr(12) ^ subr(14); - CamelliaSubkeyL(14) = subl(13) ^ subl(15); - CamelliaSubkeyR(14) = subr(13) ^ subr(15); - tl = subl(18) ^ (subr(18) & ~subr(16)); - dw = tl & subl(16), tr = subr(18) ^ CAMELLIA_RL1(dw); - CamelliaSubkeyL(15) = subl(14) ^ tl; - CamelliaSubkeyR(15) = subr(14) ^ tr; - CamelliaSubkeyL(16) = subl(16); - CamelliaSubkeyR(16) = subr(16); - CamelliaSubkeyL(17) = subl(17); - CamelliaSubkeyR(17) = subr(17); - tl = subl(15) ^ (subr(15) & ~subr(17)); - dw = tl & subl(17), tr = subr(15) ^ CAMELLIA_RL1(dw); - CamelliaSubkeyL(18) = tl ^ subl(19); - CamelliaSubkeyR(18) = tr ^ subr(19); - CamelliaSubkeyL(19) = subl(18) ^ subl(20); - CamelliaSubkeyR(19) = subr(18) ^ subr(20); - CamelliaSubkeyL(20) = subl(19) ^ subl(21); - CamelliaSubkeyR(20) = subr(19) ^ subr(21); - CamelliaSubkeyL(21) = subl(20) ^ subl(22); - CamelliaSubkeyR(21) = subr(20) ^ subr(22); - CamelliaSubkeyL(22) = subl(21) ^ subl(23); - CamelliaSubkeyR(22) = subr(21) ^ subr(23); - CamelliaSubkeyL(23) = subl(22); - CamelliaSubkeyR(23) = subr(22); - CamelliaSubkeyL(24) = subl(24) ^ subl(23); - CamelliaSubkeyR(24) = subr(24) ^ subr(23); - - /* apply the inverse of the last half of P-function */ - dw = CamelliaSubkeyL(2) ^ CamelliaSubkeyR(2), dw = CAMELLIA_RL8(dw); - CamelliaSubkeyR(2) = CamelliaSubkeyL(2) ^ dw, CamelliaSubkeyL(2) = dw; - dw = CamelliaSubkeyL(3) ^ CamelliaSubkeyR(3), dw = CAMELLIA_RL8(dw); - CamelliaSubkeyR(3) = CamelliaSubkeyL(3) ^ dw, CamelliaSubkeyL(3) = dw; - dw = CamelliaSubkeyL(4) ^ CamelliaSubkeyR(4), dw = CAMELLIA_RL8(dw); - CamelliaSubkeyR(4) = CamelliaSubkeyL(4) ^ dw, CamelliaSubkeyL(4) = dw; - dw = CamelliaSubkeyL(5) ^ CamelliaSubkeyR(5), dw = CAMELLIA_RL8(dw); - CamelliaSubkeyR(5) = CamelliaSubkeyL(5) ^ dw, CamelliaSubkeyL(5) = dw; - dw = CamelliaSubkeyL(6) ^ CamelliaSubkeyR(6), dw = CAMELLIA_RL8(dw); - CamelliaSubkeyR(6) = CamelliaSubkeyL(6) ^ dw, CamelliaSubkeyL(6) = dw; - dw = CamelliaSubkeyL(7) ^ CamelliaSubkeyR(7), dw = CAMELLIA_RL8(dw); - CamelliaSubkeyR(7) = CamelliaSubkeyL(7) ^ dw, CamelliaSubkeyL(7) = dw; - dw = CamelliaSubkeyL(10) ^ CamelliaSubkeyR(10), dw = CAMELLIA_RL8(dw); - CamelliaSubkeyR(10) = CamelliaSubkeyL(10) ^ dw, CamelliaSubkeyL(10) = dw; - dw = CamelliaSubkeyL(11) ^ CamelliaSubkeyR(11), dw = CAMELLIA_RL8(dw); - CamelliaSubkeyR(11) = CamelliaSubkeyL(11) ^ dw, CamelliaSubkeyL(11) = dw; - dw = CamelliaSubkeyL(12) ^ CamelliaSubkeyR(12), dw = CAMELLIA_RL8(dw); - CamelliaSubkeyR(12) = CamelliaSubkeyL(12) ^ dw, CamelliaSubkeyL(12) = dw; - dw = CamelliaSubkeyL(13) ^ CamelliaSubkeyR(13), dw = CAMELLIA_RL8(dw); - CamelliaSubkeyR(13) = CamelliaSubkeyL(13) ^ dw, CamelliaSubkeyL(13) = dw; - dw = CamelliaSubkeyL(14) ^ CamelliaSubkeyR(14), dw = CAMELLIA_RL8(dw); - CamelliaSubkeyR(14) = CamelliaSubkeyL(14) ^ dw, CamelliaSubkeyL(14) = dw; - dw = CamelliaSubkeyL(15) ^ CamelliaSubkeyR(15), dw = CAMELLIA_RL8(dw); - CamelliaSubkeyR(15) = CamelliaSubkeyL(15) ^ dw, CamelliaSubkeyL(15) = dw; - dw = CamelliaSubkeyL(18) ^ CamelliaSubkeyR(18), dw = CAMELLIA_RL8(dw); - CamelliaSubkeyR(18) = CamelliaSubkeyL(18) ^ dw, CamelliaSubkeyL(18) = dw; - dw = CamelliaSubkeyL(19) ^ CamelliaSubkeyR(19), dw = CAMELLIA_RL8(dw); - CamelliaSubkeyR(19) = CamelliaSubkeyL(19) ^ dw, CamelliaSubkeyL(19) = dw; - dw = CamelliaSubkeyL(20) ^ CamelliaSubkeyR(20), dw = CAMELLIA_RL8(dw); - CamelliaSubkeyR(20) = CamelliaSubkeyL(20) ^ dw, CamelliaSubkeyL(20) = dw; - dw = CamelliaSubkeyL(21) ^ CamelliaSubkeyR(21), dw = CAMELLIA_RL8(dw); - CamelliaSubkeyR(21) = CamelliaSubkeyL(21) ^ dw, CamelliaSubkeyL(21) = dw; - dw = CamelliaSubkeyL(22) ^ CamelliaSubkeyR(22), dw = CAMELLIA_RL8(dw); - CamelliaSubkeyR(22) = CamelliaSubkeyL(22) ^ dw, CamelliaSubkeyL(22) = dw; - dw = CamelliaSubkeyL(23) ^ CamelliaSubkeyR(23), dw = CAMELLIA_RL8(dw); - CamelliaSubkeyR(23) = CamelliaSubkeyL(23) ^ dw, CamelliaSubkeyL(23) = dw; - -#ifdef CYASSL_SMALL_STACK - XFREE(subL, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(subR, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - - return 0; -} - -static int camellia_setup256(const unsigned char *key, u32 *subkey) -{ - u32 kll,klr,krl,krr; /* left half of key */ - u32 krll,krlr,krrl,krrr; /* right half of key */ - u32 il, ir, t0, t1, w0, w1; /* temporary variables */ - u32 kw4l, kw4r, dw, tl, tr; - -#ifdef CYASSL_SMALL_STACK - u32* subL; - u32* subR; - - subL = (u32*) XMALLOC(sizeof(u32) * 34, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (subL == NULL) - return MEMORY_E; - - subR = (u32*) XMALLOC(sizeof(u32) * 34, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (subR == NULL) { - XFREE(subL, NULL, DYNAMIC_TYPE_TMP_BUFFER); - return MEMORY_E; - } -#else - u32 subL[34]; - u32 subR[34]; -#endif - - /** - * key = (kll || klr || krl || krr || krll || krlr || krrl || krrr) - * (|| is concatination) - */ - - kll = GETU32(key ); - klr = GETU32(key + 4); - krl = GETU32(key + 8); - krr = GETU32(key + 12); - krll = GETU32(key + 16); - krlr = GETU32(key + 20); - krrl = GETU32(key + 24); - krrr = GETU32(key + 28); - - /* generate KL dependent subkeys */ - subl(0) = kll; subr(0) = klr; - subl(1) = krl; subr(1) = krr; - CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 45); - subl(12) = kll; subr(12) = klr; - subl(13) = krl; subr(13) = krr; - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); - subl(16) = kll; subr(16) = klr; - subl(17) = krl; subr(17) = krr; - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17); - subl(22) = kll; subr(22) = klr; - subl(23) = krl; subr(23) = krr; - CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34); - subl(30) = kll; subr(30) = klr; - subl(31) = krl; subr(31) = krr; - - /* generate KR dependent subkeys */ - CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15); - subl(4) = krll; subr(4) = krlr; - subl(5) = krrl; subr(5) = krrr; - CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15); - subl(8) = krll; subr(8) = krlr; - subl(9) = krrl; subr(9) = krrr; - CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30); - subl(18) = krll; subr(18) = krlr; - subl(19) = krrl; subr(19) = krrr; - CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34); - subl(26) = krll; subr(26) = krlr; - subl(27) = krrl; subr(27) = krrr; - CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34); - - /* generate KA */ - kll = subl(0) ^ krll; klr = subr(0) ^ krlr; - krl = subl(1) ^ krrl; krr = subr(1) ^ krrr; - CAMELLIA_F(kll, klr, - CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R, - w0, w1, il, ir, t0, t1); - krl ^= w0; krr ^= w1; - CAMELLIA_F(krl, krr, - CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R, - kll, klr, il, ir, t0, t1); - kll ^= krll; klr ^= krlr; - CAMELLIA_F(kll, klr, - CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R, - krl, krr, il, ir, t0, t1); - krl ^= w0 ^ krrl; krr ^= w1 ^ krrr; - CAMELLIA_F(krl, krr, - CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R, - w0, w1, il, ir, t0, t1); - kll ^= w0; klr ^= w1; - - /* generate KB */ - krll ^= kll; krlr ^= klr; - krrl ^= krl; krrr ^= krr; - CAMELLIA_F(krll, krlr, - CAMELLIA_SIGMA5L, CAMELLIA_SIGMA5R, - w0, w1, il, ir, t0, t1); - krrl ^= w0; krrr ^= w1; - CAMELLIA_F(krrl, krrr, - CAMELLIA_SIGMA6L, CAMELLIA_SIGMA6R, - w0, w1, il, ir, t0, t1); - krll ^= w0; krlr ^= w1; - - /* generate KA dependent subkeys */ - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); - subl(6) = kll; subr(6) = klr; - subl(7) = krl; subr(7) = krr; - CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30); - subl(14) = kll; subr(14) = klr; - subl(15) = krl; subr(15) = krr; - subl(24) = klr; subr(24) = krl; - subl(25) = krr; subr(25) = kll; - CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 49); - subl(28) = kll; subr(28) = klr; - subl(29) = krl; subr(29) = krr; - - /* generate KB dependent subkeys */ - subl(2) = krll; subr(2) = krlr; - subl(3) = krrl; subr(3) = krrr; - CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30); - subl(10) = krll; subr(10) = krlr; - subl(11) = krrl; subr(11) = krrr; - CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30); - subl(20) = krll; subr(20) = krlr; - subl(21) = krrl; subr(21) = krrr; - CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 51); - subl(32) = krll; subr(32) = krlr; - subl(33) = krrl; subr(33) = krrr; - - /* absorb kw2 to other subkeys */ - subl(3) ^= subl(1); subr(3) ^= subr(1); - subl(5) ^= subl(1); subr(5) ^= subr(1); - subl(7) ^= subl(1); subr(7) ^= subr(1); - subl(1) ^= subr(1) & ~subr(9); - dw = subl(1) & subl(9), subr(1) ^= CAMELLIA_RL1(dw); - subl(11) ^= subl(1); subr(11) ^= subr(1); - subl(13) ^= subl(1); subr(13) ^= subr(1); - subl(15) ^= subl(1); subr(15) ^= subr(1); - subl(1) ^= subr(1) & ~subr(17); - dw = subl(1) & subl(17), subr(1) ^= CAMELLIA_RL1(dw); - subl(19) ^= subl(1); subr(19) ^= subr(1); - subl(21) ^= subl(1); subr(21) ^= subr(1); - subl(23) ^= subl(1); subr(23) ^= subr(1); - subl(1) ^= subr(1) & ~subr(25); - dw = subl(1) & subl(25), subr(1) ^= CAMELLIA_RL1(dw); - subl(27) ^= subl(1); subr(27) ^= subr(1); - subl(29) ^= subl(1); subr(29) ^= subr(1); - subl(31) ^= subl(1); subr(31) ^= subr(1); - subl(32) ^= subl(1); subr(32) ^= subr(1); - - /* absorb kw4 to other subkeys */ - kw4l = subl(33); kw4r = subr(33); - subl(30) ^= kw4l; subr(30) ^= kw4r; - subl(28) ^= kw4l; subr(28) ^= kw4r; - subl(26) ^= kw4l; subr(26) ^= kw4r; - kw4l ^= kw4r & ~subr(24); - dw = kw4l & subl(24), kw4r ^= CAMELLIA_RL1(dw); - subl(22) ^= kw4l; subr(22) ^= kw4r; - subl(20) ^= kw4l; subr(20) ^= kw4r; - subl(18) ^= kw4l; subr(18) ^= kw4r; - kw4l ^= kw4r & ~subr(16); - dw = kw4l & subl(16), kw4r ^= CAMELLIA_RL1(dw); - subl(14) ^= kw4l; subr(14) ^= kw4r; - subl(12) ^= kw4l; subr(12) ^= kw4r; - subl(10) ^= kw4l; subr(10) ^= kw4r; - kw4l ^= kw4r & ~subr(8); - dw = kw4l & subl(8), kw4r ^= CAMELLIA_RL1(dw); - subl(6) ^= kw4l; subr(6) ^= kw4r; - subl(4) ^= kw4l; subr(4) ^= kw4r; - subl(2) ^= kw4l; subr(2) ^= kw4r; - subl(0) ^= kw4l; subr(0) ^= kw4r; - - /* key XOR is end of F-function */ - CamelliaSubkeyL(0) = subl(0) ^ subl(2); - CamelliaSubkeyR(0) = subr(0) ^ subr(2); - CamelliaSubkeyL(2) = subl(3); - CamelliaSubkeyR(2) = subr(3); - CamelliaSubkeyL(3) = subl(2) ^ subl(4); - CamelliaSubkeyR(3) = subr(2) ^ subr(4); - CamelliaSubkeyL(4) = subl(3) ^ subl(5); - CamelliaSubkeyR(4) = subr(3) ^ subr(5); - CamelliaSubkeyL(5) = subl(4) ^ subl(6); - CamelliaSubkeyR(5) = subr(4) ^ subr(6); - CamelliaSubkeyL(6) = subl(5) ^ subl(7); - CamelliaSubkeyR(6) = subr(5) ^ subr(7); - tl = subl(10) ^ (subr(10) & ~subr(8)); - dw = tl & subl(8), tr = subr(10) ^ CAMELLIA_RL1(dw); - CamelliaSubkeyL(7) = subl(6) ^ tl; - CamelliaSubkeyR(7) = subr(6) ^ tr; - CamelliaSubkeyL(8) = subl(8); - CamelliaSubkeyR(8) = subr(8); - CamelliaSubkeyL(9) = subl(9); - CamelliaSubkeyR(9) = subr(9); - tl = subl(7) ^ (subr(7) & ~subr(9)); - dw = tl & subl(9), tr = subr(7) ^ CAMELLIA_RL1(dw); - CamelliaSubkeyL(10) = tl ^ subl(11); - CamelliaSubkeyR(10) = tr ^ subr(11); - CamelliaSubkeyL(11) = subl(10) ^ subl(12); - CamelliaSubkeyR(11) = subr(10) ^ subr(12); - CamelliaSubkeyL(12) = subl(11) ^ subl(13); - CamelliaSubkeyR(12) = subr(11) ^ subr(13); - CamelliaSubkeyL(13) = subl(12) ^ subl(14); - CamelliaSubkeyR(13) = subr(12) ^ subr(14); - CamelliaSubkeyL(14) = subl(13) ^ subl(15); - CamelliaSubkeyR(14) = subr(13) ^ subr(15); - tl = subl(18) ^ (subr(18) & ~subr(16)); - dw = tl & subl(16), tr = subr(18) ^ CAMELLIA_RL1(dw); - CamelliaSubkeyL(15) = subl(14) ^ tl; - CamelliaSubkeyR(15) = subr(14) ^ tr; - CamelliaSubkeyL(16) = subl(16); - CamelliaSubkeyR(16) = subr(16); - CamelliaSubkeyL(17) = subl(17); - CamelliaSubkeyR(17) = subr(17); - tl = subl(15) ^ (subr(15) & ~subr(17)); - dw = tl & subl(17), tr = subr(15) ^ CAMELLIA_RL1(dw); - CamelliaSubkeyL(18) = tl ^ subl(19); - CamelliaSubkeyR(18) = tr ^ subr(19); - CamelliaSubkeyL(19) = subl(18) ^ subl(20); - CamelliaSubkeyR(19) = subr(18) ^ subr(20); - CamelliaSubkeyL(20) = subl(19) ^ subl(21); - CamelliaSubkeyR(20) = subr(19) ^ subr(21); - CamelliaSubkeyL(21) = subl(20) ^ subl(22); - CamelliaSubkeyR(21) = subr(20) ^ subr(22); - CamelliaSubkeyL(22) = subl(21) ^ subl(23); - CamelliaSubkeyR(22) = subr(21) ^ subr(23); - tl = subl(26) ^ (subr(26) & ~subr(24)); - dw = tl & subl(24), tr = subr(26) ^ CAMELLIA_RL1(dw); - CamelliaSubkeyL(23) = subl(22) ^ tl; - CamelliaSubkeyR(23) = subr(22) ^ tr; - CamelliaSubkeyL(24) = subl(24); - CamelliaSubkeyR(24) = subr(24); - CamelliaSubkeyL(25) = subl(25); - CamelliaSubkeyR(25) = subr(25); - tl = subl(23) ^ (subr(23) & ~subr(25)); - dw = tl & subl(25), tr = subr(23) ^ CAMELLIA_RL1(dw); - CamelliaSubkeyL(26) = tl ^ subl(27); - CamelliaSubkeyR(26) = tr ^ subr(27); - CamelliaSubkeyL(27) = subl(26) ^ subl(28); - CamelliaSubkeyR(27) = subr(26) ^ subr(28); - CamelliaSubkeyL(28) = subl(27) ^ subl(29); - CamelliaSubkeyR(28) = subr(27) ^ subr(29); - CamelliaSubkeyL(29) = subl(28) ^ subl(30); - CamelliaSubkeyR(29) = subr(28) ^ subr(30); - CamelliaSubkeyL(30) = subl(29) ^ subl(31); - CamelliaSubkeyR(30) = subr(29) ^ subr(31); - CamelliaSubkeyL(31) = subl(30); - CamelliaSubkeyR(31) = subr(30); - CamelliaSubkeyL(32) = subl(32) ^ subl(31); - CamelliaSubkeyR(32) = subr(32) ^ subr(31); - - /* apply the inverse of the last half of P-function */ - dw = CamelliaSubkeyL(2) ^ CamelliaSubkeyR(2), dw = CAMELLIA_RL8(dw); - CamelliaSubkeyR(2) = CamelliaSubkeyL(2) ^ dw, CamelliaSubkeyL(2) = dw; - dw = CamelliaSubkeyL(3) ^ CamelliaSubkeyR(3), dw = CAMELLIA_RL8(dw); - CamelliaSubkeyR(3) = CamelliaSubkeyL(3) ^ dw, CamelliaSubkeyL(3) = dw; - dw = CamelliaSubkeyL(4) ^ CamelliaSubkeyR(4), dw = CAMELLIA_RL8(dw); - CamelliaSubkeyR(4) = CamelliaSubkeyL(4) ^ dw, CamelliaSubkeyL(4) = dw; - dw = CamelliaSubkeyL(5) ^ CamelliaSubkeyR(5), dw = CAMELLIA_RL8(dw); - CamelliaSubkeyR(5) = CamelliaSubkeyL(5) ^ dw, CamelliaSubkeyL(5) = dw; - dw = CamelliaSubkeyL(6) ^ CamelliaSubkeyR(6), dw = CAMELLIA_RL8(dw); - CamelliaSubkeyR(6) = CamelliaSubkeyL(6) ^ dw, CamelliaSubkeyL(6) = dw; - dw = CamelliaSubkeyL(7) ^ CamelliaSubkeyR(7), dw = CAMELLIA_RL8(dw); - CamelliaSubkeyR(7) = CamelliaSubkeyL(7) ^ dw, CamelliaSubkeyL(7) = dw; - dw = CamelliaSubkeyL(10) ^ CamelliaSubkeyR(10), dw = CAMELLIA_RL8(dw); - CamelliaSubkeyR(10) = CamelliaSubkeyL(10) ^ dw, CamelliaSubkeyL(10) = dw; - dw = CamelliaSubkeyL(11) ^ CamelliaSubkeyR(11), dw = CAMELLIA_RL8(dw); - CamelliaSubkeyR(11) = CamelliaSubkeyL(11) ^ dw, CamelliaSubkeyL(11) = dw; - dw = CamelliaSubkeyL(12) ^ CamelliaSubkeyR(12), dw = CAMELLIA_RL8(dw); - CamelliaSubkeyR(12) = CamelliaSubkeyL(12) ^ dw, CamelliaSubkeyL(12) = dw; - dw = CamelliaSubkeyL(13) ^ CamelliaSubkeyR(13), dw = CAMELLIA_RL8(dw); - CamelliaSubkeyR(13) = CamelliaSubkeyL(13) ^ dw, CamelliaSubkeyL(13) = dw; - dw = CamelliaSubkeyL(14) ^ CamelliaSubkeyR(14), dw = CAMELLIA_RL8(dw); - CamelliaSubkeyR(14) = CamelliaSubkeyL(14) ^ dw, CamelliaSubkeyL(14) = dw; - dw = CamelliaSubkeyL(15) ^ CamelliaSubkeyR(15), dw = CAMELLIA_RL8(dw); - CamelliaSubkeyR(15) = CamelliaSubkeyL(15) ^ dw, CamelliaSubkeyL(15) = dw; - dw = CamelliaSubkeyL(18) ^ CamelliaSubkeyR(18), dw = CAMELLIA_RL8(dw); - CamelliaSubkeyR(18) = CamelliaSubkeyL(18) ^ dw, CamelliaSubkeyL(18) = dw; - dw = CamelliaSubkeyL(19) ^ CamelliaSubkeyR(19), dw = CAMELLIA_RL8(dw); - CamelliaSubkeyR(19) = CamelliaSubkeyL(19) ^ dw, CamelliaSubkeyL(19) = dw; - dw = CamelliaSubkeyL(20) ^ CamelliaSubkeyR(20), dw = CAMELLIA_RL8(dw); - CamelliaSubkeyR(20) = CamelliaSubkeyL(20) ^ dw, CamelliaSubkeyL(20) = dw; - dw = CamelliaSubkeyL(21) ^ CamelliaSubkeyR(21), dw = CAMELLIA_RL8(dw); - CamelliaSubkeyR(21) = CamelliaSubkeyL(21) ^ dw, CamelliaSubkeyL(21) = dw; - dw = CamelliaSubkeyL(22) ^ CamelliaSubkeyR(22), dw = CAMELLIA_RL8(dw); - CamelliaSubkeyR(22) = CamelliaSubkeyL(22) ^ dw, CamelliaSubkeyL(22) = dw; - dw = CamelliaSubkeyL(23) ^ CamelliaSubkeyR(23), dw = CAMELLIA_RL8(dw); - CamelliaSubkeyR(23) = CamelliaSubkeyL(23) ^ dw, CamelliaSubkeyL(23) = dw; - dw = CamelliaSubkeyL(26) ^ CamelliaSubkeyR(26), dw = CAMELLIA_RL8(dw); - CamelliaSubkeyR(26) = CamelliaSubkeyL(26) ^ dw, CamelliaSubkeyL(26) = dw; - dw = CamelliaSubkeyL(27) ^ CamelliaSubkeyR(27), dw = CAMELLIA_RL8(dw); - CamelliaSubkeyR(27) = CamelliaSubkeyL(27) ^ dw, CamelliaSubkeyL(27) = dw; - dw = CamelliaSubkeyL(28) ^ CamelliaSubkeyR(28), dw = CAMELLIA_RL8(dw); - CamelliaSubkeyR(28) = CamelliaSubkeyL(28) ^ dw, CamelliaSubkeyL(28) = dw; - dw = CamelliaSubkeyL(29) ^ CamelliaSubkeyR(29), dw = CAMELLIA_RL8(dw); - CamelliaSubkeyR(29) = CamelliaSubkeyL(29) ^ dw, CamelliaSubkeyL(29) = dw; - dw = CamelliaSubkeyL(30) ^ CamelliaSubkeyR(30), dw = CAMELLIA_RL8(dw); - CamelliaSubkeyR(30) = CamelliaSubkeyL(30) ^ dw, CamelliaSubkeyL(30) = dw; - dw = CamelliaSubkeyL(31) ^ CamelliaSubkeyR(31), dw = CAMELLIA_RL8(dw); - CamelliaSubkeyR(31) = CamelliaSubkeyL(31) ^ dw,CamelliaSubkeyL(31) = dw; - -#ifdef CYASSL_SMALL_STACK - XFREE(subL, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(subR, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - - return 0; -} - -static int camellia_setup192(const unsigned char *key, u32 *subkey) -{ - unsigned char kk[32]; - u32 krll, krlr, krrl,krrr; - - memcpy(kk, key, 24); - memcpy((unsigned char *)&krll, key+16,4); - memcpy((unsigned char *)&krlr, key+20,4); - krrl = ~krll; - krrr = ~krlr; - memcpy(kk+24, (unsigned char *)&krrl, 4); - memcpy(kk+28, (unsigned char *)&krrr, 4); - - return camellia_setup256(kk, subkey); -} - - -/** - * Stuff related to camellia encryption/decryption - * - * "io" must be 4byte aligned and big-endian data. - */ -static void camellia_encrypt128(const u32 *subkey, u32 *io) -{ - u32 il, ir, t0, t1; - - /* pre whitening but absorb kw2*/ - io[0] ^= CamelliaSubkeyL(0); - io[1] ^= CamelliaSubkeyR(0); - /* main iteration */ - - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(2),CamelliaSubkeyR(2), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(3),CamelliaSubkeyR(3), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(4),CamelliaSubkeyR(4), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(5),CamelliaSubkeyR(5), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(6),CamelliaSubkeyR(6), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(7),CamelliaSubkeyR(7), - io[0],io[1],il,ir,t0,t1); - - CAMELLIA_FLS(io[0],io[1],io[2],io[3], - CamelliaSubkeyL(8),CamelliaSubkeyR(8), - CamelliaSubkeyL(9),CamelliaSubkeyR(9), - t0,t1,il,ir); - - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(10),CamelliaSubkeyR(10), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(11),CamelliaSubkeyR(11), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(12),CamelliaSubkeyR(12), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(13),CamelliaSubkeyR(13), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(14),CamelliaSubkeyR(14), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(15),CamelliaSubkeyR(15), - io[0],io[1],il,ir,t0,t1); - - CAMELLIA_FLS(io[0],io[1],io[2],io[3], - CamelliaSubkeyL(16),CamelliaSubkeyR(16), - CamelliaSubkeyL(17),CamelliaSubkeyR(17), - t0,t1,il,ir); - - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(18),CamelliaSubkeyR(18), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(19),CamelliaSubkeyR(19), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(20),CamelliaSubkeyR(20), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(21),CamelliaSubkeyR(21), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(22),CamelliaSubkeyR(22), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(23),CamelliaSubkeyR(23), - io[0],io[1],il,ir,t0,t1); - - /* post whitening but kw4 */ - io[2] ^= CamelliaSubkeyL(24); - io[3] ^= CamelliaSubkeyR(24); - - t0 = io[0]; - t1 = io[1]; - io[0] = io[2]; - io[1] = io[3]; - io[2] = t0; - io[3] = t1; - - return; -} - -static void camellia_decrypt128(const u32 *subkey, u32 *io) -{ - u32 il,ir,t0,t1; /* temporary valiables */ - - /* pre whitening but absorb kw2*/ - io[0] ^= CamelliaSubkeyL(24); - io[1] ^= CamelliaSubkeyR(24); - - /* main iteration */ - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(23),CamelliaSubkeyR(23), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(22),CamelliaSubkeyR(22), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(21),CamelliaSubkeyR(21), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(20),CamelliaSubkeyR(20), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(19),CamelliaSubkeyR(19), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(18),CamelliaSubkeyR(18), - io[0],io[1],il,ir,t0,t1); - - CAMELLIA_FLS(io[0],io[1],io[2],io[3], - CamelliaSubkeyL(17),CamelliaSubkeyR(17), - CamelliaSubkeyL(16),CamelliaSubkeyR(16), - t0,t1,il,ir); - - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(15),CamelliaSubkeyR(15), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(14),CamelliaSubkeyR(14), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(13),CamelliaSubkeyR(13), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(12),CamelliaSubkeyR(12), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(11),CamelliaSubkeyR(11), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(10),CamelliaSubkeyR(10), - io[0],io[1],il,ir,t0,t1); - - CAMELLIA_FLS(io[0],io[1],io[2],io[3], - CamelliaSubkeyL(9),CamelliaSubkeyR(9), - CamelliaSubkeyL(8),CamelliaSubkeyR(8), - t0,t1,il,ir); - - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(7),CamelliaSubkeyR(7), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(6),CamelliaSubkeyR(6), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(5),CamelliaSubkeyR(5), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(4),CamelliaSubkeyR(4), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(3),CamelliaSubkeyR(3), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(2),CamelliaSubkeyR(2), - io[0],io[1],il,ir,t0,t1); - - /* post whitening but kw4 */ - io[2] ^= CamelliaSubkeyL(0); - io[3] ^= CamelliaSubkeyR(0); - - t0 = io[0]; - t1 = io[1]; - io[0] = io[2]; - io[1] = io[3]; - io[2] = t0; - io[3] = t1; - - return; -} - -/** - * stuff for 192 and 256bit encryption/decryption - */ -static void camellia_encrypt256(const u32 *subkey, u32 *io) -{ - u32 il,ir,t0,t1; /* temporary valiables */ - - /* pre whitening but absorb kw2*/ - io[0] ^= CamelliaSubkeyL(0); - io[1] ^= CamelliaSubkeyR(0); - - /* main iteration */ - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(2),CamelliaSubkeyR(2), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(3),CamelliaSubkeyR(3), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(4),CamelliaSubkeyR(4), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(5),CamelliaSubkeyR(5), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(6),CamelliaSubkeyR(6), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(7),CamelliaSubkeyR(7), - io[0],io[1],il,ir,t0,t1); - - CAMELLIA_FLS(io[0],io[1],io[2],io[3], - CamelliaSubkeyL(8),CamelliaSubkeyR(8), - CamelliaSubkeyL(9),CamelliaSubkeyR(9), - t0,t1,il,ir); - - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(10),CamelliaSubkeyR(10), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(11),CamelliaSubkeyR(11), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(12),CamelliaSubkeyR(12), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(13),CamelliaSubkeyR(13), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(14),CamelliaSubkeyR(14), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(15),CamelliaSubkeyR(15), - io[0],io[1],il,ir,t0,t1); - - CAMELLIA_FLS(io[0],io[1],io[2],io[3], - CamelliaSubkeyL(16),CamelliaSubkeyR(16), - CamelliaSubkeyL(17),CamelliaSubkeyR(17), - t0,t1,il,ir); - - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(18),CamelliaSubkeyR(18), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(19),CamelliaSubkeyR(19), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(20),CamelliaSubkeyR(20), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(21),CamelliaSubkeyR(21), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(22),CamelliaSubkeyR(22), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(23),CamelliaSubkeyR(23), - io[0],io[1],il,ir,t0,t1); - - CAMELLIA_FLS(io[0],io[1],io[2],io[3], - CamelliaSubkeyL(24),CamelliaSubkeyR(24), - CamelliaSubkeyL(25),CamelliaSubkeyR(25), - t0,t1,il,ir); - - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(26),CamelliaSubkeyR(26), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(27),CamelliaSubkeyR(27), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(28),CamelliaSubkeyR(28), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(29),CamelliaSubkeyR(29), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(30),CamelliaSubkeyR(30), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(31),CamelliaSubkeyR(31), - io[0],io[1],il,ir,t0,t1); - - /* post whitening but kw4 */ - io[2] ^= CamelliaSubkeyL(32); - io[3] ^= CamelliaSubkeyR(32); - - t0 = io[0]; - t1 = io[1]; - io[0] = io[2]; - io[1] = io[3]; - io[2] = t0; - io[3] = t1; - - return; -} - -static void camellia_decrypt256(const u32 *subkey, u32 *io) -{ - u32 il,ir,t0,t1; /* temporary valiables */ - - /* pre whitening but absorb kw2*/ - io[0] ^= CamelliaSubkeyL(32); - io[1] ^= CamelliaSubkeyR(32); - - /* main iteration */ - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(31),CamelliaSubkeyR(31), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(30),CamelliaSubkeyR(30), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(29),CamelliaSubkeyR(29), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(28),CamelliaSubkeyR(28), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(27),CamelliaSubkeyR(27), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(26),CamelliaSubkeyR(26), - io[0],io[1],il,ir,t0,t1); - - CAMELLIA_FLS(io[0],io[1],io[2],io[3], - CamelliaSubkeyL(25),CamelliaSubkeyR(25), - CamelliaSubkeyL(24),CamelliaSubkeyR(24), - t0,t1,il,ir); - - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(23),CamelliaSubkeyR(23), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(22),CamelliaSubkeyR(22), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(21),CamelliaSubkeyR(21), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(20),CamelliaSubkeyR(20), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(19),CamelliaSubkeyR(19), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(18),CamelliaSubkeyR(18), - io[0],io[1],il,ir,t0,t1); - - CAMELLIA_FLS(io[0],io[1],io[2],io[3], - CamelliaSubkeyL(17),CamelliaSubkeyR(17), - CamelliaSubkeyL(16),CamelliaSubkeyR(16), - t0,t1,il,ir); - - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(15),CamelliaSubkeyR(15), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(14),CamelliaSubkeyR(14), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(13),CamelliaSubkeyR(13), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(12),CamelliaSubkeyR(12), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(11),CamelliaSubkeyR(11), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(10),CamelliaSubkeyR(10), - io[0],io[1],il,ir,t0,t1); - - CAMELLIA_FLS(io[0],io[1],io[2],io[3], - CamelliaSubkeyL(9),CamelliaSubkeyR(9), - CamelliaSubkeyL(8),CamelliaSubkeyR(8), - t0,t1,il,ir); - - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(7),CamelliaSubkeyR(7), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(6),CamelliaSubkeyR(6), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(5),CamelliaSubkeyR(5), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(4),CamelliaSubkeyR(4), - io[0],io[1],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[0],io[1], - CamelliaSubkeyL(3),CamelliaSubkeyR(3), - io[2],io[3],il,ir,t0,t1); - CAMELLIA_ROUNDSM(io[2],io[3], - CamelliaSubkeyL(2),CamelliaSubkeyR(2), - io[0],io[1],il,ir,t0,t1); - - /* post whitening but kw4 */ - io[2] ^= CamelliaSubkeyL(0); - io[3] ^= CamelliaSubkeyR(0); - - t0 = io[0]; - t1 = io[1]; - io[0] = io[2]; - io[1] = io[3]; - io[2] = t0; - io[3] = t1; - - return; -} - -/*** - * - * API for compatibility - */ - -static void Camellia_EncryptBlock(const int keyBitLength, - const unsigned char *plaintext, - const KEY_TABLE_TYPE keyTable, - unsigned char *ciphertext) -{ - u32 tmp[4]; - - tmp[0] = GETU32(plaintext); - tmp[1] = GETU32(plaintext + 4); - tmp[2] = GETU32(plaintext + 8); - tmp[3] = GETU32(plaintext + 12); - - switch (keyBitLength) { - case 128: - camellia_encrypt128(keyTable, tmp); - break; - case 192: - /* fall through */ - case 256: - camellia_encrypt256(keyTable, tmp); - break; - default: - break; - } - - PUTU32(ciphertext, tmp[0]); - PUTU32(ciphertext + 4, tmp[1]); - PUTU32(ciphertext + 8, tmp[2]); - PUTU32(ciphertext + 12, tmp[3]); -} - -static void Camellia_DecryptBlock(const int keyBitLength, - const unsigned char *ciphertext, - const KEY_TABLE_TYPE keyTable, - unsigned char *plaintext) -{ - u32 tmp[4]; - - tmp[0] = GETU32(ciphertext); - tmp[1] = GETU32(ciphertext + 4); - tmp[2] = GETU32(ciphertext + 8); - tmp[3] = GETU32(ciphertext + 12); - - switch (keyBitLength) { - case 128: - camellia_decrypt128(keyTable, tmp); - break; - case 192: - /* fall through */ - case 256: - camellia_decrypt256(keyTable, tmp); - break; - default: - break; - } - PUTU32(plaintext, tmp[0]); - PUTU32(plaintext + 4, tmp[1]); - PUTU32(plaintext + 8, tmp[2]); - PUTU32(plaintext + 12, tmp[3]); -} - - - -/* CTaoCrypt wrappers to the Camellia code */ - -int CamelliaSetKey(Camellia* cam, const byte* key, word32 len, const byte* iv) -{ - int ret = 0; - - if (cam == NULL) return BAD_FUNC_ARG; - - XMEMSET(cam->key, 0, sizeof(KEY_TABLE_TYPE)); - - switch (len) { - case 16: - ret = camellia_setup128(key, cam->key); - break; - case 24: - ret = camellia_setup192(key, cam->key); - break; - case 32: - ret = camellia_setup256(key, cam->key); - break; - default: - return BAD_FUNC_ARG; - } - - if (ret != 0) - return ret; - - cam->keySz = len * 8; - - return CamelliaSetIV(cam, iv); -} - - -int CamelliaSetIV(Camellia* cam, const byte* iv) -{ - if (cam == NULL) - return BAD_FUNC_ARG; - - if (iv) - XMEMCPY(cam->reg, iv, CAMELLIA_BLOCK_SIZE); - else - XMEMSET(cam->reg, 0, CAMELLIA_BLOCK_SIZE); - - return 0; -} - - -void CamelliaEncryptDirect(Camellia* cam, byte* out, const byte* in) -{ - Camellia_EncryptBlock(cam->keySz, in, cam->key, out); -} - - -void CamelliaDecryptDirect(Camellia* cam, byte* out, const byte* in) -{ - Camellia_DecryptBlock(cam->keySz, in, cam->key, out); -} - - -void CamelliaCbcEncrypt(Camellia* cam, byte* out, const byte* in, word32 sz) -{ - word32 blocks = sz / CAMELLIA_BLOCK_SIZE; - - while (blocks--) { - xorbuf((byte*)cam->reg, in, CAMELLIA_BLOCK_SIZE); - Camellia_EncryptBlock(cam->keySz, (byte*)cam->reg, - cam->key, (byte*)cam->reg); - XMEMCPY(out, cam->reg, CAMELLIA_BLOCK_SIZE); - - out += CAMELLIA_BLOCK_SIZE; - in += CAMELLIA_BLOCK_SIZE; - } -} - - -void CamelliaCbcDecrypt(Camellia* cam, byte* out, const byte* in, word32 sz) -{ - word32 blocks = sz / CAMELLIA_BLOCK_SIZE; - - while (blocks--) { - XMEMCPY(cam->tmp, in, CAMELLIA_BLOCK_SIZE); - Camellia_DecryptBlock(cam->keySz, (byte*)cam->tmp, cam->key, out); - xorbuf(out, (byte*)cam->reg, CAMELLIA_BLOCK_SIZE); - XMEMCPY(cam->reg, cam->tmp, CAMELLIA_BLOCK_SIZE); - - out += CAMELLIA_BLOCK_SIZE; - in += CAMELLIA_BLOCK_SIZE; - } -} - - -#endif /* HAVE_CAMELLIA */ - diff --git a/ctaocrypt/src/chacha.c b/ctaocrypt/src/chacha.c deleted file mode 100644 index 42e094f5c..000000000 --- a/ctaocrypt/src/chacha.c +++ /dev/null @@ -1,250 +0,0 @@ -/* chacha.c - * - * Copyright (C) 2006-2014 wolfSSL Inc. - * - * This file is part of wolfSSL. (formerly known as CyaSSL) - * - * wolfSSL is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * wolfSSL is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - * - * based from - * chacha-ref.c version 20080118 - * D. J. Bernstein - * Public domain. - */ - - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include - -#ifdef HAVE_CHACHA - -#include -#include -#include -#ifdef NO_INLINE - #include -#else - #include -#endif - -#ifdef CHACHA_AEAD_TEST - #include -#endif - -#ifdef BIG_ENDIAN_ORDER - #define LITTLE32(x) ByteReverseWord32(x) -#else - #define LITTLE32(x) (x) -#endif - -/* Number of rounds */ -#define ROUNDS 20 - -#define U32C(v) (v##U) -#define U32V(v) ((word32)(v) & U32C(0xFFFFFFFF)) -#define U8TO32_LITTLE(p) LITTLE32(((word32*)(p))[0]) - -#define ROTATE(v,c) rotlFixed(v, c) -#define XOR(v,w) ((v) ^ (w)) -#define PLUS(v,w) (U32V((v) + (w))) -#define PLUSONE(v) (PLUS((v),1)) - -#define QUARTERROUND(a,b,c,d) \ - x[a] = PLUS(x[a],x[b]); x[d] = ROTATE(XOR(x[d],x[a]),16); \ - x[c] = PLUS(x[c],x[d]); x[b] = ROTATE(XOR(x[b],x[c]),12); \ - x[a] = PLUS(x[a],x[b]); x[d] = ROTATE(XOR(x[d],x[a]), 8); \ - x[c] = PLUS(x[c],x[d]); x[b] = ROTATE(XOR(x[b],x[c]), 7); - - -/** - * Set up iv(nonce). Earlier versions used 64 bits instead of 96, this version - * uses the typical AEAD 96 bit nonce and can do record sizes of 256 GB. - */ -int Chacha_SetIV(ChaCha* ctx, const byte* inIv, word32 counter) -{ - word32 temp[3]; /* used for alignment of memory */ - XMEMSET(temp, 0, 12); - - if (ctx == NULL) - return BAD_FUNC_ARG; - -#ifdef CHACHA_AEAD_TEST - word32 i; - printf("NONCE : "); - for (i = 0; i < 12; i++) { - printf("%02x", inIv[i]); - } - printf("\n\n"); -#endif - - XMEMCPY(temp, inIv, 12); - - ctx->X[12] = counter; /* block counter */ - ctx->X[13] = temp[0]; /* fixed variable from nonce */ - ctx->X[14] = temp[1]; /* counter from nonce */ - ctx->X[15] = temp[2]; /* counter from nonce */ - - return 0; -} - -/* "expand 32-byte k" as unsigned 32 byte */ -static const word32 sigma[4] = {0x61707865, 0x3320646e, 0x79622d32, 0x6b206574}; -/* "expand 16-byte k" as unsigned 16 byte */ -static const word32 tau[4] = {0x61707865, 0x3120646e, 0x79622d36, 0x6b206574}; - -/** - * Key setup. 8 word iv (nonce) - */ -int Chacha_SetKey(ChaCha* ctx, const byte* key, word32 keySz) -{ - const word32* constants; - const byte* k; - - if (ctx == NULL) - return BAD_FUNC_ARG; - -#ifdef XSTREAM_ALIGN - word32 alignKey[keySz / 4]; - if ((cyassl_word)key % 4) { - CYASSL_MSG("ChachaSetKey unaligned key"); - XMEMCPY(alignKey, key, sizeof(alignKey)); - k = (byte*)alignKey; - } - else { - k = key; - } -#else - k = key; -#endif /* XSTREAM_ALIGN */ - -#ifdef CHACHA_AEAD_TEST - word32 i; - printf("ChaCha key used :\n"); - for (i = 0; i < keySz; i++) { - printf("%02x", key[i]); - if ((i + 1) % 8 == 0) - printf("\n"); - } - printf("\n\n"); -#endif - - ctx->X[4] = U8TO32_LITTLE(k + 0); - ctx->X[5] = U8TO32_LITTLE(k + 4); - ctx->X[6] = U8TO32_LITTLE(k + 8); - ctx->X[7] = U8TO32_LITTLE(k + 12); - if (keySz == 32) { - k += 16; - constants = sigma; - } - else { - /* key size of 128 */ - if (keySz != 16) - return BAD_FUNC_ARG; - - constants = tau; - } - ctx->X[ 8] = U8TO32_LITTLE(k + 0); - ctx->X[ 9] = U8TO32_LITTLE(k + 4); - ctx->X[10] = U8TO32_LITTLE(k + 8); - ctx->X[11] = U8TO32_LITTLE(k + 12); - ctx->X[ 0] = U8TO32_LITTLE(constants + 0); - ctx->X[ 1] = U8TO32_LITTLE(constants + 1); - ctx->X[ 2] = U8TO32_LITTLE(constants + 2); - ctx->X[ 3] = U8TO32_LITTLE(constants + 3); - - return 0; -} - -/** - * Converts word into bytes with rotations having been done. - */ -static INLINE void Chacha_wordtobyte(word32 output[16], const word32 input[16]) -{ - word32 x[16]; - word32 i; - - for (i = 0; i < 16; i++) { - x[i] = input[i]; - } - - for (i = (ROUNDS); i > 0; i -= 2) { - QUARTERROUND(0, 4, 8, 12) - QUARTERROUND(1, 5, 9, 13) - QUARTERROUND(2, 6, 10, 14) - QUARTERROUND(3, 7, 11, 15) - QUARTERROUND(0, 5, 10, 15) - QUARTERROUND(1, 6, 11, 12) - QUARTERROUND(2, 7, 8, 13) - QUARTERROUND(3, 4, 9, 14) - } - - for (i = 0; i < 16; i++) { - x[i] = PLUS(x[i], input[i]); - } - - for (i = 0; i < 16; i++) { - output[i] = LITTLE32(x[i]); - } -} - -/** - * Encrypt a stream of bytes - */ -static void Chacha_encrypt_bytes(ChaCha* ctx, const byte* m, byte* c, - word32 bytes) -{ - byte* output; - word32 temp[16]; /* used to make sure aligned */ - word32 i; - - output = (byte*)temp; - - if (!bytes) return; - for (;;) { - Chacha_wordtobyte(temp, ctx->X); - ctx->X[12] = PLUSONE(ctx->X[12]); - if (bytes <= 64) { - for (i = 0; i < bytes; ++i) { - c[i] = m[i] ^ output[i]; - } - return; - } - for (i = 0; i < 64; ++i) { - c[i] = m[i] ^ output[i]; - } - bytes -= 64; - c += 64; - m += 64; - } -} - -/** - * API to encrypt/decrypt a message of any size. - */ -int Chacha_Process(ChaCha* ctx, byte* output, const byte* input, word32 msglen) -{ - if (ctx == NULL) - return BAD_FUNC_ARG; - - Chacha_encrypt_bytes(ctx, input, output, msglen); - - return 0; -} - -#endif /* HAVE_CHACHA*/ - diff --git a/ctaocrypt/src/dh.c b/ctaocrypt/src/dh.c deleted file mode 100644 index 81ec60cc8..000000000 --- a/ctaocrypt/src/dh.c +++ /dev/null @@ -1,178 +0,0 @@ -/* dh.c - * - * Copyright (C) 2006-2014 wolfSSL Inc. - * - * This file is part of wolfSSL. (formerly known as CyaSSL) - * - * wolfSSL is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * wolfSSL is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include - -#ifndef NO_DH - -#include -#include - -#ifndef USER_MATH_LIB - #include - #define XPOW(x,y) pow((x),(y)) - #define XLOG(x) log((x)) -#else - /* user's own math lib */ -#endif - - -#ifndef min - - static INLINE word32 min(word32 a, word32 b) - { - return a > b ? b : a; - } - -#endif /* min */ - - -void InitDhKey(DhKey* key) -{ - (void)key; -/* TomsFastMath doesn't use memory allocation */ -#ifndef USE_FAST_MATH - key->p.dp = 0; - key->g.dp = 0; -#endif -} - - -void FreeDhKey(DhKey* key) -{ - (void)key; -/* TomsFastMath doesn't use memory allocation */ -#ifndef USE_FAST_MATH - mp_clear(&key->p); - mp_clear(&key->g); -#endif -} - - -static word32 DiscreteLogWorkFactor(word32 n) -{ - /* assuming discrete log takes about the same time as factoring */ - if (n<5) - return 0; - else - return (word32)(2.4 * XPOW((double)n, 1.0/3.0) * - XPOW(XLOG((double)n), 2.0/3.0) - 5); -} - - -static int GeneratePrivate(DhKey* key, RNG* rng, byte* priv, word32* privSz) -{ - int ret; - word32 sz = mp_unsigned_bin_size(&key->p); - sz = min(sz, 2 * DiscreteLogWorkFactor(sz * CYASSL_BIT_SIZE) / - CYASSL_BIT_SIZE + 1); - - ret = RNG_GenerateBlock(rng, priv, sz); - if (ret != 0) - return ret; - - priv[0] |= 0x0C; - - *privSz = sz; - - return 0; -} - - -static int GeneratePublic(DhKey* key, const byte* priv, word32 privSz, - byte* pub, word32* pubSz) -{ - int ret = 0; - - mp_int x; - mp_int y; - - if (mp_init_multi(&x, &y, 0, 0, 0, 0) != MP_OKAY) - return MP_INIT_E; - - if (mp_read_unsigned_bin(&x, priv, privSz) != MP_OKAY) - ret = MP_READ_E; - - if (ret == 0 && mp_exptmod(&key->g, &x, &key->p, &y) != MP_OKAY) - ret = MP_EXPTMOD_E; - - if (ret == 0 && mp_to_unsigned_bin(&y, pub) != MP_OKAY) - ret = MP_TO_E; - - if (ret == 0) - *pubSz = mp_unsigned_bin_size(&y); - - mp_clear(&y); - mp_clear(&x); - - return ret; -} - - -int DhGenerateKeyPair(DhKey* key, RNG* rng, byte* priv, word32* privSz, - byte* pub, word32* pubSz) -{ - int ret = GeneratePrivate(key, rng, priv, privSz); - - return (ret != 0) ? ret : GeneratePublic(key, priv, *privSz, pub, pubSz); -} - -int DhAgree(DhKey* key, byte* agree, word32* agreeSz, const byte* priv, - word32 privSz, const byte* otherPub, word32 pubSz) -{ - int ret = 0; - - mp_int x; - mp_int y; - mp_int z; - - if (mp_init_multi(&x, &y, &z, 0, 0, 0) != MP_OKAY) - return MP_INIT_E; - - if (mp_read_unsigned_bin(&x, priv, privSz) != MP_OKAY) - ret = MP_READ_E; - - if (ret == 0 && mp_read_unsigned_bin(&y, otherPub, pubSz) != MP_OKAY) - ret = MP_READ_E; - - if (ret == 0 && mp_exptmod(&y, &x, &key->p, &z) != MP_OKAY) - ret = MP_EXPTMOD_E; - - if (ret == 0 && mp_to_unsigned_bin(&z, agree) != MP_OKAY) - ret = MP_TO_E; - - if (ret == 0) - *agreeSz = mp_unsigned_bin_size(&z); - - mp_clear(&z); - mp_clear(&y); - mp_clear(&x); - - return ret; -} - - -#endif /* NO_DH */ - diff --git a/ctaocrypt/src/dsa.c b/ctaocrypt/src/dsa.c deleted file mode 100644 index 6c68ceecd..000000000 --- a/ctaocrypt/src/dsa.c +++ /dev/null @@ -1,226 +0,0 @@ -/* dsa.c - * - * Copyright (C) 2006-2014 wolfSSL Inc. - * - * This file is part of wolfSSL. (formerly known as CyaSSL) - * - * wolfSSL is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * wolfSSL is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include - -#ifndef NO_DSA - -#include -#include -#include -#include - - -enum { - DSA_HALF_SIZE = 20, /* r and s size */ - DSA_SIG_SIZE = 40 /* signature size */ -}; - - -#ifndef min - - static INLINE word32 min(word32 a, word32 b) - { - return a > b ? b : a; - } - -#endif /* min */ - - -void InitDsaKey(DsaKey* key) -{ - key->type = -1; /* haven't decided yet */ - -/* TomsFastMath doesn't use memory allocation */ -#ifndef USE_FAST_MATH - key->p.dp = 0; /* public alloc parts */ - key->q.dp = 0; - key->g.dp = 0; - key->y.dp = 0; - - key->x.dp = 0; /* private alloc parts */ -#endif -} - - -void FreeDsaKey(DsaKey* key) -{ - (void)key; -/* TomsFastMath doesn't use memory allocation */ -#ifndef USE_FAST_MATH - if (key->type == DSA_PRIVATE) - mp_clear(&key->x); - mp_clear(&key->y); - mp_clear(&key->g); - mp_clear(&key->q); - mp_clear(&key->p); -#endif -} - - -int DsaSign(const byte* digest, byte* out, DsaKey* key, RNG* rng) -{ - mp_int k, kInv, r, s, H; - int ret, sz; - byte buffer[DSA_HALF_SIZE]; - - sz = min(sizeof(buffer), mp_unsigned_bin_size(&key->q)); - - /* generate k */ - ret = RNG_GenerateBlock(rng, buffer, sz); - if (ret != 0) - return ret; - - buffer[0] |= 0x0C; - - if (mp_init_multi(&k, &kInv, &r, &s, &H, 0) != MP_OKAY) - return MP_INIT_E; - - if (mp_read_unsigned_bin(&k, buffer, sz) != MP_OKAY) - ret = MP_READ_E; - - if (ret == 0 && mp_cmp_d(&k, 1) != MP_GT) - ret = MP_CMP_E; - - /* inverse k mod q */ - if (ret == 0 && mp_invmod(&k, &key->q, &kInv) != MP_OKAY) - ret = MP_INVMOD_E; - - /* generate r, r = (g exp k mod p) mod q */ - if (ret == 0 && mp_exptmod(&key->g, &k, &key->p, &r) != MP_OKAY) - ret = MP_EXPTMOD_E; - - if (ret == 0 && mp_mod(&r, &key->q, &r) != MP_OKAY) - ret = MP_MOD_E; - - /* generate H from sha digest */ - if (ret == 0 && mp_read_unsigned_bin(&H, digest,SHA_DIGEST_SIZE) != MP_OKAY) - ret = MP_READ_E; - - /* generate s, s = (kInv * (H + x*r)) % q */ - if (ret == 0 && mp_mul(&key->x, &r, &s) != MP_OKAY) - ret = MP_MUL_E; - - if (ret == 0 && mp_add(&s, &H, &s) != MP_OKAY) - ret = MP_ADD_E; - - if (ret == 0 && mp_mulmod(&s, &kInv, &key->q, &s) != MP_OKAY) - ret = MP_MULMOD_E; - - /* write out */ - if (ret == 0) { - int rSz = mp_unsigned_bin_size(&r); - int sSz = mp_unsigned_bin_size(&s); - - if (rSz == DSA_HALF_SIZE - 1) { - out[0] = 0; - out++; - } - - if (mp_to_unsigned_bin(&r, out) != MP_OKAY) - ret = MP_TO_E; - else { - if (sSz == DSA_HALF_SIZE - 1) { - out[rSz] = 0; - out++; - } - ret = mp_to_unsigned_bin(&s, out + rSz); - } - } - - mp_clear(&H); - mp_clear(&s); - mp_clear(&r); - mp_clear(&kInv); - mp_clear(&k); - - return ret; -} - - -int DsaVerify(const byte* digest, const byte* sig, DsaKey* key, int* answer) -{ - mp_int w, u1, u2, v, r, s; - int ret = 0; - - if (mp_init_multi(&w, &u1, &u2, &v, &r, &s) != MP_OKAY) - return MP_INIT_E; - - /* set r and s from signature */ - if (mp_read_unsigned_bin(&r, sig, DSA_HALF_SIZE) != MP_OKAY || - mp_read_unsigned_bin(&s, sig + DSA_HALF_SIZE, DSA_HALF_SIZE) != MP_OKAY) - ret = MP_READ_E; - - /* sanity checks */ - - - /* put H into u1 from sha digest */ - if (ret == 0 && mp_read_unsigned_bin(&u1,digest,SHA_DIGEST_SIZE) != MP_OKAY) - ret = MP_READ_E; - - /* w = s invmod q */ - if (ret == 0 && mp_invmod(&s, &key->q, &w) != MP_OKAY) - ret = MP_INVMOD_E; - - /* u1 = (H * w) % q */ - if (ret == 0 && mp_mulmod(&u1, &w, &key->q, &u1) != MP_OKAY) - ret = MP_MULMOD_E; - - /* u2 = (r * w) % q */ - if (ret == 0 && mp_mulmod(&r, &w, &key->q, &u2) != MP_OKAY) - ret = MP_MULMOD_E; - - /* verify v = ((g^u1 * y^u2) mod p) mod q */ - if (ret == 0 && mp_exptmod(&key->g, &u1, &key->p, &u1) != MP_OKAY) - ret = MP_EXPTMOD_E; - - if (ret == 0 && mp_exptmod(&key->y, &u2, &key->p, &u2) != MP_OKAY) - ret = MP_EXPTMOD_E; - - if (ret == 0 && mp_mulmod(&u1, &u2, &key->p, &v) != MP_OKAY) - ret = MP_MULMOD_E; - - if (ret == 0 && mp_mod(&v, &key->q, &v) != MP_OKAY) - ret = MP_MULMOD_E; - - /* do they match */ - if (ret == 0 && mp_cmp(&r, &v) == MP_EQ) - *answer = 1; - else - *answer = 0; - - mp_clear(&s); - mp_clear(&r); - mp_clear(&u1); - mp_clear(&u2); - mp_clear(&w); - mp_clear(&v); - - return ret; -} - - -#endif /* NO_DSA */ - diff --git a/ctaocrypt/src/ecc.c b/ctaocrypt/src/ecc.c deleted file mode 100644 index 67deb7d08..000000000 --- a/ctaocrypt/src/ecc.c +++ /dev/null @@ -1,4837 +0,0 @@ -/* ecc.c - * - * Copyright (C) 2006-2014 wolfSSL Inc. - * - * This file is part of wolfSSL. (formerly known as CyaSSL) - * - * wolfSSL is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * wolfSSL is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - - -#ifdef HAVE_CONFIG_H - #include -#endif - -/* in case user set HAVE_ECC there */ -#include - -#ifdef HAVE_ECC - -#include -#include -#include - -#ifdef HAVE_ECC_ENCRYPT - #include - #include -#endif - - -/* map - - ptmul -> mulmod - -*/ - -#define ECC112 -#define ECC128 -#define ECC160 -#define ECC192 -#define ECC224 -#define ECC256 -#define ECC384 -#define ECC521 - - - -/* This holds the key settings. ***MUST*** be organized by size from - smallest to largest. */ - -const ecc_set_type ecc_sets[] = { -#ifdef ECC112 -{ - 14, - "SECP112R1", - "DB7C2ABF62E35E668076BEAD208B", - "DB7C2ABF62E35E668076BEAD2088", - "659EF8BA043916EEDE8911702B22", - "DB7C2ABF62E35E7628DFAC6561C5", - "09487239995A5EE76B55F9C2F098", - "A89CE5AF8724C0A23E0E0FF77500" -}, -#endif -#ifdef ECC128 -{ - 16, - "SECP128R1", - "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", - "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC", - "E87579C11079F43DD824993C2CEE5ED3", - "FFFFFFFE0000000075A30D1B9038A115", - "161FF7528B899B2D0C28607CA52C5B86", - "CF5AC8395BAFEB13C02DA292DDED7A83", -}, -#endif -#ifdef ECC160 -{ - 20, - "SECP160R1", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", - "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", - "0100000000000000000001F4C8F927AED3CA752257", - "4A96B5688EF573284664698968C38BB913CBFC82", - "23A628553168947D59DCC912042351377AC5FB32", -}, -#endif -#ifdef ECC192 -{ - 24, - "ECC-192", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", - "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1", - "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", - "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", - "7192B95FFC8DA78631011ED6B24CDD573F977A11E794811", -}, -#endif -#ifdef ECC224 -{ - 28, - "ECC-224", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", - "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", - "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", - "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", -}, -#endif -#ifdef ECC256 -{ - 32, - "ECC-256", - "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", - "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", - "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", - "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", - "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", - "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", -}, -#endif -#ifdef ECC384 -{ - 48, - "ECC-384", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", - "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", - "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7", - "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", -}, -#endif -#ifdef ECC521 -{ - 66, - "ECC-521", - "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", - "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", - "51953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", - "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", - "C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66", - "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650", -}, -#endif -{ - 0, - NULL, NULL, NULL, NULL, NULL, NULL, NULL -} -}; - - -ecc_point* ecc_new_point(void); -void ecc_del_point(ecc_point* p); -int ecc_map(ecc_point*, mp_int*, mp_digit*); -int ecc_projective_add_point(ecc_point* P, ecc_point* Q, ecc_point* R, - mp_int* modulus, mp_digit* mp); -int ecc_projective_dbl_point(ecc_point* P, ecc_point* R, mp_int* modulus, - mp_digit* mp); -static int ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* modulus, - int map); -#ifdef ECC_SHAMIR -static int ecc_mul2add(ecc_point* A, mp_int* kA, ecc_point* B, mp_int* kB, - ecc_point* C, mp_int* modulus); -#endif - -int mp_jacobi(mp_int* a, mp_int* p, int* c); -int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret); -int mp_submod(mp_int* a, mp_int* b, mp_int* c, mp_int* d); - -#ifdef HAVE_COMP_KEY -static int ecc_export_x963_compressed(ecc_key*, byte* out, word32* outLen); -#endif - -/* helper for either lib */ -static int get_digit_count(mp_int* a) -{ - if (a == NULL) - return 0; - - return a->used; -} - -/* helper for either lib */ -static mp_digit get_digit(mp_int* a, int n) -{ - if (a == NULL) - return 0; - - return (n >= a->used || n < 0) ? 0 : a->dp[n]; -} - - -#if defined(USE_FAST_MATH) - -/* fast math accelerated version, but not for fp ecc yet */ - -/** - Add two ECC points - P The point to add - Q The point to add - R [out] The destination of the double - modulus The modulus of the field the ECC curve is in - mp The "b" value from montgomery_setup() - return MP_OKAY on success -*/ -int ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, - mp_int* modulus, mp_digit* mp) -{ - fp_int t1, t2, x, y, z; - int err; - - if (P == NULL || Q == NULL || R == NULL || modulus == NULL || mp == NULL) - return ECC_BAD_ARG_E; - - if ((err = mp_init_multi(&t1, &t2, &x, &y, &z, NULL)) != MP_OKAY) { - return err; - } - - /* should we dbl instead? */ - fp_sub(modulus, &Q->y, &t1); - if ( (fp_cmp(&P->x, &Q->x) == FP_EQ) && - (get_digit_count(&Q->z) && fp_cmp(&P->z, &Q->z) == FP_EQ) && - (fp_cmp(&P->y, &Q->y) == FP_EQ || fp_cmp(&P->y, &t1) == FP_EQ)) { - return ecc_projective_dbl_point(P, R, modulus, mp); - } - - fp_copy(&P->x, &x); - fp_copy(&P->y, &y); - fp_copy(&P->z, &z); - - /* if Z is one then these are no-operations */ - if (get_digit_count(&Q->z)) { - /* T1 = Z' * Z' */ - fp_sqr(&Q->z, &t1); - fp_montgomery_reduce(&t1, modulus, *mp); - /* X = X * T1 */ - fp_mul(&t1, &x, &x); - fp_montgomery_reduce(&x, modulus, *mp); - /* T1 = Z' * T1 */ - fp_mul(&Q->z, &t1, &t1); - fp_montgomery_reduce(&t1, modulus, *mp); - /* Y = Y * T1 */ - fp_mul(&t1, &y, &y); - fp_montgomery_reduce(&y, modulus, *mp); - } - - /* T1 = Z*Z */ - fp_sqr(&z, &t1); - fp_montgomery_reduce(&t1, modulus, *mp); - /* T2 = X' * T1 */ - fp_mul(&Q->x, &t1, &t2); - fp_montgomery_reduce(&t2, modulus, *mp); - /* T1 = Z * T1 */ - fp_mul(&z, &t1, &t1); - fp_montgomery_reduce(&t1, modulus, *mp); - /* T1 = Y' * T1 */ - fp_mul(&Q->y, &t1, &t1); - fp_montgomery_reduce(&t1, modulus, *mp); - - /* Y = Y - T1 */ - fp_sub(&y, &t1, &y); - if (fp_cmp_d(&y, 0) == FP_LT) { - fp_add(&y, modulus, &y); - } - /* T1 = 2T1 */ - fp_add(&t1, &t1, &t1); - if (fp_cmp(&t1, modulus) != FP_LT) { - fp_sub(&t1, modulus, &t1); - } - /* T1 = Y + T1 */ - fp_add(&t1, &y, &t1); - if (fp_cmp(&t1, modulus) != FP_LT) { - fp_sub(&t1, modulus, &t1); - } - /* X = X - T2 */ - fp_sub(&x, &t2, &x); - if (fp_cmp_d(&x, 0) == FP_LT) { - fp_add(&x, modulus, &x); - } - /* T2 = 2T2 */ - fp_add(&t2, &t2, &t2); - if (fp_cmp(&t2, modulus) != FP_LT) { - fp_sub(&t2, modulus, &t2); - } - /* T2 = X + T2 */ - fp_add(&t2, &x, &t2); - if (fp_cmp(&t2, modulus) != FP_LT) { - fp_sub(&t2, modulus, &t2); - } - - /* if Z' != 1 */ - if (get_digit_count(&Q->z)) { - /* Z = Z * Z' */ - fp_mul(&z, &Q->z, &z); - fp_montgomery_reduce(&z, modulus, *mp); - } - - /* Z = Z * X */ - fp_mul(&z, &x, &z); - fp_montgomery_reduce(&z, modulus, *mp); - - /* T1 = T1 * X */ - fp_mul(&t1, &x, &t1); - fp_montgomery_reduce(&t1, modulus, *mp); - /* X = X * X */ - fp_sqr(&x, &x); - fp_montgomery_reduce(&x, modulus, *mp); - /* T2 = T2 * x */ - fp_mul(&t2, &x, &t2); - fp_montgomery_reduce(&t2, modulus, *mp); - /* T1 = T1 * X */ - fp_mul(&t1, &x, &t1); - fp_montgomery_reduce(&t1, modulus, *mp); - - /* X = Y*Y */ - fp_sqr(&y, &x); - fp_montgomery_reduce(&x, modulus, *mp); - /* X = X - T2 */ - fp_sub(&x, &t2, &x); - if (fp_cmp_d(&x, 0) == FP_LT) { - fp_add(&x, modulus, &x); - } - - /* T2 = T2 - X */ - fp_sub(&t2, &x, &t2); - if (fp_cmp_d(&t2, 0) == FP_LT) { - fp_add(&t2, modulus, &t2); - } - /* T2 = T2 - X */ - fp_sub(&t2, &x, &t2); - if (fp_cmp_d(&t2, 0) == FP_LT) { - fp_add(&t2, modulus, &t2); - } - /* T2 = T2 * Y */ - fp_mul(&t2, &y, &t2); - fp_montgomery_reduce(&t2, modulus, *mp); - /* Y = T2 - T1 */ - fp_sub(&t2, &t1, &y); - if (fp_cmp_d(&y, 0) == FP_LT) { - fp_add(&y, modulus, &y); - } - /* Y = Y/2 */ - if (fp_isodd(&y)) { - fp_add(&y, modulus, &y); - } - fp_div_2(&y, &y); - - fp_copy(&x, &R->x); - fp_copy(&y, &R->y); - fp_copy(&z, &R->z); - - return MP_OKAY; -} - - -/** - Double an ECC point - P The point to double - R [out] The destination of the double - modulus The modulus of the field the ECC curve is in - mp The "b" value from montgomery_setup() - return MP_OKAY on success -*/ -int ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* modulus, - mp_digit* mp) -{ - fp_int t1, t2; - int err; - - if (P == NULL || R == NULL || modulus == NULL || mp == NULL) - return ECC_BAD_ARG_E; - - if (P != R) { - fp_copy(&P->x, &R->x); - fp_copy(&P->y, &R->y); - fp_copy(&P->z, &R->z); - } - - if ((err = mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL)) != MP_OKAY) { - return err; - } - - /* t1 = Z * Z */ - fp_sqr(&R->z, &t1); - fp_montgomery_reduce(&t1, modulus, *mp); - /* Z = Y * Z */ - fp_mul(&R->z, &R->y, &R->z); - fp_montgomery_reduce(&R->z, modulus, *mp); - /* Z = 2Z */ - fp_add(&R->z, &R->z, &R->z); - if (fp_cmp(&R->z, modulus) != FP_LT) { - fp_sub(&R->z, modulus, &R->z); - } - - /* &t2 = X - T1 */ - fp_sub(&R->x, &t1, &t2); - if (fp_cmp_d(&t2, 0) == FP_LT) { - fp_add(&t2, modulus, &t2); - } - /* T1 = X + T1 */ - fp_add(&t1, &R->x, &t1); - if (fp_cmp(&t1, modulus) != FP_LT) { - fp_sub(&t1, modulus, &t1); - } - /* T2 = T1 * T2 */ - fp_mul(&t1, &t2, &t2); - fp_montgomery_reduce(&t2, modulus, *mp); - /* T1 = 2T2 */ - fp_add(&t2, &t2, &t1); - if (fp_cmp(&t1, modulus) != FP_LT) { - fp_sub(&t1, modulus, &t1); - } - /* T1 = T1 + T2 */ - fp_add(&t1, &t2, &t1); - if (fp_cmp(&t1, modulus) != FP_LT) { - fp_sub(&t1, modulus, &t1); - } - - /* Y = 2Y */ - fp_add(&R->y, &R->y, &R->y); - if (fp_cmp(&R->y, modulus) != FP_LT) { - fp_sub(&R->y, modulus, &R->y); - } - /* Y = Y * Y */ - fp_sqr(&R->y, &R->y); - fp_montgomery_reduce(&R->y, modulus, *mp); - /* T2 = Y * Y */ - fp_sqr(&R->y, &t2); - fp_montgomery_reduce(&t2, modulus, *mp); - /* T2 = T2/2 */ - if (fp_isodd(&t2)) { - fp_add(&t2, modulus, &t2); - } - fp_div_2(&t2, &t2); - /* Y = Y * X */ - fp_mul(&R->y, &R->x, &R->y); - fp_montgomery_reduce(&R->y, modulus, *mp); - - /* X = T1 * T1 */ - fp_sqr(&t1, &R->x); - fp_montgomery_reduce(&R->x, modulus, *mp); - /* X = X - Y */ - fp_sub(&R->x, &R->y, &R->x); - if (fp_cmp_d(&R->x, 0) == FP_LT) { - fp_add(&R->x, modulus, &R->x); - } - /* X = X - Y */ - fp_sub(&R->x, &R->y, &R->x); - if (fp_cmp_d(&R->x, 0) == FP_LT) { - fp_add(&R->x, modulus, &R->x); - } - - /* Y = Y - X */ - fp_sub(&R->y, &R->x, &R->y); - if (fp_cmp_d(&R->y, 0) == FP_LT) { - fp_add(&R->y, modulus, &R->y); - } - /* Y = Y * T1 */ - fp_mul(&R->y, &t1, &R->y); - fp_montgomery_reduce(&R->y, modulus, *mp); - /* Y = Y - T2 */ - fp_sub(&R->y, &t2, &R->y); - if (fp_cmp_d(&R->y, 0) == FP_LT) { - fp_add(&R->y, modulus, &R->y); - } - - return MP_OKAY; -} - -#else /* USE_FAST_MATH */ - -/** - Add two ECC points - P The point to add - Q The point to add - R [out] The destination of the double - modulus The modulus of the field the ECC curve is in - mp The "b" value from montgomery_setup() - return MP_OKAY on success -*/ -int ecc_projective_add_point(ecc_point* P, ecc_point* Q, ecc_point* R, - mp_int* modulus, mp_digit* mp) -{ - mp_int t1; - mp_int t2; - mp_int x; - mp_int y; - mp_int z; - int err; - - if (P == NULL || Q == NULL || R == NULL || modulus == NULL || mp == NULL) - return ECC_BAD_ARG_E; - - if ((err = mp_init_multi(&t1, &t2, &x, &y, &z, NULL)) != MP_OKAY) { - return err; - } - - /* should we dbl instead? */ - err = mp_sub(modulus, &Q->y, &t1); - - if (err == MP_OKAY) { - if ( (mp_cmp(&P->x, &Q->x) == MP_EQ) && - (get_digit_count(&Q->z) && mp_cmp(&P->z, &Q->z) == MP_EQ) && - (mp_cmp(&P->y, &Q->y) == MP_EQ || mp_cmp(&P->y, &t1) == MP_EQ)) { - mp_clear(&t1); - mp_clear(&t2); - mp_clear(&x); - mp_clear(&y); - mp_clear(&z); - - return ecc_projective_dbl_point(P, R, modulus, mp); - } - } - - if (err == MP_OKAY) - err = mp_copy(&P->x, &x); - if (err == MP_OKAY) - err = mp_copy(&P->y, &y); - if (err == MP_OKAY) - err = mp_copy(&P->z, &z); - - /* if Z is one then these are no-operations */ - if (err == MP_OKAY) { - if (get_digit_count(&Q->z)) { - /* T1 = Z' * Z' */ - err = mp_sqr(&Q->z, &t1); - if (err == MP_OKAY) - err = mp_montgomery_reduce(&t1, modulus, *mp); - - /* X = X * T1 */ - if (err == MP_OKAY) - err = mp_mul(&t1, &x, &x); - if (err == MP_OKAY) - err = mp_montgomery_reduce(&x, modulus, *mp); - - /* T1 = Z' * T1 */ - if (err == MP_OKAY) - err = mp_mul(&Q->z, &t1, &t1); - if (err == MP_OKAY) - err = mp_montgomery_reduce(&t1, modulus, *mp); - - /* Y = Y * T1 */ - if (err == MP_OKAY) - err = mp_mul(&t1, &y, &y); - if (err == MP_OKAY) - err = mp_montgomery_reduce(&y, modulus, *mp); - } - } - - /* T1 = Z*Z */ - if (err == MP_OKAY) - err = mp_sqr(&z, &t1); - if (err == MP_OKAY) - err = mp_montgomery_reduce(&t1, modulus, *mp); - - /* T2 = X' * T1 */ - if (err == MP_OKAY) - err = mp_mul(&Q->x, &t1, &t2); - if (err == MP_OKAY) - err = mp_montgomery_reduce(&t2, modulus, *mp); - - /* T1 = Z * T1 */ - if (err == MP_OKAY) - err = mp_mul(&z, &t1, &t1); - if (err == MP_OKAY) - err = mp_montgomery_reduce(&t1, modulus, *mp); - - /* T1 = Y' * T1 */ - if (err == MP_OKAY) - err = mp_mul(&Q->y, &t1, &t1); - if (err == MP_OKAY) - err = mp_montgomery_reduce(&t1, modulus, *mp); - - /* Y = Y - T1 */ - if (err == MP_OKAY) - err = mp_sub(&y, &t1, &y); - if (err == MP_OKAY) { - if (mp_cmp_d(&y, 0) == MP_LT) - err = mp_add(&y, modulus, &y); - } - /* T1 = 2T1 */ - if (err == MP_OKAY) - err = mp_add(&t1, &t1, &t1); - if (err == MP_OKAY) { - if (mp_cmp(&t1, modulus) != MP_LT) - err = mp_sub(&t1, modulus, &t1); - } - /* T1 = Y + T1 */ - if (err == MP_OKAY) - err = mp_add(&t1, &y, &t1); - if (err == MP_OKAY) { - if (mp_cmp(&t1, modulus) != MP_LT) - err = mp_sub(&t1, modulus, &t1); - } - /* X = X - T2 */ - if (err == MP_OKAY) - err = mp_sub(&x, &t2, &x); - if (err == MP_OKAY) { - if (mp_cmp_d(&x, 0) == MP_LT) - err = mp_add(&x, modulus, &x); - } - /* T2 = 2T2 */ - if (err == MP_OKAY) - err = mp_add(&t2, &t2, &t2); - if (err == MP_OKAY) { - if (mp_cmp(&t2, modulus) != MP_LT) - err = mp_sub(&t2, modulus, &t2); - } - /* T2 = X + T2 */ - if (err == MP_OKAY) - err = mp_add(&t2, &x, &t2); - if (err == MP_OKAY) { - if (mp_cmp(&t2, modulus) != MP_LT) - err = mp_sub(&t2, modulus, &t2); - } - - if (err == MP_OKAY) { - if (get_digit_count(&Q->z)) { - /* Z = Z * Z' */ - err = mp_mul(&z, &Q->z, &z); - if (err == MP_OKAY) - err = mp_montgomery_reduce(&z, modulus, *mp); - } - } - - /* Z = Z * X */ - if (err == MP_OKAY) - err = mp_mul(&z, &x, &z); - if (err == MP_OKAY) - err = mp_montgomery_reduce(&z, modulus, *mp); - - /* T1 = T1 * X */ - if (err == MP_OKAY) - err = mp_mul(&t1, &x, &t1); - if (err == MP_OKAY) - err = mp_montgomery_reduce(&t1, modulus, *mp); - - /* X = X * X */ - if (err == MP_OKAY) - err = mp_sqr(&x, &x); - if (err == MP_OKAY) - err = mp_montgomery_reduce(&x, modulus, *mp); - - /* T2 = T2 * x */ - if (err == MP_OKAY) - err = mp_mul(&t2, &x, &t2); - if (err == MP_OKAY) - err = mp_montgomery_reduce(&t2, modulus, *mp); - - /* T1 = T1 * X */ - if (err == MP_OKAY) - err = mp_mul(&t1, &x, &t1); - if (err == MP_OKAY) - err = mp_montgomery_reduce(&t1, modulus, *mp); - - /* X = Y*Y */ - if (err == MP_OKAY) - err = mp_sqr(&y, &x); - if (err == MP_OKAY) - err = mp_montgomery_reduce(&x, modulus, *mp); - - /* X = X - T2 */ - if (err == MP_OKAY) - err = mp_sub(&x, &t2, &x); - if (err == MP_OKAY) { - if (mp_cmp_d(&x, 0) == MP_LT) - err = mp_add(&x, modulus, &x); - } - /* T2 = T2 - X */ - if (err == MP_OKAY) - err = mp_sub(&t2, &x, &t2); - if (err == MP_OKAY) { - if (mp_cmp_d(&t2, 0) == MP_LT) - err = mp_add(&t2, modulus, &t2); - } - /* T2 = T2 - X */ - if (err == MP_OKAY) - err = mp_sub(&t2, &x, &t2); - if (err == MP_OKAY) { - if (mp_cmp_d(&t2, 0) == MP_LT) - err = mp_add(&t2, modulus, &t2); - } - /* T2 = T2 * Y */ - if (err == MP_OKAY) - err = mp_mul(&t2, &y, &t2); - if (err == MP_OKAY) - err = mp_montgomery_reduce(&t2, modulus, *mp); - - /* Y = T2 - T1 */ - if (err == MP_OKAY) - err = mp_sub(&t2, &t1, &y); - if (err == MP_OKAY) { - if (mp_cmp_d(&y, 0) == MP_LT) - err = mp_add(&y, modulus, &y); - } - /* Y = Y/2 */ - if (err == MP_OKAY) { - if (mp_isodd(&y)) - err = mp_add(&y, modulus, &y); - } - if (err == MP_OKAY) - err = mp_div_2(&y, &y); - - if (err == MP_OKAY) - err = mp_copy(&x, &R->x); - if (err == MP_OKAY) - err = mp_copy(&y, &R->y); - if (err == MP_OKAY) - err = mp_copy(&z, &R->z); - - /* clean up */ - mp_clear(&t1); - mp_clear(&t2); - mp_clear(&x); - mp_clear(&y); - mp_clear(&z); - - return err; -} - - -/** - Double an ECC point - P The point to double - R [out] The destination of the double - modulus The modulus of the field the ECC curve is in - mp The "b" value from montgomery_setup() - return MP_OKAY on success -*/ -int ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* modulus, - mp_digit* mp) -{ - mp_int t1; - mp_int t2; - int err; - - if (P == NULL || R == NULL || modulus == NULL || mp == NULL) - return ECC_BAD_ARG_E; - - if ((err = mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL)) != MP_OKAY) { - return err; - } - - if (P != R) { - err = mp_copy(&P->x, &R->x); - if (err == MP_OKAY) - err = mp_copy(&P->y, &R->y); - if (err == MP_OKAY) - err = mp_copy(&P->z, &R->z); - } - - /* t1 = Z * Z */ - if (err == MP_OKAY) - err = mp_sqr(&R->z, &t1); - if (err == MP_OKAY) - err = mp_montgomery_reduce(&t1, modulus, *mp); - - /* Z = Y * Z */ - if (err == MP_OKAY) - err = mp_mul(&R->z, &R->y, &R->z); - if (err == MP_OKAY) - err = mp_montgomery_reduce(&R->z, modulus, *mp); - - /* Z = 2Z */ - if (err == MP_OKAY) - err = mp_add(&R->z, &R->z, &R->z); - if (err == MP_OKAY) { - if (mp_cmp(&R->z, modulus) != MP_LT) - err = mp_sub(&R->z, modulus, &R->z); - } - - /* T2 = X - T1 */ - if (err == MP_OKAY) - err = mp_sub(&R->x, &t1, &t2); - if (err == MP_OKAY) { - if (mp_cmp_d(&t2, 0) == MP_LT) - err = mp_add(&t2, modulus, &t2); - } - /* T1 = X + T1 */ - if (err == MP_OKAY) - err = mp_add(&t1, &R->x, &t1); - if (err == MP_OKAY) { - if (mp_cmp(&t1, modulus) != MP_LT) - err = mp_sub(&t1, modulus, &t1); - } - /* T2 = T1 * T2 */ - if (err == MP_OKAY) - err = mp_mul(&t1, &t2, &t2); - if (err == MP_OKAY) - err = mp_montgomery_reduce(&t2, modulus, *mp); - - /* T1 = 2T2 */ - if (err == MP_OKAY) - err = mp_add(&t2, &t2, &t1); - if (err == MP_OKAY) { - if (mp_cmp(&t1, modulus) != MP_LT) - err = mp_sub(&t1, modulus, &t1); - } - /* T1 = T1 + T2 */ - if (err == MP_OKAY) - err = mp_add(&t1, &t2, &t1); - if (err == MP_OKAY) { - if (mp_cmp(&t1, modulus) != MP_LT) - err = mp_sub(&t1, modulus, &t1); - } - /* Y = 2Y */ - if (err == MP_OKAY) - err = mp_add(&R->y, &R->y, &R->y); - if (err == MP_OKAY) { - if (mp_cmp(&R->y, modulus) != MP_LT) - err = mp_sub(&R->y, modulus, &R->y); - } - /* Y = Y * Y */ - if (err == MP_OKAY) - err = mp_sqr(&R->y, &R->y); - if (err == MP_OKAY) - err = mp_montgomery_reduce(&R->y, modulus, *mp); - - /* T2 = Y * Y */ - if (err == MP_OKAY) - err = mp_sqr(&R->y, &t2); - if (err == MP_OKAY) - err = mp_montgomery_reduce(&t2, modulus, *mp); - - /* T2 = T2/2 */ - if (err == MP_OKAY) { - if (mp_isodd(&t2)) - err = mp_add(&t2, modulus, &t2); - } - if (err == MP_OKAY) - err = mp_div_2(&t2, &t2); - - /* Y = Y * X */ - if (err == MP_OKAY) - err = mp_mul(&R->y, &R->x, &R->y); - if (err == MP_OKAY) - err = mp_montgomery_reduce(&R->y, modulus, *mp); - - /* X = T1 * T1 */ - if (err == MP_OKAY) - err = mp_sqr(&t1, &R->x); - if (err == MP_OKAY) - err = mp_montgomery_reduce(&R->x, modulus, *mp); - - /* X = X - Y */ - if (err == MP_OKAY) - err = mp_sub(&R->x, &R->y, &R->x); - if (err == MP_OKAY) { - if (mp_cmp_d(&R->x, 0) == MP_LT) - err = mp_add(&R->x, modulus, &R->x); - } - /* X = X - Y */ - if (err == MP_OKAY) - err = mp_sub(&R->x, &R->y, &R->x); - if (err == MP_OKAY) { - if (mp_cmp_d(&R->x, 0) == MP_LT) - err = mp_add(&R->x, modulus, &R->x); - } - /* Y = Y - X */ - if (err == MP_OKAY) - err = mp_sub(&R->y, &R->x, &R->y); - if (err == MP_OKAY) { - if (mp_cmp_d(&R->y, 0) == MP_LT) - err = mp_add(&R->y, modulus, &R->y); - } - /* Y = Y * T1 */ - if (err == MP_OKAY) - err = mp_mul(&R->y, &t1, &R->y); - if (err == MP_OKAY) - err = mp_montgomery_reduce(&R->y, modulus, *mp); - - /* Y = Y - T2 */ - if (err == MP_OKAY) - err = mp_sub(&R->y, &t2, &R->y); - if (err == MP_OKAY) { - if (mp_cmp_d(&R->y, 0) == MP_LT) - err = mp_add(&R->y, modulus, &R->y); - } - - /* clean up */ - mp_clear(&t1); - mp_clear(&t2); - - return err; -} - -#endif /* USE_FAST_MATH */ - -/** - Map a projective jacbobian point back to affine space - P [in/out] The point to map - modulus The modulus of the field the ECC curve is in - mp The "b" value from montgomery_setup() - return MP_OKAY on success -*/ -int ecc_map(ecc_point* P, mp_int* modulus, mp_digit* mp) -{ - mp_int t1; - mp_int t2; - int err; - - if (P == NULL || mp == NULL || modulus == NULL) - return ECC_BAD_ARG_E; - - if ((err = mp_init_multi(&t1, &t2, NULL, NULL, NULL, NULL)) != MP_OKAY) { - return MEMORY_E; - } - - /* first map z back to normal */ - err = mp_montgomery_reduce(&P->z, modulus, *mp); - - /* get 1/z */ - if (err == MP_OKAY) - err = mp_invmod(&P->z, modulus, &t1); - - /* get 1/z^2 and 1/z^3 */ - if (err == MP_OKAY) - err = mp_sqr(&t1, &t2); - if (err == MP_OKAY) - err = mp_mod(&t2, modulus, &t2); - if (err == MP_OKAY) - err = mp_mul(&t1, &t2, &t1); - if (err == MP_OKAY) - err = mp_mod(&t1, modulus, &t1); - - /* multiply against x/y */ - if (err == MP_OKAY) - err = mp_mul(&P->x, &t2, &P->x); - if (err == MP_OKAY) - err = mp_montgomery_reduce(&P->x, modulus, *mp); - if (err == MP_OKAY) - err = mp_mul(&P->y, &t1, &P->y); - if (err == MP_OKAY) - err = mp_montgomery_reduce(&P->y, modulus, *mp); - - if (err == MP_OKAY) - mp_set(&P->z, 1); - - /* clean up */ - mp_clear(&t1); - mp_clear(&t2); - - return err; -} - - -#ifndef ECC_TIMING_RESISTANT - -/* size of sliding window, don't change this! */ -#define WINSIZE 4 - -/** - Perform a point multiplication - k The scalar to multiply by - G The base point - R [out] Destination for kG - modulus The modulus of the field the ECC curve is in - map Boolean whether to map back to affine or not - (1==map, 0 == leave in projective) - return MP_OKAY on success -*/ -#ifdef FP_ECC -static int normal_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, - mp_int* modulus, int map) -#else -static int ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* modulus, - int map) -#endif -{ - ecc_point *tG, *M[8]; - int i, j, err; - mp_int mu; - mp_digit mp; - mp_digit buf; - int first = 1, bitbuf = 0, bitcpy = 0, bitcnt = 0, mode = 0, - digidx = 0; - - if (k == NULL || G == NULL || R == NULL || modulus == NULL) - return ECC_BAD_ARG_E; - - /* init montgomery reduction */ - if ((err = mp_montgomery_setup(modulus, &mp)) != MP_OKAY) { - return err; - } - if ((err = mp_init(&mu)) != MP_OKAY) { - return err; - } - if ((err = mp_montgomery_calc_normalization(&mu, modulus)) != MP_OKAY) { - mp_clear(&mu); - return err; - } - - /* alloc ram for window temps */ - for (i = 0; i < 8; i++) { - M[i] = ecc_new_point(); - if (M[i] == NULL) { - for (j = 0; j < i; j++) { - ecc_del_point(M[j]); - } - mp_clear(&mu); - return MEMORY_E; - } - } - - /* make a copy of G incase R==G */ - tG = ecc_new_point(); - if (tG == NULL) - err = MEMORY_E; - - /* tG = G and convert to montgomery */ - if (err == MP_OKAY) { - if (mp_cmp_d(&mu, 1) == MP_EQ) { - err = mp_copy(&G->x, &tG->x); - if (err == MP_OKAY) - err = mp_copy(&G->y, &tG->y); - if (err == MP_OKAY) - err = mp_copy(&G->z, &tG->z); - } else { - err = mp_mulmod(&G->x, &mu, modulus, &tG->x); - if (err == MP_OKAY) - err = mp_mulmod(&G->y, &mu, modulus, &tG->y); - if (err == MP_OKAY) - err = mp_mulmod(&G->z, &mu, modulus, &tG->z); - } - } - mp_clear(&mu); - - /* calc the M tab, which holds kG for k==8..15 */ - /* M[0] == 8G */ - if (err == MP_OKAY) - err = ecc_projective_dbl_point(tG, M[0], modulus, &mp); - if (err == MP_OKAY) - err = ecc_projective_dbl_point(M[0], M[0], modulus, &mp); - if (err == MP_OKAY) - err = ecc_projective_dbl_point(M[0], M[0], modulus, &mp); - - /* now find (8+k)G for k=1..7 */ - if (err == MP_OKAY) - for (j = 9; j < 16; j++) { - err = ecc_projective_add_point(M[j-9], tG, M[j-8], modulus, &mp); - if (err != MP_OKAY) break; - } - - /* setup sliding window */ - if (err == MP_OKAY) { - mode = 0; - bitcnt = 1; - buf = 0; - digidx = get_digit_count(k) - 1; - bitcpy = bitbuf = 0; - first = 1; - - /* perform ops */ - for (;;) { - /* grab next digit as required */ - if (--bitcnt == 0) { - if (digidx == -1) { - break; - } - buf = get_digit(k, digidx); - bitcnt = (int) DIGIT_BIT; - --digidx; - } - - /* grab the next msb from the ltiplicand */ - i = (int)(buf >> (DIGIT_BIT - 1)) & 1; - buf <<= 1; - - /* skip leading zero bits */ - if (mode == 0 && i == 0) - continue; - - /* if the bit is zero and mode == 1 then we double */ - if (mode == 1 && i == 0) { - err = ecc_projective_dbl_point(R, R, modulus, &mp); - if (err != MP_OKAY) break; - continue; - } - - /* else we add it to the window */ - bitbuf |= (i << (WINSIZE - ++bitcpy)); - mode = 2; - - if (bitcpy == WINSIZE) { - /* if this is the first window we do a simple copy */ - if (first == 1) { - /* R = kG [k = first window] */ - err = mp_copy(&M[bitbuf-8]->x, &R->x); - if (err != MP_OKAY) break; - - err = mp_copy(&M[bitbuf-8]->y, &R->y); - if (err != MP_OKAY) break; - - err = mp_copy(&M[bitbuf-8]->z, &R->z); - first = 0; - } else { - /* normal window */ - /* ok window is filled so double as required and add */ - /* double first */ - for (j = 0; j < WINSIZE; j++) { - err = ecc_projective_dbl_point(R, R, modulus, &mp); - if (err != MP_OKAY) break; - } - if (err != MP_OKAY) break; /* out of first for(;;) */ - - /* then add, bitbuf will be 8..15 [8..2^WINSIZE] guaranted */ - err = ecc_projective_add_point(R,M[bitbuf-8],R,modulus,&mp); - } - if (err != MP_OKAY) break; - /* empty window and reset */ - bitcpy = bitbuf = 0; - mode = 1; - } - } - } - - /* if bits remain then double/add */ - if (err == MP_OKAY) { - if (mode == 2 && bitcpy > 0) { - /* double then add */ - for (j = 0; j < bitcpy; j++) { - /* only double if we have had at least one add first */ - if (first == 0) { - err = ecc_projective_dbl_point(R, R, modulus, &mp); - if (err != MP_OKAY) break; - } - - bitbuf <<= 1; - if ((bitbuf & (1 << WINSIZE)) != 0) { - if (first == 1) { - /* first add, so copy */ - err = mp_copy(&tG->x, &R->x); - if (err != MP_OKAY) break; - - err = mp_copy(&tG->y, &R->y); - if (err != MP_OKAY) break; - - err = mp_copy(&tG->z, &R->z); - if (err != MP_OKAY) break; - first = 0; - } else { - /* then add */ - err = ecc_projective_add_point(R, tG, R, modulus, &mp); - if (err != MP_OKAY) break; - } - } - } - } - } - - /* map R back from projective space */ - if (err == MP_OKAY && map) - err = ecc_map(R, modulus, &mp); - - mp_clear(&mu); - ecc_del_point(tG); - for (i = 0; i < 8; i++) { - ecc_del_point(M[i]); - } - return err; -} - -#undef WINSIZE - -#else /* ECC_TIMING_RESISTANT */ - -/** - Perform a point multiplication (timing resistant) - k The scalar to multiply by - G The base point - R [out] Destination for kG - modulus The modulus of the field the ECC curve is in - map Boolean whether to map back to affine or not - (1==map, 0 == leave in projective) - return MP_OKAY on success -*/ -#ifdef FP_ECC -static int normal_ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, - mp_int* modulus, int map) -#else -static int ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* modulus, - int map) -#endif -{ - ecc_point *tG, *M[3]; - int i, j, err; - mp_int mu; - mp_digit mp; - mp_digit buf; - int first = 1, bitbuf = 0, bitcpy = 0, bitcnt = 0, mode = 0, - digidx = 0; - - if (k == NULL || G == NULL || R == NULL || modulus == NULL) - return ECC_BAD_ARG_E; - - /* init montgomery reduction */ - if ((err = mp_montgomery_setup(modulus, &mp)) != MP_OKAY) { - return err; - } - if ((err = mp_init(&mu)) != MP_OKAY) { - return err; - } - if ((err = mp_montgomery_calc_normalization(&mu, modulus)) != MP_OKAY) { - mp_clear(&mu); - return err; - } - - /* alloc ram for window temps */ - for (i = 0; i < 3; i++) { - M[i] = ecc_new_point(); - if (M[i] == NULL) { - for (j = 0; j < i; j++) { - ecc_del_point(M[j]); - } - mp_clear(&mu); - return MEMORY_E; - } - } - - /* make a copy of G incase R==G */ - tG = ecc_new_point(); - if (tG == NULL) - err = MEMORY_E; - - /* tG = G and convert to montgomery */ - if (err == MP_OKAY) { - err = mp_mulmod(&G->x, &mu, modulus, &tG->x); - if (err == MP_OKAY) - err = mp_mulmod(&G->y, &mu, modulus, &tG->y); - if (err == MP_OKAY) - err = mp_mulmod(&G->z, &mu, modulus, &tG->z); - } - mp_clear(&mu); - - /* calc the M tab */ - /* M[0] == G */ - if (err == MP_OKAY) - err = mp_copy(&tG->x, &M[0]->x); - if (err == MP_OKAY) - err = mp_copy(&tG->y, &M[0]->y); - if (err == MP_OKAY) - err = mp_copy(&tG->z, &M[0]->z); - - /* M[1] == 2G */ - if (err == MP_OKAY) - err = ecc_projective_dbl_point(tG, M[1], modulus, &mp); - - /* setup sliding window */ - mode = 0; - bitcnt = 1; - buf = 0; - digidx = get_digit_count(k) - 1; - bitcpy = bitbuf = 0; - first = 1; - - /* perform ops */ - if (err == MP_OKAY) { - for (;;) { - /* grab next digit as required */ - if (--bitcnt == 0) { - if (digidx == -1) { - break; - } - buf = get_digit(k, digidx); - bitcnt = (int) DIGIT_BIT; - --digidx; - } - - /* grab the next msb from the ltiplicand */ - i = (buf >> (DIGIT_BIT - 1)) & 1; - buf <<= 1; - - if (mode == 0 && i == 0) { - /* dummy operations */ - if (err == MP_OKAY) - err = ecc_projective_add_point(M[0], M[1], M[2], modulus, - &mp); - if (err == MP_OKAY) - err = ecc_projective_dbl_point(M[1], M[2], modulus, &mp); - if (err == MP_OKAY) - continue; - } - - if (mode == 0 && i == 1) { - mode = 1; - /* dummy operations */ - if (err == MP_OKAY) - err = ecc_projective_add_point(M[0], M[1], M[2], modulus, - &mp); - if (err == MP_OKAY) - err = ecc_projective_dbl_point(M[1], M[2], modulus, &mp); - if (err == MP_OKAY) - continue; - } - - if (err == MP_OKAY) - err = ecc_projective_add_point(M[0], M[1], M[i^1], modulus, &mp); - if (err == MP_OKAY) - err = ecc_projective_dbl_point(M[i], M[i], modulus, &mp); - if (err != MP_OKAY) - break; - } /* end for */ - } - - /* copy result out */ - if (err == MP_OKAY) - err = mp_copy(&M[0]->x, &R->x); - if (err == MP_OKAY) - err = mp_copy(&M[0]->y, &R->y); - if (err == MP_OKAY) - err = mp_copy(&M[0]->z, &R->z); - - /* map R back from projective space */ - if (err == MP_OKAY && map) - err = ecc_map(R, modulus, &mp); - - /* done */ - mp_clear(&mu); - ecc_del_point(tG); - for (i = 0; i < 3; i++) { - ecc_del_point(M[i]); - } - return err; -} - -#endif /* ECC_TIMING_RESISTANT */ - - -/** - Allocate a new ECC point - return A newly allocated point or NULL on error -*/ -ecc_point* ecc_new_point(void) -{ - ecc_point* p; - p = (ecc_point*)XMALLOC(sizeof(ecc_point), 0, DYNAMIC_TYPE_BIGINT); - if (p == NULL) { - return NULL; - } - XMEMSET(p, 0, sizeof(ecc_point)); - if (mp_init_multi(&p->x, &p->y, &p->z, NULL, NULL, NULL) != MP_OKAY) { - XFREE(p, 0, DYNAMIC_TYPE_BIGINT); - return NULL; - } - return p; -} - -/** Free an ECC point from memory - p The point to free -*/ -void ecc_del_point(ecc_point* p) -{ - /* prevents free'ing null arguments */ - if (p != NULL) { - mp_clear(&p->x); - mp_clear(&p->y); - mp_clear(&p->z); - XFREE(p, 0, DYNAMIC_TYPE_BIGINT); - } -} - - -/** Returns whether an ECC idx is valid or not - n The idx number to check - return 1 if valid, 0 if not -*/ -static int ecc_is_valid_idx(int n) -{ - int x; - - for (x = 0; ecc_sets[x].size != 0; x++) - ; - /* -1 is a valid index --- indicating that the domain params - were supplied by the user */ - if ((n >= -1) && (n < x)) { - return 1; - } - return 0; -} - - -/** - Create an ECC shared secret between two keys - private_key The private ECC key - public_key The public key - out [out] Destination of the shared secret - Conforms to EC-DH from ANSI X9.63 - outlen [in/out] The max size and resulting size of the shared secret - return MP_OKAY if successful -*/ -int ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out, - word32* outlen) -{ - word32 x = 0; - ecc_point* result; - mp_int prime; - int err; - - if (private_key == NULL || public_key == NULL || out == NULL || - outlen == NULL) - return BAD_FUNC_ARG; - - /* type valid? */ - if (private_key->type != ECC_PRIVATEKEY) { - return ECC_BAD_ARG_E; - } - - if (ecc_is_valid_idx(private_key->idx) == 0 || - ecc_is_valid_idx(public_key->idx) == 0) - return ECC_BAD_ARG_E; - - if (XSTRNCMP(private_key->dp->name, public_key->dp->name, ECC_MAXNAME) != 0) - return ECC_BAD_ARG_E; - - /* make new point */ - result = ecc_new_point(); - if (result == NULL) { - return MEMORY_E; - } - - if ((err = mp_init(&prime)) != MP_OKAY) { - ecc_del_point(result); - return err; - } - - err = mp_read_radix(&prime, (char *)private_key->dp->prime, 16); - - if (err == MP_OKAY) - err = ecc_mulmod(&private_key->k, &public_key->pubkey, result, &prime,1); - - if (err == MP_OKAY) { - x = mp_unsigned_bin_size(&prime); - if (*outlen < x) - err = BUFFER_E; - } - - if (err == MP_OKAY) { - XMEMSET(out, 0, x); - err = mp_to_unsigned_bin(&result->x,out + (x - - mp_unsigned_bin_size(&result->x))); - *outlen = x; - } - - mp_clear(&prime); - ecc_del_point(result); - - return err; -} - - -int ecc_make_key_ex(RNG* rng, ecc_key* key, const ecc_set_type* dp); - -/** - Make a new ECC key - rng An active RNG state - keysize The keysize for the new key (in octets from 20 to 65 bytes) - key [out] Destination of the newly created key - return MP_OKAY if successful, - upon error all allocated memory will be freed -*/ -int ecc_make_key(RNG* rng, int keysize, ecc_key* key) -{ - int x, err; - - if (key == NULL || rng == NULL) - return ECC_BAD_ARG_E; - - /* find key size */ - for (x = 0; (keysize > ecc_sets[x].size) && (ecc_sets[x].size != 0); x++) - ; - keysize = ecc_sets[x].size; - - if (keysize > ECC_MAXSIZE || ecc_sets[x].size == 0) { - return BAD_FUNC_ARG; - } - err = ecc_make_key_ex(rng, key, &ecc_sets[x]); - key->idx = x; - - return err; -} - -int ecc_make_key_ex(RNG* rng, ecc_key* key, const ecc_set_type* dp) -{ - int err; - ecc_point* base; - mp_int prime; - mp_int order; -#ifdef CYASSL_SMALL_STACK - byte* buf; -#else - byte buf[ECC_MAXSIZE]; -#endif - int keysize; - - if (key == NULL || rng == NULL || dp == NULL) - return ECC_BAD_ARG_E; - -#ifdef CYASSL_SMALL_STACK - buf = (byte*)XMALLOC(ECC_MAXSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (buf == NULL) - return MEMORY_E; -#endif - - key->idx = -1; - key->dp = dp; - keysize = dp->size; - - /* allocate ram */ - base = NULL; - - /* make up random string */ - err = RNG_GenerateBlock(rng, buf, keysize); - if (err == 0) - buf[0] |= 0x0c; - - /* setup the key variables */ - if (err == 0) { - err = mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, - &key->k, &prime, &order); - if (err != MP_OKAY) - err = MEMORY_E; - } - - if (err == MP_OKAY) { - base = ecc_new_point(); - if (base == NULL) - err = MEMORY_E; - } - - /* read in the specs for this key */ - if (err == MP_OKAY) - err = mp_read_radix(&prime, (char *)key->dp->prime, 16); - if (err == MP_OKAY) - err = mp_read_radix(&order, (char *)key->dp->order, 16); - if (err == MP_OKAY) - err = mp_read_radix(&base->x, (char *)key->dp->Gx, 16); - if (err == MP_OKAY) - err = mp_read_radix(&base->y, (char *)key->dp->Gy, 16); - - if (err == MP_OKAY) - mp_set(&base->z, 1); - if (err == MP_OKAY) - err = mp_read_unsigned_bin(&key->k, (byte*)buf, keysize); - - /* the key should be smaller than the order of base point */ - if (err == MP_OKAY) { - if (mp_cmp(&key->k, &order) != MP_LT) - err = mp_mod(&key->k, &order, &key->k); - } - /* make the public key */ - if (err == MP_OKAY) - err = ecc_mulmod(&key->k, base, &key->pubkey, &prime, 1); - if (err == MP_OKAY) - key->type = ECC_PRIVATEKEY; - - if (err != MP_OKAY) { - /* clean up */ - mp_clear(&key->pubkey.x); - mp_clear(&key->pubkey.y); - mp_clear(&key->pubkey.z); - mp_clear(&key->k); - } - ecc_del_point(base); - mp_clear(&prime); - mp_clear(&order); - -#ifdef ECC_CLEAN_STACK - XMEMSET(buf, 0, ECC_MAXSIZE); -#endif - -#ifdef CYASSL_SMALL_STACK - XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - - return err; -} - - -/* Setup dynamic pointers is using normal math for proper freeing */ -void ecc_init(ecc_key* key) -{ - (void)key; -#ifndef USE_FAST_MATH - key->pubkey.x.dp = NULL; - key->pubkey.y.dp = NULL; - key->pubkey.z.dp = NULL; - - key->k.dp = NULL; -#endif -} - - -/** - Sign a message digest - in The message digest to sign - inlen The length of the digest - out [out] The destination for the signature - outlen [in/out] The max size and resulting size of the signature - key A private ECC key - return MP_OKAY if successful -*/ -int ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen, - RNG* rng, ecc_key* key) -{ - mp_int r; - mp_int s; - mp_int e; - mp_int p; - int err; - - if (in == NULL || out == NULL || outlen == NULL || key == NULL || rng ==NULL) - return ECC_BAD_ARG_E; - - /* is this a private key? */ - if (key->type != ECC_PRIVATEKEY) { - return ECC_BAD_ARG_E; - } - - /* is the IDX valid ? */ - if (ecc_is_valid_idx(key->idx) != 1) { - return ECC_BAD_ARG_E; - } - - /* get the hash and load it as a bignum into 'e' */ - /* init the bignums */ - if ((err = mp_init_multi(&r, &s, &p, &e, NULL, NULL)) != MP_OKAY) { - return err; - } - err = mp_read_radix(&p, (char *)key->dp->order, 16); - - if (err == MP_OKAY) { - /* we may need to truncate if hash is longer than key size */ - word32 orderBits = mp_count_bits(&p); - - /* truncate down to byte size, may be all that's needed */ - if ( (CYASSL_BIT_SIZE * inlen) > orderBits) - inlen = (orderBits + CYASSL_BIT_SIZE - 1)/CYASSL_BIT_SIZE; - err = mp_read_unsigned_bin(&e, (byte*)in, inlen); - - /* may still need bit truncation too */ - if (err == MP_OKAY && (CYASSL_BIT_SIZE * inlen) > orderBits) - mp_rshb(&e, CYASSL_BIT_SIZE - (orderBits & 0x7)); - } - - /* make up a key and export the public copy */ - if (err == MP_OKAY) { - ecc_key pubkey; - ecc_init(&pubkey); - for (;;) { - err = ecc_make_key_ex(rng, &pubkey, key->dp); - if (err != MP_OKAY) break; - - /* find r = x1 mod n */ - err = mp_mod(&pubkey.pubkey.x, &p, &r); - if (err != MP_OKAY) break; - - if (mp_iszero(&r) == MP_YES) - ecc_free(&pubkey); - else { - /* find s = (e + xr)/k */ - err = mp_invmod(&pubkey.k, &p, &pubkey.k); - if (err != MP_OKAY) break; - - err = mp_mulmod(&key->k, &r, &p, &s); /* s = xr */ - if (err != MP_OKAY) break; - - err = mp_add(&e, &s, &s); /* s = e + xr */ - if (err != MP_OKAY) break; - - err = mp_mod(&s, &p, &s); /* s = e + xr */ - if (err != MP_OKAY) break; - - err = mp_mulmod(&s, &pubkey.k, &p, &s); /* s = (e + xr)/k */ - if (err != MP_OKAY) break; - - ecc_free(&pubkey); - if (mp_iszero(&s) == MP_NO) - break; - } - } - ecc_free(&pubkey); - } - - /* store as SEQUENCE { r, s -- integer } */ - if (err == MP_OKAY) - err = StoreECC_DSA_Sig(out, outlen, &r, &s); - - mp_clear(&r); - mp_clear(&s); - mp_clear(&p); - mp_clear(&e); - - return err; -} - - -/** - Free an ECC key from memory - key The key you wish to free -*/ -void ecc_free(ecc_key* key) -{ - if (key == NULL) - return; - - mp_clear(&key->pubkey.x); - mp_clear(&key->pubkey.y); - mp_clear(&key->pubkey.z); - mp_clear(&key->k); -} - - -#ifdef USE_FAST_MATH - #define GEN_MEM_ERR FP_MEM -#else - #define GEN_MEM_ERR MP_MEM -#endif - -#ifdef ECC_SHAMIR - -/** Computes kA*A + kB*B = C using Shamir's Trick - A First point to multiply - kA What to multiple A by - B Second point to multiply - kB What to multiple B by - C [out] Destination point (can overlap with A or B) - modulus Modulus for curve - return MP_OKAY on success -*/ -#ifdef FP_ECC -static int normal_ecc_mul2add(ecc_point* A, mp_int* kA, - ecc_point* B, mp_int* kB, - ecc_point* C, mp_int* modulus) -#else -static int ecc_mul2add(ecc_point* A, mp_int* kA, - ecc_point* B, mp_int* kB, - ecc_point* C, mp_int* modulus) -#endif -{ - ecc_point* precomp[16]; - unsigned bitbufA, bitbufB, lenA, lenB, len, x, y, nA, nB, nibble; - unsigned char* tA; - unsigned char* tB; - int err = MP_OKAY, first; - int muInit = 0; - int tableInit = 0; - mp_digit mp; - mp_int mu; - - /* argchks */ - if (A == NULL || kA == NULL || B == NULL || kB == NULL || C == NULL || - modulus == NULL) - return ECC_BAD_ARG_E; - - - /* allocate memory */ - tA = (unsigned char*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (tA == NULL) { - return GEN_MEM_ERR; - } - tB = (unsigned char*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (tB == NULL) { - XFREE(tA, NULL, DYNAMIC_TYPE_TMP_BUFFER); - return GEN_MEM_ERR; - } - XMEMSET(tA, 0, ECC_BUFSIZE); - XMEMSET(tB, 0, ECC_BUFSIZE); - - /* get sizes */ - lenA = mp_unsigned_bin_size(kA); - lenB = mp_unsigned_bin_size(kB); - len = MAX(lenA, lenB); - - /* sanity check */ - if ((lenA > ECC_BUFSIZE) || (lenB > ECC_BUFSIZE)) { - err = BAD_FUNC_ARG; - } - - if (err == MP_OKAY) { - /* extract and justify kA */ - err = mp_to_unsigned_bin(kA, (len - lenA) + tA); - - /* extract and justify kB */ - if (err == MP_OKAY) - err = mp_to_unsigned_bin(kB, (len - lenB) + tB); - - /* allocate the table */ - if (err == MP_OKAY) { - for (x = 0; x < 16; x++) { - precomp[x] = ecc_new_point(); - if (precomp[x] == NULL) { - for (y = 0; y < x; ++y) { - ecc_del_point(precomp[y]); - } - err = GEN_MEM_ERR; - break; - } - } - } - } - - if (err == MP_OKAY) - tableInit = 1; - - if (err == MP_OKAY) - /* init montgomery reduction */ - err = mp_montgomery_setup(modulus, &mp); - - if (err == MP_OKAY) - err = mp_init(&mu); - if (err == MP_OKAY) - muInit = 1; - - if (err == MP_OKAY) - err = mp_montgomery_calc_normalization(&mu, modulus); - - if (err == MP_OKAY) - /* copy ones ... */ - err = mp_mulmod(&A->x, &mu, modulus, &precomp[1]->x); - - if (err == MP_OKAY) - err = mp_mulmod(&A->y, &mu, modulus, &precomp[1]->y); - if (err == MP_OKAY) - err = mp_mulmod(&A->z, &mu, modulus, &precomp[1]->z); - - if (err == MP_OKAY) - err = mp_mulmod(&B->x, &mu, modulus, &precomp[1<<2]->x); - if (err == MP_OKAY) - err = mp_mulmod(&B->y, &mu, modulus, &precomp[1<<2]->y); - if (err == MP_OKAY) - err = mp_mulmod(&B->z, &mu, modulus, &precomp[1<<2]->z); - - if (err == MP_OKAY) - /* precomp [i,0](A + B) table */ - err = ecc_projective_dbl_point(precomp[1], precomp[2], modulus, &mp); - - if (err == MP_OKAY) - err = ecc_projective_add_point(precomp[1], precomp[2], precomp[3], - modulus, &mp); - if (err == MP_OKAY) - /* precomp [0,i](A + B) table */ - err = ecc_projective_dbl_point(precomp[1<<2], precomp[2<<2], modulus, &mp); - - if (err == MP_OKAY) - err = ecc_projective_add_point(precomp[1<<2], precomp[2<<2], precomp[3<<2], - modulus, &mp); - - if (err == MP_OKAY) { - /* precomp [i,j](A + B) table (i != 0, j != 0) */ - for (x = 1; x < 4; x++) { - for (y = 1; y < 4; y++) { - if (err == MP_OKAY) - err = ecc_projective_add_point(precomp[x], precomp[(y<<2)], - precomp[x+(y<<2)], modulus, &mp); - } - } - } - - if (err == MP_OKAY) { - nibble = 3; - first = 1; - bitbufA = tA[0]; - bitbufB = tB[0]; - - /* for every byte of the multiplicands */ - for (x = -1;; ) { - /* grab a nibble */ - if (++nibble == 4) { - ++x; if (x == len) break; - bitbufA = tA[x]; - bitbufB = tB[x]; - nibble = 0; - } - - /* extract two bits from both, shift/update */ - nA = (bitbufA >> 6) & 0x03; - nB = (bitbufB >> 6) & 0x03; - bitbufA = (bitbufA << 2) & 0xFF; - bitbufB = (bitbufB << 2) & 0xFF; - - /* if both zero, if first, continue */ - if ((nA == 0) && (nB == 0) && (first == 1)) { - continue; - } - - /* double twice, only if this isn't the first */ - if (first == 0) { - /* double twice */ - if (err == MP_OKAY) - err = ecc_projective_dbl_point(C, C, modulus, &mp); - if (err == MP_OKAY) - err = ecc_projective_dbl_point(C, C, modulus, &mp); - else - break; - } - - /* if not both zero */ - if ((nA != 0) || (nB != 0)) { - if (first == 1) { - /* if first, copy from table */ - first = 0; - if (err == MP_OKAY) - err = mp_copy(&precomp[nA + (nB<<2)]->x, &C->x); - - if (err == MP_OKAY) - err = mp_copy(&precomp[nA + (nB<<2)]->y, &C->y); - - if (err == MP_OKAY) - err = mp_copy(&precomp[nA + (nB<<2)]->z, &C->z); - else - break; - } else { - /* if not first, add from table */ - if (err == MP_OKAY) - err = ecc_projective_add_point(C, precomp[nA + (nB<<2)], C, - modulus, &mp); - else - break; - } - } - } - } - - if (err == MP_OKAY) - /* reduce to affine */ - err = ecc_map(C, modulus, &mp); - - /* clean up */ - if (muInit) - mp_clear(&mu); - - if (tableInit) { - for (x = 0; x < 16; x++) { - ecc_del_point(precomp[x]); - } - } -#ifdef ECC_CLEAN_STACK - XMEMSET(tA, 0, ECC_BUFSIZE); - XMEMSET(tB, 0, ECC_BUFSIZE); -#endif - XFREE(tA, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(tB, NULL, DYNAMIC_TYPE_TMP_BUFFER); - - return err; -} - - -#endif /* ECC_SHAMIR */ - - - -/* verify - * - * w = s^-1 mod n - * u1 = xw - * u2 = rw - * X = u1*G + u2*Q - * v = X_x1 mod n - * accept if v == r - */ - -/** - Verify an ECC signature - sig The signature to verify - siglen The length of the signature (octets) - hash The hash (message digest) that was signed - hashlen The length of the hash (octets) - stat Result of signature, 1==valid, 0==invalid - key The corresponding public ECC key - return MP_OKAY if successful (even if the signature is not valid) -*/ -int ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash, - word32 hashlen, int* stat, ecc_key* key) -{ - ecc_point *mG, *mQ; - mp_int r; - mp_int s; - mp_int v; - mp_int w; - mp_int u1; - mp_int u2; - mp_int e; - mp_int p; - mp_int m; - int err; - - if (sig == NULL || hash == NULL || stat == NULL || key == NULL) - return ECC_BAD_ARG_E; - - /* default to invalid signature */ - *stat = 0; - - /* is the IDX valid ? */ - if (ecc_is_valid_idx(key->idx) != 1) { - return ECC_BAD_ARG_E; - } - - /* allocate ints */ - if ((err = mp_init_multi(&v, &w, &u1, &u2, &p, &e)) != MP_OKAY) { - return MEMORY_E; - } - - if ((err = mp_init(&m)) != MP_OKAY) { - mp_clear(&v); - mp_clear(&w); - mp_clear(&u1); - mp_clear(&u2); - mp_clear(&p); - mp_clear(&e); - return MEMORY_E; - } - - /* allocate points */ - mG = ecc_new_point(); - mQ = ecc_new_point(); - if (mQ == NULL || mG == NULL) - err = MEMORY_E; - - /* Note, DecodeECC_DSA_Sig() calls mp_init() on r and s. - * If either of those don't allocate correctly, none of - * the rest of this function will execute, and everything - * gets cleaned up at the end. */ - XMEMSET(&r, 0, sizeof(r)); - XMEMSET(&s, 0, sizeof(s)); - if (err == MP_OKAY) - err = DecodeECC_DSA_Sig(sig, siglen, &r, &s); - - /* get the order */ - if (err == MP_OKAY) - err = mp_read_radix(&p, (char *)key->dp->order, 16); - - /* get the modulus */ - if (err == MP_OKAY) - err = mp_read_radix(&m, (char *)key->dp->prime, 16); - - /* check for zero */ - if (err == MP_OKAY) { - if (mp_iszero(&r) || mp_iszero(&s) || mp_cmp(&r, &p) != MP_LT || - mp_cmp(&s, &p) != MP_LT) - err = MP_ZERO_E; - } - /* read hash */ - if (err == MP_OKAY) { - /* we may need to truncate if hash is longer than key size */ - unsigned int orderBits = mp_count_bits(&p); - - /* truncate down to byte size, may be all that's needed */ - if ( (CYASSL_BIT_SIZE * hashlen) > orderBits) - hashlen = (orderBits + CYASSL_BIT_SIZE - 1)/CYASSL_BIT_SIZE; - err = mp_read_unsigned_bin(&e, hash, hashlen); - - /* may still need bit truncation too */ - if (err == MP_OKAY && (CYASSL_BIT_SIZE * hashlen) > orderBits) - mp_rshb(&e, CYASSL_BIT_SIZE - (orderBits & 0x7)); - } - - /* w = s^-1 mod n */ - if (err == MP_OKAY) - err = mp_invmod(&s, &p, &w); - - /* u1 = ew */ - if (err == MP_OKAY) - err = mp_mulmod(&e, &w, &p, &u1); - - /* u2 = rw */ - if (err == MP_OKAY) - err = mp_mulmod(&r, &w, &p, &u2); - - /* find mG and mQ */ - if (err == MP_OKAY) - err = mp_read_radix(&mG->x, (char *)key->dp->Gx, 16); - - if (err == MP_OKAY) - err = mp_read_radix(&mG->y, (char *)key->dp->Gy, 16); - if (err == MP_OKAY) - mp_set(&mG->z, 1); - - if (err == MP_OKAY) - err = mp_copy(&key->pubkey.x, &mQ->x); - if (err == MP_OKAY) - err = mp_copy(&key->pubkey.y, &mQ->y); - if (err == MP_OKAY) - err = mp_copy(&key->pubkey.z, &mQ->z); - -#ifndef ECC_SHAMIR - { - mp_digit mp; - - /* compute u1*mG + u2*mQ = mG */ - if (err == MP_OKAY) - err = ecc_mulmod(&u1, mG, mG, &m, 0); - if (err == MP_OKAY) - err = ecc_mulmod(&u2, mQ, mQ, &m, 0); - - /* find the montgomery mp */ - if (err == MP_OKAY) - err = mp_montgomery_setup(&m, &mp); - - /* add them */ - if (err == MP_OKAY) - err = ecc_projective_add_point(mQ, mG, mG, &m, &mp); - - /* reduce */ - if (err == MP_OKAY) - err = ecc_map(mG, &m, &mp); - } -#else - /* use Shamir's trick to compute u1*mG + u2*mQ using half the doubles */ - if (err == MP_OKAY) - err = ecc_mul2add(mG, &u1, mQ, &u2, mG, &m); -#endif /* ECC_SHAMIR */ - - /* v = X_x1 mod n */ - if (err == MP_OKAY) - err = mp_mod(&mG->x, &p, &v); - - /* does v == r */ - if (err == MP_OKAY) { - if (mp_cmp(&v, &r) == MP_EQ) - *stat = 1; - } - - ecc_del_point(mG); - ecc_del_point(mQ); - - mp_clear(&r); - mp_clear(&s); - mp_clear(&v); - mp_clear(&w); - mp_clear(&u1); - mp_clear(&u2); - mp_clear(&p); - mp_clear(&e); - mp_clear(&m); - - return err; -} - - -/* export public ECC key in ANSI X9.63 format */ -int ecc_export_x963(ecc_key* key, byte* out, word32* outLen) -{ -#ifdef CYASSL_SMALL_STACK - byte* buf; -#else - byte buf[ECC_BUFSIZE]; -#endif - word32 numlen; - int ret = MP_OKAY; - - /* return length needed only */ - if (key != NULL && out == NULL && outLen != NULL) { - numlen = key->dp->size; - *outLen = 1 + 2*numlen; - return LENGTH_ONLY_E; - } - - if (key == NULL || out == NULL || outLen == NULL) - return ECC_BAD_ARG_E; - - if (ecc_is_valid_idx(key->idx) == 0) { - return ECC_BAD_ARG_E; - } - numlen = key->dp->size; - - if (*outLen < (1 + 2*numlen)) { - *outLen = 1 + 2*numlen; - return BUFFER_E; - } - - /* store byte 0x04 */ - out[0] = 0x04; - -#ifdef CYASSL_SMALL_STACK - buf = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (buf == NULL) - return MEMORY_E; -#endif - - do { - /* pad and store x */ - XMEMSET(buf, 0, ECC_BUFSIZE); - ret = mp_to_unsigned_bin(&key->pubkey.x, - buf + (numlen - mp_unsigned_bin_size(&key->pubkey.x))); - if (ret != MP_OKAY) - break; - XMEMCPY(out+1, buf, numlen); - - /* pad and store y */ - XMEMSET(buf, 0, ECC_BUFSIZE); - ret = mp_to_unsigned_bin(&key->pubkey.y, - buf + (numlen - mp_unsigned_bin_size(&key->pubkey.y))); - if (ret != MP_OKAY) - break; - XMEMCPY(out+1+numlen, buf, numlen); - - *outLen = 1 + 2*numlen; - } while (0); - -#ifdef CYASSL_SMALL_STACK - XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - - return ret; -} - - -/* export public ECC key in ANSI X9.63 format, extended with - * compression option */ -int ecc_export_x963_ex(ecc_key* key, byte* out, word32* outLen, int compressed) -{ - if (compressed == 0) - return ecc_export_x963(key, out, outLen); -#ifdef HAVE_COMP_KEY - else - return ecc_export_x963_compressed(key, out, outLen); -#endif - - return NOT_COMPILED_IN; -} - - -/* import public ECC key in ANSI X9.63 format */ -int ecc_import_x963(const byte* in, word32 inLen, ecc_key* key) -{ - int x, err; - int compressed = 0; - - if (in == NULL || key == NULL) - return ECC_BAD_ARG_E; - - /* must be odd */ - if ((inLen & 1) == 0) { - return ECC_BAD_ARG_E; - } - - /* init key */ - if (mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, - NULL, NULL) != MP_OKAY) { - return MEMORY_E; - } - err = MP_OKAY; - - /* check for 4, 2, or 3 */ - if (in[0] != 0x04 && in[0] != 0x02 && in[0] != 0x03) { - err = ASN_PARSE_E; - } - - if (in[0] == 0x02 || in[0] == 0x03) { -#ifdef HAVE_COMP_KEY - compressed = 1; -#else - err = NOT_COMPILED_IN; -#endif - } - - if (err == MP_OKAY) { - /* determine the idx */ - - if (compressed) - inLen = (inLen-1)*2 + 1; /* used uncompressed len */ - - for (x = 0; ecc_sets[x].size != 0; x++) { - if ((unsigned)ecc_sets[x].size >= ((inLen-1)>>1)) { - break; - } - } - if (ecc_sets[x].size == 0) { - err = ASN_PARSE_E; - } else { - /* set the idx */ - key->idx = x; - key->dp = &ecc_sets[x]; - key->type = ECC_PUBLICKEY; - } - } - - /* read data */ - if (err == MP_OKAY) - err = mp_read_unsigned_bin(&key->pubkey.x, (byte*)in+1, (inLen-1)>>1); - -#ifdef HAVE_COMP_KEY - if (err == MP_OKAY && compressed == 1) { /* build y */ - mp_int t1, t2, prime, a, b; - - if (mp_init_multi(&t1, &t2, &prime, &a, &b, NULL) != MP_OKAY) - err = MEMORY_E; - - /* load prime */ - if (err == MP_OKAY) - err = mp_read_radix(&prime, (char *)key->dp->prime, 16); - - /* load a */ - if (err == MP_OKAY) - err = mp_read_radix(&a, (char *)key->dp->Af, 16); - - /* load b */ - if (err == MP_OKAY) - err = mp_read_radix(&b, (char *)key->dp->Bf, 16); - - /* compute x^3 */ - if (err == MP_OKAY) - err = mp_sqr(&key->pubkey.x, &t1); - - if (err == MP_OKAY) - err = mp_mulmod(&t1, &key->pubkey.x, &prime, &t1); - - /* compute x^3 + a*x */ - if (err == MP_OKAY) - err = mp_mulmod(&a, &key->pubkey.x, &prime, &t2); - - if (err == MP_OKAY) - err = mp_add(&t1, &t2, &t1); - - /* compute x^3 + a*x + b */ - if (err == MP_OKAY) - err = mp_add(&t1, &b, &t1); - - /* compute sqrt(x^3 + a*x + b) */ - if (err == MP_OKAY) - err = mp_sqrtmod_prime(&t1, &prime, &t2); - - /* adjust y */ - if (err == MP_OKAY) { - if ((mp_isodd(&t2) && in[0] == 0x03) || - (!mp_isodd(&t2) && in[0] == 0x02)) { - err = mp_mod(&t2, &prime, &key->pubkey.y); - } - else { - err = mp_submod(&prime, &t2, &prime, &key->pubkey.y); - } - } - - mp_clear(&a); - mp_clear(&b); - mp_clear(&prime); - mp_clear(&t2); - mp_clear(&t1); - } -#endif - - if (err == MP_OKAY && compressed == 0) - err = mp_read_unsigned_bin(&key->pubkey.y, (byte*)in+1+((inLen-1)>>1), - (inLen-1)>>1); - if (err == MP_OKAY) - mp_set(&key->pubkey.z, 1); - - if (err != MP_OKAY) { - mp_clear(&key->pubkey.x); - mp_clear(&key->pubkey.y); - mp_clear(&key->pubkey.z); - mp_clear(&key->k); - } - - return err; -} - - -/* export ecc private key only raw, outLen is in/out size - return MP_OKAY on success */ -int ecc_export_private_only(ecc_key* key, byte* out, word32* outLen) -{ - word32 numlen; - - if (key == NULL || out == NULL || outLen == NULL) - return ECC_BAD_ARG_E; - - if (ecc_is_valid_idx(key->idx) == 0) { - return ECC_BAD_ARG_E; - } - numlen = key->dp->size; - - if (*outLen < numlen) { - *outLen = numlen; - return BUFFER_E; - } - *outLen = numlen; - XMEMSET(out, 0, *outLen); - return mp_to_unsigned_bin(&key->k, out + (numlen - - mp_unsigned_bin_size(&key->k))); -} - - -/* ecc private key import, public key in ANSI X9.63 format, private raw */ -int ecc_import_private_key(const byte* priv, word32 privSz, const byte* pub, - word32 pubSz, ecc_key* key) -{ - int ret = ecc_import_x963(pub, pubSz, key); - if (ret != 0) - return ret; - - key->type = ECC_PRIVATEKEY; - - return mp_read_unsigned_bin(&key->k, priv, privSz); -} - -/** - Convert ECC R,S to signature - r R component of signature - s S component of signature - out DER-encoded ECDSA signature - outlen [in/out] output buffer size, output signature size - return MP_OKAY on success -*/ -int ecc_rs_to_sig(const char* r, const char* s, byte* out, word32* outlen) -{ - int err; - mp_int rtmp; - mp_int stmp; - - if (r == NULL || s == NULL || out == NULL || outlen == NULL) - return ECC_BAD_ARG_E; - - err = mp_init_multi(&rtmp, &stmp, NULL, NULL, NULL, NULL); - if (err != MP_OKAY) - return err; - - err = mp_read_radix(&rtmp, r, 16); - if (err == MP_OKAY) - err = mp_read_radix(&stmp, s, 16); - - /* convert mp_ints to ECDSA sig, initializes rtmp and stmp internally */ - if (err == MP_OKAY) - err = StoreECC_DSA_Sig(out, outlen, &rtmp, &stmp); - - if (err == MP_OKAY) { - if (mp_iszero(&rtmp) || mp_iszero(&stmp)) - err = MP_ZERO_E; - } - - mp_clear(&rtmp); - mp_clear(&stmp); - - return err; -} - -/** - Import raw ECC key - key The destination ecc_key structure - qx x component of base point, as ASCII hex string - qy y component of base point, as ASCII hex string - d private key, as ASCII hex string - curveName ECC curve name, from ecc_sets[] - return MP_OKAY on success -*/ -int ecc_import_raw(ecc_key* key, const char* qx, const char* qy, - const char* d, const char* curveName) -{ - int err, x; - - if (key == NULL || qx == NULL || qy == NULL || d == NULL || - curveName == NULL) - return ECC_BAD_ARG_E; - - /* init key */ - if (mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, - NULL, NULL) != MP_OKAY) { - return MEMORY_E; - } - err = MP_OKAY; - - /* read Qx */ - if (err == MP_OKAY) - err = mp_read_radix(&key->pubkey.x, qx, 16); - - /* read Qy */ - if (err == MP_OKAY) - err = mp_read_radix(&key->pubkey.y, qy, 16); - - if (err == MP_OKAY) - mp_set(&key->pubkey.z, 1); - - /* read and set the curve */ - if (err == MP_OKAY) { - for (x = 0; ecc_sets[x].size != 0; x++) { - if (XSTRNCMP(ecc_sets[x].name, curveName, - XSTRLEN(curveName)) == 0) { - break; - } - } - if (ecc_sets[x].size == 0) { - err = ASN_PARSE_E; - } else { - /* set the curve */ - key->idx = x; - key->dp = &ecc_sets[x]; - key->type = ECC_PUBLICKEY; - } - } - - /* import private key */ - if (err == MP_OKAY) { - key->type = ECC_PRIVATEKEY; - err = mp_read_radix(&key->k, d, 16); - } - - if (err != MP_OKAY) { - mp_clear(&key->pubkey.x); - mp_clear(&key->pubkey.y); - mp_clear(&key->pubkey.z); - mp_clear(&key->k); - } - - return err; -} - - -/* key size in octets */ -int ecc_size(ecc_key* key) -{ - if (key == NULL) return 0; - - return key->dp->size; -} - - -/* worst case estimate, check actual return from ecc_sign_hash for actual value - of signature size in octets */ -int ecc_sig_size(ecc_key* key) -{ - int sz = ecc_size(key); - if (sz < 0) - return sz; - - return sz * 2 + SIG_HEADER_SZ + 4; /* (4) worst case estimate */ -} - - -#ifdef FP_ECC - -/* fixed point ECC cache */ -/* number of entries in the cache */ -#ifndef FP_ENTRIES - #define FP_ENTRIES 16 -#endif - -/* number of bits in LUT */ -#ifndef FP_LUT - #define FP_LUT 8U -#endif - -#ifdef ECC_SHAMIR - /* Sharmir requires a bigger LUT, TAO */ - #if (FP_LUT > 12) || (FP_LUT < 4) - #error FP_LUT must be between 4 and 12 inclusively - #endif -#else - #if (FP_LUT > 12) || (FP_LUT < 2) - #error FP_LUT must be between 2 and 12 inclusively - #endif -#endif - - -/** Our FP cache */ -typedef struct { - ecc_point* g; /* cached COPY of base point */ - ecc_point* LUT[1U< 6 - { 1, 0, 0 }, { 2, 1, 64 }, { 2, 2, 64 }, { 3, 3, 64 }, { 2, 4, 64 }, { 3, 5, 64 }, { 3, 6, 64 }, { 4, 7, 64 }, - { 2, 8, 64 }, { 3, 9, 64 }, { 3, 10, 64 }, { 4, 11, 64 }, { 3, 12, 64 }, { 4, 13, 64 }, { 4, 14, 64 }, { 5, 15, 64 }, - { 2, 16, 64 }, { 3, 17, 64 }, { 3, 18, 64 }, { 4, 19, 64 }, { 3, 20, 64 }, { 4, 21, 64 }, { 4, 22, 64 }, { 5, 23, 64 }, - { 3, 24, 64 }, { 4, 25, 64 }, { 4, 26, 64 }, { 5, 27, 64 }, { 4, 28, 64 }, { 5, 29, 64 }, { 5, 30, 64 }, { 6, 31, 64 }, - { 2, 32, 64 }, { 3, 33, 64 }, { 3, 34, 64 }, { 4, 35, 64 }, { 3, 36, 64 }, { 4, 37, 64 }, { 4, 38, 64 }, { 5, 39, 64 }, - { 3, 40, 64 }, { 4, 41, 64 }, { 4, 42, 64 }, { 5, 43, 64 }, { 4, 44, 64 }, { 5, 45, 64 }, { 5, 46, 64 }, { 6, 47, 64 }, - { 3, 48, 64 }, { 4, 49, 64 }, { 4, 50, 64 }, { 5, 51, 64 }, { 4, 52, 64 }, { 5, 53, 64 }, { 5, 54, 64 }, { 6, 55, 64 }, - { 4, 56, 64 }, { 5, 57, 64 }, { 5, 58, 64 }, { 6, 59, 64 }, { 5, 60, 64 }, { 6, 61, 64 }, { 6, 62, 64 }, { 7, 63, 64 }, -#if FP_LUT > 7 - { 1, 0, 0 }, { 2, 1, 128 }, { 2, 2, 128 }, { 3, 3, 128 }, { 2, 4, 128 }, { 3, 5, 128 }, { 3, 6, 128 }, { 4, 7, 128 }, - { 2, 8, 128 }, { 3, 9, 128 }, { 3, 10, 128 }, { 4, 11, 128 }, { 3, 12, 128 }, { 4, 13, 128 }, { 4, 14, 128 }, { 5, 15, 128 }, - { 2, 16, 128 }, { 3, 17, 128 }, { 3, 18, 128 }, { 4, 19, 128 }, { 3, 20, 128 }, { 4, 21, 128 }, { 4, 22, 128 }, { 5, 23, 128 }, - { 3, 24, 128 }, { 4, 25, 128 }, { 4, 26, 128 }, { 5, 27, 128 }, { 4, 28, 128 }, { 5, 29, 128 }, { 5, 30, 128 }, { 6, 31, 128 }, - { 2, 32, 128 }, { 3, 33, 128 }, { 3, 34, 128 }, { 4, 35, 128 }, { 3, 36, 128 }, { 4, 37, 128 }, { 4, 38, 128 }, { 5, 39, 128 }, - { 3, 40, 128 }, { 4, 41, 128 }, { 4, 42, 128 }, { 5, 43, 128 }, { 4, 44, 128 }, { 5, 45, 128 }, { 5, 46, 128 }, { 6, 47, 128 }, - { 3, 48, 128 }, { 4, 49, 128 }, { 4, 50, 128 }, { 5, 51, 128 }, { 4, 52, 128 }, { 5, 53, 128 }, { 5, 54, 128 }, { 6, 55, 128 }, - { 4, 56, 128 }, { 5, 57, 128 }, { 5, 58, 128 }, { 6, 59, 128 }, { 5, 60, 128 }, { 6, 61, 128 }, { 6, 62, 128 }, { 7, 63, 128 }, - { 2, 64, 128 }, { 3, 65, 128 }, { 3, 66, 128 }, { 4, 67, 128 }, { 3, 68, 128 }, { 4, 69, 128 }, { 4, 70, 128 }, { 5, 71, 128 }, - { 3, 72, 128 }, { 4, 73, 128 }, { 4, 74, 128 }, { 5, 75, 128 }, { 4, 76, 128 }, { 5, 77, 128 }, { 5, 78, 128 }, { 6, 79, 128 }, - { 3, 80, 128 }, { 4, 81, 128 }, { 4, 82, 128 }, { 5, 83, 128 }, { 4, 84, 128 }, { 5, 85, 128 }, { 5, 86, 128 }, { 6, 87, 128 }, - { 4, 88, 128 }, { 5, 89, 128 }, { 5, 90, 128 }, { 6, 91, 128 }, { 5, 92, 128 }, { 6, 93, 128 }, { 6, 94, 128 }, { 7, 95, 128 }, - { 3, 96, 128 }, { 4, 97, 128 }, { 4, 98, 128 }, { 5, 99, 128 }, { 4, 100, 128 }, { 5, 101, 128 }, { 5, 102, 128 }, { 6, 103, 128 }, - { 4, 104, 128 }, { 5, 105, 128 }, { 5, 106, 128 }, { 6, 107, 128 }, { 5, 108, 128 }, { 6, 109, 128 }, { 6, 110, 128 }, { 7, 111, 128 }, - { 4, 112, 128 }, { 5, 113, 128 }, { 5, 114, 128 }, { 6, 115, 128 }, { 5, 116, 128 }, { 6, 117, 128 }, { 6, 118, 128 }, { 7, 119, 128 }, - { 5, 120, 128 }, { 6, 121, 128 }, { 6, 122, 128 }, { 7, 123, 128 }, { 6, 124, 128 }, { 7, 125, 128 }, { 7, 126, 128 }, { 8, 127, 128 }, -#if FP_LUT > 8 - { 1, 0, 0 }, { 2, 1, 256 }, { 2, 2, 256 }, { 3, 3, 256 }, { 2, 4, 256 }, { 3, 5, 256 }, { 3, 6, 256 }, { 4, 7, 256 }, - { 2, 8, 256 }, { 3, 9, 256 }, { 3, 10, 256 }, { 4, 11, 256 }, { 3, 12, 256 }, { 4, 13, 256 }, { 4, 14, 256 }, { 5, 15, 256 }, - { 2, 16, 256 }, { 3, 17, 256 }, { 3, 18, 256 }, { 4, 19, 256 }, { 3, 20, 256 }, { 4, 21, 256 }, { 4, 22, 256 }, { 5, 23, 256 }, - { 3, 24, 256 }, { 4, 25, 256 }, { 4, 26, 256 }, { 5, 27, 256 }, { 4, 28, 256 }, { 5, 29, 256 }, { 5, 30, 256 }, { 6, 31, 256 }, - { 2, 32, 256 }, { 3, 33, 256 }, { 3, 34, 256 }, { 4, 35, 256 }, { 3, 36, 256 }, { 4, 37, 256 }, { 4, 38, 256 }, { 5, 39, 256 }, - { 3, 40, 256 }, { 4, 41, 256 }, { 4, 42, 256 }, { 5, 43, 256 }, { 4, 44, 256 }, { 5, 45, 256 }, { 5, 46, 256 }, { 6, 47, 256 }, - { 3, 48, 256 }, { 4, 49, 256 }, { 4, 50, 256 }, { 5, 51, 256 }, { 4, 52, 256 }, { 5, 53, 256 }, { 5, 54, 256 }, { 6, 55, 256 }, - { 4, 56, 256 }, { 5, 57, 256 }, { 5, 58, 256 }, { 6, 59, 256 }, { 5, 60, 256 }, { 6, 61, 256 }, { 6, 62, 256 }, { 7, 63, 256 }, - { 2, 64, 256 }, { 3, 65, 256 }, { 3, 66, 256 }, { 4, 67, 256 }, { 3, 68, 256 }, { 4, 69, 256 }, { 4, 70, 256 }, { 5, 71, 256 }, - { 3, 72, 256 }, { 4, 73, 256 }, { 4, 74, 256 }, { 5, 75, 256 }, { 4, 76, 256 }, { 5, 77, 256 }, { 5, 78, 256 }, { 6, 79, 256 }, - { 3, 80, 256 }, { 4, 81, 256 }, { 4, 82, 256 }, { 5, 83, 256 }, { 4, 84, 256 }, { 5, 85, 256 }, { 5, 86, 256 }, { 6, 87, 256 }, - { 4, 88, 256 }, { 5, 89, 256 }, { 5, 90, 256 }, { 6, 91, 256 }, { 5, 92, 256 }, { 6, 93, 256 }, { 6, 94, 256 }, { 7, 95, 256 }, - { 3, 96, 256 }, { 4, 97, 256 }, { 4, 98, 256 }, { 5, 99, 256 }, { 4, 100, 256 }, { 5, 101, 256 }, { 5, 102, 256 }, { 6, 103, 256 }, - { 4, 104, 256 }, { 5, 105, 256 }, { 5, 106, 256 }, { 6, 107, 256 }, { 5, 108, 256 }, { 6, 109, 256 }, { 6, 110, 256 }, { 7, 111, 256 }, - { 4, 112, 256 }, { 5, 113, 256 }, { 5, 114, 256 }, { 6, 115, 256 }, { 5, 116, 256 }, { 6, 117, 256 }, { 6, 118, 256 }, { 7, 119, 256 }, - { 5, 120, 256 }, { 6, 121, 256 }, { 6, 122, 256 }, { 7, 123, 256 }, { 6, 124, 256 }, { 7, 125, 256 }, { 7, 126, 256 }, { 8, 127, 256 }, - { 2, 128, 256 }, { 3, 129, 256 }, { 3, 130, 256 }, { 4, 131, 256 }, { 3, 132, 256 }, { 4, 133, 256 }, { 4, 134, 256 }, { 5, 135, 256 }, - { 3, 136, 256 }, { 4, 137, 256 }, { 4, 138, 256 }, { 5, 139, 256 }, { 4, 140, 256 }, { 5, 141, 256 }, { 5, 142, 256 }, { 6, 143, 256 }, - { 3, 144, 256 }, { 4, 145, 256 }, { 4, 146, 256 }, { 5, 147, 256 }, { 4, 148, 256 }, { 5, 149, 256 }, { 5, 150, 256 }, { 6, 151, 256 }, - { 4, 152, 256 }, { 5, 153, 256 }, { 5, 154, 256 }, { 6, 155, 256 }, { 5, 156, 256 }, { 6, 157, 256 }, { 6, 158, 256 }, { 7, 159, 256 }, - { 3, 160, 256 }, { 4, 161, 256 }, { 4, 162, 256 }, { 5, 163, 256 }, { 4, 164, 256 }, { 5, 165, 256 }, { 5, 166, 256 }, { 6, 167, 256 }, - { 4, 168, 256 }, { 5, 169, 256 }, { 5, 170, 256 }, { 6, 171, 256 }, { 5, 172, 256 }, { 6, 173, 256 }, { 6, 174, 256 }, { 7, 175, 256 }, - { 4, 176, 256 }, { 5, 177, 256 }, { 5, 178, 256 }, { 6, 179, 256 }, { 5, 180, 256 }, { 6, 181, 256 }, { 6, 182, 256 }, { 7, 183, 256 }, - { 5, 184, 256 }, { 6, 185, 256 }, { 6, 186, 256 }, { 7, 187, 256 }, { 6, 188, 256 }, { 7, 189, 256 }, { 7, 190, 256 }, { 8, 191, 256 }, - { 3, 192, 256 }, { 4, 193, 256 }, { 4, 194, 256 }, { 5, 195, 256 }, { 4, 196, 256 }, { 5, 197, 256 }, { 5, 198, 256 }, { 6, 199, 256 }, - { 4, 200, 256 }, { 5, 201, 256 }, { 5, 202, 256 }, { 6, 203, 256 }, { 5, 204, 256 }, { 6, 205, 256 }, { 6, 206, 256 }, { 7, 207, 256 }, - { 4, 208, 256 }, { 5, 209, 256 }, { 5, 210, 256 }, { 6, 211, 256 }, { 5, 212, 256 }, { 6, 213, 256 }, { 6, 214, 256 }, { 7, 215, 256 }, - { 5, 216, 256 }, { 6, 217, 256 }, { 6, 218, 256 }, { 7, 219, 256 }, { 6, 220, 256 }, { 7, 221, 256 }, { 7, 222, 256 }, { 8, 223, 256 }, - { 4, 224, 256 }, { 5, 225, 256 }, { 5, 226, 256 }, { 6, 227, 256 }, { 5, 228, 256 }, { 6, 229, 256 }, { 6, 230, 256 }, { 7, 231, 256 }, - { 5, 232, 256 }, { 6, 233, 256 }, { 6, 234, 256 }, { 7, 235, 256 }, { 6, 236, 256 }, { 7, 237, 256 }, { 7, 238, 256 }, { 8, 239, 256 }, - { 5, 240, 256 }, { 6, 241, 256 }, { 6, 242, 256 }, { 7, 243, 256 }, { 6, 244, 256 }, { 7, 245, 256 }, { 7, 246, 256 }, { 8, 247, 256 }, - { 6, 248, 256 }, { 7, 249, 256 }, { 7, 250, 256 }, { 8, 251, 256 }, { 7, 252, 256 }, { 8, 253, 256 }, { 8, 254, 256 }, { 9, 255, 256 }, -#if FP_LUT > 9 - { 1, 0, 0 }, { 2, 1, 512 }, { 2, 2, 512 }, { 3, 3, 512 }, { 2, 4, 512 }, { 3, 5, 512 }, { 3, 6, 512 }, { 4, 7, 512 }, - { 2, 8, 512 }, { 3, 9, 512 }, { 3, 10, 512 }, { 4, 11, 512 }, { 3, 12, 512 }, { 4, 13, 512 }, { 4, 14, 512 }, { 5, 15, 512 }, - { 2, 16, 512 }, { 3, 17, 512 }, { 3, 18, 512 }, { 4, 19, 512 }, { 3, 20, 512 }, { 4, 21, 512 }, { 4, 22, 512 }, { 5, 23, 512 }, - { 3, 24, 512 }, { 4, 25, 512 }, { 4, 26, 512 }, { 5, 27, 512 }, { 4, 28, 512 }, { 5, 29, 512 }, { 5, 30, 512 }, { 6, 31, 512 }, - { 2, 32, 512 }, { 3, 33, 512 }, { 3, 34, 512 }, { 4, 35, 512 }, { 3, 36, 512 }, { 4, 37, 512 }, { 4, 38, 512 }, { 5, 39, 512 }, - { 3, 40, 512 }, { 4, 41, 512 }, { 4, 42, 512 }, { 5, 43, 512 }, { 4, 44, 512 }, { 5, 45, 512 }, { 5, 46, 512 }, { 6, 47, 512 }, - { 3, 48, 512 }, { 4, 49, 512 }, { 4, 50, 512 }, { 5, 51, 512 }, { 4, 52, 512 }, { 5, 53, 512 }, { 5, 54, 512 }, { 6, 55, 512 }, - { 4, 56, 512 }, { 5, 57, 512 }, { 5, 58, 512 }, { 6, 59, 512 }, { 5, 60, 512 }, { 6, 61, 512 }, { 6, 62, 512 }, { 7, 63, 512 }, - { 2, 64, 512 }, { 3, 65, 512 }, { 3, 66, 512 }, { 4, 67, 512 }, { 3, 68, 512 }, { 4, 69, 512 }, { 4, 70, 512 }, { 5, 71, 512 }, - { 3, 72, 512 }, { 4, 73, 512 }, { 4, 74, 512 }, { 5, 75, 512 }, { 4, 76, 512 }, { 5, 77, 512 }, { 5, 78, 512 }, { 6, 79, 512 }, - { 3, 80, 512 }, { 4, 81, 512 }, { 4, 82, 512 }, { 5, 83, 512 }, { 4, 84, 512 }, { 5, 85, 512 }, { 5, 86, 512 }, { 6, 87, 512 }, - { 4, 88, 512 }, { 5, 89, 512 }, { 5, 90, 512 }, { 6, 91, 512 }, { 5, 92, 512 }, { 6, 93, 512 }, { 6, 94, 512 }, { 7, 95, 512 }, - { 3, 96, 512 }, { 4, 97, 512 }, { 4, 98, 512 }, { 5, 99, 512 }, { 4, 100, 512 }, { 5, 101, 512 }, { 5, 102, 512 }, { 6, 103, 512 }, - { 4, 104, 512 }, { 5, 105, 512 }, { 5, 106, 512 }, { 6, 107, 512 }, { 5, 108, 512 }, { 6, 109, 512 }, { 6, 110, 512 }, { 7, 111, 512 }, - { 4, 112, 512 }, { 5, 113, 512 }, { 5, 114, 512 }, { 6, 115, 512 }, { 5, 116, 512 }, { 6, 117, 512 }, { 6, 118, 512 }, { 7, 119, 512 }, - { 5, 120, 512 }, { 6, 121, 512 }, { 6, 122, 512 }, { 7, 123, 512 }, { 6, 124, 512 }, { 7, 125, 512 }, { 7, 126, 512 }, { 8, 127, 512 }, - { 2, 128, 512 }, { 3, 129, 512 }, { 3, 130, 512 }, { 4, 131, 512 }, { 3, 132, 512 }, { 4, 133, 512 }, { 4, 134, 512 }, { 5, 135, 512 }, - { 3, 136, 512 }, { 4, 137, 512 }, { 4, 138, 512 }, { 5, 139, 512 }, { 4, 140, 512 }, { 5, 141, 512 }, { 5, 142, 512 }, { 6, 143, 512 }, - { 3, 144, 512 }, { 4, 145, 512 }, { 4, 146, 512 }, { 5, 147, 512 }, { 4, 148, 512 }, { 5, 149, 512 }, { 5, 150, 512 }, { 6, 151, 512 }, - { 4, 152, 512 }, { 5, 153, 512 }, { 5, 154, 512 }, { 6, 155, 512 }, { 5, 156, 512 }, { 6, 157, 512 }, { 6, 158, 512 }, { 7, 159, 512 }, - { 3, 160, 512 }, { 4, 161, 512 }, { 4, 162, 512 }, { 5, 163, 512 }, { 4, 164, 512 }, { 5, 165, 512 }, { 5, 166, 512 }, { 6, 167, 512 }, - { 4, 168, 512 }, { 5, 169, 512 }, { 5, 170, 512 }, { 6, 171, 512 }, { 5, 172, 512 }, { 6, 173, 512 }, { 6, 174, 512 }, { 7, 175, 512 }, - { 4, 176, 512 }, { 5, 177, 512 }, { 5, 178, 512 }, { 6, 179, 512 }, { 5, 180, 512 }, { 6, 181, 512 }, { 6, 182, 512 }, { 7, 183, 512 }, - { 5, 184, 512 }, { 6, 185, 512 }, { 6, 186, 512 }, { 7, 187, 512 }, { 6, 188, 512 }, { 7, 189, 512 }, { 7, 190, 512 }, { 8, 191, 512 }, - { 3, 192, 512 }, { 4, 193, 512 }, { 4, 194, 512 }, { 5, 195, 512 }, { 4, 196, 512 }, { 5, 197, 512 }, { 5, 198, 512 }, { 6, 199, 512 }, - { 4, 200, 512 }, { 5, 201, 512 }, { 5, 202, 512 }, { 6, 203, 512 }, { 5, 204, 512 }, { 6, 205, 512 }, { 6, 206, 512 }, { 7, 207, 512 }, - { 4, 208, 512 }, { 5, 209, 512 }, { 5, 210, 512 }, { 6, 211, 512 }, { 5, 212, 512 }, { 6, 213, 512 }, { 6, 214, 512 }, { 7, 215, 512 }, - { 5, 216, 512 }, { 6, 217, 512 }, { 6, 218, 512 }, { 7, 219, 512 }, { 6, 220, 512 }, { 7, 221, 512 }, { 7, 222, 512 }, { 8, 223, 512 }, - { 4, 224, 512 }, { 5, 225, 512 }, { 5, 226, 512 }, { 6, 227, 512 }, { 5, 228, 512 }, { 6, 229, 512 }, { 6, 230, 512 }, { 7, 231, 512 }, - { 5, 232, 512 }, { 6, 233, 512 }, { 6, 234, 512 }, { 7, 235, 512 }, { 6, 236, 512 }, { 7, 237, 512 }, { 7, 238, 512 }, { 8, 239, 512 }, - { 5, 240, 512 }, { 6, 241, 512 }, { 6, 242, 512 }, { 7, 243, 512 }, { 6, 244, 512 }, { 7, 245, 512 }, { 7, 246, 512 }, { 8, 247, 512 }, - { 6, 248, 512 }, { 7, 249, 512 }, { 7, 250, 512 }, { 8, 251, 512 }, { 7, 252, 512 }, { 8, 253, 512 }, { 8, 254, 512 }, { 9, 255, 512 }, - { 2, 256, 512 }, { 3, 257, 512 }, { 3, 258, 512 }, { 4, 259, 512 }, { 3, 260, 512 }, { 4, 261, 512 }, { 4, 262, 512 }, { 5, 263, 512 }, - { 3, 264, 512 }, { 4, 265, 512 }, { 4, 266, 512 }, { 5, 267, 512 }, { 4, 268, 512 }, { 5, 269, 512 }, { 5, 270, 512 }, { 6, 271, 512 }, - { 3, 272, 512 }, { 4, 273, 512 }, { 4, 274, 512 }, { 5, 275, 512 }, { 4, 276, 512 }, { 5, 277, 512 }, { 5, 278, 512 }, { 6, 279, 512 }, - { 4, 280, 512 }, { 5, 281, 512 }, { 5, 282, 512 }, { 6, 283, 512 }, { 5, 284, 512 }, { 6, 285, 512 }, { 6, 286, 512 }, { 7, 287, 512 }, - { 3, 288, 512 }, { 4, 289, 512 }, { 4, 290, 512 }, { 5, 291, 512 }, { 4, 292, 512 }, { 5, 293, 512 }, { 5, 294, 512 }, { 6, 295, 512 }, - { 4, 296, 512 }, { 5, 297, 512 }, { 5, 298, 512 }, { 6, 299, 512 }, { 5, 300, 512 }, { 6, 301, 512 }, { 6, 302, 512 }, { 7, 303, 512 }, - { 4, 304, 512 }, { 5, 305, 512 }, { 5, 306, 512 }, { 6, 307, 512 }, { 5, 308, 512 }, { 6, 309, 512 }, { 6, 310, 512 }, { 7, 311, 512 }, - { 5, 312, 512 }, { 6, 313, 512 }, { 6, 314, 512 }, { 7, 315, 512 }, { 6, 316, 512 }, { 7, 317, 512 }, { 7, 318, 512 }, { 8, 319, 512 }, - { 3, 320, 512 }, { 4, 321, 512 }, { 4, 322, 512 }, { 5, 323, 512 }, { 4, 324, 512 }, { 5, 325, 512 }, { 5, 326, 512 }, { 6, 327, 512 }, - { 4, 328, 512 }, { 5, 329, 512 }, { 5, 330, 512 }, { 6, 331, 512 }, { 5, 332, 512 }, { 6, 333, 512 }, { 6, 334, 512 }, { 7, 335, 512 }, - { 4, 336, 512 }, { 5, 337, 512 }, { 5, 338, 512 }, { 6, 339, 512 }, { 5, 340, 512 }, { 6, 341, 512 }, { 6, 342, 512 }, { 7, 343, 512 }, - { 5, 344, 512 }, { 6, 345, 512 }, { 6, 346, 512 }, { 7, 347, 512 }, { 6, 348, 512 }, { 7, 349, 512 }, { 7, 350, 512 }, { 8, 351, 512 }, - { 4, 352, 512 }, { 5, 353, 512 }, { 5, 354, 512 }, { 6, 355, 512 }, { 5, 356, 512 }, { 6, 357, 512 }, { 6, 358, 512 }, { 7, 359, 512 }, - { 5, 360, 512 }, { 6, 361, 512 }, { 6, 362, 512 }, { 7, 363, 512 }, { 6, 364, 512 }, { 7, 365, 512 }, { 7, 366, 512 }, { 8, 367, 512 }, - { 5, 368, 512 }, { 6, 369, 512 }, { 6, 370, 512 }, { 7, 371, 512 }, { 6, 372, 512 }, { 7, 373, 512 }, { 7, 374, 512 }, { 8, 375, 512 }, - { 6, 376, 512 }, { 7, 377, 512 }, { 7, 378, 512 }, { 8, 379, 512 }, { 7, 380, 512 }, { 8, 381, 512 }, { 8, 382, 512 }, { 9, 383, 512 }, - { 3, 384, 512 }, { 4, 385, 512 }, { 4, 386, 512 }, { 5, 387, 512 }, { 4, 388, 512 }, { 5, 389, 512 }, { 5, 390, 512 }, { 6, 391, 512 }, - { 4, 392, 512 }, { 5, 393, 512 }, { 5, 394, 512 }, { 6, 395, 512 }, { 5, 396, 512 }, { 6, 397, 512 }, { 6, 398, 512 }, { 7, 399, 512 }, - { 4, 400, 512 }, { 5, 401, 512 }, { 5, 402, 512 }, { 6, 403, 512 }, { 5, 404, 512 }, { 6, 405, 512 }, { 6, 406, 512 }, { 7, 407, 512 }, - { 5, 408, 512 }, { 6, 409, 512 }, { 6, 410, 512 }, { 7, 411, 512 }, { 6, 412, 512 }, { 7, 413, 512 }, { 7, 414, 512 }, { 8, 415, 512 }, - { 4, 416, 512 }, { 5, 417, 512 }, { 5, 418, 512 }, { 6, 419, 512 }, { 5, 420, 512 }, { 6, 421, 512 }, { 6, 422, 512 }, { 7, 423, 512 }, - { 5, 424, 512 }, { 6, 425, 512 }, { 6, 426, 512 }, { 7, 427, 512 }, { 6, 428, 512 }, { 7, 429, 512 }, { 7, 430, 512 }, { 8, 431, 512 }, - { 5, 432, 512 }, { 6, 433, 512 }, { 6, 434, 512 }, { 7, 435, 512 }, { 6, 436, 512 }, { 7, 437, 512 }, { 7, 438, 512 }, { 8, 439, 512 }, - { 6, 440, 512 }, { 7, 441, 512 }, { 7, 442, 512 }, { 8, 443, 512 }, { 7, 444, 512 }, { 8, 445, 512 }, { 8, 446, 512 }, { 9, 447, 512 }, - { 4, 448, 512 }, { 5, 449, 512 }, { 5, 450, 512 }, { 6, 451, 512 }, { 5, 452, 512 }, { 6, 453, 512 }, { 6, 454, 512 }, { 7, 455, 512 }, - { 5, 456, 512 }, { 6, 457, 512 }, { 6, 458, 512 }, { 7, 459, 512 }, { 6, 460, 512 }, { 7, 461, 512 }, { 7, 462, 512 }, { 8, 463, 512 }, - { 5, 464, 512 }, { 6, 465, 512 }, { 6, 466, 512 }, { 7, 467, 512 }, { 6, 468, 512 }, { 7, 469, 512 }, { 7, 470, 512 }, { 8, 471, 512 }, - { 6, 472, 512 }, { 7, 473, 512 }, { 7, 474, 512 }, { 8, 475, 512 }, { 7, 476, 512 }, { 8, 477, 512 }, { 8, 478, 512 }, { 9, 479, 512 }, - { 5, 480, 512 }, { 6, 481, 512 }, { 6, 482, 512 }, { 7, 483, 512 }, { 6, 484, 512 }, { 7, 485, 512 }, { 7, 486, 512 }, { 8, 487, 512 }, - { 6, 488, 512 }, { 7, 489, 512 }, { 7, 490, 512 }, { 8, 491, 512 }, { 7, 492, 512 }, { 8, 493, 512 }, { 8, 494, 512 }, { 9, 495, 512 }, - { 6, 496, 512 }, { 7, 497, 512 }, { 7, 498, 512 }, { 8, 499, 512 }, { 7, 500, 512 }, { 8, 501, 512 }, { 8, 502, 512 }, { 9, 503, 512 }, - { 7, 504, 512 }, { 8, 505, 512 }, { 8, 506, 512 }, { 9, 507, 512 }, { 8, 508, 512 }, { 9, 509, 512 }, { 9, 510, 512 }, { 10, 511, 512 }, -#if FP_LUT > 10 - { 1, 0, 0 }, { 2, 1, 1024 }, { 2, 2, 1024 }, { 3, 3, 1024 }, { 2, 4, 1024 }, { 3, 5, 1024 }, { 3, 6, 1024 }, { 4, 7, 1024 }, - { 2, 8, 1024 }, { 3, 9, 1024 }, { 3, 10, 1024 }, { 4, 11, 1024 }, { 3, 12, 1024 }, { 4, 13, 1024 }, { 4, 14, 1024 }, { 5, 15, 1024 }, - { 2, 16, 1024 }, { 3, 17, 1024 }, { 3, 18, 1024 }, { 4, 19, 1024 }, { 3, 20, 1024 }, { 4, 21, 1024 }, { 4, 22, 1024 }, { 5, 23, 1024 }, - { 3, 24, 1024 }, { 4, 25, 1024 }, { 4, 26, 1024 }, { 5, 27, 1024 }, { 4, 28, 1024 }, { 5, 29, 1024 }, { 5, 30, 1024 }, { 6, 31, 1024 }, - { 2, 32, 1024 }, { 3, 33, 1024 }, { 3, 34, 1024 }, { 4, 35, 1024 }, { 3, 36, 1024 }, { 4, 37, 1024 }, { 4, 38, 1024 }, { 5, 39, 1024 }, - { 3, 40, 1024 }, { 4, 41, 1024 }, { 4, 42, 1024 }, { 5, 43, 1024 }, { 4, 44, 1024 }, { 5, 45, 1024 }, { 5, 46, 1024 }, { 6, 47, 1024 }, - { 3, 48, 1024 }, { 4, 49, 1024 }, { 4, 50, 1024 }, { 5, 51, 1024 }, { 4, 52, 1024 }, { 5, 53, 1024 }, { 5, 54, 1024 }, { 6, 55, 1024 }, - { 4, 56, 1024 }, { 5, 57, 1024 }, { 5, 58, 1024 }, { 6, 59, 1024 }, { 5, 60, 1024 }, { 6, 61, 1024 }, { 6, 62, 1024 }, { 7, 63, 1024 }, - { 2, 64, 1024 }, { 3, 65, 1024 }, { 3, 66, 1024 }, { 4, 67, 1024 }, { 3, 68, 1024 }, { 4, 69, 1024 }, { 4, 70, 1024 }, { 5, 71, 1024 }, - { 3, 72, 1024 }, { 4, 73, 1024 }, { 4, 74, 1024 }, { 5, 75, 1024 }, { 4, 76, 1024 }, { 5, 77, 1024 }, { 5, 78, 1024 }, { 6, 79, 1024 }, - { 3, 80, 1024 }, { 4, 81, 1024 }, { 4, 82, 1024 }, { 5, 83, 1024 }, { 4, 84, 1024 }, { 5, 85, 1024 }, { 5, 86, 1024 }, { 6, 87, 1024 }, - { 4, 88, 1024 }, { 5, 89, 1024 }, { 5, 90, 1024 }, { 6, 91, 1024 }, { 5, 92, 1024 }, { 6, 93, 1024 }, { 6, 94, 1024 }, { 7, 95, 1024 }, - { 3, 96, 1024 }, { 4, 97, 1024 }, { 4, 98, 1024 }, { 5, 99, 1024 }, { 4, 100, 1024 }, { 5, 101, 1024 }, { 5, 102, 1024 }, { 6, 103, 1024 }, - { 4, 104, 1024 }, { 5, 105, 1024 }, { 5, 106, 1024 }, { 6, 107, 1024 }, { 5, 108, 1024 }, { 6, 109, 1024 }, { 6, 110, 1024 }, { 7, 111, 1024 }, - { 4, 112, 1024 }, { 5, 113, 1024 }, { 5, 114, 1024 }, { 6, 115, 1024 }, { 5, 116, 1024 }, { 6, 117, 1024 }, { 6, 118, 1024 }, { 7, 119, 1024 }, - { 5, 120, 1024 }, { 6, 121, 1024 }, { 6, 122, 1024 }, { 7, 123, 1024 }, { 6, 124, 1024 }, { 7, 125, 1024 }, { 7, 126, 1024 }, { 8, 127, 1024 }, - { 2, 128, 1024 }, { 3, 129, 1024 }, { 3, 130, 1024 }, { 4, 131, 1024 }, { 3, 132, 1024 }, { 4, 133, 1024 }, { 4, 134, 1024 }, { 5, 135, 1024 }, - { 3, 136, 1024 }, { 4, 137, 1024 }, { 4, 138, 1024 }, { 5, 139, 1024 }, { 4, 140, 1024 }, { 5, 141, 1024 }, { 5, 142, 1024 }, { 6, 143, 1024 }, - { 3, 144, 1024 }, { 4, 145, 1024 }, { 4, 146, 1024 }, { 5, 147, 1024 }, { 4, 148, 1024 }, { 5, 149, 1024 }, { 5, 150, 1024 }, { 6, 151, 1024 }, - { 4, 152, 1024 }, { 5, 153, 1024 }, { 5, 154, 1024 }, { 6, 155, 1024 }, { 5, 156, 1024 }, { 6, 157, 1024 }, { 6, 158, 1024 }, { 7, 159, 1024 }, - { 3, 160, 1024 }, { 4, 161, 1024 }, { 4, 162, 1024 }, { 5, 163, 1024 }, { 4, 164, 1024 }, { 5, 165, 1024 }, { 5, 166, 1024 }, { 6, 167, 1024 }, - { 4, 168, 1024 }, { 5, 169, 1024 }, { 5, 170, 1024 }, { 6, 171, 1024 }, { 5, 172, 1024 }, { 6, 173, 1024 }, { 6, 174, 1024 }, { 7, 175, 1024 }, - { 4, 176, 1024 }, { 5, 177, 1024 }, { 5, 178, 1024 }, { 6, 179, 1024 }, { 5, 180, 1024 }, { 6, 181, 1024 }, { 6, 182, 1024 }, { 7, 183, 1024 }, - { 5, 184, 1024 }, { 6, 185, 1024 }, { 6, 186, 1024 }, { 7, 187, 1024 }, { 6, 188, 1024 }, { 7, 189, 1024 }, { 7, 190, 1024 }, { 8, 191, 1024 }, - { 3, 192, 1024 }, { 4, 193, 1024 }, { 4, 194, 1024 }, { 5, 195, 1024 }, { 4, 196, 1024 }, { 5, 197, 1024 }, { 5, 198, 1024 }, { 6, 199, 1024 }, - { 4, 200, 1024 }, { 5, 201, 1024 }, { 5, 202, 1024 }, { 6, 203, 1024 }, { 5, 204, 1024 }, { 6, 205, 1024 }, { 6, 206, 1024 }, { 7, 207, 1024 }, - { 4, 208, 1024 }, { 5, 209, 1024 }, { 5, 210, 1024 }, { 6, 211, 1024 }, { 5, 212, 1024 }, { 6, 213, 1024 }, { 6, 214, 1024 }, { 7, 215, 1024 }, - { 5, 216, 1024 }, { 6, 217, 1024 }, { 6, 218, 1024 }, { 7, 219, 1024 }, { 6, 220, 1024 }, { 7, 221, 1024 }, { 7, 222, 1024 }, { 8, 223, 1024 }, - { 4, 224, 1024 }, { 5, 225, 1024 }, { 5, 226, 1024 }, { 6, 227, 1024 }, { 5, 228, 1024 }, { 6, 229, 1024 }, { 6, 230, 1024 }, { 7, 231, 1024 }, - { 5, 232, 1024 }, { 6, 233, 1024 }, { 6, 234, 1024 }, { 7, 235, 1024 }, { 6, 236, 1024 }, { 7, 237, 1024 }, { 7, 238, 1024 }, { 8, 239, 1024 }, - { 5, 240, 1024 }, { 6, 241, 1024 }, { 6, 242, 1024 }, { 7, 243, 1024 }, { 6, 244, 1024 }, { 7, 245, 1024 }, { 7, 246, 1024 }, { 8, 247, 1024 }, - { 6, 248, 1024 }, { 7, 249, 1024 }, { 7, 250, 1024 }, { 8, 251, 1024 }, { 7, 252, 1024 }, { 8, 253, 1024 }, { 8, 254, 1024 }, { 9, 255, 1024 }, - { 2, 256, 1024 }, { 3, 257, 1024 }, { 3, 258, 1024 }, { 4, 259, 1024 }, { 3, 260, 1024 }, { 4, 261, 1024 }, { 4, 262, 1024 }, { 5, 263, 1024 }, - { 3, 264, 1024 }, { 4, 265, 1024 }, { 4, 266, 1024 }, { 5, 267, 1024 }, { 4, 268, 1024 }, { 5, 269, 1024 }, { 5, 270, 1024 }, { 6, 271, 1024 }, - { 3, 272, 1024 }, { 4, 273, 1024 }, { 4, 274, 1024 }, { 5, 275, 1024 }, { 4, 276, 1024 }, { 5, 277, 1024 }, { 5, 278, 1024 }, { 6, 279, 1024 }, - { 4, 280, 1024 }, { 5, 281, 1024 }, { 5, 282, 1024 }, { 6, 283, 1024 }, { 5, 284, 1024 }, { 6, 285, 1024 }, { 6, 286, 1024 }, { 7, 287, 1024 }, - { 3, 288, 1024 }, { 4, 289, 1024 }, { 4, 290, 1024 }, { 5, 291, 1024 }, { 4, 292, 1024 }, { 5, 293, 1024 }, { 5, 294, 1024 }, { 6, 295, 1024 }, - { 4, 296, 1024 }, { 5, 297, 1024 }, { 5, 298, 1024 }, { 6, 299, 1024 }, { 5, 300, 1024 }, { 6, 301, 1024 }, { 6, 302, 1024 }, { 7, 303, 1024 }, - { 4, 304, 1024 }, { 5, 305, 1024 }, { 5, 306, 1024 }, { 6, 307, 1024 }, { 5, 308, 1024 }, { 6, 309, 1024 }, { 6, 310, 1024 }, { 7, 311, 1024 }, - { 5, 312, 1024 }, { 6, 313, 1024 }, { 6, 314, 1024 }, { 7, 315, 1024 }, { 6, 316, 1024 }, { 7, 317, 1024 }, { 7, 318, 1024 }, { 8, 319, 1024 }, - { 3, 320, 1024 }, { 4, 321, 1024 }, { 4, 322, 1024 }, { 5, 323, 1024 }, { 4, 324, 1024 }, { 5, 325, 1024 }, { 5, 326, 1024 }, { 6, 327, 1024 }, - { 4, 328, 1024 }, { 5, 329, 1024 }, { 5, 330, 1024 }, { 6, 331, 1024 }, { 5, 332, 1024 }, { 6, 333, 1024 }, { 6, 334, 1024 }, { 7, 335, 1024 }, - { 4, 336, 1024 }, { 5, 337, 1024 }, { 5, 338, 1024 }, { 6, 339, 1024 }, { 5, 340, 1024 }, { 6, 341, 1024 }, { 6, 342, 1024 }, { 7, 343, 1024 }, - { 5, 344, 1024 }, { 6, 345, 1024 }, { 6, 346, 1024 }, { 7, 347, 1024 }, { 6, 348, 1024 }, { 7, 349, 1024 }, { 7, 350, 1024 }, { 8, 351, 1024 }, - { 4, 352, 1024 }, { 5, 353, 1024 }, { 5, 354, 1024 }, { 6, 355, 1024 }, { 5, 356, 1024 }, { 6, 357, 1024 }, { 6, 358, 1024 }, { 7, 359, 1024 }, - { 5, 360, 1024 }, { 6, 361, 1024 }, { 6, 362, 1024 }, { 7, 363, 1024 }, { 6, 364, 1024 }, { 7, 365, 1024 }, { 7, 366, 1024 }, { 8, 367, 1024 }, - { 5, 368, 1024 }, { 6, 369, 1024 }, { 6, 370, 1024 }, { 7, 371, 1024 }, { 6, 372, 1024 }, { 7, 373, 1024 }, { 7, 374, 1024 }, { 8, 375, 1024 }, - { 6, 376, 1024 }, { 7, 377, 1024 }, { 7, 378, 1024 }, { 8, 379, 1024 }, { 7, 380, 1024 }, { 8, 381, 1024 }, { 8, 382, 1024 }, { 9, 383, 1024 }, - { 3, 384, 1024 }, { 4, 385, 1024 }, { 4, 386, 1024 }, { 5, 387, 1024 }, { 4, 388, 1024 }, { 5, 389, 1024 }, { 5, 390, 1024 }, { 6, 391, 1024 }, - { 4, 392, 1024 }, { 5, 393, 1024 }, { 5, 394, 1024 }, { 6, 395, 1024 }, { 5, 396, 1024 }, { 6, 397, 1024 }, { 6, 398, 1024 }, { 7, 399, 1024 }, - { 4, 400, 1024 }, { 5, 401, 1024 }, { 5, 402, 1024 }, { 6, 403, 1024 }, { 5, 404, 1024 }, { 6, 405, 1024 }, { 6, 406, 1024 }, { 7, 407, 1024 }, - { 5, 408, 1024 }, { 6, 409, 1024 }, { 6, 410, 1024 }, { 7, 411, 1024 }, { 6, 412, 1024 }, { 7, 413, 1024 }, { 7, 414, 1024 }, { 8, 415, 1024 }, - { 4, 416, 1024 }, { 5, 417, 1024 }, { 5, 418, 1024 }, { 6, 419, 1024 }, { 5, 420, 1024 }, { 6, 421, 1024 }, { 6, 422, 1024 }, { 7, 423, 1024 }, - { 5, 424, 1024 }, { 6, 425, 1024 }, { 6, 426, 1024 }, { 7, 427, 1024 }, { 6, 428, 1024 }, { 7, 429, 1024 }, { 7, 430, 1024 }, { 8, 431, 1024 }, - { 5, 432, 1024 }, { 6, 433, 1024 }, { 6, 434, 1024 }, { 7, 435, 1024 }, { 6, 436, 1024 }, { 7, 437, 1024 }, { 7, 438, 1024 }, { 8, 439, 1024 }, - { 6, 440, 1024 }, { 7, 441, 1024 }, { 7, 442, 1024 }, { 8, 443, 1024 }, { 7, 444, 1024 }, { 8, 445, 1024 }, { 8, 446, 1024 }, { 9, 447, 1024 }, - { 4, 448, 1024 }, { 5, 449, 1024 }, { 5, 450, 1024 }, { 6, 451, 1024 }, { 5, 452, 1024 }, { 6, 453, 1024 }, { 6, 454, 1024 }, { 7, 455, 1024 }, - { 5, 456, 1024 }, { 6, 457, 1024 }, { 6, 458, 1024 }, { 7, 459, 1024 }, { 6, 460, 1024 }, { 7, 461, 1024 }, { 7, 462, 1024 }, { 8, 463, 1024 }, - { 5, 464, 1024 }, { 6, 465, 1024 }, { 6, 466, 1024 }, { 7, 467, 1024 }, { 6, 468, 1024 }, { 7, 469, 1024 }, { 7, 470, 1024 }, { 8, 471, 1024 }, - { 6, 472, 1024 }, { 7, 473, 1024 }, { 7, 474, 1024 }, { 8, 475, 1024 }, { 7, 476, 1024 }, { 8, 477, 1024 }, { 8, 478, 1024 }, { 9, 479, 1024 }, - { 5, 480, 1024 }, { 6, 481, 1024 }, { 6, 482, 1024 }, { 7, 483, 1024 }, { 6, 484, 1024 }, { 7, 485, 1024 }, { 7, 486, 1024 }, { 8, 487, 1024 }, - { 6, 488, 1024 }, { 7, 489, 1024 }, { 7, 490, 1024 }, { 8, 491, 1024 }, { 7, 492, 1024 }, { 8, 493, 1024 }, { 8, 494, 1024 }, { 9, 495, 1024 }, - { 6, 496, 1024 }, { 7, 497, 1024 }, { 7, 498, 1024 }, { 8, 499, 1024 }, { 7, 500, 1024 }, { 8, 501, 1024 }, { 8, 502, 1024 }, { 9, 503, 1024 }, - { 7, 504, 1024 }, { 8, 505, 1024 }, { 8, 506, 1024 }, { 9, 507, 1024 }, { 8, 508, 1024 }, { 9, 509, 1024 }, { 9, 510, 1024 }, { 10, 511, 1024 }, - { 2, 512, 1024 }, { 3, 513, 1024 }, { 3, 514, 1024 }, { 4, 515, 1024 }, { 3, 516, 1024 }, { 4, 517, 1024 }, { 4, 518, 1024 }, { 5, 519, 1024 }, - { 3, 520, 1024 }, { 4, 521, 1024 }, { 4, 522, 1024 }, { 5, 523, 1024 }, { 4, 524, 1024 }, { 5, 525, 1024 }, { 5, 526, 1024 }, { 6, 527, 1024 }, - { 3, 528, 1024 }, { 4, 529, 1024 }, { 4, 530, 1024 }, { 5, 531, 1024 }, { 4, 532, 1024 }, { 5, 533, 1024 }, { 5, 534, 1024 }, { 6, 535, 1024 }, - { 4, 536, 1024 }, { 5, 537, 1024 }, { 5, 538, 1024 }, { 6, 539, 1024 }, { 5, 540, 1024 }, { 6, 541, 1024 }, { 6, 542, 1024 }, { 7, 543, 1024 }, - { 3, 544, 1024 }, { 4, 545, 1024 }, { 4, 546, 1024 }, { 5, 547, 1024 }, { 4, 548, 1024 }, { 5, 549, 1024 }, { 5, 550, 1024 }, { 6, 551, 1024 }, - { 4, 552, 1024 }, { 5, 553, 1024 }, { 5, 554, 1024 }, { 6, 555, 1024 }, { 5, 556, 1024 }, { 6, 557, 1024 }, { 6, 558, 1024 }, { 7, 559, 1024 }, - { 4, 560, 1024 }, { 5, 561, 1024 }, { 5, 562, 1024 }, { 6, 563, 1024 }, { 5, 564, 1024 }, { 6, 565, 1024 }, { 6, 566, 1024 }, { 7, 567, 1024 }, - { 5, 568, 1024 }, { 6, 569, 1024 }, { 6, 570, 1024 }, { 7, 571, 1024 }, { 6, 572, 1024 }, { 7, 573, 1024 }, { 7, 574, 1024 }, { 8, 575, 1024 }, - { 3, 576, 1024 }, { 4, 577, 1024 }, { 4, 578, 1024 }, { 5, 579, 1024 }, { 4, 580, 1024 }, { 5, 581, 1024 }, { 5, 582, 1024 }, { 6, 583, 1024 }, - { 4, 584, 1024 }, { 5, 585, 1024 }, { 5, 586, 1024 }, { 6, 587, 1024 }, { 5, 588, 1024 }, { 6, 589, 1024 }, { 6, 590, 1024 }, { 7, 591, 1024 }, - { 4, 592, 1024 }, { 5, 593, 1024 }, { 5, 594, 1024 }, { 6, 595, 1024 }, { 5, 596, 1024 }, { 6, 597, 1024 }, { 6, 598, 1024 }, { 7, 599, 1024 }, - { 5, 600, 1024 }, { 6, 601, 1024 }, { 6, 602, 1024 }, { 7, 603, 1024 }, { 6, 604, 1024 }, { 7, 605, 1024 }, { 7, 606, 1024 }, { 8, 607, 1024 }, - { 4, 608, 1024 }, { 5, 609, 1024 }, { 5, 610, 1024 }, { 6, 611, 1024 }, { 5, 612, 1024 }, { 6, 613, 1024 }, { 6, 614, 1024 }, { 7, 615, 1024 }, - { 5, 616, 1024 }, { 6, 617, 1024 }, { 6, 618, 1024 }, { 7, 619, 1024 }, { 6, 620, 1024 }, { 7, 621, 1024 }, { 7, 622, 1024 }, { 8, 623, 1024 }, - { 5, 624, 1024 }, { 6, 625, 1024 }, { 6, 626, 1024 }, { 7, 627, 1024 }, { 6, 628, 1024 }, { 7, 629, 1024 }, { 7, 630, 1024 }, { 8, 631, 1024 }, - { 6, 632, 1024 }, { 7, 633, 1024 }, { 7, 634, 1024 }, { 8, 635, 1024 }, { 7, 636, 1024 }, { 8, 637, 1024 }, { 8, 638, 1024 }, { 9, 639, 1024 }, - { 3, 640, 1024 }, { 4, 641, 1024 }, { 4, 642, 1024 }, { 5, 643, 1024 }, { 4, 644, 1024 }, { 5, 645, 1024 }, { 5, 646, 1024 }, { 6, 647, 1024 }, - { 4, 648, 1024 }, { 5, 649, 1024 }, { 5, 650, 1024 }, { 6, 651, 1024 }, { 5, 652, 1024 }, { 6, 653, 1024 }, { 6, 654, 1024 }, { 7, 655, 1024 }, - { 4, 656, 1024 }, { 5, 657, 1024 }, { 5, 658, 1024 }, { 6, 659, 1024 }, { 5, 660, 1024 }, { 6, 661, 1024 }, { 6, 662, 1024 }, { 7, 663, 1024 }, - { 5, 664, 1024 }, { 6, 665, 1024 }, { 6, 666, 1024 }, { 7, 667, 1024 }, { 6, 668, 1024 }, { 7, 669, 1024 }, { 7, 670, 1024 }, { 8, 671, 1024 }, - { 4, 672, 1024 }, { 5, 673, 1024 }, { 5, 674, 1024 }, { 6, 675, 1024 }, { 5, 676, 1024 }, { 6, 677, 1024 }, { 6, 678, 1024 }, { 7, 679, 1024 }, - { 5, 680, 1024 }, { 6, 681, 1024 }, { 6, 682, 1024 }, { 7, 683, 1024 }, { 6, 684, 1024 }, { 7, 685, 1024 }, { 7, 686, 1024 }, { 8, 687, 1024 }, - { 5, 688, 1024 }, { 6, 689, 1024 }, { 6, 690, 1024 }, { 7, 691, 1024 }, { 6, 692, 1024 }, { 7, 693, 1024 }, { 7, 694, 1024 }, { 8, 695, 1024 }, - { 6, 696, 1024 }, { 7, 697, 1024 }, { 7, 698, 1024 }, { 8, 699, 1024 }, { 7, 700, 1024 }, { 8, 701, 1024 }, { 8, 702, 1024 }, { 9, 703, 1024 }, - { 4, 704, 1024 }, { 5, 705, 1024 }, { 5, 706, 1024 }, { 6, 707, 1024 }, { 5, 708, 1024 }, { 6, 709, 1024 }, { 6, 710, 1024 }, { 7, 711, 1024 }, - { 5, 712, 1024 }, { 6, 713, 1024 }, { 6, 714, 1024 }, { 7, 715, 1024 }, { 6, 716, 1024 }, { 7, 717, 1024 }, { 7, 718, 1024 }, { 8, 719, 1024 }, - { 5, 720, 1024 }, { 6, 721, 1024 }, { 6, 722, 1024 }, { 7, 723, 1024 }, { 6, 724, 1024 }, { 7, 725, 1024 }, { 7, 726, 1024 }, { 8, 727, 1024 }, - { 6, 728, 1024 }, { 7, 729, 1024 }, { 7, 730, 1024 }, { 8, 731, 1024 }, { 7, 732, 1024 }, { 8, 733, 1024 }, { 8, 734, 1024 }, { 9, 735, 1024 }, - { 5, 736, 1024 }, { 6, 737, 1024 }, { 6, 738, 1024 }, { 7, 739, 1024 }, { 6, 740, 1024 }, { 7, 741, 1024 }, { 7, 742, 1024 }, { 8, 743, 1024 }, - { 6, 744, 1024 }, { 7, 745, 1024 }, { 7, 746, 1024 }, { 8, 747, 1024 }, { 7, 748, 1024 }, { 8, 749, 1024 }, { 8, 750, 1024 }, { 9, 751, 1024 }, - { 6, 752, 1024 }, { 7, 753, 1024 }, { 7, 754, 1024 }, { 8, 755, 1024 }, { 7, 756, 1024 }, { 8, 757, 1024 }, { 8, 758, 1024 }, { 9, 759, 1024 }, - { 7, 760, 1024 }, { 8, 761, 1024 }, { 8, 762, 1024 }, { 9, 763, 1024 }, { 8, 764, 1024 }, { 9, 765, 1024 }, { 9, 766, 1024 }, { 10, 767, 1024 }, - { 3, 768, 1024 }, { 4, 769, 1024 }, { 4, 770, 1024 }, { 5, 771, 1024 }, { 4, 772, 1024 }, { 5, 773, 1024 }, { 5, 774, 1024 }, { 6, 775, 1024 }, - { 4, 776, 1024 }, { 5, 777, 1024 }, { 5, 778, 1024 }, { 6, 779, 1024 }, { 5, 780, 1024 }, { 6, 781, 1024 }, { 6, 782, 1024 }, { 7, 783, 1024 }, - { 4, 784, 1024 }, { 5, 785, 1024 }, { 5, 786, 1024 }, { 6, 787, 1024 }, { 5, 788, 1024 }, { 6, 789, 1024 }, { 6, 790, 1024 }, { 7, 791, 1024 }, - { 5, 792, 1024 }, { 6, 793, 1024 }, { 6, 794, 1024 }, { 7, 795, 1024 }, { 6, 796, 1024 }, { 7, 797, 1024 }, { 7, 798, 1024 }, { 8, 799, 1024 }, - { 4, 800, 1024 }, { 5, 801, 1024 }, { 5, 802, 1024 }, { 6, 803, 1024 }, { 5, 804, 1024 }, { 6, 805, 1024 }, { 6, 806, 1024 }, { 7, 807, 1024 }, - { 5, 808, 1024 }, { 6, 809, 1024 }, { 6, 810, 1024 }, { 7, 811, 1024 }, { 6, 812, 1024 }, { 7, 813, 1024 }, { 7, 814, 1024 }, { 8, 815, 1024 }, - { 5, 816, 1024 }, { 6, 817, 1024 }, { 6, 818, 1024 }, { 7, 819, 1024 }, { 6, 820, 1024 }, { 7, 821, 1024 }, { 7, 822, 1024 }, { 8, 823, 1024 }, - { 6, 824, 1024 }, { 7, 825, 1024 }, { 7, 826, 1024 }, { 8, 827, 1024 }, { 7, 828, 1024 }, { 8, 829, 1024 }, { 8, 830, 1024 }, { 9, 831, 1024 }, - { 4, 832, 1024 }, { 5, 833, 1024 }, { 5, 834, 1024 }, { 6, 835, 1024 }, { 5, 836, 1024 }, { 6, 837, 1024 }, { 6, 838, 1024 }, { 7, 839, 1024 }, - { 5, 840, 1024 }, { 6, 841, 1024 }, { 6, 842, 1024 }, { 7, 843, 1024 }, { 6, 844, 1024 }, { 7, 845, 1024 }, { 7, 846, 1024 }, { 8, 847, 1024 }, - { 5, 848, 1024 }, { 6, 849, 1024 }, { 6, 850, 1024 }, { 7, 851, 1024 }, { 6, 852, 1024 }, { 7, 853, 1024 }, { 7, 854, 1024 }, { 8, 855, 1024 }, - { 6, 856, 1024 }, { 7, 857, 1024 }, { 7, 858, 1024 }, { 8, 859, 1024 }, { 7, 860, 1024 }, { 8, 861, 1024 }, { 8, 862, 1024 }, { 9, 863, 1024 }, - { 5, 864, 1024 }, { 6, 865, 1024 }, { 6, 866, 1024 }, { 7, 867, 1024 }, { 6, 868, 1024 }, { 7, 869, 1024 }, { 7, 870, 1024 }, { 8, 871, 1024 }, - { 6, 872, 1024 }, { 7, 873, 1024 }, { 7, 874, 1024 }, { 8, 875, 1024 }, { 7, 876, 1024 }, { 8, 877, 1024 }, { 8, 878, 1024 }, { 9, 879, 1024 }, - { 6, 880, 1024 }, { 7, 881, 1024 }, { 7, 882, 1024 }, { 8, 883, 1024 }, { 7, 884, 1024 }, { 8, 885, 1024 }, { 8, 886, 1024 }, { 9, 887, 1024 }, - { 7, 888, 1024 }, { 8, 889, 1024 }, { 8, 890, 1024 }, { 9, 891, 1024 }, { 8, 892, 1024 }, { 9, 893, 1024 }, { 9, 894, 1024 }, { 10, 895, 1024 }, - { 4, 896, 1024 }, { 5, 897, 1024 }, { 5, 898, 1024 }, { 6, 899, 1024 }, { 5, 900, 1024 }, { 6, 901, 1024 }, { 6, 902, 1024 }, { 7, 903, 1024 }, - { 5, 904, 1024 }, { 6, 905, 1024 }, { 6, 906, 1024 }, { 7, 907, 1024 }, { 6, 908, 1024 }, { 7, 909, 1024 }, { 7, 910, 1024 }, { 8, 911, 1024 }, - { 5, 912, 1024 }, { 6, 913, 1024 }, { 6, 914, 1024 }, { 7, 915, 1024 }, { 6, 916, 1024 }, { 7, 917, 1024 }, { 7, 918, 1024 }, { 8, 919, 1024 }, - { 6, 920, 1024 }, { 7, 921, 1024 }, { 7, 922, 1024 }, { 8, 923, 1024 }, { 7, 924, 1024 }, { 8, 925, 1024 }, { 8, 926, 1024 }, { 9, 927, 1024 }, - { 5, 928, 1024 }, { 6, 929, 1024 }, { 6, 930, 1024 }, { 7, 931, 1024 }, { 6, 932, 1024 }, { 7, 933, 1024 }, { 7, 934, 1024 }, { 8, 935, 1024 }, - { 6, 936, 1024 }, { 7, 937, 1024 }, { 7, 938, 1024 }, { 8, 939, 1024 }, { 7, 940, 1024 }, { 8, 941, 1024 }, { 8, 942, 1024 }, { 9, 943, 1024 }, - { 6, 944, 1024 }, { 7, 945, 1024 }, { 7, 946, 1024 }, { 8, 947, 1024 }, { 7, 948, 1024 }, { 8, 949, 1024 }, { 8, 950, 1024 }, { 9, 951, 1024 }, - { 7, 952, 1024 }, { 8, 953, 1024 }, { 8, 954, 1024 }, { 9, 955, 1024 }, { 8, 956, 1024 }, { 9, 957, 1024 }, { 9, 958, 1024 }, { 10, 959, 1024 }, - { 5, 960, 1024 }, { 6, 961, 1024 }, { 6, 962, 1024 }, { 7, 963, 1024 }, { 6, 964, 1024 }, { 7, 965, 1024 }, { 7, 966, 1024 }, { 8, 967, 1024 }, - { 6, 968, 1024 }, { 7, 969, 1024 }, { 7, 970, 1024 }, { 8, 971, 1024 }, { 7, 972, 1024 }, { 8, 973, 1024 }, { 8, 974, 1024 }, { 9, 975, 1024 }, - { 6, 976, 1024 }, { 7, 977, 1024 }, { 7, 978, 1024 }, { 8, 979, 1024 }, { 7, 980, 1024 }, { 8, 981, 1024 }, { 8, 982, 1024 }, { 9, 983, 1024 }, - { 7, 984, 1024 }, { 8, 985, 1024 }, { 8, 986, 1024 }, { 9, 987, 1024 }, { 8, 988, 1024 }, { 9, 989, 1024 }, { 9, 990, 1024 }, { 10, 991, 1024 }, - { 6, 992, 1024 }, { 7, 993, 1024 }, { 7, 994, 1024 }, { 8, 995, 1024 }, { 7, 996, 1024 }, { 8, 997, 1024 }, { 8, 998, 1024 }, { 9, 999, 1024 }, - { 7, 1000, 1024 }, { 8, 1001, 1024 }, { 8, 1002, 1024 }, { 9, 1003, 1024 }, { 8, 1004, 1024 }, { 9, 1005, 1024 }, { 9, 1006, 1024 }, { 10, 1007, 1024 }, - { 7, 1008, 1024 }, { 8, 1009, 1024 }, { 8, 1010, 1024 }, { 9, 1011, 1024 }, { 8, 1012, 1024 }, { 9, 1013, 1024 }, { 9, 1014, 1024 }, { 10, 1015, 1024 }, - { 8, 1016, 1024 }, { 9, 1017, 1024 }, { 9, 1018, 1024 }, { 10, 1019, 1024 }, { 9, 1020, 1024 }, { 10, 1021, 1024 }, { 10, 1022, 1024 }, { 11, 1023, 1024 }, -#if FP_LUT > 11 - { 1, 0, 0 }, { 2, 1, 2048 }, { 2, 2, 2048 }, { 3, 3, 2048 }, { 2, 4, 2048 }, { 3, 5, 2048 }, { 3, 6, 2048 }, { 4, 7, 2048 }, - { 2, 8, 2048 }, { 3, 9, 2048 }, { 3, 10, 2048 }, { 4, 11, 2048 }, { 3, 12, 2048 }, { 4, 13, 2048 }, { 4, 14, 2048 }, { 5, 15, 2048 }, - { 2, 16, 2048 }, { 3, 17, 2048 }, { 3, 18, 2048 }, { 4, 19, 2048 }, { 3, 20, 2048 }, { 4, 21, 2048 }, { 4, 22, 2048 }, { 5, 23, 2048 }, - { 3, 24, 2048 }, { 4, 25, 2048 }, { 4, 26, 2048 }, { 5, 27, 2048 }, { 4, 28, 2048 }, { 5, 29, 2048 }, { 5, 30, 2048 }, { 6, 31, 2048 }, - { 2, 32, 2048 }, { 3, 33, 2048 }, { 3, 34, 2048 }, { 4, 35, 2048 }, { 3, 36, 2048 }, { 4, 37, 2048 }, { 4, 38, 2048 }, { 5, 39, 2048 }, - { 3, 40, 2048 }, { 4, 41, 2048 }, { 4, 42, 2048 }, { 5, 43, 2048 }, { 4, 44, 2048 }, { 5, 45, 2048 }, { 5, 46, 2048 }, { 6, 47, 2048 }, - { 3, 48, 2048 }, { 4, 49, 2048 }, { 4, 50, 2048 }, { 5, 51, 2048 }, { 4, 52, 2048 }, { 5, 53, 2048 }, { 5, 54, 2048 }, { 6, 55, 2048 }, - { 4, 56, 2048 }, { 5, 57, 2048 }, { 5, 58, 2048 }, { 6, 59, 2048 }, { 5, 60, 2048 }, { 6, 61, 2048 }, { 6, 62, 2048 }, { 7, 63, 2048 }, - { 2, 64, 2048 }, { 3, 65, 2048 }, { 3, 66, 2048 }, { 4, 67, 2048 }, { 3, 68, 2048 }, { 4, 69, 2048 }, { 4, 70, 2048 }, { 5, 71, 2048 }, - { 3, 72, 2048 }, { 4, 73, 2048 }, { 4, 74, 2048 }, { 5, 75, 2048 }, { 4, 76, 2048 }, { 5, 77, 2048 }, { 5, 78, 2048 }, { 6, 79, 2048 }, - { 3, 80, 2048 }, { 4, 81, 2048 }, { 4, 82, 2048 }, { 5, 83, 2048 }, { 4, 84, 2048 }, { 5, 85, 2048 }, { 5, 86, 2048 }, { 6, 87, 2048 }, - { 4, 88, 2048 }, { 5, 89, 2048 }, { 5, 90, 2048 }, { 6, 91, 2048 }, { 5, 92, 2048 }, { 6, 93, 2048 }, { 6, 94, 2048 }, { 7, 95, 2048 }, - { 3, 96, 2048 }, { 4, 97, 2048 }, { 4, 98, 2048 }, { 5, 99, 2048 }, { 4, 100, 2048 }, { 5, 101, 2048 }, { 5, 102, 2048 }, { 6, 103, 2048 }, - { 4, 104, 2048 }, { 5, 105, 2048 }, { 5, 106, 2048 }, { 6, 107, 2048 }, { 5, 108, 2048 }, { 6, 109, 2048 }, { 6, 110, 2048 }, { 7, 111, 2048 }, - { 4, 112, 2048 }, { 5, 113, 2048 }, { 5, 114, 2048 }, { 6, 115, 2048 }, { 5, 116, 2048 }, { 6, 117, 2048 }, { 6, 118, 2048 }, { 7, 119, 2048 }, - { 5, 120, 2048 }, { 6, 121, 2048 }, { 6, 122, 2048 }, { 7, 123, 2048 }, { 6, 124, 2048 }, { 7, 125, 2048 }, { 7, 126, 2048 }, { 8, 127, 2048 }, - { 2, 128, 2048 }, { 3, 129, 2048 }, { 3, 130, 2048 }, { 4, 131, 2048 }, { 3, 132, 2048 }, { 4, 133, 2048 }, { 4, 134, 2048 }, { 5, 135, 2048 }, - { 3, 136, 2048 }, { 4, 137, 2048 }, { 4, 138, 2048 }, { 5, 139, 2048 }, { 4, 140, 2048 }, { 5, 141, 2048 }, { 5, 142, 2048 }, { 6, 143, 2048 }, - { 3, 144, 2048 }, { 4, 145, 2048 }, { 4, 146, 2048 }, { 5, 147, 2048 }, { 4, 148, 2048 }, { 5, 149, 2048 }, { 5, 150, 2048 }, { 6, 151, 2048 }, - { 4, 152, 2048 }, { 5, 153, 2048 }, { 5, 154, 2048 }, { 6, 155, 2048 }, { 5, 156, 2048 }, { 6, 157, 2048 }, { 6, 158, 2048 }, { 7, 159, 2048 }, - { 3, 160, 2048 }, { 4, 161, 2048 }, { 4, 162, 2048 }, { 5, 163, 2048 }, { 4, 164, 2048 }, { 5, 165, 2048 }, { 5, 166, 2048 }, { 6, 167, 2048 }, - { 4, 168, 2048 }, { 5, 169, 2048 }, { 5, 170, 2048 }, { 6, 171, 2048 }, { 5, 172, 2048 }, { 6, 173, 2048 }, { 6, 174, 2048 }, { 7, 175, 2048 }, - { 4, 176, 2048 }, { 5, 177, 2048 }, { 5, 178, 2048 }, { 6, 179, 2048 }, { 5, 180, 2048 }, { 6, 181, 2048 }, { 6, 182, 2048 }, { 7, 183, 2048 }, - { 5, 184, 2048 }, { 6, 185, 2048 }, { 6, 186, 2048 }, { 7, 187, 2048 }, { 6, 188, 2048 }, { 7, 189, 2048 }, { 7, 190, 2048 }, { 8, 191, 2048 }, - { 3, 192, 2048 }, { 4, 193, 2048 }, { 4, 194, 2048 }, { 5, 195, 2048 }, { 4, 196, 2048 }, { 5, 197, 2048 }, { 5, 198, 2048 }, { 6, 199, 2048 }, - { 4, 200, 2048 }, { 5, 201, 2048 }, { 5, 202, 2048 }, { 6, 203, 2048 }, { 5, 204, 2048 }, { 6, 205, 2048 }, { 6, 206, 2048 }, { 7, 207, 2048 }, - { 4, 208, 2048 }, { 5, 209, 2048 }, { 5, 210, 2048 }, { 6, 211, 2048 }, { 5, 212, 2048 }, { 6, 213, 2048 }, { 6, 214, 2048 }, { 7, 215, 2048 }, - { 5, 216, 2048 }, { 6, 217, 2048 }, { 6, 218, 2048 }, { 7, 219, 2048 }, { 6, 220, 2048 }, { 7, 221, 2048 }, { 7, 222, 2048 }, { 8, 223, 2048 }, - { 4, 224, 2048 }, { 5, 225, 2048 }, { 5, 226, 2048 }, { 6, 227, 2048 }, { 5, 228, 2048 }, { 6, 229, 2048 }, { 6, 230, 2048 }, { 7, 231, 2048 }, - { 5, 232, 2048 }, { 6, 233, 2048 }, { 6, 234, 2048 }, { 7, 235, 2048 }, { 6, 236, 2048 }, { 7, 237, 2048 }, { 7, 238, 2048 }, { 8, 239, 2048 }, - { 5, 240, 2048 }, { 6, 241, 2048 }, { 6, 242, 2048 }, { 7, 243, 2048 }, { 6, 244, 2048 }, { 7, 245, 2048 }, { 7, 246, 2048 }, { 8, 247, 2048 }, - { 6, 248, 2048 }, { 7, 249, 2048 }, { 7, 250, 2048 }, { 8, 251, 2048 }, { 7, 252, 2048 }, { 8, 253, 2048 }, { 8, 254, 2048 }, { 9, 255, 2048 }, - { 2, 256, 2048 }, { 3, 257, 2048 }, { 3, 258, 2048 }, { 4, 259, 2048 }, { 3, 260, 2048 }, { 4, 261, 2048 }, { 4, 262, 2048 }, { 5, 263, 2048 }, - { 3, 264, 2048 }, { 4, 265, 2048 }, { 4, 266, 2048 }, { 5, 267, 2048 }, { 4, 268, 2048 }, { 5, 269, 2048 }, { 5, 270, 2048 }, { 6, 271, 2048 }, - { 3, 272, 2048 }, { 4, 273, 2048 }, { 4, 274, 2048 }, { 5, 275, 2048 }, { 4, 276, 2048 }, { 5, 277, 2048 }, { 5, 278, 2048 }, { 6, 279, 2048 }, - { 4, 280, 2048 }, { 5, 281, 2048 }, { 5, 282, 2048 }, { 6, 283, 2048 }, { 5, 284, 2048 }, { 6, 285, 2048 }, { 6, 286, 2048 }, { 7, 287, 2048 }, - { 3, 288, 2048 }, { 4, 289, 2048 }, { 4, 290, 2048 }, { 5, 291, 2048 }, { 4, 292, 2048 }, { 5, 293, 2048 }, { 5, 294, 2048 }, { 6, 295, 2048 }, - { 4, 296, 2048 }, { 5, 297, 2048 }, { 5, 298, 2048 }, { 6, 299, 2048 }, { 5, 300, 2048 }, { 6, 301, 2048 }, { 6, 302, 2048 }, { 7, 303, 2048 }, - { 4, 304, 2048 }, { 5, 305, 2048 }, { 5, 306, 2048 }, { 6, 307, 2048 }, { 5, 308, 2048 }, { 6, 309, 2048 }, { 6, 310, 2048 }, { 7, 311, 2048 }, - { 5, 312, 2048 }, { 6, 313, 2048 }, { 6, 314, 2048 }, { 7, 315, 2048 }, { 6, 316, 2048 }, { 7, 317, 2048 }, { 7, 318, 2048 }, { 8, 319, 2048 }, - { 3, 320, 2048 }, { 4, 321, 2048 }, { 4, 322, 2048 }, { 5, 323, 2048 }, { 4, 324, 2048 }, { 5, 325, 2048 }, { 5, 326, 2048 }, { 6, 327, 2048 }, - { 4, 328, 2048 }, { 5, 329, 2048 }, { 5, 330, 2048 }, { 6, 331, 2048 }, { 5, 332, 2048 }, { 6, 333, 2048 }, { 6, 334, 2048 }, { 7, 335, 2048 }, - { 4, 336, 2048 }, { 5, 337, 2048 }, { 5, 338, 2048 }, { 6, 339, 2048 }, { 5, 340, 2048 }, { 6, 341, 2048 }, { 6, 342, 2048 }, { 7, 343, 2048 }, - { 5, 344, 2048 }, { 6, 345, 2048 }, { 6, 346, 2048 }, { 7, 347, 2048 }, { 6, 348, 2048 }, { 7, 349, 2048 }, { 7, 350, 2048 }, { 8, 351, 2048 }, - { 4, 352, 2048 }, { 5, 353, 2048 }, { 5, 354, 2048 }, { 6, 355, 2048 }, { 5, 356, 2048 }, { 6, 357, 2048 }, { 6, 358, 2048 }, { 7, 359, 2048 }, - { 5, 360, 2048 }, { 6, 361, 2048 }, { 6, 362, 2048 }, { 7, 363, 2048 }, { 6, 364, 2048 }, { 7, 365, 2048 }, { 7, 366, 2048 }, { 8, 367, 2048 }, - { 5, 368, 2048 }, { 6, 369, 2048 }, { 6, 370, 2048 }, { 7, 371, 2048 }, { 6, 372, 2048 }, { 7, 373, 2048 }, { 7, 374, 2048 }, { 8, 375, 2048 }, - { 6, 376, 2048 }, { 7, 377, 2048 }, { 7, 378, 2048 }, { 8, 379, 2048 }, { 7, 380, 2048 }, { 8, 381, 2048 }, { 8, 382, 2048 }, { 9, 383, 2048 }, - { 3, 384, 2048 }, { 4, 385, 2048 }, { 4, 386, 2048 }, { 5, 387, 2048 }, { 4, 388, 2048 }, { 5, 389, 2048 }, { 5, 390, 2048 }, { 6, 391, 2048 }, - { 4, 392, 2048 }, { 5, 393, 2048 }, { 5, 394, 2048 }, { 6, 395, 2048 }, { 5, 396, 2048 }, { 6, 397, 2048 }, { 6, 398, 2048 }, { 7, 399, 2048 }, - { 4, 400, 2048 }, { 5, 401, 2048 }, { 5, 402, 2048 }, { 6, 403, 2048 }, { 5, 404, 2048 }, { 6, 405, 2048 }, { 6, 406, 2048 }, { 7, 407, 2048 }, - { 5, 408, 2048 }, { 6, 409, 2048 }, { 6, 410, 2048 }, { 7, 411, 2048 }, { 6, 412, 2048 }, { 7, 413, 2048 }, { 7, 414, 2048 }, { 8, 415, 2048 }, - { 4, 416, 2048 }, { 5, 417, 2048 }, { 5, 418, 2048 }, { 6, 419, 2048 }, { 5, 420, 2048 }, { 6, 421, 2048 }, { 6, 422, 2048 }, { 7, 423, 2048 }, - { 5, 424, 2048 }, { 6, 425, 2048 }, { 6, 426, 2048 }, { 7, 427, 2048 }, { 6, 428, 2048 }, { 7, 429, 2048 }, { 7, 430, 2048 }, { 8, 431, 2048 }, - { 5, 432, 2048 }, { 6, 433, 2048 }, { 6, 434, 2048 }, { 7, 435, 2048 }, { 6, 436, 2048 }, { 7, 437, 2048 }, { 7, 438, 2048 }, { 8, 439, 2048 }, - { 6, 440, 2048 }, { 7, 441, 2048 }, { 7, 442, 2048 }, { 8, 443, 2048 }, { 7, 444, 2048 }, { 8, 445, 2048 }, { 8, 446, 2048 }, { 9, 447, 2048 }, - { 4, 448, 2048 }, { 5, 449, 2048 }, { 5, 450, 2048 }, { 6, 451, 2048 }, { 5, 452, 2048 }, { 6, 453, 2048 }, { 6, 454, 2048 }, { 7, 455, 2048 }, - { 5, 456, 2048 }, { 6, 457, 2048 }, { 6, 458, 2048 }, { 7, 459, 2048 }, { 6, 460, 2048 }, { 7, 461, 2048 }, { 7, 462, 2048 }, { 8, 463, 2048 }, - { 5, 464, 2048 }, { 6, 465, 2048 }, { 6, 466, 2048 }, { 7, 467, 2048 }, { 6, 468, 2048 }, { 7, 469, 2048 }, { 7, 470, 2048 }, { 8, 471, 2048 }, - { 6, 472, 2048 }, { 7, 473, 2048 }, { 7, 474, 2048 }, { 8, 475, 2048 }, { 7, 476, 2048 }, { 8, 477, 2048 }, { 8, 478, 2048 }, { 9, 479, 2048 }, - { 5, 480, 2048 }, { 6, 481, 2048 }, { 6, 482, 2048 }, { 7, 483, 2048 }, { 6, 484, 2048 }, { 7, 485, 2048 }, { 7, 486, 2048 }, { 8, 487, 2048 }, - { 6, 488, 2048 }, { 7, 489, 2048 }, { 7, 490, 2048 }, { 8, 491, 2048 }, { 7, 492, 2048 }, { 8, 493, 2048 }, { 8, 494, 2048 }, { 9, 495, 2048 }, - { 6, 496, 2048 }, { 7, 497, 2048 }, { 7, 498, 2048 }, { 8, 499, 2048 }, { 7, 500, 2048 }, { 8, 501, 2048 }, { 8, 502, 2048 }, { 9, 503, 2048 }, - { 7, 504, 2048 }, { 8, 505, 2048 }, { 8, 506, 2048 }, { 9, 507, 2048 }, { 8, 508, 2048 }, { 9, 509, 2048 }, { 9, 510, 2048 }, { 10, 511, 2048 }, - { 2, 512, 2048 }, { 3, 513, 2048 }, { 3, 514, 2048 }, { 4, 515, 2048 }, { 3, 516, 2048 }, { 4, 517, 2048 }, { 4, 518, 2048 }, { 5, 519, 2048 }, - { 3, 520, 2048 }, { 4, 521, 2048 }, { 4, 522, 2048 }, { 5, 523, 2048 }, { 4, 524, 2048 }, { 5, 525, 2048 }, { 5, 526, 2048 }, { 6, 527, 2048 }, - { 3, 528, 2048 }, { 4, 529, 2048 }, { 4, 530, 2048 }, { 5, 531, 2048 }, { 4, 532, 2048 }, { 5, 533, 2048 }, { 5, 534, 2048 }, { 6, 535, 2048 }, - { 4, 536, 2048 }, { 5, 537, 2048 }, { 5, 538, 2048 }, { 6, 539, 2048 }, { 5, 540, 2048 }, { 6, 541, 2048 }, { 6, 542, 2048 }, { 7, 543, 2048 }, - { 3, 544, 2048 }, { 4, 545, 2048 }, { 4, 546, 2048 }, { 5, 547, 2048 }, { 4, 548, 2048 }, { 5, 549, 2048 }, { 5, 550, 2048 }, { 6, 551, 2048 }, - { 4, 552, 2048 }, { 5, 553, 2048 }, { 5, 554, 2048 }, { 6, 555, 2048 }, { 5, 556, 2048 }, { 6, 557, 2048 }, { 6, 558, 2048 }, { 7, 559, 2048 }, - { 4, 560, 2048 }, { 5, 561, 2048 }, { 5, 562, 2048 }, { 6, 563, 2048 }, { 5, 564, 2048 }, { 6, 565, 2048 }, { 6, 566, 2048 }, { 7, 567, 2048 }, - { 5, 568, 2048 }, { 6, 569, 2048 }, { 6, 570, 2048 }, { 7, 571, 2048 }, { 6, 572, 2048 }, { 7, 573, 2048 }, { 7, 574, 2048 }, { 8, 575, 2048 }, - { 3, 576, 2048 }, { 4, 577, 2048 }, { 4, 578, 2048 }, { 5, 579, 2048 }, { 4, 580, 2048 }, { 5, 581, 2048 }, { 5, 582, 2048 }, { 6, 583, 2048 }, - { 4, 584, 2048 }, { 5, 585, 2048 }, { 5, 586, 2048 }, { 6, 587, 2048 }, { 5, 588, 2048 }, { 6, 589, 2048 }, { 6, 590, 2048 }, { 7, 591, 2048 }, - { 4, 592, 2048 }, { 5, 593, 2048 }, { 5, 594, 2048 }, { 6, 595, 2048 }, { 5, 596, 2048 }, { 6, 597, 2048 }, { 6, 598, 2048 }, { 7, 599, 2048 }, - { 5, 600, 2048 }, { 6, 601, 2048 }, { 6, 602, 2048 }, { 7, 603, 2048 }, { 6, 604, 2048 }, { 7, 605, 2048 }, { 7, 606, 2048 }, { 8, 607, 2048 }, - { 4, 608, 2048 }, { 5, 609, 2048 }, { 5, 610, 2048 }, { 6, 611, 2048 }, { 5, 612, 2048 }, { 6, 613, 2048 }, { 6, 614, 2048 }, { 7, 615, 2048 }, - { 5, 616, 2048 }, { 6, 617, 2048 }, { 6, 618, 2048 }, { 7, 619, 2048 }, { 6, 620, 2048 }, { 7, 621, 2048 }, { 7, 622, 2048 }, { 8, 623, 2048 }, - { 5, 624, 2048 }, { 6, 625, 2048 }, { 6, 626, 2048 }, { 7, 627, 2048 }, { 6, 628, 2048 }, { 7, 629, 2048 }, { 7, 630, 2048 }, { 8, 631, 2048 }, - { 6, 632, 2048 }, { 7, 633, 2048 }, { 7, 634, 2048 }, { 8, 635, 2048 }, { 7, 636, 2048 }, { 8, 637, 2048 }, { 8, 638, 2048 }, { 9, 639, 2048 }, - { 3, 640, 2048 }, { 4, 641, 2048 }, { 4, 642, 2048 }, { 5, 643, 2048 }, { 4, 644, 2048 }, { 5, 645, 2048 }, { 5, 646, 2048 }, { 6, 647, 2048 }, - { 4, 648, 2048 }, { 5, 649, 2048 }, { 5, 650, 2048 }, { 6, 651, 2048 }, { 5, 652, 2048 }, { 6, 653, 2048 }, { 6, 654, 2048 }, { 7, 655, 2048 }, - { 4, 656, 2048 }, { 5, 657, 2048 }, { 5, 658, 2048 }, { 6, 659, 2048 }, { 5, 660, 2048 }, { 6, 661, 2048 }, { 6, 662, 2048 }, { 7, 663, 2048 }, - { 5, 664, 2048 }, { 6, 665, 2048 }, { 6, 666, 2048 }, { 7, 667, 2048 }, { 6, 668, 2048 }, { 7, 669, 2048 }, { 7, 670, 2048 }, { 8, 671, 2048 }, - { 4, 672, 2048 }, { 5, 673, 2048 }, { 5, 674, 2048 }, { 6, 675, 2048 }, { 5, 676, 2048 }, { 6, 677, 2048 }, { 6, 678, 2048 }, { 7, 679, 2048 }, - { 5, 680, 2048 }, { 6, 681, 2048 }, { 6, 682, 2048 }, { 7, 683, 2048 }, { 6, 684, 2048 }, { 7, 685, 2048 }, { 7, 686, 2048 }, { 8, 687, 2048 }, - { 5, 688, 2048 }, { 6, 689, 2048 }, { 6, 690, 2048 }, { 7, 691, 2048 }, { 6, 692, 2048 }, { 7, 693, 2048 }, { 7, 694, 2048 }, { 8, 695, 2048 }, - { 6, 696, 2048 }, { 7, 697, 2048 }, { 7, 698, 2048 }, { 8, 699, 2048 }, { 7, 700, 2048 }, { 8, 701, 2048 }, { 8, 702, 2048 }, { 9, 703, 2048 }, - { 4, 704, 2048 }, { 5, 705, 2048 }, { 5, 706, 2048 }, { 6, 707, 2048 }, { 5, 708, 2048 }, { 6, 709, 2048 }, { 6, 710, 2048 }, { 7, 711, 2048 }, - { 5, 712, 2048 }, { 6, 713, 2048 }, { 6, 714, 2048 }, { 7, 715, 2048 }, { 6, 716, 2048 }, { 7, 717, 2048 }, { 7, 718, 2048 }, { 8, 719, 2048 }, - { 5, 720, 2048 }, { 6, 721, 2048 }, { 6, 722, 2048 }, { 7, 723, 2048 }, { 6, 724, 2048 }, { 7, 725, 2048 }, { 7, 726, 2048 }, { 8, 727, 2048 }, - { 6, 728, 2048 }, { 7, 729, 2048 }, { 7, 730, 2048 }, { 8, 731, 2048 }, { 7, 732, 2048 }, { 8, 733, 2048 }, { 8, 734, 2048 }, { 9, 735, 2048 }, - { 5, 736, 2048 }, { 6, 737, 2048 }, { 6, 738, 2048 }, { 7, 739, 2048 }, { 6, 740, 2048 }, { 7, 741, 2048 }, { 7, 742, 2048 }, { 8, 743, 2048 }, - { 6, 744, 2048 }, { 7, 745, 2048 }, { 7, 746, 2048 }, { 8, 747, 2048 }, { 7, 748, 2048 }, { 8, 749, 2048 }, { 8, 750, 2048 }, { 9, 751, 2048 }, - { 6, 752, 2048 }, { 7, 753, 2048 }, { 7, 754, 2048 }, { 8, 755, 2048 }, { 7, 756, 2048 }, { 8, 757, 2048 }, { 8, 758, 2048 }, { 9, 759, 2048 }, - { 7, 760, 2048 }, { 8, 761, 2048 }, { 8, 762, 2048 }, { 9, 763, 2048 }, { 8, 764, 2048 }, { 9, 765, 2048 }, { 9, 766, 2048 }, { 10, 767, 2048 }, - { 3, 768, 2048 }, { 4, 769, 2048 }, { 4, 770, 2048 }, { 5, 771, 2048 }, { 4, 772, 2048 }, { 5, 773, 2048 }, { 5, 774, 2048 }, { 6, 775, 2048 }, - { 4, 776, 2048 }, { 5, 777, 2048 }, { 5, 778, 2048 }, { 6, 779, 2048 }, { 5, 780, 2048 }, { 6, 781, 2048 }, { 6, 782, 2048 }, { 7, 783, 2048 }, - { 4, 784, 2048 }, { 5, 785, 2048 }, { 5, 786, 2048 }, { 6, 787, 2048 }, { 5, 788, 2048 }, { 6, 789, 2048 }, { 6, 790, 2048 }, { 7, 791, 2048 }, - { 5, 792, 2048 }, { 6, 793, 2048 }, { 6, 794, 2048 }, { 7, 795, 2048 }, { 6, 796, 2048 }, { 7, 797, 2048 }, { 7, 798, 2048 }, { 8, 799, 2048 }, - { 4, 800, 2048 }, { 5, 801, 2048 }, { 5, 802, 2048 }, { 6, 803, 2048 }, { 5, 804, 2048 }, { 6, 805, 2048 }, { 6, 806, 2048 }, { 7, 807, 2048 }, - { 5, 808, 2048 }, { 6, 809, 2048 }, { 6, 810, 2048 }, { 7, 811, 2048 }, { 6, 812, 2048 }, { 7, 813, 2048 }, { 7, 814, 2048 }, { 8, 815, 2048 }, - { 5, 816, 2048 }, { 6, 817, 2048 }, { 6, 818, 2048 }, { 7, 819, 2048 }, { 6, 820, 2048 }, { 7, 821, 2048 }, { 7, 822, 2048 }, { 8, 823, 2048 }, - { 6, 824, 2048 }, { 7, 825, 2048 }, { 7, 826, 2048 }, { 8, 827, 2048 }, { 7, 828, 2048 }, { 8, 829, 2048 }, { 8, 830, 2048 }, { 9, 831, 2048 }, - { 4, 832, 2048 }, { 5, 833, 2048 }, { 5, 834, 2048 }, { 6, 835, 2048 }, { 5, 836, 2048 }, { 6, 837, 2048 }, { 6, 838, 2048 }, { 7, 839, 2048 }, - { 5, 840, 2048 }, { 6, 841, 2048 }, { 6, 842, 2048 }, { 7, 843, 2048 }, { 6, 844, 2048 }, { 7, 845, 2048 }, { 7, 846, 2048 }, { 8, 847, 2048 }, - { 5, 848, 2048 }, { 6, 849, 2048 }, { 6, 850, 2048 }, { 7, 851, 2048 }, { 6, 852, 2048 }, { 7, 853, 2048 }, { 7, 854, 2048 }, { 8, 855, 2048 }, - { 6, 856, 2048 }, { 7, 857, 2048 }, { 7, 858, 2048 }, { 8, 859, 2048 }, { 7, 860, 2048 }, { 8, 861, 2048 }, { 8, 862, 2048 }, { 9, 863, 2048 }, - { 5, 864, 2048 }, { 6, 865, 2048 }, { 6, 866, 2048 }, { 7, 867, 2048 }, { 6, 868, 2048 }, { 7, 869, 2048 }, { 7, 870, 2048 }, { 8, 871, 2048 }, - { 6, 872, 2048 }, { 7, 873, 2048 }, { 7, 874, 2048 }, { 8, 875, 2048 }, { 7, 876, 2048 }, { 8, 877, 2048 }, { 8, 878, 2048 }, { 9, 879, 2048 }, - { 6, 880, 2048 }, { 7, 881, 2048 }, { 7, 882, 2048 }, { 8, 883, 2048 }, { 7, 884, 2048 }, { 8, 885, 2048 }, { 8, 886, 2048 }, { 9, 887, 2048 }, - { 7, 888, 2048 }, { 8, 889, 2048 }, { 8, 890, 2048 }, { 9, 891, 2048 }, { 8, 892, 2048 }, { 9, 893, 2048 }, { 9, 894, 2048 }, { 10, 895, 2048 }, - { 4, 896, 2048 }, { 5, 897, 2048 }, { 5, 898, 2048 }, { 6, 899, 2048 }, { 5, 900, 2048 }, { 6, 901, 2048 }, { 6, 902, 2048 }, { 7, 903, 2048 }, - { 5, 904, 2048 }, { 6, 905, 2048 }, { 6, 906, 2048 }, { 7, 907, 2048 }, { 6, 908, 2048 }, { 7, 909, 2048 }, { 7, 910, 2048 }, { 8, 911, 2048 }, - { 5, 912, 2048 }, { 6, 913, 2048 }, { 6, 914, 2048 }, { 7, 915, 2048 }, { 6, 916, 2048 }, { 7, 917, 2048 }, { 7, 918, 2048 }, { 8, 919, 2048 }, - { 6, 920, 2048 }, { 7, 921, 2048 }, { 7, 922, 2048 }, { 8, 923, 2048 }, { 7, 924, 2048 }, { 8, 925, 2048 }, { 8, 926, 2048 }, { 9, 927, 2048 }, - { 5, 928, 2048 }, { 6, 929, 2048 }, { 6, 930, 2048 }, { 7, 931, 2048 }, { 6, 932, 2048 }, { 7, 933, 2048 }, { 7, 934, 2048 }, { 8, 935, 2048 }, - { 6, 936, 2048 }, { 7, 937, 2048 }, { 7, 938, 2048 }, { 8, 939, 2048 }, { 7, 940, 2048 }, { 8, 941, 2048 }, { 8, 942, 2048 }, { 9, 943, 2048 }, - { 6, 944, 2048 }, { 7, 945, 2048 }, { 7, 946, 2048 }, { 8, 947, 2048 }, { 7, 948, 2048 }, { 8, 949, 2048 }, { 8, 950, 2048 }, { 9, 951, 2048 }, - { 7, 952, 2048 }, { 8, 953, 2048 }, { 8, 954, 2048 }, { 9, 955, 2048 }, { 8, 956, 2048 }, { 9, 957, 2048 }, { 9, 958, 2048 }, { 10, 959, 2048 }, - { 5, 960, 2048 }, { 6, 961, 2048 }, { 6, 962, 2048 }, { 7, 963, 2048 }, { 6, 964, 2048 }, { 7, 965, 2048 }, { 7, 966, 2048 }, { 8, 967, 2048 }, - { 6, 968, 2048 }, { 7, 969, 2048 }, { 7, 970, 2048 }, { 8, 971, 2048 }, { 7, 972, 2048 }, { 8, 973, 2048 }, { 8, 974, 2048 }, { 9, 975, 2048 }, - { 6, 976, 2048 }, { 7, 977, 2048 }, { 7, 978, 2048 }, { 8, 979, 2048 }, { 7, 980, 2048 }, { 8, 981, 2048 }, { 8, 982, 2048 }, { 9, 983, 2048 }, - { 7, 984, 2048 }, { 8, 985, 2048 }, { 8, 986, 2048 }, { 9, 987, 2048 }, { 8, 988, 2048 }, { 9, 989, 2048 }, { 9, 990, 2048 }, { 10, 991, 2048 }, - { 6, 992, 2048 }, { 7, 993, 2048 }, { 7, 994, 2048 }, { 8, 995, 2048 }, { 7, 996, 2048 }, { 8, 997, 2048 }, { 8, 998, 2048 }, { 9, 999, 2048 }, - { 7, 1000, 2048 }, { 8, 1001, 2048 }, { 8, 1002, 2048 }, { 9, 1003, 2048 }, { 8, 1004, 2048 }, { 9, 1005, 2048 }, { 9, 1006, 2048 }, { 10, 1007, 2048 }, - { 7, 1008, 2048 }, { 8, 1009, 2048 }, { 8, 1010, 2048 }, { 9, 1011, 2048 }, { 8, 1012, 2048 }, { 9, 1013, 2048 }, { 9, 1014, 2048 }, { 10, 1015, 2048 }, - { 8, 1016, 2048 }, { 9, 1017, 2048 }, { 9, 1018, 2048 }, { 10, 1019, 2048 }, { 9, 1020, 2048 }, { 10, 1021, 2048 }, { 10, 1022, 2048 }, { 11, 1023, 2048 }, - { 2, 1024, 2048 }, { 3, 1025, 2048 }, { 3, 1026, 2048 }, { 4, 1027, 2048 }, { 3, 1028, 2048 }, { 4, 1029, 2048 }, { 4, 1030, 2048 }, { 5, 1031, 2048 }, - { 3, 1032, 2048 }, { 4, 1033, 2048 }, { 4, 1034, 2048 }, { 5, 1035, 2048 }, { 4, 1036, 2048 }, { 5, 1037, 2048 }, { 5, 1038, 2048 }, { 6, 1039, 2048 }, - { 3, 1040, 2048 }, { 4, 1041, 2048 }, { 4, 1042, 2048 }, { 5, 1043, 2048 }, { 4, 1044, 2048 }, { 5, 1045, 2048 }, { 5, 1046, 2048 }, { 6, 1047, 2048 }, - { 4, 1048, 2048 }, { 5, 1049, 2048 }, { 5, 1050, 2048 }, { 6, 1051, 2048 }, { 5, 1052, 2048 }, { 6, 1053, 2048 }, { 6, 1054, 2048 }, { 7, 1055, 2048 }, - { 3, 1056, 2048 }, { 4, 1057, 2048 }, { 4, 1058, 2048 }, { 5, 1059, 2048 }, { 4, 1060, 2048 }, { 5, 1061, 2048 }, { 5, 1062, 2048 }, { 6, 1063, 2048 }, - { 4, 1064, 2048 }, { 5, 1065, 2048 }, { 5, 1066, 2048 }, { 6, 1067, 2048 }, { 5, 1068, 2048 }, { 6, 1069, 2048 }, { 6, 1070, 2048 }, { 7, 1071, 2048 }, - { 4, 1072, 2048 }, { 5, 1073, 2048 }, { 5, 1074, 2048 }, { 6, 1075, 2048 }, { 5, 1076, 2048 }, { 6, 1077, 2048 }, { 6, 1078, 2048 }, { 7, 1079, 2048 }, - { 5, 1080, 2048 }, { 6, 1081, 2048 }, { 6, 1082, 2048 }, { 7, 1083, 2048 }, { 6, 1084, 2048 }, { 7, 1085, 2048 }, { 7, 1086, 2048 }, { 8, 1087, 2048 }, - { 3, 1088, 2048 }, { 4, 1089, 2048 }, { 4, 1090, 2048 }, { 5, 1091, 2048 }, { 4, 1092, 2048 }, { 5, 1093, 2048 }, { 5, 1094, 2048 }, { 6, 1095, 2048 }, - { 4, 1096, 2048 }, { 5, 1097, 2048 }, { 5, 1098, 2048 }, { 6, 1099, 2048 }, { 5, 1100, 2048 }, { 6, 1101, 2048 }, { 6, 1102, 2048 }, { 7, 1103, 2048 }, - { 4, 1104, 2048 }, { 5, 1105, 2048 }, { 5, 1106, 2048 }, { 6, 1107, 2048 }, { 5, 1108, 2048 }, { 6, 1109, 2048 }, { 6, 1110, 2048 }, { 7, 1111, 2048 }, - { 5, 1112, 2048 }, { 6, 1113, 2048 }, { 6, 1114, 2048 }, { 7, 1115, 2048 }, { 6, 1116, 2048 }, { 7, 1117, 2048 }, { 7, 1118, 2048 }, { 8, 1119, 2048 }, - { 4, 1120, 2048 }, { 5, 1121, 2048 }, { 5, 1122, 2048 }, { 6, 1123, 2048 }, { 5, 1124, 2048 }, { 6, 1125, 2048 }, { 6, 1126, 2048 }, { 7, 1127, 2048 }, - { 5, 1128, 2048 }, { 6, 1129, 2048 }, { 6, 1130, 2048 }, { 7, 1131, 2048 }, { 6, 1132, 2048 }, { 7, 1133, 2048 }, { 7, 1134, 2048 }, { 8, 1135, 2048 }, - { 5, 1136, 2048 }, { 6, 1137, 2048 }, { 6, 1138, 2048 }, { 7, 1139, 2048 }, { 6, 1140, 2048 }, { 7, 1141, 2048 }, { 7, 1142, 2048 }, { 8, 1143, 2048 }, - { 6, 1144, 2048 }, { 7, 1145, 2048 }, { 7, 1146, 2048 }, { 8, 1147, 2048 }, { 7, 1148, 2048 }, { 8, 1149, 2048 }, { 8, 1150, 2048 }, { 9, 1151, 2048 }, - { 3, 1152, 2048 }, { 4, 1153, 2048 }, { 4, 1154, 2048 }, { 5, 1155, 2048 }, { 4, 1156, 2048 }, { 5, 1157, 2048 }, { 5, 1158, 2048 }, { 6, 1159, 2048 }, - { 4, 1160, 2048 }, { 5, 1161, 2048 }, { 5, 1162, 2048 }, { 6, 1163, 2048 }, { 5, 1164, 2048 }, { 6, 1165, 2048 }, { 6, 1166, 2048 }, { 7, 1167, 2048 }, - { 4, 1168, 2048 }, { 5, 1169, 2048 }, { 5, 1170, 2048 }, { 6, 1171, 2048 }, { 5, 1172, 2048 }, { 6, 1173, 2048 }, { 6, 1174, 2048 }, { 7, 1175, 2048 }, - { 5, 1176, 2048 }, { 6, 1177, 2048 }, { 6, 1178, 2048 }, { 7, 1179, 2048 }, { 6, 1180, 2048 }, { 7, 1181, 2048 }, { 7, 1182, 2048 }, { 8, 1183, 2048 }, - { 4, 1184, 2048 }, { 5, 1185, 2048 }, { 5, 1186, 2048 }, { 6, 1187, 2048 }, { 5, 1188, 2048 }, { 6, 1189, 2048 }, { 6, 1190, 2048 }, { 7, 1191, 2048 }, - { 5, 1192, 2048 }, { 6, 1193, 2048 }, { 6, 1194, 2048 }, { 7, 1195, 2048 }, { 6, 1196, 2048 }, { 7, 1197, 2048 }, { 7, 1198, 2048 }, { 8, 1199, 2048 }, - { 5, 1200, 2048 }, { 6, 1201, 2048 }, { 6, 1202, 2048 }, { 7, 1203, 2048 }, { 6, 1204, 2048 }, { 7, 1205, 2048 }, { 7, 1206, 2048 }, { 8, 1207, 2048 }, - { 6, 1208, 2048 }, { 7, 1209, 2048 }, { 7, 1210, 2048 }, { 8, 1211, 2048 }, { 7, 1212, 2048 }, { 8, 1213, 2048 }, { 8, 1214, 2048 }, { 9, 1215, 2048 }, - { 4, 1216, 2048 }, { 5, 1217, 2048 }, { 5, 1218, 2048 }, { 6, 1219, 2048 }, { 5, 1220, 2048 }, { 6, 1221, 2048 }, { 6, 1222, 2048 }, { 7, 1223, 2048 }, - { 5, 1224, 2048 }, { 6, 1225, 2048 }, { 6, 1226, 2048 }, { 7, 1227, 2048 }, { 6, 1228, 2048 }, { 7, 1229, 2048 }, { 7, 1230, 2048 }, { 8, 1231, 2048 }, - { 5, 1232, 2048 }, { 6, 1233, 2048 }, { 6, 1234, 2048 }, { 7, 1235, 2048 }, { 6, 1236, 2048 }, { 7, 1237, 2048 }, { 7, 1238, 2048 }, { 8, 1239, 2048 }, - { 6, 1240, 2048 }, { 7, 1241, 2048 }, { 7, 1242, 2048 }, { 8, 1243, 2048 }, { 7, 1244, 2048 }, { 8, 1245, 2048 }, { 8, 1246, 2048 }, { 9, 1247, 2048 }, - { 5, 1248, 2048 }, { 6, 1249, 2048 }, { 6, 1250, 2048 }, { 7, 1251, 2048 }, { 6, 1252, 2048 }, { 7, 1253, 2048 }, { 7, 1254, 2048 }, { 8, 1255, 2048 }, - { 6, 1256, 2048 }, { 7, 1257, 2048 }, { 7, 1258, 2048 }, { 8, 1259, 2048 }, { 7, 1260, 2048 }, { 8, 1261, 2048 }, { 8, 1262, 2048 }, { 9, 1263, 2048 }, - { 6, 1264, 2048 }, { 7, 1265, 2048 }, { 7, 1266, 2048 }, { 8, 1267, 2048 }, { 7, 1268, 2048 }, { 8, 1269, 2048 }, { 8, 1270, 2048 }, { 9, 1271, 2048 }, - { 7, 1272, 2048 }, { 8, 1273, 2048 }, { 8, 1274, 2048 }, { 9, 1275, 2048 }, { 8, 1276, 2048 }, { 9, 1277, 2048 }, { 9, 1278, 2048 }, { 10, 1279, 2048 }, - { 3, 1280, 2048 }, { 4, 1281, 2048 }, { 4, 1282, 2048 }, { 5, 1283, 2048 }, { 4, 1284, 2048 }, { 5, 1285, 2048 }, { 5, 1286, 2048 }, { 6, 1287, 2048 }, - { 4, 1288, 2048 }, { 5, 1289, 2048 }, { 5, 1290, 2048 }, { 6, 1291, 2048 }, { 5, 1292, 2048 }, { 6, 1293, 2048 }, { 6, 1294, 2048 }, { 7, 1295, 2048 }, - { 4, 1296, 2048 }, { 5, 1297, 2048 }, { 5, 1298, 2048 }, { 6, 1299, 2048 }, { 5, 1300, 2048 }, { 6, 1301, 2048 }, { 6, 1302, 2048 }, { 7, 1303, 2048 }, - { 5, 1304, 2048 }, { 6, 1305, 2048 }, { 6, 1306, 2048 }, { 7, 1307, 2048 }, { 6, 1308, 2048 }, { 7, 1309, 2048 }, { 7, 1310, 2048 }, { 8, 1311, 2048 }, - { 4, 1312, 2048 }, { 5, 1313, 2048 }, { 5, 1314, 2048 }, { 6, 1315, 2048 }, { 5, 1316, 2048 }, { 6, 1317, 2048 }, { 6, 1318, 2048 }, { 7, 1319, 2048 }, - { 5, 1320, 2048 }, { 6, 1321, 2048 }, { 6, 1322, 2048 }, { 7, 1323, 2048 }, { 6, 1324, 2048 }, { 7, 1325, 2048 }, { 7, 1326, 2048 }, { 8, 1327, 2048 }, - { 5, 1328, 2048 }, { 6, 1329, 2048 }, { 6, 1330, 2048 }, { 7, 1331, 2048 }, { 6, 1332, 2048 }, { 7, 1333, 2048 }, { 7, 1334, 2048 }, { 8, 1335, 2048 }, - { 6, 1336, 2048 }, { 7, 1337, 2048 }, { 7, 1338, 2048 }, { 8, 1339, 2048 }, { 7, 1340, 2048 }, { 8, 1341, 2048 }, { 8, 1342, 2048 }, { 9, 1343, 2048 }, - { 4, 1344, 2048 }, { 5, 1345, 2048 }, { 5, 1346, 2048 }, { 6, 1347, 2048 }, { 5, 1348, 2048 }, { 6, 1349, 2048 }, { 6, 1350, 2048 }, { 7, 1351, 2048 }, - { 5, 1352, 2048 }, { 6, 1353, 2048 }, { 6, 1354, 2048 }, { 7, 1355, 2048 }, { 6, 1356, 2048 }, { 7, 1357, 2048 }, { 7, 1358, 2048 }, { 8, 1359, 2048 }, - { 5, 1360, 2048 }, { 6, 1361, 2048 }, { 6, 1362, 2048 }, { 7, 1363, 2048 }, { 6, 1364, 2048 }, { 7, 1365, 2048 }, { 7, 1366, 2048 }, { 8, 1367, 2048 }, - { 6, 1368, 2048 }, { 7, 1369, 2048 }, { 7, 1370, 2048 }, { 8, 1371, 2048 }, { 7, 1372, 2048 }, { 8, 1373, 2048 }, { 8, 1374, 2048 }, { 9, 1375, 2048 }, - { 5, 1376, 2048 }, { 6, 1377, 2048 }, { 6, 1378, 2048 }, { 7, 1379, 2048 }, { 6, 1380, 2048 }, { 7, 1381, 2048 }, { 7, 1382, 2048 }, { 8, 1383, 2048 }, - { 6, 1384, 2048 }, { 7, 1385, 2048 }, { 7, 1386, 2048 }, { 8, 1387, 2048 }, { 7, 1388, 2048 }, { 8, 1389, 2048 }, { 8, 1390, 2048 }, { 9, 1391, 2048 }, - { 6, 1392, 2048 }, { 7, 1393, 2048 }, { 7, 1394, 2048 }, { 8, 1395, 2048 }, { 7, 1396, 2048 }, { 8, 1397, 2048 }, { 8, 1398, 2048 }, { 9, 1399, 2048 }, - { 7, 1400, 2048 }, { 8, 1401, 2048 }, { 8, 1402, 2048 }, { 9, 1403, 2048 }, { 8, 1404, 2048 }, { 9, 1405, 2048 }, { 9, 1406, 2048 }, { 10, 1407, 2048 }, - { 4, 1408, 2048 }, { 5, 1409, 2048 }, { 5, 1410, 2048 }, { 6, 1411, 2048 }, { 5, 1412, 2048 }, { 6, 1413, 2048 }, { 6, 1414, 2048 }, { 7, 1415, 2048 }, - { 5, 1416, 2048 }, { 6, 1417, 2048 }, { 6, 1418, 2048 }, { 7, 1419, 2048 }, { 6, 1420, 2048 }, { 7, 1421, 2048 }, { 7, 1422, 2048 }, { 8, 1423, 2048 }, - { 5, 1424, 2048 }, { 6, 1425, 2048 }, { 6, 1426, 2048 }, { 7, 1427, 2048 }, { 6, 1428, 2048 }, { 7, 1429, 2048 }, { 7, 1430, 2048 }, { 8, 1431, 2048 }, - { 6, 1432, 2048 }, { 7, 1433, 2048 }, { 7, 1434, 2048 }, { 8, 1435, 2048 }, { 7, 1436, 2048 }, { 8, 1437, 2048 }, { 8, 1438, 2048 }, { 9, 1439, 2048 }, - { 5, 1440, 2048 }, { 6, 1441, 2048 }, { 6, 1442, 2048 }, { 7, 1443, 2048 }, { 6, 1444, 2048 }, { 7, 1445, 2048 }, { 7, 1446, 2048 }, { 8, 1447, 2048 }, - { 6, 1448, 2048 }, { 7, 1449, 2048 }, { 7, 1450, 2048 }, { 8, 1451, 2048 }, { 7, 1452, 2048 }, { 8, 1453, 2048 }, { 8, 1454, 2048 }, { 9, 1455, 2048 }, - { 6, 1456, 2048 }, { 7, 1457, 2048 }, { 7, 1458, 2048 }, { 8, 1459, 2048 }, { 7, 1460, 2048 }, { 8, 1461, 2048 }, { 8, 1462, 2048 }, { 9, 1463, 2048 }, - { 7, 1464, 2048 }, { 8, 1465, 2048 }, { 8, 1466, 2048 }, { 9, 1467, 2048 }, { 8, 1468, 2048 }, { 9, 1469, 2048 }, { 9, 1470, 2048 }, { 10, 1471, 2048 }, - { 5, 1472, 2048 }, { 6, 1473, 2048 }, { 6, 1474, 2048 }, { 7, 1475, 2048 }, { 6, 1476, 2048 }, { 7, 1477, 2048 }, { 7, 1478, 2048 }, { 8, 1479, 2048 }, - { 6, 1480, 2048 }, { 7, 1481, 2048 }, { 7, 1482, 2048 }, { 8, 1483, 2048 }, { 7, 1484, 2048 }, { 8, 1485, 2048 }, { 8, 1486, 2048 }, { 9, 1487, 2048 }, - { 6, 1488, 2048 }, { 7, 1489, 2048 }, { 7, 1490, 2048 }, { 8, 1491, 2048 }, { 7, 1492, 2048 }, { 8, 1493, 2048 }, { 8, 1494, 2048 }, { 9, 1495, 2048 }, - { 7, 1496, 2048 }, { 8, 1497, 2048 }, { 8, 1498, 2048 }, { 9, 1499, 2048 }, { 8, 1500, 2048 }, { 9, 1501, 2048 }, { 9, 1502, 2048 }, { 10, 1503, 2048 }, - { 6, 1504, 2048 }, { 7, 1505, 2048 }, { 7, 1506, 2048 }, { 8, 1507, 2048 }, { 7, 1508, 2048 }, { 8, 1509, 2048 }, { 8, 1510, 2048 }, { 9, 1511, 2048 }, - { 7, 1512, 2048 }, { 8, 1513, 2048 }, { 8, 1514, 2048 }, { 9, 1515, 2048 }, { 8, 1516, 2048 }, { 9, 1517, 2048 }, { 9, 1518, 2048 }, { 10, 1519, 2048 }, - { 7, 1520, 2048 }, { 8, 1521, 2048 }, { 8, 1522, 2048 }, { 9, 1523, 2048 }, { 8, 1524, 2048 }, { 9, 1525, 2048 }, { 9, 1526, 2048 }, { 10, 1527, 2048 }, - { 8, 1528, 2048 }, { 9, 1529, 2048 }, { 9, 1530, 2048 }, { 10, 1531, 2048 }, { 9, 1532, 2048 }, { 10, 1533, 2048 }, { 10, 1534, 2048 }, { 11, 1535, 2048 }, - { 3, 1536, 2048 }, { 4, 1537, 2048 }, { 4, 1538, 2048 }, { 5, 1539, 2048 }, { 4, 1540, 2048 }, { 5, 1541, 2048 }, { 5, 1542, 2048 }, { 6, 1543, 2048 }, - { 4, 1544, 2048 }, { 5, 1545, 2048 }, { 5, 1546, 2048 }, { 6, 1547, 2048 }, { 5, 1548, 2048 }, { 6, 1549, 2048 }, { 6, 1550, 2048 }, { 7, 1551, 2048 }, - { 4, 1552, 2048 }, { 5, 1553, 2048 }, { 5, 1554, 2048 }, { 6, 1555, 2048 }, { 5, 1556, 2048 }, { 6, 1557, 2048 }, { 6, 1558, 2048 }, { 7, 1559, 2048 }, - { 5, 1560, 2048 }, { 6, 1561, 2048 }, { 6, 1562, 2048 }, { 7, 1563, 2048 }, { 6, 1564, 2048 }, { 7, 1565, 2048 }, { 7, 1566, 2048 }, { 8, 1567, 2048 }, - { 4, 1568, 2048 }, { 5, 1569, 2048 }, { 5, 1570, 2048 }, { 6, 1571, 2048 }, { 5, 1572, 2048 }, { 6, 1573, 2048 }, { 6, 1574, 2048 }, { 7, 1575, 2048 }, - { 5, 1576, 2048 }, { 6, 1577, 2048 }, { 6, 1578, 2048 }, { 7, 1579, 2048 }, { 6, 1580, 2048 }, { 7, 1581, 2048 }, { 7, 1582, 2048 }, { 8, 1583, 2048 }, - { 5, 1584, 2048 }, { 6, 1585, 2048 }, { 6, 1586, 2048 }, { 7, 1587, 2048 }, { 6, 1588, 2048 }, { 7, 1589, 2048 }, { 7, 1590, 2048 }, { 8, 1591, 2048 }, - { 6, 1592, 2048 }, { 7, 1593, 2048 }, { 7, 1594, 2048 }, { 8, 1595, 2048 }, { 7, 1596, 2048 }, { 8, 1597, 2048 }, { 8, 1598, 2048 }, { 9, 1599, 2048 }, - { 4, 1600, 2048 }, { 5, 1601, 2048 }, { 5, 1602, 2048 }, { 6, 1603, 2048 }, { 5, 1604, 2048 }, { 6, 1605, 2048 }, { 6, 1606, 2048 }, { 7, 1607, 2048 }, - { 5, 1608, 2048 }, { 6, 1609, 2048 }, { 6, 1610, 2048 }, { 7, 1611, 2048 }, { 6, 1612, 2048 }, { 7, 1613, 2048 }, { 7, 1614, 2048 }, { 8, 1615, 2048 }, - { 5, 1616, 2048 }, { 6, 1617, 2048 }, { 6, 1618, 2048 }, { 7, 1619, 2048 }, { 6, 1620, 2048 }, { 7, 1621, 2048 }, { 7, 1622, 2048 }, { 8, 1623, 2048 }, - { 6, 1624, 2048 }, { 7, 1625, 2048 }, { 7, 1626, 2048 }, { 8, 1627, 2048 }, { 7, 1628, 2048 }, { 8, 1629, 2048 }, { 8, 1630, 2048 }, { 9, 1631, 2048 }, - { 5, 1632, 2048 }, { 6, 1633, 2048 }, { 6, 1634, 2048 }, { 7, 1635, 2048 }, { 6, 1636, 2048 }, { 7, 1637, 2048 }, { 7, 1638, 2048 }, { 8, 1639, 2048 }, - { 6, 1640, 2048 }, { 7, 1641, 2048 }, { 7, 1642, 2048 }, { 8, 1643, 2048 }, { 7, 1644, 2048 }, { 8, 1645, 2048 }, { 8, 1646, 2048 }, { 9, 1647, 2048 }, - { 6, 1648, 2048 }, { 7, 1649, 2048 }, { 7, 1650, 2048 }, { 8, 1651, 2048 }, { 7, 1652, 2048 }, { 8, 1653, 2048 }, { 8, 1654, 2048 }, { 9, 1655, 2048 }, - { 7, 1656, 2048 }, { 8, 1657, 2048 }, { 8, 1658, 2048 }, { 9, 1659, 2048 }, { 8, 1660, 2048 }, { 9, 1661, 2048 }, { 9, 1662, 2048 }, { 10, 1663, 2048 }, - { 4, 1664, 2048 }, { 5, 1665, 2048 }, { 5, 1666, 2048 }, { 6, 1667, 2048 }, { 5, 1668, 2048 }, { 6, 1669, 2048 }, { 6, 1670, 2048 }, { 7, 1671, 2048 }, - { 5, 1672, 2048 }, { 6, 1673, 2048 }, { 6, 1674, 2048 }, { 7, 1675, 2048 }, { 6, 1676, 2048 }, { 7, 1677, 2048 }, { 7, 1678, 2048 }, { 8, 1679, 2048 }, - { 5, 1680, 2048 }, { 6, 1681, 2048 }, { 6, 1682, 2048 }, { 7, 1683, 2048 }, { 6, 1684, 2048 }, { 7, 1685, 2048 }, { 7, 1686, 2048 }, { 8, 1687, 2048 }, - { 6, 1688, 2048 }, { 7, 1689, 2048 }, { 7, 1690, 2048 }, { 8, 1691, 2048 }, { 7, 1692, 2048 }, { 8, 1693, 2048 }, { 8, 1694, 2048 }, { 9, 1695, 2048 }, - { 5, 1696, 2048 }, { 6, 1697, 2048 }, { 6, 1698, 2048 }, { 7, 1699, 2048 }, { 6, 1700, 2048 }, { 7, 1701, 2048 }, { 7, 1702, 2048 }, { 8, 1703, 2048 }, - { 6, 1704, 2048 }, { 7, 1705, 2048 }, { 7, 1706, 2048 }, { 8, 1707, 2048 }, { 7, 1708, 2048 }, { 8, 1709, 2048 }, { 8, 1710, 2048 }, { 9, 1711, 2048 }, - { 6, 1712, 2048 }, { 7, 1713, 2048 }, { 7, 1714, 2048 }, { 8, 1715, 2048 }, { 7, 1716, 2048 }, { 8, 1717, 2048 }, { 8, 1718, 2048 }, { 9, 1719, 2048 }, - { 7, 1720, 2048 }, { 8, 1721, 2048 }, { 8, 1722, 2048 }, { 9, 1723, 2048 }, { 8, 1724, 2048 }, { 9, 1725, 2048 }, { 9, 1726, 2048 }, { 10, 1727, 2048 }, - { 5, 1728, 2048 }, { 6, 1729, 2048 }, { 6, 1730, 2048 }, { 7, 1731, 2048 }, { 6, 1732, 2048 }, { 7, 1733, 2048 }, { 7, 1734, 2048 }, { 8, 1735, 2048 }, - { 6, 1736, 2048 }, { 7, 1737, 2048 }, { 7, 1738, 2048 }, { 8, 1739, 2048 }, { 7, 1740, 2048 }, { 8, 1741, 2048 }, { 8, 1742, 2048 }, { 9, 1743, 2048 }, - { 6, 1744, 2048 }, { 7, 1745, 2048 }, { 7, 1746, 2048 }, { 8, 1747, 2048 }, { 7, 1748, 2048 }, { 8, 1749, 2048 }, { 8, 1750, 2048 }, { 9, 1751, 2048 }, - { 7, 1752, 2048 }, { 8, 1753, 2048 }, { 8, 1754, 2048 }, { 9, 1755, 2048 }, { 8, 1756, 2048 }, { 9, 1757, 2048 }, { 9, 1758, 2048 }, { 10, 1759, 2048 }, - { 6, 1760, 2048 }, { 7, 1761, 2048 }, { 7, 1762, 2048 }, { 8, 1763, 2048 }, { 7, 1764, 2048 }, { 8, 1765, 2048 }, { 8, 1766, 2048 }, { 9, 1767, 2048 }, - { 7, 1768, 2048 }, { 8, 1769, 2048 }, { 8, 1770, 2048 }, { 9, 1771, 2048 }, { 8, 1772, 2048 }, { 9, 1773, 2048 }, { 9, 1774, 2048 }, { 10, 1775, 2048 }, - { 7, 1776, 2048 }, { 8, 1777, 2048 }, { 8, 1778, 2048 }, { 9, 1779, 2048 }, { 8, 1780, 2048 }, { 9, 1781, 2048 }, { 9, 1782, 2048 }, { 10, 1783, 2048 }, - { 8, 1784, 2048 }, { 9, 1785, 2048 }, { 9, 1786, 2048 }, { 10, 1787, 2048 }, { 9, 1788, 2048 }, { 10, 1789, 2048 }, { 10, 1790, 2048 }, { 11, 1791, 2048 }, - { 4, 1792, 2048 }, { 5, 1793, 2048 }, { 5, 1794, 2048 }, { 6, 1795, 2048 }, { 5, 1796, 2048 }, { 6, 1797, 2048 }, { 6, 1798, 2048 }, { 7, 1799, 2048 }, - { 5, 1800, 2048 }, { 6, 1801, 2048 }, { 6, 1802, 2048 }, { 7, 1803, 2048 }, { 6, 1804, 2048 }, { 7, 1805, 2048 }, { 7, 1806, 2048 }, { 8, 1807, 2048 }, - { 5, 1808, 2048 }, { 6, 1809, 2048 }, { 6, 1810, 2048 }, { 7, 1811, 2048 }, { 6, 1812, 2048 }, { 7, 1813, 2048 }, { 7, 1814, 2048 }, { 8, 1815, 2048 }, - { 6, 1816, 2048 }, { 7, 1817, 2048 }, { 7, 1818, 2048 }, { 8, 1819, 2048 }, { 7, 1820, 2048 }, { 8, 1821, 2048 }, { 8, 1822, 2048 }, { 9, 1823, 2048 }, - { 5, 1824, 2048 }, { 6, 1825, 2048 }, { 6, 1826, 2048 }, { 7, 1827, 2048 }, { 6, 1828, 2048 }, { 7, 1829, 2048 }, { 7, 1830, 2048 }, { 8, 1831, 2048 }, - { 6, 1832, 2048 }, { 7, 1833, 2048 }, { 7, 1834, 2048 }, { 8, 1835, 2048 }, { 7, 1836, 2048 }, { 8, 1837, 2048 }, { 8, 1838, 2048 }, { 9, 1839, 2048 }, - { 6, 1840, 2048 }, { 7, 1841, 2048 }, { 7, 1842, 2048 }, { 8, 1843, 2048 }, { 7, 1844, 2048 }, { 8, 1845, 2048 }, { 8, 1846, 2048 }, { 9, 1847, 2048 }, - { 7, 1848, 2048 }, { 8, 1849, 2048 }, { 8, 1850, 2048 }, { 9, 1851, 2048 }, { 8, 1852, 2048 }, { 9, 1853, 2048 }, { 9, 1854, 2048 }, { 10, 1855, 2048 }, - { 5, 1856, 2048 }, { 6, 1857, 2048 }, { 6, 1858, 2048 }, { 7, 1859, 2048 }, { 6, 1860, 2048 }, { 7, 1861, 2048 }, { 7, 1862, 2048 }, { 8, 1863, 2048 }, - { 6, 1864, 2048 }, { 7, 1865, 2048 }, { 7, 1866, 2048 }, { 8, 1867, 2048 }, { 7, 1868, 2048 }, { 8, 1869, 2048 }, { 8, 1870, 2048 }, { 9, 1871, 2048 }, - { 6, 1872, 2048 }, { 7, 1873, 2048 }, { 7, 1874, 2048 }, { 8, 1875, 2048 }, { 7, 1876, 2048 }, { 8, 1877, 2048 }, { 8, 1878, 2048 }, { 9, 1879, 2048 }, - { 7, 1880, 2048 }, { 8, 1881, 2048 }, { 8, 1882, 2048 }, { 9, 1883, 2048 }, { 8, 1884, 2048 }, { 9, 1885, 2048 }, { 9, 1886, 2048 }, { 10, 1887, 2048 }, - { 6, 1888, 2048 }, { 7, 1889, 2048 }, { 7, 1890, 2048 }, { 8, 1891, 2048 }, { 7, 1892, 2048 }, { 8, 1893, 2048 }, { 8, 1894, 2048 }, { 9, 1895, 2048 }, - { 7, 1896, 2048 }, { 8, 1897, 2048 }, { 8, 1898, 2048 }, { 9, 1899, 2048 }, { 8, 1900, 2048 }, { 9, 1901, 2048 }, { 9, 1902, 2048 }, { 10, 1903, 2048 }, - { 7, 1904, 2048 }, { 8, 1905, 2048 }, { 8, 1906, 2048 }, { 9, 1907, 2048 }, { 8, 1908, 2048 }, { 9, 1909, 2048 }, { 9, 1910, 2048 }, { 10, 1911, 2048 }, - { 8, 1912, 2048 }, { 9, 1913, 2048 }, { 9, 1914, 2048 }, { 10, 1915, 2048 }, { 9, 1916, 2048 }, { 10, 1917, 2048 }, { 10, 1918, 2048 }, { 11, 1919, 2048 }, - { 5, 1920, 2048 }, { 6, 1921, 2048 }, { 6, 1922, 2048 }, { 7, 1923, 2048 }, { 6, 1924, 2048 }, { 7, 1925, 2048 }, { 7, 1926, 2048 }, { 8, 1927, 2048 }, - { 6, 1928, 2048 }, { 7, 1929, 2048 }, { 7, 1930, 2048 }, { 8, 1931, 2048 }, { 7, 1932, 2048 }, { 8, 1933, 2048 }, { 8, 1934, 2048 }, { 9, 1935, 2048 }, - { 6, 1936, 2048 }, { 7, 1937, 2048 }, { 7, 1938, 2048 }, { 8, 1939, 2048 }, { 7, 1940, 2048 }, { 8, 1941, 2048 }, { 8, 1942, 2048 }, { 9, 1943, 2048 }, - { 7, 1944, 2048 }, { 8, 1945, 2048 }, { 8, 1946, 2048 }, { 9, 1947, 2048 }, { 8, 1948, 2048 }, { 9, 1949, 2048 }, { 9, 1950, 2048 }, { 10, 1951, 2048 }, - { 6, 1952, 2048 }, { 7, 1953, 2048 }, { 7, 1954, 2048 }, { 8, 1955, 2048 }, { 7, 1956, 2048 }, { 8, 1957, 2048 }, { 8, 1958, 2048 }, { 9, 1959, 2048 }, - { 7, 1960, 2048 }, { 8, 1961, 2048 }, { 8, 1962, 2048 }, { 9, 1963, 2048 }, { 8, 1964, 2048 }, { 9, 1965, 2048 }, { 9, 1966, 2048 }, { 10, 1967, 2048 }, - { 7, 1968, 2048 }, { 8, 1969, 2048 }, { 8, 1970, 2048 }, { 9, 1971, 2048 }, { 8, 1972, 2048 }, { 9, 1973, 2048 }, { 9, 1974, 2048 }, { 10, 1975, 2048 }, - { 8, 1976, 2048 }, { 9, 1977, 2048 }, { 9, 1978, 2048 }, { 10, 1979, 2048 }, { 9, 1980, 2048 }, { 10, 1981, 2048 }, { 10, 1982, 2048 }, { 11, 1983, 2048 }, - { 6, 1984, 2048 }, { 7, 1985, 2048 }, { 7, 1986, 2048 }, { 8, 1987, 2048 }, { 7, 1988, 2048 }, { 8, 1989, 2048 }, { 8, 1990, 2048 }, { 9, 1991, 2048 }, - { 7, 1992, 2048 }, { 8, 1993, 2048 }, { 8, 1994, 2048 }, { 9, 1995, 2048 }, { 8, 1996, 2048 }, { 9, 1997, 2048 }, { 9, 1998, 2048 }, { 10, 1999, 2048 }, - { 7, 2000, 2048 }, { 8, 2001, 2048 }, { 8, 2002, 2048 }, { 9, 2003, 2048 }, { 8, 2004, 2048 }, { 9, 2005, 2048 }, { 9, 2006, 2048 }, { 10, 2007, 2048 }, - { 8, 2008, 2048 }, { 9, 2009, 2048 }, { 9, 2010, 2048 }, { 10, 2011, 2048 }, { 9, 2012, 2048 }, { 10, 2013, 2048 }, { 10, 2014, 2048 }, { 11, 2015, 2048 }, - { 7, 2016, 2048 }, { 8, 2017, 2048 }, { 8, 2018, 2048 }, { 9, 2019, 2048 }, { 8, 2020, 2048 }, { 9, 2021, 2048 }, { 9, 2022, 2048 }, { 10, 2023, 2048 }, - { 8, 2024, 2048 }, { 9, 2025, 2048 }, { 9, 2026, 2048 }, { 10, 2027, 2048 }, { 9, 2028, 2048 }, { 10, 2029, 2048 }, { 10, 2030, 2048 }, { 11, 2031, 2048 }, - { 8, 2032, 2048 }, { 9, 2033, 2048 }, { 9, 2034, 2048 }, { 10, 2035, 2048 }, { 9, 2036, 2048 }, { 10, 2037, 2048 }, { 10, 2038, 2048 }, { 11, 2039, 2048 }, - { 9, 2040, 2048 }, { 10, 2041, 2048 }, { 10, 2042, 2048 }, { 11, 2043, 2048 }, { 10, 2044, 2048 }, { 11, 2045, 2048 }, { 11, 2046, 2048 }, { 12, 2047, 2048 }, -#endif -#endif -#endif -#endif -#endif -#endif -}; - -/* find a hole and free as required, return -1 if no hole found */ -static int find_hole(void) -{ - unsigned x; - int y, z; - for (z = -1, y = INT_MAX, x = 0; x < FP_ENTRIES; x++) { - if (fp_cache[x].lru_count < y && fp_cache[x].lock == 0) { - z = x; - y = fp_cache[x].lru_count; - } - } - - /* decrease all */ - for (x = 0; x < FP_ENTRIES; x++) { - if (fp_cache[x].lru_count > 3) { - --(fp_cache[x].lru_count); - } - } - - /* free entry z */ - if (z >= 0 && fp_cache[z].g) { - mp_clear(&fp_cache[z].mu); - ecc_del_point(fp_cache[z].g); - fp_cache[z].g = NULL; - for (x = 0; x < (1U<x, &g->x) == MP_EQ && - mp_cmp(&fp_cache[x].g->y, &g->y) == MP_EQ && - mp_cmp(&fp_cache[x].g->z, &g->z) == MP_EQ) { - break; - } - } - if (x == FP_ENTRIES) { - x = -1; - } - return x; -} - -/* add a new base to the cache */ -static int add_entry(int idx, ecc_point *g) -{ - unsigned x, y; - - /* allocate base and LUT */ - fp_cache[idx].g = ecc_new_point(); - if (fp_cache[idx].g == NULL) { - return GEN_MEM_ERR; - } - - /* copy x and y */ - if ((mp_copy(&g->x, &fp_cache[idx].g->x) != MP_OKAY) || - (mp_copy(&g->y, &fp_cache[idx].g->y) != MP_OKAY) || - (mp_copy(&g->z, &fp_cache[idx].g->z) != MP_OKAY)) { - ecc_del_point(fp_cache[idx].g); - fp_cache[idx].g = NULL; - return GEN_MEM_ERR; - } - - for (x = 0; x < (1U<x, mu, modulus, - &fp_cache[idx].LUT[1]->x) != MP_OKAY) || - (mp_mulmod(&fp_cache[idx].g->y, mu, modulus, - &fp_cache[idx].LUT[1]->y) != MP_OKAY) || - (mp_mulmod(&fp_cache[idx].g->z, mu, modulus, - &fp_cache[idx].LUT[1]->z) != MP_OKAY)) { - err = MP_MULMOD_E; - } - } - - /* make all single bit entries */ - for (x = 1; x < FP_LUT; x++) { - if (err != MP_OKAY) - break; - if ((mp_copy(&fp_cache[idx].LUT[1<<(x-1)]->x, - &fp_cache[idx].LUT[1<x) != MP_OKAY) || - (mp_copy(&fp_cache[idx].LUT[1<<(x-1)]->y, - &fp_cache[idx].LUT[1<y) != MP_OKAY) || - (mp_copy(&fp_cache[idx].LUT[1<<(x-1)]->z, - &fp_cache[idx].LUT[1<z) != MP_OKAY)){ - err = MP_INIT_E; - break; - } else { - - /* now double it bitlen/FP_LUT times */ - for (y = 0; y < lut_gap; y++) { - if ((err = ecc_projective_dbl_point(fp_cache[idx].LUT[1<z, modulus, *mp); - - /* invert it */ - if (err == MP_OKAY) - err = mp_invmod(&fp_cache[idx].LUT[x]->z, modulus, - &fp_cache[idx].LUT[x]->z); - - if (err == MP_OKAY) - /* now square it */ - err = mp_sqrmod(&fp_cache[idx].LUT[x]->z, modulus, &tmp); - - if (err == MP_OKAY) - /* fix x */ - err = mp_mulmod(&fp_cache[idx].LUT[x]->x, &tmp, modulus, - &fp_cache[idx].LUT[x]->x); - - if (err == MP_OKAY) - /* get 1/z^3 */ - err = mp_mulmod(&tmp, &fp_cache[idx].LUT[x]->z, modulus, &tmp); - - if (err == MP_OKAY) - /* fix y */ - err = mp_mulmod(&fp_cache[idx].LUT[x]->y, &tmp, modulus, - &fp_cache[idx].LUT[x]->y); - - if (err == MP_OKAY) - /* free z */ - mp_clear(&fp_cache[idx].LUT[x]->z); - } - mp_clear(&tmp); - - if (err == MP_OKAY) - return MP_OKAY; - - /* err cleanup */ - for (y = 0; y < (1U< mp_unsigned_bin_size(modulus)) { - mp_int order; - if (mp_init(&order) != MP_OKAY) { - mp_clear(&tk); - return MP_INIT_E; - } - - /* find order */ - y = mp_unsigned_bin_size(modulus); - for (x = 0; ecc_sets[x].size; x++) { - if (y <= (unsigned)ecc_sets[x].size) break; - } - - /* back off if we are on the 521 bit curve */ - if (y == 66) --x; - - if ((err = mp_read_radix(&order, ecc_sets[x].order, 16)) != MP_OKAY) { - mp_clear(&order); - mp_clear(&tk); - return err; - } - - /* k must be less than modulus */ - if (mp_cmp(k, &order) != MP_LT) { - if ((err = mp_mod(k, &order, &tk)) != MP_OKAY) { - mp_clear(&tk); - mp_clear(&order); - return err; - } - } else { - mp_copy(k, &tk); - } - mp_clear(&order); - } else { - mp_copy(k, &tk); - } - - /* get bitlen and round up to next multiple of FP_LUT */ - bitlen = mp_unsigned_bin_size(modulus) << 3; - x = bitlen % FP_LUT; - if (x) { - bitlen += FP_LUT - x; - } - lut_gap = bitlen / FP_LUT; - - /* get the k value */ - if (mp_unsigned_bin_size(&tk) > (int)(KB_SIZE - 2)) { - mp_clear(&tk); - return BUFFER_E; - } - - /* store k */ -#ifdef CYASSL_SMALL_STACK - kb = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (kb == NULL) - return MEMORY_E; -#endif - - XMEMSET(kb, 0, KB_SIZE); - if ((err = mp_to_unsigned_bin(&tk, kb)) != MP_OKAY) { - mp_clear(&tk); - } - else { - /* let's reverse kb so it's little endian */ - x = 0; - y = mp_unsigned_bin_size(&tk) - 1; - mp_clear(&tk); - - while ((unsigned)x < y) { - z = kb[x]; kb[x] = kb[y]; kb[y] = z; - ++x; --y; - } - - /* at this point we can start, yipee */ - first = 1; - for (x = lut_gap-1; x >= 0; x--) { - /* extract FP_LUT bits from kb spread out by lut_gap bits and offset - by x bits from the start */ - bitpos = x; - for (y = z = 0; y < FP_LUT; y++) { - z |= ((kb[bitpos>>3] >> (bitpos&7)) & 1) << y; - bitpos += lut_gap; /* it's y*lut_gap + x, but here we can avoid - the mult in each loop */ - } - - /* double if not first */ - if (!first) { - if ((err = ecc_projective_dbl_point(R, R, modulus, - mp)) != MP_OKAY) { - break; - } - } - - /* add if not first, otherwise copy */ - if (!first && z) { - if ((err = ecc_projective_add_point(R, fp_cache[idx].LUT[z], R, - modulus, mp)) != MP_OKAY) { - break; - } - } else if (z) { - if ((mp_copy(&fp_cache[idx].LUT[z]->x, &R->x) != MP_OKAY) || - (mp_copy(&fp_cache[idx].LUT[z]->y, &R->y) != MP_OKAY) || - (mp_copy(&fp_cache[idx].mu, &R->z) != MP_OKAY)) { - err = GEN_MEM_ERR; - break; - } - first = 0; - } - } - } - - if (err == MP_OKAY) { - z = 0; - XMEMSET(kb, 0, KB_SIZE); - /* map R back from projective space */ - if (map) { - err = ecc_map(R, modulus, mp); - } else { - err = MP_OKAY; - } - } - -#ifdef CYASSL_SMALL_STACK - XFREE(kb, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - -#undef KB_SIZE - - return err; -} - -#ifdef ECC_SHAMIR -/* perform a fixed point ECC mulmod */ -static int accel_fp_mul2add(int idx1, int idx2, - mp_int* kA, mp_int* kB, - ecc_point *R, mp_int* modulus, mp_digit* mp) -{ -#define KB_SIZE 128 - -#ifdef CYASSL_SMALL_STACK - unsigned char* kb[2]; -#else - unsigned char kb[2][128]; -#endif - int x; - unsigned y, z, err, bitlen, bitpos, lut_gap, first, zA, zB; - mp_int tka; - mp_int tkb; - mp_int order; - - if (mp_init_multi(&tka, &tkb, 0, 0, 0, 0) != MP_OKAY) - return MP_INIT_E; - - /* if it's smaller than modulus we fine */ - if (mp_unsigned_bin_size(kA) > mp_unsigned_bin_size(modulus)) { - /* find order */ - y = mp_unsigned_bin_size(modulus); - for (x = 0; ecc_sets[x].size; x++) { - if (y <= (unsigned)ecc_sets[x].size) break; - } - - /* back off if we are on the 521 bit curve */ - if (y == 66) --x; - - if ((err = mp_init(&order)) != MP_OKAY) { - mp_clear(&tkb); - mp_clear(&tka); - return err; - } - if ((err = mp_read_radix(&order, ecc_sets[x].order, 16)) != MP_OKAY) { - mp_clear(&tkb); - mp_clear(&tka); - mp_clear(&order); - return err; - } - - /* kA must be less than modulus */ - if (mp_cmp(kA, &order) != MP_LT) { - if ((err = mp_mod(kA, &order, &tka)) != MP_OKAY) { - mp_clear(&tkb); - mp_clear(&tka); - mp_clear(&order); - return err; - } - } else { - mp_copy(kA, &tka); - } - mp_clear(&order); - } else { - mp_copy(kA, &tka); - } - - /* if it's smaller than modulus we fine */ - if (mp_unsigned_bin_size(kB) > mp_unsigned_bin_size(modulus)) { - /* find order */ - y = mp_unsigned_bin_size(modulus); - for (x = 0; ecc_sets[x].size; x++) { - if (y <= (unsigned)ecc_sets[x].size) break; - } - - /* back off if we are on the 521 bit curve */ - if (y == 66) --x; - - if ((err = mp_init(&order)) != MP_OKAY) { - mp_clear(&tkb); - mp_clear(&tka); - return err; - } - if ((err = mp_read_radix(&order, ecc_sets[x].order, 16)) != MP_OKAY) { - mp_clear(&tkb); - mp_clear(&tka); - mp_clear(&order); - return err; - } - - /* kB must be less than modulus */ - if (mp_cmp(kB, &order) != MP_LT) { - if ((err = mp_mod(kB, &order, &tkb)) != MP_OKAY) { - mp_clear(&tkb); - mp_clear(&tka); - mp_clear(&order); - return err; - } - } else { - mp_copy(kB, &tkb); - } - mp_clear(&order); - } else { - mp_copy(kB, &tkb); - } - - /* get bitlen and round up to next multiple of FP_LUT */ - bitlen = mp_unsigned_bin_size(modulus) << 3; - x = bitlen % FP_LUT; - if (x) { - bitlen += FP_LUT - x; - } - lut_gap = bitlen / FP_LUT; - - /* get the k value */ - if ((mp_unsigned_bin_size(&tka) > (int)(KB_SIZE - 2)) || - (mp_unsigned_bin_size(&tkb) > (int)(KB_SIZE - 2)) ) { - mp_clear(&tka); - mp_clear(&tkb); - return BUFFER_E; - } - - /* store k */ -#ifdef CYASSL_SMALL_STACK - kb[0] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (kb[0] == NULL) - return MEMORY_E; -#endif - - XMEMSET(kb[0], 0, KB_SIZE); - if ((err = mp_to_unsigned_bin(&tka, kb[0])) != MP_OKAY) { - mp_clear(&tka); - mp_clear(&tkb); - XFREE(kb[0], NULL, DYNAMIC_TYPE_TMP_BUFFER); - return err; - } - - /* let's reverse kb so it's little endian */ - x = 0; - y = mp_unsigned_bin_size(&tka) - 1; - mp_clear(&tka); - while ((unsigned)x < y) { - z = kb[0][x]; kb[0][x] = kb[0][y]; kb[0][y] = z; - ++x; --y; - } - - /* store b */ -#ifdef CYASSL_SMALL_STACK - kb[1] = (unsigned char*)XMALLOC(KB_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (kb[1] == NULL) { - XFREE(kb[0], NULL, DYNAMIC_TYPE_TMP_BUFFER); - return MEMORY_E; - } -#endif - - XMEMSET(kb[1], 0, KB_SIZE); - if ((err = mp_to_unsigned_bin(&tkb, kb[1])) != MP_OKAY) { - mp_clear(&tkb); - } - else { - x = 0; - y = mp_unsigned_bin_size(&tkb) - 1; - mp_clear(&tkb); - while ((unsigned)x < y) { - z = kb[1][x]; kb[1][x] = kb[1][y]; kb[1][y] = z; - ++x; --y; - } - - /* at this point we can start, yipee */ - first = 1; - for (x = lut_gap-1; x >= 0; x--) { - /* extract FP_LUT bits from kb spread out by lut_gap bits and - offset by x bits from the start */ - bitpos = x; - for (y = zA = zB = 0; y < FP_LUT; y++) { - zA |= ((kb[0][bitpos>>3] >> (bitpos&7)) & 1) << y; - zB |= ((kb[1][bitpos>>3] >> (bitpos&7)) & 1) << y; - bitpos += lut_gap; /* it's y*lut_gap + x, but here we can avoid - the mult in each loop */ - } - - /* double if not first */ - if (!first) { - if ((err = ecc_projective_dbl_point(R, R, modulus, - mp)) != MP_OKAY) { - break; - } - } - - /* add if not first, otherwise copy */ - if (!first) { - if (zA) { - if ((err = ecc_projective_add_point(R, fp_cache[idx1].LUT[zA], - R, modulus, mp)) != MP_OKAY) { - break; - } - } - if (zB) { - if ((err = ecc_projective_add_point(R, fp_cache[idx2].LUT[zB], - R, modulus, mp)) != MP_OKAY) { - break; - } - } - } else { - if (zA) { - if ((mp_copy(&fp_cache[idx1].LUT[zA]->x, &R->x) != MP_OKAY) || - (mp_copy(&fp_cache[idx1].LUT[zA]->y, &R->y) != MP_OKAY) || - (mp_copy(&fp_cache[idx1].mu, &R->z) != MP_OKAY)) { - err = GEN_MEM_ERR; - break; - } - first = 0; - } - if (zB && first == 0) { - if (zB) { - if ((err = ecc_projective_add_point(R, - fp_cache[idx2].LUT[zB], R, modulus, mp)) != MP_OKAY){ - break; - } - } - } else if (zB && first == 1) { - if ((mp_copy(&fp_cache[idx2].LUT[zB]->x, &R->x) != MP_OKAY) || - (mp_copy(&fp_cache[idx2].LUT[zB]->y, &R->y) != MP_OKAY) || - (mp_copy(&fp_cache[idx2].mu, &R->z) != MP_OKAY)) { - err = GEN_MEM_ERR; - break; - } - first = 0; - } - } - } - } - - XMEMSET(kb[0], 0, KB_SIZE); - XMEMSET(kb[1], 0, KB_SIZE); - -#ifdef CYASSL_SMALL_STACK - XFREE(kb[0], NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(kb[1], NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - -#undef KB_SIZE - - return ecc_map(R, modulus, mp); -} - -/** ECC Fixed Point mulmod global - Computes kA*A + kB*B = C using Shamir's Trick - A First point to multiply - kA What to multiple A by - B Second point to multiply - kB What to multiple B by - C [out] Destination point (can overlap with A or B) - modulus Modulus for curve - return MP_OKAY on success -*/ -int ecc_mul2add(ecc_point* A, mp_int* kA, - ecc_point* B, mp_int* kB, - ecc_point* C, mp_int* modulus) -{ - int idx1 = -1, idx2 = -1, err = MP_OKAY, mpInit = 0; - mp_digit mp; - mp_int mu; - - err = mp_init(&mu); - if (err != MP_OKAY) - return err; - -#ifndef HAVE_THREAD_LS - if (initMutex == 0) { - InitMutex(&ecc_fp_lock); - initMutex = 1; - } - if (LockMutex(&ecc_fp_lock) != 0) - return BAD_MUTEX_E; -#endif /* HAVE_THREAD_LS */ - - /* find point */ - idx1 = find_base(A); - - /* no entry? */ - if (idx1 == -1) { - /* find hole and add it */ - if ((idx1 = find_hole()) >= 0) { - err = add_entry(idx1, A); - } - } - if (err == MP_OKAY && idx1 != -1) { - /* increment LRU */ - ++(fp_cache[idx1].lru_count); - } - - if (err == MP_OKAY) - /* find point */ - idx2 = find_base(B); - - if (err == MP_OKAY) { - /* no entry? */ - if (idx2 == -1) { - /* find hole and add it */ - if ((idx2 = find_hole()) >= 0) - err = add_entry(idx2, B); - } - } - - if (err == MP_OKAY && idx2 != -1) { - /* increment LRU */ - ++(fp_cache[idx2].lru_count); - } - - if (err == MP_OKAY) { - /* if it's 2 build the LUT, if it's higher just use the LUT */ - if (idx1 >= 0 && fp_cache[idx1].lru_count == 2) { - /* compute mp */ - err = mp_montgomery_setup(modulus, &mp); - - if (err == MP_OKAY) { - mpInit = 1; - err = mp_montgomery_calc_normalization(&mu, modulus); - } - - if (err == MP_OKAY) - /* build the LUT */ - err = build_lut(idx1, modulus, &mp, &mu); - } - } - - if (err == MP_OKAY) { - /* if it's 2 build the LUT, if it's higher just use the LUT */ - if (idx2 >= 0 && fp_cache[idx2].lru_count == 2) { - if (mpInit == 0) { - /* compute mp */ - err = mp_montgomery_setup(modulus, &mp); - if (err == MP_OKAY) { - mpInit = 1; - err = mp_montgomery_calc_normalization(&mu, modulus); - } - } - - if (err == MP_OKAY) - /* build the LUT */ - err = build_lut(idx2, modulus, &mp, &mu); - } - } - - - if (err == MP_OKAY) { - if (idx1 >=0 && idx2 >= 0 && fp_cache[idx1].lru_count >= 2 && - fp_cache[idx2].lru_count >= 2) { - if (mpInit == 0) { - /* compute mp */ - err = mp_montgomery_setup(modulus, &mp); - } - if (err == MP_OKAY) - err = accel_fp_mul2add(idx1, idx2, kA, kB, C, modulus, &mp); - } else { - err = normal_ecc_mul2add(A, kA, B, kB, C, modulus); - } - } - -#ifndef HAVE_THREAD_LS - UnLockMutex(&ecc_fp_lock); -#endif /* HAVE_THREAD_LS */ - mp_clear(&mu); - - return err; -} -#endif - -/** ECC Fixed Point mulmod global - k The multiplicand - G Base point to multiply - R [out] Destination of product - modulus The modulus for the curve - map [boolean] If non-zero maps the point back to affine co-ordinates, - otherwise it's left in jacobian-montgomery form - return MP_OKAY if successful -*/ -int ecc_mulmod(mp_int* k, ecc_point *G, ecc_point *R, mp_int* modulus, - int map) -{ - int idx, err = MP_OKAY; - mp_digit mp; - mp_int mu; - int mpSetup = 0; - - if (mp_init(&mu) != MP_OKAY) - return MP_INIT_E; - -#ifndef HAVE_THREAD_LS - if (initMutex == 0) { - InitMutex(&ecc_fp_lock); - initMutex = 1; - } - - if (LockMutex(&ecc_fp_lock) != 0) - return BAD_MUTEX_E; -#endif /* HAVE_THREAD_LS */ - - /* find point */ - idx = find_base(G); - - /* no entry? */ - if (idx == -1) { - /* find hole and add it */ - idx = find_hole(); - - if (idx >= 0) - err = add_entry(idx, G); - } - if (err == MP_OKAY && idx != -1) { - /* increment LRU */ - ++(fp_cache[idx].lru_count); - } - - - if (err == MP_OKAY) { - /* if it's 2 build the LUT, if it's higher just use the LUT */ - if (idx >= 0 && fp_cache[idx].lru_count == 2) { - /* compute mp */ - err = mp_montgomery_setup(modulus, &mp); - - if (err == MP_OKAY) { - /* compute mu */ - mpSetup = 1; - err = mp_montgomery_calc_normalization(&mu, modulus); - } - - if (err == MP_OKAY) - /* build the LUT */ - err = build_lut(idx, modulus, &mp, &mu); - } - } - - if (err == MP_OKAY) { - if (idx >= 0 && fp_cache[idx].lru_count >= 2) { - if (mpSetup == 0) { - /* compute mp */ - err = mp_montgomery_setup(modulus, &mp); - } - if (err == MP_OKAY) - err = accel_fp_mul(idx, k, R, modulus, &mp, map); - } else { - err = normal_ecc_mulmod(k, G, R, modulus, map); - } - } - -#ifndef HAVE_THREAD_LS - UnLockMutex(&ecc_fp_lock); -#endif /* HAVE_THREAD_LS */ - mp_clear(&mu); - - return err; -} - -/* helper function for freeing the cache ... - must be called with the cache mutex locked */ -static void ecc_fp_free_cache(void) -{ - unsigned x, y; - for (x = 0; x < FP_ENTRIES; x++) { - if (fp_cache[x].g != NULL) { - for (y = 0; y < (1U<protocol == 0) - return NULL; - - if (ctx->protocol == REQ_RESP_CLIENT) { - if (ctx->cliSt == ecCLI_INIT) { - ctx->cliSt = ecCLI_SALT_GET; - return ctx->clientSalt; - } - else { - ctx->cliSt = ecCLI_BAD_STATE; - return NULL; - } - } - else if (ctx->protocol == REQ_RESP_SERVER) { - if (ctx->srvSt == ecSRV_INIT) { - ctx->srvSt = ecSRV_SALT_GET; - return ctx->serverSalt; - } - else { - ctx->srvSt = ecSRV_BAD_STATE; - return NULL; - } - } - - return NULL; -} - - -/* optional set info, can be called before or after set_peer_salt */ -int ecc_ctx_set_info(ecEncCtx* ctx, const byte* info, int sz) -{ - if (ctx == NULL || info == 0 || sz < 0) - return BAD_FUNC_ARG; - - ctx->kdfInfo = info; - ctx->kdfInfoSz = sz; - - return 0; -} - - -static const char* exchange_info = "Secure Message Exchange"; - -int ecc_ctx_set_peer_salt(ecEncCtx* ctx, const byte* salt) -{ - byte tmp[EXCHANGE_SALT_SZ/2]; - int halfSz = EXCHANGE_SALT_SZ/2; - - if (ctx == NULL || ctx->protocol == 0 || salt == NULL) - return BAD_FUNC_ARG; - - if (ctx->protocol == REQ_RESP_CLIENT) { - XMEMCPY(ctx->serverSalt, salt, EXCHANGE_SALT_SZ); - if (ctx->cliSt == ecCLI_SALT_GET) - ctx->cliSt = ecCLI_SALT_SET; - else { - ctx->cliSt = ecCLI_BAD_STATE; - return BAD_ENC_STATE_E; - } - } - else { - XMEMCPY(ctx->clientSalt, salt, EXCHANGE_SALT_SZ); - if (ctx->srvSt == ecSRV_SALT_GET) - ctx->srvSt = ecSRV_SALT_SET; - else { - ctx->srvSt = ecSRV_BAD_STATE; - return BAD_ENC_STATE_E; - } - } - - /* mix half and half */ - /* tmp stores 2nd half of client before overwrite */ - XMEMCPY(tmp, ctx->clientSalt + halfSz, halfSz); - XMEMCPY(ctx->clientSalt + halfSz, ctx->serverSalt, halfSz); - XMEMCPY(ctx->serverSalt, tmp, halfSz); - - ctx->kdfSalt = ctx->clientSalt; - ctx->kdfSaltSz = EXCHANGE_SALT_SZ; - - ctx->macSalt = ctx->serverSalt; - ctx->macSaltSz = EXCHANGE_SALT_SZ; - - if (ctx->kdfInfo == NULL) { - /* default info */ - ctx->kdfInfo = (const byte*)exchange_info; - ctx->kdfInfoSz = EXCHANGE_INFO_SZ; - } - - return 0; -} - - -static int ecc_ctx_set_salt(ecEncCtx* ctx, int flags, RNG* rng) -{ - byte* saltBuffer = NULL; - - if (ctx == NULL || rng == NULL || flags == 0) - return BAD_FUNC_ARG; - - saltBuffer = (flags == REQ_RESP_CLIENT) ? ctx->clientSalt : ctx->serverSalt; - - return RNG_GenerateBlock(rng, saltBuffer, EXCHANGE_SALT_SZ); -} - - -static void ecc_ctx_init(ecEncCtx* ctx, int flags) -{ - if (ctx) { - XMEMSET(ctx, 0, sizeof(ecEncCtx)); - - ctx->encAlgo = ecAES_128_CBC; - ctx->kdfAlgo = ecHKDF_SHA256; - ctx->macAlgo = ecHMAC_SHA256; - ctx->protocol = (byte)flags; - - if (flags == REQ_RESP_CLIENT) - ctx->cliSt = ecCLI_INIT; - if (flags == REQ_RESP_SERVER) - ctx->srvSt = ecSRV_INIT; - } -} - - -/* allow ecc context reset so user doesn't have to init/free for resue */ -int ecc_ctx_reset(ecEncCtx* ctx, RNG* rng) -{ - if (ctx == NULL || rng == NULL) - return BAD_FUNC_ARG; - - ecc_ctx_init(ctx, ctx->protocol); - return ecc_ctx_set_salt(ctx, ctx->protocol, rng); -} - - -/* alloc/init and set defaults, return new Context */ -ecEncCtx* ecc_ctx_new(int flags, RNG* rng) -{ - int ret = 0; - ecEncCtx* ctx = (ecEncCtx*)XMALLOC(sizeof(ecEncCtx), 0, DYNAMIC_TYPE_ECC); - - if (ctx) - ctx->protocol = (byte)flags; - - ret = ecc_ctx_reset(ctx, rng); - if (ret != 0) { - ecc_ctx_free(ctx); - ctx = NULL; - } - - return ctx; -} - - -/* free any resources, clear any keys */ -void ecc_ctx_free(ecEncCtx* ctx) -{ - if (ctx) { - XMEMSET(ctx, 0, sizeof(ecEncCtx)); - XFREE(ctx, 0, DYNAMIC_TYPE_ECC); - } -} - - -static int ecc_get_key_sizes(ecEncCtx* ctx, int* encKeySz, int* ivSz, - int* keysLen, word32* digestSz, word32* blockSz) -{ - if (ctx) { - switch (ctx->encAlgo) { - case ecAES_128_CBC: - *encKeySz = KEY_SIZE_128; - *ivSz = IV_SIZE_64; - *blockSz = AES_BLOCK_SIZE; - break; - default: - return BAD_FUNC_ARG; - } - - switch (ctx->macAlgo) { - case ecHMAC_SHA256: - *digestSz = SHA256_DIGEST_SIZE; - break; - default: - return BAD_FUNC_ARG; - } - } else - return BAD_FUNC_ARG; - - *keysLen = *encKeySz + *ivSz + *digestSz; - - return 0; -} - - -/* ecc encrypt with shared secret run through kdf - ctx holds non default algos and inputs - msgSz should be the right size for encAlgo, i.e., already padded - return 0 on success */ -int ecc_encrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg, - word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx) -{ - int ret; - word32 blockSz; - word32 digestSz; - ecEncCtx localCtx; -#ifdef CYASSL_SMALL_STACK - byte* sharedSecret; - byte* keys; -#else - byte sharedSecret[ECC_MAXSIZE]; /* 521 max size */ - byte keys[ECC_BUFSIZE]; /* max size */ -#endif - word32 sharedSz = ECC_MAXSIZE; - int keysLen; - int encKeySz; - int ivSz; - int offset = 0; /* keys offset if doing msg exchange */ - byte* encKey; - byte* encIv; - byte* macKey; - - if (privKey == NULL || pubKey == NULL || msg == NULL || out == NULL || - outSz == NULL) - return BAD_FUNC_ARG; - - if (ctx == NULL) { /* use defaults */ - ecc_ctx_init(&localCtx, 0); - ctx = &localCtx; - } - - ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz, - &blockSz); - if (ret != 0) - return ret; - - if (ctx->protocol == REQ_RESP_SERVER) { - offset = keysLen; - keysLen *= 2; - - if (ctx->srvSt != ecSRV_RECV_REQ) - return BAD_ENC_STATE_E; - - ctx->srvSt = ecSRV_BAD_STATE; /* we're done no more ops allowed */ - } - else if (ctx->protocol == REQ_RESP_CLIENT) { - if (ctx->cliSt != ecCLI_SALT_SET) - return BAD_ENC_STATE_E; - - ctx->cliSt = ecCLI_SENT_REQ; /* only do this once */ - } - - if (keysLen > ECC_BUFSIZE) /* keys size */ - return BUFFER_E; - - if ( (msgSz%blockSz) != 0) - return BAD_PADDING_E; - - if (*outSz < (msgSz + digestSz)) - return BUFFER_E; - -#ifdef CYASSL_SMALL_STACK - sharedSecret = (byte*)XMALLOC(ECC_MAXSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (sharedSecret == NULL) - return MEMORY_E; - - keys = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (keys == NULL) { - XFREE(sharedSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); - return MEMORY_E; - } -#endif - - ret = ecc_shared_secret(privKey, pubKey, sharedSecret, &sharedSz); - - if (ret == 0) { - switch (ctx->kdfAlgo) { - case ecHKDF_SHA256 : - ret = HKDF(SHA256, sharedSecret, sharedSz, ctx->kdfSalt, - ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz, - keys, keysLen); - break; - - default: - ret = BAD_FUNC_ARG; - break; - } - } - - if (ret == 0) { - encKey = keys + offset; - encIv = encKey + encKeySz; - macKey = encKey + encKeySz + ivSz; - - switch (ctx->encAlgo) { - case ecAES_128_CBC: - { - Aes aes; - ret = AesSetKey(&aes, encKey, KEY_SIZE_128, encIv, - AES_ENCRYPTION); - if (ret != 0) - break; - ret = AesCbcEncrypt(&aes, out, msg, msgSz); - } - break; - - default: - ret = BAD_FUNC_ARG; - break; - } - } - - if (ret == 0) { - switch (ctx->macAlgo) { - case ecHMAC_SHA256: - { - Hmac hmac; - ret = HmacSetKey(&hmac, SHA256, macKey, SHA256_DIGEST_SIZE); - if (ret != 0) - break; - ret = HmacUpdate(&hmac, out, msgSz); - if (ret != 0) - break; - ret = HmacUpdate(&hmac, ctx->macSalt, ctx->macSaltSz); - if (ret != 0) - break; - ret = HmacFinal(&hmac, out+msgSz); - } - break; - - default: - ret = BAD_FUNC_ARG; - break; - } - } - - if (ret == 0) - *outSz = msgSz + digestSz; - -#ifdef CYASSL_SMALL_STACK - XFREE(sharedSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(keys, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - - return ret; -} - - -/* ecc decrypt with shared secret run through kdf - ctx holds non default algos and inputs - return 0 on success */ -int ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg, - word32 msgSz, byte* out, word32* outSz, ecEncCtx* ctx) -{ - int ret; - word32 blockSz; - word32 digestSz; - ecEncCtx localCtx; -#ifdef CYASSL_SMALL_STACK - byte* sharedSecret; - byte* keys; -#else - byte sharedSecret[ECC_MAXSIZE]; /* 521 max size */ - byte keys[ECC_BUFSIZE]; /* max size */ -#endif - word32 sharedSz = ECC_MAXSIZE; - int keysLen; - int encKeySz; - int ivSz; - int offset = 0; /* in case using msg exchange */ - byte* encKey; - byte* encIv; - byte* macKey; - - if (privKey == NULL || pubKey == NULL || msg == NULL || out == NULL || - outSz == NULL) - return BAD_FUNC_ARG; - - if (ctx == NULL) { /* use defaults */ - ecc_ctx_init(&localCtx, 0); - ctx = &localCtx; - } - - ret = ecc_get_key_sizes(ctx, &encKeySz, &ivSz, &keysLen, &digestSz, - &blockSz); - if (ret != 0) - return ret; - - if (ctx->protocol == REQ_RESP_CLIENT) { - offset = keysLen; - keysLen *= 2; - - if (ctx->cliSt != ecCLI_SENT_REQ) - return BAD_ENC_STATE_E; - - ctx->cliSt = ecSRV_BAD_STATE; /* we're done no more ops allowed */ - } - else if (ctx->protocol == REQ_RESP_SERVER) { - if (ctx->srvSt != ecSRV_SALT_SET) - return BAD_ENC_STATE_E; - - ctx->srvSt = ecSRV_RECV_REQ; /* only do this once */ - } - - if (keysLen > ECC_BUFSIZE) /* keys size */ - return BUFFER_E; - - if ( ((msgSz-digestSz) % blockSz) != 0) - return BAD_PADDING_E; - - if (*outSz < (msgSz - digestSz)) - return BUFFER_E; - -#ifdef CYASSL_SMALL_STACK - sharedSecret = (byte*)XMALLOC(ECC_MAXSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (sharedSecret == NULL) - return MEMORY_E; - - keys = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (keys == NULL) { - XFREE(sharedSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); - return MEMORY_E; - } -#endif - - ret = ecc_shared_secret(privKey, pubKey, sharedSecret, &sharedSz); - - if (ret == 0) { - switch (ctx->kdfAlgo) { - case ecHKDF_SHA256 : - ret = HKDF(SHA256, sharedSecret, sharedSz, ctx->kdfSalt, - ctx->kdfSaltSz, ctx->kdfInfo, ctx->kdfInfoSz, - keys, keysLen); - break; - - default: - ret = BAD_FUNC_ARG; - break; - } - } - - if (ret == 0) { - encKey = keys + offset; - encIv = encKey + encKeySz; - macKey = encKey + encKeySz + ivSz; - - switch (ctx->macAlgo) { - case ecHMAC_SHA256: - { - byte verify[SHA256_DIGEST_SIZE]; - Hmac hmac; - ret = HmacSetKey(&hmac, SHA256, macKey, SHA256_DIGEST_SIZE); - if (ret != 0) - break; - ret = HmacUpdate(&hmac, msg, msgSz-digestSz); - if (ret != 0) - break; - ret = HmacUpdate(&hmac, ctx->macSalt, ctx->macSaltSz); - if (ret != 0) - break; - ret = HmacFinal(&hmac, verify); - if (ret != 0) - break; - if (memcmp(verify, msg + msgSz - digestSz, digestSz) != 0) - ret = -1; - } - break; - - default: - ret = BAD_FUNC_ARG; - break; - } - } - - if (ret == 0) { - switch (ctx->encAlgo) { - case ecAES_128_CBC: - { - Aes aes; - ret = AesSetKey(&aes, encKey, KEY_SIZE_128, encIv, - AES_DECRYPTION); - if (ret != 0) - break; - ret = AesCbcDecrypt(&aes, out, msg, msgSz-digestSz); - } - break; - - default: - ret = BAD_FUNC_ARG; - break; - } - } - - if (ret == 0) - *outSz = msgSz - digestSz; - -#ifdef CYASSL_SMALL_STACK - XFREE(sharedSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(keys, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - - return ret; -} - - -#endif /* HAVE_ECC_ENCRYPT */ - - -#ifdef HAVE_COMP_KEY - -/* computes the jacobi c = (a | n) (or Legendre if n is prime) - * HAC pp. 73 Algorithm 2.149 - */ -int mp_jacobi(mp_int* a, mp_int* p, int* c) -{ - mp_int a1, p1; - int k, s, r, res; - mp_digit residue; - - /* if p <= 0 return MP_VAL */ - if (mp_cmp_d(p, 0) != MP_GT) { - return MP_VAL; - } - - /* step 1. if a == 0, return 0 */ - if (mp_iszero (a) == 1) { - *c = 0; - return MP_OKAY; - } - - /* step 2. if a == 1, return 1 */ - if (mp_cmp_d (a, 1) == MP_EQ) { - *c = 1; - return MP_OKAY; - } - - /* default */ - s = 0; - - /* step 3. write a = a1 * 2**k */ - if ((res = mp_init_copy (&a1, a)) != MP_OKAY) { - return res; - } - - if ((res = mp_init (&p1)) != MP_OKAY) { - mp_clear(&a1); - return res; - } - - /* divide out larger power of two */ - k = mp_cnt_lsb(&a1); - res = mp_div_2d(&a1, k, &a1, NULL); - - if (res == MP_OKAY) { - /* step 4. if e is even set s=1 */ - if ((k & 1) == 0) { - s = 1; - } else { - /* else set s=1 if p = 1/7 (mod 8) or s=-1 if p = 3/5 (mod 8) */ - residue = p->dp[0] & 7; - - if (residue == 1 || residue == 7) { - s = 1; - } else if (residue == 3 || residue == 5) { - s = -1; - } - } - - /* step 5. if p == 3 (mod 4) *and* a1 == 3 (mod 4) then s = -s */ - if ( ((p->dp[0] & 3) == 3) && ((a1.dp[0] & 3) == 3)) { - s = -s; - } - } - - if (res == MP_OKAY) { - /* if a1 == 1 we're done */ - if (mp_cmp_d (&a1, 1) == MP_EQ) { - *c = s; - } else { - /* n1 = n mod a1 */ - res = mp_mod (p, &a1, &p1); - if (res == MP_OKAY) - res = mp_jacobi (&p1, &a1, &r); - - if (res == MP_OKAY) - *c = s * r; - } - } - - /* done */ - mp_clear (&p1); - mp_clear (&a1); - - return res; -} - - -int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret) -{ - int res, legendre, done = 0; - mp_int t1, C, Q, S, Z, M, T, R, two; - mp_digit i; - - /* first handle the simple cases */ - if (mp_cmp_d(n, 0) == MP_EQ) { - mp_zero(ret); - return MP_OKAY; - } - if (mp_cmp_d(prime, 2) == MP_EQ) return MP_VAL; /* prime must be odd */ - /* TAO removed - if ((res = mp_jacobi(n, prime, &legendre)) != MP_OKAY) return res; - if (legendre == -1) return MP_VAL; */ /* quadratic non-residue mod prime */ - - if ((res = mp_init_multi(&t1, &C, &Q, &S, &Z, &M)) != MP_OKAY) - return res; - - if ((res = mp_init_multi(&T, &R, &two, NULL, NULL, NULL)) - != MP_OKAY) { - mp_clear(&t1); mp_clear(&C); mp_clear(&Q); mp_clear(&S); mp_clear(&Z); - mp_clear(&M); - return res; - } - - /* SPECIAL CASE: if prime mod 4 == 3 - * compute directly: res = n^(prime+1)/4 mod prime - * Handbook of Applied Cryptography algorithm 3.36 - */ - res = mp_mod_d(prime, 4, &i); - if (res == MP_OKAY && i == 3) { - res = mp_add_d(prime, 1, &t1); - - if (res == MP_OKAY) - res = mp_div_2(&t1, &t1); - if (res == MP_OKAY) - res = mp_div_2(&t1, &t1); - if (res == MP_OKAY) - res = mp_exptmod(n, &t1, prime, ret); - - done = 1; - } - - /* NOW: TonelliShanks algorithm */ - - if (res == MP_OKAY && done == 0) { - - /* factor out powers of 2 from prime-1, defining Q and S - * as: prime-1 = Q*2^S */ - res = mp_copy(prime, &Q); - if (res == MP_OKAY) - res = mp_sub_d(&Q, 1, &Q); - /* Q = prime - 1 */ - if (res == MP_OKAY) - mp_zero(&S); - /* S = 0 */ - while (res == MP_OKAY && mp_iseven(&Q)) { - res = mp_div_2(&Q, &Q); - /* Q = Q / 2 */ - if (res == MP_OKAY) - res = mp_add_d(&S, 1, &S); - /* S = S + 1 */ - } - - /* find a Z such that the Legendre symbol (Z|prime) == -1 */ - if (res == MP_OKAY) - res = mp_set_int(&Z, 2); - /* Z = 2 */ - while (res == MP_OKAY) { - res = mp_jacobi(&Z, prime, &legendre); - if (res == MP_OKAY && legendre == -1) - break; - if (res == MP_OKAY) - res = mp_add_d(&Z, 1, &Z); - /* Z = Z + 1 */ - } - - if (res == MP_OKAY) - res = mp_exptmod(&Z, &Q, prime, &C); - /* C = Z ^ Q mod prime */ - if (res == MP_OKAY) - res = mp_add_d(&Q, 1, &t1); - if (res == MP_OKAY) - res = mp_div_2(&t1, &t1); - /* t1 = (Q + 1) / 2 */ - if (res == MP_OKAY) - res = mp_exptmod(n, &t1, prime, &R); - /* R = n ^ ((Q + 1) / 2) mod prime */ - if (res == MP_OKAY) - res = mp_exptmod(n, &Q, prime, &T); - /* T = n ^ Q mod prime */ - if (res == MP_OKAY) - res = mp_copy(&S, &M); - /* M = S */ - if (res == MP_OKAY) - res = mp_set_int(&two, 2); - - while (res == MP_OKAY && done == 0) { - res = mp_copy(&T, &t1); - i = 0; - while (res == MP_OKAY) { - if (mp_cmp_d(&t1, 1) == MP_EQ) - break; - res = mp_exptmod(&t1, &two, prime, &t1); - if (res == MP_OKAY) - i++; - } - if (res == MP_OKAY && i == 0) { - mp_copy(&R, ret); - res = MP_OKAY; - done = 1; - } - - if (done == 0) { - if (res == MP_OKAY) - res = mp_sub_d(&M, i, &t1); - if (res == MP_OKAY) - res = mp_sub_d(&t1, 1, &t1); - if (res == MP_OKAY) - res = mp_exptmod(&two, &t1, prime, &t1); - /* t1 = 2 ^ (M - i - 1) */ - if (res == MP_OKAY) - res = mp_exptmod(&C, &t1, prime, &t1); - /* t1 = C ^ (2 ^ (M - i - 1)) mod prime */ - if (res == MP_OKAY) - res = mp_sqrmod(&t1, prime, &C); - /* C = (t1 * t1) mod prime */ - if (res == MP_OKAY) - res = mp_mulmod(&R, &t1, prime, &R); - /* R = (R * t1) mod prime */ - if (res == MP_OKAY) - res = mp_mulmod(&T, &C, prime, &T); - /* T = (T * C) mod prime */ - if (res == MP_OKAY) - mp_set(&M, i); - /* M = i */ - } - } - } - - /* done */ - mp_clear(&t1); - mp_clear(&C); - mp_clear(&Q); - mp_clear(&S); - mp_clear(&Z); - mp_clear(&M); - mp_clear(&T); - mp_clear(&R); - mp_clear(&two); - - return res; -} - - -/* export public ECC key in ANSI X9.63 format compressed */ -int ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen) -{ - word32 numlen; - int ret = MP_OKAY; - - if (key == NULL || out == NULL || outLen == NULL) - return ECC_BAD_ARG_E; - - if (ecc_is_valid_idx(key->idx) == 0) { - return ECC_BAD_ARG_E; - } - numlen = key->dp->size; - - if (*outLen < (1 + numlen)) { - *outLen = 1 + numlen; - return BUFFER_E; - } - - /* store first byte */ - out[0] = mp_isodd(&key->pubkey.y) ? 0x03 : 0x02; - - /* pad and store x */ - XMEMSET(out+1, 0, numlen); - ret = mp_to_unsigned_bin(&key->pubkey.x, - out+1 + (numlen - mp_unsigned_bin_size(&key->pubkey.x))); - *outLen = 1 + numlen; - return ret; -} - - -/* d = a - b (mod c) */ -int mp_submod(mp_int* a, mp_int* b, mp_int* c, mp_int* d) -{ - int res; - mp_int t; - - if ((res = mp_init (&t)) != MP_OKAY) { - return res; - } - - if ((res = mp_sub (a, b, &t)) != MP_OKAY) { - mp_clear (&t); - return res; - } - res = mp_mod (&t, c, d); - mp_clear (&t); - - return res; -} - - -#endif /* HAVE_COMP_KEY */ - -#endif /* HAVE_ECC */ diff --git a/ctaocrypt/src/ecc_fp.c b/ctaocrypt/src/ecc_fp.c deleted file mode 100644 index c8acf9387..000000000 --- a/ctaocrypt/src/ecc_fp.c +++ /dev/null @@ -1 +0,0 @@ -/* dummy ecc_fp.c for dist */ diff --git a/ctaocrypt/src/poly1305.c b/ctaocrypt/src/poly1305.c deleted file mode 100644 index ec9cec111..000000000 --- a/ctaocrypt/src/poly1305.c +++ /dev/null @@ -1,554 +0,0 @@ -/* poly1305.c - * - * Copyright (C) 2006-2014 wolfSSL Inc. - * - * This file is part of wolfSSL. (formerly known as CyaSSL) - * - * wolfSSL is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * wolfSSL is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - * - * Based off the public domain implementations by Andrew Moon - * and Daniel J. Bernstein - */ - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include - -#ifdef HAVE_POLY1305 -#include -#include -#include -#ifdef NO_INLINE - #include -#else - #include -#endif -#ifdef CHACHA_AEAD_TEST - #include -#endif - -#ifdef _MSC_VER - /* 4127 warning constant while(1) */ - #pragma warning(disable: 4127) -#endif - -#if defined(POLY130564) - - #if defined(_MSC_VER) - #define POLY1305_NOINLINE __declspec(noinline) - #elif defined(__GNUC__) - #define POLY1305_NOINLINE __attribute__((noinline)) - #else - #define POLY1305_NOINLINE - #endif - - #if defined(_MSC_VER) - #include - - typedef struct word128 { - word64 lo; - word64 hi; - } word128; - - #define MUL(out, x, y) out.lo = _umul128((x), (y), &out.hi) - #define ADD(out, in) { word64 t = out.lo; out.lo += in.lo; - out.hi += (out.lo < t) + in.hi; } - #define ADDLO(out, in) { word64 t = out.lo; out.lo += in; - out.hi += (out.lo < t); } - #define SHR(in, shift) (__shiftright128(in.lo, in.hi, (shift))) - #define LO(in) (in.lo) - - #elif defined(__GNUC__) - #if defined(__SIZEOF_INT128__) - typedef unsigned __int128 word128; - #else - typedef unsigned word128 __attribute__((mode(TI))); - #endif - - #define MUL(out, x, y) out = ((word128)x * y) - #define ADD(out, in) out += in - #define ADDLO(out, in) out += in - #define SHR(in, shift) (word64)(in >> (shift)) - #define LO(in) (word64)(in) - #endif - - static word64 U8TO64(const byte* p) { - return - (((word64)(p[0] & 0xff) ) | - ((word64)(p[1] & 0xff) << 8) | - ((word64)(p[2] & 0xff) << 16) | - ((word64)(p[3] & 0xff) << 24) | - ((word64)(p[4] & 0xff) << 32) | - ((word64)(p[5] & 0xff) << 40) | - ((word64)(p[6] & 0xff) << 48) | - ((word64)(p[7] & 0xff) << 56)); - } - - static void U64TO8(byte* p, word64 v) { - p[0] = (v ) & 0xff; - p[1] = (v >> 8) & 0xff; - p[2] = (v >> 16) & 0xff; - p[3] = (v >> 24) & 0xff; - p[4] = (v >> 32) & 0xff; - p[5] = (v >> 40) & 0xff; - p[6] = (v >> 48) & 0xff; - p[7] = (v >> 56) & 0xff; - } - -#else /* if not 64 bit then use 32 bit */ - - static word32 U8TO32(const byte *p) { - return - (((word32)(p[0] & 0xff) ) | - ((word32)(p[1] & 0xff) << 8) | - ((word32)(p[2] & 0xff) << 16) | - ((word32)(p[3] & 0xff) << 24)); - } - - static void U32TO8(byte *p, word32 v) { - p[0] = (v ) & 0xff; - p[1] = (v >> 8) & 0xff; - p[2] = (v >> 16) & 0xff; - p[3] = (v >> 24) & 0xff; - } -#endif - -static void poly1305_blocks(Poly1305* ctx, const unsigned char *m, - size_t bytes) { - -#ifdef POLY130564 - - const word64 hibit = (ctx->final) ? 0 : ((word64)1 << 40); /* 1 << 128 */ - word64 r0,r1,r2; - word64 s1,s2; - word64 h0,h1,h2; - word64 c; - word128 d0,d1,d2,d; - -#else - - const word32 hibit = (ctx->final) ? 0 : (1 << 24); /* 1 << 128 */ - word32 r0,r1,r2,r3,r4; - word32 s1,s2,s3,s4; - word32 h0,h1,h2,h3,h4; - word64 d0,d1,d2,d3,d4; - word32 c; - -#endif - -#ifdef POLY130564 - - r0 = ctx->r[0]; - r1 = ctx->r[1]; - r2 = ctx->r[2]; - - h0 = ctx->h[0]; - h1 = ctx->h[1]; - h2 = ctx->h[2]; - - s1 = r1 * (5 << 2); - s2 = r2 * (5 << 2); - - while (bytes >= POLY1305_BLOCK_SIZE) { - word64 t0,t1; - - /* h += m[i] */ - t0 = U8TO64(&m[0]); - t1 = U8TO64(&m[8]); - - h0 += (( t0 ) & 0xfffffffffff); - h1 += (((t0 >> 44) | (t1 << 20)) & 0xfffffffffff); - h2 += (((t1 >> 24) ) & 0x3ffffffffff) | hibit; - - /* h *= r */ - MUL(d0, h0, r0); MUL(d, h1, s2); ADD(d0, d); MUL(d, h2, s1); ADD(d0, d); - MUL(d1, h0, r1); MUL(d, h1, r0); ADD(d1, d); MUL(d, h2, s2); ADD(d1, d); - MUL(d2, h0, r2); MUL(d, h1, r1); ADD(d2, d); MUL(d, h2, r0); ADD(d2, d); - - /* (partial) h %= p */ - c = SHR(d0, 44); h0 = LO(d0) & 0xfffffffffff; - ADDLO(d1, c); c = SHR(d1, 44); h1 = LO(d1) & 0xfffffffffff; - ADDLO(d2, c); c = SHR(d2, 42); h2 = LO(d2) & 0x3ffffffffff; - h0 += c * 5; c = (h0 >> 44); h0 = h0 & 0xfffffffffff; - h1 += c; - - m += POLY1305_BLOCK_SIZE; - bytes -= POLY1305_BLOCK_SIZE; - } - - ctx->h[0] = h0; - ctx->h[1] = h1; - ctx->h[2] = h2; - -#else /* if not 64 bit then use 32 bit */ - - r0 = ctx->r[0]; - r1 = ctx->r[1]; - r2 = ctx->r[2]; - r3 = ctx->r[3]; - r4 = ctx->r[4]; - - s1 = r1 * 5; - s2 = r2 * 5; - s3 = r3 * 5; - s4 = r4 * 5; - - h0 = ctx->h[0]; - h1 = ctx->h[1]; - h2 = ctx->h[2]; - h3 = ctx->h[3]; - h4 = ctx->h[4]; - - while (bytes >= POLY1305_BLOCK_SIZE) { - /* h += m[i] */ - h0 += (U8TO32(m+ 0) ) & 0x3ffffff; - h1 += (U8TO32(m+ 3) >> 2) & 0x3ffffff; - h2 += (U8TO32(m+ 6) >> 4) & 0x3ffffff; - h3 += (U8TO32(m+ 9) >> 6) & 0x3ffffff; - h4 += (U8TO32(m+12) >> 8) | hibit; - - /* h *= r */ - d0 = ((word64)h0 * r0) + ((word64)h1 * s4) + ((word64)h2 * s3) + - ((word64)h3 * s2) + ((word64)h4 * s1); - d1 = ((word64)h0 * r1) + ((word64)h1 * r0) + ((word64)h2 * s4) + - ((word64)h3 * s3) + ((word64)h4 * s2); - d2 = ((word64)h0 * r2) + ((word64)h1 * r1) + ((word64)h2 * r0) + - ((word64)h3 * s4) + ((word64)h4 * s3); - d3 = ((word64)h0 * r3) + ((word64)h1 * r2) + ((word64)h2 * r1) + - ((word64)h3 * r0) + ((word64)h4 * s4); - d4 = ((word64)h0 * r4) + ((word64)h1 * r3) + ((word64)h2 * r2) + - ((word64)h3 * r1) + ((word64)h4 * r0); - - /* (partial) h %= p */ - c = (word32)(d0 >> 26); h0 = (word32)d0 & 0x3ffffff; - d1 += c; c = (word32)(d1 >> 26); h1 = (word32)d1 & 0x3ffffff; - d2 += c; c = (word32)(d2 >> 26); h2 = (word32)d2 & 0x3ffffff; - d3 += c; c = (word32)(d3 >> 26); h3 = (word32)d3 & 0x3ffffff; - d4 += c; c = (word32)(d4 >> 26); h4 = (word32)d4 & 0x3ffffff; - h0 += c * 5; c = (h0 >> 26); h0 = h0 & 0x3ffffff; - h1 += c; - - m += POLY1305_BLOCK_SIZE; - bytes -= POLY1305_BLOCK_SIZE; - } - - ctx->h[0] = h0; - ctx->h[1] = h1; - ctx->h[2] = h2; - ctx->h[3] = h3; - ctx->h[4] = h4; - -#endif /* end of 64 bit cpu blocks or 32 bit cpu */ -} - - -int Poly1305SetKey(Poly1305* ctx, const byte* key, word32 keySz) { - -#if defined(POLY130564) - word64 t0,t1; -#endif - -#ifdef CHACHA_AEAD_TEST - word32 k; - printf("Poly key used:\n"); - for (k = 0; k < keySz; k++) { - printf("%02x", key[k]); - if ((k+1) % 8 == 0) - printf("\n"); - } - printf("\n"); -#endif - - if (keySz != 32 || ctx == NULL) - return BAD_FUNC_ARG; - -#if defined(POLY130564) - - /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */ - t0 = U8TO64(key + 0); - t1 = U8TO64(key + 8); - - ctx->r[0] = ( t0 ) & 0xffc0fffffff; - ctx->r[1] = ((t0 >> 44) | (t1 << 20)) & 0xfffffc0ffff; - ctx->r[2] = ((t1 >> 24) ) & 0x00ffffffc0f; - - /* h (accumulator) = 0 */ - ctx->h[0] = 0; - ctx->h[1] = 0; - ctx->h[2] = 0; - - /* save pad for later */ - ctx->pad[0] = U8TO64(key + 16); - ctx->pad[1] = U8TO64(key + 24); - -#else /* if not 64 bit then use 32 bit */ - - /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */ - ctx->r[0] = (U8TO32(key + 0) ) & 0x3ffffff; - ctx->r[1] = (U8TO32(key + 3) >> 2) & 0x3ffff03; - ctx->r[2] = (U8TO32(key + 6) >> 4) & 0x3ffc0ff; - ctx->r[3] = (U8TO32(key + 9) >> 6) & 0x3f03fff; - ctx->r[4] = (U8TO32(key + 12) >> 8) & 0x00fffff; - - /* h = 0 */ - ctx->h[0] = 0; - ctx->h[1] = 0; - ctx->h[2] = 0; - ctx->h[3] = 0; - ctx->h[4] = 0; - - /* save pad for later */ - ctx->pad[0] = U8TO32(key + 16); - ctx->pad[1] = U8TO32(key + 20); - ctx->pad[2] = U8TO32(key + 24); - ctx->pad[3] = U8TO32(key + 28); - -#endif - - ctx->leftover = 0; - ctx->final = 0; - - return 0; -} - - -int Poly1305Final(Poly1305* ctx, byte* mac) { - -#if defined(POLY130564) - - word64 h0,h1,h2,c; - word64 g0,g1,g2; - word64 t0,t1; - -#else - - word32 h0,h1,h2,h3,h4,c; - word32 g0,g1,g2,g3,g4; - word64 f; - word32 mask; - -#endif - - if (ctx == NULL) - return BAD_FUNC_ARG; - -#if defined(POLY130564) - - /* process the remaining block */ - if (ctx->leftover) { - size_t i = ctx->leftover; - ctx->buffer[i] = 1; - for (i = i + 1; i < POLY1305_BLOCK_SIZE; i++) - ctx->buffer[i] = 0; - ctx->final = 1; - poly1305_blocks(ctx, ctx->buffer, POLY1305_BLOCK_SIZE); - } - - /* fully carry h */ - h0 = ctx->h[0]; - h1 = ctx->h[1]; - h2 = ctx->h[2]; - - c = (h1 >> 44); h1 &= 0xfffffffffff; - h2 += c; c = (h2 >> 42); h2 &= 0x3ffffffffff; - h0 += c * 5; c = (h0 >> 44); h0 &= 0xfffffffffff; - h1 += c; c = (h1 >> 44); h1 &= 0xfffffffffff; - h2 += c; c = (h2 >> 42); h2 &= 0x3ffffffffff; - h0 += c * 5; c = (h0 >> 44); h0 &= 0xfffffffffff; - h1 += c; - - /* compute h + -p */ - g0 = h0 + 5; c = (g0 >> 44); g0 &= 0xfffffffffff; - g1 = h1 + c; c = (g1 >> 44); g1 &= 0xfffffffffff; - g2 = h2 + c - ((word64)1 << 42); - - /* select h if h < p, or h + -p if h >= p */ - c = (g2 >> ((sizeof(word64) * 8) - 1)) - 1; - g0 &= c; - g1 &= c; - g2 &= c; - c = ~c; - h0 = (h0 & c) | g0; - h1 = (h1 & c) | g1; - h2 = (h2 & c) | g2; - - /* h = (h + pad) */ - t0 = ctx->pad[0]; - t1 = ctx->pad[1]; - - h0 += (( t0 ) & 0xfffffffffff) ; - c = (h0 >> 44); h0 &= 0xfffffffffff; - h1 += (((t0 >> 44) | (t1 << 20)) & 0xfffffffffff) + c; - c = (h1 >> 44); h1 &= 0xfffffffffff; - h2 += (((t1 >> 24) ) & 0x3ffffffffff) + c; - h2 &= 0x3ffffffffff; - - /* mac = h % (2^128) */ - h0 = ((h0 ) | (h1 << 44)); - h1 = ((h1 >> 20) | (h2 << 24)); - - U64TO8(mac + 0, h0); - U64TO8(mac + 8, h1); - - /* zero out the state */ - ctx->h[0] = 0; - ctx->h[1] = 0; - ctx->h[2] = 0; - ctx->r[0] = 0; - ctx->r[1] = 0; - ctx->r[2] = 0; - ctx->pad[0] = 0; - ctx->pad[1] = 0; - -#else /* if not 64 bit then use 32 bit */ - - /* process the remaining block */ - if (ctx->leftover) { - size_t i = ctx->leftover; - ctx->buffer[i++] = 1; - for (; i < POLY1305_BLOCK_SIZE; i++) - ctx->buffer[i] = 0; - ctx->final = 1; - poly1305_blocks(ctx, ctx->buffer, POLY1305_BLOCK_SIZE); - } - - /* fully carry h */ - h0 = ctx->h[0]; - h1 = ctx->h[1]; - h2 = ctx->h[2]; - h3 = ctx->h[3]; - h4 = ctx->h[4]; - - c = h1 >> 26; h1 = h1 & 0x3ffffff; - h2 += c; c = h2 >> 26; h2 = h2 & 0x3ffffff; - h3 += c; c = h3 >> 26; h3 = h3 & 0x3ffffff; - h4 += c; c = h4 >> 26; h4 = h4 & 0x3ffffff; - h0 += c * 5; c = h0 >> 26; h0 = h0 & 0x3ffffff; - h1 += c; - - /* compute h + -p */ - g0 = h0 + 5; c = g0 >> 26; g0 &= 0x3ffffff; - g1 = h1 + c; c = g1 >> 26; g1 &= 0x3ffffff; - g2 = h2 + c; c = g2 >> 26; g2 &= 0x3ffffff; - g3 = h3 + c; c = g3 >> 26; g3 &= 0x3ffffff; - g4 = h4 + c - (1 << 26); - - /* select h if h < p, or h + -p if h >= p */ - mask = (g4 >> ((sizeof(word32) * 8) - 1)) - 1; - g0 &= mask; - g1 &= mask; - g2 &= mask; - g3 &= mask; - g4 &= mask; - mask = ~mask; - h0 = (h0 & mask) | g0; - h1 = (h1 & mask) | g1; - h2 = (h2 & mask) | g2; - h3 = (h3 & mask) | g3; - h4 = (h4 & mask) | g4; - - /* h = h % (2^128) */ - h0 = ((h0 ) | (h1 << 26)) & 0xffffffff; - h1 = ((h1 >> 6) | (h2 << 20)) & 0xffffffff; - h2 = ((h2 >> 12) | (h3 << 14)) & 0xffffffff; - h3 = ((h3 >> 18) | (h4 << 8)) & 0xffffffff; - - /* mac = (h + pad) % (2^128) */ - f = (word64)h0 + ctx->pad[0] ; h0 = (word32)f; - f = (word64)h1 + ctx->pad[1] + (f >> 32); h1 = (word32)f; - f = (word64)h2 + ctx->pad[2] + (f >> 32); h2 = (word32)f; - f = (word64)h3 + ctx->pad[3] + (f >> 32); h3 = (word32)f; - - U32TO8(mac + 0, h0); - U32TO8(mac + 4, h1); - U32TO8(mac + 8, h2); - U32TO8(mac + 12, h3); - - /* zero out the state */ - ctx->h[0] = 0; - ctx->h[1] = 0; - ctx->h[2] = 0; - ctx->h[3] = 0; - ctx->h[4] = 0; - ctx->r[0] = 0; - ctx->r[1] = 0; - ctx->r[2] = 0; - ctx->r[3] = 0; - ctx->r[4] = 0; - ctx->pad[0] = 0; - ctx->pad[1] = 0; - ctx->pad[2] = 0; - ctx->pad[3] = 0; - -#endif - - return 0; -} - - -int Poly1305Update(Poly1305* ctx, const byte* m, word32 bytes) { - - size_t i; - -#ifdef CHACHA_AEAD_TEST - word32 k; - printf("Raw input to poly:\n"); - for (k = 0; k < bytes; k++) { - printf("%02x", m[k]); - if ((k+1) % 16 == 0) - printf("\n"); - } - printf("\n"); -#endif - - if (ctx == NULL) - return BAD_FUNC_ARG; - - /* handle leftover */ - if (ctx->leftover) { - size_t want = (POLY1305_BLOCK_SIZE - ctx->leftover); - if (want > bytes) - want = bytes; - for (i = 0; i < want; i++) - ctx->buffer[ctx->leftover + i] = m[i]; - bytes -= want; - m += want; - ctx->leftover += want; - if (ctx->leftover < POLY1305_BLOCK_SIZE) - return 0; - poly1305_blocks(ctx, ctx->buffer, POLY1305_BLOCK_SIZE); - ctx->leftover = 0; - } - - /* process full blocks */ - if (bytes >= POLY1305_BLOCK_SIZE) { - size_t want = (bytes & ~(POLY1305_BLOCK_SIZE - 1)); - poly1305_blocks(ctx, m, want); - m += want; - bytes -= want; - } - - /* store leftover */ - if (bytes) { - for (i = 0; i < bytes; i++) - ctx->buffer[ctx->leftover + i] = m[i]; - ctx->leftover += bytes; - } - return 0; -} -#endif /* HAVE_POLY1305 */ - diff --git a/ctaocrypt/src/ripemd.c b/ctaocrypt/src/ripemd.c deleted file mode 100644 index 3f0858c85..000000000 --- a/ctaocrypt/src/ripemd.c +++ /dev/null @@ -1,354 +0,0 @@ -/* ripemd.c - * - * Copyright (C) 2006-2014 wolfSSL Inc. - * - * This file is part of wolfSSL. (formerly known as CyaSSL) - * - * wolfSSL is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * wolfSSL is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include - -#ifdef CYASSL_RIPEMD - -#include -#ifdef NO_INLINE - #include -#else - #include -#endif - - -#ifndef min - - static INLINE word32 min(word32 a, word32 b) - { - return a > b ? b : a; - } - -#endif /* min */ - - -void InitRipeMd(RipeMd* ripemd) -{ - ripemd->digest[0] = 0x67452301L; - ripemd->digest[1] = 0xEFCDAB89L; - ripemd->digest[2] = 0x98BADCFEL; - ripemd->digest[3] = 0x10325476L; - ripemd->digest[4] = 0xC3D2E1F0L; - - ripemd->buffLen = 0; - ripemd->loLen = 0; - ripemd->hiLen = 0; -} - - -/* for all */ -#define F(x, y, z) (x ^ y ^ z) -#define G(x, y, z) (z ^ (x & (y^z))) -#define H(x, y, z) (z ^ (x | ~y)) -#define I(x, y, z) (y ^ (z & (x^y))) -#define J(x, y, z) (x ^ (y | ~z)) - -#define k0 0 -#define k1 0x5a827999 -#define k2 0x6ed9eba1 -#define k3 0x8f1bbcdc -#define k4 0xa953fd4e -#define k5 0x50a28be6 -#define k6 0x5c4dd124 -#define k7 0x6d703ef3 -#define k8 0x7a6d76e9 -#define k9 0 - -/* for 160 and 320 */ -#define Subround(f, a, b, c, d, e, x, s, k) \ - a += f(b, c, d) + x + k;\ - a = rotlFixed((word32)a, s) + e;\ - c = rotlFixed((word32)c, 10U) - -static void Transform(RipeMd* ripemd) -{ - word32 a1, b1, c1, d1, e1, a2, b2, c2, d2, e2; - a1 = a2 = ripemd->digest[0]; - b1 = b2 = ripemd->digest[1]; - c1 = c2 = ripemd->digest[2]; - d1 = d2 = ripemd->digest[3]; - e1 = e2 = ripemd->digest[4]; - - Subround(F, a1, b1, c1, d1, e1, ripemd->buffer[ 0], 11, k0); - Subround(F, e1, a1, b1, c1, d1, ripemd->buffer[ 1], 14, k0); - Subround(F, d1, e1, a1, b1, c1, ripemd->buffer[ 2], 15, k0); - Subround(F, c1, d1, e1, a1, b1, ripemd->buffer[ 3], 12, k0); - Subround(F, b1, c1, d1, e1, a1, ripemd->buffer[ 4], 5, k0); - Subround(F, a1, b1, c1, d1, e1, ripemd->buffer[ 5], 8, k0); - Subround(F, e1, a1, b1, c1, d1, ripemd->buffer[ 6], 7, k0); - Subround(F, d1, e1, a1, b1, c1, ripemd->buffer[ 7], 9, k0); - Subround(F, c1, d1, e1, a1, b1, ripemd->buffer[ 8], 11, k0); - Subround(F, b1, c1, d1, e1, a1, ripemd->buffer[ 9], 13, k0); - Subround(F, a1, b1, c1, d1, e1, ripemd->buffer[10], 14, k0); - Subround(F, e1, a1, b1, c1, d1, ripemd->buffer[11], 15, k0); - Subround(F, d1, e1, a1, b1, c1, ripemd->buffer[12], 6, k0); - Subround(F, c1, d1, e1, a1, b1, ripemd->buffer[13], 7, k0); - Subround(F, b1, c1, d1, e1, a1, ripemd->buffer[14], 9, k0); - Subround(F, a1, b1, c1, d1, e1, ripemd->buffer[15], 8, k0); - - Subround(G, e1, a1, b1, c1, d1, ripemd->buffer[ 7], 7, k1); - Subround(G, d1, e1, a1, b1, c1, ripemd->buffer[ 4], 6, k1); - Subround(G, c1, d1, e1, a1, b1, ripemd->buffer[13], 8, k1); - Subround(G, b1, c1, d1, e1, a1, ripemd->buffer[ 1], 13, k1); - Subround(G, a1, b1, c1, d1, e1, ripemd->buffer[10], 11, k1); - Subround(G, e1, a1, b1, c1, d1, ripemd->buffer[ 6], 9, k1); - Subround(G, d1, e1, a1, b1, c1, ripemd->buffer[15], 7, k1); - Subround(G, c1, d1, e1, a1, b1, ripemd->buffer[ 3], 15, k1); - Subround(G, b1, c1, d1, e1, a1, ripemd->buffer[12], 7, k1); - Subround(G, a1, b1, c1, d1, e1, ripemd->buffer[ 0], 12, k1); - Subround(G, e1, a1, b1, c1, d1, ripemd->buffer[ 9], 15, k1); - Subround(G, d1, e1, a1, b1, c1, ripemd->buffer[ 5], 9, k1); - Subround(G, c1, d1, e1, a1, b1, ripemd->buffer[ 2], 11, k1); - Subround(G, b1, c1, d1, e1, a1, ripemd->buffer[14], 7, k1); - Subround(G, a1, b1, c1, d1, e1, ripemd->buffer[11], 13, k1); - Subround(G, e1, a1, b1, c1, d1, ripemd->buffer[ 8], 12, k1); - - Subround(H, d1, e1, a1, b1, c1, ripemd->buffer[ 3], 11, k2); - Subround(H, c1, d1, e1, a1, b1, ripemd->buffer[10], 13, k2); - Subround(H, b1, c1, d1, e1, a1, ripemd->buffer[14], 6, k2); - Subround(H, a1, b1, c1, d1, e1, ripemd->buffer[ 4], 7, k2); - Subround(H, e1, a1, b1, c1, d1, ripemd->buffer[ 9], 14, k2); - Subround(H, d1, e1, a1, b1, c1, ripemd->buffer[15], 9, k2); - Subround(H, c1, d1, e1, a1, b1, ripemd->buffer[ 8], 13, k2); - Subround(H, b1, c1, d1, e1, a1, ripemd->buffer[ 1], 15, k2); - Subround(H, a1, b1, c1, d1, e1, ripemd->buffer[ 2], 14, k2); - Subround(H, e1, a1, b1, c1, d1, ripemd->buffer[ 7], 8, k2); - Subround(H, d1, e1, a1, b1, c1, ripemd->buffer[ 0], 13, k2); - Subround(H, c1, d1, e1, a1, b1, ripemd->buffer[ 6], 6, k2); - Subround(H, b1, c1, d1, e1, a1, ripemd->buffer[13], 5, k2); - Subround(H, a1, b1, c1, d1, e1, ripemd->buffer[11], 12, k2); - Subround(H, e1, a1, b1, c1, d1, ripemd->buffer[ 5], 7, k2); - Subround(H, d1, e1, a1, b1, c1, ripemd->buffer[12], 5, k2); - - Subround(I, c1, d1, e1, a1, b1, ripemd->buffer[ 1], 11, k3); - Subround(I, b1, c1, d1, e1, a1, ripemd->buffer[ 9], 12, k3); - Subround(I, a1, b1, c1, d1, e1, ripemd->buffer[11], 14, k3); - Subround(I, e1, a1, b1, c1, d1, ripemd->buffer[10], 15, k3); - Subround(I, d1, e1, a1, b1, c1, ripemd->buffer[ 0], 14, k3); - Subround(I, c1, d1, e1, a1, b1, ripemd->buffer[ 8], 15, k3); - Subround(I, b1, c1, d1, e1, a1, ripemd->buffer[12], 9, k3); - Subround(I, a1, b1, c1, d1, e1, ripemd->buffer[ 4], 8, k3); - Subround(I, e1, a1, b1, c1, d1, ripemd->buffer[13], 9, k3); - Subround(I, d1, e1, a1, b1, c1, ripemd->buffer[ 3], 14, k3); - Subround(I, c1, d1, e1, a1, b1, ripemd->buffer[ 7], 5, k3); - Subround(I, b1, c1, d1, e1, a1, ripemd->buffer[15], 6, k3); - Subround(I, a1, b1, c1, d1, e1, ripemd->buffer[14], 8, k3); - Subround(I, e1, a1, b1, c1, d1, ripemd->buffer[ 5], 6, k3); - Subround(I, d1, e1, a1, b1, c1, ripemd->buffer[ 6], 5, k3); - Subround(I, c1, d1, e1, a1, b1, ripemd->buffer[ 2], 12, k3); - - Subround(J, b1, c1, d1, e1, a1, ripemd->buffer[ 4], 9, k4); - Subround(J, a1, b1, c1, d1, e1, ripemd->buffer[ 0], 15, k4); - Subround(J, e1, a1, b1, c1, d1, ripemd->buffer[ 5], 5, k4); - Subround(J, d1, e1, a1, b1, c1, ripemd->buffer[ 9], 11, k4); - Subround(J, c1, d1, e1, a1, b1, ripemd->buffer[ 7], 6, k4); - Subround(J, b1, c1, d1, e1, a1, ripemd->buffer[12], 8, k4); - Subround(J, a1, b1, c1, d1, e1, ripemd->buffer[ 2], 13, k4); - Subround(J, e1, a1, b1, c1, d1, ripemd->buffer[10], 12, k4); - Subround(J, d1, e1, a1, b1, c1, ripemd->buffer[14], 5, k4); - Subround(J, c1, d1, e1, a1, b1, ripemd->buffer[ 1], 12, k4); - Subround(J, b1, c1, d1, e1, a1, ripemd->buffer[ 3], 13, k4); - Subround(J, a1, b1, c1, d1, e1, ripemd->buffer[ 8], 14, k4); - Subround(J, e1, a1, b1, c1, d1, ripemd->buffer[11], 11, k4); - Subround(J, d1, e1, a1, b1, c1, ripemd->buffer[ 6], 8, k4); - Subround(J, c1, d1, e1, a1, b1, ripemd->buffer[15], 5, k4); - Subround(J, b1, c1, d1, e1, a1, ripemd->buffer[13], 6, k4); - - Subround(J, a2, b2, c2, d2, e2, ripemd->buffer[ 5], 8, k5); - Subround(J, e2, a2, b2, c2, d2, ripemd->buffer[14], 9, k5); - Subround(J, d2, e2, a2, b2, c2, ripemd->buffer[ 7], 9, k5); - Subround(J, c2, d2, e2, a2, b2, ripemd->buffer[ 0], 11, k5); - Subround(J, b2, c2, d2, e2, a2, ripemd->buffer[ 9], 13, k5); - Subround(J, a2, b2, c2, d2, e2, ripemd->buffer[ 2], 15, k5); - Subround(J, e2, a2, b2, c2, d2, ripemd->buffer[11], 15, k5); - Subround(J, d2, e2, a2, b2, c2, ripemd->buffer[ 4], 5, k5); - Subround(J, c2, d2, e2, a2, b2, ripemd->buffer[13], 7, k5); - Subround(J, b2, c2, d2, e2, a2, ripemd->buffer[ 6], 7, k5); - Subround(J, a2, b2, c2, d2, e2, ripemd->buffer[15], 8, k5); - Subround(J, e2, a2, b2, c2, d2, ripemd->buffer[ 8], 11, k5); - Subround(J, d2, e2, a2, b2, c2, ripemd->buffer[ 1], 14, k5); - Subround(J, c2, d2, e2, a2, b2, ripemd->buffer[10], 14, k5); - Subround(J, b2, c2, d2, e2, a2, ripemd->buffer[ 3], 12, k5); - Subround(J, a2, b2, c2, d2, e2, ripemd->buffer[12], 6, k5); - - Subround(I, e2, a2, b2, c2, d2, ripemd->buffer[ 6], 9, k6); - Subround(I, d2, e2, a2, b2, c2, ripemd->buffer[11], 13, k6); - Subround(I, c2, d2, e2, a2, b2, ripemd->buffer[ 3], 15, k6); - Subround(I, b2, c2, d2, e2, a2, ripemd->buffer[ 7], 7, k6); - Subround(I, a2, b2, c2, d2, e2, ripemd->buffer[ 0], 12, k6); - Subround(I, e2, a2, b2, c2, d2, ripemd->buffer[13], 8, k6); - Subround(I, d2, e2, a2, b2, c2, ripemd->buffer[ 5], 9, k6); - Subround(I, c2, d2, e2, a2, b2, ripemd->buffer[10], 11, k6); - Subround(I, b2, c2, d2, e2, a2, ripemd->buffer[14], 7, k6); - Subround(I, a2, b2, c2, d2, e2, ripemd->buffer[15], 7, k6); - Subround(I, e2, a2, b2, c2, d2, ripemd->buffer[ 8], 12, k6); - Subround(I, d2, e2, a2, b2, c2, ripemd->buffer[12], 7, k6); - Subround(I, c2, d2, e2, a2, b2, ripemd->buffer[ 4], 6, k6); - Subround(I, b2, c2, d2, e2, a2, ripemd->buffer[ 9], 15, k6); - Subround(I, a2, b2, c2, d2, e2, ripemd->buffer[ 1], 13, k6); - Subround(I, e2, a2, b2, c2, d2, ripemd->buffer[ 2], 11, k6); - - Subround(H, d2, e2, a2, b2, c2, ripemd->buffer[15], 9, k7); - Subround(H, c2, d2, e2, a2, b2, ripemd->buffer[ 5], 7, k7); - Subround(H, b2, c2, d2, e2, a2, ripemd->buffer[ 1], 15, k7); - Subround(H, a2, b2, c2, d2, e2, ripemd->buffer[ 3], 11, k7); - Subround(H, e2, a2, b2, c2, d2, ripemd->buffer[ 7], 8, k7); - Subround(H, d2, e2, a2, b2, c2, ripemd->buffer[14], 6, k7); - Subround(H, c2, d2, e2, a2, b2, ripemd->buffer[ 6], 6, k7); - Subround(H, b2, c2, d2, e2, a2, ripemd->buffer[ 9], 14, k7); - Subround(H, a2, b2, c2, d2, e2, ripemd->buffer[11], 12, k7); - Subround(H, e2, a2, b2, c2, d2, ripemd->buffer[ 8], 13, k7); - Subround(H, d2, e2, a2, b2, c2, ripemd->buffer[12], 5, k7); - Subround(H, c2, d2, e2, a2, b2, ripemd->buffer[ 2], 14, k7); - Subround(H, b2, c2, d2, e2, a2, ripemd->buffer[10], 13, k7); - Subround(H, a2, b2, c2, d2, e2, ripemd->buffer[ 0], 13, k7); - Subround(H, e2, a2, b2, c2, d2, ripemd->buffer[ 4], 7, k7); - Subround(H, d2, e2, a2, b2, c2, ripemd->buffer[13], 5, k7); - - Subround(G, c2, d2, e2, a2, b2, ripemd->buffer[ 8], 15, k8); - Subround(G, b2, c2, d2, e2, a2, ripemd->buffer[ 6], 5, k8); - Subround(G, a2, b2, c2, d2, e2, ripemd->buffer[ 4], 8, k8); - Subround(G, e2, a2, b2, c2, d2, ripemd->buffer[ 1], 11, k8); - Subround(G, d2, e2, a2, b2, c2, ripemd->buffer[ 3], 14, k8); - Subround(G, c2, d2, e2, a2, b2, ripemd->buffer[11], 14, k8); - Subround(G, b2, c2, d2, e2, a2, ripemd->buffer[15], 6, k8); - Subround(G, a2, b2, c2, d2, e2, ripemd->buffer[ 0], 14, k8); - Subround(G, e2, a2, b2, c2, d2, ripemd->buffer[ 5], 6, k8); - Subround(G, d2, e2, a2, b2, c2, ripemd->buffer[12], 9, k8); - Subround(G, c2, d2, e2, a2, b2, ripemd->buffer[ 2], 12, k8); - Subround(G, b2, c2, d2, e2, a2, ripemd->buffer[13], 9, k8); - Subround(G, a2, b2, c2, d2, e2, ripemd->buffer[ 9], 12, k8); - Subround(G, e2, a2, b2, c2, d2, ripemd->buffer[ 7], 5, k8); - Subround(G, d2, e2, a2, b2, c2, ripemd->buffer[10], 15, k8); - Subround(G, c2, d2, e2, a2, b2, ripemd->buffer[14], 8, k8); - - Subround(F, b2, c2, d2, e2, a2, ripemd->buffer[12], 8, k9); - Subround(F, a2, b2, c2, d2, e2, ripemd->buffer[15], 5, k9); - Subround(F, e2, a2, b2, c2, d2, ripemd->buffer[10], 12, k9); - Subround(F, d2, e2, a2, b2, c2, ripemd->buffer[ 4], 9, k9); - Subround(F, c2, d2, e2, a2, b2, ripemd->buffer[ 1], 12, k9); - Subround(F, b2, c2, d2, e2, a2, ripemd->buffer[ 5], 5, k9); - Subround(F, a2, b2, c2, d2, e2, ripemd->buffer[ 8], 14, k9); - Subround(F, e2, a2, b2, c2, d2, ripemd->buffer[ 7], 6, k9); - Subround(F, d2, e2, a2, b2, c2, ripemd->buffer[ 6], 8, k9); - Subround(F, c2, d2, e2, a2, b2, ripemd->buffer[ 2], 13, k9); - Subround(F, b2, c2, d2, e2, a2, ripemd->buffer[13], 6, k9); - Subround(F, a2, b2, c2, d2, e2, ripemd->buffer[14], 5, k9); - Subround(F, e2, a2, b2, c2, d2, ripemd->buffer[ 0], 15, k9); - Subround(F, d2, e2, a2, b2, c2, ripemd->buffer[ 3], 13, k9); - Subround(F, c2, d2, e2, a2, b2, ripemd->buffer[ 9], 11, k9); - Subround(F, b2, c2, d2, e2, a2, ripemd->buffer[11], 11, k9); - - c1 = ripemd->digest[1] + c1 + d2; - ripemd->digest[1] = ripemd->digest[2] + d1 + e2; - ripemd->digest[2] = ripemd->digest[3] + e1 + a2; - ripemd->digest[3] = ripemd->digest[4] + a1 + b2; - ripemd->digest[4] = ripemd->digest[0] + b1 + c2; - ripemd->digest[0] = c1; -} - - -static INLINE void AddLength(RipeMd* ripemd, word32 len) -{ - word32 tmp = ripemd->loLen; - if ( (ripemd->loLen += len) < tmp) - ripemd->hiLen++; /* carry low to high */ -} - - -void RipeMdUpdate(RipeMd* ripemd, const byte* data, word32 len) -{ - /* do block size increments */ - byte* local = (byte*)ripemd->buffer; - - while (len) { - word32 add = min(len, RIPEMD_BLOCK_SIZE - ripemd->buffLen); - XMEMCPY(&local[ripemd->buffLen], data, add); - - ripemd->buffLen += add; - data += add; - len -= add; - - if (ripemd->buffLen == RIPEMD_BLOCK_SIZE) { - #ifdef BIG_ENDIAN_ORDER - ByteReverseWords(ripemd->buffer, ripemd->buffer, - RIPEMD_BLOCK_SIZE); - #endif - Transform(ripemd); - AddLength(ripemd, RIPEMD_BLOCK_SIZE); - ripemd->buffLen = 0; - } - } -} - - -void RipeMdFinal(RipeMd* ripemd, byte* hash) -{ - byte* local = (byte*)ripemd->buffer; - - AddLength(ripemd, ripemd->buffLen); /* before adding pads */ - - local[ripemd->buffLen++] = 0x80; /* add 1 */ - - /* pad with zeros */ - if (ripemd->buffLen > RIPEMD_PAD_SIZE) { - XMEMSET(&local[ripemd->buffLen], 0, RIPEMD_BLOCK_SIZE - ripemd->buffLen); - ripemd->buffLen += RIPEMD_BLOCK_SIZE - ripemd->buffLen; - - #ifdef BIG_ENDIAN_ORDER - ByteReverseWords(ripemd->buffer, ripemd->buffer, RIPEMD_BLOCK_SIZE); - #endif - Transform(ripemd); - ripemd->buffLen = 0; - } - XMEMSET(&local[ripemd->buffLen], 0, RIPEMD_PAD_SIZE - ripemd->buffLen); - - /* put lengths in bits */ - ripemd->loLen = ripemd->loLen << 3; - ripemd->hiLen = (ripemd->loLen >> (8*sizeof(ripemd->loLen) - 3)) + - (ripemd->hiLen << 3); - - /* store lengths */ - #ifdef BIG_ENDIAN_ORDER - ByteReverseWords(ripemd->buffer, ripemd->buffer, RIPEMD_BLOCK_SIZE); - #endif - /* ! length ordering dependent on digest endian type ! */ - XMEMCPY(&local[RIPEMD_PAD_SIZE], &ripemd->loLen, sizeof(word32)); - XMEMCPY(&local[RIPEMD_PAD_SIZE + sizeof(word32)], &ripemd->hiLen, - sizeof(word32)); - - Transform(ripemd); - #ifdef BIG_ENDIAN_ORDER - ByteReverseWords(ripemd->digest, ripemd->digest, RIPEMD_DIGEST_SIZE); - #endif - XMEMCPY(hash, ripemd->digest, RIPEMD_DIGEST_SIZE); - - InitRipeMd(ripemd); /* reset state */ -} - - -#endif /* CYASSL_RIPEMD */ diff --git a/cyassl/ctaocrypt/arc4.h b/cyassl/ctaocrypt/arc4.h index 27d6ba5ca..49ee71c12 100644 --- a/cyassl/ctaocrypt/arc4.h +++ b/cyassl/ctaocrypt/arc4.h @@ -22,8 +22,6 @@ #ifndef CTAO_CRYPT_ARC4_H #define CTAO_CRYPT_ARC4_H -#include - /* for arc4 reverse compatibility */ #ifndef NO_RC4 #include diff --git a/cyassl/ctaocrypt/camellia.h b/cyassl/ctaocrypt/camellia.h index 1f541ee22..6291f1823 100644 --- a/cyassl/ctaocrypt/camellia.h +++ b/cyassl/ctaocrypt/camellia.h @@ -22,10 +22,10 @@ #ifndef CTAO_CRYPT_CAMELLIA_H #define CTAO_CRYPT_CAMELLIA_H -#include /* for blake2 reverse compatibility */ #ifdef HAVE_CAMELLIA + #include #define CamelliaSetKey wc_CamelliaSetKey #define CamelliaSetIV wc_CamelliaSetIV #define CamelliaEncryptDirect wc_CamelliaEncryptDirect diff --git a/cyassl/ctaocrypt/chacha.h b/cyassl/ctaocrypt/chacha.h index db9689a28..45f3243c0 100644 --- a/cyassl/ctaocrypt/chacha.h +++ b/cyassl/ctaocrypt/chacha.h @@ -22,12 +22,14 @@ #ifndef CTAO_CRYPT_CHACHA_H #define CTAO_CRYPT_CHACHA_H -#include /* for chacha reverse compatibility */ -#define Chacha_Process wc_Chacha_Process -#define Chacha_SetKey wc_Chacha_SetKey -#define Chacha_SetIV wc_Chacha_SetIV +#ifdef HAVE_CHACHA + #include + #define Chacha_Process wc_Chacha_Process + #define Chacha_SetKey wc_Chacha_SetKey + #define Chacha_SetIV wc_Chacha_SetIV +#endif #endif /* CTAO_CRYPT_CHACHA_H */ diff --git a/cyassl/ctaocrypt/dh.h b/cyassl/ctaocrypt/dh.h index c8c88d322..8daffe234 100644 --- a/cyassl/ctaocrypt/dh.h +++ b/cyassl/ctaocrypt/dh.h @@ -25,9 +25,8 @@ #ifndef CTAO_CRYPT_DH_H #define CTAO_CRYPT_DH_H -#include - -/* for dh reverse compatibility */ + /* for dh reverse compatibility */ + #include #define InitDhKey wc_InitDhKey #define FreeDhKey wc_FreeDhKey #define DhGenerateKeyPair wc_DhGenerateKeyPair @@ -36,42 +35,6 @@ #define DhSetKey wc_DhSetKey #define DhParamsLoad wc_DhParamsLoad -//#include -//#include -//#include -// -//#ifdef __cplusplus -// extern "C" { -//#endif -// -// -///* Diffie-Hellman Key */ -//typedef struct DhKey { -// mp_int p, g; /* group parameters */ -//} DhKey; -// -// -//CYASSL_API void InitDhKey(DhKey* key); -//CYASSL_API void FreeDhKey(DhKey* key); -// -//CYASSL_API int DhGenerateKeyPair(DhKey* key, RNG* rng, byte* priv, -// word32* privSz, byte* pub, word32* pubSz); -//CYASSL_API int DhAgree(DhKey* key, byte* agree, word32* agreeSz, -// const byte* priv, word32 privSz, const byte* otherPub, -// word32 pubSz); -// -//CYASSL_API int DhKeyDecode(const byte* input, word32* inOutIdx, DhKey* key, -// word32); -//CYASSL_API int DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g, -// word32 gSz); -//CYASSL_API int DhParamsLoad(const byte* input, word32 inSz, byte* p, -// word32* pInOutSz, byte* g, word32* gInOutSz); -// -// -//#ifdef __cplusplus -// } /* extern "C" */ -//#endif - #endif /* CTAO_CRYPT_DH_H */ #endif /* NO_DH */ diff --git a/src/include.am b/src/include.am index 55c53022e..115a987e2 100644 --- a/src/include.am +++ b/src/include.am @@ -124,12 +124,8 @@ src_libwolfssl_la_SOURCES += wolfcrypt/src/arc4.c endif if BUILD_MD4 -if BUILD_FIPS -src_libwolfssl_la_SOURCES += ctaocrypt/src/md4.c -else src_libwolfssl_la_SOURCES += wolfcrypt/src/md4.c endif -endif if BUILD_MD5 if BUILD_FIPS @@ -152,7 +148,11 @@ src_libwolfssl_la_SOURCES += wolfcrypt/src/dsa.c endif if BUILD_AESNI +if BUILD_FIPS src_libwolfssl_la_SOURCES += ctaocrypt/src/aes_asm.s +else +src_libwolfssl_la_SOURCES += wolfcrypt/src/aes_asm.s +endif endif if BUILD_CAMELLIA @@ -160,12 +160,8 @@ src_libwolfssl_la_SOURCES += wolfcrypt/src/camellia.c endif if BUILD_MD2 -if BUILD_FIPS -src_libwolfssl_la_SOURCES += ctaocrypt/src/md2.c -else src_libwolfssl_la_SOURCES += wolfcrypt/src/md2.c endif -endif if BUILD_RIPEMD src_libwolfssl_la_SOURCES += wolfcrypt/src/ripemd.c diff --git a/wolfcrypt/src/aes_asm.s b/wolfcrypt/src/aes_asm.s new file mode 100755 index 000000000..5313a6d16 --- /dev/null +++ b/wolfcrypt/src/aes_asm.s @@ -0,0 +1,816 @@ +/* aes_asm.s + * + * Copyright (C) 2006-2014 wolfSSL Inc. + * + * This file is part of wolfSSL. (formerly known as CyaSSL) + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + + +/* See IntelĀ® Advanced Encryption Standard (AES) Instructions Set White Paper + * by Intel Mobility Group, Israel Development Center, Israel Shay Gueron + */ + +/* This file is in at&t asm syntax, see .asm for intel syntax */ + + +/* +AES_CBC_encrypt (const unsigned char *in, + unsigned char *out, + unsigned char ivec[16], + unsigned long length, + const unsigned char *KS, + int nr) +*/ +.globl AES_CBC_encrypt +AES_CBC_encrypt: +# parameter 1: %rdi +# parameter 2: %rsi +# parameter 3: %rdx +# parameter 4: %rcx +# parameter 5: %r8 +# parameter 6: %r9d +movq %rcx, %r10 +shrq $4, %rcx +shlq $60, %r10 +je NO_PARTS +addq $1, %rcx +NO_PARTS: +subq $16, %rsi +movdqa (%rdx), %xmm1 +LOOP: +pxor (%rdi), %xmm1 +pxor (%r8), %xmm1 +addq $16,%rsi +addq $16,%rdi +cmpl $12, %r9d +aesenc 16(%r8),%xmm1 +aesenc 32(%r8),%xmm1 +aesenc 48(%r8),%xmm1 +aesenc 64(%r8),%xmm1 +aesenc 80(%r8),%xmm1 +aesenc 96(%r8),%xmm1 +aesenc 112(%r8),%xmm1 +aesenc 128(%r8),%xmm1 +aesenc 144(%r8),%xmm1 +movdqa 160(%r8),%xmm2 +jb LAST +cmpl $14, %r9d + +aesenc 160(%r8),%xmm1 +aesenc 176(%r8),%xmm1 +movdqa 192(%r8),%xmm2 +jb LAST +aesenc 192(%r8),%xmm1 +aesenc 208(%r8),%xmm1 +movdqa 224(%r8),%xmm2 +LAST: +decq %rcx +aesenclast %xmm2,%xmm1 +movdqu %xmm1,(%rsi) +jne LOOP +ret + + + + +/* +AES_CBC_decrypt (const unsigned char *in, + unsigned char *out, + unsigned char ivec[16], + unsigned long length, + const unsigned char *KS, + int nr) +*/ +.globl AES_CBC_decrypt +AES_CBC_decrypt: +# parameter 1: %rdi +# parameter 2: %rsi +# parameter 3: %rdx +# parameter 4: %rcx +# parameter 5: %r8 +# parameter 6: %r9d + +movq %rcx, %r10 +shrq $4, %rcx +shlq $60, %r10 +je DNO_PARTS_4 +addq $1, %rcx +DNO_PARTS_4: +movq %rcx, %r10 +shlq $62, %r10 +shrq $62, %r10 +shrq $2, %rcx +movdqu (%rdx),%xmm5 +je DREMAINDER_4 +subq $64, %rsi +DLOOP_4: +movdqu (%rdi), %xmm1 +movdqu 16(%rdi), %xmm2 +movdqu 32(%rdi), %xmm3 +movdqu 48(%rdi), %xmm4 +movdqa %xmm1, %xmm6 +movdqa %xmm2, %xmm7 +movdqa %xmm3, %xmm8 +movdqa %xmm4, %xmm15 +movdqa (%r8), %xmm9 +movdqa 16(%r8), %xmm10 +movdqa 32(%r8), %xmm11 +movdqa 48(%r8), %xmm12 +pxor %xmm9, %xmm1 +pxor %xmm9, %xmm2 +pxor %xmm9, %xmm3 + +pxor %xmm9, %xmm4 +aesdec %xmm10, %xmm1 +aesdec %xmm10, %xmm2 +aesdec %xmm10, %xmm3 +aesdec %xmm10, %xmm4 +aesdec %xmm11, %xmm1 +aesdec %xmm11, %xmm2 +aesdec %xmm11, %xmm3 +aesdec %xmm11, %xmm4 +aesdec %xmm12, %xmm1 +aesdec %xmm12, %xmm2 +aesdec %xmm12, %xmm3 +aesdec %xmm12, %xmm4 +movdqa 64(%r8), %xmm9 +movdqa 80(%r8), %xmm10 +movdqa 96(%r8), %xmm11 +movdqa 112(%r8), %xmm12 +aesdec %xmm9, %xmm1 +aesdec %xmm9, %xmm2 +aesdec %xmm9, %xmm3 +aesdec %xmm9, %xmm4 +aesdec %xmm10, %xmm1 +aesdec %xmm10, %xmm2 +aesdec %xmm10, %xmm3 +aesdec %xmm10, %xmm4 +aesdec %xmm11, %xmm1 +aesdec %xmm11, %xmm2 +aesdec %xmm11, %xmm3 +aesdec %xmm11, %xmm4 +aesdec %xmm12, %xmm1 +aesdec %xmm12, %xmm2 +aesdec %xmm12, %xmm3 +aesdec %xmm12, %xmm4 +movdqa 128(%r8), %xmm9 +movdqa 144(%r8), %xmm10 +movdqa 160(%r8), %xmm11 +cmpl $12, %r9d +aesdec %xmm9, %xmm1 +aesdec %xmm9, %xmm2 +aesdec %xmm9, %xmm3 +aesdec %xmm9, %xmm4 +aesdec %xmm10, %xmm1 +aesdec %xmm10, %xmm2 +aesdec %xmm10, %xmm3 +aesdec %xmm10, %xmm4 +jb DLAST_4 +movdqa 160(%r8), %xmm9 +movdqa 176(%r8), %xmm10 +movdqa 192(%r8), %xmm11 +cmpl $14, %r9d +aesdec %xmm9, %xmm1 +aesdec %xmm9, %xmm2 +aesdec %xmm9, %xmm3 +aesdec %xmm9, %xmm4 +aesdec %xmm10, %xmm1 +aesdec %xmm10, %xmm2 +aesdec %xmm10, %xmm3 +aesdec %xmm10, %xmm4 +jb DLAST_4 + +movdqa 192(%r8), %xmm9 +movdqa 208(%r8), %xmm10 +movdqa 224(%r8), %xmm11 +aesdec %xmm9, %xmm1 +aesdec %xmm9, %xmm2 +aesdec %xmm9, %xmm3 +aesdec %xmm9, %xmm4 +aesdec %xmm10, %xmm1 +aesdec %xmm10, %xmm2 +aesdec %xmm10, %xmm3 +aesdec %xmm10, %xmm4 +DLAST_4: +addq $64, %rdi +addq $64, %rsi +decq %rcx +aesdeclast %xmm11, %xmm1 +aesdeclast %xmm11, %xmm2 +aesdeclast %xmm11, %xmm3 +aesdeclast %xmm11, %xmm4 +pxor %xmm5 ,%xmm1 +pxor %xmm6 ,%xmm2 +pxor %xmm7 ,%xmm3 +pxor %xmm8 ,%xmm4 +movdqu %xmm1, (%rsi) +movdqu %xmm2, 16(%rsi) +movdqu %xmm3, 32(%rsi) +movdqu %xmm4, 48(%rsi) +movdqa %xmm15,%xmm5 +jne DLOOP_4 +addq $64, %rsi +DREMAINDER_4: +cmpq $0, %r10 +je DEND_4 +DLOOP_4_2: +movdqu (%rdi), %xmm1 +movdqa %xmm1 ,%xmm15 +addq $16, %rdi +pxor (%r8), %xmm1 +movdqu 160(%r8), %xmm2 +cmpl $12, %r9d +aesdec 16(%r8), %xmm1 +aesdec 32(%r8), %xmm1 +aesdec 48(%r8), %xmm1 +aesdec 64(%r8), %xmm1 +aesdec 80(%r8), %xmm1 +aesdec 96(%r8), %xmm1 +aesdec 112(%r8), %xmm1 +aesdec 128(%r8), %xmm1 +aesdec 144(%r8), %xmm1 +jb DLAST_4_2 +movdqu 192(%r8), %xmm2 +cmpl $14, %r9d +aesdec 160(%r8), %xmm1 +aesdec 176(%r8), %xmm1 +jb DLAST_4_2 +movdqu 224(%r8), %xmm2 +aesdec 192(%r8), %xmm1 +aesdec 208(%r8), %xmm1 +DLAST_4_2: +aesdeclast %xmm2, %xmm1 +pxor %xmm5, %xmm1 +movdqa %xmm15, %xmm5 +movdqu %xmm1, (%rsi) + +addq $16, %rsi +decq %r10 +jne DLOOP_4_2 +DEND_4: +ret + + +/* +AES_ECB_encrypt (const unsigned char *in, + unsigned char *out, + unsigned long length, + const unsigned char *KS, + int nr) +*/ +.globl AES_ECB_encrypt +AES_ECB_encrypt: +# parameter 1: %rdi +# parameter 2: %rsi +# parameter 3: %rdx +# parameter 4: %rcx +# parameter 5: %r8d + movq %rdx, %r10 + shrq $4, %rdx + shlq $60, %r10 + je EECB_NO_PARTS_4 + addq $1, %rdx +EECB_NO_PARTS_4: + movq %rdx, %r10 + shlq $62, %r10 + shrq $62, %r10 + shrq $2, %rdx + je EECB_REMAINDER_4 + subq $64, %rsi +EECB_LOOP_4: + movdqu (%rdi), %xmm1 + movdqu 16(%rdi), %xmm2 + movdqu 32(%rdi), %xmm3 + movdqu 48(%rdi), %xmm4 + movdqa (%rcx), %xmm9 + movdqa 16(%rcx), %xmm10 + movdqa 32(%rcx), %xmm11 + movdqa 48(%rcx), %xmm12 + pxor %xmm9, %xmm1 + pxor %xmm9, %xmm2 + pxor %xmm9, %xmm3 + pxor %xmm9, %xmm4 + aesenc %xmm10, %xmm1 + aesenc %xmm10, %xmm2 + aesenc %xmm10, %xmm3 + aesenc %xmm10, %xmm4 + aesenc %xmm11, %xmm1 + aesenc %xmm11, %xmm2 + aesenc %xmm11, %xmm3 + aesenc %xmm11, %xmm4 + aesenc %xmm12, %xmm1 + aesenc %xmm12, %xmm2 + aesenc %xmm12, %xmm3 + aesenc %xmm12, %xmm4 + movdqa 64(%rcx), %xmm9 + movdqa 80(%rcx), %xmm10 + movdqa 96(%rcx), %xmm11 + movdqa 112(%rcx), %xmm12 + aesenc %xmm9, %xmm1 + aesenc %xmm9, %xmm2 + aesenc %xmm9, %xmm3 + aesenc %xmm9, %xmm4 + aesenc %xmm10, %xmm1 + aesenc %xmm10, %xmm2 + aesenc %xmm10, %xmm3 + aesenc %xmm10, %xmm4 + aesenc %xmm11, %xmm1 + aesenc %xmm11, %xmm2 + aesenc %xmm11, %xmm3 + aesenc %xmm11, %xmm4 + aesenc %xmm12, %xmm1 + aesenc %xmm12, %xmm2 + aesenc %xmm12, %xmm3 + aesenc %xmm12, %xmm4 + movdqa 128(%rcx), %xmm9 + movdqa 144(%rcx), %xmm10 + movdqa 160(%rcx), %xmm11 + cmpl $12, %r8d + aesenc %xmm9, %xmm1 + aesenc %xmm9, %xmm2 + aesenc %xmm9, %xmm3 + aesenc %xmm9, %xmm4 + aesenc %xmm10, %xmm1 + aesenc %xmm10, %xmm2 + aesenc %xmm10, %xmm3 + aesenc %xmm10, %xmm4 + jb EECB_LAST_4 + movdqa 160(%rcx), %xmm9 + movdqa 176(%rcx), %xmm10 + movdqa 192(%rcx), %xmm11 + cmpl $14, %r8d + aesenc %xmm9, %xmm1 + aesenc %xmm9, %xmm2 + aesenc %xmm9, %xmm3 + aesenc %xmm9, %xmm4 + aesenc %xmm10, %xmm1 + aesenc %xmm10, %xmm2 + aesenc %xmm10, %xmm3 + aesenc %xmm10, %xmm4 + jb EECB_LAST_4 + movdqa 192(%rcx), %xmm9 + movdqa 208(%rcx), %xmm10 + movdqa 224(%rcx), %xmm11 + aesenc %xmm9, %xmm1 + aesenc %xmm9, %xmm2 + aesenc %xmm9, %xmm3 + aesenc %xmm9, %xmm4 + aesenc %xmm10, %xmm1 + aesenc %xmm10, %xmm2 + aesenc %xmm10, %xmm3 + aesenc %xmm10, %xmm4 +EECB_LAST_4: + addq $64, %rdi + addq $64, %rsi + decq %rdx + aesenclast %xmm11, %xmm1 + aesenclast %xmm11, %xmm2 + aesenclast %xmm11, %xmm3 + aesenclast %xmm11, %xmm4 + movdqu %xmm1, (%rsi) + movdqu %xmm2, 16(%rsi) + movdqu %xmm3, 32(%rsi) + movdqu %xmm4, 48(%rsi) + jne EECB_LOOP_4 + addq $64, %rsi +EECB_REMAINDER_4: + cmpq $0, %r10 + je EECB_END_4 +EECB_LOOP_4_2: + movdqu (%rdi), %xmm1 + addq $16, %rdi + pxor (%rcx), %xmm1 + movdqu 160(%rcx), %xmm2 + aesenc 16(%rcx), %xmm1 + aesenc 32(%rcx), %xmm1 + aesenc 48(%rcx), %xmm1 + aesenc 64(%rcx), %xmm1 + aesenc 80(%rcx), %xmm1 + aesenc 96(%rcx), %xmm1 + aesenc 112(%rcx), %xmm1 + aesenc 128(%rcx), %xmm1 + aesenc 144(%rcx), %xmm1 + cmpl $12, %r8d + jb EECB_LAST_4_2 + movdqu 192(%rcx), %xmm2 + aesenc 160(%rcx), %xmm1 + aesenc 176(%rcx), %xmm1 + cmpl $14, %r8d + jb EECB_LAST_4_2 + movdqu 224(%rcx), %xmm2 + aesenc 192(%rcx), %xmm1 + aesenc 208(%rcx), %xmm1 +EECB_LAST_4_2: + aesenclast %xmm2, %xmm1 + movdqu %xmm1, (%rsi) + addq $16, %rsi + decq %r10 + jne EECB_LOOP_4_2 +EECB_END_4: + ret + + +/* +AES_ECB_decrypt (const unsigned char *in, + unsigned char *out, + unsigned long length, + const unsigned char *KS, + int nr) +*/ +.globl AES_ECB_decrypt +AES_ECB_decrypt: +# parameter 1: %rdi +# parameter 2: %rsi +# parameter 3: %rdx +# parameter 4: %rcx +# parameter 5: %r8d + + movq %rdx, %r10 + shrq $4, %rdx + shlq $60, %r10 + je DECB_NO_PARTS_4 + addq $1, %rdx +DECB_NO_PARTS_4: + movq %rdx, %r10 + shlq $62, %r10 + shrq $62, %r10 + shrq $2, %rdx + je DECB_REMAINDER_4 + subq $64, %rsi +DECB_LOOP_4: + movdqu (%rdi), %xmm1 + movdqu 16(%rdi), %xmm2 + movdqu 32(%rdi), %xmm3 + movdqu 48(%rdi), %xmm4 + movdqa (%rcx), %xmm9 + movdqa 16(%rcx), %xmm10 + movdqa 32(%rcx), %xmm11 + movdqa 48(%rcx), %xmm12 + pxor %xmm9, %xmm1 + pxor %xmm9, %xmm2 + pxor %xmm9, %xmm3 + pxor %xmm9, %xmm4 + aesdec %xmm10, %xmm1 + aesdec %xmm10, %xmm2 + aesdec %xmm10, %xmm3 + aesdec %xmm10, %xmm4 + aesdec %xmm11, %xmm1 + aesdec %xmm11, %xmm2 + aesdec %xmm11, %xmm3 + aesdec %xmm11, %xmm4 + aesdec %xmm12, %xmm1 + aesdec %xmm12, %xmm2 + aesdec %xmm12, %xmm3 + aesdec %xmm12, %xmm4 + movdqa 64(%rcx), %xmm9 + movdqa 80(%rcx), %xmm10 + movdqa 96(%rcx), %xmm11 + movdqa 112(%rcx), %xmm12 + aesdec %xmm9, %xmm1 + aesdec %xmm9, %xmm2 + aesdec %xmm9, %xmm3 + aesdec %xmm9, %xmm4 + aesdec %xmm10, %xmm1 + aesdec %xmm10, %xmm2 + aesdec %xmm10, %xmm3 + aesdec %xmm10, %xmm4 + aesdec %xmm11, %xmm1 + aesdec %xmm11, %xmm2 + aesdec %xmm11, %xmm3 + aesdec %xmm11, %xmm4 + aesdec %xmm12, %xmm1 + aesdec %xmm12, %xmm2 + aesdec %xmm12, %xmm3 + aesdec %xmm12, %xmm4 + movdqa 128(%rcx), %xmm9 + movdqa 144(%rcx), %xmm10 + movdqa 160(%rcx), %xmm11 + cmpl $12, %r8d + aesdec %xmm9, %xmm1 + aesdec %xmm9, %xmm2 + aesdec %xmm9, %xmm3 + aesdec %xmm9, %xmm4 + aesdec %xmm10, %xmm1 + aesdec %xmm10, %xmm2 + aesdec %xmm10, %xmm3 + aesdec %xmm10, %xmm4 + jb DECB_LAST_4 + movdqa 160(%rcx), %xmm9 + movdqa 176(%rcx), %xmm10 + movdqa 192(%rcx), %xmm11 + cmpl $14, %r8d + aesdec %xmm9, %xmm1 + aesdec %xmm9, %xmm2 + aesdec %xmm9, %xmm3 + aesdec %xmm9, %xmm4 + aesdec %xmm10, %xmm1 + aesdec %xmm10, %xmm2 + aesdec %xmm10, %xmm3 + aesdec %xmm10, %xmm4 + jb DECB_LAST_4 + movdqa 192(%rcx), %xmm9 + movdqa 208(%rcx), %xmm10 + movdqa 224(%rcx), %xmm11 + aesdec %xmm9, %xmm1 + aesdec %xmm9, %xmm2 + aesdec %xmm9, %xmm3 + aesdec %xmm9, %xmm4 + aesdec %xmm10, %xmm1 + aesdec %xmm10, %xmm2 + aesdec %xmm10, %xmm3 + aesdec %xmm10, %xmm4 +DECB_LAST_4: + addq $64, %rdi + addq $64, %rsi + decq %rdx + aesdeclast %xmm11, %xmm1 + aesdeclast %xmm11, %xmm2 + aesdeclast %xmm11, %xmm3 + aesdeclast %xmm11, %xmm4 + movdqu %xmm1, (%rsi) + movdqu %xmm2, 16(%rsi) + movdqu %xmm3, 32(%rsi) + movdqu %xmm4, 48(%rsi) + jne DECB_LOOP_4 + addq $64, %rsi +DECB_REMAINDER_4: + cmpq $0, %r10 + je DECB_END_4 +DECB_LOOP_4_2: + movdqu (%rdi), %xmm1 + addq $16, %rdi + pxor (%rcx), %xmm1 + movdqu 160(%rcx), %xmm2 + cmpl $12, %r8d + aesdec 16(%rcx), %xmm1 + aesdec 32(%rcx), %xmm1 + aesdec 48(%rcx), %xmm1 + aesdec 64(%rcx), %xmm1 + aesdec 80(%rcx), %xmm1 + aesdec 96(%rcx), %xmm1 + aesdec 112(%rcx), %xmm1 + aesdec 128(%rcx), %xmm1 + aesdec 144(%rcx), %xmm1 + jb DECB_LAST_4_2 + cmpl $14, %r8d + movdqu 192(%rcx), %xmm2 + aesdec 160(%rcx), %xmm1 + aesdec 176(%rcx), %xmm1 + jb DECB_LAST_4_2 + movdqu 224(%rcx), %xmm2 + aesdec 192(%rcx), %xmm1 + aesdec 208(%rcx), %xmm1 +DECB_LAST_4_2: + aesdeclast %xmm2, %xmm1 + movdqu %xmm1, (%rsi) + addq $16, %rsi + decq %r10 + jne DECB_LOOP_4_2 +DECB_END_4: + ret + + + + +/* +void AES_128_Key_Expansion(const unsigned char* userkey, + unsigned char* key_schedule); +*/ +.align 16,0x90 +.globl AES_128_Key_Expansion +AES_128_Key_Expansion: +# parameter 1: %rdi +# parameter 2: %rsi +movl $10, 240(%rsi) + +movdqu (%rdi), %xmm1 +movdqa %xmm1, (%rsi) + + +ASSISTS: +aeskeygenassist $1, %xmm1, %xmm2 +call PREPARE_ROUNDKEY_128 +movdqa %xmm1, 16(%rsi) +aeskeygenassist $2, %xmm1, %xmm2 +call PREPARE_ROUNDKEY_128 +movdqa %xmm1, 32(%rsi) +aeskeygenassist $4, %xmm1, %xmm2 +call PREPARE_ROUNDKEY_128 +movdqa %xmm1, 48(%rsi) +aeskeygenassist $8, %xmm1, %xmm2 +call PREPARE_ROUNDKEY_128 +movdqa %xmm1, 64(%rsi) +aeskeygenassist $16, %xmm1, %xmm2 +call PREPARE_ROUNDKEY_128 +movdqa %xmm1, 80(%rsi) +aeskeygenassist $32, %xmm1, %xmm2 +call PREPARE_ROUNDKEY_128 +movdqa %xmm1, 96(%rsi) +aeskeygenassist $64, %xmm1, %xmm2 +call PREPARE_ROUNDKEY_128 +movdqa %xmm1, 112(%rsi) +aeskeygenassist $0x80, %xmm1, %xmm2 +call PREPARE_ROUNDKEY_128 +movdqa %xmm1, 128(%rsi) +aeskeygenassist $0x1b, %xmm1, %xmm2 +call PREPARE_ROUNDKEY_128 +movdqa %xmm1, 144(%rsi) +aeskeygenassist $0x36, %xmm1, %xmm2 +call PREPARE_ROUNDKEY_128 +movdqa %xmm1, 160(%rsi) +ret + +PREPARE_ROUNDKEY_128: +pshufd $255, %xmm2, %xmm2 +movdqa %xmm1, %xmm3 +pslldq $4, %xmm3 +pxor %xmm3, %xmm1 +pslldq $4, %xmm3 +pxor %xmm3, %xmm1 +pslldq $4, %xmm3 +pxor %xmm3, %xmm1 +pxor %xmm2, %xmm1 +ret + + +/* +void AES_192_Key_Expansion (const unsigned char *userkey, + unsigned char *key) +*/ +.globl AES_192_Key_Expansion +AES_192_Key_Expansion: +# parameter 1: %rdi +# parameter 2: %rsi + +movdqu (%rdi), %xmm1 +movdqu 16(%rdi), %xmm3 +movdqa %xmm1, (%rsi) +movdqa %xmm3, %xmm5 + +aeskeygenassist $0x1, %xmm3, %xmm2 +call PREPARE_ROUNDKEY_192 +shufpd $0, %xmm1, %xmm5 +movdqa %xmm5, 16(%rsi) +movdqa %xmm1, %xmm6 +shufpd $1, %xmm3, %xmm6 +movdqa %xmm6, 32(%rsi) + +aeskeygenassist $0x2, %xmm3, %xmm2 +call PREPARE_ROUNDKEY_192 +movdqa %xmm1, 48(%rsi) +movdqa %xmm3, %xmm5 + +aeskeygenassist $0x4, %xmm3, %xmm2 +call PREPARE_ROUNDKEY_192 +shufpd $0, %xmm1, %xmm5 +movdqa %xmm5, 64(%rsi) +movdqa %xmm1, %xmm6 +shufpd $1, %xmm3, %xmm6 +movdqa %xmm6, 80(%rsi) + +aeskeygenassist $0x8, %xmm3, %xmm2 +call PREPARE_ROUNDKEY_192 +movdqa %xmm1, 96(%rsi) +movdqa %xmm3, %xmm5 + +aeskeygenassist $0x10, %xmm3, %xmm2 +call PREPARE_ROUNDKEY_192 +shufpd $0, %xmm1, %xmm5 +movdqa %xmm5, 112(%rsi) +movdqa %xmm1, %xmm6 +shufpd $1, %xmm3, %xmm6 +movdqa %xmm6, 128(%rsi) + +aeskeygenassist $0x20, %xmm3, %xmm2 +call PREPARE_ROUNDKEY_192 +movdqa %xmm1, 144(%rsi) +movdqa %xmm3, %xmm5 + +aeskeygenassist $0x40, %xmm3, %xmm2 +call PREPARE_ROUNDKEY_192 +shufpd $0, %xmm1, %xmm5 +movdqa %xmm5, 160(%rsi) +movdqa %xmm1, %xmm6 +shufpd $1, %xmm3, %xmm6 +movdqa %xmm6, 176(%rsi) + +aeskeygenassist $0x80, %xmm3, %xmm2 +call PREPARE_ROUNDKEY_192 +movdqa %xmm1, 192(%rsi) +movdqa %xmm3, 208(%rsi) +ret + +PREPARE_ROUNDKEY_192: +pshufd $0x55, %xmm2, %xmm2 +movdqu %xmm1, %xmm4 +pslldq $4, %xmm4 +pxor %xmm4, %xmm1 + +pslldq $4, %xmm4 +pxor %xmm4, %xmm1 +pslldq $4, %xmm4 +pxor %xmm4, %xmm1 +pxor %xmm2, %xmm1 +pshufd $0xff, %xmm1, %xmm2 +movdqu %xmm3, %xmm4 +pslldq $4, %xmm4 +pxor %xmm4, %xmm3 +pxor %xmm2, %xmm3 +ret + + +/* +void AES_256_Key_Expansion (const unsigned char *userkey, + unsigned char *key) +*/ +.globl AES_256_Key_Expansion +AES_256_Key_Expansion: +# parameter 1: %rdi +# parameter 2: %rsi + +movdqu (%rdi), %xmm1 +movdqu 16(%rdi), %xmm3 +movdqa %xmm1, (%rsi) +movdqa %xmm3, 16(%rsi) + +aeskeygenassist $0x1, %xmm3, %xmm2 +call MAKE_RK256_a +movdqa %xmm1, 32(%rsi) +aeskeygenassist $0x0, %xmm1, %xmm2 +call MAKE_RK256_b +movdqa %xmm3, 48(%rsi) +aeskeygenassist $0x2, %xmm3, %xmm2 +call MAKE_RK256_a +movdqa %xmm1, 64(%rsi) +aeskeygenassist $0x0, %xmm1, %xmm2 +call MAKE_RK256_b +movdqa %xmm3, 80(%rsi) +aeskeygenassist $0x4, %xmm3, %xmm2 +call MAKE_RK256_a +movdqa %xmm1, 96(%rsi) +aeskeygenassist $0x0, %xmm1, %xmm2 +call MAKE_RK256_b +movdqa %xmm3, 112(%rsi) +aeskeygenassist $0x8, %xmm3, %xmm2 +call MAKE_RK256_a +movdqa %xmm1, 128(%rsi) +aeskeygenassist $0x0, %xmm1, %xmm2 +call MAKE_RK256_b +movdqa %xmm3, 144(%rsi) +aeskeygenassist $0x10, %xmm3, %xmm2 +call MAKE_RK256_a +movdqa %xmm1, 160(%rsi) +aeskeygenassist $0x0, %xmm1, %xmm2 +call MAKE_RK256_b +movdqa %xmm3, 176(%rsi) +aeskeygenassist $0x20, %xmm3, %xmm2 +call MAKE_RK256_a +movdqa %xmm1, 192(%rsi) + +aeskeygenassist $0x0, %xmm1, %xmm2 +call MAKE_RK256_b +movdqa %xmm3, 208(%rsi) +aeskeygenassist $0x40, %xmm3, %xmm2 +call MAKE_RK256_a +movdqa %xmm1, 224(%rsi) + +ret + +MAKE_RK256_a: +pshufd $0xff, %xmm2, %xmm2 +movdqa %xmm1, %xmm4 +pslldq $4, %xmm4 +pxor %xmm4, %xmm1 +pslldq $4, %xmm4 +pxor %xmm4, %xmm1 +pslldq $4, %xmm4 +pxor %xmm4, %xmm1 +pxor %xmm2, %xmm1 +ret + +MAKE_RK256_b: +pshufd $0xaa, %xmm2, %xmm2 +movdqa %xmm3, %xmm4 +pslldq $4, %xmm4 +pxor %xmm4, %xmm3 +pslldq $4, %xmm4 +pxor %xmm4, %xmm3 +pslldq $4, %xmm4 +pxor %xmm4, %xmm3 +pxor %xmm2, %xmm3 +ret + diff --git a/wolfssl/wolfcrypt/rsa.h b/wolfssl/wolfcrypt/rsa.h index 7fc6d6906..b653436cf 100644 --- a/wolfssl/wolfcrypt/rsa.h +++ b/wolfssl/wolfcrypt/rsa.h @@ -42,6 +42,7 @@ #endif #ifndef HAVE_FIPS +#define CTAO_CRYPT_RSA_H #define WOLFSSL_RSA_CAVIUM_MAGIC 0xBEEF0006 enum {