Skip to content

Commit

Permalink
feat: force the same key for each poll
Browse files Browse the repository at this point in the history
  • Loading branch information
ctrlc03 committed Jan 22, 2025
1 parent 00a4f78 commit fe19928
Show file tree
Hide file tree
Showing 13 changed files with 105 additions and 174 deletions.
13 changes: 5 additions & 8 deletions packages/circuits/circom/anon/pollJoining.circom
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ template PollJoining(stateTreeDepth) {

// User's private key
signal input privKey;
// Poll's private key
signal input pollPrivKey;
// Poll's public key
signal input pollPubKey[2];
// Siblings
Expand All @@ -37,18 +35,17 @@ template PollJoining(stateTreeDepth) {
// Hash the public key
var pubKeyHash = PoseidonHasher(2)([derivedPubKey[0], derivedPubKey[1]]);

// Poll private to public key to verify the correct one is used to join the poll (public input)
var derivedPollPubKey[2] = PrivToPubKey()(pollPrivKey);
derivedPollPubKey[0] === pollPubKey[0];
derivedPollPubKey[1] === pollPubKey[1];
// Ensure the poll public key is the same as the maci one (public input)
derivedPubKey[0] === pollPubKey[0];
derivedPubKey[1] === pollPubKey[1];

// Inclusion proof
var stateLeafQip = BinaryMerkleRoot(stateTreeDepth)(
var calculatedRoot = BinaryMerkleRoot(stateTreeDepth)(
pubKeyHash,
actualStateTreeDepth,
indices,
siblings
);

stateLeafQip === stateRoot;
calculatedRoot === stateRoot;
}
16 changes: 6 additions & 10 deletions packages/circuits/ts/__tests__/PollJoining.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ describe("Poll Joining circuit", function test() {

type PollJoiningCircuitInputs = [
"privKey",
"pollPrivKey",
"pollPubKey",
"stateLeaf",
"siblings",
Expand All @@ -42,7 +41,6 @@ describe("Poll Joining circuit", function test() {
let pollId: bigint;
let poll: Poll;
let users: Keypair[];
const { privKey: pollPrivKey, pubKey: pollPubKey } = new Keypair();
const messages: Message[] = [];
const commands: PCommand[] = [];

Expand All @@ -65,24 +63,24 @@ describe("Poll Joining circuit", function test() {
poll.updatePoll(BigInt(maciState.pubKeys.length));

// Join the poll
const { privKey } = users[0];
const { privKey, pubKey } = users[0];

const nullifier = poseidon([BigInt(privKey.rawPrivKey.toString())]);
const timestamp = BigInt(Math.floor(Date.now() / 1000));

const stateIndex = BigInt(poll.joinPoll(nullifier, pollPubKey, voiceCreditBalance, timestamp));
const stateIndex = BigInt(poll.joinPoll(nullifier, pubKey, voiceCreditBalance, timestamp));

// First command (valid)
const command = new PCommand(
stateIndex,
pollPubKey,
pubKey,
BigInt(0), // voteOptionIndex,
BigInt(9), // vote weight
BigInt(1), // nonce
BigInt(pollId),
);

const signature = command.sign(pollPrivKey);
const signature = command.sign(privKey);

const ecdhKeypair = new Keypair();
const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey);
Expand All @@ -97,27 +95,25 @@ describe("Poll Joining circuit", function test() {
});

it("should produce a proof", async () => {
const privateKey = users[0].privKey;
const { privKey: privateKey, pubKey: pollPubKey } = users[0];
const stateLeafIndex = BigInt(1);

const inputs = poll.joiningCircuitInputs({
maciPrivKey: privateKey,
stateLeafIndex,
pollPrivKey,
pollPubKey,
}) as unknown as IPollJoiningInputs;
const witness = await circuit.calculateWitness(inputs);
await circuit.expectConstraintPass(witness);
});

it("should fail for fake witness", async () => {
const privateKey = users[0].privKey;
const { privKey: privateKey, pubKey: pollPubKey } = users[0];
const stateLeafIndex = BigInt(1);

const inputs = poll.joiningCircuitInputs({
maciPrivKey: privateKey,
stateLeafIndex,
pollPrivKey,
pollPubKey,
}) as unknown as IPollJoiningInputs;
const witness = await circuit.calculateWitness(inputs);
Expand Down
61 changes: 25 additions & 36 deletions packages/circuits/ts/__tests__/ProcessMessages.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,9 @@ describe("ProcessMessage circuit", function test() {
before(() => {
// Sign up and publish
const users = new Array(5).fill(0).map(() => new Keypair());
const pollKeys: Keypair[] = [];

users.forEach((userKeypair) => {
maciState.signUp(userKeypair.pubKey);
pollKeys.push(new Keypair());
});

pollId = maciState.deployPoll(
Expand All @@ -88,7 +86,7 @@ describe("ProcessMessage circuit", function test() {
// Join the poll
for (let i = 0; i < users.length; i += 1) {

Check failure on line 87 in packages/circuits/ts/__tests__/ProcessMessages.test.ts

View workflow job for this annotation

GitHub Actions / check (lint:ts)

Expected a `for-of` loop instead of a `for` loop with this simple iteration
const { privKey } = users[i];
const { pubKey: pollPubKey } = pollKeys[i];
const { pubKey: pollPubKey } = users[i];

const nullifier = poseidon([BigInt(privKey.rawPrivKey.toString())]);
const timestamp = BigInt(Math.floor(Date.now() / 1000));
Expand Down Expand Up @@ -119,14 +117,14 @@ describe("ProcessMessage circuit", function test() {
// First command (valid)
const command = new PCommand(
5n,
pollKeys[4].pubKey,
users[4].pubKey,
voteOptionIndex, // voteOptionIndex,
voteWeight, // vote weight
BigInt(2), // nonce
BigInt(pollId),
);

const signature = command.sign(pollKeys[4].privKey);
const signature = command.sign(users[4].privKey);

const ecdhKeypair = new Keypair();
const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey);
Expand Down Expand Up @@ -172,8 +170,7 @@ describe("ProcessMessage circuit", function test() {
poll.updatePoll(BigInt(maciState.pubKeys.length));

// Join the poll
const { privKey } = userKeypair;
const { privKey: pollPrivKey, pubKey: pollPubKey } = new Keypair();
const { privKey, pubKey: pollPubKey } = userKeypair;

const nullifier = poseidon([BigInt(privKey.rawPrivKey.toString())]);
const timestamp = BigInt(Math.floor(Date.now() / 1000));
Expand All @@ -190,7 +187,7 @@ describe("ProcessMessage circuit", function test() {
BigInt(pollId),
);

const signature = command.sign(pollPrivKey);
const signature = command.sign(privKey);

const ecdhKeypair = new Keypair();
const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey);
Expand All @@ -209,7 +206,7 @@ describe("ProcessMessage circuit", function test() {
BigInt(1), // nonce
BigInt(pollId),
);
const signature2 = command2.sign(pollPrivKey);
const signature2 = command2.sign(privKey);

const ecdhKeypair2 = new Keypair();
const sharedKey2 = Keypair.genEcdhSharedKey(ecdhKeypair2.privKey, coordinatorKeypair.pubKey);
Expand Down Expand Up @@ -277,8 +274,7 @@ describe("ProcessMessage circuit", function test() {
poll.updatePoll(BigInt(maciState.pubKeys.length));

// Join the poll
const { privKey } = userKeypair;
const { privKey: pollPrivKey, pubKey: pollPubKey } = new Keypair();
const { privKey, pubKey: pollPubKey } = userKeypair;

const nullifier = poseidon([BigInt(privKey.rawPrivKey.toString())]);
const timestamp = BigInt(1);
Expand All @@ -294,7 +290,7 @@ describe("ProcessMessage circuit", function test() {
BigInt(pollId),
);

const signature = command.sign(pollPrivKey);
const signature = command.sign(privKey);

const ecdhKeypair = new Keypair();
const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey);
Expand Down Expand Up @@ -360,16 +356,13 @@ describe("ProcessMessage circuit", function test() {

poll.updatePoll(BigInt(maciState.pubKeys.length));

const { privKey } = userKeypair;
const { privKey: pollPrivKey, pubKey: pollPubKey } = new Keypair();
const { privKey, pubKey: pollPubKey } = userKeypair;

const nullifier = poseidon([BigInt(privKey.rawPrivKey.toString())]);
const timestamp = BigInt(1);

const stateIndex = poll.joinPoll(nullifier, pollPubKey, voiceCreditBalance, timestamp);

const { privKey: pollPrivKey2, pubKey: pollPubKey2 } = new Keypair();

// Vote for option 0
const command = new PCommand(
BigInt(stateIndex), // BigInt(1),
Expand All @@ -380,7 +373,7 @@ describe("ProcessMessage circuit", function test() {
BigInt(pollId),
);

const signature = command.sign(pollPrivKey);
const signature = command.sign(privKey);

const ecdhKeypair = new Keypair();
const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey);
Expand All @@ -399,7 +392,7 @@ describe("ProcessMessage circuit", function test() {
BigInt(2), // nonce
BigInt(pollId),
);
const signature2 = command2.sign(pollPrivKey);
const signature2 = command2.sign(privKey);

const ecdhKeypair2 = new Keypair();
const sharedKey2 = Keypair.genEcdhSharedKey(ecdhKeypair2.privKey, coordinatorKeypair.pubKey);
Expand All @@ -411,14 +404,14 @@ describe("ProcessMessage circuit", function test() {
// Change key
const command3 = new PCommand(
BigInt(stateIndex), // BigInt(1),
pollPubKey2,
pollPubKey,
BigInt(1), // voteOptionIndex,
BigInt(0), // vote weight
BigInt(1), // nonce
BigInt(pollId),
);

const signature3 = command3.sign(pollPrivKey2);
const signature3 = command3.sign(privKey);

const ecdhKeypair3 = new Keypair();
const sharedKey3 = Keypair.genEcdhSharedKey(ecdhKeypair3.privKey, coordinatorKeypair.pubKey);
Expand Down Expand Up @@ -483,8 +476,7 @@ describe("ProcessMessage circuit", function test() {
poll.updatePoll(BigInt(maciState.pubKeys.length));

// Join the poll
const { privKey } = userKeypair;
const { privKey: pollPrivKey, pubKey: pollPubKey } = new Keypair();
const { privKey, pubKey: pollPubKey } = userKeypair;

const nullifier = poseidon([BigInt(privKey.rawPrivKey.toString())]);
const timestamp = BigInt(Math.floor(Date.now() / 1000));
Expand All @@ -503,7 +495,7 @@ describe("ProcessMessage circuit", function test() {
BigInt(pollId),
);

const signature = command.sign(pollPrivKey);
const signature = command.sign(privKey);

const ecdhKeypair = new Keypair();
const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey);
Expand Down Expand Up @@ -547,8 +539,7 @@ describe("ProcessMessage circuit", function test() {
poll.updatePoll(BigInt(maciState.pubKeys.length));

// Join the poll
const { privKey } = userKeypair;
const { privKey: pollPrivKey, pubKey: pollPubKey } = new Keypair();
const { privKey, pubKey: pollPubKey } = userKeypair;

const nullifier = poseidon([BigInt(privKey.rawPrivKey.toString())]);
const timestamp = BigInt(Math.floor(Date.now() / 1000));
Expand Down Expand Up @@ -585,7 +576,7 @@ describe("ProcessMessage circuit", function test() {
pollId,
);

const signature = command.sign(pollPrivKey);
const signature = command.sign(privKey);

const ecdhKeypair = new Keypair();
const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey);
Expand All @@ -604,7 +595,7 @@ describe("ProcessMessage circuit", function test() {
1n, // nonce
pollId,
);
const signature2 = command2.sign(pollPrivKey);
const signature2 = command2.sign(privKey);

const ecdhKeypair2 = new Keypair();
const sharedKey2 = Keypair.genEcdhSharedKey(ecdhKeypair2.privKey, coordinatorKeypair.pubKey);
Expand Down Expand Up @@ -670,8 +661,7 @@ describe("ProcessMessage circuit", function test() {
poll.updatePoll(BigInt(maciState.pubKeys.length));

// Join the poll
const { privKey } = userKeypair;
const { privKey: pollPrivKey, pubKey: pollPubKey } = new Keypair();
const { privKey, pubKey: pollPubKey } = userKeypair;

const nullifier = poseidon([BigInt(privKey.rawPrivKey.toString())]);
const timestamp = BigInt(Math.floor(Date.now() / 1000));
Expand Down Expand Up @@ -708,7 +698,7 @@ describe("ProcessMessage circuit", function test() {
pollId,
);

const signature = command.sign(pollPrivKey);
const signature = command.sign(privKey);

const ecdhKeypair = new Keypair();
const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey);
Expand All @@ -732,7 +722,7 @@ describe("ProcessMessage circuit", function test() {
1n, // nonce
pollId,
);
const signature2 = command2.sign(pollPrivKey);
const signature2 = command2.sign(privKey);

const ecdhKeypair2 = new Keypair();
const sharedKey2 = Keypair.genEcdhSharedKey(ecdhKeypair2.privKey, coordinatorKeypair.pubKey);
Expand Down Expand Up @@ -800,8 +790,7 @@ describe("ProcessMessage circuit", function test() {
poll.updatePoll(BigInt(maciState.pubKeys.length));

// Join the poll
const { privKey } = userKeypair;
const { privKey: pollPrivKey, pubKey: pollPubKey } = new Keypair();
const { privKey, pubKey: pollPubKey } = userKeypair;

const nullifier = poseidon([BigInt(privKey.rawPrivKey.toString())]);
const timestamp = BigInt(Math.floor(Date.now() / 1000));
Expand Down Expand Up @@ -837,7 +826,7 @@ describe("ProcessMessage circuit", function test() {
pollId,
);

const signatureFinal = commandFinal.sign(pollPrivKey);
const signatureFinal = commandFinal.sign(privKey);

const ecdhKeypairFinal = new Keypair();
const sharedKeyFinal = Keypair.genEcdhSharedKey(ecdhKeypairFinal.privKey, coordinatorKeypair.pubKey);
Expand All @@ -857,7 +846,7 @@ describe("ProcessMessage circuit", function test() {
pollId,
);

const signature = command.sign(pollPrivKey);
const signature = command.sign(privKey);

const ecdhKeypair = new Keypair();
const sharedKey = Keypair.genEcdhSharedKey(ecdhKeypair.privKey, coordinatorKeypair.pubKey);
Expand All @@ -881,7 +870,7 @@ describe("ProcessMessage circuit", function test() {
1n, // nonce
pollId,
);
const signature2 = command2.sign(pollPrivKey);
const signature2 = command2.sign(privKey);

const ecdhKeypair2 = new Keypair();
const sharedKey2 = Keypair.genEcdhSharedKey(ecdhKeypair2.privKey, coordinatorKeypair.pubKey);
Expand Down
Loading

0 comments on commit fe19928

Please sign in to comment.