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

org.bouncycastle.crypto.engines.AsconEngine 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.crypto.CipherParameters;
import org.bouncycastle.util.Pack;

/**
 * The {@code AsconEngine} class provides an implementation of ASCON AEAD version 1.2,
 * based on the official specification available at:
 * https://ascon.iaik.tugraz.at/ and the
 * updated specification document from the NIST competition:
 * 
 * ASCON Specification (Finalist Round)
 * .
 * 

* This version references the C reference implementation provided by NIST, available at: * * ASCON C Reference Implementation (NIST Round 2) * . *

* @deprecated Now superseded. Please refer to {@code AsconAEAD128Engine} for future implementations. */ public class AsconEngine extends AsconBaseEngine { public enum AsconParameters { ascon80pq, ascon128a, ascon128 } private final AsconParameters asconParameters; private long K2; public AsconEngine(AsconParameters asconParameters) { this.asconParameters = asconParameters; IV_SIZE = 16; MAC_SIZE = 16; switch (asconParameters) { case ascon80pq: KEY_SIZE = 20; ASCON_AEAD_RATE = 8; ASCON_IV = 0xa0400c0600000000L; algorithmName = "Ascon-80pq AEAD"; break; case ascon128a: KEY_SIZE = 16; ASCON_AEAD_RATE = 16; ASCON_IV = 0x80800c0800000000L; algorithmName = "Ascon-128a AEAD"; break; case ascon128: KEY_SIZE = 16; ASCON_AEAD_RATE = 8; ASCON_IV = 0x80400c0600000000L; algorithmName = "Ascon-128 AEAD"; break; default: throw new IllegalArgumentException("invalid parameter setting for ASCON AEAD"); } nr = (ASCON_AEAD_RATE == 8) ? 6 : 8; m_bufferSizeDecrypt = ASCON_AEAD_RATE + MAC_SIZE; m_buf = new byte[m_bufferSizeDecrypt]; dsep = 1L; } protected long pad(int i) { return 0x80L << (56 - (i << 3)); } @Override protected long loadBytes(byte[] in, int inOff) { return Pack.bigEndianToLong(in, inOff); } @Override protected void setBytes(long n, byte[] bs, int off) { Pack.longToBigEndian(n, bs, off); } protected void ascon_aeadinit() { /* initialize */ x0 = ASCON_IV; if (KEY_SIZE == 20) { x0 ^= K0; } x1 = K1; x2 = K2; x3 = N0; x4 = N1; p(12); if (KEY_SIZE == 20) { x2 ^= K0; } x3 ^= K1; x4 ^= K2; } protected void processFinalAadBlock() { m_buf[m_bufPos] = (byte)0x80; if (m_bufPos >= 8) // ASCON_AEAD_RATE == 16 is implied { x0 ^= Pack.bigEndianToLong(m_buf, 0); x1 ^= Pack.bigEndianToLong(m_buf, 8) & (-1L << (56 - ((m_bufPos - 8) << 3))); } else { x0 ^= Pack.bigEndianToLong(m_buf, 0) & (-1L << (56 - (m_bufPos << 3))); } } protected void processFinalDecrypt(byte[] input, int inLen, byte[] output, int outOff) { if (inLen >= 8) // ASCON_AEAD_RATE == 16 is implied { long c0 = Pack.bigEndianToLong(input, 0); x0 ^= c0; Pack.longToBigEndian(x0, output, outOff); x0 = c0; outOff += 8; inLen -= 8; x1 ^= pad(inLen); if (inLen != 0) { long c1 = Pack.littleEndianToLong_High(input, 8, inLen); x1 ^= c1; Pack.longToLittleEndian_High(x1, output, outOff, inLen); x1 &= -1L >>> (inLen << 3); x1 ^= c1; } } else { x0 ^= pad(inLen); if (inLen != 0) { long c0 = Pack.littleEndianToLong_High(input, 0, inLen); x0 ^= c0; Pack.longToLittleEndian_High(x0, output, outOff, inLen); x0 &= -1L >>> (inLen << 3); x0 ^= c0; } } finishData(State.DecFinal); } protected void processFinalEncrypt(byte[] input, int inLen, byte[] output, int outOff) { if (inLen >= 8) // ASCON_AEAD_RATE == 16 is implied { x0 ^= Pack.bigEndianToLong(input, 0); Pack.longToBigEndian(x0, output, outOff); outOff += 8; inLen -= 8; x1 ^= pad(inLen); if (inLen != 0) { x1 ^= Pack.littleEndianToLong_High(input, 8, inLen); Pack.longToLittleEndian_High(x1, output, outOff, inLen); } } else { x0 ^= pad(inLen); if (inLen != 0) { x0 ^= Pack.littleEndianToLong_High(input, 0, inLen); Pack.longToLittleEndian_High(x0, output, outOff, inLen); } } finishData(State.EncFinal); } private void finishData(State nextState) { switch (asconParameters) { case ascon128: x1 ^= K1; x2 ^= K2; break; case ascon128a: x2 ^= K1; x3 ^= K2; break; case ascon80pq: x1 ^= (K0 << 32 | K1 >> 32); x2 ^= (K1 << 32 | K2 >> 32); x3 ^= K2 << 32; break; default: throw new IllegalStateException(); } p(12); x3 ^= K1; x4 ^= K2; m_state = nextState; } protected void init(byte[] key, byte[] iv) throws IllegalArgumentException { N0 = Pack.bigEndianToLong(iv, 0); N1 = Pack.bigEndianToLong(iv, 8); if (KEY_SIZE == 16) { K1 = Pack.bigEndianToLong(key, 0); K2 = Pack.bigEndianToLong(key, 8); } else if (KEY_SIZE == 20) { K0 = Pack.bigEndianToInt(key, 0); K1 = Pack.bigEndianToLong(key, 4); K2 = Pack.bigEndianToLong(key, 12); } else { throw new IllegalStateException(); } m_state = forEncryption ? State.EncInit : State.DecInit; reset(true); } public String getAlgorithmVersion() { return "v1.2"; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy