📄 square.java
字号:
// $Id: Square.java,v 1.5 1998/02/21 19:15:10 iang Exp $//// $Log: Square.java,v $// Revision 1.5 1998/02/21 19:15:10 iang// Updated javadoc comment to refer to test data. Not used yet.//// Revision 1.4 1997/11/29 04:42:56 hopwood// + Changes to engineUpdate method.//// Revision 1.3 1997/11/20 19:31:41 hopwood// + cryptix.util.* name changes.//// Revision 1.2 1997/11/08 14:39:20 raif// *** empty log message ***//// Revision 1.1.1.1 1997/11/03 22:36:56 hopwood// + Imported to CVS (tagged as 'start').//// Revision 0.3.2.1 1997/10/26 David Hopwood// + Implementation is now in the same style as Blowfish 0.3.2.x.// + Formatting changes.//// Revision 0.3.2.0 1997/09/18 David Hopwood// + Ensured that this class is final, and added a comment that this is for// security reasons.// If it were not final, some VMs have a bug that would allow a subclass// that implements Cloneable to call Object's or Cipher's clone() method// using invokenonvirtual, which would duplicate the pointer to the native// state. Then calling finalize() on the original and using the clone (for// example) would result in freed memory being written to :-(.// + Native linking and debugging brought up to date with Blowfish 0.3.2.0.//// Revision 0.3.1.0 1997/07/14 David Hopwood// + Jump in version number (from 0.1.1.1) to be the same as Blowfish,// DES and IDEA.// + Blowfish, DES, IDEA, and Square 0.3.1.0 are now at the same API// level and in the same style.// + Fixed security bug (out-of-bounds read) introduced in 0.1.1.1 -// same bug as for Blowfish 0.3.0.5.// + Renamed outs variable in engineUpdate to temp, to avoid similarity// with out.//// Revision 0.1.1.1 1997/07/12 P. Barreto & R. Naffah// + Amended native implementation as per Blowfish 0.3.0.5.// + Minor changes for better readability and improved performance.//// Revision 0.1.1.0 1997/07/08 R. Naffah & P. Barreto// + Tested OK with and without Square.DLL;// + Optimised the sub-keys generation sub-function code by in-lining// the values of the diffusion matrix G and hence removing its need// (in the code) altogether;// + Added support for native library;// + Incorporated D. Hopwood framework for native library linking// and debugging;// + Use initialisation code to generate the SE, SD, TE and TD arrays.// Size down from 15K to 6K.//// Revision 0.1.0.0 1997/06/30 R. Naffah// + Original version.//// $Endlog$/* * Copyright (c) 1997 Systemics Ltd * on behalf of the Cryptix Development Team. All rights reserved. */package cryptix.provider.cipher;import cryptix.util.core.Debug;import cryptix.CryptixException;import cryptix.util.core.ArrayUtil;import cryptix.util.core.Hex;import cryptix.provider.key.RawSecretKey;import java.io.PrintWriter;import java.security.Cipher;import java.security.Key;import java.security.InvalidKeyException;import java.security.Security;import java.security.SymmetricCipher;/** * A subclass of Cipher to implement a Java class of the Square algorithm. * <p> * Square is a cipher algorithm developed by Joan Daemen <Daemen.J@banksys.com> * and Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be> * <p> * <b>References:</b> * <p> * <blockquote> * <UL> * <li>The * <a href="http://www.esat.kuleuven.ac.be/%7Erijmen/square/"> * Square home page</a> * has up-to-date comments, implementations, and certification data. * <li>J. Daemen, L.R. Knudsen, V. Rijmen, * "<a href="http://www.esat.kuleuven.ac.be/%7Erijmen/downloadable/square/fse.ps.gz"> * The block cipher Square</a>," * <cite>Fast Software Encryption</cite>, * LNCS 1267, E. Biham, Ed., Springer-Verlag, 1997, pp. 149-165. * </UL> * </blockquote> * <p> * <b>Copyright</b> © 1997 * <a href="http://www.systemics.com/">Systemics Ltd</a> on behalf of the * <a href="http://www.systemics.com/docs/cryptix/">Cryptix Development Team</a>. * <br>All rights reserved. * <p> * <b>$Revision: 1.5 $</b> * @author Raif S. Naffah * @author Paulo S.L.M. Barreto * @author David Hopwood * @since Cryptix 2.2 */public final class Square // must be final for security reasonsextends Cipherimplements SymmetricCipher{// Debugging methods and vars.//........................................................................... private static final boolean DEBUG = Debug.GLOBAL_DEBUG; private static final boolean DEBUG_SLOW = Debug.GLOBAL_DEBUG_SLOW; private static final int debuglevel = DEBUG ? Debug.getLevel("Square") : 0; private static final PrintWriter err = DEBUG ? Debug.getOutput() : null; private static void debug(String s) { err.println("Square: " + s); }// Native library linking methods and vars.//........................................................................... private static NativeLink linkStatus = new NativeLink("Square", 2, 3); /** * Gets an object representing the native linking status of this class. */ public static cryptix.util.core.LinkStatus getLinkStatus() { return linkStatus; } /** * The native reference to the current native key schedule * structure. Defaults to 0 but is set by native code after a * successful call to native_init(). * <p> * IMPORTANT: Do not change the name of this variable without * duplicating the same in the native code. */ private long native_cookie; /** * This object must be synchronized on while calling any native instance * method. It is null if the native code is not being used (e.g. the * library did not load successfully, or the user disabled its use in * the properties file). */ private Object native_lock; // defaults to null private void link() { synchronized(linkStatus) { try { if (linkStatus.attemptLoad()) { linkStatus.checkVersion(getLibMajorVersion(), getLibMinorVersion()); linkStatus.check(native_clinit()); } if (linkStatus.useNative()) { linkStatus.check(native_init()); native_lock = new Object(); } } catch (UnsatisfiedLinkError e) { linkStatus.fail(e);if (DEBUG && debuglevel > 2) debug(e.getMessage()); }if (DEBUG && debuglevel > 2) debug("Using native library? " + (native_lock != null)); } }// Native support API//........................................................................... // The methods that get the library version. private native static int getLibMajorVersion(); private native static int getLibMinorVersion(); /** * Static initialization and self-test method for the native code. * * @return a string if an error occurred or null otherwise. */ private native String native_clinit(); /** * Initializes the native state for this cipher object and allocates * needed native storage for the internal key schedule. A reference * to the newly allocated space, if successful, is stored in the * instance variable <code>native_cookie</code>. * * @return a string if an error occurred or null otherwise. */ private native String native_init(); /** * This function expands the user key to an internal form. * * @param cookie a valid reference to the native key structure. This * value is set by the native library upon return from * native_init() (see link() method at the top). * @param userKey a byte array representing the user key * @return an error String, or null if there was no error */// private native String native_ks(long cookie, byte[] userKey, boolean encrypt); private native String native_ks(long cookie, byte[] userKey); /** * Encrypts/decrypts a data block. * <p> * FUTURE: possibly change this to be able to process more than one block, * to reduce native method call overhead. * <p> * SECURITY: the caller <strong>must</strong> ensure that: * <ul> * <li> <code>in != null</code> * <li> <code>out != null</code> * <li> <code>inOffset >= 0</code> * <li> <code>(long)inOffset + BLOCK_SIZE <= in.length</code> * <li> <code>outOffset >= 0</code> * <li> <code>(long)outOffset + BLOCK_SIZE <= out.length</code> * </ul> * * @param cookie a valid reference to the native key structure. This * value is set by the native library upon return from * native_init() (see link() method at the top). * @param in input array containing data to encrypt or decrypt * depending on the value of the encrypt boolean parameter. * @param inOffset index of where we should start reading from input. * @param out output array containing data decrypted or encrypted * depending on the value of the encrypt boolean parameter. * @param outOffset index of where we should start writing to output. * @param encrypt if true then encrypt, otherwise decrypt. * @return the number of bytes crypted (always BLOCK_SIZE) or 0 if an error * occurred. */ private native int native_crypt(long cookie, byte[] in, int inOffset, byte[] out, int outOffset, boolean encrypt); /** * Finalizes the native state for this object. * * @return a string if an error occurred or null otherwise. */ private native String native_finalize();// Square variables and constants//............................................................................ /** * Encryption and decryption Square S-Box values */ private static final byte[] SE = new byte[256]; // blank finals private static final byte[] SD = new byte[256]; /** * Transposition boxes for encryption and decryption */ private static final int[] TE = new int[256]; private static final int[] TD = new int[256]; /** * Square block size in bytes */ private static final int BLOCK_SIZE = 16; /* * Square's number of rounds. */ private static final int R = 8; /* * This instance's Square key schedule. */ private int[][] sKey = new int[R + 1][4]; private static final int ROOT = 0x1F5; // for generating GF(2**8) private static final int[] OFFSET = new int[R];// Static code to build some tables//............................................................................ static { int i, j; // // Generate exp and log tables used in multiplication over GF(2 ** m) // byte[] exp = new byte[256]; byte[] log = new byte[256]; exp[0] = 1; for (i = 1; i < 256; i++) { j = exp[i - 1] << 1; if ((j & 0x100) != 0) j ^= ROOT; // reduce j (mod ROOT) exp[i] = (byte)j; log[j & 0xFF] = (byte)i; } // // Compute the substitution box SE[] and its inverse SD[] // based on F(x) = x**{-1} plus affine transform of the output. // SE[0] = 0; SE[1] = 1; for (i = 2; i < 256; i++) SE[i] = exp[(255 - log[i]) & 0xFF]; // // Let SE[i] be represented as an 8-row vector V over GF(2); // the affine transformation is A * V + T, where the rows of // the 8 x 8 matrix A are contained in trans[0]...trans[7] // and the 8-row vector T is contained in 0xB1. // int[] trans = {0x01, 0x03, 0x05, 0x0F, 0x1F, 0x3D, 0x7B, 0xD6}; int u, v; for (i = 0; i < 256; i++) { v = 0xB1; // the affine part of the transform for (j = 0; j < 8; j++) { u = SE[i] & trans[j] & 0xFF; // column-wise multiplication over GF(2) u ^= u >>> 4; // sum of all bits of u over GF(2) u ^= u >>> 2; u ^= u >>> 1; u &= 1; v ^= u << j; // row alignment of the result } SE[i] = (byte) v; SD[v] = (byte) i; // inverse substitution box } // // Generate the OFFSET values. // OFFSET[0] = 1; for (i = 1; i < R; i++) { OFFSET[i] = mul(OFFSET[i - 1], 2); OFFSET[i - 1] <<= 24; } OFFSET[R - 1] <<= 24; // // Generate the TE and TD transposition boxes. // Notes: // (1) The function mul below computes the product of two // elements of GF(2 ** 8) with ROOT as reduction polynomial // (see implementation below in Square's Own Methods section) // (2) the values used in computing the TE and TD values are // the GF(2 ** 8) coefficients of the diffusion polynomial c(x) // and its inverse (modulo x ** 4 + 1) d(x), defined in sections // 2.1 and 4 of the algorithm designers' paper (see References // above). // int se, sd; for (i = 0; i < 256; i++) { se = SE[i] & 0xFF; sd = SD[i] & 0xFF; TE[i] = SE[i & 3] == 0 ? 0 : mul(se, 2) << 24 | se << 16 | se << 8 | mul(se, 3); TD[i] = SD[i & 3] == 0 ? 0 : mul(sd, 14) << 24 | mul(sd, 9) << 16 | mul(sd, 13) << 8 | mul(sd, 11); } }// Constructor, finalizer, and clone()//............................................................................ /** * Constructs a Square cipher object, in the UNINITIALIZED state. * This calls the Cipher constructor with <i>implBuffering</i> false, * <i>implPadding</i> false and the provider set to "Cryptix". */ public Square() { super(false, false, "Cryptix"); link(); } /** * Cleans up resources used by this instance, if necessary. */ protected final void finalize() { if (native_lock != null) { synchronized(native_lock) { String error = native_finalize(); // may be called more than once if (error != null) debug(error + " in native_finalize"); } } } /** * Always throws a CloneNotSupportedException (cloning of ciphers is not * supported for security reasons). */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -