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

org.bouncycastle.crypto.digests.CSHAKEDigest 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.digests;

import org.bouncycastle.crypto.CryptoServicePurpose;
import org.bouncycastle.util.Arrays;

/**
 * Customizable SHAKE function.
 */
public class CSHAKEDigest
    extends SHAKEDigest
{
    private static final byte[] padding = new byte[100];
    private final byte[] diff;

    /**
     * Base constructor.
     *
     * @param bitLength security strength (in bits) of the underlying SHAKE function, 128 or 256.
     * @param N         the function name string, note this is reserved for use by NIST. Avoid using it if not required.
     * @param S         the customization string - available for local use.
     */
    public CSHAKEDigest(int bitLength, byte[] N, byte[] S)
    {
        this(bitLength, CryptoServicePurpose.ANY, N, S);
    }

    /**
     * Base constructor.
     *
     * @param bitLength security strength (in bits) of the underlying SHAKE function, 128 or 256.
     * @param purpose   the purpose for constructing the CSHAKEDigest
     * @param N         the function name string, note this is reserved for use by NIST. Avoid using it if not required.
     * @param S         the customization string - available for local use.
     */
    public CSHAKEDigest(int bitLength, CryptoServicePurpose purpose, byte[] N, byte[] S)
    {
        super(bitLength, purpose);

        if ((N == null || N.length == 0) && (S == null || S.length == 0))
        {
            diff = null;
        }
        else
        {
            diff = Arrays.concatenate(XofUtils.leftEncode(rate / 8), encodeString(N), encodeString(S));
            diffPadAndAbsorb();
        }
    }

    public CSHAKEDigest(CSHAKEDigest source)
    {
        super(source);

        this.diff = Arrays.clone(source.diff);
    }

    // bytepad in SP 800-185
    private void diffPadAndAbsorb()
    {
        int blockSize = rate / 8;
        absorb(diff, 0, diff.length);

        int delta = diff.length % blockSize;

        // only add padding if needed
        if (delta != 0)
        {
            int required = blockSize - delta;

            while (required > padding.length)
            {
                absorb(padding, 0, padding.length);
                required -= padding.length;
            }

            absorb(padding, 0, required);
        }
    }

    private byte[] encodeString(byte[] str)
    {
        if (str == null || str.length == 0)
        {
            return XofUtils.leftEncode(0);
        }

        return Arrays.concatenate(XofUtils.leftEncode(str.length * 8L), str);
    }

    public String getAlgorithmName()
    {
        return "CSHAKE" + fixedOutputLength;
    }

    public int doOutput(byte[] out, int outOff, int outLen)
    {
        if (diff != null)
        {
            if (!squeezing)
            {
                absorbBits(0x00, 2);
            }

            squeeze(out, outOff, ((long)outLen) * 8);

            return outLen;
        }
        else
        {
            return super.doOutput(out, outOff, outLen);
        }
    }

    public void reset()
    {
        super.reset();

        if (diff != null)
        {
            diffPadAndAbsorb();
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy