Skip to content

Commit 11c950f

Browse files
committed
Fix Blake2xs ignoring offset and specified digestLength
1 parent 89f0b22 commit 11c950f

File tree

2 files changed

+35
-27
lines changed

2 files changed

+35
-27
lines changed

core/src/main/java/org/bouncycastle/crypto/digests/Blake2xsDigest.java

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
*/
1010

1111
import org.bouncycastle.crypto.CryptoServicePurpose;
12-
import org.bouncycastle.crypto.CryptoServicesRegistrar;
1312
import org.bouncycastle.crypto.Xof;
1413
import org.bouncycastle.util.Arrays;
1514

@@ -87,7 +86,7 @@ public class Blake2xsDigest
8786
*/
8887
public Blake2xsDigest()
8988
{
90-
this(Blake2xsDigest.UNKNOWN_DIGEST_LENGTH, CryptoServicePurpose.ANY); //TODO: change this?
89+
this(UNKNOWN_DIGEST_LENGTH, CryptoServicePurpose.ANY); //TODO: change this?
9190
}
9291

9392
/**
@@ -125,7 +124,7 @@ public Blake2xsDigest(int digestBytes, byte[] key)
125124
*/
126125
public Blake2xsDigest(int digestBytes, byte[] key, byte[] salt, byte[] personalization, CryptoServicePurpose purpose)
127126
{
128-
if (digestBytes < 1 || digestBytes > Blake2xsDigest.UNKNOWN_DIGEST_LENGTH)
127+
if (digestBytes < 1 || digestBytes > UNKNOWN_DIGEST_LENGTH)
129128
{
130129
throw new IllegalArgumentException(
131130
"BLAKE2xs digest length must be between 1 and 2^16-1");
@@ -134,7 +133,7 @@ public Blake2xsDigest(int digestBytes, byte[] key, byte[] salt, byte[] personali
134133
digestLength = digestBytes;
135134
nodeOffset = computeNodeOffset();
136135
this.purpose = purpose;
137-
hash = new Blake2sDigest(Blake2xsDigest.DIGEST_LENGTH, key, salt, personalization, nodeOffset, purpose);
136+
hash = new Blake2sDigest(DIGEST_LENGTH, key, salt, personalization, nodeOffset, purpose);
138137
}
139138

140139
public Blake2xsDigest(Blake2xsDigest digest)
@@ -189,7 +188,7 @@ public int getByteLength()
189188
*/
190189
public long getUnknownMaxLength()
191190
{
192-
return Blake2xsDigest.MAX_NUMBER_BLOCKS * Blake2xsDigest.DIGEST_LENGTH;
191+
return MAX_NUMBER_BLOCKS * DIGEST_LENGTH;
193192
}
194193

195194
/**
@@ -223,7 +222,7 @@ public void reset()
223222
hash.reset();
224223

225224
h0 = null;
226-
bufPos = Blake2xsDigest.DIGEST_LENGTH;
225+
bufPos = DIGEST_LENGTH;
227226
digestPos = 0;
228227
blockPos = 0;
229228
nodeOffset = computeNodeOffset();
@@ -238,7 +237,7 @@ public void reset()
238237
*/
239238
public int doFinal(byte[] out, int outOffset)
240239
{
241-
return doFinal(out, outOffset, out.length);
240+
return doFinal(out, outOffset, digestLength);
242241
}
243242

244243
/**
@@ -275,7 +274,7 @@ public int doOutput(byte[] out, int outOff, int outLen)
275274
hash.doFinal(h0, 0);
276275
}
277276

278-
if (digestLength != Blake2xsDigest.UNKNOWN_DIGEST_LENGTH)
277+
if (digestLength != UNKNOWN_DIGEST_LENGTH)
279278
{
280279
if (digestPos + outLen > digestLength)
281280
{
@@ -291,9 +290,9 @@ else if (blockPos << 5 >= getUnknownMaxLength())
291290

292291
for (int i = 0; i < outLen; i++)
293292
{
294-
if (bufPos >= Blake2xsDigest.DIGEST_LENGTH)
293+
if (bufPos >= DIGEST_LENGTH)
295294
{
296-
Blake2sDigest h = new Blake2sDigest(computeStepLength(), Blake2xsDigest.DIGEST_LENGTH, nodeOffset);
295+
Blake2sDigest h = new Blake2sDigest(computeStepLength(), DIGEST_LENGTH, nodeOffset);
297296
h.update(h0, 0, h0.length);
298297

299298
Arrays.fill(buf, (byte)0);
@@ -302,7 +301,7 @@ else if (blockPos << 5 >= getUnknownMaxLength())
302301
nodeOffset++;
303302
blockPos++;
304303
}
305-
out[i] = buf[bufPos];
304+
out[outOff + i] = buf[bufPos];
306305
bufPos++;
307306
digestPos++;
308307
}
@@ -314,12 +313,12 @@ else if (blockPos << 5 >= getUnknownMaxLength())
314313
// always the maximum.
315314
private int computeStepLength()
316315
{
317-
if (digestLength == Blake2xsDigest.UNKNOWN_DIGEST_LENGTH)
316+
if (digestLength == UNKNOWN_DIGEST_LENGTH)
318317
{
319-
return Blake2xsDigest.DIGEST_LENGTH;
318+
return DIGEST_LENGTH;
320319
}
321320

322-
return Math.min(Blake2xsDigest.DIGEST_LENGTH, digestLength - digestPos);
321+
return Math.min(DIGEST_LENGTH, digestLength - digestPos);
323322
}
324323

325324
private long computeNodeOffset()

core/src/test/java/org/bouncycastle/crypto/test/Blake2xsDigestTest.java

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package org.bouncycastle.crypto.test;
22

3+
import java.util.Arrays;
4+
import java.util.Random;
5+
36
import org.bouncycastle.crypto.digests.Blake2xsDigest;
47
import org.bouncycastle.util.encoders.Hex;
58
import org.bouncycastle.util.test.SimpleTest;
@@ -2579,38 +2582,44 @@ public String getName()
25792582

25802583
private void testBlake2xsTestVectors()
25812584
{
2585+
Random random = new Random();
2586+
25822587
for (int i = 0; i != Blake2xsDigestTest.xofTestVectors.length; i++)
25832588
{
25842589
String[] vector = Blake2xsDigestTest.xofTestVectors[i];
25852590
byte[] input = Hex.decode(vector[0]);
25862591
byte[] key = Hex.decode(vector[1]);
2592+
byte[] expected = Hex.decode(vector[2]);
25872593

2588-
Blake2xsDigest h = new Blake2xsDigest(vector[2].length() / 2, key);
2594+
int digestSize = expected.length;
2595+
Blake2xsDigest h = new Blake2xsDigest(digestSize, key);
25892596
h.update(input, 0, input.length);
25902597

2591-
byte[] out = new byte[vector[2].length() / 2];
2592-
h.doFinal(out, 0);
2593-
if (!areEqual(out, Hex.decode(vector[2])))
2598+
byte[] out = new byte[16 + digestSize];
2599+
int outOff = 1 + random.nextInt(16);
2600+
h.doFinal(out, outOff);
2601+
if (!areEqual(out, outOff, outOff + digestSize, expected, 0, digestSize))
25942602
{
2595-
fail("BLAKE2xs mismatch on test vector ", vector[2], Hex.toHexString(out));
2603+
fail("BLAKE2xs mismatch on test vector ", vector[2], Hex.toHexString(out, outOff, digestSize));
25962604
}
25972605

2598-
out = new byte[vector[2].length() / 2];
2606+
Arrays.fill(out, (byte)0);
2607+
outOff = 1 + random.nextInt(16);
2608+
25992609
h.update(input, 0, input.length);
26002610
Blake2xsDigest clone = new Blake2xsDigest(h);
26012611

2602-
h.doOutput(out, 0, out.length);
2603-
if (!areEqual(out, Hex.decode(vector[2])))
2612+
h.doOutput(out, outOff, digestSize);
2613+
if (!areEqual(out, outOff, outOff + digestSize, expected, 0, digestSize))
26042614
{
2605-
fail("BLAKE2xs mismatch on test vector after a reset", vector[2], Hex.toHexString(out));
2615+
fail("BLAKE2xs mismatch on test vector after a reset", vector[2], Hex.toHexString(out, outOff, digestSize));
26062616
}
26072617

2608-
byte[] outClone = new byte[out.length];
2618+
byte[] outClone = new byte[digestSize];
26092619
clone.doFinal(outClone, 0, outClone.length);
2610-
if (!areEqual(out, outClone))
2620+
if (!areEqual(outClone, expected))
26112621
{
2612-
fail("BLAKE2xs mismatch on test vector against a clone",
2613-
vector[2], Hex.toHexString(outClone));
2622+
fail("BLAKE2xs mismatch on test vector against a clone", vector[2], Hex.toHexString(outClone));
26142623
}
26152624
}
26162625
}

0 commit comments

Comments
 (0)