org.bouncycastle.crypto.macs.SipHash128 Maven / Gradle / Ivy
Show all versions of bcprov-jdk15to18 Show documentation
package org.bouncycastle.crypto.macs;
import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.util.Pack;
/**
* Implementation of SipHash with 128 bit output.
*
* Based on the {@link SipHash} and the C reference implementation
* https://github.com/veorq/SipHash.
*
*/
public class SipHash128
extends SipHash
{
/**
* SipHash128-2-4
*/
public SipHash128()
{
super();
}
/**
* SipHash128-c-d
*
* @param c the number of compression rounds
* @param d the number of finalization rounds
*/
public SipHash128(int c, int d)
{
super(c, d);
}
public String getAlgorithmName()
{
return "SipHash128-" + c + "-" + d;
}
public int getMacSize()
{
return 16;
}
public long doFinal()
throws DataLengthException, IllegalStateException {
throw new UnsupportedOperationException("doFinal() is not supported");
}
public int doFinal(byte[] out, int outOff)
throws DataLengthException, IllegalStateException
{
// NOTE: 2 distinct shifts to avoid "64-bit shift" when wordPos == 0
m >>>= ((7 - wordPos) << 3);
m >>>= 8;
m |= (((wordCount << 3) + wordPos) & 0xffL) << 56;
processMessageWord();
v2 ^= 0xeeL;
applySipRounds(d);
long r0 = v0 ^ v1 ^ v2 ^ v3;
v1 ^= 0xddL;
applySipRounds(d);
long r1 = v0 ^ v1 ^ v2 ^ v3;
reset();
Pack.longToLittleEndian(r0, out, outOff);
Pack.longToLittleEndian(r1, out, outOff + 8);
return 16;
}
public void reset()
{
super.reset();
v1 ^= 0xeeL;
}
}