题目:用零知识证明实现地图的三染色问题(用三种颜色染色一个地图,保证任意两个相邻的地区都是不同的颜色)。
编程验证下述的设计思路,采用Python和C语言编写均可。
条件:假设一个交互协议有证明者Alice和验证者Bob。Alice手里有一个地图三染色的答案(请见下图),这个图总共有6个顶点和6条边。现在Alice想证明给Bob她有答案,但是又不想让Bob知道这个答案。请用零知识证明的思想设计实验并验证至少20次的结果。
测试数据:
1)边集:(1, 2), (1, 4), (1, 3), (2, 5), (3, 6), (5, 6)
颜色集:(1: 0, 2: 1, 3: 2, 4: 1, 5: 2, 6: 0)
2)边集:(1, 2), (1, 4), (1, 3), (2, 3), (2, 5), (2, 6), (3, 4), (3, 6), (5, 6)
颜色集:(1: 0, 2: 1, 3: 2, 4: 1, 5: 2, 6: 0)
3)边集:(1, 2), (1, 4), (1, 3), (2, 3), (2, 5), (2, 6), (3, 4), (3, 6), (5, 6)
颜色集:(1: 0, 2: 1, 3: 1, 4: 2, 5: 2, 6: 0)
思路:
1)Alice 先要对染过色的图进行一些变换,把颜色做一次全改,例如把所有的绿色变成橙色,把所有的黄色变成蓝色,把所有的红色变成粉色。然后 Alice 得到了一个新的染色答案,这时候她把新的图的每一个顶点都用纸片盖上,然后出示给 Bob 看。
2)Bob要随机挑选一条边,并由Alice揭开这条边两端的纸片,让Bob检查,Bob发现这两个顶点的颜色是不同的,那么Bob认为这次检验同构。
经过多次验证,可以证明Bob认为这个图满足三染色的要求。
我的想法
用color0,color1,color2代表图上三种不同的颜色
这里我采用了python的networkx库来进行图的生成绘制以及相关图属性的修改
先构造一个空的无向图,依次将结点123456添加进去
*注意*这里的123456为结点的编号,但是,networkx构造图结点真正的序号是从0开始的!
输入n值,即选择三组测试数据中的一组展开实验
根据选择的n值,导入相应的属性(边的连通性,结点颜色列表)
画出原始图型
随机生成颜色的函数randomColor(这个函数在网上找的)
颜色有三种表示方法:str类型的字符串:red、RGB表示法:(0,255,255)
以及我采用的16进制表示法:以“#”开头表示,例如“#FFFFFF”或“#FFF”
此时,用randomColor更新结点颜色列表colors
输出无色图(此时每个结点的颜色已经更新了!只是没有显示)
输入要查看的结点序号(这就是为什么开始时说真实的结点序号要比标号小1)
输出这两个结点的颜色(直接再colors列表中索引即可)
输出新的颜色图
重复上述操作
代码
import random
import matplotlib.pyplot as plt
import networkx as nx
import numpy as np
#初始化结点颜色
color0='red'
color1='yellow'
color2='green'
#构造空的无向图
graph= nx.Graph()
#添加结点
node_list = [1,2,3,4,5,6]
for i in range(0,5):
graph.add_node(node_list[i])
#添加测试数据的边与颜色
n = str(input('请选择图a,图b,图c'))
if n=='a':
edge_list=[(1, 2), (1, 4), (1, 3), (2, 5), (3, 6), (5, 6)]
colors=[color0,color1,color2,color1,color2,color0]
elif n=='b':
edge_list = [(1, 2), (1, 4), (1, 3), (2, 3), (2, 5), (2, 6), (3, 4), (3, 6), (5, 6)]
colors=[color0,color1,color2,color1,color2,color0]
elif n=='c':
edge_list=[(1, 2), (1, 4), (1, 3), (2, 3), (2, 5), (2, 6), (3, 4), (3, 6), (5, 6)]
colors=[color0, color1, color1, color2, color2, color0]
graph.add_edges_from(edge_list)
#画原始图形
nx.draw(graph, pos=nx.spring_layout(graph), with_labels=True, font_size=20, node_size=500, node_color=colors)
plt.show()
#随机生成颜色函数
def randomcolor():
colorArr = ['1','2','3','4','5','6','7','8','9','A','B','C','D','E','F']
color = ""
for i in range(6):
color += colorArr[random.randint(0,14)]
return "#"+color
#修改颜色
def changeColor():
color0=randomcolor()
color1=randomcolor()
color2=randomcolor()
if n == 'a':
colors = [color0, color1, color2,