diff options
Diffstat (limited to 'bcprov/src/main/java/org/bouncycastle/crypto/test/SCryptTest.java')
-rw-r--r-- | bcprov/src/main/java/org/bouncycastle/crypto/test/SCryptTest.java | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/test/SCryptTest.java b/bcprov/src/main/java/org/bouncycastle/crypto/test/SCryptTest.java new file mode 100644 index 0000000..b017a1d --- /dev/null +++ b/bcprov/src/main/java/org/bouncycastle/crypto/test/SCryptTest.java @@ -0,0 +1,144 @@ +package org.bouncycastle.crypto.test; + +import java.io.BufferedReader; +import java.io.InputStreamReader; + +import org.bouncycastle.crypto.generators.SCrypt; +import org.bouncycastle.util.Strings; +import org.bouncycastle.util.encoders.Hex; +import org.bouncycastle.util.test.SimpleTest; + +/* + * scrypt test vectors from "Stronger Key Derivation Via Sequential Memory-hard Functions" Appendix B. + * (http://www.tarsnap.com/scrypt/scrypt.pdf) + */ +public class SCryptTest extends SimpleTest +{ + public String getName() + { + return "SCrypt"; + } + + public void performTest() throws Exception + { + testParameters(); + testVectors(); + } + + public void testParameters() + { + checkOK("Minimal values", new byte[0], new byte[0], 2, 1, 1, 1); + checkIllegal("Cost parameter must be > 1", new byte[0], new byte[0], 1, 1, 1, 1); + checkOK("Cost parameter 65536 OK for r == 1", new byte[0], new byte[0], 65536, 1, 1, 1); + checkIllegal("Cost parameter must <= 65536 for r == 1", new byte[0], new byte[0], 65537, 1, 1, 1); + checkIllegal("Block size must be >= 1", new byte[0], new byte[0], 2, 0, 2, 1); + checkIllegal("Parallelisation parameter must be >= 1", new byte[0], new byte[0], 2, 1, 0, 1); + // checkOK("Parallelisation parameter 65535 OK for r = 4", new byte[0], new byte[0], 2, 32, + // 65535, 1); + checkIllegal("Parallelisation parameter must be < 65535 for r = 4", new byte[0], new byte[0], 2, 32, 65536, 1); + + checkIllegal("Len parameter must be > 1", new byte[0], new byte[0], 2, 1, 1, 0); + } + + private void checkOK(String msg, byte[] pass, byte[] salt, int N, int r, int p, int len) + { + try + { + SCrypt.generate(pass, salt, N, r, p, len); + } + catch (IllegalArgumentException e) + { + e.printStackTrace(); + fail(msg); + } + } + + private void checkIllegal(String msg, byte[] pass, byte[] salt, int N, int r, int p, int len) + { + try + { + SCrypt.generate(pass, salt, N, r, p, len); + fail(msg); + } + catch (IllegalArgumentException e) + { + // e.printStackTrace(); + } + } + + public void testVectors() + throws Exception + { + BufferedReader br = new BufferedReader(new InputStreamReader( + getClass().getResourceAsStream("SCryptTestVectors.txt"))); + + int count = 0; + String line = br.readLine(); + + while (line != null) + { + ++count; + String header = line; + StringBuffer data = new StringBuffer(); + + while (!isEndData(line = br.readLine())) + { + for (int i = 0; i != line.length(); i++) + { + if (line.charAt(i) != ' ') + { + data.append(line.charAt(i)); + } + } + } + + int start = header.indexOf('(') + 1; + int limit = header.lastIndexOf(')'); + String argStr = header.substring(start, limit); + String[] args = Strings.split(argStr, ','); + + byte[] P = extractQuotedString(args[0]); + byte[] S = extractQuotedString(args[1]); + int N = extractInteger(args[2]); + int r = extractInteger(args[3]); + int p = extractInteger(args[4]); + int dkLen = extractInteger(args[5]); + byte[] expected = Hex.decode(data.toString()); + + // This skips very expensive test case(s), remove check to re-enable + if (N <= 16384) + { + byte[] result = SCrypt.generate(P, S, N, r, p, dkLen); + + if (!areEqual(expected, result)) + { + fail("Result does not match expected value in test case " + count); + } + } + } + + br.close(); + } + + private static boolean isEndData(String line) + { + return line == null || line.startsWith("scrypt"); + } + + private static byte[] extractQuotedString(String arg) + { + arg = arg.trim(); + arg = arg.substring(1, arg.length() - 1); + return Strings.toByteArray(arg); + } + + private static int extractInteger(String arg) + { + return Integer.parseInt(arg.trim()); + } + + public static void main(String[] args) + { + runTest(new SCryptTest()); + } +} |