<s> """<STR_LIT>""" <EOL> from hashlib import sha256 <EOL> from tools import clean_string <EOL> import struct <EOL> import logging <EOL> class HashError ( Exception ) : <EOL> pass <EOL> class CryptError ( HashError ) : <EOL> pass <EOL> log = logging . getLogger ( "<STR_LIT>" ) <EOL> KByte = <NUM_LIT> <EOL> MByte = KByte * <NUM_LIT> <EOL> try : <EOL> from pycryptopp . cipher . aes import AES <EOL> except ImportError : <EOL> from Crypto . Cipher import AES <EOL> class Counter ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , a = <NUM_LIT:0> , b = <NUM_LIT:0> , c = <NUM_LIT:0> , d = <NUM_LIT:0> ) : <EOL> self . a = a <EOL> self . b = b <EOL> self . c = c <EOL> self . d = d <EOL> first = True <EOL> def __call__ ( self ) : <EOL> if self . first : <EOL> self . first = False <EOL> else : <EOL> if self . d < <NUM_LIT> : <EOL> self . d += <NUM_LIT:1> <EOL> elif self . c < <NUM_LIT> : <EOL> self . c += <NUM_LIT:1> <EOL> self . d = <NUM_LIT:0> <EOL> elif self . b < <NUM_LIT> : <EOL> self . b += <NUM_LIT:1> <EOL> self . c = self . d = <NUM_LIT:0> <EOL> elif self . a < <NUM_LIT> : <EOL> self . a += <NUM_LIT:1> <EOL> self . b = self . c = self . d = <NUM_LIT:0> <EOL> return struct . pack ( "<STR_LIT>" , self . a , self . b , self . c , self . d ) <EOL> def aes ( key , data , counter = False ) : <EOL> """<STR_LIT>""" <EOL> if hasattr ( AES , "<STR_LIT>" ) : <EOL> a = AES ( key ) <EOL> return a . process ( data ) <EOL> counter = counter or Counter ( ) <EOL> a = AES . new ( key , AES . MODE_CTR , counter = counter ) <EOL> rest = len ( data ) % <NUM_LIT:16> <EOL> if not rest : <EOL> return a . encrypt ( data ) <EOL> pad = ( <NUM_LIT:16> - rest ) <EOL> data += chr ( pad ) * pad <EOL> return a . encrypt ( data ) [ : - pad ] <EOL> class SHA256d ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , data = None , truncate_to = None ) : <EOL> """<STR_LIT>""" <EOL> self . h = sha256 ( ) <EOL> self . truncate_to = truncate_to <EOL> if data : <EOL> self . h . update ( data ) <EOL> def update ( self , data ) : <EOL> assert ( isinstance ( data , str ) ) <EOL> self . h . update ( data ) <EOL> def digest ( self ) : <EOL> return sha256 ( self . h . digest ( ) ) . digest ( ) [ : self . truncate_to ] <EOL> def hexdigest ( self ) : <EOL> return self . digest ( ) . encode ( '<STR_LIT>' ) <EOL> class ConvergentEncryption ( object ) : <EOL> """<STR_LIT>""" <EOL> info = "<STR_LIT>" <EOL> __convergence_secret = None <EOL> def __init__ ( self , secret = None , warn = True ) : <EOL> """<STR_LIT>""" <EOL> if secret : <EOL> self . set_convergence_secret ( secret ) <EOL> if not warn : <EOL> self . __warn_convergence ( warn = False ) <EOL> def set_convergence_secret ( self , secret ) : <EOL> """<STR_LIT>""" <EOL> secret = clean_string ( secret ) <EOL> if self . __convergence_secret and self . __convergence_secret != secret : <EOL> msg = "<STR_LIT>" <EOL> raise CryptError ( msg ) <EOL> self . __convergence_secret = secret <EOL> @ classmethod <EOL> def __warn_convergence ( cls , warn = True ) : <EOL> """<STR_LIT>""" <EOL> if not hasattr ( cls , "<STR_LIT>" ) and warn : <EOL> msg = "<STR_LIT>" <EOL> log . warning ( msg ) <EOL> cls . warned = True <EOL> def __sec_key ( self , data ) : <EOL> """<STR_LIT>""" <EOL> h = SHA256d ( data ) <EOL> if not self . __convergence_secret : <EOL> self . __warn_convergence ( ) <EOL> else : <EOL> h . update ( self . __convergence_secret ) <EOL> key = h . digest ( ) <EOL> del h <EOL> id = SHA256d ( key ) . digest ( ) <EOL> return key , id <EOL> def encrypt ( self , data ) : <EOL> """<STR_LIT>""" <EOL> assert ( isinstance ( data , str ) ) <EOL> key , id = self . __sec_key ( data ) <EOL> return key , id , aes ( key , data ) <EOL> def decrypt ( self , key , ciphertext , verify = False ) : <EOL> """<STR_LIT>""" <EOL> plain = aes ( key , ciphertext ) <EOL> if verify : <EOL> h = SHA256d ( plain ) <EOL> if self . __convergence_secret : <EOL> h . update ( self . __convergence_secret ) <EOL> digest = h . digest ( ) <EOL> if self . __convergence_secret and not key == digest : <EOL> msg = "<STR_LIT>" % SHA256d ( key ) . hexdigest ( ) <EOL> log . error ( msg ) <EOL> raise CryptError ( msg ) <EOL> return plain <EOL> def encrypt_key ( key , nonce , data ) : <EOL> """<STR_LIT>""" <EOL> key = clean_string ( key ) <EOL> key = SHA256d ( key ) . digest ( ) <EOL> nonce_hash = SHA256d ( nonce ) . digest ( ) <EOL> enc_key = aes ( key , nonce_hash ) <EOL> return aes ( enc_key , data ) </s>
