Annotation of OpenXM/src/ox_ntl/crypt/camellia/camellia.c, Revision 1.1
1.1 ! iwane 1: /* $OpenXM$ */
! 2: /*
! 3: * Camellia
! 4: * http://info.isl.ntt.co.jp/crypt/camellia/index.html
! 5: */
! 6:
! 7: #include "camellia.h"
! 8:
! 9:
! 10: #if HAVE_CONFIG_H
! 11: #include "config.h"
! 12: #endif /* HAVE_CONFIG_H */
! 13:
! 14:
! 15: #define leftrot32(x, n) ((((uint32_t)x) << n) | ((uint32_t)x) >> (32 - n))
! 16:
! 17:
! 18: #define DPRINTF(str, x, n) /* DPRINTF__(str, (x), (n)) */
! 19: #define DPRINTF__(str, x, n) { \
! 20: int _i; \
! 21: printf("%s: ", str); \
! 22: for (_i = 0; _i < n; _i++) { \
! 23: printf("%02x", ARY(x, _i) & 0xff); \
! 24: if (_i % 8 == 7) \
! 25: printf(" "); \
! 26: } \
! 27: printf("\n"); \
! 28: fflush(stdout); \
! 29: }
! 30:
! 31: #ifdef WORDS_BIGENDIAN
! 32: #define ARY(x, i) (((uint8_t *)(x))[i])
! 33: #else
! 34: #define ARY(x, i) (((uint8_t *)(x))[(int)("\x03\x02\x01\x00\x07\x06\x05\x04\x0b\x0a\x09\x08\x0f\x0e\x0d\x0c\x13\x12\x11\x10\x17\x16\x15\x14\x1b\x1a\x19\x18\x1f\x1e\x1d\x1c"[i])])
! 35: #endif
! 36:
! 37:
! 38: static const uint32_t G_camellia_sigma[] = {
! 39: 0xa09e667f, 0x3bcc908b,
! 40: 0xb67ae858, 0x4caa73b2,
! 41: 0xc6ef372f, 0xe94f82be,
! 42: 0x54ff53a5, 0xf1d36f1c,
! 43: 0x10e527fa, 0xde682d1d,
! 44: 0xb05688c2, 0xb3e6c1fd,
! 45: };
! 46:
! 47: #define SIGMA(i) (G_camellia_sigma + (2 * ((i) - 1)))
! 48:
! 49:
! 50: static const uint8_t G_camellia_sbox[256] = {
! 51: 112,130, 44,236,179, 39,192,229,228,133, 87, 53,234, 12,174, 65,
! 52: 35,239,107,147, 69, 25,165, 33,237, 14, 79, 78, 29,101,146,189,
! 53: 134,184,175,143,124,235, 31,206, 62, 48,220, 95, 94,197, 11, 26,
! 54: 166,225, 57,202,213, 71, 93, 61,217, 1, 90,214, 81, 86,108, 77,
! 55: 139, 13,154,102,251,204,176, 45,116, 18, 43, 32,240,177,132,153,
! 56: 223, 76,203,194, 52,126,118, 5,109,183,169, 49,209, 23, 4,215,
! 57: 20, 88, 58, 97,222, 27, 17, 28, 50, 15,156, 22, 83, 24,242, 34,
! 58: 254, 68,207,178,195,181,122,145, 36, 8,232,168, 96,252,105, 80,
! 59: 170,208,160,125,161,137, 98,151, 84, 91, 30,149,224,255,100,210,
! 60: 16,196, 0, 72,163,247,117,219,138, 3,230,218, 9, 63,221,148,
! 61: 135, 92,131, 2,205, 74,144, 51,115,103,246,243,157,127,191,226,
! 62: 82,155,216, 38,200, 55,198, 59,129,150,111, 75, 19,190, 99, 46,
! 63: 233,121,167,140,159,110,188,142, 41,245,249,182, 47,253,180, 89,
! 64: 120,152, 6,106,231, 70,113,186,212, 37,171, 66,136,162,141,250,
! 65: 114, 7,185, 85,248,238,172, 10, 54, 73, 42,104, 60, 56,241,164,
! 66: 64, 40,211,123,187,201, 67,193, 21,227,173,244,119,199,128,158,
! 67: };
! 68:
! 69: #define SBOX1(n) G_camellia_sbox[n]
! 70: #define SBOX2(n) (uint8_t)((SBOX1(n) >> 7 ^ SBOX1(n) << 1) & 0xff)
! 71: #define SBOX3(n) (uint8_t)((SBOX1(n) >> 1 ^ SBOX1(n) << 7) & 0xff)
! 72: #define SBOX4(n) SBOX1(((n) << 1 ^ (n) >> 7) & 0xff)
! 73:
! 74:
! 75: #if 0
! 76: static void
! 77: camellia_binprt(const uint32_t *t, int n)
! 78: {
! 79: int i;
! 80: int q, r;
! 81: for (i = 0; i < n; i++) {
! 82: q = i / 32;
! 83: r = i % 32;
! 84:
! 85: printf("%d", (t[q] >> r) & 1);
! 86: if (i % 32 == 31)
! 87: printf(" ");
! 88: }
! 89: printf("\n");
! 90: }
! 91: #endif
! 92:
! 93: /**
! 94: * return (a ^ b)
! 95: * a - 128 bit
! 96: * b - 128 bit
! 97: */
! 98: static void
! 99: camellia_xor128(uint32_t *t, const uint32_t *a, const uint32_t *b)
! 100: {
! 101: int i;
! 102: for (i = 0; i < 4; i++) {
! 103: t[i] = a[i] ^ b[i];
! 104: }
! 105: }
! 106: static void
! 107: camellia_xor64(uint32_t *t, const uint32_t *a, const uint32_t *b)
! 108: {
! 109: int i;
! 110: for (i = 0; i < 2; i++) {
! 111: t[i] = a[i] ^ b[i];
! 112: }
! 113: }
! 114:
! 115: static void
! 116: camellia_rot128(uint32_t *t, const uint32_t *a, int n)
! 117: {
! 118: const int N = 128 / 32;
! 119: int i;
! 120: int r = n % 32;
! 121: int r2 = 32 - r;
! 122: int q = (n / 32) % N;
! 123:
! 124: if (r) {
! 125: for (i = 0; i < N; i++) {
! 126: t[i] = (a[(i + q) % N] << r) | (a[(i + q + N + 1) % N] >> r2);
! 127: }
! 128: } else {
! 129: for (i = 0; i < N; i++) {
! 130: t[i] = a[(i + q) % N];
! 131: }
! 132: }
! 133: }
! 134:
! 135:
! 136:
! 137:
! 138: /**
! 139: * return s(l)
! 140: * t - 64 bit
! 141: * l - 64 bit
! 142: */
! 143: static inline void
! 144: camellia_s(uint32_t *t, const uint32_t *l)
! 145: {
! 146: ARY(t, 0) = SBOX1(ARY(l, 0));
! 147: ARY(t, 1) = SBOX2(ARY(l, 1));
! 148: ARY(t, 2) = SBOX3(ARY(l, 2));
! 149: ARY(t, 3) = SBOX4(ARY(l, 3));
! 150: ARY(t, 4) = SBOX2(ARY(l, 4));
! 151: ARY(t, 5) = SBOX3(ARY(l, 5));
! 152: ARY(t, 6) = SBOX4(ARY(l, 6));
! 153: ARY(t, 7) = SBOX1(ARY(l, 7));
! 154: }
! 155:
! 156:
! 157: /**
! 158: * return p(l)
! 159: * t - 64 bit
! 160: * l - 64 bit
! 161: */
! 162: static inline void
! 163: camellia_p(uint32_t *t, const uint32_t *l)
! 164: {
! 165: #define L(i) (ARY(l, (i) - 1))
! 166: ARY(t, 0) = L(1) ^ L(3) ^ L(4) ^ L(6) ^ L(7) ^ L(8);
! 167: ARY(t, 1) = L(1) ^ L(2) ^ L(4) ^ L(5) ^ L(7) ^ L(8);
! 168: ARY(t, 2) = L(1) ^ L(2) ^ L(3) ^ L(5) ^ L(6) ^ L(8);
! 169: ARY(t, 3) = L(2) ^ L(3) ^ L(4) ^ L(5) ^ L(6) ^ L(7);
! 170: ARY(t, 4) = L(1) ^ L(2) ^ L(6) ^ L(7) ^ L(8);
! 171: ARY(t, 5) = L(2) ^ L(3) ^ L(5) ^ L(7) ^ L(8);
! 172: ARY(t, 6) = L(3) ^ L(4) ^ L(5) ^ L(6) ^ L(8);
! 173: ARY(t, 7) = L(1) ^ L(4) ^ L(5) ^ L(6) ^ L(7);
! 174: #undef L
! 175: }
! 176:
! 177:
! 178: /**
! 179: * return p(s(x^k))
! 180: * t - 64 bit
! 181: * l - 64 bit
! 182: */
! 183: static inline void
! 184: camellia_f(uint32_t *y, const uint32_t *x, const uint32_t *k)
! 185: {
! 186: uint32_t xor[4];
! 187: uint32_t s[4];
! 188:
! 189: camellia_xor64(xor, x, k);
! 190: camellia_s(s, xor);
! 191: camellia_p(y, s);
! 192: }
! 193:
! 194:
! 195: /**
! 196: * kl : 64 bit
! 197: * kr : 64 bit
! 198: * smg: 64 bit
! 199: */
! 200: static inline void
! 201: camellia_feistel(uint32_t *w, const uint32_t *kl, const uint32_t *kr, const uint32_t *sgm)
! 202: {
! 203: camellia_f(w, kl, sgm);
! 204: camellia_xor64(w, w, kr);
! 205: }
! 206:
! 207: static inline void
! 208: camellia_fl(uint32_t *y, const uint32_t *x, const uint32_t *k)
! 209: {
! 210: uint32_t t;
! 211:
! 212: t = x[0] & k[0];
! 213: y[1] = leftrot32(t, 1) ^ x[1];
! 214: y[0] = (y[1] | k[1]) ^ x[0];
! 215: }
! 216:
! 217: static inline void
! 218: camellia_fl_(uint32_t *x, const uint32_t *y, const uint32_t *k)
! 219: {
! 220: uint32_t t;
! 221:
! 222: x[0] = (y[1] | k[1]) ^ y[0];
! 223: t = x[0] & k[0];
! 224: x[1] = leftrot32(t, 1) ^ y[1];
! 225: }
! 226:
! 227:
! 228:
! 229: /*
! 230: * len = 16 or 24 or 32
! 231: * bit = 128 or 192 or 256
! 232: */
! 233: int
! 234: camellia_keyset(const unsigned char *key, int len, camellia_key *ckey)
! 235: {
! 236: int i;
! 237: const uint32_t *kr, *kl, *kb;
! 238: uint32_t ka[4];
! 239: uint32_t t[4]; /* 128 bit */
! 240: uint32_t w[4]; /* 128 bit */
! 241: uint32_t v[4]; /* 128 bit */
! 242:
! 243: #define Kl(i) (ARY(ckey->key, i))
! 244: #define Kr(i) (ARY(ckey->key, (i + 16)))
! 245: #define T(i) (ARY(t, i))
! 246:
! 247: if (len == 16) {
! 248: for (i = 0; i < 16; i++) {
! 249: Kl(i) = key[i];
! 250: Kr(i) = 0x00;
! 251: }
! 252: } else if (len == 24) {
! 253: for (i = 0; i < 16; i++) {
! 254: Kl(i) = key[i];
! 255: }
! 256: for (; i < 24; i++) {
! 257: Kr(i - 16) = key[i];
! 258: Kr(i - 8) = ~key[i];
! 259: }
! 260: } else if (len == 32) {
! 261: for (i = 0; i < 16; i++) {
! 262: Kl(i) = key[i];
! 263: Kr(i) = key[i + 16];
! 264: }
! 265: } else {
! 266: return (-1);
! 267: }
! 268:
! 269: kl = ckey->key;
! 270: kr = ckey->key + 4;
! 271:
! 272: ckey->len = len;
! 273:
! 274: camellia_xor128(t, kl, kr);
! 275:
! 276:
! 277: camellia_feistel(w + 2, t, t + 2, SIGMA(1));
! 278: camellia_feistel(w, w + 2, t, SIGMA(2));
! 279:
! 280: camellia_xor128(v, w, kl);
! 281:
! 282: camellia_feistel(w + 2, v, v + 2, SIGMA(3));
! 283: camellia_feistel(w, w + 2, v, SIGMA(4));
! 284:
! 285: if (len == 16) {
! 286: /*
! 287: * KA = w
! 288: * KL = key
! 289: */
! 290: camellia_rot128(ckey->kw, ckey->key, 0);
! 291: camellia_rot128(ckey->kw + 4, w, 111);
! 292:
! 293: camellia_rot128(ckey->kl, w, 30);
! 294: camellia_rot128(ckey->kl + 4, ckey->key, 77);
! 295:
! 296: camellia_rot128(ckey->k + 0, w, 0);
! 297: camellia_rot128(ckey->k + 4, ckey->key, 15);
! 298: camellia_rot128(ckey->k + 8, w, 15);
! 299: camellia_rot128(ckey->k + 12, ckey->key, 45);
! 300: camellia_rot128(ckey->k + 16, w, 45);
! 301: camellia_rot128(ckey->k + 20, w, 60);
! 302: camellia_rot128(ckey->k + 24, ckey->key, 94);
! 303: camellia_rot128(ckey->k + 28, w, 94);
! 304: camellia_rot128(ckey->k + 32, ckey->key, 111);
! 305:
! 306: camellia_rot128(v, ckey->key, 60);
! 307: ckey->k[18] = v[2];
! 308: ckey->k[19] = v[3];
! 309:
! 310: return (0);
! 311: }
! 312:
! 313: memcpy(ka, w, sizeof(w));
! 314:
! 315: camellia_xor128(v, w, kr);
! 316:
! 317: camellia_feistel(w + 2, v, v + 2, SIGMA(5));
! 318: camellia_feistel(w + 0, w + 2, v, SIGMA(6));
! 319:
! 320: kb = w;
! 321:
! 322: camellia_rot128(ckey->kw + 0, kl, 0);
! 323: camellia_rot128(ckey->kw + 4, kb, 111);
! 324:
! 325: camellia_rot128(ckey->kl + 0, kr, 30);
! 326: camellia_rot128(ckey->kl + 4, kl, 60);
! 327: camellia_rot128(ckey->kl + 8, ka, 77);
! 328:
! 329: camellia_rot128(ckey->k + 0, kb, 0);
! 330: camellia_rot128(ckey->k + 4, kr, 15);
! 331: camellia_rot128(ckey->k + 8, ka, 15);
! 332: camellia_rot128(ckey->k + 12, kb, 30);
! 333: camellia_rot128(ckey->k + 16, kl, 45);
! 334: camellia_rot128(ckey->k + 20, ka, 45);
! 335:
! 336: camellia_rot128(ckey->k + 24, kr, 60);
! 337: camellia_rot128(ckey->k + 28, kb, 60);
! 338: camellia_rot128(ckey->k + 32, kl, 77);
! 339: camellia_rot128(ckey->k + 36, kr, 94);
! 340: camellia_rot128(ckey->k + 40, ka, 94);
! 341: camellia_rot128(ckey->k + 44, kl, 111);
! 342:
! 343:
! 344: return (0);
! 345: #undef X
! 346: }
! 347:
! 348:
! 349: /*
! 350: * m: message 128 bit
! 351: * e: encrypt 128 bit
! 352: */
! 353: void
! 354: camellia_enc(camellia_key *ckey, const uint8_t *msg, uint8_t *e)
! 355: {
! 356: uint32_t m[4];
! 357: uint32_t w[8] = {0, 0, 0, 0, 0, 0, 0, 0};
! 358: int i, j, k;
! 359: int loop;
! 360:
! 361:
! 362: if (ckey->len == 16) { /* 128 bit */
! 363: loop = 2;
! 364: } else { /* 192 or 256 bit */
! 365: loop = 3;
! 366: }
! 367:
! 368: for (i = 0; i < 16; i++) {
! 369: ARY(m, i) = msg[i];
! 370: }
! 371:
! 372: for (i = 0; i < 4; i++) {
! 373: w[(i + 2) % 4] = m[i] ^ ckey->kw[i];
! 374: }
! 375:
! 376: i = 0;
! 377: for (j = 0;; j++) {
! 378:
! 379: for (k = 0; k < 6; k++, i++) {
! 380: camellia_feistel(w + (4 + 2 * k) % 8, w + (2 + 2 * k) % 8, w + (0 + 2 * k) % 8, ckey->k + 2 * i);
! 381: }
! 382:
! 383: if (j == loop)
! 384: break;
! 385:
! 386: camellia_fl(w + 2, w + 6, ckey->kl + 4 * j);
! 387: camellia_fl_(w + 0, w + 4, ckey->kl + 4 * j + 2);
! 388:
! 389: }
! 390:
! 391:
! 392: camellia_xor128(w, w + 4, ckey->kw + 4);
! 393:
! 394: for (i = 0; i < 32; i++) {
! 395: e[i] = ARY(w, i);
! 396: }
! 397:
! 398: }
! 399:
! 400: /*
! 401: * e: encrypt 128 bit
! 402: * m: message 128 bit
! 403: */
! 404: void
! 405: camellia_dec(camellia_key *ckey, const uint8_t *enc, uint8_t *m)
! 406: {
! 407: uint32_t e[4];
! 408: uint32_t w[8] = {0, 0, 0, 0, 0, 0, 0, 0};
! 409: int i, j, k;
! 410: int loop;
! 411:
! 412: if (ckey->len == 16) { /* 128 bit */
! 413: loop = 2;
! 414: /*18*/
! 415: } else {
! 416: loop = 3;
! 417: /*24*/
! 418: }
! 419:
! 420: for (i = 0; i < 16; i++) {
! 421: ARY(e, i) = enc[i];
! 422: }
! 423:
! 424:
! 425: for (i = 0; i < 4; i++) {
! 426: w[(i + 2) % 4] = e[i] ^ ckey->kw[(i + 0) % 4 + 4];
! 427: }
! 428:
! 429:
! 430: i = (loop + 1) * 6 - 1;
! 431: for (j = loop - 1;; j--) {
! 432:
! 433: for (k = 0; k < 6; k++, i--) {
! 434: camellia_feistel(w + (4 + 2 * k) % 8, w + (2 + 2 * k) % 8, w + (0 + 2 * k) % 8, ckey->k + 2 * i);
! 435: }
! 436:
! 437: if (j < 0)
! 438: break;
! 439:
! 440:
! 441: camellia_fl(w + 2, w + 6, ckey->kl + 4 * j + 2);
! 442: camellia_fl_(w + 0, w + 4, ckey->kl + 4 * j + 0);
! 443:
! 444: }
! 445:
! 446:
! 447: camellia_xor128(w, w + 4, ckey->kw + 0);
! 448:
! 449: for (i = 0; i < 32; i++) {
! 450: m[i] = ARY(w, i);
! 451: }
! 452:
! 453: }
! 454:
! 455:
! 456:
! 457: /* End of File */
! 458:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>