版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
实验14A百万富翁协议与区块链仿真
一、实验目的
i.编程实现百万富翁协议,深化对安全多方计算的理解。
2.编程实现Merkle树,并计算出Merkle树的TreeRoot。
3.深化对区块链和智能合约的理解。
二、实验准备
1、通过抓包,可以进行网络故障分析、流量监控、隐私盗取等操作,相关的抓包工具有很
多,主要有Fiddler、Wireshark、Charles等。
2、区块链中的交易是以Merkle树的形式组织在一个个区块中的,Merkle树是通过递归哈
希节点对来构造的,直到只有一个哈希。这个最终地hash称为Merkle根,Merkle树可以
仅用log2(N)的时间复杂度检查任何一个交易是否包含在树中。
三、实验内容
1、参考本章百万富翁协议,把下述python代码改成java代码
importmath
importrandom
#获取小于等于指定数的素数数组
defget_prime_arr(max):
prime_array=[]
foriinrange(2,max):
ifis_prime(i):
prirne_array.append(i)
returnprime_array
#判断是否为素数
defis_prime(num):
ifnum==1:
raiseExccption('l既不是素数也不是合数')
foriinrange(2,inath.floor(math.sqrt(num))+1):
ifnum%i==0:
#print("当前数%s为非素数,其有因子%s"%(str(num),str(i)))
returnFalse
returnTrue
#找出一个指定范围内与n互质的整数e
deffind_pub_key(n.max_num):
whileTrue:
#这里是随机获取保证随机性
c=random.randint(1,max_num)
ifgcd(e,n)=-1:
break
returne
#求两个数的最大公约数
defgcd(a,b):
ifb==0:
returna
else:
returngcd(b,a%b)
#根据e*dmods=1,找出d
deffind_pri_key(e,s):
fordinrange(lOOOOOCOO):#随机太难找,就按顺序找到d,range里的数字随意
x=(e*d)%s
ifx==1;
returnd
#生成公钥和私钥
defbuildJkeyO:
prime_arr=get_prime_arr(100)
p=random.choice(piinie_arr)
#保证p和q不为同一个数
whileTrue:
q=random.choice(prime_arr)
ifp!=q:
break
print("随机生成两个素数p和q.p=",p,"q=",q)
n=p*q
s=(p-l)*(q-l)
e=find_pub_key(s,100)
print("根据e和(p-l)*(q・l)互质得到:e=",e)
d=find_pri_kcy(c,s)
print("根据e*d模(p-l)*(q-I)等于1得到d=H,d)
print。公钥:n=H,n,"e=",e)
prim("私钥:n=H,n,"d=",d)
returnn,e,d
#加密
defrsa_encrypt(content,ned):
#密文B=明文A的e次方模n,ned为公钥
#content就是明文A:ned[1]是c,ned[0]是n
B=pow(content,ned[l])%ned[0]
returnB
#解密
defrsa_decrypt(encrypt_result,ned):
#明文C=密文B的d次方模n,ned为私钥匙
#cnurypl_rcsuk就是密文,nod[1]是cl,ned[0]是ii
C=pow(cncrypt_result,ncdllj)%ncdlOJ
returnC
if_name_=='_main_
pbvk=build_key()
pbk=(pbvk[0],pbvk[l])#公钥(n,e)
pvk=(pbvk[OJ,pbvk[2J)#私钥(n,d)
print("xmodp为:%s"%(x%p))
ifdjistfj-1]==x%p:
print("i>j,即Alice比Bob有钱。")
ifi-j>=0:
print("验证成功”)
else:
print("代码存在错误”)
elifdjistfj-1]==(x%p)+l:
print("i=j,npAlice和Bob一样有钱。
else:
print(”i<j,即Bob比Alice有钱”)
prinl("验证成功”)
else:
print(“代码存在错误”)
2.分析、调试下面的代码,体会区块链中每•个区块的构造方法
(1)Merkle树的代码实现
packagetest;
importjava.securily.MessageDigest;
importjava.util.ArrayList;
importjava.util.List;
publicclassMerkle树s{
//traiisaulioiiList
List<String>txList;
//MerkleRoot
Stringroot;
/**
*constructor
(a)paramtxListtransactionList交易List
*/
publicMerkle树s(List<String>txList){
this.txList=txList;
root=
)
/**
*executemerkle_Wandsetroot.
*/
publicvoidmerkle_树(){
List<String>tcmpTxList=newArrayList<String>();
for(inti=0;i<this.txList.size();i++){
ternpTxList.add(this.txList.get(i)):
)
List<String>newTxList=getNewTxList(tempTxList);
while(newTxList.size()!=1){
newTxList=getNcwTxList(newTxList);
}
this.root=newTxList.get(O);
)
/**
*returnNodeHashList.
*@paramtempTxList
*@rclurn
*/
privateList<String>getNe\vTxList(List<Slring>tempTxList){
List<String>newTxList=newArrayList<String>();
intindex=0;
while(index<tempTxList.size()){
//left
Stringleft=tempTxList.get(index);
index++;
//right
Stringright=
if(index!=tempTxList.sizeO){
right=tempTxList.gel(index);
)
//sha2hexvalue
Stringsha2HexValue=getSHA2HexVahie(Ieft+right);
ncwTxList.add(sha2HcxValue);
indcx++;
)
returnnewTxList:
)
*Returnhexstring
*@paramstr
*@return
*/
publicStringgetSHA2HexValue(Stringstr){
byteflcipher_byte;
try(
McssageDigcslmd二McssaguDigcsl.gctIiistancc("SHA-256");
md.update(str.gctBytcsO);
cipher_byte=ind.digest();
SiringBuildersb=newS(ringBuilder(2*cipher_byle.lenglh);
for(byteb:cipher_byle){
sb.append(String.format("%02x",b&Oxff));
returnsb.toStringO;
}catch(Exceptione){
c.printStackTracc();
)
return
)
/**
*GetRoot
*@return
*/
publicStringgctRoot(){
returnthis.root:
)
}
(2)将交易的数据abcde放入到List中,进行测试:
packagetest;
importjava.util.ArrayList;
importjava.util.List;
publicclassApp{
publicstaticvoidmain(String[]args){
List<String>tempTxList=newArrayLis(<S(ring>();
tempTxList.add("a");
tempTxList.add("b");
IcinpTxLisl.addC'i:");
tempTxList.add(',d'');
tempTxList.add("en);
Merkle树smerkle树s=newMerkle树s(tempTxList);
merkle树s.merklj树0;
System.out.printlnC'root:"+merkle树s.getRoot());
四、实验报告
1、通过实验回答下列问题
(1)给出实验1的完成代码。
packageyzj;
importjava.util.*;
publicclasszhenjieyu3{
publicstaticList<Integer>get_prime_arr(intmax){
List<Integer>primes=newLinkedList<Integer>();
List<Integer>numbers=newLinkedList<Integer>();
for(inti=2;i<=max;i++){
numbers.add(i);
}
while(!numbers.isEmpty()){
intfront=numbers.remove(0);
primes.add(front);
Iterator<Integer>itr=numbers.iterator();
while(itr.hasNext()){
intcurrent=itr.next();
if(current%front==0){
itr.remove();
)
}
)
returnprimes;
}
privatestaticinte;
publicstaticintfind_pub_key(intn,intmax_num){
while(true){
Randomrand=newRandom。;
inte=rand.nextlnt(max_num)+1;
if(gcd(e,n)==1){
break;
}
}
returne;
}
publicstaticintgcd(inta,intb){
if(b==0){
returna;
}else{
returngcd(b,a%b);
}
}
publicstaticintfind_pri_key(inte,ints){
intd=0;
for(inti=1;i<=100000000;i++){
intx=(e%i)%s;
if(x==1)d=i;
returnd;
}
publicstaticint[]build_key(){
List<Integer>prime_arr=get_prime_arr(100);
Randomrand=newRandom();
intq=0;
intp=prime_arr.get(rand.nextInt(prime_arr.size()));
while(true){
q=prime_arr.get(rand.nextlnt(prime_arr.size()));
if(p!=q)break;
)
System,out.printIn("随机生成两个素数p和q.p="+p+"q="
+q);
intn=p*q;
ints=(p-1)*(q-1);
inte=find_pub_key(s,100);
System.out.println("根据e和(p・l)*(q・l)互质得到:e="+
e);
intd=find_pub_key(e,s);
System.out.println("根据e*d模(p・l)*(q-l)等于1
得到d="+d);
System,out.printin("公钥:n="+n+"e="+e);
System,out.printin("私钥:n="+n+"d="+d);
int[]ned=newint[3];
ned[0]=nj
ned[l]=e;
ned[2]=d;
returnned;
}
publicstaticdoublersa_encrypt(intcontent,int[]ned){
doubleB=Math.powCcontent,ned[l])%ned[0];
returnB;
)
publicstaticdoublersa_decrypt(doubled,int[]ned){
doubleC=Math.pow(d,ned[l])%ned[0];
returnC;
}
privatestaticvoidprintln(Stringstring){
//TODOAuto-generatedmethodstub
}
publicstaticvoidmain(String[]args){
//TODOAuto-generatedmethodstub
int[]pbvk=build_key();
int[]pbk={pbvk[0],pbvk[l]};
int[]pvk={pbvk[0]jpbvk[2]};
Randomr=newRandom。;
inti=r.nextlnt(10)+1;
intj=r.nextlnt(10)+1;
System.out.printIn("==========================================
====");
System.out.println("Alice有i="+i+"亿,Bob有j="+
j+“亿”);
intx=r.nextlnt(pbk[0]-1)+50;
System.out.printIn("随机选取的大整数x:"+x);
doubleK=rsa_encrypt(x,pbk);
System.out.printin("大整数加密后得密文K:"+K);
doublec=K-j;
System.out.println("Alice收到数字c:"+c);
doublet]c_list=newdouble[10];
for(intil=1;il<=10;il++){
doublet=rsa_decrypt(c+il,pvk);
c_list[il-1]=t;
)
doublet]d_list=newdouble[10];
intp=r.nextlnt(x)+30;
for(inti2=0;i2<10;i2++){
d_list[i]=(c_list[i]%p);
}
System.out.printin("p的值为:"+p);
System.out.printin("除以p后的余数为:”+d_list);
d_list[i-1]+=1;
for(inti3=0;i3<10;i3++){
d_list[i3]+=2;
}
System.out.printin("前i-1位数字不动,第i位数字后面数
字+2后:”+d_list);
System.out.printIn("第j个数字为:"+d_list[j-1]);
System.out.println("xmodp为:”+(x%p));
if(d_list[j-1]==x%p){
System.oirt.println("i>j,即Alice比Bob有钱。”);
if((i-j)>=0){
System.out.printin("验证成功");
}else{
System.out.printin("代码存在错误“);
}
}elseif(d_list[j-1]==(x%p)+1){
System.out.printIn("i=j,BPAlice和Bob一样有钱。
}else{
System.out.println("i<j,即Bob比Alice有钱“);
if((i-j)<0){
System.out.printin("验证成功");
}else{
System.out.printin("代码存在错误”);
}
}
)
(2)贴图给出实验2的测试结果。
packageyzj;
importjava.util.ArrayList;
importjava.util.List;
publicclasszhenjieyu4{
publicstaticvoidmain(String[]args){
List<String>tempTxList=newArrayList<String>();
tempTxList.addC'a");
tempTxList.add("b");
tempTxList.addC'c");
tempTxList.addC'd");
tempTxList.addC'e");
Merkle树smerkle树s=newMerkle树s(tempTxList);
merkle树s.merkle_树();|
System.out.println(Mroot:"+merklelrs.getRoot());
}
}
zhenjieyu4
"C:\ProgramFiles\Java\jdk-14.0.2\bin\java.exe""-javaagent:C:\ProgramFi
-Dfile.encoding=UTF-8-classpathC:\Users\25868\IdeaPro~jec:s\untitled2M
root:3b7ele6ba3b82975d7802511d8c7fabbe7a5dll2d0ddll2fbcfbb7e6417a3214
2、问答题
(1)对实验2,如果再增加一个链表,把每个区块链起来,应该怎么做?
在Golang中,可以通过一个array和map来实现这个结构:array存
储有序的哈希(Golang中array是有序的),map存储hask->block对
(Golang中,map是无序的)。但是在基本的原型阶段,我们只用到了array,
因为现在还不需要通过哈希来获取块。
为了加入一个新的块,我们必须要有一个已有的块,但是,初始状态下,
我们的链是空的,一个块都没有!所以,在任何一个区块链中,都必须至少有
一个块。这个块,也就是链中的第一个块,通常叫做创世块(genesisblock).
让我们实现一个方法来创建创世块
packagemain
import(
"awesomeProject/src/core"
*'fmt"
)
funcmain(){
be:=core.NewBlockchain()
be.AddBlock("Send1BTCtoIvan")
be.AddBlock("Send2moreBTCtoIvan")
forblock:=rangebc.Blocks{
fmt.Printf("Prev.hash:%x\n'\block.PrevBlockHash)
fmt.Printf("Data:%s\n",block.Data)
fmt.Printf("Hash:%x\n",block.Hash)
fmt.Prlntln()
}
)
packagecore
typeBlockchainstruct{
Blocks[]*Block}
//AddBlocksavesprovideddataasablockinthebl
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026中国智能教育装备系统行业市场供需分析及投资发展评估规划研究报告
- 2026区域营销行业市场深度调研发展趋势投资策略分析研究文件
- 2026中国功率半导体器件新能源领域应用拓展与产能布局
- 2026能源新能源行业市场深度调研及发展趋势和前景预测研究报告
- 美术考试中关于山水画的题目和答案
- 2026中国卫星互联网星座组网进度与地面终端兼容性研究
- 2026乳制品行业市场结构调整策略及其产品品质控制措施分析文献
- 2026中国医疗软件开发业市场供需发展及投资方向合理评估报告
- 2026人工智能技术应用这个行业市场深度挖掘及创新方向与投身规划文档
- 宴会设计课程的试题及详细答案展示
- 电工四级练习题库(含参考答案)
- 牛结节病的症状和治疗方法
- 企业违反纪律检讨书范文(8篇)
- 《非遗手工技艺(拓印)》课件-第一章 拓片的由来和历史
- 工程量清单及招标控制价编制服务采购实施方案
- (高清版)JTGT 5440-2018 公路隧道加固技术规范
- (正式版)QBT 2821-2024 金属晾衣架
- 施工方案设计的经济性与可行性分析
- 汽车钢管激光打标自动化产线课件
- 国际红十字运动的基本知识
- 中药注射剂合理应用手册
评论
0/150
提交评论