Thanks for the explanation, now I added a check for duplicate data at each processing step.
For the encryption, for each sender we generate a new public/private key pair using curve25519, unique for each sender/shuffle/recipient combination, and then use this plus the recipient public key to generate a DH shared key, then use AES for the actual encryption. If you take a look at the current way public keys are generated based on secret phrase:
https://bitbucket.org/JeanLucPicard/nxt/src/369546f91ba32142562c18d224369ea64a3f0720/src/java/nxt/crypto/Crypto.java?at=master#Crypto.java-63 , for shuffling I have added generation of one-time keys based on secretPhrase plus known nonces:
public static byte[] getKeySeed(String secretPhrase, byte[]... nonces) {
MessageDigest digest = Crypto.sha256();
digest.update(Convert.toBytes(secretPhrase));
for (byte[] nonce : nonces) {
digest.update(nonce);
}
return digest.digest();
}
public static byte[] getPublicKey(byte[] keySeed) {
byte[] publicKey = new byte[32];
Curve25519.keygen(publicKey, null, Arrays.copyOf(keySeed, keySeed.length));
return publicKey;
}
public static byte[] getPublicKey(String secretPhrase) {
byte[] publicKey = new byte[32];
Curve25519.keygen(publicKey, null, Crypto.sha256().digest(Convert.toBytes(secretPhrase)));
return publicKey;
}
public static byte[] getPrivateKey(byte[] keySeed) {
byte[] s = Arrays.copyOf(keySeed, keySeed.length);
Curve25519.clamp(s);
return s;
}
public static byte[] getPrivateKey(String secretPhrase) {
byte[] s = Crypto.sha256().digest(Convert.toBytes(secretPhrase));
Curve25519.clamp(s);
return s;
}
and for the one-time keys used in the shuffle, shuffleId and recipientId are used as nonces. Then the one-time sender public key is added to the encrypted data, to allow its decryption by the recipient, yet it is not possible for the recipient (or anyone else) to tell who the sender of each encrypted data is.
If the blame phase needs to be entered, each participant discloses the array of sha256 digests ("keySeeds") used to generate each public/private key pair he used to encrypt to each of the next participants, which allows anyone to decrypt the content ot the data.