Skip to content

Commit

Permalink
Merge branch 'master' of github.com:Password4j/password4j
Browse files Browse the repository at this point in the history
  • Loading branch information
firaja committed May 1, 2024
2 parents 7041635 + 69ff99e commit f80271d
Show file tree
Hide file tree
Showing 17 changed files with 496 additions and 489 deletions.
10 changes: 5 additions & 5 deletions src/main/java/com/password4j/AlgorithmFinder.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ public class AlgorithmFinder
*/
private static SecureRandom secureRandom;

static
{
initialize();
}

private AlgorithmFinder()
{
//
Expand Down Expand Up @@ -419,9 +424,4 @@ private static class Param
this.length = length;
}
}

static
{
initialize();
}
}
220 changes: 104 additions & 116 deletions src/main/java/com/password4j/Argon2Function.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,26 +51,16 @@ public class Argon2Function extends AbstractHashingFunction
private static final int ARGON2_BLOCK_SIZE = 1024;

public static final int ARGON2_QWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 8;

private ExecutorService service;

private final int iterations;

private final int memory;

private final long[][] initialBlockMemory;

private final int parallelism;

private final int outputLength;

private final int segmentLength;

private final Argon2 variant;

private final int version;

private final int laneLength;
private ExecutorService service;

Argon2Function(int memory, int iterations, int parallelism, int outputLength, Argon2 variant, int version)
{
Expand Down Expand Up @@ -136,7 +126,7 @@ public static Argon2Function getInstance(int memory, int iterations, int paralle
* @since 1.5.0
*/
public static Argon2Function getInstance(int memory, int iterations, int parallelism, int outputLength, Argon2 type,
int version)
int version)
{
String key = getUID(memory, iterations, parallelism, outputLength, type, version);
if (INSTANCES.containsKey(key))
Expand Down Expand Up @@ -171,99 +161,6 @@ public static Argon2Function getInstanceFromHash(String hashed)
return getInstance(memory, iterations, parallelism, outputLength, type, version);
}

@Override
public Hash hash(CharSequence plainTextPassword)
{
byte[] salt = SaltGenerator.generate();
return internalHash(Utils.fromCharSequenceToBytes(plainTextPassword), salt, null);
}

@Override
public Hash hash(byte[] plainTextPassword)
{
byte[] salt = SaltGenerator.generate();
return internalHash(plainTextPassword, salt, null);
}

@Override
public Hash hash(CharSequence plainTextPassword, String salt)
{
return hash(plainTextPassword, salt, null);
}

@Override
public Hash hash(byte[] plainTextPassword, byte[] salt)
{
return hash(plainTextPassword, salt, null);
}

@Override
public Hash hash(CharSequence plainTextPassword, String salt, CharSequence pepper)
{
return internalHash(Utils.fromCharSequenceToBytes(plainTextPassword), Utils.fromCharSequenceToBytes(salt), pepper);
}

@Override
public Hash hash(byte[] plainTextPassword, byte[] salt, CharSequence pepper)
{
return internalHash(plainTextPassword, salt, pepper);
}

private Hash internalHash(byte[] plainTextPassword, byte[] salt, CharSequence pepper)
{
long[][] blockMemory = copyOf(initialBlockMemory);

if (salt == null)
{
salt = SaltGenerator.generate();
}
initialize(plainTextPassword, salt, Utils.fromCharSequenceToBytes(pepper), null, blockMemory);
fillMemoryBlocks(blockMemory);
byte[] hash = ending(blockMemory);
Hash result = new Hash(this, encodeHash(hash, salt), hash, salt);
result.setPepper(pepper);
return result;
}

@Override
public boolean check(CharSequence plainTextPassword, String hashed)
{
return check(plainTextPassword, hashed, null, null);
}

@Override
public boolean check(byte[] plainTextPassword, byte[] hashed)
{
return check(plainTextPassword, hashed, null, null);
}

@Override
public boolean check(CharSequence plainTextPassword, String hashed, String salt, CharSequence pepper)
{
byte[] plainTextPasswordAsBytes = Utils.fromCharSequenceToBytes(plainTextPassword);
byte[] saltAsBytes = Utils.fromCharSequenceToBytes(salt);
byte[] hashedAsBytes = Utils.fromCharSequenceToBytes(hashed);
return check(plainTextPasswordAsBytes, hashedAsBytes, saltAsBytes, pepper);
}

@Override
public boolean check(byte[] plainTextPassword, byte[] hashed, byte[] salt, CharSequence pepper)
{
byte[] theSalt;
if (salt == null || salt.length == 0)
{
Object[] params = decodeHash(Utils.fromBytesToString(hashed));
theSalt = (byte[]) params[5];
}
else
{
theSalt = salt;
}

Hash internalHash = internalHash(plainTextPassword, theSalt, pepper);
return slowEquals(internalHash.getResultAsBytes(), hashed);
}

protected static String getUID(int memory, int iterations, int parallelism, int outputLength, Argon2 type, int version)
{
return memory + "|" + iterations + "|" + parallelism + "|" + outputLength + "|" + type.ordinal() + "|" + version;
Expand Down Expand Up @@ -346,8 +243,8 @@ private static void fillBlock(long[] x, long[] y, long[] currentBlock, boolean w
}

private static void roundFunction(long[] block, int v0, int v1, int v2, int v3, int v4, int v5, int v6, int v7, int v8,
int v9, // NOSONAR
int v10, int v11, int v12, int v13, int v14, int v15)
int v9, // NOSONAR
int v10, int v11, int v12, int v13, int v14, int v15)
{
f(block, v0, v4, v8, v12);
f(block, v1, v5, v9, v13);
Expand Down Expand Up @@ -418,7 +315,103 @@ protected static String toString(int memory, int iterations, int parallelism, in
.name() + ", v=" + version;
}

private static String remove(String source, String remove)
{
return source.substring(remove.length());
}

@Override
public Hash hash(CharSequence plainTextPassword)
{
byte[] salt = SaltGenerator.generate();
return internalHash(Utils.fromCharSequenceToBytes(plainTextPassword), salt, null);
}

@Override
public Hash hash(byte[] plainTextPassword)
{
byte[] salt = SaltGenerator.generate();
return internalHash(plainTextPassword, salt, null);
}

@Override
public Hash hash(CharSequence plainTextPassword, String salt)
{
return hash(plainTextPassword, salt, null);
}

@Override
public Hash hash(byte[] plainTextPassword, byte[] salt)
{
return hash(plainTextPassword, salt, null);
}

@Override
public Hash hash(CharSequence plainTextPassword, String salt, CharSequence pepper)
{
return internalHash(Utils.fromCharSequenceToBytes(plainTextPassword), Utils.fromCharSequenceToBytes(salt), pepper);
}

@Override
public Hash hash(byte[] plainTextPassword, byte[] salt, CharSequence pepper)
{
return internalHash(plainTextPassword, salt, pepper);
}

private Hash internalHash(byte[] plainTextPassword, byte[] salt, CharSequence pepper)
{
long[][] blockMemory = copyOf(initialBlockMemory);

if (salt == null)
{
salt = SaltGenerator.generate();
}
initialize(plainTextPassword, salt, Utils.fromCharSequenceToBytes(pepper), null, blockMemory);
fillMemoryBlocks(blockMemory);
byte[] hash = ending(blockMemory);
Hash result = new Hash(this, encodeHash(hash, salt), hash, salt);
result.setPepper(pepper);
return result;
}

@Override
public boolean check(CharSequence plainTextPassword, String hashed)
{
return check(plainTextPassword, hashed, null, null);
}

@Override
public boolean check(byte[] plainTextPassword, byte[] hashed)
{
return check(plainTextPassword, hashed, null, null);
}

@Override
public boolean check(CharSequence plainTextPassword, String hashed, String salt, CharSequence pepper)
{
byte[] plainTextPasswordAsBytes = Utils.fromCharSequenceToBytes(plainTextPassword);
byte[] saltAsBytes = Utils.fromCharSequenceToBytes(salt);
byte[] hashedAsBytes = Utils.fromCharSequenceToBytes(hashed);
return check(plainTextPasswordAsBytes, hashedAsBytes, saltAsBytes, pepper);
}

@Override
public boolean check(byte[] plainTextPassword, byte[] hashed, byte[] salt, CharSequence pepper)
{
byte[] theSalt;
if (salt == null || salt.length == 0)
{
Object[] params = decodeHash(Utils.fromBytesToString(hashed));
theSalt = (byte[]) params[5];
}
else
{
theSalt = salt;
}

Hash internalHash = internalHash(plainTextPassword, theSalt, pepper);
return slowEquals(internalHash.getResultAsBytes(), hashed);
}

/**
* @return the memory in bytes
Expand Down Expand Up @@ -496,8 +489,8 @@ private void initialize(byte[] plainTextPassword, byte[] salt, byte[] secret, by
byte[] initialHash = new byte[64];
blake2b.doFinal(initialHash, 0);

final byte[] zeroBytes = { 0, 0, 0, 0 };
final byte[] oneBytes = { 1, 0, 0, 0 };
final byte[] zeroBytes = {0, 0, 0, 0};
final byte[] oneBytes = {1, 0, 0, 0};

byte[] initialHashWithZeros = getInitialHashLong(initialHash, zeroBytes);
byte[] initialHashWithOnes = getInitialHashLong(initialHash, oneBytes);
Expand Down Expand Up @@ -696,7 +689,7 @@ private int rotatePrevOffset(int currentOffset, int prevOffset)
}

private long getPseudoRandom(int index, long[] addressBlock, long[] inputBlock, long[] zeroBlock, int prevOffset,
boolean dataIndependentAddressing, long[][] blockMemory)
boolean dataIndependentAddressing, long[][] blockMemory)
{
if (dataIndependentAddressing)
{
Expand Down Expand Up @@ -724,7 +717,7 @@ private int getRefLane(int pass, int lane, int slice, long pseudoRandom)
}

private void initAddressBlocks(int pass, int lane, int slice, long[] zeroBlock, long[] inputBlock, long[] addressBlock,
long[][] blockMemory)
long[][] blockMemory)
{
inputBlock[0] = Utils.intToLong(pass);
inputBlock[1] = Utils.intToLong(lane);
Expand Down Expand Up @@ -831,11 +824,6 @@ private long[][] copyOf(long[][] old)
return current;
}

private static String remove(String source, String remove)
{
return source.substring(remove.length());
}

private String encodeHash(byte[] hash, byte[] salt)
{
return "$argon2" + variant.name()
Expand Down
Loading

0 comments on commit f80271d

Please sign in to comment.