All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.isaichkindanila.crypt.lib.cipher.StreamCipher Maven / Gradle / Ivy

There is a newer version: 1.1.1
Show newest version
package com.github.isaichkindanila.crypt.lib.cipher;

/**
 * Class representing stream ciphers.
 */
@SuppressWarnings("WeakerAccess")
public abstract class StreamCipher {
    /**
     * Expected key length in bytes.
     */
    public static final int KEY_LENGTH = 32;

    /**
     * Expected initialization vector length in bytes.
     */
    public static final int IV_LENGTH = 16;

    private byte[] key;
    private byte[] iv;

    private byte[] block;
    private int index;

    /**
     * Initializes stream cipher with given key and initialization vector.
     *
     * @param key 32-byte long key
     * @param iv  16-byte long initialization vector
     */
    protected abstract void init0(byte[] key, byte[] iv);

    /**
     * Computes and returns next block of keystream.
     * 

* Returned array must be not {@code null} and have length greater than 0. * * @return next block of keystream */ protected abstract byte[] nextBlock(); private byte[] copyOfLength(byte[] source, int length) { byte[] result = new byte[length]; System.arraycopy(source, 0, result, 0, Math.min(source.length, result.length)); return result; } /** * Used to initialize (or reinitialize) stream cipher with given key and initialization vector. *

* Key is expected to be 256-bit long (32-byte long), * and will be truncated or expanded if necessary. *

* Initialization vector is expected to be 128-bit long (16-byte long), * and will be truncated or expanded if necessary. * * @param key cipher key * @param iv initialization vector */ public final void init(byte[] key, byte[] iv) { if (key.length != KEY_LENGTH) { key = copyOfLength(key, KEY_LENGTH); } if (iv.length != IV_LENGTH) { iv = copyOfLength(iv, IV_LENGTH); } this.key = key; this.iv = iv; this.block = new byte[0]; this.index = 0; init0(key, iv); } /** * Encrypts/decrypts a byte. * * @param b byte to encrypt/decrypt * @return encrypted/decrypted byte */ public final byte apply(byte b) { if (index == block.length) { index = 0; block = nextBlock(); } return (byte) (b ^ block[index++]); } /** * Encrypts/decrypts byte array. * * @param bytes byte array to encrypt/decrypt */ public final void apply(byte[] bytes) { apply(bytes, 0, bytes.length); } /** * Encrypts/decrypts byte array. * * @param bytes byte array to encrypt/decrypt * @param offset the start offset in array * @param length the number of bytes to encrypt/decrypt */ public final void apply(byte[] bytes, int offset, int length) { for (int i = offset; i < offset + length; i++) { bytes[i] = apply(bytes[i]); } } /** * Returns 256-bit long (32-byte long) key of this cipher. * * @return key of this cipher */ public final byte[] getKey() { return key; } /** * Return 128-bit long (16-byte long) initialization vector of this cipher. * * @return initialization vector of this cipher */ public final byte[] getIV() { return iv; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy