From 3d80f68381f78d9aef00c95d3fd9d94c3d05fcc0 Mon Sep 17 00:00:00 2001 From: thomaslavaur Date: Thu, 29 Aug 2024 07:07:46 +0200 Subject: [PATCH] add proof constraints specification --- cryptarchia/cryptarchia.py | 31 ++++++++++++++++++------------- cryptarchia/test_common.py | 4 ++-- cryptarchia/test_leader.py | 2 +- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/cryptarchia/cryptarchia.py b/cryptarchia/cryptarchia.py index 7f595ee..ec70ffb 100644 --- a/cryptarchia/cryptarchia.py +++ b/cryptarchia/cryptarchia.py @@ -182,22 +182,28 @@ class LeaderProof: @staticmethod def new(#Public inputs slot: Slot, - _epoch_nonce: Id, - _threshold_0: int, - _threshold_1: int, - _eligible_notes: set[Id], + epoch_nonce: Id, + threshold_0: int, + threshold_1: int, + eligible_notes: set[Id], #Secret inputs coin: Coin, - #membership witness + #membership witness to check that coin.commitment() is in eligible_notes ): + #These verifications are normally done in the risc0 zk-proof: + lottery_ticket = LEADER_VRF.vrf(coin, epoch_nonce, slot) + winning_threshold = leader_winning_threshold(threshold_0, threshold_1, coin.value) + assert(lottery_ticket < winning_threshold) + coin_nullifier = coin.nullifier() + assert(coin.commitment() in eligible_notes) evolved_coin = coin.evolve() - #These verifications are normally done in the risc0 zk-proof + return LeaderProof( # TODO: generate the proof with risc0 - nullifier=coin.nullifier(), + nullifier=coin_nullifier, evolved_commitment=evolved_coin.commitment(), slot=slot, ) @@ -666,6 +672,9 @@ def phi(f: float, alpha: float) -> float: """ return alpha * (- log(1-f) - 0.5 * alpha * log(1-f) ** 2) +def leader_winning_threshold(threshold_0: int, threshold_1: int, stake: int) -> int: + return stake * (threshold_0 + threshold_1 * stake) + class LEADER_VRF: """NOT SECURE: A mock VRF function""" @@ -707,13 +716,9 @@ class Leader: return LeaderProof.new(slot, epoch.nonce(), threshold_0, threshold_1, eligible_notes, self.coin) def _is_slot_leader(self, epoch: EpochState, slot: Slot): - relative_stake = self.coin.value / epoch.total_active_stake() - + threshold_0, threshold_1 = lottery_threshold(self.config.active_slot_coeff, epoch.total_active_stake()) r = LEADER_VRF.vrf(self.coin, epoch.nonce(), slot) - - return r < LEADER_VRF.ORDER * phi( - self.config.active_slot_coeff, relative_stake - ) + return r < leader_winning_threshold(threshold_0, threshold_1, self.coin.value) def common_prefix_len(a: Chain, b: Chain) -> int: diff --git a/cryptarchia/test_common.py b/cryptarchia/test_common.py index f0e704a..4d2186b 100644 --- a/cryptarchia/test_common.py +++ b/cryptarchia/test_common.py @@ -26,7 +26,7 @@ class TestNode: def on_slot(self, slot: Slot) -> BlockHeader | None: parent = self.follower.tip_id() epoch_state = self.epoch_state(slot) - if leader_proof := self.leader.try_prove_slot_leader(epoch_state, slot, parent): + if leader_proof := self.leader.try_prove_slot_leader(epoch_state, slot, {self.leader.coin.commitment()}): orphans = self.follower.unimported_orphans(parent) self.leader.coin = self.leader.coin.evolve() return BlockHeader( @@ -73,7 +73,7 @@ def mk_block( content_size=len(content), content_id=sha256(content).digest(), # TODO: replace with correct values if necessary - leader_proof=LeaderProof.new(Slot(slot), bytes(32), 0, 0, set(),coin), + leader_proof=LeaderProof.new(Slot(slot), bytes(32), 2**256, 0, {coin.commitment()}, coin), orphaned_proofs=orphaned_proofs, ) diff --git a/cryptarchia/test_leader.py b/cryptarchia/test_leader.py index 3f6918c..a1bc0b5 100644 --- a/cryptarchia/test_leader.py +++ b/cryptarchia/test_leader.py @@ -42,7 +42,7 @@ class TestLeader(TestCase): # interval `p +- margin_of_error` with high probabiltiy leader_rate = ( sum( - l.try_prove_slot_leader(epoch, Slot(slot), bytes(32)) is not None + l.try_prove_slot_leader(epoch, Slot(slot), {coin.commitment()}) is not None for slot in range(N) ) / N