mirror of
https://github.com/logos-blockchain/logos-blockchain-pocs.git
synced 2026-01-02 13:13:09 +00:00
updated the circuit to reflect the names of the specs
This commit is contained in:
parent
73e5ecb7e7
commit
5c0465a41e
@ -292,36 +292,36 @@ K_two = F(randrange(0,p,1))
|
||||
# 5) Assemble JSON
|
||||
inp = {
|
||||
"session": str(session),
|
||||
"Qc": str(Qc),
|
||||
"Ql": str(Ql),
|
||||
"pk_root": str(core_root),
|
||||
"aged_root": str(aged_root),
|
||||
"core_quota": str(Qc),
|
||||
"leader_quota": str(Ql),
|
||||
"core_root": str(core_root),
|
||||
"pol_ledger_aged": str(aged_root),
|
||||
"K_part_one": str(K_one),
|
||||
"K_part_two": str(K_two),
|
||||
"selector": str(core_or_leader),
|
||||
"index": str(index),
|
||||
"core_sk": str(core_sk),
|
||||
"core_path": [str(x) for x in core_nodes],
|
||||
"core_selectors": [str(x) for x in core_selectors],
|
||||
"slot": str(slot_number),
|
||||
"epoch_nonce": str(epoch_nonce),
|
||||
"t0": str(t0),
|
||||
"t1": str(t1),
|
||||
"slot_secret": str(slot_secret),
|
||||
"slot_secret_path": [str(x) for x in slot_secret_path],
|
||||
"aged_nodes": [str(x) for x in aged_nodes],
|
||||
"aged_selectors": [str(x) for x in aged_selectors],
|
||||
"transaction_hash": str(tx_hash),
|
||||
"output_number": str(output_number),
|
||||
"starting_slot": str(starting_slot),
|
||||
"secrets_root": str(secret_root),
|
||||
"value": str(value)
|
||||
"core_path_selectors": [str(x) for x in core_selectors],
|
||||
"pol_sl": str(slot_number),
|
||||
"pol_epoch_nonce": str(epoch_nonce),
|
||||
"pol_t0": str(t0),
|
||||
"pol_t1": str(t1),
|
||||
"pol_slot_secret": str(slot_secret),
|
||||
"pol_slot_secret_path": [str(x) for x in slot_secret_path],
|
||||
"pol_noteid_path": [str(x) for x in aged_nodes],
|
||||
"pol_noteid_path_selectors": [str(x) for x in aged_selectors],
|
||||
"pol_note_tx_hash": str(tx_hash),
|
||||
"pol_note_output_number": str(output_number),
|
||||
"pol_sk_starting_slot": str(starting_slot),
|
||||
"secrets_root": str(secret_root), # THIS NEEDS TO BE REMOVED
|
||||
"pol_note_value": str(value)
|
||||
}
|
||||
|
||||
if core_or_leader == 0:
|
||||
inp["aged_root"] = randrange(0,p,1)
|
||||
inp["pol_ledger_aged"] = randrange(0,p,1)
|
||||
else:
|
||||
inp["pk_root"] = randrange(0,p,1)
|
||||
inp["core_root"] = randrange(0,p,1)
|
||||
|
||||
import json
|
||||
|
||||
|
||||
@ -17,10 +17,10 @@ include "../Mantle/pol.circom"; // defines proof_of_leadership
|
||||
template ProofOfQuota(nLevelsPK, nLevelsPol, bitsQuota) {
|
||||
// Public Inputs
|
||||
signal input session; // session s
|
||||
signal input Qc; // core quota Q_C
|
||||
signal input Ql; // leadership quota Q_L
|
||||
signal input pk_root; // Merkle root of registered core-node public keys
|
||||
signal input aged_root; // PoL: aged notes root
|
||||
signal input core_quota;
|
||||
signal input leader_quota;
|
||||
signal input core_root;
|
||||
signal input pol_ledger_aged; // PoL: aged notes root
|
||||
signal input K_part_one; // Blend: one-time signature public key
|
||||
signal input K_part_two; // Blend: one-time signature public key
|
||||
|
||||
@ -29,7 +29,7 @@ template ProofOfQuota(nLevelsPK, nLevelsPol, bitsQuota) {
|
||||
signal dummy_two;
|
||||
dummy_two <== K_part_two * K_part_two;
|
||||
|
||||
signal output nullifier; //key_nullifier
|
||||
signal output key_nullifier; //key_nullifier
|
||||
|
||||
// Private Inputs
|
||||
signal input selector; // 0 = core, 1 = leader
|
||||
@ -38,24 +38,24 @@ template ProofOfQuota(nLevelsPK, nLevelsPol, bitsQuota) {
|
||||
// Core-nodes inputs
|
||||
signal input core_sk; // core node secret key
|
||||
signal input core_path[nLevelsPK]; // Merkle path for core PK
|
||||
signal input core_selectors[nLevelsPK]; // path selectors (bits)
|
||||
signal input core_path_selectors[nLevelsPK]; // path selectors (bits)
|
||||
|
||||
// PoL branch inputs (all the PoL private data)
|
||||
signal input slot;
|
||||
signal input epoch_nonce;
|
||||
signal input t0;
|
||||
signal input t1;
|
||||
signal input slot_secret;
|
||||
signal input slot_secret_path[nLevelsPol];
|
||||
signal input pol_sl;
|
||||
signal input pol_epoch_nonce;
|
||||
signal input pol_t0;
|
||||
signal input pol_t1;
|
||||
signal input pol_slot_secret;
|
||||
signal input pol_slot_secret_path[nLevelsPol];
|
||||
|
||||
signal input aged_nodes[32];
|
||||
signal input aged_selectors[32];
|
||||
signal input transaction_hash;
|
||||
signal input output_number;
|
||||
signal input pol_noteid_path[32];
|
||||
signal input pol_noteid_path_selectors[32];
|
||||
signal input pol_note_tx_hash;
|
||||
signal input pol_note_output_number;
|
||||
|
||||
signal input starting_slot;
|
||||
signal input secrets_root;
|
||||
signal input value;
|
||||
signal input pol_sk_starting_slot;
|
||||
signal input secrets_root; // THIS NEEDS TO BE REMOVED
|
||||
signal input pol_note_value;
|
||||
|
||||
|
||||
|
||||
@ -70,37 +70,37 @@ template ProofOfQuota(nLevelsPK, nLevelsPol, bitsQuota) {
|
||||
signal pk_core;
|
||||
pk_core <== kdf.out;
|
||||
|
||||
// Merkle‐verify pk_core in pk_root
|
||||
// Merkle‐verify pk_core in core_root
|
||||
component coreReg = proof_of_membership(nLevelsPK);
|
||||
for (var i = 0; i < nLevelsPK; i++) {
|
||||
core_selectors[i] * (1 - core_selectors[i]) === 0;
|
||||
core_path_selectors[i] * (1 - core_path_selectors[i]) === 0;
|
||||
coreReg.nodes[i] <== core_path[i];
|
||||
coreReg.selector[i] <== core_selectors[i];
|
||||
coreReg.selector[i] <== core_path_selectors[i];
|
||||
}
|
||||
coreReg.root <== pk_root;
|
||||
coreReg.root <== core_root;
|
||||
coreReg.leaf <== pk_core;
|
||||
|
||||
// enforce potential PoL (without verification that the note is unspent)
|
||||
// (All constraints inside pol ensure LeadershipVerify)
|
||||
component would_win = would_win_leadership(nLevelsPol);
|
||||
would_win.slot <== slot;
|
||||
would_win.epoch_nonce <== epoch_nonce;
|
||||
would_win.t0 <== t0;
|
||||
would_win.t1 <== t1;
|
||||
would_win.slot_secret <== slot_secret;
|
||||
would_win.slot <== pol_sl;
|
||||
would_win.epoch_nonce <== pol_epoch_nonce;
|
||||
would_win.t0 <== pol_t0;
|
||||
would_win.t1 <== pol_t1;
|
||||
would_win.slot_secret <== pol_slot_secret;
|
||||
for (var i = 0; i < nLevelsPol; i++) {
|
||||
would_win.slot_secret_path[i] <== slot_secret_path[i];
|
||||
would_win.slot_secret_path[i] <== pol_slot_secret_path[i];
|
||||
}
|
||||
for (var i = 0; i < 32; i++) {
|
||||
would_win.aged_nodes[i] <== aged_nodes[i];
|
||||
would_win.aged_selectors[i] <== aged_selectors[i];
|
||||
would_win.aged_nodes[i] <== pol_noteid_path[i];
|
||||
would_win.aged_selectors[i] <== pol_noteid_path_selectors[i];
|
||||
}
|
||||
would_win.aged_root <== aged_root;
|
||||
would_win.transaction_hash <== transaction_hash;
|
||||
would_win.output_number <== output_number;
|
||||
would_win.starting_slot <== starting_slot;
|
||||
would_win.aged_root <== pol_ledger_aged;
|
||||
would_win.transaction_hash <== pol_note_tx_hash;
|
||||
would_win.output_number <== pol_note_output_number;
|
||||
would_win.starting_slot <== pol_sk_starting_slot;
|
||||
would_win.secrets_root <== secrets_root;
|
||||
would_win.value <== value;
|
||||
would_win.value <== pol_note_value;
|
||||
|
||||
// Enforce the selected role is correct
|
||||
selector * (would_win.out - coreReg.out) + coreReg.out === 1;
|
||||
@ -108,10 +108,10 @@ template ProofOfQuota(nLevelsPK, nLevelsPol, bitsQuota) {
|
||||
|
||||
|
||||
|
||||
// Quota check: index < Qc if core, index < Ql if leader
|
||||
// Quota check: index < core_quota if core, index < leader_quota if leader
|
||||
component cmp = SafeLessThan(bitsQuota);
|
||||
cmp.in[0] <== index;
|
||||
cmp.in[1] <== selector * (Ql - Qc) + Qc;
|
||||
cmp.in[1] <== selector * (leader_quota - core_quota) + core_quota;
|
||||
cmp.out === 1;
|
||||
|
||||
// Derive selection_randomness
|
||||
@ -123,14 +123,14 @@ template ProofOfQuota(nLevelsPK, nLevelsPol, bitsQuota) {
|
||||
randomness.inp[2] <== index;
|
||||
randomness.inp[3] <== session;
|
||||
|
||||
// Derive proof_nullifier
|
||||
// Derive key_nullifier
|
||||
component nf = Poseidon2_hash(2);
|
||||
component dstNF = PROOF_NULLIFIER_V1();
|
||||
component dstNF = PROOF_NULLIFIER_V1(); // THIS NEEDS TO BE UPDATED
|
||||
nf.inp[0] <== dstNF.out;
|
||||
nf.inp[1] <== randomness.out;
|
||||
nullifier <== nf.out;
|
||||
key_nullifier <== nf.out;
|
||||
}
|
||||
|
||||
// Instantiate with chosen depths: 20 for core PK tree, 25 for PoL slot tree
|
||||
component main { public [ session, Qc, Ql, pk_root, aged_root, K_part_one, K_part_two ] }
|
||||
// Instantiate with chosen depths: 20 for core PK tree, 25 for PoL secret slot tree
|
||||
component main { public [ session, core_quota, leader_quota, core_root, pol_ledger_aged, K_part_one, K_part_two ] }
|
||||
= ProofOfQuota(20, 25, 20);
|
||||
@ -278,25 +278,25 @@ for i in range(32):
|
||||
|
||||
# 5) Assemble JSON
|
||||
inp = {
|
||||
"slot": str(slot_number),
|
||||
"sl": str(slot_number),
|
||||
"epoch_nonce": str(epoch_nonce),
|
||||
"t0": str(t0),
|
||||
"t1": str(t1),
|
||||
"slot_secret": str(slot_secret),
|
||||
"one_time_key_part_one": str(F(123456)),
|
||||
"one_time_key_part_two": str(F(654321)),
|
||||
"P_lead_part_one": str(F(123456)),
|
||||
"P_lead_part_two": str(F(654321)),
|
||||
"slot_secret_path": [str(x) for x in slot_secret_path],
|
||||
"aged_nodes": [str(x) for x in aged_nodes],
|
||||
"aged_selectors": [str(x) for x in aged_selectors],
|
||||
"aged_root": str(aged_root),
|
||||
"transaction_hash": str(tx_hash),
|
||||
"output_number": str(output_number),
|
||||
"latest_nodes": [str(x) for x in unspent_nodes],
|
||||
"latest_selectors": [str(x) for x in unspent_selectors],
|
||||
"latest_root": str(latest_root),
|
||||
"noteid_aged_path": [str(x) for x in aged_nodes],
|
||||
"noteid_aged_selectors": [str(x) for x in aged_selectors],
|
||||
"ledger_aged": str(aged_root),
|
||||
"note_tx_hash": str(tx_hash),
|
||||
"note_output_number": str(output_number),
|
||||
"noteid_latest_path": [str(x) for x in unspent_nodes],
|
||||
"noteid_latest_selectors": [str(x) for x in unspent_selectors],
|
||||
"ledger_latest": str(latest_root),
|
||||
"starting_slot": str(starting_slot),
|
||||
"secrets_root": str(secret_root) ,
|
||||
"value": str(value)
|
||||
"v": str(value)
|
||||
}
|
||||
|
||||
import json
|
||||
|
||||
@ -224,9 +224,9 @@ data_msg = F(randrange(0,p,1))
|
||||
|
||||
inp = {
|
||||
"secret_voucher": str(secret_voucher),
|
||||
"merkle_nodes": [str(x) for x in merkle_nodes],
|
||||
"selectors": [str(x) for x in selectors],
|
||||
"attached_data": str(data_msg),
|
||||
"voucher_merkle_path":[str(x) for x in merkle_nodes],
|
||||
"voucher_merkle_path_selectors": [str(x) for x in selectors],
|
||||
"mantle_tx_hash": str(data_msg),
|
||||
"voucher_root": str(voucher_root)
|
||||
}
|
||||
|
||||
|
||||
@ -215,13 +215,13 @@ data_msg = F(randrange(0,p,1))
|
||||
|
||||
if nInput == 1:
|
||||
inp = {
|
||||
"secret_key": str(sk[0]),
|
||||
"attached_data": str(data_msg)
|
||||
"secret_keys": str(sk[0]),
|
||||
"msg": str(data_msg)
|
||||
}
|
||||
else:
|
||||
inp = {
|
||||
"secret_key": [str(x) for x in sk],
|
||||
"attached_data": str(data_msg)
|
||||
"secret_keys": [str(x) for x in sk],
|
||||
"msg": str(data_msg)
|
||||
}
|
||||
|
||||
import json
|
||||
|
||||
@ -172,37 +172,37 @@ template would_win_leadership(secret_depth){
|
||||
|
||||
|
||||
template proof_of_leadership(secret_depth){
|
||||
signal input slot;
|
||||
signal input epoch_nonce;
|
||||
signal input sl;
|
||||
signal input epoch_nonce; // the epoch nonce eta
|
||||
signal input t0;
|
||||
signal input t1;
|
||||
signal input slot_secret;
|
||||
signal input slot_secret; // This is r_sl
|
||||
signal input slot_secret_path[secret_depth];
|
||||
|
||||
//Part of the note id proof of membership to prove aged
|
||||
signal input aged_nodes[32];
|
||||
signal input aged_selectors[32]; // must be bits
|
||||
signal input aged_root;
|
||||
signal input noteid_aged_path[32];
|
||||
signal input noteid_aged_selectors[32]; // must be bits
|
||||
signal input ledger_aged;
|
||||
|
||||
//Used to derive the note identifier
|
||||
signal input transaction_hash;
|
||||
signal input output_number;
|
||||
signal input note_tx_hash;
|
||||
signal input note_output_number;
|
||||
|
||||
//Part of the note id proof of membership to prove it's unspent
|
||||
signal input latest_nodes[32];
|
||||
signal input latest_selectors[32]; // must be bits
|
||||
signal input latest_root;
|
||||
signal input noteid_latest_path[32];
|
||||
signal input noteid_latest_selectors[32]; // must be bits
|
||||
signal input ledger_latest;
|
||||
|
||||
//Part of the secret key
|
||||
signal input starting_slot;
|
||||
signal input secrets_root;
|
||||
signal input secrets_root; // THIS NEEDS TO BE REMOVED
|
||||
|
||||
// The winning note. The unit is supposed to be NMO and the ZoneID is MANTLE
|
||||
signal input value;
|
||||
signal input v; // value of the note
|
||||
|
||||
// Verify the note is winning the lottery
|
||||
component lottery_checker = would_win_leadership(secret_depth);
|
||||
lottery_checker.slot <== slot;
|
||||
lottery_checker.slot <== sl;
|
||||
lottery_checker.epoch_nonce <== epoch_nonce;
|
||||
lottery_checker.t0 <== t0;
|
||||
lottery_checker.t1 <== t1;
|
||||
@ -211,42 +211,42 @@ template proof_of_leadership(secret_depth){
|
||||
lottery_checker.slot_secret_path[i] <== slot_secret_path[i];
|
||||
}
|
||||
for(var i = 0; i < 32; i++){
|
||||
lottery_checker.aged_nodes[i] <== aged_nodes[i];
|
||||
lottery_checker.aged_selectors[i] <== aged_selectors[i];
|
||||
lottery_checker.aged_nodes[i] <== noteid_aged_path[i];
|
||||
lottery_checker.aged_selectors[i] <== noteid_aged_selectors[i];
|
||||
}
|
||||
lottery_checker.aged_root <== aged_root;
|
||||
lottery_checker.transaction_hash <== transaction_hash;
|
||||
lottery_checker.output_number <== output_number;
|
||||
lottery_checker.aged_root <== ledger_aged;
|
||||
lottery_checker.transaction_hash <== note_tx_hash;
|
||||
lottery_checker.output_number <== note_output_number;
|
||||
lottery_checker.starting_slot <== starting_slot;
|
||||
lottery_checker.secrets_root <== secrets_root;
|
||||
lottery_checker.value <== value;
|
||||
lottery_checker.value <== v;
|
||||
|
||||
|
||||
// One time signing key used to sign the block proposal and the block
|
||||
signal input one_time_key_part_one;
|
||||
signal input one_time_key_part_two;
|
||||
signal input P_lead_part_one;
|
||||
signal input P_lead_part_two;
|
||||
|
||||
//Avoid the circom optimisation that removes unused public input
|
||||
signal dummy_one;
|
||||
signal dummy_two;
|
||||
dummy_one <== one_time_key_part_one * one_time_key_part_one;
|
||||
dummy_two <== one_time_key_part_two * one_time_key_part_two;
|
||||
dummy_one <== P_lead_part_one * P_lead_part_one;
|
||||
dummy_two <== P_lead_part_two * P_lead_part_two;
|
||||
|
||||
signal output entropy_contrib;
|
||||
signal output entropy_contribution; // This is rho_lead
|
||||
|
||||
|
||||
// Check that the note is unspent
|
||||
//First check selectors are indeed bits
|
||||
for(var i = 0; i < 32; i++){
|
||||
latest_selectors[i] * (1 - latest_selectors[i]) === 0;
|
||||
noteid_latest_selectors[i] * (1 - noteid_latest_selectors[i]) === 0;
|
||||
}
|
||||
//Then check the note id is in the latest ledger state
|
||||
component unspent_membership = proof_of_membership(32);
|
||||
for(var i = 0; i < 32; i++){
|
||||
unspent_membership.nodes[i] <== latest_nodes[i];
|
||||
unspent_membership.selector[i] <== latest_selectors[i];
|
||||
unspent_membership.nodes[i] <== noteid_latest_path[i];
|
||||
unspent_membership.selector[i] <== noteid_latest_selectors[i];
|
||||
}
|
||||
unspent_membership.root <== latest_root;
|
||||
unspent_membership.root <== ledger_latest;
|
||||
unspent_membership.leaf <== lottery_checker.note_identifier;
|
||||
|
||||
lottery_checker.out * unspent_membership.out === 1;
|
||||
@ -254,12 +254,12 @@ template proof_of_leadership(secret_depth){
|
||||
|
||||
// Compute the entropy contribution
|
||||
component entropy = derive_entropy();
|
||||
entropy.slot <== slot;
|
||||
entropy.slot <== sl;
|
||||
entropy.note_id <== lottery_checker.note_identifier;
|
||||
entropy.secret_key <== lottery_checker.secret_key;
|
||||
|
||||
entropy_contrib <== entropy.out;
|
||||
entropy_contribution <== entropy.out;
|
||||
}
|
||||
|
||||
|
||||
component main {public [slot,epoch_nonce,t0,t1,aged_root,latest_root,one_time_key_part_one,one_time_key_part_two]}= proof_of_leadership(25);
|
||||
//component main {public [sl,epoch_nonce,t0,t1,ledger_aged,ledger_latest,P_lead_part_one,P_lead_part_two]}= proof_of_leadership(25);
|
||||
@ -31,9 +31,9 @@ template derive_reward_voucher(){
|
||||
|
||||
template proof_of_claim(){
|
||||
signal input secret_voucher;
|
||||
signal input merkle_nodes[32];
|
||||
signal input selectors[32];
|
||||
signal input attached_data;
|
||||
signal input voucher_merkle_path[32];
|
||||
signal input voucher_merkle_path_selectors[32];
|
||||
signal input mantle_tx_hash;
|
||||
signal input voucher_root;
|
||||
|
||||
signal output voucher_nullifier;
|
||||
@ -45,13 +45,13 @@ template proof_of_claim(){
|
||||
//Check reward voucher membership
|
||||
//First check selectors are indeed bits
|
||||
for(var i = 0; i < 32; i++){
|
||||
selectors[i] * (1 - selectors[i]) === 0;
|
||||
voucher_merkle_path_selectors[i] * (1 - voucher_merkle_path_selectors[i]) === 0;
|
||||
}
|
||||
//Then check the proof of membership
|
||||
component reward_membership = proof_of_membership(32);
|
||||
for(var i = 0; i < 32; i++){
|
||||
reward_membership.nodes[i] <== merkle_nodes[i];
|
||||
reward_membership.selector[i] <== selectors[i];
|
||||
reward_membership.nodes[i] <== voucher_merkle_path[i];
|
||||
reward_membership.selector[i] <== voucher_merkle_path_selectors[i];
|
||||
}
|
||||
reward_membership.root <== voucher_root;
|
||||
reward_membership.leaf <== reward_voucher.out;
|
||||
@ -68,7 +68,7 @@ template proof_of_claim(){
|
||||
|
||||
// dummy constraint to avoid unused public input to be erased after compilation optimisation
|
||||
signal dummy;
|
||||
dummy <== attached_data * attached_data;
|
||||
dummy <== mantle_tx_hash * mantle_tx_hash;
|
||||
}
|
||||
|
||||
component main {public [voucher_root,attached_data]}= proof_of_claim();
|
||||
component main {public [voucher_root,mantle_tx_hash]}= proof_of_claim();
|
||||
@ -5,22 +5,20 @@ include "../ledger/notes.circom";
|
||||
include "../misc/constants.circom";
|
||||
|
||||
template zkSignature(maxInput){
|
||||
signal input secret_key[maxInput];
|
||||
|
||||
signal input attached_data;
|
||||
|
||||
signal output public_key[maxInput];
|
||||
signal input secret_keys[maxInput];
|
||||
signal input msg;
|
||||
signal output public_keys[maxInput];
|
||||
|
||||
component pk[maxInput];
|
||||
for(var i =0; i<maxInput; i++){
|
||||
pk[i] = derive_public_key();
|
||||
pk[i].secret_key <== secret_key[i];
|
||||
public_key[i] <== pk[i].out;
|
||||
pk[i].secret_key <== secret_keys[i];
|
||||
public_keys[i] <== pk[i].out;
|
||||
}
|
||||
|
||||
// dummy constraint to avoid unused public input to be erased after compilation optimisation
|
||||
signal dummy;
|
||||
dummy <== attached_data * attached_data;
|
||||
dummy <== msg * msg;
|
||||
}
|
||||
|
||||
component main {public [attached_data]}= zkSignature(32);
|
||||
component main {public [msg]}= zkSignature(32);
|
||||
@ -1,5 +1,5 @@
|
||||
//
|
||||
pragma circom 2.0.0;
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "poseidon2_sponge.circom";
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
//
|
||||
pragma circom 2.0.0;
|
||||
pragma circom 2.1.9;
|
||||
|
||||
//
|
||||
// The Poseidon2 permutation for bn128 and t=3
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
//
|
||||
pragma circom 2.0.0;
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "poseidon2_perm.circom";
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user