📄 safer.java
字号:
K128_DEFAULT_NOF_ROUNDS = 10, SK64_DEFAULT_NOF_ROUNDS = 8, SK128_DEFAULT_NOF_ROUNDS = 10, MAX_NOF_ROUNDS = 13, BLOCK_SIZE = 8, // SAFER block size in bytes KEY_LENGTH = (1 + BLOCK_SIZE * (1 + 2 * MAX_NOF_ROUNDS)), TAB_LEN = 256; private int[] sKey; // only the lower byte in each int is used private int rounds = SK128_DEFAULT_NOF_ROUNDS; private int variant = SK128_VARIANT; private static final int[] EXP = new int[TAB_LEN]; // blank finals private static final int[] LOG = new int[TAB_LEN];// Static code//........................................................................... static { int exp = 1; for (int i = 0; i < TAB_LEN; i++) { EXP[i] = exp & 0xFF; LOG[EXP[i]] = i; exp = exp * 45 % 257; } }// Constructor, finalizer, and clone()//........................................................................... /** * Calls the Cipher constructor with <code>implBuffering</code> false, * <code>implPadding</code> false and the provider set to "Cryptix". * <p> * Sets the variant of this cipher based on the currently set "variant" * property in the provider properties file. The current JCE syntax * for the SAFER algorithm variant property is: * <pre> * Alg.variant.SAFER = ... * </pre> * <p> * Valid alternatives for variant are: * <ul> * <li> SK-128, SK128, sk-128 and sk128: Strengthened key schedule of * length 128 bits. * <li> SK-64, SK64, sk-64 and sk64: Strengthened key schedule of * length 64 bits. * <li> K-128, K128, k-128 and k128: Non-strengthened key schedule of * length 128 bits. * <li> K-64, K64, k-64 and k64: Non-strengthened key schedule of length * 64 bits. * </ul> * <p> * Once the variant is set, a default value for the number of rounds * to use is also set as follows: * <pre> * Variant Number of rounds = current value * ------- -------------------------------- * SK-128 SK128_DEFAULT_NOF_ROUNDS = 10 * SK-64 SK64_DEFAULT_NOF_ROUNDS = 8 * K-128 K128_DEFAULT_NOF_ROUNDS = 10 * K-64 K64_DEFAULT_NOF_ROUNDS = 6 * </pre> * <p> * If no variant property is found in the provider's properties file * a strengthened key schedule of 128 bits is used with 10 rounds. * <p> * This constructor also attempts to set the desired number of rounds * for this cipher object from a "rounds" property in the provider's * properties file. Acceptable values are non-zero integers between 1 * and the MAX_NOF_ROUNDS constant; i.e. 13. If no such property is * found, or is found but deemed invalid, then the already set value * (depending on the variant property as determined above) remains * unaltered. */ public SAFER() { super(false, false, "Cryptix"); sKey = new int[KEY_LENGTH]; // at this point variant and rounds are set to their default values // see 'Variables and constants' section in the code above. try { String ps = Security.getAlgorithmProperty("SAFER", "variant"); if (ps != null) setVariant(ps); } catch (Exception e) {} switch (variant) { case SK128_VARIANT: rounds = SK128_DEFAULT_NOF_ROUNDS; break; case SK64_VARIANT: rounds = SK64_DEFAULT_NOF_ROUNDS; break; case K128_VARIANT: rounds = K128_DEFAULT_NOF_ROUNDS; break; case K64_VARIANT: rounds = K64_DEFAULT_NOF_ROUNDS; break; } try { String ps = Security.getAlgorithmProperty("SAFER", "rounds"); if (ps != null) setRounds(Integer.parseInt(ps)); } catch (Exception e) {} 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). */ public final Object clone() throws CloneNotSupportedException { throw new CloneNotSupportedException(); }// Implementation of JCE methods//........................................................................... /** * <b>SPI</b>: Returns the length of an input block, in bytes. * * @return the length in bytes of an input block for this cipher. */ public int engineBlockSize () { return BLOCK_SIZE; } /** * <b>SPI</b>: Initializes this cipher for encryption, using the * specified key. * * @param key the key to use for encryption. * @exception KeyException if the key is invalid. */ public void engineInitEncrypt (Key key) throws KeyException { makeKey(key); } /** * <b>SPI</b>: Initializes this cipher for decryption, using the * specified key. * * @param key the key to use for decryption. * @exception KeyException if the key is invalid. */ public void engineInitDecrypt (Key key) throws KeyException { makeKey(key); } /** * <b>SPI</b>: This is the main engine method for updating data. * <p> * <i>in</i> and <i>out</i> may be the same array, and the input and output * regions may overlap. * * @param in the input data. * @param inOffset the offset into in specifying where the data starts. * @param inLen the length of the subarray. * @param out the output array. * @param outOffset the offset indicating where to start writing into * the out array. * @return the number of bytes written. * @exception CryptixException if the native library is being used, and it * reports an error. */ protected int engineUpdate(byte[] in, int inOffset, int inLen, byte[] out, int outOffset) { if (inLen < 0) throw new IllegalArgumentException("inLen < 0"); int blockCount = inLen / BLOCK_SIZE; inLen = blockCount * BLOCK_SIZE; boolean doEncrypt = (getState() == ENCRYPT); // Avoid overlapping input and output regions. if (in == out && (outOffset >= inOffset && outOffset < (long)inOffset+inLen || inOffset >= outOffset && inOffset < (long)outOffset+inLen)) { byte[] newin = new byte[inLen]; System.arraycopy(in, inOffset, newin, 0, inLen); in = newin; inOffset = 0; } if (native_lock != null) { synchronized(native_lock) { // If in == null || out == 0, evaluating their lengths will throw a // NullPointerException. if (inOffset < 0 || (long)inOffset + inLen > in.length || outOffset < 0 || (long)outOffset + inLen > out.length) throw new ArrayIndexOutOfBoundsException(getAlgorithm() + ": Arguments to native_crypt would cause a buffer overflow"); // In future, we may pass more than one block to native_crypt to reduce // native method overhead. for (int i = 0; i < blockCount; i++) { if (0 == native_crypt(native_cookie, in, inOffset, out, outOffset, doEncrypt)) throw new CryptixException(getAlgorithm() + ": Error in native code"); inOffset += BLOCK_SIZE; outOffset += BLOCK_SIZE; } } } else if (doEncrypt) { // state == ENCRYPT for (int i = 0; i < blockCount; i++) { blockEncrypt(in, inOffset, out, outOffset); inOffset += BLOCK_SIZE; outOffset += BLOCK_SIZE; } } else { // state == DECRYPT for (int i = 0; i < blockCount; i++) { blockDecrypt(in, inOffset, out, outOffset); inOffset += BLOCK_SIZE; outOffset += BLOCK_SIZE; } } return inLen; } protected void engineSetParameter(String param, Object value) throws NoSuchParameterException, InvalidParameterException, InvalidParameterTypeException { if (param.equalsIgnoreCase("rounds")) { if (value instanceof Integer) setRounds(((Integer) value).intValue()); else throw new InvalidParameterTypeException("rounds.SAFER"); } else if (param.equalsIgnoreCase("variant")) { if (value instanceof String) setVariant((String) value); else throw new InvalidParameterTypeException("variant.SAFER"); } else throw new NoSuchParameterException(param + ".SAFER"); } protected Object engineGetParameter(String param) throws NoSuchParameterException, InvalidParameterException { if (param.equalsIgnoreCase("rounds")) return new Integer(rounds); else if (param.equalsIgnoreCase("variant")) return getVariant(); else throw new NoSuchParameterException(param + ".SAFER"); }// Own methods//........................................................................... /** * Sets the number of rounds for this cipher. Allowed only when this * cipher is in the UNINITIALIZED state; otherwise an exception is * thrown. * <p> * If the specified number is invalid, the current one remains unchanged. * * @param rounds the desired number of rounds for this cipher. * @throw IllegalStateException if this cipher is not uninitialised. */ public void setRounds(int rounds) { if (getState() != UNINITIALIZED) throw new IllegalStateException("Cipher not in UNINITIALIZED state"); if (rounds > 0 && rounds <= MAX_NOF_ROUNDS) this.rounds = rounds; else throw new InvalidParameterException(); } /** * Gets the number of rounds for this cipher. */ public int getRounds() { return rounds; } /** * Sets the variant for this cipher. Allowed only when this cipher is in * the UNINITIALIZED state; otherwise an exception is thrown. *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -