Skip to content

Commit

Permalink
Fix Blake2xs ignoring offset and specified digestLength
Browse files Browse the repository at this point in the history
  • Loading branch information
peterdettman committed Sep 30, 2022
1 parent 89f0b22 commit 11c950f
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
*/

import org.bouncycastle.crypto.CryptoServicePurpose;
import org.bouncycastle.crypto.CryptoServicesRegistrar;
import org.bouncycastle.crypto.Xof;
import org.bouncycastle.util.Arrays;

Expand Down Expand Up @@ -87,7 +86,7 @@ public class Blake2xsDigest
*/
public Blake2xsDigest()
{
this(Blake2xsDigest.UNKNOWN_DIGEST_LENGTH, CryptoServicePurpose.ANY); //TODO: change this?
this(UNKNOWN_DIGEST_LENGTH, CryptoServicePurpose.ANY); //TODO: change this?
}

/**
Expand Down Expand Up @@ -125,7 +124,7 @@ public Blake2xsDigest(int digestBytes, byte[] key)
*/
public Blake2xsDigest(int digestBytes, byte[] key, byte[] salt, byte[] personalization, CryptoServicePurpose purpose)
{
if (digestBytes < 1 || digestBytes > Blake2xsDigest.UNKNOWN_DIGEST_LENGTH)
if (digestBytes < 1 || digestBytes > UNKNOWN_DIGEST_LENGTH)
{
throw new IllegalArgumentException(
"BLAKE2xs digest length must be between 1 and 2^16-1");
Expand All @@ -134,7 +133,7 @@ public Blake2xsDigest(int digestBytes, byte[] key, byte[] salt, byte[] personali
digestLength = digestBytes;
nodeOffset = computeNodeOffset();
this.purpose = purpose;
hash = new Blake2sDigest(Blake2xsDigest.DIGEST_LENGTH, key, salt, personalization, nodeOffset, purpose);
hash = new Blake2sDigest(DIGEST_LENGTH, key, salt, personalization, nodeOffset, purpose);
}

public Blake2xsDigest(Blake2xsDigest digest)
Expand Down Expand Up @@ -189,7 +188,7 @@ public int getByteLength()
*/
public long getUnknownMaxLength()
{
return Blake2xsDigest.MAX_NUMBER_BLOCKS * Blake2xsDigest.DIGEST_LENGTH;
return MAX_NUMBER_BLOCKS * DIGEST_LENGTH;
}

/**
Expand Down Expand Up @@ -223,7 +222,7 @@ public void reset()
hash.reset();

h0 = null;
bufPos = Blake2xsDigest.DIGEST_LENGTH;
bufPos = DIGEST_LENGTH;
digestPos = 0;
blockPos = 0;
nodeOffset = computeNodeOffset();
Expand All @@ -238,7 +237,7 @@ public void reset()
*/
public int doFinal(byte[] out, int outOffset)
{
return doFinal(out, outOffset, out.length);
return doFinal(out, outOffset, digestLength);
}

/**
Expand Down Expand Up @@ -275,7 +274,7 @@ public int doOutput(byte[] out, int outOff, int outLen)
hash.doFinal(h0, 0);
}

if (digestLength != Blake2xsDigest.UNKNOWN_DIGEST_LENGTH)
if (digestLength != UNKNOWN_DIGEST_LENGTH)
{
if (digestPos + outLen > digestLength)
{
Expand All @@ -291,9 +290,9 @@ else if (blockPos << 5 >= getUnknownMaxLength())

for (int i = 0; i < outLen; i++)
{
if (bufPos >= Blake2xsDigest.DIGEST_LENGTH)
if (bufPos >= DIGEST_LENGTH)
{
Blake2sDigest h = new Blake2sDigest(computeStepLength(), Blake2xsDigest.DIGEST_LENGTH, nodeOffset);
Blake2sDigest h = new Blake2sDigest(computeStepLength(), DIGEST_LENGTH, nodeOffset);
h.update(h0, 0, h0.length);

Arrays.fill(buf, (byte)0);
Expand All @@ -302,7 +301,7 @@ else if (blockPos << 5 >= getUnknownMaxLength())
nodeOffset++;
blockPos++;
}
out[i] = buf[bufPos];
out[outOff + i] = buf[bufPos];
bufPos++;
digestPos++;
}
Expand All @@ -314,12 +313,12 @@ else if (blockPos << 5 >= getUnknownMaxLength())
// always the maximum.
private int computeStepLength()
{
if (digestLength == Blake2xsDigest.UNKNOWN_DIGEST_LENGTH)
if (digestLength == UNKNOWN_DIGEST_LENGTH)
{
return Blake2xsDigest.DIGEST_LENGTH;
return DIGEST_LENGTH;
}

return Math.min(Blake2xsDigest.DIGEST_LENGTH, digestLength - digestPos);
return Math.min(DIGEST_LENGTH, digestLength - digestPos);
}

private long computeNodeOffset()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package org.bouncycastle.crypto.test;

import java.util.Arrays;
import java.util.Random;

import org.bouncycastle.crypto.digests.Blake2xsDigest;
import org.bouncycastle.util.encoders.Hex;
import org.bouncycastle.util.test.SimpleTest;
Expand Down Expand Up @@ -2579,38 +2582,44 @@ public String getName()

private void testBlake2xsTestVectors()
{
Random random = new Random();

for (int i = 0; i != Blake2xsDigestTest.xofTestVectors.length; i++)
{
String[] vector = Blake2xsDigestTest.xofTestVectors[i];
byte[] input = Hex.decode(vector[0]);
byte[] key = Hex.decode(vector[1]);
byte[] expected = Hex.decode(vector[2]);

Blake2xsDigest h = new Blake2xsDigest(vector[2].length() / 2, key);
int digestSize = expected.length;
Blake2xsDigest h = new Blake2xsDigest(digestSize, key);
h.update(input, 0, input.length);

byte[] out = new byte[vector[2].length() / 2];
h.doFinal(out, 0);
if (!areEqual(out, Hex.decode(vector[2])))
byte[] out = new byte[16 + digestSize];
int outOff = 1 + random.nextInt(16);
h.doFinal(out, outOff);
if (!areEqual(out, outOff, outOff + digestSize, expected, 0, digestSize))
{
fail("BLAKE2xs mismatch on test vector ", vector[2], Hex.toHexString(out));
fail("BLAKE2xs mismatch on test vector ", vector[2], Hex.toHexString(out, outOff, digestSize));
}

out = new byte[vector[2].length() / 2];
Arrays.fill(out, (byte)0);
outOff = 1 + random.nextInt(16);

h.update(input, 0, input.length);
Blake2xsDigest clone = new Blake2xsDigest(h);

h.doOutput(out, 0, out.length);
if (!areEqual(out, Hex.decode(vector[2])))
h.doOutput(out, outOff, digestSize);
if (!areEqual(out, outOff, outOff + digestSize, expected, 0, digestSize))
{
fail("BLAKE2xs mismatch on test vector after a reset", vector[2], Hex.toHexString(out));
fail("BLAKE2xs mismatch on test vector after a reset", vector[2], Hex.toHexString(out, outOff, digestSize));
}

byte[] outClone = new byte[out.length];
byte[] outClone = new byte[digestSize];
clone.doFinal(outClone, 0, outClone.length);
if (!areEqual(out, outClone))
if (!areEqual(outClone, expected))
{
fail("BLAKE2xs mismatch on test vector against a clone",
vector[2], Hex.toHexString(outClone));
fail("BLAKE2xs mismatch on test vector against a clone", vector[2], Hex.toHexString(outClone));
}
}
}
Expand Down

0 comments on commit 11c950f

Please sign in to comment.