Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,9 @@ public void update(byte[] input, int inOff, int len)
@Override
public int doFinal(byte[] output, int outOff)
{
return hash(output, outOff, CRYPTO_BYTES);
int rv = hash(output, outOff, CRYPTO_BYTES);
reset();
return rv;
}

protected void padAndAbsorb()
Expand All @@ -149,8 +151,7 @@ protected void squeeze(byte[] output, int outOff, int len)
}
/* squeeze final output block */
setBytes(x0, output, outOff, len);
reset();
}
}

protected int hash(byte[] output, int outOff, int outLen)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package org.bouncycastle.crypto.digests;

import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.crypto.OutputLengthException;
import org.bouncycastle.crypto.Xof;
import org.bouncycastle.util.Pack;

/**
Expand All @@ -17,10 +15,8 @@
* </p>
*/
public class AsconCXof128
extends AsconBaseDigest
implements Xof
extends AsconXof128
{
private boolean m_squeezing = false;
private final long z0, z1, z2, z3, z4;

public AsconCXof128()
Expand All @@ -35,6 +31,7 @@ public AsconCXof128(byte[] s)

public AsconCXof128(byte[] s, int off, int len)
{
super(false);
if ((off + len) > s.length)
{
throw new DataLengthException("input buffer too short");
Expand All @@ -52,90 +49,18 @@ public AsconCXof128(byte[] s, int off, int len)
z4 = x4;
}

@Override
public void update(byte in)
{
if (m_squeezing)
{
throw new IllegalArgumentException("attempt to absorb while squeezing");
}
super.update(in);
}

@Override
public void update(byte[] input, int inOff, int len)
{
if (m_squeezing)
{
throw new IllegalArgumentException("attempt to absorb while squeezing");
}
super.update(input, inOff, len);
}

protected long pad(int i)
{
return 0x01L << (i << 3);
}

protected long loadBytes(final byte[] bytes, int inOff)
{
return Pack.littleEndianToLong(bytes, inOff);
}

protected long loadBytes(final byte[] bytes, int inOff, int n)
{
return Pack.littleEndianToLong(bytes, inOff, n);
}

protected void setBytes(long w, byte[] bytes, int inOff)
{
Pack.longToLittleEndian(w, bytes, inOff);
}

protected void setBytes(long w, byte[] bytes, int inOff, int n)
{
Pack.longToLittleEndian(w, bytes, inOff, n);
}

protected void padAndAbsorb()
{
m_squeezing = true;
super.padAndAbsorb();
}

@Override
public String getAlgorithmName()
{
return "Ascon-CXOF128";
}

@Override
public int doOutput(byte[] output, int outOff, int outLen)
{
if (CRYPTO_BYTES + outOff > output.length)
{
throw new OutputLengthException("output buffer is too short");
}
padAndAbsorb();
/* squeeze full output blocks */
squeeze(output, outOff, outLen);
return outLen;
}


@Override
public int doFinal(byte[] output, int outOff, int outLen)
{
int rlt = doOutput(output, outOff, outLen);
reset();
return rlt;
}

@Override
public void reset()
{
super.reset();
baseReset();
m_squeezing = false;
bytesInBuffer = 0;
/* initialize */
x0 = z0;
x1 = z1;
Expand All @@ -157,6 +82,6 @@ private void initState(byte[] z, int zOff, int zLen)
update(z, zOff, zLen);
padAndAbsorb();
m_squeezing = false;
bytesInBuffer = 0;
}
}

Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.bouncycastle.crypto.digests;

import org.bouncycastle.crypto.OutputLengthException;
import org.bouncycastle.crypto.Xof;
import org.bouncycastle.util.Pack;

Expand All @@ -18,11 +19,22 @@ public class AsconXof128
extends AsconBaseDigest
implements Xof
{
private boolean m_squeezing = false;
protected boolean m_squeezing = false;

private final byte[] buffer = new byte[ASCON_HASH_RATE];
protected int bytesInBuffer;

public AsconXof128()
{
reset();
this(true);
}

protected AsconXof128(final boolean doReset)
{
if (doReset)
{
reset();
}
}

protected long pad(int i)
Expand Down Expand Up @@ -52,8 +64,15 @@ protected void setBytes(long w, byte[] bytes, int inOff, int n)

protected void padAndAbsorb()
{
m_squeezing = true;
super.padAndAbsorb();
if (!m_squeezing)
{
m_squeezing = true;
super.padAndAbsorb();
}
else
{
p(ASCON_PB_ROUNDS);
}
}

@Override
Expand Down Expand Up @@ -85,7 +104,45 @@ public void update(byte[] input, int inOff, int len)
@Override
public int doOutput(byte[] output, int outOff, int outLen)
{
return hash(output, outOff, outLen);
if (outLen + outOff > output.length)
{
throw new OutputLengthException("output buffer is too short");
}

/* Use buffered output first */
int bytesOutput = 0;
if (bytesInBuffer != 0)
{
int startPos = ASCON_HASH_RATE - bytesInBuffer;
int bytesToOutput = Math.min(outLen, bytesInBuffer);
System.arraycopy(buffer, startPos, output, outOff, bytesToOutput);
bytesInBuffer -= bytesToOutput;
bytesOutput += bytesToOutput;
}

/* If we still need to output data */
if (outLen - bytesOutput >= ASCON_HASH_RATE)
{
/* Output full blocks */
int bytesToOutput = ASCON_HASH_RATE * ((outLen - bytesOutput) / ASCON_HASH_RATE);
bytesOutput += hash(output, outOff + bytesOutput, bytesToOutput);
}

/* If we need to output a partial buffer */
if (bytesOutput < outLen)
{
/* Access the next buffer's worth of data */
hash(buffer, 0, ASCON_HASH_RATE);

/* Copy required length of data */
int bytesToOutput = outLen - bytesOutput;
System.arraycopy(buffer, 0, output, outOff + bytesOutput, bytesToOutput);
bytesInBuffer = buffer.length - bytesToOutput;
bytesOutput += bytesToOutput;
}

/* return the length of data output */
return bytesOutput;
}

@Override
Expand All @@ -106,6 +163,7 @@ public int getByteLength()
public void reset()
{
m_squeezing = false;
bytesInBuffer = 0;
super.reset();
/* initialize */
x0 = -2701369817892108309L;
Expand All @@ -114,5 +172,9 @@ public void reset()
x3 = 1072114354614917324L;
x4 = -2282070310009238562L;
}
}

protected void baseReset()
{
super.reset();
}
}