package org.bouncycastle.crypto.agreement.kdf;

import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.crypto.DerivationFunction;
import org.bouncycastle.crypto.DerivationParameters;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.params.KDFParameters;

/**
 * Generator for Concatenation Key Derivation Function defined in NIST SP 800-56A, Sect 5.8.1
 */
public class ConcatenationKDFGenerator
    implements DerivationFunction
{
    private Digest  digest;
    private byte[]  shared;
    private byte[]  otherInfo;
    private int     hLen;

    /**
     * @param digest the digest to be used as the source of generated bytes
     */
    public ConcatenationKDFGenerator(
        Digest digest)
    {
        this.digest = digest;
        this.hLen = digest.getDigestSize();
    }

    public void init(
        DerivationParameters    param)
    {
        if (param instanceof KDFParameters)
        {
            KDFParameters p = (KDFParameters)param;

            shared = p.getSharedSecret();
            otherInfo = p.getIV();
        }
        else
        {
            throw new IllegalArgumentException("KDF parameters required for generator");
        }
    }

    /**
     * return the underlying digest.
     */
    public Digest getDigest()
    {
        return digest;
    }

    /**
     * int to octet string.
     */
    private void ItoOSP(
        int     i,
        byte[]  sp)
    {
        sp[0] = (byte)(i >>> 24);
        sp[1] = (byte)(i >>> 16);
        sp[2] = (byte)(i >>> 8);
        sp[3] = (byte)(i >>> 0);
    }

    /**
     * fill len bytes of the output buffer with bytes generated from
     * the derivation function.
     *
     * @throws DataLengthException if the out buffer is too small.
     */
    public int generateBytes(
        byte[]  out,
        int     outOff,
        int     len)
        throws DataLengthException, IllegalArgumentException
    {
        if ((out.length - len) < outOff)
        {
            throw new DataLengthException("output buffer too small");
        }

        byte[]  hashBuf = new byte[hLen];
        byte[]  C = new byte[4];
        int     counter = 1;
        int     outputLen = 0;

        digest.reset();

        if (len > hLen)
        {
            do
            {
                ItoOSP(counter, C);

                digest.update(C, 0, C.length);
                digest.update(shared, 0, shared.length);
                digest.update(otherInfo, 0, otherInfo.length);

                digest.doFinal(hashBuf, 0);

                System.arraycopy(hashBuf, 0, out, outOff + outputLen, hLen);
                outputLen += hLen;
            }
            while ((counter++) < (len / hLen));
        }

        if (outputLen < len)
        {
            ItoOSP(counter, C);

            digest.update(C, 0, C.length);
            digest.update(shared, 0, shared.length);
            digest.update(otherInfo, 0, otherInfo.length);

            digest.doFinal(hashBuf, 0);

            System.arraycopy(hashBuf, 0, out, outOff + outputLen, len - outputLen);
        }

        return len;
    }
}
