But then you trust the initiator of the shuffle to not be an attacker himself. If he occupies the first k spots, it is as if the shuffle starts from k+1. At least in the Nxt core implementation, the shuffle creator is equal to all other participants, and will be penalized the same way if discovered to cheat.
I have all parts of the algorithm implemented and working now, including the blame phase of detecting and penalizing rogue participants who either submit invalid data or do not submit their transactions in time, with all integration tests passing. What remains is only to make the shuffle process user friendly, by automating the submission of process/verify/cancel transactions.
For the AES encryption, I now use GCMBlockCipher:
public static byte[] aesGCMEncrypt(byte[] plaintext, byte[] key) {
try {
byte[] iv = new byte[16];
secureRandom.get().nextBytes(iv);
GCMBlockCipher aes = new GCMBlockCipher(new AESEngine());
CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(key), iv);
aes.init(true, ivAndKey);
byte[] output = new byte[aes.getOutputSize(plaintext.length)];
int ciphertextLength = aes.processBytes(plaintext, 0, plaintext.length, output, 0);
ciphertextLength += aes.doFinal(output, ciphertextLength);
byte[] result = new byte[iv.length + ciphertextLength];
System.arraycopy(iv, 0, result, 0, iv.length);
System.arraycopy(output, 0, result, iv.length, ciphertextLength);
return result;
} catch (InvalidCipherTextException e) {
throw new RuntimeException(e.getMessage(), e);
}
}