fr.cryptohash.CubeHashCore Maven / Gradle / Ivy
// $Id: CubeHashCore.java 232 2010-06-17 14:19:24Z tp $
package fr.cryptohash;
/**
* This class implements the core operations for the CubeHash digest
* algorithm.
*
*
* ==========================(LICENSE BEGIN)============================
*
* Copyright (c) 2007-2010 Projet RNRT SAPHIR
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* ===========================(LICENSE END)=============================
*
*
* @version $Revision: 232 $
* @author Thomas Pornin <[email protected]>
*/
abstract class CubeHashCore extends DigestEngine {
CubeHashCore()
{
}
private int x0, x1, x2, x3, x4, x5, x6, x7;
private int x8, x9, xa, xb, xc, xd, xe, xf;
private int xg, xh, xi, xj, xk, xl, xm, xn;
private int xo, xp, xq, xr, xs, xt, xu, xv;
private final void inputBlock(byte[] data)
{
x0 ^= decodeLEInt(data, 0);
x1 ^= decodeLEInt(data, 4);
x2 ^= decodeLEInt(data, 8);
x3 ^= decodeLEInt(data, 12);
x4 ^= decodeLEInt(data, 16);
x5 ^= decodeLEInt(data, 20);
x6 ^= decodeLEInt(data, 24);
x7 ^= decodeLEInt(data, 28);
}
private final void sixteenRounds()
{
for (int i = 0; i < 8; i ++) {
xg = x0 + xg;
x0 = (x0 << 7) | (x0 >>> (32 - 7));
xh = x1 + xh;
x1 = (x1 << 7) | (x1 >>> (32 - 7));
xi = x2 + xi;
x2 = (x2 << 7) | (x2 >>> (32 - 7));
xj = x3 + xj;
x3 = (x3 << 7) | (x3 >>> (32 - 7));
xk = x4 + xk;
x4 = (x4 << 7) | (x4 >>> (32 - 7));
xl = x5 + xl;
x5 = (x5 << 7) | (x5 >>> (32 - 7));
xm = x6 + xm;
x6 = (x6 << 7) | (x6 >>> (32 - 7));
xn = x7 + xn;
x7 = (x7 << 7) | (x7 >>> (32 - 7));
xo = x8 + xo;
x8 = (x8 << 7) | (x8 >>> (32 - 7));
xp = x9 + xp;
x9 = (x9 << 7) | (x9 >>> (32 - 7));
xq = xa + xq;
xa = (xa << 7) | (xa >>> (32 - 7));
xr = xb + xr;
xb = (xb << 7) | (xb >>> (32 - 7));
xs = xc + xs;
xc = (xc << 7) | (xc >>> (32 - 7));
xt = xd + xt;
xd = (xd << 7) | (xd >>> (32 - 7));
xu = xe + xu;
xe = (xe << 7) | (xe >>> (32 - 7));
xv = xf + xv;
xf = (xf << 7) | (xf >>> (32 - 7));
x8 ^= xg;
x9 ^= xh;
xa ^= xi;
xb ^= xj;
xc ^= xk;
xd ^= xl;
xe ^= xm;
xf ^= xn;
x0 ^= xo;
x1 ^= xp;
x2 ^= xq;
x3 ^= xr;
x4 ^= xs;
x5 ^= xt;
x6 ^= xu;
x7 ^= xv;
xi = x8 + xi;
x8 = (x8 << 11) | (x8 >>> (32 - 11));
xj = x9 + xj;
x9 = (x9 << 11) | (x9 >>> (32 - 11));
xg = xa + xg;
xa = (xa << 11) | (xa >>> (32 - 11));
xh = xb + xh;
xb = (xb << 11) | (xb >>> (32 - 11));
xm = xc + xm;
xc = (xc << 11) | (xc >>> (32 - 11));
xn = xd + xn;
xd = (xd << 11) | (xd >>> (32 - 11));
xk = xe + xk;
xe = (xe << 11) | (xe >>> (32 - 11));
xl = xf + xl;
xf = (xf << 11) | (xf >>> (32 - 11));
xq = x0 + xq;
x0 = (x0 << 11) | (x0 >>> (32 - 11));
xr = x1 + xr;
x1 = (x1 << 11) | (x1 >>> (32 - 11));
xo = x2 + xo;
x2 = (x2 << 11) | (x2 >>> (32 - 11));
xp = x3 + xp;
x3 = (x3 << 11) | (x3 >>> (32 - 11));
xu = x4 + xu;
x4 = (x4 << 11) | (x4 >>> (32 - 11));
xv = x5 + xv;
x5 = (x5 << 11) | (x5 >>> (32 - 11));
xs = x6 + xs;
x6 = (x6 << 11) | (x6 >>> (32 - 11));
xt = x7 + xt;
x7 = (x7 << 11) | (x7 >>> (32 - 11));
xc ^= xi;
xd ^= xj;
xe ^= xg;
xf ^= xh;
x8 ^= xm;
x9 ^= xn;
xa ^= xk;
xb ^= xl;
x4 ^= xq;
x5 ^= xr;
x6 ^= xo;
x7 ^= xp;
x0 ^= xu;
x1 ^= xv;
x2 ^= xs;
x3 ^= xt;
xj = xc + xj;
xc = (xc << 7) | (xc >>> (32 - 7));
xi = xd + xi;
xd = (xd << 7) | (xd >>> (32 - 7));
xh = xe + xh;
xe = (xe << 7) | (xe >>> (32 - 7));
xg = xf + xg;
xf = (xf << 7) | (xf >>> (32 - 7));
xn = x8 + xn;
x8 = (x8 << 7) | (x8 >>> (32 - 7));
xm = x9 + xm;
x9 = (x9 << 7) | (x9 >>> (32 - 7));
xl = xa + xl;
xa = (xa << 7) | (xa >>> (32 - 7));
xk = xb + xk;
xb = (xb << 7) | (xb >>> (32 - 7));
xr = x4 + xr;
x4 = (x4 << 7) | (x4 >>> (32 - 7));
xq = x5 + xq;
x5 = (x5 << 7) | (x5 >>> (32 - 7));
xp = x6 + xp;
x6 = (x6 << 7) | (x6 >>> (32 - 7));
xo = x7 + xo;
x7 = (x7 << 7) | (x7 >>> (32 - 7));
xv = x0 + xv;
x0 = (x0 << 7) | (x0 >>> (32 - 7));
xu = x1 + xu;
x1 = (x1 << 7) | (x1 >>> (32 - 7));
xt = x2 + xt;
x2 = (x2 << 7) | (x2 >>> (32 - 7));
xs = x3 + xs;
x3 = (x3 << 7) | (x3 >>> (32 - 7));
x4 ^= xj;
x5 ^= xi;
x6 ^= xh;
x7 ^= xg;
x0 ^= xn;
x1 ^= xm;
x2 ^= xl;
x3 ^= xk;
xc ^= xr;
xd ^= xq;
xe ^= xp;
xf ^= xo;
x8 ^= xv;
x9 ^= xu;
xa ^= xt;
xb ^= xs;
xh = x4 + xh;
x4 = (x4 << 11) | (x4 >>> (32 - 11));
xg = x5 + xg;
x5 = (x5 << 11) | (x5 >>> (32 - 11));
xj = x6 + xj;
x6 = (x6 << 11) | (x6 >>> (32 - 11));
xi = x7 + xi;
x7 = (x7 << 11) | (x7 >>> (32 - 11));
xl = x0 + xl;
x0 = (x0 << 11) | (x0 >>> (32 - 11));
xk = x1 + xk;
x1 = (x1 << 11) | (x1 >>> (32 - 11));
xn = x2 + xn;
x2 = (x2 << 11) | (x2 >>> (32 - 11));
xm = x3 + xm;
x3 = (x3 << 11) | (x3 >>> (32 - 11));
xp = xc + xp;
xc = (xc << 11) | (xc >>> (32 - 11));
xo = xd + xo;
xd = (xd << 11) | (xd >>> (32 - 11));
xr = xe + xr;
xe = (xe << 11) | (xe >>> (32 - 11));
xq = xf + xq;
xf = (xf << 11) | (xf >>> (32 - 11));
xt = x8 + xt;
x8 = (x8 << 11) | (x8 >>> (32 - 11));
xs = x9 + xs;
x9 = (x9 << 11) | (x9 >>> (32 - 11));
xv = xa + xv;
xa = (xa << 11) | (xa >>> (32 - 11));
xu = xb + xu;
xb = (xb << 11) | (xb >>> (32 - 11));
x0 ^= xh;
x1 ^= xg;
x2 ^= xj;
x3 ^= xi;
x4 ^= xl;
x5 ^= xk;
x6 ^= xn;
x7 ^= xm;
x8 ^= xp;
x9 ^= xo;
xa ^= xr;
xb ^= xq;
xc ^= xt;
xd ^= xs;
xe ^= xv;
xf ^= xu;
}
}
/**
* Encode the 32-bit word {@code val} into the array
* {@code buf} at offset {@code off}, in little-endian
* convention (least significant byte first).
*
* @param val the value to encode
* @param buf the destination buffer
* @param off the destination offset
*/
private static final void encodeLEInt(int val, byte[] buf, int off)
{
buf[off + 0] = (byte)val;
buf[off + 1] = (byte)(val >>> 8);
buf[off + 2] = (byte)(val >>> 16);
buf[off + 3] = (byte)(val >>> 24);
}
/**
* Decode a 32-bit little-endian word from the array {@code buf}
* at offset {@code off}.
*
* @param buf the source buffer
* @param off the source offset
* @return the decoded value
*/
private static final int decodeLEInt(byte[] buf, int off)
{
return (buf[off + 0] & 0xFF)
| ((buf[off + 1] & 0xFF) << 8)
| ((buf[off + 2] & 0xFF) << 16)
| ((buf[off + 3] & 0xFF) << 24);
}
/** @see DigestEngine */
protected void engineReset()
{
doReset();
}
/** @see DigestEngine */
protected void processBlock(byte[] data)
{
inputBlock(data);
sixteenRounds();
}
/** @see DigestEngine */
protected void doPadding(byte[] out, int off)
{
int ptr = flush();
byte[] buf = getBlockBuffer();
buf[ptr ++] = (byte)0x80;
while (ptr < 32)
buf[ptr ++] = 0x00;
inputBlock(buf);
sixteenRounds();
xv ^= 1;
for (int j = 0; j < 10; j ++)
sixteenRounds();
int dlen = getDigestLength();
encodeLEInt(x0, out, off + 0);
encodeLEInt(x1, out, off + 4);
encodeLEInt(x2, out, off + 8);
encodeLEInt(x3, out, off + 12);
encodeLEInt(x4, out, off + 16);
encodeLEInt(x5, out, off + 20);
encodeLEInt(x6, out, off + 24);
if (dlen == 28)
return;
encodeLEInt(x7, out, off + 28);
if (dlen == 32)
return;
encodeLEInt(x8, out, off + 32);
encodeLEInt(x9, out, off + 36);
encodeLEInt(xa, out, off + 40);
encodeLEInt(xb, out, off + 44);
if (dlen == 48)
return;
encodeLEInt(xc, out, off + 48);
encodeLEInt(xd, out, off + 52);
encodeLEInt(xe, out, off + 56);
encodeLEInt(xf, out, off + 60);
}
/** @see DigestEngine */
protected void doInit()
{
doReset();
}
/**
* Get the initial values.
*
* @return the IV
*/
abstract int[] getIV();
/** @see DigestEngine */
public int getInternalBlockLength()
{
return 32;
}
/** @see Digest */
public int getBlockLength()
{
/*
* From the CubeHash specification:
*
* << Applications such as HMAC that pad to a full block
* of SHA-h input are required to pad to a full minimal
* integral number of b-byte blocks for CubeHashr/b-h. >>
*
* Here, b = 32.
*/
return -32;
}
private final void doReset()
{
int[] iv = getIV();
x0 = iv[ 0];
x1 = iv[ 1];
x2 = iv[ 2];
x3 = iv[ 3];
x4 = iv[ 4];
x5 = iv[ 5];
x6 = iv[ 6];
x7 = iv[ 7];
x8 = iv[ 8];
x9 = iv[ 9];
xa = iv[10];
xb = iv[11];
xc = iv[12];
xd = iv[13];
xe = iv[14];
xf = iv[15];
xg = iv[16];
xh = iv[17];
xi = iv[18];
xj = iv[19];
xk = iv[20];
xl = iv[21];
xm = iv[22];
xn = iv[23];
xo = iv[24];
xp = iv[25];
xq = iv[26];
xr = iv[27];
xs = iv[28];
xt = iv[29];
xu = iv[30];
xv = iv[31];
}
/** @see DigestEngine */
protected Digest copyState(CubeHashCore dst)
{
dst.x0 = x0;
dst.x1 = x1;
dst.x2 = x2;
dst.x3 = x3;
dst.x4 = x4;
dst.x5 = x5;
dst.x6 = x6;
dst.x7 = x7;
dst.x8 = x8;
dst.x9 = x9;
dst.xa = xa;
dst.xb = xb;
dst.xc = xc;
dst.xd = xd;
dst.xe = xe;
dst.xf = xf;
dst.xg = xg;
dst.xh = xh;
dst.xi = xi;
dst.xj = xj;
dst.xk = xk;
dst.xl = xl;
dst.xm = xm;
dst.xn = xn;
dst.xo = xo;
dst.xp = xp;
dst.xq = xq;
dst.xr = xr;
dst.xs = xs;
dst.xt = xt;
dst.xu = xu;
dst.xv = xv;
return super.copyState(dst);
}
/** @see Digest */
public String toString()
{
return "CubeHash-" + (getDigestLength() << 3);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy