?? saferp.c
字號:
/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org *//** @file saferp.c SAFER+ Implementation by Tom St Denis */#include "tomcrypt.h"#ifdef SAFERPconst struct ltc_cipher_descriptor saferp_desc ={ "safer+", 4, 16, 32, 16, 8, &saferp_setup, &saferp_ecb_encrypt, &saferp_ecb_decrypt, &saferp_test, &saferp_done, &saferp_keysize, NULL, NULL, NULL, NULL, NULL, NULL, NULL};/* ROUND(b,i) * * This is one forward key application. Note the basic form is * key addition, substitution, key addition. The safer_ebox and safer_lbox * are the exponentiation box and logarithm boxes respectively. * The value of 'i' is the current round number which allows this * function to be unrolled massively. Most of SAFER+'s speed * comes from not having to compute indirect accesses into the * array of 16 bytes b[0..15] which is the block of data*/extern const unsigned char safer_ebox[], safer_lbox[];#define ROUND(b, i) \ b[0] = (safer_ebox[(b[0] ^ skey->saferp.K[i][0]) & 255] + skey->saferp.K[i+1][0]) & 255; \ b[1] = safer_lbox[(b[1] + skey->saferp.K[i][1]) & 255] ^ skey->saferp.K[i+1][1]; \ b[2] = safer_lbox[(b[2] + skey->saferp.K[i][2]) & 255] ^ skey->saferp.K[i+1][2]; \ b[3] = (safer_ebox[(b[3] ^ skey->saferp.K[i][3]) & 255] + skey->saferp.K[i+1][3]) & 255; \ b[4] = (safer_ebox[(b[4] ^ skey->saferp.K[i][4]) & 255] + skey->saferp.K[i+1][4]) & 255; \ b[5] = safer_lbox[(b[5] + skey->saferp.K[i][5]) & 255] ^ skey->saferp.K[i+1][5]; \ b[6] = safer_lbox[(b[6] + skey->saferp.K[i][6]) & 255] ^ skey->saferp.K[i+1][6]; \ b[7] = (safer_ebox[(b[7] ^ skey->saferp.K[i][7]) & 255] + skey->saferp.K[i+1][7]) & 255; \ b[8] = (safer_ebox[(b[8] ^ skey->saferp.K[i][8]) & 255] + skey->saferp.K[i+1][8]) & 255; \ b[9] = safer_lbox[(b[9] + skey->saferp.K[i][9]) & 255] ^ skey->saferp.K[i+1][9]; \ b[10] = safer_lbox[(b[10] + skey->saferp.K[i][10]) & 255] ^ skey->saferp.K[i+1][10]; \ b[11] = (safer_ebox[(b[11] ^ skey->saferp.K[i][11]) & 255] + skey->saferp.K[i+1][11]) & 255; \ b[12] = (safer_ebox[(b[12] ^ skey->saferp.K[i][12]) & 255] + skey->saferp.K[i+1][12]) & 255; \ b[13] = safer_lbox[(b[13] + skey->saferp.K[i][13]) & 255] ^ skey->saferp.K[i+1][13]; \ b[14] = safer_lbox[(b[14] + skey->saferp.K[i][14]) & 255] ^ skey->saferp.K[i+1][14]; \ b[15] = (safer_ebox[(b[15] ^ skey->saferp.K[i][15]) & 255] + skey->saferp.K[i+1][15]) & 255; /* This is one inverse key application */#define iROUND(b, i) \ b[0] = safer_lbox[(b[0] - skey->saferp.K[i+1][0]) & 255] ^ skey->saferp.K[i][0]; \ b[1] = (safer_ebox[(b[1] ^ skey->saferp.K[i+1][1]) & 255] - skey->saferp.K[i][1]) & 255; \ b[2] = (safer_ebox[(b[2] ^ skey->saferp.K[i+1][2]) & 255] - skey->saferp.K[i][2]) & 255; \ b[3] = safer_lbox[(b[3] - skey->saferp.K[i+1][3]) & 255] ^ skey->saferp.K[i][3]; \ b[4] = safer_lbox[(b[4] - skey->saferp.K[i+1][4]) & 255] ^ skey->saferp.K[i][4]; \ b[5] = (safer_ebox[(b[5] ^ skey->saferp.K[i+1][5]) & 255] - skey->saferp.K[i][5]) & 255; \ b[6] = (safer_ebox[(b[6] ^ skey->saferp.K[i+1][6]) & 255] - skey->saferp.K[i][6]) & 255; \ b[7] = safer_lbox[(b[7] - skey->saferp.K[i+1][7]) & 255] ^ skey->saferp.K[i][7]; \ b[8] = safer_lbox[(b[8] - skey->saferp.K[i+1][8]) & 255] ^ skey->saferp.K[i][8]; \ b[9] = (safer_ebox[(b[9] ^ skey->saferp.K[i+1][9]) & 255] - skey->saferp.K[i][9]) & 255; \ b[10] = (safer_ebox[(b[10] ^ skey->saferp.K[i+1][10]) & 255] - skey->saferp.K[i][10]) & 255; \ b[11] = safer_lbox[(b[11] - skey->saferp.K[i+1][11]) & 255] ^ skey->saferp.K[i][11]; \ b[12] = safer_lbox[(b[12] - skey->saferp.K[i+1][12]) & 255] ^ skey->saferp.K[i][12]; \ b[13] = (safer_ebox[(b[13] ^ skey->saferp.K[i+1][13]) & 255] - skey->saferp.K[i][13]) & 255; \ b[14] = (safer_ebox[(b[14] ^ skey->saferp.K[i+1][14]) & 255] - skey->saferp.K[i][14]) & 255; \ b[15] = safer_lbox[(b[15] - skey->saferp.K[i+1][15]) & 255] ^ skey->saferp.K[i][15];/* This is a forward single layer PHT transform. */#define PHT(b) \ b[0] = (b[0] + (b[1] = (b[0] + b[1]) & 255)) & 255; \ b[2] = (b[2] + (b[3] = (b[3] + b[2]) & 255)) & 255; \ b[4] = (b[4] + (b[5] = (b[5] + b[4]) & 255)) & 255; \ b[6] = (b[6] + (b[7] = (b[7] + b[6]) & 255)) & 255; \ b[8] = (b[8] + (b[9] = (b[9] + b[8]) & 255)) & 255; \ b[10] = (b[10] + (b[11] = (b[11] + b[10]) & 255)) & 255; \ b[12] = (b[12] + (b[13] = (b[13] + b[12]) & 255)) & 255; \ b[14] = (b[14] + (b[15] = (b[15] + b[14]) & 255)) & 255; /* This is an inverse single layer PHT transform */#define iPHT(b) \ b[15] = (b[15] - (b[14] = (b[14] - b[15]) & 255)) & 255; \ b[13] = (b[13] - (b[12] = (b[12] - b[13]) & 255)) & 255; \ b[11] = (b[11] - (b[10] = (b[10] - b[11]) & 255)) & 255; \ b[9] = (b[9] - (b[8] = (b[8] - b[9]) & 255)) & 255; \ b[7] = (b[7] - (b[6] = (b[6] - b[7]) & 255)) & 255; \ b[5] = (b[5] - (b[4] = (b[4] - b[5]) & 255)) & 255; \ b[3] = (b[3] - (b[2] = (b[2] - b[3]) & 255)) & 255; \ b[1] = (b[1] - (b[0] = (b[0] - b[1]) & 255)) & 255; \/* This is the "Armenian" Shuffle. It takes the input from b and stores it in b2 */#define SHUF(b, b2) \ b2[0] = b[8]; b2[1] = b[11]; b2[2] = b[12]; b2[3] = b[15]; \ b2[4] = b[2]; b2[5] = b[1]; b2[6] = b[6]; b2[7] = b[5]; \ b2[8] = b[10]; b2[9] = b[9]; b2[10] = b[14]; b2[11] = b[13]; \ b2[12] = b[0]; b2[13] = b[7]; b2[14] = b[4]; b2[15] = b[3];/* This is the inverse shuffle. It takes from b and gives to b2 */#define iSHUF(b, b2) \ b2[0] = b[12]; b2[1] = b[5]; b2[2] = b[4]; b2[3] = b[15]; \ b2[4] = b[14]; b2[5] = b[7]; b2[6] = b[6]; b2[7] = b[13]; \ b2[8] = b[0]; b2[9] = b[9]; b2[10] = b[8]; b2[11] = b[1]; \ b2[12] = b[2]; b2[13] = b[11]; b2[14] = b[10]; b2[15] = b[3];/* The complete forward Linear Transform layer. * Note that alternating usage of b and b2. * Each round of LT starts in 'b' and ends in 'b2'. */#define LT(b, b2) \ PHT(b); SHUF(b, b2); \ PHT(b2); SHUF(b2, b); \ PHT(b); SHUF(b, b2); \ PHT(b2); /* This is the inverse linear transform layer. */#define iLT(b, b2) \ iPHT(b); \ iSHUF(b, b2); iPHT(b2); \ iSHUF(b2, b); iPHT(b); \ iSHUF(b, b2); iPHT(b2); #ifdef LTC_SMALL_CODE static void _round(unsigned char *b, int i, symmetric_key *skey) { ROUND(b, i);}static void _iround(unsigned char *b, int i, symmetric_key *skey){ iROUND(b, i);}static void _lt(unsigned char *b, unsigned char *b2){ LT(b, b2);}static void _ilt(unsigned char *b, unsigned char *b2){ iLT(b, b2);} #undef ROUND#define ROUND(b, i) _round(b, i, skey)#undef iROUND#define iROUND(b, i) _iround(b, i, skey)#undef LT#define LT(b, b2) _lt(b, b2)#undef iLT#define iLT(b, b2) _ilt(b, b2)#endif/* These are the 33, 128-bit bias words for the key schedule */static const unsigned char safer_bias[33][16] = {{ 70, 151, 177, 186, 163, 183, 16, 10, 197, 55, 179, 201, 90, 40, 172, 100},{ 236, 171, 170, 198, 103, 149, 88, 13, 248, 154, 246, 110, 102, 220, 5, 61},{ 138, 195, 216, 137, 106, 233, 54, 73, 67, 191, 235, 212, 150, 155, 104, 160},{ 93, 87, 146, 31, 213, 113, 92, 187, 34, 193, 190, 123, 188, 153, 99, 148},{ 42, 97, 184, 52, 50, 25, 253, 251, 23, 64, 230, 81, 29, 65, 68, 143},{ 221, 4, 128, 222, 231, 49, 214, 127, 1, 162, 247, 57, 218, 111, 35, 202},{ 58, 208, 28, 209, 48, 62, 18, 161, 205, 15, 224, 168, 175, 130, 89, 44},{ 125, 173, 178, 239, 194, 135, 206, 117, 6, 19, 2, 144, 79, 46, 114, 51},{ 192, 141, 207, 169, 129, 226, 196, 39, 47, 108, 122, 159, 82, 225, 21, 56},{ 252, 32, 66, 199, 8, 228, 9, 85, 94, 140, 20, 118, 96, 255, 223, 215},{ 250, 11, 33, 0, 26, 249, 166, 185, 232, 158, 98, 76, 217, 145, 80, 210},{ 24, 180, 7, 132, 234, 91, 164, 200, 14, 203, 72, 105, 75, 78, 156, 53},{ 69, 77, 84, 229, 37, 60, 12, 74, 139, 63, 204, 167, 219, 107, 174, 244},{ 45, 243, 124, 109, 157, 181, 38, 116, 242, 147, 83, 176, 240, 17, 237, 131},{ 182, 3, 22, 115, 59, 30, 142, 112, 189, 134, 27, 71, 126, 36, 86, 241},{ 136, 70, 151, 177, 186, 163, 183, 16, 10, 197, 55, 179, 201, 90, 40, 172},{ 220, 134, 119, 215, 166, 17, 251, 244, 186, 146, 145, 100, 131, 241, 51, 239},{ 44, 181, 178, 43, 136, 209, 153, 203, 140, 132, 29, 20, 129, 151, 113, 202},{ 163, 139, 87, 60, 130, 196, 82, 92, 28, 232, 160, 4, 180, 133, 74, 246},{ 84, 182, 223, 12, 26, 142, 222, 224, 57, 252, 32, 155, 36, 78, 169, 152},{ 171, 242, 96, 208, 108, 234, 250, 199, 217, 0, 212, 31, 110, 67, 188, 236},{ 137, 254, 122, 93, 73, 201, 50, 194, 249, 154, 248, 109, 22, 219, 89, 150},{ 233, 205, 230, 70, 66, 143, 10, 193, 204, 185, 101, 176, 210, 198, 172, 30},{ 98, 41, 46, 14, 116, 80, 2, 90, 195, 37, 123, 138, 42, 91, 240, 6},{ 71, 111, 112, 157, 126, 16, 206, 18, 39, 213, 76, 79, 214, 121, 48, 104},{ 117, 125, 228, 237, 128, 106, 144, 55, 162, 94, 118, 170, 197, 127, 61, 175},{ 229, 25, 97, 253, 77, 124, 183, 11, 238, 173, 75, 34, 245, 231, 115, 35},{ 200, 5, 225, 102, 221, 179, 88, 105, 99, 86, 15, 161, 49, 149, 23, 7},{ 40, 1, 45, 226, 147, 190, 69, 21, 174, 120, 3, 135, 164, 184, 56, 207},{ 8, 103, 9, 148, 235, 38, 168, 107, 189, 24, 52, 27, 187, 191, 114, 247},{ 53, 72, 156, 81, 47, 59, 85, 227, 192, 159, 216, 211, 243, 141, 177, 255},{ 62, 220, 134, 119, 215, 166, 17, 251, 244, 186, 146, 145, 100, 131, 241, 51}}; /** Initialize the SAFER+ block cipher @param key The symmetric key you wish to pass @param keylen The key length in bytes @param num_rounds The number of rounds desired (0 for default) @param skey The key in as scheduled by this function. @return CRYPT_OK if successful */int saferp_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey){ unsigned x, y, z; unsigned char t[33]; static const int rounds[3] = { 8, 12, 16 }; LTC_ARGCHK(key != NULL); LTC_ARGCHK(skey != NULL); /* check arguments */ if (keylen != 16 && keylen != 24 && keylen != 32) { return CRYPT_INVALID_KEYSIZE; } /* Is the number of rounds valid? Either use zero for default or * 8,12,16 rounds for 16,24,32 byte keys */ if (num_rounds != 0 && num_rounds != rounds[(keylen/8)-2]) { return CRYPT_INVALID_ROUNDS; } /* 128 bit key version */ if (keylen == 16) { /* copy key into t */ for (x = y = 0; x < 16; x++) { t[x] = key[x]; y ^= key[x]; } t[16] = y; /* make round keys */ for (x = 0; x < 16; x++) { skey->saferp.K[0][x] = t[x]; } /* make the 16 other keys as a transformation of the first key */ for (x = 1; x < 17; x++) { /* rotate 3 bits each */ for (y = 0; y < 17; y++) { t[y] = ((t[y]<<3)|(t[y]>>5)) & 255; } /* select and add */ z = x; for (y = 0; y < 16; y++) { skey->saferp.K[x][y] = (t[z] + safer_bias[x-1][y]) & 255; if (++z == 17) { z = 0; } } } skey->saferp.rounds = 8; } else if (keylen == 24) { /* copy key into t */ for (x = y = 0; x < 24; x++) { t[x] = key[x]; y ^= key[x]; } t[24] = y; /* make round keys */ for (x = 0; x < 16; x++) { skey->saferp.K[0][x] = t[x]; }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -