基于变色龙哈希的可修改区块链

import hashlib
import string
import json
import random
import threading
from decimal import Decimal
from time import time
import newChameleonHash
 
length=50
n=0
p,q,g=newChameleonHash.Setup(length)
SKlist,PKlist,rlist=[],[],[]
 
class MyThread(threading.Thread):
 
    def __init__(self, target, args=()):
        super(MyThread, self).__init__()
        self.func = target
        self.args = args
 
    def run(self):
        self.result = self.func(*self.args)
 
    def get_result(self):
        try:
            return self.result
        except Exception:
            return None
 
 
class BlockChain:
    def __init__(self, initialHash):
        # init block chain
        self.chain = []
 
        # init pitman
        self.pitmen = []
        for i in range(6):
            self.pitmen.append(Pitman)
 
        # collect mine results
        self.results = []
 
        # generate GenesisBlock
        self.new_block(initialHash)
 
    @property
    def last_block(self):
        if len(self.chain):
            return self.chain[-1]
        else:
            return None
 
    def get_trans(self):
        return json.dumps({
            'sender': ''.join(random.sample(string.ascii_letters + string.digits, 8)),
            'recipient': ''.join(random.sample(string.ascii_letters + string.digits, 8)),
            'amount': random.randint(1, 10000)
        })
 
    def new_block(self, initialHash=None):
        global n
        if initialHash:
            # generate Genesis Block
            block = Block()
            block.index = 0
            block.SK=newChameleonHash.getSecretKey(q)
            block.PK=newChameleonHash.getPublicKey(g,block.SK,p)
            block.nonce = newChameleonHash.getr(q)
            block.previousHash = '0'
            block.difficulty = 0
            block.transactionData = self.get_trans()
            SKlist.append(block.SK)
            PKlist.append(block.PK)
            rlist.append(block.nonce)
            n+=1
            guess = f'{block.previousHash}{block.transactionData}'
            block.hash = str(hex(newChameleonHash.ChameleonHash(PKlist,guess,rlist,p,q,g,n))).replace('0x','')
            block.time = time()
            self.chain.append(block)
        else:
            for i in range(len(self.pitmen)):
                pm = MyThread(target=self.pitmen[i].mine,
                                      args=(self.pitmen[i],
                                            len(self.chain),
                                            self.last_block.get_block()['Hash'],
                                            self.get_trans()))
                pm.start()
                pm.join()
                self.results.append(pm.get_result())
 
            # show all blocks
            #print("All blocks generated by pitmen:")
            #for result in self.results:
            #    print(result[0].get_block())
 
            # get new block
            firstblock = self.results[0][0]
            mintime = Decimal(self.results[0][1])
            for i in range(1, len(self.results)):
                if Decimal(self.results[i][1]) < mintime:
                    firstblock = self.results[i][0]
                else:
                    continue
            self.chain.append(firstblock)
            SKlist.append(firstblock.SK)
            PKlist.append(firstblock.PK)
            rlist.append(firstblock.nonce)
            n+=1
            self.results = []
    def show_chain(self):
        print('This is mine first block chain!')
        for block in self.chain:
            print(block.get_block())
            print('')
    def changeMSG(self,i,newtransactionData):
        block=self.chain[i-1]
        guess = f'{block.previousHash}{block.transactionData}'
        hash = str(hex(newChameleonHash.ChameleonHash(PKlist,guess,rlist,p,q,g,i))).replace('0x','')
        #print(hash)
        newguess = f'{block.previousHash}{newtransactionData}'
        newnonce=newChameleonHash.Forge(SKlist,guess,rlist,newguess,p,q,g,n,i)
        #print(newnonce)
        rlist[i-1]=newnonce
        newhash = str(hex(newChameleonHash.ChameleonHash(PKlist,newguess,rlist,p,q,g,i))).replace('0x','')
        #print(newhash)
        block.guess=guess
        block.transactionData=newtransactionData
        print(hash)
        print(newhash)
        
class Block:
    def __init__(self):
        self.index = None
        self.time = None
        self.difficulty = None
        self.SK = None
        self.PK = None
        self.nonce = None
        self.hash = None
        self.previousHash = None
        self.transactionData = None
    def get_block(self):
        return {
            'Index': self.index,
            'Time': self.time,
            'Difficulty': self.difficulty,
            'Hash': self.hash,
            'SK': self.SK,
            'PK':self.PK,
            'Nonce': self.nonce,
            'PreviousHash': self.previousHash,
            'TransactionData': self.transactionData
        }
class Pitman:
    def mine(self, index, previousHash, transactionData):
        beginTime = time()
        block = Block()
        block.index = index
        block.previousHash = previousHash
        block.transactionData = transactionData
        block.difficulty, block.hash,block.SK,block.PK, block.nonce = self.generate_hash(previousHash, transactionData)
        block.time = time()
        endTime = time()
        return block, endTime - beginTime
    @staticmethod
    def generate_hash(previousHash, transactionData):
        difficulty = 0
        SK=newChameleonHash.getSecretKey(q)
        PK=newChameleonHash.getPublicKey(g,SK,p)
        nonce = newChameleonHash.getr(q)
        SKlist.append(SK)
        PKlist.append(PK)
        rlist.append(nonce)
        a=n
        a+=1
        guess = f'{previousHash}{transactionData}'
        myhash = str(hex(newChameleonHash.ChameleonHash(PKlist,guess,rlist,p,q,g,a))).replace('0x','')
        while myhash[-1] != '0':
            difficulty += 1
            nonce += difficulty
            guess = f'{previousHash}{transactionData}'
            del rlist[-1]
            rlist.append(nonce)
            myhash = str(hex(newChameleonHash.ChameleonHash(PKlist,guess,rlist,p,q,g,a))).replace('0x','')
        del SKlist[-1]
        del PKlist[-1]
        del rlist[-1]
        return difficulty, myhash, SK,PK,nonce

def vote(i):
    num=0
    agreelist=[]
    for j in range(n):
        if j!=i-1:
            rand=random.randint(0,1)
            if rand==1:
                print('Index:',j,'同意修改')
                agreelist.append(j)
                num+=1
            else:
                print('Index:',j,'拒绝修改')
    if num>int(n/2):
        print('修改请求通过')
        r=0
        for k in range(num):
            random1=random.randint(1,q)
            print('Index:',agreelist[k],random1)
            r+=random1
        temp=newChameleonHash.quickPower(g,r,p)
        chosen=agreelist[temp%num-1]
        print('Index:',chosen,'进行修改')
        return chosen
    else:
        print('修改请求被拒绝')
        return -1
if __name__ == '__main__':
    chain = BlockChain(1)
    length1 = 5
    for i in range(length1):
        chain.new_block()
    chain.show_chain()
    while True:
        chosen=vote(3)
        if chosen!=-1:
            break
    newtransactionData='{"sender":"111","recipient":"222","amount":100}'
    chain.changeMSG(chosen,newtransactionData)
    chain.show_chain()

变色龙哈希

# n个用户,n个PK,SK,r,CH=g^m*h1^r1*h2^r2……hn^rn mod p

#Setup(),KeyGen(),ChameleonHash(),Forge()四个函数
   
import random
from pyunit_prime import get_large_prime_length    #随机生成指定长度大素数
from pyunit_prime import is_prime                  #判断素数
from pyunit_prime import prime_range               #输出指定区间素数
import math


#p=0
#q=0
    
def primeFactorization(length):                    #分解质因数
    #global p,q
    p,q=0,0
    q=get_large_prime_length(length)
    while True:
        d=random.randint(2,10000)
        if d%2==0:
            p=q*d+1
            if is_prime(p)==True:
                break
            else:
                continue
        else:
            continue
    primeList=prime_range(2,int(math.sqrt(d)))
    result=[[0,0] for i in range(len(primeList))]
    for i in range(len(primeList)):
        result[i][0]=primeList[i]
        while d%primeList[i]==0:
            result[i][1]+=1
            d=d//primeList[i]
    if d!=1:
        result.append([d,1])
    result.append([q,1])
    return result,p,q  

def quickPower(a,b,c):                               #快速幂,a^b mod c
    result=1
    while b>0:
        if b%2==1:
            result=result*a%c
        a=a*a%c
        b>>=1
    return result

def getGenerator(result,p,q):                             #get g
    generator=random.randint(1,1000)
    while True:
        if quickPower(generator,q,p)!=1:
            generator+=1
        else:
            for i in range(len(result)):
                if quickPower(generator,int((p-1)/result[i][0]),p)==1:
                    break
            if i!=len(result)-1:
                generator+=1
            else:
                break
    return generator

def Setup(length):
    factorization,p,q=primeFactorization(length)
    g=getGenerator(factorization,p,q)
    return p,q,g

def getSecretKey(q):                                 #get SKlist,x1,x2……xn
    SK=random.randint(1,q)
    return SK

def getPublicKey(g,SK,p):                        #get PKlist,h1,h2……hn
    PK=quickPower(g,SK,p)
    return PK


    
def getr(q):                                         # rlist,r1,r2……rn
    r=random.randint(1,q)
    return r

def treatMSG(msg):                                #处理消息msg为整数
    newmsg=''
    for i in msg:
        newmsg+=str(ord(i))
    return int(newmsg)

def ChameleonHash(PKlist,m,rlist,p,q,g,n):                 #变色龙哈希
    newm=treatMSG(m)
    CH=quickPower(g,newm,p)
    for i in range(n):
        CH=CH*quickPower(PKlist[i],rlist[i],p)
    CH=CH%p
    return CH
    
def exgcd(a,b):                                    #扩展欧几里得
    if b==0:
        return 1,0,a
    else:
        x,y,gcd=exgcd(b,a%b)
        x,y=y,(x-(a//b)*y)
        return x,y,gcd

def Forge(SKlist,m1,rlist,m2,p,q,g,n,i):                            #求r',线性同余方程
    newm1=treatMSG(m1)
    newm2=treatMSG(m2)
    x,y,gcd=exgcd(SKlist[i-1],q)
    result=x*(newm1-newm2+SKlist[i-1]*rlist[i-1])%q
    return result

 

posted @ 2021-04-20 21:31  Lou1s  阅读(494)  评论(0编辑  收藏  举报