Source code for protocol_cns07

""" 
Camenisch-Neven-shelat - Oblivious Transfer

| From: "J. Camenisch, G. Neven, a. shelat - Simulatable Adaptive Oblivious Transfer"
| Published in: EUROCRYPT 2007
| Available from: http://eprint.iacr.org/2008/014
| Notes: 

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

:Authors:    J. Ayo Akinyele
:Date:       2/2012
"""
from charm.core.engine.protocol import *
from charm.core.engine.util import *
from socket import *
from charm.toolbox.pairinggroup import PairingGroup,ZR,G1,G2,GT,pair
from charm.schemes.sigma1 import *
from charm.schemes.sigma2 import *
from charm.schemes.sigma3 import *
import sys

SENDER,RECEIVER = 1,2
HOST, PORT = "", 8083

[docs]class ObliviousTransfer(Protocol): def __init__(self, messages=None, groupObj=None, common_input=None): Protocol.__init__(self, None) receiver_states = { 2:self.receiver_init2, 4:self.receiver_transfer4, 6:self.receiver_transfer6, 8:self.receiver_transfer8 } sender_states = { 1:self.sender_init1, 3:self.sender_init3, 5:self.sender_transfer5, 7:self.sender_transfer7, 9:self.sender_transfer9 } receiver_trans = { 2:4, 4:6, 6:8 } sender_trans = { 1:3, 3:[3,5], 5:7, 7:9 } # describe the parties involved and the valid transitions Protocol.addPartyType(self, RECEIVER, receiver_states, receiver_trans) Protocol.addPartyType(self, SENDER, sender_states, sender_trans, True) # Protocol.setSerializers(self, self.serialize, self.deserialize) # make sure if groupObj == None: self.group = PairingGroup('SS512') else: self.group = groupObj # proof parameter generation if common_input == None: # generate common parameters to P and V db = {} self.__gen_setup = True else: # can be used as a sub-protocol if common_input is specified by caller db = common_input self.__gen_setup = False Protocol.setSubclassVars(self, self.group, db) if messages != None: self.M, self.sig = [], [] for i in range(0, len(messages)): self.M.append( bytes(messages[i], 'utf8') ) print("bytes =>", self.M[i],", message =>", messages[i]) # self.M.append(self.group.hash(messages[i], ZR)) # self.sig.append(messages[i]) # dict to hold variables from interaction
[docs] def get_common(self): if self.__gen_setup: g, h = self.group.random(G1), self.group.random(G2) H = pair(g, h) Protocol.store(self, ('g', g), ('h', h), ('H', H) ) return (g, h, H) else: # common parameters generated already return Protocol.get(self, ['g', 'h', 'H'])
# msgs => dict of M -> H(M)
[docs] def sender_init1(self): M = self.M print("SENDER 1: ") (g, h, H) = self.get_common() x = self.group.random(ZR) y = g ** x print("send g =>", g) print("send h =>", h) print("send H =>", H) print("send x =>", x) print("send y =>", y) A, B, C = {}, {}, {} for i in range(0, len(self.M)): j = self.group.init(ZR, i+1) print("j =>", j) A[i] = g ** ~(x + j) B[i] = pair(A[i], h) #, M[i]) C[i] = { 'A':A[i], 'B':B[i] } S = { 'g':g, 'h':h, 'H':H, 'y':y } Protocol.store(self, ('x', y), ('y',y), ('C', C) ) Protocol.setState(self, 3) return { 'S':S, 'C':C , 'PoK':'SigmaProtocol1' }
[docs] def sender_init3(self, input): print("SENDER 3: ", input) result = 'FAIL' pk = Protocol.get(self, ['g', 'H', 'h'], dict) if input == 'GO': PoK1 = SigmaProtocol1(self.group, pk) PoK1.setup( {'name':'prover', 'type':PoK1.PROVER, 'socket':self._socket} ) PoK1.execute(PoK1.PROVER, close_sock=False) # print("PoK1 prover result =>", PoK1.result) if PoK1.result == 'OK': # transition to transfer phase Protocol.setState(self, 5) result = PoK1.result # else: # JAA - something to this effect (Error case doesn't work yet) # Protocol.setState(self, 3); return {'PoK': 'REDO' } # need store and get functions for db return {'PoK': result }
[docs] def sender_transfer5(self, input): print("SENDER 5: query =>", input) if input.get('PoK') != None: # continue Protocol.setState(self, 7) return 'OK' Protocol.setState(self, None) return None
[docs] def sender_transfer7(self, input): # print("SENDER 7: input =>", input) if input.get('PoK2') != None: # pk = Protocol.get(self, ['g','g2','y'], dict) V = Protocol.get(self, ['V']) pk = { 'V':V } PoK2 = SigmaProtocol2(self.group, pk) PoK2.setup( {'name':'verifier', 'type':PoK2.VERIFIER, 'socket':self._socket} ) Protocol.send_msg(self, 'GO') PoK2.execute(PoK2.VERIFIER, close_sock=False) # print("PoK2 verifier result =>", PoK2.result) result = PoK2.result if result == 'OK': # print("transitioning to transfer9 result =>", result) h, V = Protocol.get(self, ['h','V']) W = pair(V, h) Protocol.setState(self, 9) return { 'PoK2':result, 'W':W, 'PoM':'SigmaProtocol3' } Protocol.setState(self, None) return None
[docs] def sender_transfer9(self, input): # print("SENDER 9: PoM init =>", input) if input == 'GO': # print("Executing the PoM interactive proof.") pk = Protocol.get(self, ['h','g','H','V'], dict) PoM = SigmaProtocol3(self.group, pk) PoM.setup( {'name':'prover', 'type':PoM.PROVER, 'socket':self._socket} ) PoM.execute(PoM.PROVER) print("PoM prover result =>", PoM.result) Protocol.setState(self, None) return None
################################# # END of SENDER state functions # #################################
[docs] def receiver_init2(self, input): print("RECEIVER 2: ") pk = Sigma.get(self, ['S']) if input['PoK'] == 'SigmaProtocol1': PoK1 = SigmaProtocol1(self.group, pk) PoK1.setup( {'name':'verifier', 'type':PoK1.VERIFIER, 'socket': self._socket} ) Protocol.send_msg(self, 'GO') # important: 1. acknowledges sub-protocol transition, 2. sends a short message using this socket PoK1.execute(PoK1.VERIFIER, close_sock=False) print("PoK1 verifier result =>", PoK1.result) result = PoK1.result if result == 'OK': Protocol.setState(self, 4) # desired: 4 (TBD) return {'PoK': result } # result should be R0 (state info) for Receiver
# let sender know to expect a PoK2 interaction next
[docs] def receiver_transfer4(self, input): # rec_tran4 -> sender_tran5 print("RECEIVER 4: Get query from end user.") index = 0 # maps to position 0 in array (+1 indexed) C = Protocol.get(self, ['C'])[0] v = self.group.random(ZR) # secret for Receiver V = C[index]['A'] ** v # public value Protocol.setState(self, 6) Protocol.store( self, ('v',v), ('V',V), ('query', index+1) ) return { 'V':V, 'PoK2':'SigmaProtocol2' }
[docs] def receiver_transfer6(self, input): print("RECEIVER 6: input =>",input) if input == 'GO': (pk, V, v, query) = Protocol.get(self, ['S','V','v','query']) pk['V'], pk['v'], pk['sigma'] = V, v, query # set up client end of PoK2 PoK2 = SigmaProtocol2(self.group, pk) PoK2.setup( {'name':'prover', 'type':PoK2.PROVER, 'socket':self._socket} ) PoK2.execute(PoK2.PROVER, close_sock=False) print("PoK2 prover result =>", PoK2.result) result = PoK2.result Protocol.setState(self, 8) return {'Pok2':result} Protocol.setState(self, None) return None
[docs] def receiver_transfer8(self, input): print("RECEIVER 8:") if input['PoK2'] != 'OK': Protocol.setState(self, None) return None if input.get('PoM') != None: # print("Executing the PoM interactive proof.") pk = Protocol.get(self, ['W'], dict) PoM = SigmaProtocol3(self.group, pk) PoM.setup( {'name':'verifier', 'type':PoM.VERIFIER, 'socket': self._socket} ) Protocol.send_msg(self, 'GO') # important: 1. acknowledges sub-protocol transition, 2. sends a short message using this socket PoM.execute(PoM.VERIFIER, close_sock=False) result = PoM.result print("PoM verifier result =>", result) if result == 'OK': # print("Now we recover ") # W allows us to unlock the appropriate keyword, right? # get query, B_query, and v (W, v, C) = Protocol.get(self, ['W','v','C']) index = 0 B = C[index]['B'] w = W ** ~v # m = self.xor(B, w) print("Query =>", index) print("Corresponding B =>", B) print("Original message key =>", w) print("Search complete!!!") Protocol.setState(self, None) return None
if __name__ == "__main__": if len(sys.argv) != 2: print("Usage: %s [-r or -s]" % sys.argv[0]) exit(-1) if sys.argv[1] == "-r": print("Operating as receiver...") svr = socket(AF_INET, SOCK_STREAM) svr.bind((HOST, PORT)) svr.listen(1) svr_sock, addr = svr.accept() print("Connected by ", addr) msgs = None _name, _type, _sock = "receiver", RECEIVER, svr_sock # sp.setup( {'name':"receiver", 'type':_type, 'socket':svr_sock} ) elif sys.argv[1] == "-s": print("Operating as sender...") clt = socket(AF_INET, SOCK_STREAM) clt.connect((HOST, PORT)) clt.settimeout(15) msgs = ['one', 'two', 'three'] _name, _type, _sock = "sender", SENDER, clt else: print("Usage: %s -r or -s" % sys.argv[0]) exit(-1) # group = PairingGroup('library/a.param') sp = ObliviousTransfer(msgs) sp.setup( {'name':_name, 'type':_type, 'socket':_sock} ) # run as a thread... sp.execute(_type)