package peergos.shared.crypto.hash;
import java.security.*;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import peergos.shared.scrypt.com.lambdaworks.crypto.SCrypt;
import peergos.shared.user.*;
public class ScryptJava implements LoginHasher {
private static final int LOG_2_MIN_RAM = 17;
@Override
public CompletableFuture<byte[]> hashToKeyBytes(String username, String password, UserGenerationAlgorithm algorithm) {
CompletableFuture<byte[]> res = new CompletableFuture<>();
if (algorithm.getType() == UserGenerationAlgorithm.Type.ScryptEd25519Curve25519) {
byte[] hash = Arrays.copyOfRange(Hash.sha256(password.getBytes()), 2, 34);
byte[] salt = username.getBytes();
try {
ScryptEd25519Curve25519 params = (ScryptEd25519Curve25519) algorithm;
long t1 = System.currentTimeMillis();
int parallelism = params.parallelism;
int nOutputBytes = params.outputBytes;
int cpuCost = params.cpuCost;
int memoryCost = 1 << params.memoryCost; // Amount of ram required to run algorithm in bytes
byte[] scryptHash = SCrypt.scrypt(hash, salt, memoryCost, cpuCost, parallelism, nOutputBytes);
long t2 = System.currentTimeMillis();
System.out.println("Scrypt hashing took: " + (t2 - t1) + " mS");
res.complete(scryptHash);
return res;
} catch (GeneralSecurityException gse) {
res.completeExceptionally(gse);
}
return res;
}
throw new IllegalStateException("Unknown user generation algorithm: " + algorithm);
}
}