Replaced generic RandomOracle with explicit SHA-256 to make description of random oracle simpler for external verifiers
parent
43d4fb75b2
commit
2744005263
|
@ -13,8 +13,6 @@ import meerkat.mixer.MixerOutput;
|
||||||
import meerkat.mixer.proofs.concrete.Mix2nizk;
|
import meerkat.mixer.proofs.concrete.Mix2nizk;
|
||||||
import meerkat.protobuf.ConcreteCrypto;
|
import meerkat.protobuf.ConcreteCrypto;
|
||||||
import meerkat.protobuf.Crypto;
|
import meerkat.protobuf.Crypto;
|
||||||
import org.factcenter.qilin.primitives.RandomOracle;
|
|
||||||
import org.factcenter.qilin.primitives.concrete.DigestOracle;
|
|
||||||
import org.factcenter.qilin.primitives.concrete.ECElGamal;
|
import org.factcenter.qilin.primitives.concrete.ECElGamal;
|
||||||
import org.factcenter.qilin.primitives.concrete.ECGroup;
|
import org.factcenter.qilin.primitives.concrete.ECGroup;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -30,17 +28,17 @@ import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
import static java.lang.System.exit;
|
import static java.lang.System.exit;
|
||||||
import static java.lang.System.in;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Command-line mixProverVerifier and verifier.
|
* Command-line mixProverVerifier and verifier.
|
||||||
*/
|
*/
|
||||||
public class Mix {
|
public class Mix {
|
||||||
|
final static String DEFAULT_ECGROUP = "secp256k1";
|
||||||
final static Logger logger = LoggerFactory.getLogger(Mix.class);
|
final static Logger logger = LoggerFactory.getLogger(Mix.class);
|
||||||
|
|
||||||
public Random rand;
|
public Random rand;
|
||||||
public ECGroup group;
|
public ECGroup group;
|
||||||
public ECElGamalEncryption enc;
|
public ECElGamalEncryption enc;
|
||||||
public RandomOracle randomOracle;
|
|
||||||
public ConcreteCrypto.ElGamalPublicKey serializedPk;
|
public ConcreteCrypto.ElGamalPublicKey serializedPk;
|
||||||
public ECElGamal.SK secretKey;
|
public ECElGamal.SK secretKey;
|
||||||
public Mix2nizk mixProverVerifier;
|
public Mix2nizk mixProverVerifier;
|
||||||
|
@ -49,7 +47,6 @@ public class Mix {
|
||||||
|
|
||||||
public Mix() {
|
public Mix() {
|
||||||
rand = new SecureRandom();
|
rand = new SecureRandom();
|
||||||
randomOracle = new DigestOracle();
|
|
||||||
enc = new ECElGamalEncryption();
|
enc = new ECElGamalEncryption();
|
||||||
serializedPk = null;
|
serializedPk = null;
|
||||||
secretKey = null;
|
secretKey = null;
|
||||||
|
@ -108,7 +105,7 @@ public class Mix {
|
||||||
exit(-2);
|
exit(-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
mixProverVerifier = new Mix2nizk(rand, enc, randomOracle);
|
mixProverVerifier = new Mix2nizk(rand, enc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -117,7 +114,7 @@ public class Mix {
|
||||||
* @param outFile
|
* @param outFile
|
||||||
*/
|
*/
|
||||||
public void createKeypair(File outFile) throws IOException {
|
public void createKeypair(File outFile) throws IOException {
|
||||||
group = new ECGroup("secp256k1");
|
group = new ECGroup(DEFAULT_ECGROUP);
|
||||||
BigInteger sk = ECElGamal.generateSecretKey(group, rand);
|
BigInteger sk = ECElGamal.generateSecretKey(group, rand);
|
||||||
secretKey = new ECElGamal.SK(group, sk);
|
secretKey = new ECElGamal.SK(group, sk);
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@ import meerkat.mixer.proofs.Mix2nizk.Verifier;
|
||||||
import meerkat.mixer.proofs.generic.SigmaFiatShamir;
|
import meerkat.mixer.proofs.generic.SigmaFiatShamir;
|
||||||
import meerkat.protobuf.Crypto;
|
import meerkat.protobuf.Crypto;
|
||||||
import meerkat.protobuf.Mixing;
|
import meerkat.protobuf.Mixing;
|
||||||
import org.factcenter.qilin.primitives.RandomOracle;
|
|
||||||
import org.factcenter.qilin.primitives.concrete.ECGroup;
|
import org.factcenter.qilin.primitives.concrete.ECGroup;
|
||||||
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
@ -28,15 +27,14 @@ public class Mix2nizk implements Prover, Verifier {
|
||||||
/**
|
/**
|
||||||
* @param rand
|
* @param rand
|
||||||
* @param encryptor
|
* @param encryptor
|
||||||
* @param randomOracle - use for Fiat–Shamir heuristic
|
|
||||||
*/
|
*/
|
||||||
public Mix2nizk(Random rand, ECElGamalEncryption encryptor, RandomOracle randomOracle) {
|
public Mix2nizk(Random rand, ECElGamalEncryption encryptor) {
|
||||||
|
|
||||||
this.rand = rand;
|
this.rand = rand;
|
||||||
this.encryptor = encryptor;
|
this.encryptor = encryptor;
|
||||||
this.group = this.encryptor.getGroup();
|
this.group = this.encryptor.getGroup();
|
||||||
this.mixParams = new Statements(encryptor);
|
this.mixParams = new Statements(encryptor);
|
||||||
this.mix2NIZK = new SigmaFiatShamir(ProtobufConcatenators.concatNIZK, randomOracle);
|
this.mix2NIZK = new SigmaFiatShamir(ProtobufConcatenators.concatNIZK);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -3,20 +3,28 @@ package meerkat.mixer.proofs.generic;
|
||||||
import com.google.protobuf.Message;
|
import com.google.protobuf.Message;
|
||||||
import meerkat.mixer.proofs.Concatenator;
|
import meerkat.mixer.proofs.Concatenator;
|
||||||
import meerkat.mixer.proofs.SigmaProtocol;
|
import meerkat.mixer.proofs.SigmaProtocol;
|
||||||
import org.factcenter.qilin.primitives.RandomOracle;
|
|
||||||
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transform a Sigma protocol into a NIZK using Fiat-Shamir
|
* Transform a Sigma protocol into a NIZK using Fiat-Shamir
|
||||||
|
* We use SHA-256 explicitly to make it easier to verify in other codebases
|
||||||
*/
|
*/
|
||||||
public class SigmaFiatShamir<NIZKMsgType, FirstMsgType extends Message, FinalMessageType> {
|
public class SigmaFiatShamir<NIZKMsgType, FirstMsgType extends Message, FinalMessageType> {
|
||||||
final RandomOracle randomOracle;
|
final static String DIGEST_ALG = "SHA-256";
|
||||||
|
final MessageDigest md;
|
||||||
final Concatenator.Pair<NIZKMsgType, FirstMsgType, FinalMessageType> concat;
|
final Concatenator.Pair<NIZKMsgType, FirstMsgType, FinalMessageType> concat;
|
||||||
|
|
||||||
public SigmaFiatShamir(Concatenator.Pair<NIZKMsgType, FirstMsgType, FinalMessageType> concat, RandomOracle randomOracle) {
|
public SigmaFiatShamir(Concatenator.Pair<NIZKMsgType, FirstMsgType, FinalMessageType> concat) {
|
||||||
this.concat = concat;
|
this.concat = concat;
|
||||||
this.randomOracle = randomOracle;
|
try {
|
||||||
|
md = MessageDigest.getInstance(DIGEST_ALG);
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
// Should never happen
|
||||||
|
throw new RuntimeException("Error in instantiating " + DIGEST_ALG + " digest", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -24,21 +32,24 @@ public class SigmaFiatShamir<NIZKMsgType, FirstMsgType extends Message, FinalMes
|
||||||
* @param input - protobuf contains all parameters from the first step of the current proof
|
* @param input - protobuf contains all parameters from the first step of the current proof
|
||||||
* @return randomOracle.hash(input)
|
* @return randomOracle.hash(input)
|
||||||
*/
|
*/
|
||||||
public static BigInteger hash(Message input, RandomOracle randomOracle) {
|
public BigInteger hash(Message input) {
|
||||||
|
md.reset();
|
||||||
|
|
||||||
byte[] arr = input.toByteArray();
|
byte[] arr = input.toByteArray();
|
||||||
return new BigInteger(1,randomOracle.hash(arr,arr.length));
|
byte[] digest = md.digest(arr);
|
||||||
|
return new BigInteger(1,digest);
|
||||||
}
|
}
|
||||||
|
|
||||||
public NIZKMsgType generateNizk(SigmaProtocol.Prover<FirstMsgType, FinalMessageType> prover) {
|
public NIZKMsgType generateNizk(SigmaProtocol.Prover<FirstMsgType, FinalMessageType> prover) {
|
||||||
FirstMsgType firstMessage = prover.getFirstMessage();
|
FirstMsgType firstMessage = prover.getFirstMessage();
|
||||||
BigInteger challenge = hash(firstMessage, randomOracle);
|
BigInteger challenge = hash(firstMessage);
|
||||||
FinalMessageType finalMessage = prover.getFinalMessage(challenge);
|
FinalMessageType finalMessage = prover.getFinalMessage(challenge);
|
||||||
return concat.concatenate(firstMessage, finalMessage);
|
return concat.concatenate(firstMessage, finalMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean verifyNizk(NIZKMsgType NIZK, SigmaProtocol.Verifier<FirstMsgType, FinalMessageType> verifier) {
|
public boolean verifyNizk(NIZKMsgType NIZK, SigmaProtocol.Verifier<FirstMsgType, FinalMessageType> verifier) {
|
||||||
FirstMsgType firstMessage = concat.getMsg1(NIZK);
|
FirstMsgType firstMessage = concat.getMsg1(NIZK);
|
||||||
BigInteger challenge = hash(firstMessage, randomOracle);
|
BigInteger challenge = hash(firstMessage);
|
||||||
return verifier.verify(firstMessage, challenge, concat.getMsg2(NIZK));
|
return verifier.verify(firstMessage, challenge, concat.getMsg2(NIZK));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,6 @@ public class ECParamTestBase {
|
||||||
public ECElGamal.SK key;
|
public ECElGamal.SK key;
|
||||||
public ECGroup group;
|
public ECGroup group;
|
||||||
public ECElGamalEncryption enc;
|
public ECElGamalEncryption enc;
|
||||||
public RandomOracle randomOracle = new DigestOracle();
|
|
||||||
public ConcreteCrypto.ElGamalPublicKey serializedPk;
|
public ConcreteCrypto.ElGamalPublicKey serializedPk;
|
||||||
|
|
||||||
public ECParamTestBase() {
|
public ECParamTestBase() {
|
||||||
|
|
|
@ -29,7 +29,7 @@ public class MixingTest extends ECParamTestBase {
|
||||||
random = new Random(1);
|
random = new Random(1);
|
||||||
randomMixer = new Random(2);
|
randomMixer = new Random(2);
|
||||||
randomProver = new Random(3);
|
randomProver = new Random(3);
|
||||||
mix2nizk = new Mix2nizk(randomProver, enc,randomOracle);
|
mix2nizk = new Mix2nizk(randomProver, enc);
|
||||||
mixer = new MixGenerator(mix2nizk, enc);
|
mixer = new MixGenerator(mix2nizk, enc);
|
||||||
|
|
||||||
// generate n
|
// generate n
|
||||||
|
|
|
@ -2,8 +2,6 @@ package meerkat.mixer.proofs;
|
||||||
|
|
||||||
import com.google.protobuf.Message;
|
import com.google.protobuf.Message;
|
||||||
import meerkat.mixer.proofs.generic.SigmaFiatShamir;
|
import meerkat.mixer.proofs.generic.SigmaFiatShamir;
|
||||||
import org.factcenter.qilin.primitives.RandomOracle;
|
|
||||||
import org.factcenter.qilin.primitives.concrete.DigestOracle;
|
|
||||||
import org.factcenter.qilin.util.Pair;
|
import org.factcenter.qilin.util.Pair;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -11,7 +9,7 @@ import org.junit.Test;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generic test for Sigma Protocol
|
* Generic test for Sigma Protocol
|
||||||
|
@ -19,8 +17,6 @@ import static org.junit.Assert.*;
|
||||||
abstract public class SigmaProtocolTest<M1 extends Message, M2> {
|
abstract public class SigmaProtocolTest<M1 extends Message, M2> {
|
||||||
public final int NUM_REPEAT = 10;
|
public final int NUM_REPEAT = 10;
|
||||||
|
|
||||||
final protected RandomOracle randomOracle = new DigestOracle();
|
|
||||||
|
|
||||||
abstract protected void generateRandomTrueStatement();
|
abstract protected void generateRandomTrueStatement();
|
||||||
|
|
||||||
abstract protected void generateRandomFalseStatement();
|
abstract protected void generateRandomFalseStatement();
|
||||||
|
@ -97,7 +93,7 @@ abstract public class SigmaProtocolTest<M1 extends Message, M2> {
|
||||||
for (int i = 0; i < NUM_REPEAT; ++i) {
|
for (int i = 0; i < NUM_REPEAT; ++i) {
|
||||||
generateRandomTrueStatement();
|
generateRandomTrueStatement();
|
||||||
|
|
||||||
SigmaFiatShamir<Pair<M1,M2>, M1, M2> fiatShamir = new SigmaFiatShamir<Pair<M1,M2>, M1, M2>(nizkConcat, randomOracle);
|
SigmaFiatShamir<Pair<M1,M2>, M1, M2> fiatShamir = new SigmaFiatShamir<Pair<M1,M2>, M1, M2>(nizkConcat);
|
||||||
|
|
||||||
prover = getNewProver();
|
prover = getNewProver();
|
||||||
Pair<M1,M2> nizk = fiatShamir.generateNizk(prover);
|
Pair<M1,M2> nizk = fiatShamir.generateNizk(prover);
|
||||||
|
|
|
@ -26,7 +26,7 @@ public class Mix2ProofTest extends ECParamTestBase {
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup() throws Exception {
|
public void setup() throws Exception {
|
||||||
nizk = new Mix2nizk(rand, enc, randomOracle);
|
nizk = new Mix2nizk(rand, enc);
|
||||||
verifier = nizk;
|
verifier = nizk;
|
||||||
prover = nizk;
|
prover = nizk;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,15 +35,14 @@ public class ZeroKnowledgeProof {
|
||||||
Crypto.RerandomizableEncryptedMessage[] reencryptedMessage;
|
Crypto.RerandomizableEncryptedMessage[] reencryptedMessage;
|
||||||
|
|
||||||
public void setup() throws Exception {
|
public void setup() throws Exception {
|
||||||
rand = new Random();
|
rand = new Random(1);
|
||||||
group = new ECGroup("secp256k1");
|
group = new ECGroup("secp256k1");
|
||||||
BigInteger sk = ECElGamal.generateSecretKey(group, rand);
|
BigInteger sk = ECElGamal.generateSecretKey(group, rand);
|
||||||
key = new ECElGamal.SK(group, sk);
|
key = new ECElGamal.SK(group, sk);
|
||||||
serializedPk = Util.encodePK(group, key);
|
serializedPk = Util.encodePK(group, key);
|
||||||
enc = new ECElGamalEncryption();
|
enc = new ECElGamalEncryption();
|
||||||
enc.init(serializedPk);
|
enc.init(serializedPk);
|
||||||
RandomOracle randomOracle = new DigestOracle();
|
prover = new Mix2nizk(rand,enc);
|
||||||
prover = new Mix2nizk(new Random(),enc,randomOracle);
|
|
||||||
int LogVotes = 12;
|
int LogVotes = 12;
|
||||||
int layers = 2*LogVotes - 1;
|
int layers = 2*LogVotes - 1;
|
||||||
n = layers * (1<<LogVotes) / 2;
|
n = layers * (1<<LogVotes) / 2;
|
||||||
|
|
Loading…
Reference in New Issue