Last active
September 22, 2017 11:57
-
-
Save MewX/230d5d905a409e12cc72f6707955bc1c to your computer and use it in GitHub Desktop.
Failed algorithms
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* 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. | |
*/ | |
/* | |
* Algorithm Specification | |
* http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html | |
*/ | |
#include <stdlib.h> | |
#include <msp430.h> | |
#include <stdint.h> | |
#include "tools.h" | |
#define CAMELLIA_BLOCK_SIZE 16 | |
#define CAMELLIA_TABLE_BYTE_LEN 272 | |
#define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4) | |
typedef unsigned int KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN]; | |
/* u32 must be 32bit word */ | |
typedef uint32_t u32; | |
typedef uint16_t u16; | |
typedef uint8_t u8; | |
/* key constants */ | |
#define CAMELLIA_SIGMA1L (0xA09E667FL) | |
#define CAMELLIA_SIGMA1R (0x3BCC908BL) | |
#define CAMELLIA_SIGMA2L (0xB67AE858L) | |
#define CAMELLIA_SIGMA2R (0x4CAA73B2L) | |
#define CAMELLIA_SIGMA3L (0xC6EF372FL) | |
#define CAMELLIA_SIGMA3R (0xE94F82BEL) | |
#define CAMELLIA_SIGMA4L (0x54FF53A5L) | |
#define CAMELLIA_SIGMA4R (0xF1D36F1CL) | |
#define CAMELLIA_SIGMA5L (0x10E527FAL) | |
#define CAMELLIA_SIGMA5R (0xDE682D1DL) | |
#define CAMELLIA_SIGMA6L (0xB05688C2L) | |
#define CAMELLIA_SIGMA6R (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)] | |
void 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; | |
u32 subL[26]; | |
u32 subR[26]; | |
/** | |
* 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; | |
return; | |
} | |
/** | |
* Stuff related to camellia encryption/decryption | |
* | |
* "io" must be 4byte aligned and big-endian data. | |
*/ | |
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 | |
*/ | |
void Camellia_DecryptBlock(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); | |
camellia_decrypt128(keyTable, tmp); | |
PUTU32(plaintext, tmp[0]); | |
PUTU32(plaintext + 4, tmp[1]); | |
PUTU32(plaintext + 8, tmp[2]); | |
PUTU32(plaintext + 12, tmp[3]); | |
} | |
int main(int argc, char* argv[]) | |
{ | |
// Stop WatchDog during initialization | |
WDTCTL = WDTPW + WDTHOLD; | |
// ************ Declarations ************ | |
u16 text[8]={0xeeff, 0xccdd, 0xaabb, 0x8899, 0x6677, 0x4455, 0x4455, 0x0011}; | |
u16 ptext[8]={0}; | |
u16 k128[8] = {0x0011, 0x4455, 0x4455, 0x6677, 0x8899, 0xaabb, 0xccdd, 0xeeff}; | |
uint32_t roundKey[CAMELLIA_TABLE_WORD_LEN] = {0}; | |
START_DECRYPT(); | |
camellia_setup128((u8 *)k128, roundKey); | |
Camellia_DecryptBlock(text, roundKey, ptext); | |
END_EXPE(); | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/************************************************** | |
* * | |
* Camellia Block Encryption Algorithm * | |
* in ANSI-C Language : Camellia.c * | |
* * | |
* Version M1.02 September 24 2001 * | |
* Copyright Mitsubishi Electric Corp 2000-2001 * | |
* * | |
**************************************************/ | |
#include <stdlib.h> | |
#include <msp430.h> | |
#include <stdint.h> | |
#include "tools.h" | |
typedef uint8_t Byte; | |
typedef uint16_t u16; | |
typedef uint32_t Word; | |
void Camellia_Ekeygen( const Byte *, Byte * ); | |
void Camellia_Decrypt( const Byte *, const Byte *, Byte * ); | |
void Camellia_Feistel( const Byte *, const Byte *, Byte * ); | |
void Camellia_FLlayer( Byte *, const Byte *, const Byte * ); | |
void ByteWord( const Byte *, Word * ); | |
void WordByte( const Word *, Byte * ); | |
void XorBlock( const Byte *, const Byte *, Byte * ); | |
void SwapHalf( Byte * ); | |
void RotBlock( const Word *, const int, Word * ); | |
const Byte SIGMA[48] = { | |
0xa0,0x9e,0x66,0x7f,0x3b,0xcc,0x90,0x8b, | |
0xb6,0x7a,0xe8,0x58,0x4c,0xaa,0x73,0xb2, | |
0xc6,0xef,0x37,0x2f,0xe9,0x4f,0x82,0xbe, | |
0x54,0xff,0x53,0xa5,0xf1,0xd3,0x6f,0x1c, | |
0x10,0xe5,0x27,0xfa,0xde,0x68,0x2d,0x1d, | |
0xb0,0x56,0x88,0xc2,0xb3,0xe6,0xc1,0xfd}; | |
const int KSFT1[26] = { | |
0,64,0,64,15,79,15,79,30,94,45,109,45,124,60,124,77,13, | |
94,30,94,30,111,47,111,47 }; | |
const int KIDX1[26] = { | |
0,0,4,4,0,0,4,4,4,4,0,0,4,0,4,4,0,0,0,0,4,4,0,0,4,4 }; | |
const int KSFT2[34] = { | |
0,64,0,64,15,79,15,79,30,94,30,94,45,109,45,109,60,124, | |
60,124,60,124,77,13,77,13,94,30,94,30,111,47,111,47 }; | |
const int KIDX2[34] = { | |
0,0,12,12,8,8,4,4,8,8,12,12,0,0,4,4,0,0,8,8,12,12, | |
0,0,4,4,8,8,4,4,0,0,12,12 }; | |
const Byte SBOX[256] = { | |
112,130, 44,236,179, 39,192,229,228,133, 87, 53,234, 12,174, 65, | |
35,239,107,147, 69, 25,165, 33,237, 14, 79, 78, 29,101,146,189, | |
134,184,175,143,124,235, 31,206, 62, 48,220, 95, 94,197, 11, 26, | |
166,225, 57,202,213, 71, 93, 61,217, 1, 90,214, 81, 86,108, 77, | |
139, 13,154,102,251,204,176, 45,116, 18, 43, 32,240,177,132,153, | |
223, 76,203,194, 52,126,118, 5,109,183,169, 49,209, 23, 4,215, | |
20, 88, 58, 97,222, 27, 17, 28, 50, 15,156, 22, 83, 24,242, 34, | |
254, 68,207,178,195,181,122,145, 36, 8,232,168, 96,252,105, 80, | |
170,208,160,125,161,137, 98,151, 84, 91, 30,149,224,255,100,210, | |
16,196, 0, 72,163,247,117,219,138, 3,230,218, 9, 63,221,148, | |
135, 92,131, 2,205, 74,144, 51,115,103,246,243,157,127,191,226, | |
82,155,216, 38,200, 55,198, 59,129,150,111, 75, 19,190, 99, 46, | |
233,121,167,140,159,110,188,142, 41,245,249,182, 47,253,180, 89, | |
120,152, 6,106,231, 70,113,186,212, 37,171, 66,136,162,141,250, | |
114, 7,185, 85,248,238,172, 10, 54, 73, 42,104, 60, 56,241,164, | |
64, 40,211,123,187,201, 67,193, 21,227,173,244,119,199,128,158}; | |
#define SBOX1(n) SBOX[(n)] | |
#define SBOX2(n) (Byte)((SBOX[(n)]>>7^SBOX[(n)]<<1)&0xff) | |
#define SBOX3(n) (Byte)((SBOX[(n)]>>1^SBOX[(n)]<<7)&0xff) | |
#define SBOX4(n) SBOX[((n)<<1^(n)>>7)&0xff] | |
void Camellia_Ekeygen(const Byte *k, Byte *e ) | |
{ | |
Byte t[64]; | |
Word u[20]; | |
int i; | |
for( i=0 ; i<16; i++ ) t[i] = k[i]; | |
for( i=16; i<32; i++ ) t[i] = 0; | |
XorBlock( t+0, t+16, t+32 ); | |
Camellia_Feistel( t+32, SIGMA+0, t+40 ); | |
Camellia_Feistel( t+40, SIGMA+8, t+32 ); | |
XorBlock( t+32, t+0, t+32 ); | |
Camellia_Feistel( t+32, SIGMA+16, t+40 ); | |
Camellia_Feistel( t+40, SIGMA+24, t+32 ); | |
ByteWord( t+0, u+0 ); | |
ByteWord( t+32, u+4 ); | |
for( i=0; i<26; i+=2 ){ | |
RotBlock( u+KIDX1[i+0], KSFT1[i+0], u+16 ); | |
RotBlock( u+KIDX1[i+1], KSFT1[i+1], u+18 ); | |
WordByte( u+16, e+i*8 ); | |
} | |
} | |
void Camellia_Decrypt(const Byte *c, const Byte *e, Byte *p ) | |
{ | |
int i; | |
XorBlock( c, e+192, p ); | |
for( i=2; i>=0; i-- ){ | |
Camellia_Feistel( p+0, e+152+(i<<4), p+8 ); | |
Camellia_Feistel( p+8, e+144+(i<<4), p+0 ); | |
} | |
Camellia_FLlayer( p, e+136, e+128 ); | |
for( i=2; i>=0; i-- ){ | |
Camellia_Feistel( p+0, e+88+(i<<4), p+8 ); | |
Camellia_Feistel( p+8, e+80+(i<<4), p+0 ); | |
} | |
Camellia_FLlayer( p, e+72, e+64 ); | |
for( i=2; i>=0; i-- ){ | |
Camellia_Feistel( p+0, e+24+(i<<4), p+8 ); | |
Camellia_Feistel( p+8, e+16+(i<<4), p+0 ); | |
} | |
SwapHalf( p ); | |
XorBlock( p, e+0, p ); | |
} | |
void Camellia_Feistel( const Byte *x, const Byte *k, Byte *y ) | |
{ | |
Byte t[8]; | |
t[0] = SBOX1(x[0]^k[0]); | |
t[1] = SBOX2(x[1]^k[1]); | |
t[2] = SBOX3(x[2]^k[2]); | |
t[3] = SBOX4(x[3]^k[3]); | |
t[4] = SBOX2(x[4]^k[4]); | |
t[5] = SBOX3(x[5]^k[5]); | |
t[6] = SBOX4(x[6]^k[6]); | |
t[7] = SBOX1(x[7]^k[7]); | |
y[0] ^= t[0]^t[2]^t[3]^t[5]^t[6]^t[7]; | |
y[1] ^= t[0]^t[1]^t[3]^t[4]^t[6]^t[7]; | |
y[2] ^= t[0]^t[1]^t[2]^t[4]^t[5]^t[7]; | |
y[3] ^= t[1]^t[2]^t[3]^t[4]^t[5]^t[6]; | |
y[4] ^= t[0]^t[1]^t[5]^t[6]^t[7]; | |
y[5] ^= t[1]^t[2]^t[4]^t[6]^t[7]; | |
y[6] ^= t[2]^t[3]^t[4]^t[5]^t[7]; | |
y[7] ^= t[0]^t[3]^t[4]^t[5]^t[6]; | |
} | |
void Camellia_FLlayer( Byte *x, const Byte *kl, const Byte *kr ) | |
{ | |
Word t[4],u[4],v[4]; | |
ByteWord( x, t ); | |
ByteWord( kl, u ); | |
ByteWord( kr, v ); | |
t[1] ^= (t[0]&u[0])<<1^(t[0]&u[0])>>31; | |
t[0] ^= t[1]|u[1]; | |
t[2] ^= t[3]|v[1]; | |
t[3] ^= (t[2]&v[0])<<1^(t[2]&v[0])>>31; | |
WordByte( t, x ); | |
} | |
void ByteWord( const Byte *x, Word *y ) | |
{ | |
int i; | |
for( i=0; i<4; i++ ){ | |
y[i] = ((Word)x[(i<<2)+0]<<24) + ((Word)x[(i<<2)+1]<<16) | |
+ ((Word)x[(i<<2)+2]<<8 ) + ((Word)x[(i<<2)+3]<<0 ); | |
} | |
} | |
void WordByte( const Word *x, Byte *y ) | |
{ | |
int i; | |
for( i=0; i<4; i++ ){ | |
y[(i<<2)+0] = (Byte)(x[i]>>24&0xff); | |
y[(i<<2)+1] = (Byte)(x[i]>>16&0xff); | |
y[(i<<2)+2] = (Byte)(x[i]>> 8&0xff); | |
y[(i<<2)+3] = (Byte)(x[i]>> 0&0xff); | |
} | |
} | |
void RotBlock( const Word *x, const int n, Word *y ) | |
{ | |
int r; | |
if( r = (n & 31) ){ | |
y[0] = x[((n>>5)+0)&3]<<r^x[((n>>5)+1)&3]>>(32-r); | |
y[1] = x[((n>>5)+1)&3]<<r^x[((n>>5)+2)&3]>>(32-r); | |
} | |
else{ | |
y[0] = x[((n>>5)+0)&3]; | |
y[1] = x[((n>>5)+1)&3]; | |
} | |
} | |
void SwapHalf( Byte *x ) | |
{ | |
Byte t; | |
int i; | |
for( i=0; i<8; i++ ){ | |
t = x[i]; | |
x[i] = x[8+i]; | |
x[8+i] = t; | |
} | |
} | |
void XorBlock( const Byte *x, const Byte *y, Byte *z ) | |
{ | |
int i; | |
for( i=0; i<16; i++ ) z[i] = x[i] ^ y[i]; | |
} | |
int main(int argc, char* argv[]) | |
{ | |
// Stop WatchDog during initialization | |
WDTCTL = WDTPW + WDTHOLD; | |
// ************ Declarations ************ | |
u16 text[8]={0xeeff, 0xccdd, 0xaabb, 0x8899, 0x6677, 0x4455, 0x4455, 0x0011}; | |
u16 ptext[8]={0}; | |
u16 k128[8] = {0x0011, 0x4455, 0x4455, 0x6677, 0x8899, 0xaabb, 0xccdd, 0xeeff}; | |
Word roundKey[272] = {0}; | |
START_DECRYPT(); | |
Camellia_Ekeygen((Byte *)k128, (Byte *)roundKey); | |
Camellia_Decrypt((Byte *)text, (Byte *)roundKey, (Byte *)ptext); | |
END_EXPE(); | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/****************************************************************************** | |
* Copyright 2007, 2008 Sony Corporation | |
* | |
* clefia_ref.c | |
* | |
* "The 128-bit Blockcipher CLEFIA" | |
* Reference ANSI C code | |
* | |
* Version 1.0.1 (August 26 2008) | |
* | |
* NOTICE | |
* This reference code is written for a clear understanding of the CLEFIA | |
* blockcipher algorithm based on the specification of CLEFIA. | |
* Therefore, this code does not include any optimizations for | |
* high-speed or low-cost implementations or any countermeasures against | |
* implementation attacks. | |
* | |
*****************************************************************************/ | |
#include <stdlib.h> | |
#include <msp430.h> | |
#include <stdint.h> | |
#include "tools.h" | |
typedef uint8_t u8; | |
typedef uint16_t u16; | |
typedef uint32_t u32; | |
void ByteCpy(u8 *dst, const u8 *src, int bytelen); | |
void ByteXor(u8 *dst, const u8 *a, const u8 *b, int bytelen); | |
u8 ClefiaMul2(u8 x); | |
void ClefiaF0Xor(u8 *y, const u8 *x, const u8 *rk); | |
void ClefiaF1Xor(u8 *y, const u8 *x, const u8 *rk); | |
void ClefiaGfn4(u8 *y, const u8 *x, const u8 *rk, int r); | |
void ClefiaGfn8(u8 *y, const u8 *x, const u8 *rk, int r); | |
void ClefiaGfn4Inv(u8 *y, const u8 *x, const u8 *rk, int r); | |
void ClefiaDoubleSwap(u8 *lk); | |
void ClefiaConSet(u8 *con, const u8 *iv, int lk); | |
void ClefiaKeySet128(u8 *rk, const u8 *skey); | |
void ClefiaKeySet192(u8 *rk, const u8 *skey); | |
void ClefiaKeySet256(u8 *rk, const u8 *skey); | |
int ClefiaKeySet(u8 *rk, const u8 *skey, const int key_bitlen); | |
void ClefiaEncrypt(u8 *ct, const u8 *pt, const u8 *rk, const int r); | |
void ClefiaDecrypt(u8 *pt, const u8 *ct, const u8 *rk, const int r); | |
/* S0 (8-bit S-box based on four 4-bit S-boxes) */ | |
const u8 clefia_s0[256] = { | |
0x57U, 0x49U, 0xd1U, 0xc6U, 0x2fU, 0x33U, 0x74U, 0xfbU, | |
0x95U, 0x6dU, 0x82U, 0xeaU, 0x0eU, 0xb0U, 0xa8U, 0x1cU, | |
0x28U, 0xd0U, 0x4bU, 0x92U, 0x5cU, 0xeeU, 0x85U, 0xb1U, | |
0xc4U, 0x0aU, 0x76U, 0x3dU, 0x63U, 0xf9U, 0x17U, 0xafU, | |
0xbfU, 0xa1U, 0x19U, 0x65U, 0xf7U, 0x7aU, 0x32U, 0x20U, | |
0x06U, 0xceU, 0xe4U, 0x83U, 0x9dU, 0x5bU, 0x4cU, 0xd8U, | |
0x42U, 0x5dU, 0x2eU, 0xe8U, 0xd4U, 0x9bU, 0x0fU, 0x13U, | |
0x3cU, 0x89U, 0x67U, 0xc0U, 0x71U, 0xaaU, 0xb6U, 0xf5U, | |
0xa4U, 0xbeU, 0xfdU, 0x8cU, 0x12U, 0x00U, 0x97U, 0xdaU, | |
0x78U, 0xe1U, 0xcfU, 0x6bU, 0x39U, 0x43U, 0x55U, 0x26U, | |
0x30U, 0x98U, 0xccU, 0xddU, 0xebU, 0x54U, 0xb3U, 0x8fU, | |
0x4eU, 0x16U, 0xfaU, 0x22U, 0xa5U, 0x77U, 0x09U, 0x61U, | |
0xd6U, 0x2aU, 0x53U, 0x37U, 0x45U, 0xc1U, 0x6cU, 0xaeU, | |
0xefU, 0x70U, 0x08U, 0x99U, 0x8bU, 0x1dU, 0xf2U, 0xb4U, | |
0xe9U, 0xc7U, 0x9fU, 0x4aU, 0x31U, 0x25U, 0xfeU, 0x7cU, | |
0xd3U, 0xa2U, 0xbdU, 0x56U, 0x14U, 0x88U, 0x60U, 0x0bU, | |
0xcdU, 0xe2U, 0x34U, 0x50U, 0x9eU, 0xdcU, 0x11U, 0x05U, | |
0x2bU, 0xb7U, 0xa9U, 0x48U, 0xffU, 0x66U, 0x8aU, 0x73U, | |
0x03U, 0x75U, 0x86U, 0xf1U, 0x6aU, 0xa7U, 0x40U, 0xc2U, | |
0xb9U, 0x2cU, 0xdbU, 0x1fU, 0x58U, 0x94U, 0x3eU, 0xedU, | |
0xfcU, 0x1bU, 0xa0U, 0x04U, 0xb8U, 0x8dU, 0xe6U, 0x59U, | |
0x62U, 0x93U, 0x35U, 0x7eU, 0xcaU, 0x21U, 0xdfU, 0x47U, | |
0x15U, 0xf3U, 0xbaU, 0x7fU, 0xa6U, 0x69U, 0xc8U, 0x4dU, | |
0x87U, 0x3bU, 0x9cU, 0x01U, 0xe0U, 0xdeU, 0x24U, 0x52U, | |
0x7bU, 0x0cU, 0x68U, 0x1eU, 0x80U, 0xb2U, 0x5aU, 0xe7U, | |
0xadU, 0xd5U, 0x23U, 0xf4U, 0x46U, 0x3fU, 0x91U, 0xc9U, | |
0x6eU, 0x84U, 0x72U, 0xbbU, 0x0dU, 0x18U, 0xd9U, 0x96U, | |
0xf0U, 0x5fU, 0x41U, 0xacU, 0x27U, 0xc5U, 0xe3U, 0x3aU, | |
0x81U, 0x6fU, 0x07U, 0xa3U, 0x79U, 0xf6U, 0x2dU, 0x38U, | |
0x1aU, 0x44U, 0x5eU, 0xb5U, 0xd2U, 0xecU, 0xcbU, 0x90U, | |
0x9aU, 0x36U, 0xe5U, 0x29U, 0xc3U, 0x4fU, 0xabU, 0x64U, | |
0x51U, 0xf8U, 0x10U, 0xd7U, 0xbcU, 0x02U, 0x7dU, 0x8eU | |
}; | |
/* S1 (8-bit S-box based on inverse function) */ | |
const u8 clefia_s1[256] = { | |
0x6cU, 0xdaU, 0xc3U, 0xe9U, 0x4eU, 0x9dU, 0x0aU, 0x3dU, | |
0xb8U, 0x36U, 0xb4U, 0x38U, 0x13U, 0x34U, 0x0cU, 0xd9U, | |
0xbfU, 0x74U, 0x94U, 0x8fU, 0xb7U, 0x9cU, 0xe5U, 0xdcU, | |
0x9eU, 0x07U, 0x49U, 0x4fU, 0x98U, 0x2cU, 0xb0U, 0x93U, | |
0x12U, 0xebU, 0xcdU, 0xb3U, 0x92U, 0xe7U, 0x41U, 0x60U, | |
0xe3U, 0x21U, 0x27U, 0x3bU, 0xe6U, 0x19U, 0xd2U, 0x0eU, | |
0x91U, 0x11U, 0xc7U, 0x3fU, 0x2aU, 0x8eU, 0xa1U, 0xbcU, | |
0x2bU, 0xc8U, 0xc5U, 0x0fU, 0x5bU, 0xf3U, 0x87U, 0x8bU, | |
0xfbU, 0xf5U, 0xdeU, 0x20U, 0xc6U, 0xa7U, 0x84U, 0xceU, | |
0xd8U, 0x65U, 0x51U, 0xc9U, 0xa4U, 0xefU, 0x43U, 0x53U, | |
0x25U, 0x5dU, 0x9bU, 0x31U, 0xe8U, 0x3eU, 0x0dU, 0xd7U, | |
0x80U, 0xffU, 0x69U, 0x8aU, 0xbaU, 0x0bU, 0x73U, 0x5cU, | |
0x6eU, 0x54U, 0x15U, 0x62U, 0xf6U, 0x35U, 0x30U, 0x52U, | |
0xa3U, 0x16U, 0xd3U, 0x28U, 0x32U, 0xfaU, 0xaaU, 0x5eU, | |
0xcfU, 0xeaU, 0xedU, 0x78U, 0x33U, 0x58U, 0x09U, 0x7bU, | |
0x63U, 0xc0U, 0xc1U, 0x46U, 0x1eU, 0xdfU, 0xa9U, 0x99U, | |
0x55U, 0x04U, 0xc4U, 0x86U, 0x39U, 0x77U, 0x82U, 0xecU, | |
0x40U, 0x18U, 0x90U, 0x97U, 0x59U, 0xddU, 0x83U, 0x1fU, | |
0x9aU, 0x37U, 0x06U, 0x24U, 0x64U, 0x7cU, 0xa5U, 0x56U, | |
0x48U, 0x08U, 0x85U, 0xd0U, 0x61U, 0x26U, 0xcaU, 0x6fU, | |
0x7eU, 0x6aU, 0xb6U, 0x71U, 0xa0U, 0x70U, 0x05U, 0xd1U, | |
0x45U, 0x8cU, 0x23U, 0x1cU, 0xf0U, 0xeeU, 0x89U, 0xadU, | |
0x7aU, 0x4bU, 0xc2U, 0x2fU, 0xdbU, 0x5aU, 0x4dU, 0x76U, | |
0x67U, 0x17U, 0x2dU, 0xf4U, 0xcbU, 0xb1U, 0x4aU, 0xa8U, | |
0xb5U, 0x22U, 0x47U, 0x3aU, 0xd5U, 0x10U, 0x4cU, 0x72U, | |
0xccU, 0x00U, 0xf9U, 0xe0U, 0xfdU, 0xe2U, 0xfeU, 0xaeU, | |
0xf8U, 0x5fU, 0xabU, 0xf1U, 0x1bU, 0x42U, 0x81U, 0xd6U, | |
0xbeU, 0x44U, 0x29U, 0xa6U, 0x57U, 0xb9U, 0xafU, 0xf2U, | |
0xd4U, 0x75U, 0x66U, 0xbbU, 0x68U, 0x9fU, 0x50U, 0x02U, | |
0x01U, 0x3cU, 0x7fU, 0x8dU, 0x1aU, 0x88U, 0xbdU, 0xacU, | |
0xf7U, 0xe4U, 0x79U, 0x96U, 0xa2U, 0xfcU, 0x6dU, 0xb2U, | |
0x6bU, 0x03U, 0xe1U, 0x2eU, 0x7dU, 0x14U, 0x95U, 0x1dU | |
}; | |
void ByteCpy(u8 *dst, const u8 *src, int bytelen) | |
{ | |
while(bytelen-- > 0){ | |
*dst++ = *src++; | |
} | |
} | |
void ByteXor(u8 *dst, const u8 *a, const u8 *b, int bytelen) | |
{ | |
while(bytelen-- > 0){ | |
*dst++ = *a++ ^ *b++; | |
} | |
} | |
u8 ClefiaMul2(u8 x) | |
{ | |
/* multiplication over GF(2^8) (p(x) = '11d') */ | |
if(x & 0x80U){ | |
x ^= 0x0eU; | |
} | |
return ((x << 1) | (x >> 7)); | |
} | |
#define ClefiaMul4(_x) (ClefiaMul2(ClefiaMul2((_x)))) | |
#define ClefiaMul6(_x) (ClefiaMul2((_x)) ^ ClefiaMul4((_x))) | |
#define ClefiaMul8(_x) (ClefiaMul2(ClefiaMul4((_x)))) | |
#define ClefiaMulA(_x) (ClefiaMul2((_x)) ^ ClefiaMul8((_x))) | |
void ClefiaF0Xor(u8 *dst, const u8 *src, const u8 *rk) | |
{ | |
u8 x[4], y[4], z[4]; | |
/* F0 */ | |
/* Key addition */ | |
ByteXor(x, src, rk, 4); | |
/* Substitution layer */ | |
z[0] = clefia_s0[x[0]]; | |
z[1] = clefia_s1[x[1]]; | |
z[2] = clefia_s0[x[2]]; | |
z[3] = clefia_s1[x[3]]; | |
/* Diffusion layer (M0) */ | |
y[0] = z[0] ^ ClefiaMul2(z[1]) ^ ClefiaMul4(z[2]) ^ ClefiaMul6(z[3]); | |
y[1] = ClefiaMul2(z[0]) ^ z[1] ^ ClefiaMul6(z[2]) ^ ClefiaMul4(z[3]); | |
y[2] = ClefiaMul4(z[0]) ^ ClefiaMul6(z[1]) ^ z[2] ^ ClefiaMul2(z[3]); | |
y[3] = ClefiaMul6(z[0]) ^ ClefiaMul4(z[1]) ^ ClefiaMul2(z[2]) ^ z[3] ; | |
/* Xoring after F0 */ | |
ByteCpy(dst + 0, src + 0, 4); | |
ByteXor(dst + 4, src + 4, y, 4); | |
} | |
void ClefiaF1Xor(u8 *dst, const u8 *src, const u8 *rk) | |
{ | |
u8 x[4], y[4], z[4]; | |
/* F1 */ | |
/* Key addition */ | |
ByteXor(x, src, rk, 4); | |
/* Substitution layer */ | |
z[0] = clefia_s1[x[0]]; | |
z[1] = clefia_s0[x[1]]; | |
z[2] = clefia_s1[x[2]]; | |
z[3] = clefia_s0[x[3]]; | |
/* Diffusion layer (M1) */ | |
y[0] = z[0] ^ ClefiaMul8(z[1]) ^ ClefiaMul2(z[2]) ^ ClefiaMulA(z[3]); | |
y[1] = ClefiaMul8(z[0]) ^ z[1] ^ ClefiaMulA(z[2]) ^ ClefiaMul2(z[3]); | |
y[2] = ClefiaMul2(z[0]) ^ ClefiaMulA(z[1]) ^ z[2] ^ ClefiaMul8(z[3]); | |
y[3] = ClefiaMulA(z[0]) ^ ClefiaMul2(z[1]) ^ ClefiaMul8(z[2]) ^ z[3] ; | |
/* Xoring after F1 */ | |
ByteCpy(dst + 0, src + 0, 4); | |
ByteXor(dst + 4, src + 4, y, 4); | |
} | |
void ClefiaGfn4(u8 *y, const u8 *x, const u8 *rk, int r) | |
{ | |
u8 fin[16], fout[16]; | |
ByteCpy(fin, x, 16); | |
while(r-- > 0){ | |
ClefiaF0Xor(fout + 0, fin + 0, rk + 0); | |
ClefiaF1Xor(fout + 8, fin + 8, rk + 4); | |
rk += 8; | |
if(r){ /* swapping for encryption */ | |
ByteCpy(fin + 0, fout + 4, 12); | |
ByteCpy(fin + 12, fout + 0, 4); | |
} | |
} | |
ByteCpy(y, fout, 16); | |
} | |
void ClefiaGfn8(u8 *y, const u8 *x, const u8 *rk, int r) | |
{ | |
u8 fin[32], fout[32]; | |
ByteCpy(fin, x, 32); | |
while(r-- > 0){ | |
ClefiaF0Xor(fout + 0, fin + 0, rk + 0); | |
ClefiaF1Xor(fout + 8, fin + 8, rk + 4); | |
ClefiaF0Xor(fout + 16, fin + 16, rk + 8); | |
ClefiaF1Xor(fout + 24, fin + 24, rk + 12); | |
rk += 16; | |
if(r){ /* swapping for encryption */ | |
ByteCpy(fin + 0, fout + 4, 28); | |
ByteCpy(fin + 28, fout + 0, 4); | |
} | |
} | |
ByteCpy(y, fout, 32); | |
} | |
void ClefiaGfn4Inv(u8 *y, const u8 *x, const u8 *rk, int r) | |
{ | |
u8 fin[16], fout[16]; | |
rk += (r - 1) * 8; | |
ByteCpy(fin, x, 16); | |
while(r-- > 0){ | |
ClefiaF0Xor(fout + 0, fin + 0, rk + 0); | |
ClefiaF1Xor(fout + 8, fin + 8, rk + 4); | |
rk -= 8; | |
if(r){ /* swapping for decryption */ | |
ByteCpy(fin + 0, fout + 12, 4); | |
ByteCpy(fin + 4, fout + 0, 12); | |
} | |
} | |
ByteCpy(y, fout, 16); | |
} | |
void ClefiaDoubleSwap(u8 *lk) | |
{ | |
u8 t[16]; | |
t[0] = (lk[0] << 7) | (lk[1] >> 1); | |
t[1] = (lk[1] << 7) | (lk[2] >> 1); | |
t[2] = (lk[2] << 7) | (lk[3] >> 1); | |
t[3] = (lk[3] << 7) | (lk[4] >> 1); | |
t[4] = (lk[4] << 7) | (lk[5] >> 1); | |
t[5] = (lk[5] << 7) | (lk[6] >> 1); | |
t[6] = (lk[6] << 7) | (lk[7] >> 1); | |
t[7] = (lk[7] << 7) | (lk[15] & 0x7fU); | |
t[8] = (lk[8] >> 7) | (lk[0] & 0xfeU); | |
t[9] = (lk[9] >> 7) | (lk[8] << 1); | |
t[10] = (lk[10] >> 7) | (lk[9] << 1); | |
t[11] = (lk[11] >> 7) | (lk[10] << 1); | |
t[12] = (lk[12] >> 7) | (lk[11] << 1); | |
t[13] = (lk[13] >> 7) | (lk[12] << 1); | |
t[14] = (lk[14] >> 7) | (lk[13] << 1); | |
t[15] = (lk[15] >> 7) | (lk[14] << 1); | |
ByteCpy(lk, t, 16); | |
} | |
void ClefiaConSet(u8 *con, const u8 *iv, int lk) | |
{ | |
u8 t[2]; | |
u8 tmp; | |
ByteCpy(t, iv, 2); | |
while(lk-- > 0){ | |
con[0] = t[0] ^ 0xb7U; /* P_16 = 0xb7e1 (natural logarithm) */ | |
con[1] = t[1] ^ 0xe1U; | |
con[2] = ~((t[0] << 1) | (t[1] >> 7)); | |
con[3] = ~((t[1] << 1) | (t[0] >> 7)); | |
con[4] = ~t[0] ^ 0x24U; /* Q_16 = 0x243f (circle ratio) */ | |
con[5] = ~t[1] ^ 0x3fU; | |
con[6] = t[1]; | |
con[7] = t[0]; | |
con += 8; | |
/* updating T */ | |
if(t[1] & 0x01U){ | |
t[0] ^= 0xa8U; | |
t[1] ^= 0x30U; | |
} | |
tmp = t[0] << 7; | |
t[0] = (t[0] >> 1) | (t[1] << 7); | |
t[1] = (t[1] >> 1) | tmp; | |
} | |
} | |
void ClefiaKeySet128(u8 *rk, const u8 *skey) | |
{ | |
const u8 iv[2] = {0x42U, 0x8aU}; /* cubic root of 2 */ | |
u8 lk[16]; | |
u8 con128[4 * 60]; | |
int i; | |
/* generating CONi^(128) (0 <= i < 60, lk = 30) */ | |
ClefiaConSet(con128, iv, 30); | |
/* GFN_{4,12} (generating L from K) */ | |
ClefiaGfn4(lk, skey, con128, 12); | |
ByteCpy(rk, skey, 8); /* initial whitening key (WK0, WK1) */ | |
rk += 8; | |
for(i = 0; i < 9; i++){ /* round key (RKi (0 <= i < 36)) */ | |
ByteXor(rk, lk, con128 + i * 16 + (4 * 24), 16); | |
if(i % 2){ | |
ByteXor(rk, rk, skey, 16); /* Xoring K */ | |
} | |
ClefiaDoubleSwap(lk); /* Updating L (DoubleSwap function) */ | |
rk += 16; | |
} | |
ByteCpy(rk, skey + 8, 8); /* final whitening key (WK2, WK3) */ | |
} | |
void ClefiaDecrypt(u8 *pt, const u8 *ct, const u8 *rk, const int r) | |
{ | |
u8 rin[16], rout[16]; | |
ByteCpy(rin, ct, 16); | |
ByteXor(rin + 4, rin + 4, rk + r * 8 + 8, 4); /* initial key whitening */ | |
ByteXor(rin + 12, rin + 12, rk + r * 8 + 12, 4); | |
rk += 8; | |
ClefiaGfn4Inv(rout, rin, rk, r); /* GFN^{-1}_{4,r} */ | |
ByteCpy(pt, rout, 16); | |
ByteXor(pt + 4, pt + 4, rk - 8, 4); /* final key whitening */ | |
ByteXor(pt + 12, pt + 12, rk - 4, 4); | |
} | |
int main(int argc, u8* argv[]) | |
{ | |
// Stop WatchDog during initialization | |
WDTCTL = WDTPW + WDTHOLD; | |
// ************ Declarations ************ | |
const u8 skey[16] = { | |
0xffU,0xeeU,0xddU,0xccU,0xbbU,0xaaU,0x99U,0x88U, | |
0x77U,0x66U,0x55U,0x44U,0x33U,0x22U,0x11U,0x00U | |
}; | |
const u8 ctext[16] = { | |
0x00U,0x01U,0x02U,0x03U,0x04U,0x05U,0x06U,0x07U, | |
0x08U,0x09U,0x0aU,0x0bU,0x0cU,0x0dU,0x0eU,0x0fU | |
}; | |
u8 rk[8 * 26 + 16]; /* 8 bytes x 26 rounds(max) + whitening keys */ | |
uint16_t ptext[8]={0}; | |
START_DECRYPT(); | |
ClefiaKeySet128(rk, skey); | |
ClefiaDecrypt(ptext, ctext, rk, 18); | |
END_EXPE(); | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
// Implementation of LEA Block Cipher on 8-bit AVR Processors (Balanced Optimization) // | |
// Copyright (C) 2015 KISA <http://www.kisa.or.kr> // | |
////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
#include <stdlib.h> | |
#include <msp430.h> | |
#include <stdint.h> | |
#include "tools.h" | |
typedef uint32_t DWORD; | |
typedef uint8_t BYTE; | |
#define ROR(W,i) (((W)>>(i)) | ((W)<<(32-(i)))) | |
#define ROL(W,i) (((W)<<(i)) | ((W)>>(32-(i)))) | |
#define DWORD_in(x) (*(DWORD*)(x)) | |
#define DWORD_out(x, v) {*((DWORD*)(x)) = (v);} | |
static inline uint32_t rot32l1(uint32_t x) { | |
return (x << 1) | (x >> 31); | |
} | |
static inline uint32_t rot32r1(uint32_t x) { | |
return (x >> 1) | (x << 31); | |
} | |
static inline uint32_t rot32l8(uint32_t x) { | |
return (x << 8) | (x >> 24); | |
} | |
static inline uint32_t rot32r8(uint32_t x) { | |
return (x >> 8) | (x << 24); | |
} | |
static inline uint32_t rot32l3(uint32_t x) { | |
return rot32l1(rot32l1(rot32l1(x))); | |
} | |
static inline uint32_t rot32r3(uint32_t x) { | |
return rot32r1(rot32r1(rot32r1(x))); | |
} | |
static inline uint32_t rot32l5(uint32_t x) { | |
return rot32r3(rot32l8(x)); | |
} | |
static inline uint32_t rot32l9(uint32_t x) { | |
return rot32l1(rot32l8(x)); | |
} | |
static inline uint32_t rot32r5(uint32_t x) { | |
return rot32l3(rot32r8(x)); | |
} | |
static inline uint32_t rot32r9(uint32_t x) { | |
return rot32r1(rot32r8(x)); | |
} | |
static inline uint32_t rot32l2(uint32_t x) { | |
return rot32l1(rot32l1(x)); | |
} | |
static inline uint32_t rot32l4(uint32_t x) { | |
return rot32l2(rot32l2(x)); | |
} | |
static inline uint32_t rot32l6(uint32_t x) { | |
return rot32r1(rot32r1(rot32l8(x))); | |
} | |
static inline uint32_t rot32l11(uint32_t x) { | |
return rot32l3(rot32l8(x)); | |
} | |
const static uint32_t DELTA[4] = {0xc3efe9db, 0x88c4d604, 0xe789f229, 0xc6f98763}; | |
void LEA_Key(const uint8_t* userkey, uint8_t* roundkey){ | |
uint32_t* rk = (uint32_t*) roundkey; | |
uint32_t* t = (uint32_t*) userkey; | |
uint32_t delta[4] = {DELTA[0], DELTA[1], DELTA[2], DELTA[3]}; | |
uint32_t tmp; | |
int ridx = 0; | |
int i; | |
uint32_t t0 = t[0]; | |
uint32_t t1 = t[1]; | |
uint32_t t2 = t[2]; | |
uint32_t t3 = t[3]; | |
for (i = 0; i < 24; ++i) { | |
tmp = delta[i & 3]; | |
t0 = rot32l1(t0 + tmp); | |
t1 = rot32l3(t1 + rot32l1(tmp)); | |
t2 = rot32l6(t2 + rot32l2(tmp)); | |
t3 = rot32l11(t3 + rot32l3(tmp)); | |
delta[i & 3] = rot32l4(tmp); | |
rk[ridx++] = t1; | |
rk[ridx++] = t3; | |
rk[ridx++] = t2; | |
rk[ridx++] = t0; | |
} | |
} | |
void LEA_Enc(const uint8_t* roundkey, uint8_t* data) { | |
uint32_t* block = (uint32_t*) data; | |
const uint32_t* rk = (const uint32_t*) roundkey; | |
uint8_t i; | |
uint32_t b0 = block[0]; | |
uint32_t b1 = block[1]; | |
uint32_t b2 = block[2]; | |
uint32_t b3 = block[3]; | |
for (i = 0; i < 6; ++i) { | |
b3 = rot32r3(((b2 ^ rk[1]) + (b3 ^ rk[0]))); | |
b2 = rot32r5(((b1 ^ rk[2]) + (b2 ^ rk[0]))); | |
b1 = rot32l9(((b0 ^ rk[3]) + (b1 ^ rk[0]))); | |
rk += 4; | |
b0 = rot32r3(((b3 ^ rk[1]) + (b0 ^ rk[0]))); | |
b3 = rot32r5(((b2 ^ rk[2]) + (b3 ^ rk[0]))); | |
b2 = rot32l9(((b1 ^ rk[3]) + (b2 ^ rk[0]))); | |
rk += 4; | |
b3 = rot32r3(((b0 ^ rk[1]) + (b1 ^ rk[0]))); | |
b2 = rot32r5(((b3 ^ rk[2]) + (b0 ^ rk[0]))); | |
b1 = rot32l9(((b2 ^ rk[3]) + (b3 ^ rk[0]))); | |
rk += 4; | |
b3 = rot32r3(((b1 ^ rk[1]) + (b2 ^ rk[0]))); | |
b2 = rot32r5(((b0 ^ rk[2]) + (b1 ^ rk[0]))); | |
b1 = rot32l9(((b3 ^ rk[3]) + (b0 ^ rk[0]))); | |
rk += 4; | |
} | |
block[0] = b0; | |
block[1] = b1; | |
block[2] = b2; | |
block[3] = b3; | |
} | |
void LEA_Dec(const uint8_t* roundkey, uint8_t* data) | |
{ | |
uint32_t* block = (uint32_t*) data; | |
const uint32_t* rk = (const uint32_t*) roundkey; | |
uint8_t i; | |
uint32_t b0 = block[0]; | |
uint32_t b1 = block[1]; | |
uint32_t b2 = block[2]; | |
uint32_t b3 = block[3]; | |
rk += 92; | |
for (i = 0; i < 6; ++i) { | |
b0 = (rot32r9(b0) - (b3 ^ rk[3])) ^ rk[0]; | |
b1 = (rot32l5(b1) - (b0 ^ rk[2])) ^ rk[0]; | |
b2 = (rot32l3(b2) - (b1 ^ rk[1])) ^ rk[0]; | |
rk -= 4; | |
b3 = (rot32r9(b3) - (b2 ^ rk[3])) ^ rk[0]; | |
b0 = (rot32l5(b0) - (b3 ^ rk[2])) ^ rk[0]; | |
b1 = (rot32l3(b1) - (b0 ^ rk[1])) ^ rk[0]; | |
rk -= 4; | |
b2 = (rot32r9(b2) - (b1 ^ rk[3])) ^ rk[0]; | |
b3 = (rot32l5(b3) - (b2 ^ rk[2])) ^ rk[0]; | |
b0 = (rot32l3(b0) - (b3 ^ rk[1])) ^ rk[0]; | |
rk -= 4; | |
b1 = (rot32r9(b1) - (b0 ^ rk[3])) ^ rk[0]; | |
b2 = (rot32l5(b2) - (b1 ^ rk[2])) ^ rk[0]; | |
b3 = (rot32l3(b3) - (b2 ^ rk[1])) ^ rk[0]; | |
rk -= 4; | |
} | |
block[0] = b0; | |
block[1] = b1; | |
block[2] = b2; | |
block[3] = b3; | |
} | |
int main(int argc, char* argv[]) | |
{ | |
// Stop WatchDog during initialization | |
WDTCTL = WDTPW + WDTHOLD; | |
// ************ Declarations ************ | |
uint16_t text[8]={0xeeff, 0xccdd, 0xaabb, 0x8899, 0x6677, 0x4455, 0x4455, 0x0011}; | |
uint16_t ptext[8]={0}; | |
uint16_t k128[8] = {0x0011, 0x4455, 0x4455, 0x6677, 0x8899, 0xaabb, 0xccdd, 0xeeff}; | |
uint8_t roundKey[384] = {0}; | |
START_DECRYPT(); | |
LEA_Key((uint8_t *)k128, roundKey); | |
LEA_Dec(roundKey, (uint8_t)ptext); | |
END_EXPE(); | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// prince.c | |
// PRINCE-128 | |
// | |
// Created by Dare, Christopher E. (Assoc) on 6/1/16. | |
// Copyright © 2016 Dare, Christopher E. (Assoc). All rights reserved. | |
// | |
/*****************************************************************************/ | |
/* Private variables: */ | |
/*****************************************************************************/ | |
#include <msp430.h> | |
#include <stdint.h> | |
// State in the form {10,32,54,76,98,ba,dc,fe} for bit ordering in array | |
static uint8_t* State; | |
static const uint8_t RoundConstant[96] = { | |
/*i=0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
/*i=1*/ 0x31, 0x91, 0xa8, 0xe2, 0x30, 0x07, 0x37, 0x44, | |
/*i=2*/ 0x4a, 0x90, 0x83, 0x22, 0x92, 0xf9, 0x13, 0x0d, | |
/*i=3*/ 0x80, 0xe2, 0xaf, 0x89, 0xce, 0xe4, 0xc6, 0x98, | |
/*i=4*/ 0x54, 0x82, 0x12, 0x6e, 0x83, 0x0d, 0x31, 0x77, | |
/*i=5*/ 0xeb, 0x45, 0x66, 0xfc, 0x43, 0x9e, 0xc0, 0xc6, | |
/*i=6*/ 0xe7, 0x8f, 0xf4, 0x87, 0xdf, 0x59, 0xc5, 0x1b, | |
/*i=7*/ 0x58, 0x48, 0x80, 0x15, 0x1f, 0xca, 0x34, 0xaa, | |
/*i=8*/ 0x8c, 0x28, 0x3d, 0xf2, 0x52, 0x23, 0xc3, 0x45, | |
/*i=9*/ 0x46, 0x5a, 0x11, 0x59, 0x0e, 0x3e, 0x16, 0xd0, | |
/*i=10*/ 0x3d, 0x5b, 0x3a, 0x99, 0xac, 0xc0, 0x32, 0x99, | |
/*i=11*/ 0x0c, 0xca, 0x92, 0x7b, 0x9c, 0xc7, 0x05, 0xdd | |
}; | |
static const uint8_t SBox[16] = { | |
//0 1 2 3 4 5 6 7 8 9 A B C D E F | |
0x0B, 0x0F, 0x03, 0x02, 0x0A, 0x0C, 0x09, 0x01, 0x06, 0x07, 0x08, 0x00, 0x0E, 0x05, 0x0D, 0x04 | |
}; | |
static const uint8_t InvSBox[16] = { | |
//0 1 2 3 4 5 6 7 8 9 A B C D E F | |
0x0B, 0x07, 0x03, 0x02, 0x0F, 0x0D, 0x08, 0x09, 0x0A, 0x06, 0x04, 0x00, 0x05, 0x0E, 0x0C, 0x01 | |
}; | |
/*****************************************************************************/ | |
/* Function Declarations: */ | |
/*****************************************************************************/ | |
static void MPrimeLayer(); | |
static void MLayer(); | |
static void ShiftRow(); | |
static void InvShiftRow(); | |
static void InvMLayer(); | |
static void addRoundKey(uint8_t* Key); | |
static void addRoundConstant(uint8_t round); | |
static void sBoxLayer(); | |
static void InvSBoxLayer(); | |
/*****************************************************************************/ | |
/* Private functions: */ | |
/*****************************************************************************/ | |
/* The last 64 bits of the round key are added to the state */ | |
static void addRoundKey(uint8_t* Key) | |
{ | |
State[0] ^= Key[8]; | |
State[1] ^= Key[9]; | |
State[2] ^= Key[10]; | |
State[3] ^= Key[11]; | |
State[4] ^= Key[12]; | |
State[5] ^= Key[13]; | |
State[6] ^= Key[14]; | |
State[7] ^= Key[15]; | |
} // End addRoundKey() | |
/* Each nibble of the 64-bit state goes through a non-linear S-Box. | |
In our algorithm we use a mask and bit shift to isolate each nibble | |
separately. | |
*/ | |
static void sBoxLayer() | |
{ | |
uint8_t lownib, highnib, i; | |
for (i = 0; i < 8; i++) | |
{ | |
lownib = State[i] & 0x0F; | |
highnib = State[i] >> 4; | |
lownib = SBox[lownib]; | |
highnib = SBox[highnib]; | |
highnib <<= 4; | |
State[i] = lownib + highnib; | |
} // End for-loop() | |
} // End sBoxLayer() | |
/* In the M and M0-layer the 64-bit state is multiplied with a 64 × 64 matrix M | |
(resp. M0) defined below. We have different requirements for the two different | |
linear layers. The M0-layer is only used in the middle round, thus M0 has to | |
be an involution to ensure the α-reflection property. Each output bit | |
of an Sbox has to influence 3 Sboxes in the next round and therefore the minimum | |
number of ones per row and column is 3 | |
In our algorithm we use a variance of bitwise shifts and masks in order to mimic | |
the bitwise matrix multiplication operation on the state. Since the even indexed | |
elements of the state are changed before the odd, yet the odd relies on the even, | |
we save the even indexed elements of the state in Read Only Memory. | |
*/ | |
static void MPrimeLayer() | |
{ | |
// temporary storage variables stored in read only memory | |
uint8_t s0 = State[0]; | |
uint8_t s2 = State[2]; | |
uint8_t s4 = State[4]; | |
uint8_t s6 = State[6]; | |
//M0 | |
State[0] = (s0 & 0xD7) ^ (State[1] & 0x7D) ^ (s0 >> 4 & 0x0B) ^ (State[1] >> 4 & 0x0E) ^ (s0 << 4 & 0xB0) ^ (State[1] << 4 & 0xE0); | |
State[1] = (s0 & 0x7D) ^ (State[1] & 0xD7) ^ (s0 >> 4 & 0x0E) ^ (State[1] >> 4 & 0x0B) ^ (s0 << 4 & 0xE0) ^ (State[1] << 4 & 0xB0); | |
//M1 | |
State[2] = (s2 & 0xEB) ^ (State[3] & 0xBE) ^ (s2 >> 4 & 0x0D) ^ (State[3] >> 4 & 0x07) ^ (s2 << 4 & 0xD0) ^ (State[3] << 4 & 0x70); | |
State[3] = (s2 & 0xBE) ^ (State[3] & 0xEB) ^ (s2 >> 4 & 0x07) ^ (State[3] >> 4 & 0x0D) ^ (s2 << 4 & 0x70) ^ (State[3] << 4 & 0xD0); | |
//M1 | |
State[4] = (s4 & 0xEB) ^ (State[5] & 0xBE) ^ (s4 >> 4 & 0x0D) ^ (State[5] >> 4 & 0x07) ^ (s4 << 4 & 0xD0) ^ (State[5] << 4 & 0x70); | |
State[5] = (s4 & 0xBE) ^ (State[5] & 0xEB) ^ (s4 >> 4 & 0x07) ^ (State[5] >> 4 & 0x0D) ^ (s4 << 4 & 0x70) ^ (State[5] << 4 & 0xD0); | |
//M0 | |
State[6] = (s6 & 0xD7) ^ (State[7] & 0x7D) ^ (s6 >> 4 & 0x0B) ^ (State[7] >> 4 & 0x0E) ^ (s6 << 4 & 0xB0) ^ (State[7] << 4 & 0xE0); | |
State[7] = (s6 & 0x7D) ^ (State[7] & 0xD7) ^ (s6 >> 4 & 0x0E) ^ (State[7] >> 4 & 0x0B) ^ (s6 << 4 & 0xE0) ^ (State[7] << 4 & 0xB0); | |
} // End MPrimeLayer() | |
/* The MLayer is simply the M-Prime layer with a Row Shift operation | |
to shift each nibble. For this reason, the MLayer no longer has the | |
α-reflection property mentioned above in the MPrimeLayer. Due to the α-reflection property, | |
the MPrimeLayer is its own inverse (since addition and subtraction are identical in the Galois | |
Field, matrix multiplication must be invertible as well); however, the SR prevents the | |
MLayer from being its own inverse, such that we require an Inverse MLayer protocol as well. | |
*/ | |
static void MLayer() | |
{ | |
MPrimeLayer(); | |
ShiftRow(); | |
} // End MLayer | |
/* Our ShiftRow() operation performs similarly to the AES Shift Row | |
and permutes the 16 nibbles in the following way: | |
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 −→ 0 5 10 15 4 9 14 3 8 13 2 7 12 1 6 11 | |
*/ | |
static void ShiftRow() | |
{ | |
uint8_t temp[8]; | |
uint8_t i = 0; | |
temp[0] = (State[0] & 0x0F) | (State[2] & 0xF0); | |
temp[1] = (State[5] & 0x0F) | (State[7] & 0xF0); | |
temp[2] = (State[2] & 0x0F) | (State[4] & 0xF0); | |
temp[3] = (State[7] & 0x0F) | (State[1] & 0xF0); | |
temp[4] = (State[4] & 0x0F) | (State[6] & 0xF0); | |
temp[5] = (State[1] & 0x0F) | (State[3] & 0xF0); | |
temp[6] = (State[6] & 0x0F) | (State[0] & 0xF0); | |
temp[7] = (State[3] & 0x0F) | (State[5] & 0xF0); | |
for (; i < 8; i++) { | |
State[i] = temp[i]; | |
} // End for-loop | |
} // End ShiftRow() | |
/* In the RCi-add step a 64-bit round constant is xored with the state. | |
We define the constants used below (in hex notation): | |
RC0 | 0000000000000000 | |
RC1 | 13198a2e03707344 | |
RC2 | a4093822299f31d0 | |
RC3 | 082efa98ec4e6c89 | |
RC4 | 452821e638d01377 | |
RC5 | be5466cf34e90c6c | |
RC6 | 7ef84f78fd955cb1 | |
RC7 | 85840851f1ac43aa | |
RC8 | c882d32f25323c54 | |
RC9 | 64a51195e0e3610d | |
RC10| d3b5a399ca0c2399 | |
RC11| c0ac29b7c97c50dd | |
Note that, for all 0 ≤ i ≤ 11, RCi⊕RC11−i | |
is the constant α = c0ac29b7c97c50dd, | |
RC0 = 0 and that RC1, . . . , RC5 and α are derived from the fraction part of | |
π = 3.141.... | |
In our algorithm we treat each round constant as a byte array of length 8, | |
stored in little endian order such that we can add the round constant to the | |
state simply by state[i] += RoundConstant[8 * round + i]; | |
*/ | |
static void addRoundConstant(uint8_t round) | |
{ | |
State[0] ^= RoundConstant[8 * round]; | |
State[1] ^= RoundConstant[8 * round + 1]; | |
State[2] ^= RoundConstant[8 * round + 2]; | |
State[3] ^= RoundConstant[8 * round + 3]; | |
State[4] ^= RoundConstant[8 * round + 4]; | |
State[5] ^= RoundConstant[8 * round + 5]; | |
State[6] ^= RoundConstant[8 * round + 6]; | |
State[7] ^= RoundConstant[8 * round + 7]; | |
} // End addRoundConstant() | |
/* As noted above, the MBox in each MLayer prevents MLayer from being its own inverse. | |
The MLayer is defined as M = SR ◦ M'. Because ◦ (function composition) composes the group | |
operation on the set of all functions from GF(2) to GF(2), M must have an inverse, defined by | |
M^-1 = M'^-1 ◦ SR^-1 = M' ◦ SR^-1 . Thus, we first take the inverse MBox and call MPrimeLayer | |
(as it is its own inverse). | |
*/ | |
static void InvMLayer() | |
{ | |
InvShiftRow(); | |
MPrimeLayer(); | |
} // End InvMLayer() | |
/* We invert the SBox and apply the transformation to each nibble in the state | |
such that SBox[InvSBox[x]] = x and InvSBox[SBox[x]] = x for all x in GF(2) | |
*/ | |
static void InvSBoxLayer() | |
{ | |
uint8_t lownib, highnib, i; | |
for (i = 0; i < 8; i++) | |
{ | |
lownib = State[i] & 0x0F; | |
highnib = State[i] >> 4; | |
lownib = InvSBox[lownib]; | |
highnib = InvSBox[highnib]; | |
highnib <<= 4; | |
State[i] = lownib + highnib; | |
} // End for-loop | |
} // End InvSBoxLayer() | |
static void InvShiftRow() | |
{ | |
uint8_t temp[8]; | |
uint8_t i = 0; | |
temp[0] = (State[0] & 0x0F) | (State[6] & 0xF0); | |
temp[1] = (State[5] & 0x0F) | (State[3] & 0xF0); | |
temp[2] = (State[2] & 0x0F) | (State[0] & 0xF0); | |
temp[3] = (State[7] & 0x0F) | (State[5] & 0xF0); | |
temp[4] = (State[4] & 0x0F) | (State[2] & 0xF0); | |
temp[5] = (State[1] & 0x0F) | (State[7] & 0xF0); | |
temp[6] = (State[6] & 0x0F) | (State[4] & 0xF0); | |
temp[7] = (State[3] & 0x0F) | (State[1] & 0xF0); | |
for (; i < 8; i++) { | |
State[i] = temp[i]; | |
} | |
} | |
/* In our cipher, we use the first 64 bits of the key as for whitening before proceeding | |
to PRINCE_core. In prince_core, the state undergoes 5 rounds of an Sbox Layer followed | |
by an MLayer, followed by adding the Round Constant and last 64 bits of the key, | |
respectively. In the middle of the cipher, the SBox is applied, followed by the symmetric | |
MPrimeLayer, and an Inverse SBox. For the consequent 5 rounds, the inverse of the first 5 rounds | |
is applied. Lastly, the subkey is used for whitening after PRINCE_core has completed. | |
From the fact that the round constants satisfy RCi ⊕ RC11−i = α and that M' | |
is an involution, we deduce that the core cipher is such that the inverse | |
of PRINCE_core parametrized with k is equal to PRINCE_core parametrized with | |
(k⊕α). We call this property of PRINCE_core the α-reflection property. It follows | |
that, for any expanded key (k0||k'0||k1), | |
D(k0||k'0||k1)(·) = E(k'0||k0||k1⊕α)(·) | |
*/ | |
void cipher(uint8_t* state, uint8_t* Key, uint8_t* subkey) | |
{ | |
State = state; | |
uint8_t i; | |
for (i = 0; i < 8; i++) { | |
State[i] ^= Key[i]; | |
} // End for-loop | |
addRoundKey(Key); | |
addRoundConstant(0); | |
for (i = 1; i <= 5; i++) | |
{ | |
sBoxLayer(); | |
MLayer(); | |
addRoundConstant(i); | |
addRoundKey(Key); | |
} // End for-loop | |
sBoxLayer(); | |
MPrimeLayer(); | |
InvSBoxLayer(); | |
for (i = 6; i <= 10; i++) | |
{ | |
addRoundKey(Key); | |
addRoundConstant(i); | |
InvMLayer(); | |
InvSBoxLayer(); | |
} // End for-loop | |
addRoundConstant(11); | |
addRoundKey(Key); | |
for (i = 0; i < 8; i++) { | |
State[i] ^= subkey[i]; | |
} // End for-loop | |
} // End cipher() | |
/* | |
From the fact that the round constants satisfy RCi ⊕ RC11−i = α and that M' | |
is an involution, we deduce that the core cipher is such that the inverse | |
of PRINCE_core parametrized with k is equal to PRINCE_core parametrized with | |
(k⊕α). We call this property of PRINCE_core the α-reflection property. It follows | |
that, for any expanded key (k0||k'0||k1), | |
D(k0||k'0||k1)(·) = E(k'0||k0||k1⊕α)(·) | |
*/ | |
void decipher(uint8_t* state, uint8_t* Key, uint8_t* subkey) | |
{ | |
uint8_t temp[8]; | |
uint8_t i = 0; | |
for (; i < 8; i++) | |
{ | |
temp[i] = subkey[i]; | |
} // End for-loop | |
for (i = 0; i < 8; i++) | |
{ | |
subkey[i] = Key[i]; | |
} // End for-loop | |
for (i = 0; i < 8; i++) | |
{ | |
Key[i] = temp[i]; | |
} // End for-loop | |
Key[8] ^= 0x0c; | |
Key[9] ^= 0xca; | |
Key[10] ^= 0x92; | |
Key[11] ^= 0x7b; | |
Key[12] ^= 0x9c; | |
Key[13] ^= 0xc7; | |
Key[14] ^= 0x05; | |
Key[15] ^= 0xdd; | |
cipher(state, Key, subkey); | |
Key[8] ^= 0x0c; | |
Key[9] ^= 0xca; | |
Key[10] ^= 0x92; | |
Key[11] ^= 0x7b; | |
Key[12] ^= 0x9c; | |
Key[13] ^= 0xc7; | |
Key[14] ^= 0x05; | |
Key[15] ^= 0xdd; | |
} // End decipher | |
/* The 128-bit key (k0||k1) is extended to a 192-bit key (k0||k'0||k1) by a linear | |
mapping of the form | |
(k0||k1) -→ (k0||P(k0)||k1). | |
Thus, a hardware-optimal choice for P such that both P and P ⊕ Id are | |
permutations is | |
P(x) = (x ≫> 1) ⊕ (x ≫ 63) , | |
i.e., P(x63, . . . , x0) = (x0, x63, . . . , x2, x1 ⊕ x63). | |
In our algorithm we perform a simple bitwise shift on the first 64-bits of the | |
key in order to produce our subkey, k'0 or P(k0) as denoted above. The subkey does | |
not change by round, as in other algorithms. | |
*/ | |
void keySchedule(uint8_t* Key, uint8_t* subkey) | |
{ | |
subkey[0] = (Key[0] >> 1) | (Key[1] << 7); | |
subkey[1] = (Key[1] >> 1) | (Key[2] << 7); | |
subkey[2] = (Key[2] >> 1) | (Key[3] << 7); | |
subkey[3] = (Key[3] >> 1) | (Key[4] << 7); | |
subkey[4] = (Key[4] >> 1) | (Key[5] << 7); | |
subkey[5] = (Key[5] >> 1) | (Key[6] << 7); | |
subkey[6] = (Key[6] >> 1) | (Key[7] << 7); | |
subkey[7] = (Key[7] >> 1) | (Key[0] << 7); | |
subkey[7] ^= (Key[7] & 0x10); | |
} // End keySchedule() | |
int main() | |
{ | |
// Stop WatchDog during initialization | |
WDTCTL = WDTPW + WDTHOLD; | |
uint8_t state[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; | |
uint32_t key[] = {0x17485418, 0x42465615, 0x90872153, 0x99887765}; | |
uint8_t ptext[] = {0x18, 0x68, 0x56, 0xaa, 0xd0, 0x20, 0xfd, 0xad}; | |
uint8_t subkey[8]; | |
keySchedule((uint8_t *)key, subkey); | |
decipher(state, (uint8_t *)key, subkey); | |
return 0; | |
} // End main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment