📄 serpent_standard.java
字号:
{ 1, 5, 20, 90, xFF, xFF, xFF, xFF}, { 15, 102, xFF, xFF, xFF, xFF, xFF, xFF}, { 3, 31, 90, xFF, xFF, xFF, xFF, xFF}, { 57, 59, 76, xFF, xFF, xFF, xFF, xFF}, { 5, 9, 24, 94, xFF, xFF, xFF, xFF}, { 19, 106, xFF, xFF, xFF, xFF, xFF, xFF}, { 7, 35, 94, xFF, xFF, xFF, xFF, xFF}, { 61, 63, 80, xFF, xFF, xFF, xFF, xFF}, { 9, 13, 28, 98, xFF, xFF, xFF, xFF}, { 23, 110, xFF, xFF, xFF, xFF, xFF, xFF}, { 11, 39, 98, xFF, xFF, xFF, xFF, xFF}, { 65, 67, 84, xFF, xFF, xFF, xFF, xFF}, { 13, 17, 32, 102, xFF, xFF, xFF, xFF}, { 27, 114, xFF, xFF, xFF, xFF, xFF, xFF}, { 1, 3, 15, 20, 43, 102, xFF, xFF}, { 69, 71, 88, xFF, xFF, xFF, xFF, xFF}, { 17, 21, 36, 106, xFF, xFF, xFF, xFF}, { 1, 31, 118, xFF, xFF, xFF, xFF, xFF}, { 5, 7, 19, 24, 47, 106, xFF, xFF}, { 73, 75, 92, xFF, xFF, xFF, xFF, xFF}, { 21, 25, 40, 110, xFF, xFF, xFF, xFF}, { 5, 35, 122, xFF, xFF, xFF, xFF, xFF}, { 9, 11, 23, 28, 51, 110, xFF, xFF}, { 77, 79, 96, xFF, xFF, xFF, xFF, xFF}, { 25, 29, 44, 114, xFF, xFF, xFF, xFF}, { 9, 39, 126, xFF, xFF, xFF, xFF, xFF}, { 13, 15, 27, 32, 55, 114, xFF, xFF}, { 81, 83, 100, xFF, xFF, xFF, xFF, xFF}, { 1, 29, 33, 48, 118, xFF, xFF, xFF}, { 2, 13, 43, xFF, xFF, xFF, xFF, xFF}, { 1, 17, 19, 31, 36, 59, 118, xFF}, { 85, 87, 104, xFF, xFF, xFF, xFF, xFF}, { 5, 33, 37, 52, 122, xFF, xFF, xFF}, { 6, 17, 47, xFF, xFF, xFF, xFF, xFF}, { 5, 21, 23, 35, 40, 63, 122, xFF}, { 89, 91, 108, xFF, xFF, xFF, xFF, xFF}, { 9, 37, 41, 56, 126, xFF, xFF, xFF}, { 10, 21, 51, xFF, xFF, xFF, xFF, xFF}, { 9, 25, 27, 39, 44, 67, 126, xFF}, { 93, 95, 112, xFF, xFF, xFF, xFF, xFF}, { 2, 13, 41, 45, 60, xFF, xFF, xFF}, { 14, 25, 55, xFF, xFF, xFF, xFF, xFF}, { 2, 13, 29, 31, 43, 48, 71, xFF}, { 97, 99, 116, xFF, xFF, xFF, xFF, xFF}, { 6, 17, 45, 49, 64, xFF, xFF, xFF}, { 18, 29, 59, xFF, xFF, xFF, xFF, xFF}, { 6, 17, 33, 35, 47, 52, 75, xFF}, {101, 103, 120, xFF, xFF, xFF, xFF, xFF}, { 10, 21, 49, 53, 68, xFF, xFF, xFF}, { 22, 33, 63, xFF, xFF, xFF, xFF, xFF}, { 10, 21, 37, 39, 51, 56, 79, xFF}, {105, 107, 124, xFF, xFF, xFF, xFF, xFF}, { 14, 25, 53, 57, 72, xFF, xFF, xFF}, { 26, 37, 67, xFF, xFF, xFF, xFF, xFF}, { 14, 25, 41, 43, 55, 60, 83, xFF}, { 0, 109, 111, xFF, xFF, xFF, xFF, xFF}, { 18, 29, 57, 61, 76, xFF, xFF, xFF}, { 30, 41, 71, xFF, xFF, xFF, xFF, xFF}, { 18, 29, 45, 47, 59, 64, 87, xFF}, { 4, 113, 115, xFF, xFF, xFF, xFF, xFF}, { 22, 33, 61, 65, 80, xFF, xFF, xFF}, { 34, 45, 75, xFF, xFF, xFF, xFF, xFF}, { 22, 33, 49, 51, 63, 68, 91, xFF}, { 8, 117, 119, xFF, xFF, xFF, xFF, xFF}, { 26, 37, 65, 69, 84, xFF, xFF, xFF}, { 38, 49, 79, xFF, xFF, xFF, xFF, xFF}, { 26, 37, 53, 55, 67, 72, 95, xFF}, { 12, 121, 123, xFF, xFF, xFF, xFF, xFF}, { 30, 41, 69, 73, 88, xFF, xFF, xFF}, { 42, 53, 83, xFF, xFF, xFF, xFF, xFF}, { 30, 41, 57, 59, 71, 76, 99, xFF}, { 16, 125, 127, xFF, xFF, xFF, xFF, xFF}, { 34, 45, 73, 77, 92, xFF, xFF, xFF}, { 46, 57, 87, xFF, xFF, xFF, xFF, xFF}, { 34, 45, 61, 63, 75, 80, 103, xFF}, { 1, 3, 20, xFF, xFF, xFF, xFF, xFF}, { 38, 49, 77, 81, 96, xFF, xFF, xFF}, { 50, 61, 91, xFF, xFF, xFF, xFF, xFF}, { 38, 49, 65, 67, 79, 84, 107, xFF}, { 5, 7, 24, xFF, xFF, xFF, xFF, xFF}, { 42, 53, 81, 85, 100, xFF, xFF, xFF}, { 54, 65, 95, xFF, xFF, xFF, xFF, xFF}, { 42, 53, 69, 71, 83, 88, 111, xFF}, { 9, 11, 28, xFF, xFF, xFF, xFF, xFF}, { 46, 57, 85, 89, 104, xFF, xFF, xFF}, { 58, 69, 99, xFF, xFF, xFF, xFF, xFF}, { 46, 57, 73, 75, 87, 92, 115, xFF}, { 13, 15, 32, xFF, xFF, xFF, xFF, xFF}, { 50, 61, 89, 93, 108, xFF, xFF, xFF}, { 62, 73, 103, xFF, xFF, xFF, xFF, xFF}, { 50, 61, 77, 79, 91, 96, 119, xFF}, { 17, 19, 36, xFF, xFF, xFF, xFF, xFF}, { 54, 65, 93, 97, 112, xFF, xFF, xFF}, { 66, 77, 107, xFF, xFF, xFF, xFF, xFF}, { 54, 65, 81, 83, 95, 100, 123, xFF}, { 21, 23, 40, xFF, xFF, xFF, xFF, xFF}, { 58, 69, 97, 101, 116, xFF, xFF, xFF}, { 70, 81, 111, xFF, xFF, xFF, xFF, xFF}, { 58, 69, 85, 87, 99, 104, 127, xFF}, { 25, 27, 44, xFF, xFF, xFF, xFF, xFF}, { 62, 73, 101, 105, 120, xFF, xFF, xFF}, { 74, 85, 115, xFF, xFF, xFF, xFF, xFF}, { 3, 62, 73, 89, 91, 103, 108, xFF}, { 29, 31, 48, xFF, xFF, xFF, xFF, xFF}, { 66, 77, 105, 109, 124, xFF, xFF, xFF}, { 78, 89, 119, xFF, xFF, xFF, xFF, xFF}, { 7, 66, 77, 93, 95, 107, 112, xFF}, { 33, 35, 52, xFF, xFF, xFF, xFF, xFF}, { 0, 70, 81, 109, 113, xFF, xFF, xFF}, { 82, 93, 123, xFF, xFF, xFF, xFF, xFF}, { 11, 70, 81, 97, 99, 111, 116, xFF}, { 37, 39, 56, xFF, xFF, xFF, xFF, xFF}, { 4, 74, 85, 113, 117, xFF, xFF, xFF}, { 86, 97, 127, xFF, xFF, xFF, xFF, xFF}, { 15, 74, 85, 101, 103, 115, 120, xFF}, { 41, 43, 60, xFF, xFF, xFF, xFF, xFF}, { 8, 78, 89, 117, 121, xFF, xFF, xFF}, { 3, 90, xFF, xFF, xFF, xFF, xFF, xFF}, { 19, 78, 89, 105, 107, 119, 124, xFF}, { 45, 47, 64, xFF, xFF, xFF, xFF, xFF}, { 12, 82, 93, 121, 125, xFF, xFF, xFF}, { 7, 94, xFF, xFF, xFF, xFF, xFF, xFF}, { 0, 23, 82, 93, 109, 111, 123, xFF}, { 49, 51, 68, xFF, xFF, xFF, xFF, xFF}, { 1, 16, 86, 97, 125, xFF, xFF, xFF}, { 11, 98, xFF, xFF, xFF, xFF, xFF, xFF}, { 4, 27, 86, 97, 113, 115, 127, xFF} }; private static final char[] HEX_DIGITS = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' };// Basic API methods//........................................................................... /** * Expand a user-supplied key material into a session key. * * @param key The user-key bytes (multiples of 4) to use. * @exception InvalidKeyException If the key is invalid. */ public static synchronized Object makeKey (byte[] key) throws InvalidKeyException {if (DEBUG) trace(IN, "makeKey("+key+")");if (DEBUG && debuglevel > 7) {System.out.println("Intermediate Standard Session Key Values");System.out.println();System.out.println("Raw="+toString(key));} // compute prekeys w[]: // (a) from user key material int[] w = new int[4 * (ROUNDS + 1)]; int offset = 0; int limit = key.length / 4; int i, j; for (i = 0; i < limit; i++) w[i] = (key[offset++] & 0xFF) | (key[offset++] & 0xFF) << 8 | (key[offset++] & 0xFF) << 16 | (key[offset++] & 0xFF) << 24; if (i < 8) w[i++] = 1;// for (; i < 8; i++)// w[i] = 0; // (b) and expanding them to full 132 x 32-bit material // this is a literal implementation of the Serpent paper // (section 4 The Key Schedule, p.226) int t; // start by computing the first 8 values using the second // lot of 8 values as an intermediary buffer for (i = 8, j = 0; i < 16; i++) { t = w[j] ^ w[i-5] ^ w[i-3] ^ w[i-1] ^ PHI ^ j++; w[i] = t << 11 | t >>> 21; } // translate the buffer by -8 for (i = 0, j = 8; i < 8; ) w[i++] = w[j++]; limit = 4 * (ROUNDS + 1); // 132 for a 32-round Serpent // finish computing the remaining intermediary subkeys for ( ; i < limit; i++) { t = w[i-8] ^ w[i-5] ^ w[i-3] ^ w[i-1] ^ PHI ^ i; w[i] = t << 11 | t >>> 21; }if (DEBUG && debuglevel > 8) for(i=0;i<limit;i++) debug("w["+i+"]: "+intToString(w[i])); // compute intermediary key into k[] int[] k = new int[limit]; int box, a, b, c, d, in, out; for (i = 0; i < ROUNDS + 1; i++) { box = (ROUNDS + 3 - i) % ROUNDS; a = w[4*i ]; b = w[4*i + 1]; c = w[4*i + 2]; d = w[4*i + 3]; for (j = 0; j < 32; j++) { in = getBit(a, j) | getBit(b, j) << 1 | getBit(c, j) << 2 | getBit(d, j) << 3; out = S(box, in); k[4*i ] |= getBit(out, 0) << j; k[4*i + 1] |= getBit(out, 1) << j; k[4*i + 2] |= getBit(out, 2) << j; k[4*i + 3] |= getBit(out, 3) << j; } } // renumber the 32-bit values k[] as 128-bit subkeys K[][] int[][] K = new int[ROUNDS + 1][4]; for (i = 0, offset = 0; i < ROUNDS + 1; i++) { K[i][0] = k[offset++]; K[i][1] = k[offset++]; K[i][2] = k[offset++]; K[i][3] = k[offset++];if (DEBUG && debuglevel > 8) debug("K["+i+"]: "+toReversedString(K[i])); } // we now apply IP to the round key in order to place the key bits // in the correct column; ie. Khat[i] = IP(K[i]) --we use same K for (i = 0; i < ROUNDS + 1; i++) { K[i] = IP(K[i]);if (DEBUG && debuglevel > 7) debug("Khat["+i+"]: "+toReversedString(K[i])); }if (DEBUG && debuglevel > 7) {for (i=0;i<ROUNDS+1;i++) System.out.println("K"+i+"="+toString(K[i]));System.out.println();}if (DEBUG) trace(OUT, "makeKey()"); return K; } /** * Encrypt exactly one block of plaintext. * * @param in The plaintext. * @param inOffset Index of in from which to start considering data. * @param sessionKey The session key to use for encryption. * @return The ciphertext generated from a plaintext using the session key. */ public static byte[] blockEncrypt (byte[] in, int inOffset, Object sessionKey) {if (DEBUG) trace(IN, "blockEncrypt("+toString(in)+", "+inOffset+", "+sessionKey+")"); int[][] Khat = (int[][]) sessionKey; int[] x = { (in[inOffset++] & 0xFF) | (in[inOffset++] & 0xFF) << 8 | (in[inOffset++] & 0xFF) << 16 | (in[inOffset++] & 0xFF) << 24, (in[inOffset++] & 0xFF) | (in[inOffset++] & 0xFF) << 8 | (in[inOffset++] & 0xFF) << 16 | (in[inOffset++] & 0xFF) << 24, (in[inOffset++] & 0xFF) | (in[inOffset++] & 0xFF) << 8 | (in[inOffset++] & 0xFF) << 16 | (in[inOffset++] & 0xFF) << 24, (in[inOffset++] & 0xFF) | (in[inOffset++] & 0xFF) << 8 | (in[inOffset++] & 0xFF) << 16 | (in[inOffset++] & 0xFF) << 24 }; int[] Bhat = IP(x);if (DEBUG && debuglevel > 6) System.out.println("IP(PT)="+toString(Bhat)); for (int i = 0; i < ROUNDS; i++) { Bhat = R(i, Bhat, Khat);if (DEBUG && debuglevel > 6) System.out.println("CT"+i+"="+toString(Bhat)); }if (DEBUG && debuglevel > 5) debug("Bhat[32]: "+toReversedString(Bhat)); x = FP(Bhat); int a = x[0], b = x[1], c = x[2], d = x[3]; byte[] result = new byte[] { (byte)(a), (byte)(a >>> 8), (byte)(a >>> 16), (byte)(a >>> 24), (byte)(b), (byte)(b >>> 8), (byte)(b >>> 16), (byte)(b >>> 24), (byte)(c), (byte)(c >>> 8), (byte)(c >>> 16), (byte)(c >>> 24), (byte)(d), (byte)(d >>> 8), (byte)(d >>> 16), (byte)(d >>> 24) };if (DEBUG && debuglevel > 6) {System.out.println("CT="+toString(result));System.out.println();}if (DEBUG) trace(OUT, "blockEncrypt()"); return result; } /** * Decrypt exactly one block of ciphertext. * * @param in The ciphertext. * @param inOffset Index of in from which to start considering data. * @param sessionKey The session key to use for decryption. * @return The plaintext generated from a ciphertext using the session key. */ public static byte[] blockDecrypt (byte[] in, int inOffset, Object sessionKey) {if (DEBUG) trace(IN, "blockDecrypt("+toString(in)+", "+inOffset+", "+sessionKey+")"); int[][] Khat = (int[][]) sessionKey; int[] x = { (in[inOffset++] & 0xFF) | (in[inOffset++] & 0xFF) << 8 | (in[inOffset++] & 0xFF) << 16 | (in[inOffset++] & 0xFF) << 24, (in[inOffset++] & 0xFF) | (in[inOffset++] & 0xFF) << 8 | (in[inOffset++] & 0xFF) << 16 | (in[inOffset++] & 0xFF) << 24, (in[inOffset++] & 0xFF) | (in[inOffset++] & 0xFF) << 8 | (in[inOffset++] & 0xFF) << 16 | (in[inOffset++] & 0xFF) << 24, (in[inOffset++] & 0xFF) | (in[inOffset++] & 0xFF) << 8 | (in[inOffset++] & 0xFF) << 16 | (in[inOffset++] & 0xFF) << 24 }; int[] Bhat = FPinverse(x);if (DEBUG && debuglevel > 6) System.out.println("FP'(CT)="+toString(Bhat)); for (int i = ROUNDS - 1; i >= 0; i--) { Bhat = Rinverse(i, Bhat, Khat);if (DEBUG && debuglevel > 6) System.out.println("PT"+i+"="+toString(Bhat)); }if (DEBUG && debuglevel > 5) debug("Bhat[0]: "+toReversedString(Bhat)); x = IPinverse(Bhat); int a = x[0], b = x[1], c = x[2], d = x[3]; byte[] result = new byte[] { (byte)(a), (byte)(a >>> 8), (byte)(a >>> 16), (byte)(a >>> 24), (byte)(b), (byte)(b >>> 8), (byte)(b >>> 16), (byte)(b >>> 24), (byte)(c), (byte)(c >>> 8), (byte)(c >>> 16), (byte)(c >>> 24), (byte)(d), (byte)(d >>> 8), (byte)(d >>> 16), (byte)(d >>> 24) };if (DEBUG && debuglevel > 6) {System.out.println("PT="+toString(result));System.out.println();}if (DEBUG) trace(OUT, "blockDecrypt()"); return result; } public static byte[] blockDecryptGetP (int in, int val, int inOffset, Object sessionKey) { int[][] Khat = (int[][]) sessionKey; int[] x = {0, 0, 0, 0}; int[] Bhat = FPinverse(x); for (int i = ROUNDS - 1; i >= 0; i--) { Bhat = Rinverse(i, Bhat, Khat, in, val); } x = IPinverse(Bhat); int a = x[0], b = x[1], c = x[2], d = x[3];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -