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

org.bouncycastle.crypto.macs.KMAC 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 Java 1.8 and later with debug enabled.

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

import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.crypto.Mac;
import org.bouncycastle.crypto.Xof;
import org.bouncycastle.crypto.digests.CSHAKEDigest;
import org.bouncycastle.crypto.digests.XofUtils;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.Strings;

/**
 * KMAC - MAC with optional XOF mode.
 * 

* From NIST Special Publication 800-185 - SHA-3 Derived Functions:cSHAKE, KMAC, TupleHash and ParallelHash *

*/ public class KMAC implements Mac, Xof { private static final byte[] padding = new byte[100]; private final CSHAKEDigest cshake; private final int bitLength; private final int outputLength; private byte[] key; private boolean initialised; private boolean firstOutput; /** * Base constructor. * * @param bitLength bit length of the underlying SHAKE function, 128 or 256. * @param S the customization string - available for local use. */ public KMAC(int bitLength, byte[] S) { this.cshake = new CSHAKEDigest(bitLength, Strings.toByteArray("KMAC"), S); this.bitLength = bitLength; this.outputLength = bitLength * 2 / 8; } public void init(CipherParameters params) throws IllegalArgumentException { KeyParameter kParam = (KeyParameter)params; this.key = Arrays.clone(kParam.getKey()); this.initialised = true; reset(); } public String getAlgorithmName() { return "KMAC" + cshake.getAlgorithmName().substring(6); } public int getByteLength() { return cshake.getByteLength(); } public int getMacSize() { return outputLength; } public int getDigestSize() { return outputLength; } public void update(byte in) throws IllegalStateException { if (!initialised) { throw new IllegalStateException("KMAC not initialized"); } cshake.update(in); } public void update(byte[] in, int inOff, int len) throws DataLengthException, IllegalStateException { if (!initialised) { throw new IllegalStateException("KMAC not initialized"); } cshake.update(in, inOff, len); } public int doFinal(byte[] out, int outOff) throws DataLengthException, IllegalStateException { if (firstOutput) { if (!initialised) { throw new IllegalStateException("KMAC not initialized"); } byte[] encOut = XofUtils.rightEncode(getMacSize() * 8); cshake.update(encOut, 0, encOut.length); } int rv = cshake.doFinal(out, outOff, getMacSize()); reset(); return rv; } public int doFinal(byte[] out, int outOff, int outLen) { if (firstOutput) { if (!initialised) { throw new IllegalStateException("KMAC not initialized"); } byte[] encOut = XofUtils.rightEncode(outLen * 8); cshake.update(encOut, 0, encOut.length); } int rv = cshake.doFinal(out, outOff, outLen); reset(); return rv; } public int doOutput(byte[] out, int outOff, int outLen) { if (firstOutput) { if (!initialised) { throw new IllegalStateException("KMAC not initialized"); } byte[] encOut = XofUtils.rightEncode(0); cshake.update(encOut, 0, encOut.length); firstOutput = false; } return cshake.doOutput(out, outOff, outLen); } public void reset() { cshake.reset(); if (key != null) { if (bitLength == 128) { bytePad(key, 168); } else { bytePad(key, 136); } } firstOutput = true; } private void bytePad(byte[] X, int w) { byte[] bytes = XofUtils.leftEncode(w); update(bytes, 0, bytes.length); byte[] encX = encode(X); update(encX, 0, encX.length); int required = w - ((bytes.length + encX.length) % w); if (required > 0 && required != w) { while (required > padding.length) { update(padding, 0, padding.length); required -= padding.length; } update(padding, 0, required); } } private static byte[] encode(byte[] X) { return Arrays.concatenate(XofUtils.leftEncode(X.length * 8), X); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy