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

org.bouncycastle.crypto.engines.ISAPEngine Maven / Gradle / Ivy

Go to download

The Bouncy Castle Crypto package is a Java implementation of cryptographic algorithms. This jar contains JCE provider and lightweight API for the Bouncy Castle Cryptography APIs for JDK 1.5 to JDK 1.8.

The newest version!
package org.bouncycastle.crypto.engines;

import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.Pack;

/**
 * ISAP AEAD v2, https://isap.iaik.tugraz.at/
 * https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/finalist-round/updated-spec-doc/isap-spec-final.pdf
 * 

* ISAP AEAD v2 with reference to C Reference Impl from: https://github.com/isap-lwc/isap-code-package *

*/ public class ISAPEngine extends AEADBufferBaseEngine { public enum IsapType { ISAP_A_128A, ISAP_K_128A, ISAP_A_128, ISAP_K_128 } public ISAPEngine(IsapType isapType) { KEY_SIZE = 16; IV_SIZE = 16; MAC_SIZE = 16; switch (isapType) { case ISAP_A_128A: ISAPAEAD = new ISAPAEAD_A_128A(); algorithmName = "ISAP-A-128A AEAD"; break; case ISAP_K_128A: ISAPAEAD = new ISAPAEAD_K_128A(); algorithmName = "ISAP-K-128A AEAD"; break; case ISAP_A_128: ISAPAEAD = new ISAPAEAD_A_128(); algorithmName = "ISAP-A-128 AEAD"; break; case ISAP_K_128: ISAPAEAD = new ISAPAEAD_K_128(); algorithmName = "ISAP-K-128 AEAD"; break; } AADBufferSize = BlockSize; m_aad = new byte[AADBufferSize]; } final int ISAP_STATE_SZ = 40; private byte[] k; private byte[] npub; private int ISAP_rH; private ISAP_AEAD ISAPAEAD; private interface ISAP_AEAD { void init(); void reset(); void absorbMacBlock(byte[] input, int inOff); void absorbFinalAADBlock(); void swapInternalState(); void processEncBlock(byte[] input, int inOff, byte[] output, int outOff); void processEncFinalBlock(byte[] output, int outOff); void processMACFinal(byte[] input, int inOff, int len, byte[] tag); } private abstract class ISAPAEAD_A implements ISAP_AEAD { protected long[] k64; protected long[] npub64; protected long ISAP_IV1_64; protected long ISAP_IV2_64; protected long ISAP_IV3_64; protected long x0, x1, x2, x3, x4, t0, t1, t2, t3, t4, macx0, macx1, macx2, macx3, macx4; public ISAPAEAD_A() { ISAP_rH = 64; BlockSize = (ISAP_rH + 7) >> 3; } public void init() { npub64 = new long[getLongSize(npub.length)]; k64 = new long[getLongSize(k.length)]; Pack.bigEndianToLong(npub, 0, npub64); Pack.bigEndianToLong(k, 0, k64); //reset(); } protected abstract void PX1(); protected abstract void PX2(); public void swapInternalState() { t0 = x0; t1 = x1; t2 = x2; t3 = x3; t4 = x4; x0 = macx0; x1 = macx1; x2 = macx2; x3 = macx3; x4 = macx4; macx0 = t0; macx1 = t1; macx2 = t2; macx3 = t3; macx4 = t4; } public void absorbMacBlock(byte[] input, int inOff) { x0 ^= Pack.bigEndianToLong(input, inOff); P12(); } public void absorbFinalAADBlock() { if (m_aadPos == AADBufferSize) { absorbMacBlock(m_aad, 0); m_aadPos = 0; } else { for (int i = 0; i < m_aadPos; ++i) { x0 ^= (m_aad[i] & 0xFFL) << ((7 - i) << 3); } } x0 ^= 0x80L << ((7 - m_aadPos) << 3); P12(); x4 ^= 1L; } public void processMACFinal(byte[] input, int inOff, int len, byte[] tag) { if (len == BlockSize) { absorbMacBlock(input, inOff); len = 0; } else { for (int i = 0; i < len; ++i) { x0 ^= (input[inOff++] & 0xFFL) << ((7 - i) << 3); } } x0 ^= 0x80L << ((7 - len) << 3); P12(); // Derive K* Pack.longToBigEndian(x0, tag, 0); Pack.longToBigEndian(x1, tag, 8); long tmp_x2 = x2, tmp_x3 = x3, tmp_x4 = x4; isap_rk(ISAP_IV2_64, tag, KEY_SIZE); x2 = tmp_x2; x3 = tmp_x3; x4 = tmp_x4; // Squeeze tag P12(); Pack.longToBigEndian(x0, tag, 0); Pack.longToBigEndian(x1, tag, 8); } public void isap_rk(long iv64, byte[] y, int ylen) { // Init state x0 = k64[0]; x1 = k64[1]; x2 = iv64; x3 = x4 = 0; P12(); // Absorb Y for (int i = 0; i < (ylen << 3) - 1; i++) { x0 ^= ((((y[i >>> 3] >>> (7 - (i & 7))) & 0x01) << 7) & 0xFFL) << 56; PX2(); } x0 ^= (((y[ylen - 1]) & 0x01L) << 7) << 56; P12(); } public void processEncBlock(byte[] input, int inOff, byte[] output, int outOff) { long m64 = Pack.littleEndianToLong(input, inOff); long c64 = U64BIG(x0) ^ m64; PX1(); Pack.longToLittleEndian(c64, output, outOff); } public void processEncFinalBlock(byte[] output, int outOff) { if (m_bufPos == BlockSize) { processEncBlock(m_buf, 0, output, outOff); } else { /* Encrypt final m block */ byte[] xo = Pack.longToLittleEndian(x0); int mlen = m_bufPos; while (mlen > 0) { output[outOff + mlen - 1] = (byte)(xo[BlockSize - mlen] ^ m_buf[--mlen]); } } } public void reset() { // Init state isap_rk(ISAP_IV3_64, npub, IV_SIZE); x3 = npub64[0]; x4 = npub64[1]; PX1(); swapInternalState(); // Init State for mac x0 = npub64[0]; x1 = npub64[1]; x2 = ISAP_IV1_64; x3 = x4 = 0; P12(); } private int getLongSize(int x) { return (x >>> 3) + ((x & 7) != 0 ? 1 : 0); } private long ROTR(long x, long n) { return (x >>> n) | (x << (64 - n)); } protected long U64BIG(long x) { return ((ROTR(x, 8) & (0xFF000000FF000000L)) | (ROTR(x, 24) & (0x00FF000000FF0000L)) | (ROTR(x, 40) & (0x0000FF000000FF00L)) | (ROTR(x, 56) & (0x000000FF000000FFL))); } protected void ROUND(long C) { t0 = x0 ^ x1 ^ x2 ^ x3 ^ C ^ (x1 & (x0 ^ x2 ^ x4 ^ C)); t1 = x0 ^ x2 ^ x3 ^ x4 ^ C ^ ((x1 ^ x2 ^ C) & (x1 ^ x3)); t2 = x1 ^ x2 ^ x4 ^ C ^ (x3 & x4); t3 = x0 ^ x1 ^ x2 ^ C ^ ((~x0) & (x3 ^ x4)); t4 = x1 ^ x3 ^ x4 ^ ((x0 ^ x4) & x1); x0 = t0 ^ ROTR(t0, 19) ^ ROTR(t0, 28); x1 = t1 ^ ROTR(t1, 39) ^ ROTR(t1, 61); x2 = ~(t2 ^ ROTR(t2, 1) ^ ROTR(t2, 6)); x3 = t3 ^ ROTR(t3, 10) ^ ROTR(t3, 17); x4 = t4 ^ ROTR(t4, 7) ^ ROTR(t4, 41); } public void P12() { ROUND(0xf0); ROUND(0xe1); ROUND(0xd2); ROUND(0xc3); ROUND(0xb4); ROUND(0xa5); P6(); } protected void P6() { ROUND(0x96); ROUND(0x87); ROUND(0x78); ROUND(0x69); ROUND(0x5a); ROUND(0x4b); } } private class ISAPAEAD_A_128A extends ISAPAEAD_A { public ISAPAEAD_A_128A() { ISAP_IV1_64 = 108156764297430540L; ISAP_IV2_64 = 180214358335358476L; ISAP_IV3_64 = 252271952373286412L; } protected void PX1() { P6(); } protected void PX2() { ROUND(0x4b); } } private class ISAPAEAD_A_128 extends ISAPAEAD_A { public ISAPAEAD_A_128() { ISAP_IV1_64 = 108156764298152972L; ISAP_IV2_64 = 180214358336080908L; ISAP_IV3_64 = 252271952374008844L; } protected void PX1() { P12(); } protected void PX2() { P12(); } } private abstract class ISAPAEAD_K implements ISAP_AEAD { final int ISAP_STATE_SZ_CRYPTO_NPUBBYTES = ISAP_STATE_SZ - IV_SIZE; protected short[] ISAP_IV1_16; protected short[] ISAP_IV2_16; protected short[] ISAP_IV3_16; protected short[] k16; protected short[] iv16; private final int[] KeccakF400RoundConstants = {0x0001, 0x8082, 0x808a, 0x8000, 0x808b, 0x0001, 0x8081, 0x8009, 0x008a, 0x0088, 0x8009, 0x000a, 0x808b, 0x008b, 0x8089, 0x8003, 0x8002, 0x0080, 0x800a, 0x000a}; protected short[] SX = new short[25]; protected short[] macSX = new short[25]; protected short[] E = new short[25]; protected short[] C = new short[5]; protected short[] macE = new short[25]; protected short[] macC = new short[5]; public ISAPAEAD_K() { ISAP_rH = 144; BlockSize = (ISAP_rH + 7) >> 3; } public void init() { k16 = new short[k.length >> 1]; byteToShort(k, k16, k16.length); iv16 = new short[npub.length >> 1]; byteToShort(npub, iv16, iv16.length); //reset(); } public void reset() { // Init state Arrays.fill(SX, (byte)0); isap_rk(ISAP_IV3_16, npub, IV_SIZE, SX, ISAP_STATE_SZ_CRYPTO_NPUBBYTES, C); System.arraycopy(iv16, 0, SX, 17, 8); PermuteRoundsKX(SX, E, C); // Init state for mac swapInternalState(); Arrays.fill(SX, 12, 25, (short)0); System.arraycopy(iv16, 0, SX, 0, 8); System.arraycopy(ISAP_IV1_16, 0, SX, 8, 4); PermuteRoundsHX(SX, E, C); } public void swapInternalState() { short[] tmp = SX; SX = macSX; macSX = tmp; tmp = E; E = macE; macE = tmp; tmp = C; C = macC; macC = tmp; } protected abstract void PermuteRoundsHX(short[] SX, short[] E, short[] C); protected abstract void PermuteRoundsKX(short[] SX, short[] E, short[] C); protected abstract void PermuteRoundsBX(short[] SX, short[] E, short[] C); public void absorbMacBlock(byte[] input, int inOff) { byteToShortXor(input, inOff, SX, BlockSize >> 1); PermuteRoundsHX(SX, E, C); } public void absorbFinalAADBlock() { if (m_aadPos == AADBufferSize) { absorbMacBlock(m_aad, 0); m_aadPos = 0; } else { for (int i = 0; i < m_aadPos; i++) { SX[i >> 1] ^= (m_aad[i] & 0xFF) << ((i & 1) << 3); } } SX[m_aadPos >> 1] ^= 0x80 << ((m_aadPos & 1) << 3); PermuteRoundsHX(SX, E, C); // Domain seperation SX[24] ^= 0x0100; } public void isap_rk(short[] iv16, byte[] y, int ylen, short[] out16, int outlen, short[] C) { // Init state short[] SX = new short[25]; short[] E = new short[25]; System.arraycopy(k16, 0, SX, 0, 8); System.arraycopy(iv16, 0, SX, 8, 4); PermuteRoundsKX(SX, E, C); // Absorb all bits of Y for (int i = 0; i < (ylen << 3) - 1; i++) { SX[0] ^= (((y[i >> 3] >>> (7 - (i & 7))) & 0x01) << 7); PermuteRoundsBX(SX, E, C); } SX[0] ^= (((y[ylen - 1]) & 0x01) << 7); PermuteRoundsKX(SX, E, C); // Extract K* System.arraycopy(SX, 0, out16, 0, outlen == ISAP_STATE_SZ_CRYPTO_NPUBBYTES ? 17 : 8); } public void processMACFinal(byte[] input, int inOff, int len, byte[] tag) { if (len == BlockSize) { absorbMacBlock(input, inOff); len = 0; } else { // Absorb C final block for (int i = 0; i < len; i++) { SX[i >> 1] ^= (input[inOff++] & 0xFF) << ((i & 1) << 3); } } SX[len >> 1] ^= 0x80 << ((len & 1) << 3); PermuteRoundsHX(SX, E, C); // Derive K* shortToByte(SX, tag); isap_rk(ISAP_IV2_16, tag, KEY_SIZE, SX, KEY_SIZE, C); // Squeeze tag PermuteRoundsHX(SX, E, C); shortToByte(SX, tag); } public void processEncBlock(byte[] input, int inOff, byte[] output, int outOff) { for (int i = 0; i < BlockSize; ++i) { output[outOff++] = (byte)((SX[i >> 1] >>> ((i & 1) << 3)) ^ input[inOff++]); } PermuteRoundsKX(SX, E, C); } public void processEncFinalBlock(byte[] output, int outOff) { // Squeeze full or partial lane and stop int len = m_bufPos; for (int i = 0; i < len; ++i) { output[outOff++] = (byte)((SX[i >> 1] >>> ((i & 1) << 3)) ^ m_buf[i]); } } private void byteToShortXor(byte[] input, int inOff, short[] output, int outLen) { for (int i = 0; i < outLen; ++i) { output[i] ^= Pack.littleEndianToShort(input, inOff + (i << 1)); } } private void byteToShort(byte[] input, short[] output, int outLen) { for (int i = 0; i < outLen; ++i) { output[i] = Pack.littleEndianToShort(input, (i << 1)); } } private void shortToByte(short[] input, byte[] output) { for (int i = 0; i < 8; ++i) { Pack.shortToLittleEndian(input[i], output, (i << 1)); } } protected void rounds12X(short[] SX, short[] E, short[] C) { prepareThetaX(SX, C); rounds_8_18(SX, E, C); } protected void rounds_4_18(short[] SX, short[] E, short[] C) { thetaRhoPiChiIotaPrepareTheta(4, SX, E, C); thetaRhoPiChiIotaPrepareTheta(5, E, SX, C); thetaRhoPiChiIotaPrepareTheta(6, SX, E, C); thetaRhoPiChiIotaPrepareTheta(7, E, SX, C); rounds_8_18(SX, E, C); } protected void rounds_8_18(short[] SX, short[] E, short[] C) { thetaRhoPiChiIotaPrepareTheta(8, SX, E, C); thetaRhoPiChiIotaPrepareTheta(9, E, SX, C); thetaRhoPiChiIotaPrepareTheta(10, SX, E, C); thetaRhoPiChiIotaPrepareTheta(11, E, SX, C); rounds_12_18(SX, E, C); } protected void rounds_12_18(short[] SX, short[] E, short[] C) { thetaRhoPiChiIotaPrepareTheta(12, SX, E, C); thetaRhoPiChiIotaPrepareTheta(13, E, SX, C); thetaRhoPiChiIotaPrepareTheta(14, SX, E, C); thetaRhoPiChiIotaPrepareTheta(15, E, SX, C); thetaRhoPiChiIotaPrepareTheta(16, SX, E, C); thetaRhoPiChiIotaPrepareTheta(17, E, SX, C); thetaRhoPiChiIotaPrepareTheta(18, SX, E, C); thetaRhoPiChiIota(E, SX, C); } protected void prepareThetaX(short[] SX, short[] C) { C[0] = (short)(SX[0] ^ SX[5] ^ SX[10] ^ SX[15] ^ SX[20]); C[1] = (short)(SX[1] ^ SX[6] ^ SX[11] ^ SX[16] ^ SX[21]); C[2] = (short)(SX[2] ^ SX[7] ^ SX[12] ^ SX[17] ^ SX[22]); C[3] = (short)(SX[3] ^ SX[8] ^ SX[13] ^ SX[18] ^ SX[23]); C[4] = (short)(SX[4] ^ SX[9] ^ SX[14] ^ SX[19] ^ SX[24]); } private short ROL16(short a, int offset) { return (short)(((a & 0xFFFF) << offset) ^ ((a & 0xFFFF) >>> (16 - offset))); } protected void thetaRhoPiChiIotaPrepareTheta(int i, short[] A, short[] E, short[] C) { short Da = (short)(C[4] ^ ROL16(C[1], 1)); short De = (short)(C[0] ^ ROL16(C[2], 1)); short Di = (short)(C[1] ^ ROL16(C[3], 1)); short Do = (short)(C[2] ^ ROL16(C[4], 1)); short Du = (short)(C[3] ^ ROL16(C[0], 1)); short Ba = A[0] ^= Da; A[6] ^= De; short Be = ROL16(A[6], 12); A[12] ^= Di; short Bi = ROL16(A[12], 11); A[18] ^= Do; short Bo = ROL16(A[18], 5); A[24] ^= Du; short Bu = ROL16(A[24], 14); C[0] = E[0] = (short)(Ba ^ ((~Be) & Bi) ^ KeccakF400RoundConstants[i]); C[1] = E[1] = (short)(Be ^ ((~Bi) & Bo)); C[2] = E[2] = (short)(Bi ^ ((~Bo) & Bu)); C[3] = E[3] = (short)(Bo ^ ((~Bu) & Ba)); C[4] = E[4] = (short)(Bu ^ ((~Ba) & Be)); A[3] ^= Do; Ba = ROL16(A[3], 12); A[9] ^= Du; Be = ROL16(A[9], 4); A[10] ^= Da; Bi = ROL16(A[10], 3); A[16] ^= De; Bo = ROL16(A[16], 13); A[22] ^= Di; Bu = ROL16(A[22], 13); E[5] = (short)(Ba ^ ((~Be) & Bi)); C[0] ^= E[5]; E[6] = (short)(Be ^ ((~Bi) & Bo)); C[1] ^= E[6]; E[7] = (short)(Bi ^ ((~Bo) & Bu)); C[2] ^= E[7]; E[8] = (short)(Bo ^ ((~Bu) & Ba)); C[3] ^= E[8]; E[9] = (short)(Bu ^ ((~Ba) & Be)); C[4] ^= E[9]; A[1] ^= De; Ba = ROL16(A[1], 1); A[7] ^= Di; Be = ROL16(A[7], 6); A[13] ^= Do; Bi = ROL16(A[13], 9); A[19] ^= Du; Bo = ROL16(A[19], 8); A[20] ^= Da; Bu = ROL16(A[20], 2); E[10] = (short)(Ba ^ ((~Be) & Bi)); C[0] ^= E[10]; E[11] = (short)(Be ^ ((~Bi) & Bo)); C[1] ^= E[11]; E[12] = (short)(Bi ^ ((~Bo) & Bu)); C[2] ^= E[12]; E[13] = (short)(Bo ^ ((~Bu) & Ba)); C[3] ^= E[13]; E[14] = (short)(Bu ^ ((~Ba) & Be)); C[4] ^= E[14]; A[4] ^= Du; Ba = ROL16(A[4], 11); A[5] ^= Da; Be = ROL16(A[5], 4); A[11] ^= De; Bi = ROL16(A[11], 10); A[17] ^= Di; Bo = ROL16(A[17], 15); A[23] ^= Do; Bu = ROL16(A[23], 8); E[15] = (short)(Ba ^ ((~Be) & Bi)); C[0] ^= E[15]; E[16] = (short)(Be ^ ((~Bi) & Bo)); C[1] ^= E[16]; E[17] = (short)(Bi ^ ((~Bo) & Bu)); C[2] ^= E[17]; E[18] = (short)(Bo ^ ((~Bu) & Ba)); C[3] ^= E[18]; E[19] = (short)(Bu ^ ((~Ba) & Be)); C[4] ^= E[19]; A[2] ^= Di; Ba = ROL16(A[2], 14); A[8] ^= Do; Be = ROL16(A[8], 7); A[14] ^= Du; Bi = ROL16(A[14], 7); A[15] ^= Da; Bo = ROL16(A[15], 9); A[21] ^= De; Bu = ROL16(A[21], 2); E[20] = (short)(Ba ^ ((~Be) & Bi)); C[0] ^= E[20]; E[21] = (short)(Be ^ ((~Bi) & Bo)); C[1] ^= E[21]; E[22] = (short)(Bi ^ ((~Bo) & Bu)); C[2] ^= E[22]; E[23] = (short)(Bo ^ ((~Bu) & Ba)); C[3] ^= E[23]; E[24] = (short)(Bu ^ ((~Ba) & Be)); C[4] ^= E[24]; } protected void thetaRhoPiChiIota(short[] A, short[] E, short[] C) { short Da = (short)(C[4] ^ ROL16(C[1], 1)); short De = (short)(C[0] ^ ROL16(C[2], 1)); short Di = (short)(C[1] ^ ROL16(C[3], 1)); short Do = (short)(C[2] ^ ROL16(C[4], 1)); short Du = (short)(C[3] ^ ROL16(C[0], 1)); short Ba = A[0] ^= Da; A[6] ^= De; short Be = ROL16(A[6], 12); A[12] ^= Di; short Bi = ROL16(A[12], 11); A[18] ^= Do; short Bo = ROL16(A[18], 5); A[24] ^= Du; short Bu = ROL16(A[24], 14); E[0] = (short)(Ba ^ ((~Be) & Bi) ^ KeccakF400RoundConstants[19]); E[1] = (short)(Be ^ ((~Bi) & Bo)); E[2] = (short)(Bi ^ ((~Bo) & Bu)); E[3] = (short)(Bo ^ ((~Bu) & Ba)); E[4] = (short)(Bu ^ ((~Ba) & Be)); A[3] ^= Do; Ba = ROL16(A[3], 12); A[9] ^= Du; Be = ROL16(A[9], 4); A[10] ^= Da; Bi = ROL16(A[10], 3); A[16] ^= De; Bo = ROL16(A[16], 13); A[22] ^= Di; Bu = ROL16(A[22], 13); E[5] = (short)(Ba ^ ((~Be) & Bi)); E[6] = (short)(Be ^ ((~Bi) & Bo)); E[7] = (short)(Bi ^ ((~Bo) & Bu)); E[8] = (short)(Bo ^ ((~Bu) & Ba)); E[9] = (short)(Bu ^ ((~Ba) & Be)); A[1] ^= De; Ba = ROL16(A[1], 1); A[7] ^= Di; Be = ROL16(A[7], 6); A[13] ^= Do; Bi = ROL16(A[13], 9); A[19] ^= Du; Bo = ROL16(A[19], 8); A[20] ^= Da; Bu = ROL16(A[20], 2); E[10] = (short)(Ba ^ ((~Be) & Bi)); E[11] = (short)(Be ^ ((~Bi) & Bo)); E[12] = (short)(Bi ^ ((~Bo) & Bu)); E[13] = (short)(Bo ^ ((~Bu) & Ba)); E[14] = (short)(Bu ^ ((~Ba) & Be)); A[4] ^= Du; Ba = ROL16(A[4], 11); A[5] ^= Da; Be = ROL16(A[5], 4); A[11] ^= De; Bi = ROL16(A[11], 10); A[17] ^= Di; Bo = ROL16(A[17], 15); A[23] ^= Do; Bu = ROL16(A[23], 8); E[15] = (short)(Ba ^ ((~Be) & Bi)); E[16] = (short)(Be ^ ((~Bi) & Bo)); E[17] = (short)(Bi ^ ((~Bo) & Bu)); E[18] = (short)(Bo ^ ((~Bu) & Ba)); E[19] = (short)(Bu ^ ((~Ba) & Be)); A[2] ^= Di; Ba = ROL16(A[2], 14); A[8] ^= Do; Be = ROL16(A[8], 7); A[14] ^= Du; Bi = ROL16(A[14], 7); A[15] ^= Da; Bo = ROL16(A[15], 9); A[21] ^= De; Bu = ROL16(A[21], 2); E[20] = (short)(Ba ^ ((~Be) & Bi)); E[21] = (short)(Be ^ ((~Bi) & Bo)); E[22] = (short)(Bi ^ ((~Bo) & Bu)); E[23] = (short)(Bo ^ ((~Bu) & Ba)); E[24] = (short)(Bu ^ ((~Ba) & Be)); } } private class ISAPAEAD_K_128A extends ISAPAEAD_K { public ISAPAEAD_K_128A() { ISAP_IV1_16 = new short[]{-32767, 400, 272, 2056}; ISAP_IV2_16 = new short[]{-32766, 400, 272, 2056}; ISAP_IV3_16 = new short[]{-32765, 400, 272, 2056}; } protected void PermuteRoundsHX(short[] SX, short[] E, short[] C) { prepareThetaX(SX, C); rounds_4_18(SX, E, C); } protected void PermuteRoundsKX(short[] SX, short[] E, short[] C) { prepareThetaX(SX, C); rounds_12_18(SX, E, C); } protected void PermuteRoundsBX(short[] SX, short[] E, short[] C) { prepareThetaX(SX, C); thetaRhoPiChiIotaPrepareTheta(19, SX, E, C); System.arraycopy(E, 0, SX, 0, E.length); } } private class ISAPAEAD_K_128 extends ISAPAEAD_K { public ISAPAEAD_K_128() { ISAP_IV1_16 = new short[]{-32767, 400, 3092, 3084}; ISAP_IV2_16 = new short[]{-32766, 400, 3092, 3084}; ISAP_IV3_16 = new short[]{-32765, 400, 3092, 3084}; } protected void PermuteRoundsHX(short[] SX, short[] E, short[] C) { prepareThetaX(SX, C); thetaRhoPiChiIotaPrepareTheta(0, SX, E, C); thetaRhoPiChiIotaPrepareTheta(1, E, SX, C); thetaRhoPiChiIotaPrepareTheta(2, SX, E, C); thetaRhoPiChiIotaPrepareTheta(3, E, SX, C); rounds_4_18(SX, E, C); } protected void PermuteRoundsKX(short[] SX, short[] E, short[] C) { rounds12X(SX, E, C); } protected void PermuteRoundsBX(short[] SX, short[] E, short[] C) { rounds12X(SX, E, C); } } @Override protected void init(byte[] key, byte[] iv) throws IllegalArgumentException { npub = iv; k = key; m_buf = new byte[BlockSize + (forEncryption ? 0 : MAC_SIZE)]; ISAPAEAD.init(); initialised = true; m_state = forEncryption ? State.EncInit : State.DecInit; reset(); } protected void processBufferAAD(byte[] input, int inOff) { ISAPAEAD.absorbMacBlock(input, inOff); } protected void processFinalAAD() { if (!aadFinished) { ISAPAEAD.absorbFinalAADBlock(); ISAPAEAD.swapInternalState(); m_aadPos = 0; aadFinished = true; } } protected void processBuffer(byte[] input, int inOff, byte[] output, int outOff) { processFinalAAD(); ISAPAEAD.processEncBlock(input, inOff, output, outOff); ISAPAEAD.swapInternalState(); if (forEncryption) { ISAPAEAD.absorbMacBlock(output, outOff); } else { ISAPAEAD.absorbMacBlock(input, inOff); } ISAPAEAD.swapInternalState(); } @Override protected void processFinalBlock(byte[] output, int outOff) { processFinalAAD(); int len = m_bufPos; mac = new byte[MAC_SIZE]; ISAPAEAD.processEncFinalBlock(output, outOff); ISAPAEAD.swapInternalState(); if (forEncryption) { ISAPAEAD.processMACFinal(output, outOff, len, mac); } else { ISAPAEAD.processMACFinal(m_buf, 0, len, mac); } } protected void reset(boolean clearMac) { if (!initialised) { throw new IllegalStateException("Need call init function before encryption/decryption"); } Arrays.fill(m_buf, (byte)0); Arrays.fill(m_aad, (byte)0); ISAPAEAD.reset(); m_bufPos = 0; m_aadPos = 0; aadFinished = false; super.reset(clearMac); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy