package com.subgraph.orchid.crypto;
import java.nio.ByteBuffer;
public class TorKeyDerivation {
private final byte[] kdfBuffer;
private int round;
public TorKeyDerivation(byte[] seed) {
this.kdfBuffer = new byte[seed.length + 1];
System.arraycopy(seed, 0, kdfBuffer, 0, seed.length);
}
public void deriveKeys(byte[] keyMaterialOut, byte[] verifyHashOut) {
final ByteBuffer keyData = deriveKeys(keyMaterialOut.length + verifyHashOut.length);
keyData.get(verifyHashOut);
keyData.get(keyMaterialOut);
}
public ByteBuffer deriveKeys(int length) {
final ByteBuffer outputBuffer = ByteBuffer.allocate(length);
round = 0;
while(outputBuffer.hasRemaining()) {
byte[] bs = calculateRoundData();
int n = Math.min(outputBuffer.remaining(), bs.length);
outputBuffer.put(bs, 0, n);
}
outputBuffer.flip();
return outputBuffer;
}
private byte[] calculateRoundData() {
final TorMessageDigest md = new TorMessageDigest();
kdfBuffer[kdfBuffer.length - 1] = (byte) round;
round += 1;
md.update(kdfBuffer);
return md.getDigestBytes();
}
}