|
| 1 | +package org.bouncycastle.crypto.test; |
| 2 | + |
| 3 | +import java.util.Random; |
| 4 | + |
| 5 | +import org.bouncycastle.crypto.Digest; |
| 6 | +import org.bouncycastle.crypto.agreement.kdf.ConcatenationKDFGenerator; |
| 7 | +import org.bouncycastle.crypto.digests.SHA1Digest; |
| 8 | +import org.bouncycastle.crypto.digests.SHA256Digest; |
| 9 | +import org.bouncycastle.crypto.digests.SHA512Digest; |
| 10 | +import org.bouncycastle.crypto.params.KDFParameters; |
| 11 | +import org.bouncycastle.util.Arrays; |
| 12 | +import org.bouncycastle.util.encoders.Hex; |
| 13 | +import org.bouncycastle.util.test.SimpleTest; |
| 14 | + |
| 15 | +/** |
| 16 | + * Test vectors were copied from https://github.com/patrickfav/singlestep-kdf/wiki/NIST-SP-800-56C-Rev1:-Non-Official-Test-Vectors |
| 17 | + */ |
| 18 | +public class ConcatenationKDFTest |
| 19 | + extends SimpleTest |
| 20 | +{ |
| 21 | + public String getName() |
| 22 | + { |
| 23 | + return "ConcatenationKDF"; |
| 24 | + } |
| 25 | + |
| 26 | + public void performTest() |
| 27 | + { |
| 28 | + implSHA1Test(); |
| 29 | + implSHA256Test(); |
| 30 | + implSHA512Test(); |
| 31 | + } |
| 32 | + |
| 33 | + private void implSHA1Test() |
| 34 | + { |
| 35 | + String sharedSecret = "ebe28edbae5a410b87a479243db3f690"; |
| 36 | + String otherInfo = "e60dd8b28228ce5b9be74d3b"; |
| 37 | + String expected = "b4a23963e07f485382cb358a493daec1759ac7043dbeac37152c6ddf105031f0f239f270b7f30616166f10e5d2b4cb11ba8bf4ba3f2276885abfbc3e811a568d480d9192"; |
| 38 | + |
| 39 | + implKDFTest(new SHA1Digest(), sharedSecret, otherInfo, expected); |
| 40 | + } |
| 41 | + |
| 42 | + private void implSHA256Test() |
| 43 | + { |
| 44 | + String sharedSecret = "3f892bd8b84dae64a782a35f6eaa8f00"; |
| 45 | + String otherInfo = "ec3f1cd873d28858a58cc39e"; |
| 46 | + String expected = "a7c0665298252531e0db37737a374651b368275f2048284d16a166c6d8a90a91a491c16f49641b9f516a03d9d6d0f4fe7b81ffdf1c816f40ecd74aed8eda2b8a3c714fa0"; |
| 47 | + |
| 48 | + implKDFTest(new SHA256Digest(), sharedSecret, otherInfo, expected); |
| 49 | + } |
| 50 | + |
| 51 | + private void implSHA512Test() |
| 52 | + { |
| 53 | + String sharedSecret = "e65b1905878b95f68b5535bd3b2b1013"; |
| 54 | + String otherInfo = "830221b1730d9176f807d407"; |
| 55 | + String expected = "b8c44bdf0b85a64b6a51c12a06710e373d829bb1fda5b4e1a20795c6199594f6fa65198a721257f7d58cb2f6f6db9bb5699f73863045909054b2389e06ec00fe318cabd9"; |
| 56 | + |
| 57 | + implKDFTest(new SHA512Digest(), sharedSecret, otherInfo, expected); |
| 58 | + } |
| 59 | + |
| 60 | + private void implKDFTest(Digest digest, String sharedSecret, String otherInfo, String expected) |
| 61 | + { |
| 62 | + byte[] sharedSecretBytes = Hex.decodeStrict(sharedSecret); |
| 63 | + byte[] otherInfoBytes = Hex.decodeStrict(otherInfo); |
| 64 | + byte[] expectedBytes = Hex.decodeStrict(expected); |
| 65 | + byte[] output = new byte[15 + expectedBytes.length]; |
| 66 | + |
| 67 | + Random random = new Random(); |
| 68 | + ConcatenationKDFGenerator kdf = new ConcatenationKDFGenerator(digest); |
| 69 | + |
| 70 | + for (int count = 0; count <= expectedBytes.length; ++count) |
| 71 | + { |
| 72 | + Arrays.fill(output, (byte)0); |
| 73 | + int outputPos = random.nextInt(16); |
| 74 | + |
| 75 | + kdf.init(new KDFParameters(sharedSecretBytes, otherInfoBytes)); |
| 76 | + kdf.generateBytes(output, outputPos, count); |
| 77 | + |
| 78 | + if (!Arrays.areEqual(expectedBytes, 0, count, output, outputPos, outputPos + count)) |
| 79 | + { |
| 80 | + fail("ConcatenationKDF (" + digest.getAlgorithmName() + ") failed for count of " + count); |
| 81 | + } |
| 82 | + } |
| 83 | + } |
| 84 | + |
| 85 | + public static void main(String[] args) |
| 86 | + { |
| 87 | + runTest(new ConcatenationKDFTest()); |
| 88 | + } |
| 89 | +} |
0 commit comments