#NEWLINE# def decryptCell( cell , crypt_path ) : #NEWLINE# #INDENT# "Decrypt *cell* until it is recognized or we've tried all RelayCrypto's\n    in *crypt_path*.\n\n    Attempt to decrypt the cell one hop at a time. Stop if the cell is\n    recognized. Raise an exception if the cell is not recognized at all.\n\n    :param cell cell: cell to decrypt\n    :param list, oppy.crypto.relaycrypto.RelayCrypto crypt_path: list of\n        RelayCrypto instances to use for decryption\n    :param int origin: the originating hop we think this cell came from\n    :returns: the concrete RelayCell type of this decrypted cell\n    " #NEWLINE# origin = 0 #NEWLINE# recognized = False #NEWLINE# payload = cell . getPayload ( ) #NEWLINE# for node in crypt_path : #NEWLINE# #INDENT# payload = node . backward_cipher . decrypt ( payload ) #NEWLINE# if _cellRecognized ( payload , node ) : #NEWLINE# #INDENT# recognized = True #NEWLINE# break #NEWLINE# #UNINDENT# origin += 1 #NEWLINE# #UNINDENT# if ( not recognized ) : #NEWLINE# #INDENT# raise UnrecognizedCell ( ) #NEWLINE# #UNINDENT# updated_payload = _makePayloadWithDigest ( payload ) #NEWLINE# crypt_path [ origin ] . backward_digest . update ( updated_payload ) #NEWLINE# if ( cell . header . link_version < 4 ) : #NEWLINE# #INDENT# cid = struct . pack ( '!H' , cell . header . circ_id ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# cid = struct . pack ( '!I' , cell . header . circ_id ) #NEWLINE# #UNINDENT# cmd = struct . pack ( '!B' , cell . header . cmd ) #NEWLINE# dec = Cell . parse ( ( ( cid + cmd ) + payload ) ) #NEWLINE# return ( dec , origin )