1
1
import sys
2
+ import subprocess
2
3
import hashlib
3
4
import random
4
5
from PyQt5 .QtWidgets import (
5
6
QApplication , QWidget , QLabel , QPushButton , QVBoxLayout , QGraphicsScene ,
6
- QGraphicsView , QGraphicsEllipseItem , QGraphicsTextItem , QGraphicsLineItem , QMessageBox , QHBoxLayout , QGraphicsOpacityEffect
7
+ QGraphicsView , QGraphicsEllipseItem , QGraphicsTextItem , QGraphicsLineItem ,
8
+ QHBoxLayout , QScrollArea
7
9
)
8
10
from PyQt5 .QtGui import QFont , QPen , QBrush , QColor
9
- from PyQt5 .QtCore import Qt , QPointF , QLineF , QPropertyAnimation , QEasingCurve
11
+ from PyQt5 .QtCore import Qt , QPointF , QLineF
12
+
10
13
11
14
class ZKPNode :
12
15
def __init__ (self , name , role_label , position , color ):
@@ -19,6 +22,7 @@ def __init__(self, name, role_label, position, color):
19
22
self .revealed_role = role_label
20
23
self .revealed_nonce = self .nonce
21
24
25
+
22
26
class NarrationEngine :
23
27
@staticmethod
24
28
def format_log (node1 , node2 , binding_ok , hiding_ok , binding_broken = False ):
@@ -43,12 +47,12 @@ def format_log(node1, node2, binding_ok, hiding_ok, binding_broken=False):
43
47
log += " ✅ Matches original commitments — Binding held.\n \n "
44
48
45
49
if not binding_broken and hiding_ok :
46
- log += "✅ Hiding held — Verifier only learns that roles are different.\n ZKP passed successfully.\n "
50
+ log += "✅ Hiding held — Verifier only learns that roles are different.\n ZKP passed successfully.\n "
47
51
elif not binding_broken and not hiding_ok :
48
- log += f"⚠️ Hiding broken — { node1 .name } and { node2 .name } revealed same role!\n ZKP failed. Verifier now knows part of the secret mapping.\n "
52
+ log += f"⚠️ Hiding broken — { node1 .name } and { node2 .name } revealed same role!\n ZKP failed. Verifier now knows part of the secret mapping.\n "
49
53
50
54
log += """
51
- Explanation:
55
+ 📘 Explanation:
52
56
- Binding ensures that once a role is committed with a hash, it can't be changed.
53
57
- Hiding ensures that the hash doesn't reveal the actual role until the reveal phase.
54
58
- If two adjacent nodes share the same role, it can indicate a conflict of interest or security flaw.
@@ -57,6 +61,7 @@ def format_log(node1, node2, binding_ok, hiding_ok, binding_broken=False):
57
61
"""
58
62
return log
59
63
64
+
60
65
class SceneZKPGraph (QWidget ):
61
66
def __init__ (self ):
62
67
super ().__init__ ()
@@ -68,20 +73,40 @@ def __init__(self):
68
73
self .view = QGraphicsView (self .scene )
69
74
self .view .setStyleSheet ("background-color: #1e1e1e; border: none;" )
70
75
76
+ # Scrollable narration box
71
77
self .text_output = QLabel ()
72
78
self .text_output .setWordWrap (True )
73
79
self .text_output .setFont (QFont ("Courier New" , 12 ))
74
80
self .text_output .setStyleSheet ("background-color: #1c1c1c; padding: 10px; border: 1px solid #444; color: white;" )
81
+ scroll = QScrollArea ()
82
+ scroll .setWidgetResizable (True )
83
+ scroll .setWidget (self .text_output )
84
+ scroll .setMinimumHeight (250 )
75
85
76
86
self .verify_button = QPushButton ("🎯 Simulate ZKP Verification" )
77
87
self .verify_button .setFont (QFont ("Arial" , 14 ))
78
88
self .verify_button .setStyleSheet ("padding: 10px; background-color: #2d3436; color: white; border-radius: 8px;" )
79
89
self .verify_button .clicked .connect (self .reveal_connection )
80
90
91
+ self .next_button = QPushButton ("➡ Next: Scene 3 - Bipartate Graph" )
92
+ self .next_button .setFont (QFont ("Arial" , 13 , QFont .Bold ))
93
+ self .next_button .setStyleSheet (
94
+ "background-color: #0055ff; color: white; padding: 10px; border-radius: 10px;"
95
+ )
96
+ self .next_button .clicked .connect (self .go_to_next_scene )
97
+
81
98
layout = QVBoxLayout ()
82
99
layout .addWidget (self .view )
83
100
layout .addWidget (self .verify_button )
84
- layout .addWidget (self .text_output )
101
+ layout .addWidget (scroll )
102
+
103
+ # Center the button using a horizontal layout
104
+ button_layout = QHBoxLayout ()
105
+ button_layout .addStretch ()
106
+ button_layout .addWidget (self .next_button )
107
+ button_layout .addStretch ()
108
+ layout .addLayout (button_layout )
109
+
85
110
self .setLayout (layout )
86
111
87
112
self .nodes = []
@@ -100,7 +125,7 @@ def build_graph(self):
100
125
("Insider" , "Validator" , QPointF (150 , 450 ), QColor ("#f1c40f" ))
101
126
]
102
127
103
- connections = [(0 ,1 ), (1 ,2 ), (2 ,4 ), (3 ,1 ), (5 ,2 ), (0 ,5 )]
128
+ connections = [(0 , 1 ), (1 , 2 ), (2 , 4 ), (3 , 1 ), (5 , 2 ), (0 , 5 )]
104
129
105
130
for name , role , pos , color in layout :
106
131
node = ZKPNode (name , role , pos , color )
@@ -156,6 +181,11 @@ def reveal_connection(self):
156
181
)
157
182
self .text_output .setText (log )
158
183
184
+ def go_to_next_scene (self ):
185
+ subprocess .Popen (["python" , "scene3_bipartate.py" ])
186
+ self .close ()
187
+
188
+
159
189
if __name__ == "__main__" :
160
190
app = QApplication (sys .argv )
161
191
window = SceneZKPGraph ()
0 commit comments