diff --git a/circom_circuits/Blend/generate_inputs_for_poq.py b/circom_circuits/Blend/generate_inputs_for_poq.py index 9390ab3..68af40b 100644 --- a/circom_circuits/Blend/generate_inputs_for_poq.py +++ b/circom_circuits/Blend/generate_inputs_for_poq.py @@ -207,7 +207,7 @@ def PoseidonSponge(data, capacity, output_len): # Main # ——————————————————————— if len(sys.argv) != 5: - print("Usage: python3 generate_inputs_for_poq.py ") + print("Usage: python3 generate_inputs_for_poq.py ") sys.exit(1) session = int(sys.argv[1]) @@ -314,7 +314,6 @@ inp = { "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) } diff --git a/circom_circuits/Blend/poq.circom b/circom_circuits/Blend/poq.circom index e8b9ff0..0129477 100644 --- a/circom_circuits/Blend/poq.circom +++ b/circom_circuits/Blend/poq.circom @@ -54,14 +54,13 @@ template ProofOfQuota(nLevelsPK, nLevelsPol, bitsQuota) { signal input pol_note_output_number; signal input pol_sk_starting_slot; - signal input secrets_root; // THIS NEEDS TO BE REMOVED signal input pol_note_value; - - // Constraints + // Constraint the selector to be a bit selector * (1 - selector) === 0; + // derive pk_core = Poseidon(NOMOS_KDF || core_sk) component kdf = Poseidon2_hash(2); component dstKdf = NOMOS_KDF_V1(); @@ -70,6 +69,7 @@ template ProofOfQuota(nLevelsPK, nLevelsPol, bitsQuota) { signal pk_core; pk_core <== kdf.out; + // Merkle‐verify pk_core in core_root component coreReg = proof_of_membership(nLevelsPK); for (var i = 0; i < nLevelsPK; i++) { @@ -80,6 +80,7 @@ template ProofOfQuota(nLevelsPK, nLevelsPol, bitsQuota) { 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); @@ -99,21 +100,19 @@ template ProofOfQuota(nLevelsPK, nLevelsPol, bitsQuota) { 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 <== pol_note_value; // Enforce the selected role is correct selector * (would_win.out - coreReg.out) + coreReg.out === 1; - - // Quota check: index < core_quota if core, index < leader_quota if leader component cmp = SafeLessThan(bitsQuota); cmp.in[0] <== index; cmp.in[1] <== selector * (leader_quota - core_quota) + core_quota; cmp.out === 1; + // Derive selection_randomness component randomness = Poseidon2_hash(4); component dstSel = SELECTION_RANDOMNESS_V1(); @@ -123,9 +122,10 @@ template ProofOfQuota(nLevelsPK, nLevelsPol, bitsQuota) { randomness.inp[2] <== index; randomness.inp[3] <== session; + // Derive key_nullifier component nf = Poseidon2_hash(2); - component dstNF = PROOF_NULLIFIER_V1(); // THIS NEEDS TO BE UPDATED + component dstNF = KEY_NULLIFIER_V1(); nf.inp[0] <== dstNF.out; nf.inp[1] <== randomness.out; key_nullifier <== nf.out; diff --git a/circom_circuits/Mantle/generate_inputs_for_pol.py b/circom_circuits/Mantle/generate_inputs_for_pol.py index 4bbc5d5..cd90714 100755 --- a/circom_circuits/Mantle/generate_inputs_for_pol.py +++ b/circom_circuits/Mantle/generate_inputs_for_pol.py @@ -295,7 +295,6 @@ inp = { "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) , "v": str(value) } diff --git a/circom_circuits/Mantle/pol.circom b/circom_circuits/Mantle/pol.circom index 97961e4..5e7cdc8 100644 --- a/circom_circuits/Mantle/pol.circom +++ b/circom_circuits/Mantle/pol.circom @@ -3,7 +3,7 @@ pragma circom 2.1.9; include "../hash_bn/poseidon2_hash.circom"; include "../ledger/notes.circom"; -include "../ledger/merkle.circom"; +include "../hash_bn/merkle.circom"; include "../misc/comparator.circom"; include "../circomlib/circuits/bitify.circom"; include "../misc/constants.circom"; @@ -76,7 +76,6 @@ template would_win_leadership(secret_depth){ //Part of the secret key signal input starting_slot; - signal input secrets_root; // The winning note value signal input value; @@ -86,10 +85,29 @@ template would_win_leadership(secret_depth){ signal output secret_key; + // Check the knowledge of the slot secret at position slot - starting_slot + // Verify that the substraction wont underflow (starting_slot < slot) + component checker = SafeLessEqThan(252); + checker.in[0] <== starting_slot; + checker.in[1] <== slot; + + // Compute the positions related to slot - starting_slot (and make sure secret_depth = 25 bits) + component bits = Num2Bits(secret_depth); + bits.in <== slot - starting_slot; + + // Derive the secrets root + component secrets_root = compute_merkle_root(secret_depth); + for(var i=0; i