Source code for pksig_boyen

""" 
Xavier Boyen - Anonymous Ring Signatures

| From: "X. Boyen. Mesh Signatures: How to Leak a Secret with Unwitting and Unwilling Participants"
| Published in: EUROCRYPT 2007
| Available from: http://eprint.iacr.org/2007/094.pdf
| Notes: 

* type:           signature (ring-based)
* setting:        bilinear groups (asymmetric)

:Authors:    J. Ayo Akinyele
:Date:       11/2011

"""
from charm.toolbox.pairinggroup import PairingGroup,ZR,G1,G2,GT,pair
from charm.toolbox.PKSig import PKSig

debug = False

# need RingSig
[docs]class Boyen(PKSig): """ >>> from charm.toolbox.pairinggroup import PairingGroup >>> group = PairingGroup('MNT224') >>> boyen = Boyen(group) >>> master_public_key = boyen.setup() >>> num_signers = 3 >>> keys = [ boyen.keygen(master_public_key) for i in range(num_signers)] >>> public_keys, secret_keys = {},{} >>> for i in range(len(keys)): ... public_keys[ i+1 ] = keys[ i ][ 0 ] ... secret_keys[ i+1 ] = keys[ i ][ 1 ] >>> signer = 3 >>> secret_key = secret_keys[signer] >>> msg = 'please sign this new message!' >>> signature = boyen.sign(signer, master_public_key, public_keys, secret_key, msg) >>> boyen.verify(master_public_key, public_keys, msg, signature) True """ def __init__(self, groupObj): global group group = groupObj
[docs] def setup(self): global H H = lambda a: group.hash(('1', str(a)), ZR) g1, g2 = group.random(G1), group.random(G2) a = [group.random(ZR) for i in range(3)] A = []; At = []; for i in range(3): A.append(g1 ** a[i]) At.append(g2 ** a[i]) # public verification key "in the sky" for all users return {'g1':g1, 'g2':g2, 'A':A[0], 'B':A[1], 'C':A[2], 'At':At[0], 'Bt':At[1], 'Ct':At[2]}
[docs] def keygen(self, mpk): a, b, c = group.random(ZR), group.random(ZR), group.random(ZR) A = mpk['g1'] ** a; B = mpk['g1'] ** b; C = mpk['g1'] ** c At = mpk['g2'] ** a; Bt = mpk['g2'] ** b; Ct = mpk['g2'] ** c sk = {'a':a, 'b':b, 'c':c} pk = {'A':A, 'B':B, 'C':C, 'At':At, 'Bt':Bt, 'Ct':Ct} return (pk, sk)
[docs] def getPKdict(self, mpk, pk, k): A_pk, B_pk, C_pk = {}, {}, {} A_pk[ 0 ] = mpk[ k[0] ] B_pk[ 0 ] = mpk[ k[1] ] C_pk[ 0 ] = mpk[ k[2] ] for i in pk.keys(): A_pk[ i ] = pk[ i ][ k[0] ] B_pk[ i ] = pk[ i ][ k[1] ] C_pk[ i ] = pk[ i ][ k[2] ] return A_pk, B_pk, C_pk
[docs] def sign(self, index, mpk, pk, sk, M): if debug: print("pk =>", pk.keys()) (A_pk, B_pk, C_pk) = self.getPKdict(mpk, pk, ['A', 'B', 'C']) m = H(M) l = len(A_pk.keys()) assert index >= 0 and index < l, "invalid index" if debug: print("l defined as =>", l) s = {} S = {} for i in range(0, l): if i != index: s[i] = group.random(ZR) S[i] = mpk['g1'] ** s[i] t = [group.random(ZR) for i in range(l)] # index=0 (A, B, C) = A_pk[ 0 ], B_pk[ 0 ], C_pk[ 0 ] prod = (A * (B ** m) * (C ** t[0])) ** -s[0] # 1 -> l for i in range(1, l): if i != index: (A, B, C) = A_pk[i], B_pk[i], C_pk[i] prod *= ((A * (B ** m) * (C ** t[i])) ** -s[i]) d = (sk['a'] + (sk['b'] * m) + (sk['c'] * t[index])) # s[l] S[index] = (mpk['g1'] * prod) ** (1 / d) # S[l] if debug: print("S[", index, "] :=", S[index]) sig = { 'S':S, 't':t } return sig
[docs] def verify(self, mpk, pk, M, sig): if debug: print("Verifying...") At, Bt, Ct = self.getPKdict(mpk, pk, ['At', 'Bt', 'Ct']) l = len(At.keys()) D = pair(mpk['g1'], mpk['g2']) S, t = sig['S'], sig['t'] m = H(M) dotProd0 = 1 for i in range(l): dotProd0 *= pair(S[i], At[i] * (Bt[i] ** m) * (Ct[i] ** t[i])) if dotProd0 == D: return True return False
[docs]def main(): groupObj = PairingGroup('MNT224') boyen = Boyen(groupObj) mpk = boyen.setup() if debug: print("Pub parameters") if debug: print(mpk, "\n\n") num_signers = 3 L_keys = [ boyen.keygen(mpk) for i in range(num_signers)] L_pk = {}; L_sk = {} for i in range(len(L_keys)): L_pk[ i+1 ] = L_keys[ i ][ 0 ] # pk L_sk[ i+1 ] = L_keys[ i ][ 1 ] if debug: print("Keygen...") if debug: print("sec keys =>", L_sk.keys(),"\n", L_sk) signer = 3 sk = L_sk[signer] M = 'please sign this new message!' sig = boyen.sign(signer, mpk, L_pk, sk, M) if debug: print("\nSignature...") if debug: print("sig =>", sig) assert boyen.verify(mpk, L_pk, M, sig), "invalid signature!" if debug: print("Verification successful!")
if __name__ == "__main__": debug = True main()