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

org.bouncycastle.crypto.general.SipHash Maven / Gradle / Ivy

Go to download

The FIPS 140-3 Bouncy Castle Crypto package is a Java implementation of cryptographic algorithms certified to FIPS 140-3 level 1. This jar contains JCE provider and low-level API for the BC-FJA version 2.0.0, FIPS Certificate #4743. Please see certificate for certified platform details.

There is a newer version: 2.0.0
Show newest version
package org.bouncycastle.crypto.general;

import java.security.SecureRandom;

import org.bouncycastle.crypto.Algorithm;
import org.bouncycastle.crypto.AuthenticationParameters;
import org.bouncycastle.crypto.IllegalKeyException;
import org.bouncycastle.crypto.SymmetricKey;
import org.bouncycastle.crypto.SymmetricSecretKey;
import org.bouncycastle.crypto.internal.KeyGenerationParameters;
import org.bouncycastle.crypto.internal.Mac;
import org.bouncycastle.crypto.internal.ValidatedSymmetricKey;
import org.bouncycastle.crypto.internal.macs.TruncatingMac;

/**
 * Source class for implementations of SipHash based algorithms
 */
public final class SipHash
{
    private SipHash()
    {

    }

    public static final GeneralAlgorithm ALGORITHM = new GeneralAlgorithm("SipHash");

    public static final GeneralAlgorithm SIPHASH_2_4 = new GeneralAlgorithm("SipHash-2-4");
    public static final GeneralAlgorithm SIPHASH_4_8 = new GeneralAlgorithm("SipHash-4-8");

    /**
     * Parameters for SipHash MAC modes.
     */
    public static final class AuthParameters
        extends GeneralParameters
        implements AuthenticationParameters
    {
        private final int macSizeInBits;

        private AuthParameters(GeneralAlgorithm algorithm, int macSizeInBits)
        {
            super(algorithm);
            this.macSizeInBits = macSizeInBits;
        }

        public AuthParameters()
        {
            this(SIPHASH_2_4);
        }

        public AuthParameters(GeneralAlgorithm algorithm)
        {
            this(algorithm, 64);
        }

        public int getMACSizeInBits()
        {
            return macSizeInBits;
        }

        public AuthParameters withMACSize(int macSizeInBits)
        {
            return new AuthParameters(this.getAlgorithm(), macSizeInBits);
        }
    }

    /**
     * SipHash key generator.
     */
    public static final class KeyGenerator
        extends GuardedSymmetricKeyGenerator
    {
        private final GeneralAlgorithm algorithm;
        private final SecureRandom random;

        public KeyGenerator(SecureRandom random)
        {
            this(ALGORITHM, random);
        }

        public KeyGenerator(GeneralAlgorithm algorithm, SecureRandom random)
        {
            this.algorithm = algorithm;
            this.random = random;
        }

        public SymmetricKey doGenerateKey()
        {
            CipherKeyGenerator cipherKeyGenerator = new CipherKeyGenerator();

            cipherKeyGenerator.init(new KeyGenerationParameters(random, 128));

            return new SymmetricSecretKey(algorithm, cipherKeyGenerator.generateKey());
        }
    }

    /**
     * Factory for producing SipHash MAC calculators.
     */
    public static final class MACOperatorFactory
        extends GuardedMACOperatorFactory
    {
        @Override
        protected Mac createMAC(SymmetricKey key, final AuthParameters parameters)
        {
            Mac mac = getMac(parameters);
            if (mac.getMacSize() != (parameters.getMACSizeInBits() + 7) / 8)
            {
                mac = new TruncatingMac(mac, parameters.macSizeInBits);
            }

            mac.init(Utils.getKeyParameter(validateKey(key, parameters)));

            return mac;
        }

        private Mac getMac(AuthParameters parameters)
        {
            Mac mac;
            if (parameters.getAlgorithm() == SIPHASH_2_4)
            {
                mac = new SipHashEngine(2, 4);
            }
            else if (parameters.getAlgorithm() == SIPHASH_4_8)
            {
                mac = new SipHashEngine(4, 8);
            }
            else
            {
                throw new IllegalArgumentException("Unknown algorithm passed to createMAC: " + parameters.getAlgorithm());
            }
            return mac;
        }


        @Override
        protected int calculateMACSize(AuthParameters parameters)
        {
            return getMac(parameters).getMacSize();
        }

    }

    private static ValidatedSymmetricKey validateKey(SymmetricKey key, org.bouncycastle.crypto.Parameters parameters)
    {
        ValidatedSymmetricKey vKey = PrivilegedUtils.getValidatedKey(key);

        int keyLength = vKey.getKeySizeInBits();
        if (invalidKeySize(keyLength))
        {
            throw new IllegalKeyException("SipHash key must be of length 128 bits");
        }

        Algorithm algorithm = key.getAlgorithm();

        if (algorithm != ALGORITHM)
        {
            if (algorithm != parameters.getAlgorithm())
            {
                throw new IllegalKeyException("Key not for appropriate algorithm");
            }
        }

        return vKey;
    }

    private static boolean invalidKeySize(int keyLength)
    {
        return keyLength != 128;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy