org.xwiki.crypto.passwd.internal
Class ScryptMemoryHardKeyDerivationFunction

java.lang.Object
  extended by org.xwiki.crypto.passwd.internal.AbstractMemoryHardKeyDerivationFunction
      extended by org.xwiki.crypto.passwd.internal.ScryptMemoryHardKeyDerivationFunction
All Implemented Interfaces:
java.io.Serializable, KeyDerivationFunction, MemoryHardKeyDerivationFunction

public class ScryptMemoryHardKeyDerivationFunction
extends AbstractMemoryHardKeyDerivationFunction

The Scrypt Key Derivation Function. A java implementation of this http://www.tarsnap.com/scrypt/scrypt.pdf Scrypt function includes a shortcut which may be regarded as a weakness. This function may be executed with half the memory by throwing out every other blockMix output and when one of the missing outputs is needed, recomputing it. This will halve the memory cost while increasing the processor cost by 1/6 of the total. Using even less memory is possible but the processor cost grows at a much higher rate. The existance of this shortcut has been confirmend with the designer of Scrypt who claimed it was for cases when decryption was necessary on a system with less memory than the system used to encrypt the data.

Since:
2.5M1
Version:
$Id$
See Also:
Serialized Form

Constructor Summary
ScryptMemoryHardKeyDerivationFunction()
           
 
Method Summary
protected  void allocateMemory(boolean forReal)
          Allocate the memory necessary to run the hash function.
protected  void blockMix(byte[] block)
          Implementation of BlockMix.
protected  void bulkXOR(byte[] input, int inputOffset, byte[] output, int outputOffset, int length)
          XOR all bytes in two byte arrays.
protected  void bytesToIntsLittle(byte[] input, int[] output)
          Pack byte[] array into an int in little endian order.
 byte[] deriveKey(byte[] password)
          Convert the given password to a byte array similar to the output from a message digest except specially tuned for the unique requirements of protecting passwords.
protected  void freeMemory()
          Sets the working buffers to null.
 void init(byte[] salt, int memoryExpense, int blockSize, int processorExpense, int derivedKeyLength)
          This is an implementation of scrypt(P, S, N, r, p, dkLen) function.
 void init(int kilobytesOfMemoryToUse, int millisecondsOfProcessorTimeToSpend, int derivedKeyLength)
          Initialize this function with the desired parameters.
protected  long integerify(byte[] array)
          Convert 4 bytes from a specified place in the array to a long.
protected  int integerifyAndMod(byte[] array, int modulus)
          Convert 8 bytes from a specified place in the array to an integer and take the mod of that number against modulus.
protected  void intsToBytesLittle(int[] input, byte[] output)
          Convert an array of integer to an array of little endian bytes.
protected  int rotl(int x, int y)
          Rotate left.
protected  void salsa20Core(int[] input, int[] output, int numberOfRounds)
          Salsa20 function.
protected  void scryptSalsa8(byte[] bytesToModify)
          salsa20_8 function as defined in crypto_scrypt.
protected  void smix(byte[] bufferToMix, int offset)
          Compute B = SMix(B, N) where B is a section of bufferToMix starting at offset and proceeding for (128 * blockSize) bytes and N is memoryExpense.
protected  int unsignedMod(long unsignedLong, int signedModulus)
          Compute (unsignedLong % signedModulus) quickly.
 
Methods inherited from class org.xwiki.crypto.passwd.internal.AbstractMemoryHardKeyDerivationFunction
getDefaultDerivedKeyLength, getDefaultMillisecondsOfProcessorTime, getDefaultNumberOfKilobytesOfMemoryToUse, init, init, init, serialize
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

ScryptMemoryHardKeyDerivationFunction

public ScryptMemoryHardKeyDerivationFunction()
Method Detail

init

public void init(int kilobytesOfMemoryToUse,
                 int millisecondsOfProcessorTimeToSpend,
                 int derivedKeyLength)
Initialize this function with the desired parameters.

Parameters:
kilobytesOfMemoryToUse - number of kilobytes or RAM which should be required by any implementation to validate a password. This amount of memory will be occupied for the time given by millisecondsOfProcessorTimeToSpend. Obviously if the adversary has a faster processor, then this time will be shorter on his computer.
millisecondsOfProcessorTimeToSpend - target amount of time to spend verifying the password. This will be tested on the system when init is called.
derivedKeyLength - the number of bytes of length the derived key (output) should be.

init

public void init(byte[] salt,
                 int memoryExpense,
                 int blockSize,
                 int processorExpense,
                 int derivedKeyLength)
This is an implementation of scrypt(P, S, N, r, p, dkLen) function.

Parameters:
salt - when encoding, a random byte array, when verifying, the same salt as was used to encode.
memoryExpense - a positive integer representing the relative memory expense which the function should take. with blocksize equal to 8 this is the number of kilobytes of memory which this function should require.
blockSize - the block size to use in the internal function.
processorExpense - a positive integer representing the relative CPU expense which the function should take.
derivedKeyLength - the number of bytes of length the derived key should be (dkLen)

deriveKey

public byte[] deriveKey(byte[] password)
Convert the given password to a byte array similar to the output from a message digest except specially tuned for the unique requirements of protecting passwords.

Parameters:
password - the user supplied password.
Returns:
a byte array derived from the password.

allocateMemory

protected void allocateMemory(boolean forReal)
Allocate the memory necessary to run the hash function. First check and see if there is enough free memory before attempting to allocate.

Parameters:
forReal - if false then memory isn't allocated, only tested to see if there is enough to allocate.

freeMemory

protected void freeMemory()
Sets the working buffers to null. Necessary because this function takes a large amount of memory and it should be released as quickly as possible.


smix

protected void smix(byte[] bufferToMix,
                    int offset)
Compute B = SMix(B, N) where B is a section of bufferToMix starting at offset and proceeding for (128 * blockSize) bytes and N is memoryExpense.

Parameters:
bufferToMix - part of this buffer (128 * blockSize) bytes wide will be mixed using the SMix function.
offset - the index in bytes where the part to be mixed starts.

blockMix

protected void blockMix(byte[] block)
Implementation of BlockMix. Defined here: http://www.tarsnap.com/scrypt.html as BlockMix_salsa20/8,r (B)

Parameters:
block - 1024 byte block of bytes to scramble (B)

integerifyAndMod

protected int integerifyAndMod(byte[] array,
                               int modulus)
Convert 8 bytes from a specified place in the array to an integer and take the mod of that number against modulus. This function uses a fast modulus operation which requires that modulus is a power of 2.

Parameters:
array - the array to take bytes from.
modulus - the output will not be larger than this (must be a power of 2).
Returns:
integer gathered from the array and modded against the modulus.

integerify

protected long integerify(byte[] array)
Convert 4 bytes from a specified place in the array to a long. This is a binary operation, sign is ignored. The paper says Integerify takes the last 8 bytes from the array but the reference implementation takes byte at index (2 * r - 1) * 64 and the 7 bytes following. With a blockSize of 8, that means bytes 960-967 are used from an array of 1024. This function follows the reference implementation.

Parameters:
array - the array to take bytes from.
Returns:
long value gathered from the array.

unsignedMod

protected int unsignedMod(long unsignedLong,
                          int signedModulus)
Compute (unsignedLong % signedModulus) quickly. signedModulus must be is a power of 2

Parameters:
unsignedLong - a long value which is treated as unsigned.
signedModulus - a modulus which must be a positive number and is treated as signed.
Returns:
value of (x - Long.MIN_VALUE) % signedModulus

bulkXOR

protected void bulkXOR(byte[] input,
                       int inputOffset,
                       byte[] output,
                       int outputOffset,
                       int length)
XOR all bytes in two byte arrays. The output array will be XOR'd against the input array and the result will be saved to the output array. If the input array is smaller than the output, an array index exception will result.

Parameters:
input - an array which will not be modified.
inputOffset - start with byte at this index.
output - an array which will be modified.
outputOffset - start modifying (and reading) output at this index.
length - number of bytes to XOR.

scryptSalsa8

protected void scryptSalsa8(byte[] bytesToModify)
salsa20_8 function as defined in crypto_scrypt. see: http://www.tarsnap.com/scrypt.html

Parameters:
bytesToModify - 64 bytes of data to mangle with the function. For performance reasons, this array is mutated and becomes the output.

salsa20Core

protected void salsa20Core(int[] input,
                           int[] output,
                           int numberOfRounds)
Salsa20 function. Implementation of function defined here: http://cr.yp.to/salsa20.html

Parameters:
input - the data to mangle with the function (array of int, 16 long)
output - the output will be put into this array.
numberOfRounds - if this is 8, you will have Salsa20/8 if 12, you have Salsa20/12, if 20 you have Salsa20

rotl

protected int rotl(int x,
                   int y)
Rotate left. Copied from bouncycastle.crypto.engines.Salsa20Engine

Parameters:
x - value to rotate
y - amount to rotate x
Returns:
rotated x

intsToBytesLittle

protected void intsToBytesLittle(int[] input,
                                 byte[] output)
Convert an array of integer to an array of little endian bytes.

Parameters:
input - the integers to convert.
output - the byte array to put the output in, if this array is not at least 4 times the length of input, an array index out of bounds exception will result.

bytesToIntsLittle

protected void bytesToIntsLittle(byte[] input,
                                 int[] output)
Pack byte[] array into an int in little endian order.

Parameters:
input - the byte array to convert to int array.
output - the int array to put the output in, if this array is not at least 1/4 the length of input, an array index out of bounds exception will result.


Copyright © 2004-2011 XWiki. All Rights Reserved.