def test_symmetric_one_pass(self): encrypt, decrypt = 1, 0 iv = ec.Cipher.gen_IV(self.ciphername) enc_cipher = ec.Cipher(self.secret_key, iv, encrypt, ciphername=self.ciphername) plaintext_part1 = "Test plaintext part 1" plaintext_part2 = "Test plaintext part 2" plaintext = plaintext_part1 + plaintext_part2 ciphertext_part1 = enc_cipher.update(plaintext_part1) ciphertext_part2 = enc_cipher.update(plaintext_part2) ciphertext_final = enc_cipher.final() ciphertext = "".join( (ciphertext_part1, ciphertext_part2, ciphertext_final)) dec_cipher = ec.Cipher(self.secret_key, iv, decrypt, ciphername=self.ciphername) self.assertEqual(plaintext, dec_cipher.ciphering(ciphertext))
def setup_cipher(self): # https://github.com/ethereum/cpp-ethereum/blob/develop/libp2p/RLPxFrameIO.cpp#L34 assert self.responder_nonce assert self.initiator_nonce assert self.auth_init assert self.auth_ack assert self.remote_ephemeral_pubkey if not self.ecc.is_valid_key(self.remote_ephemeral_pubkey): raise InvalidKeyError('invalid remote ephemeral pubkey') # derive base secrets from ephemeral key agreement # ecdhe-shared-secret = ecdh.agree(ephemeral-privkey, remote-ephemeral-pubk) ecdhe_shared_secret = self.ephemeral_ecc.get_ecdh_key( self.remote_ephemeral_pubkey) # shared-secret = sha3(ecdhe-shared-secret || sha3(nonce || initiator-nonce)) shared_secret = sha3(ecdhe_shared_secret + sha3(self.responder_nonce + self.initiator_nonce)) self.ecdhe_shared_secret = ecdhe_shared_secret # FIXME DEBUG self.shared_secret = shared_secret # FIXME DEBUG # token = sha3(shared-secret) self.token = sha3(shared_secret) self.token_by_pubkey[self.remote_pubkey] = self.token # aes-secret = sha3(ecdhe-shared-secret || shared-secret) self.aes_secret = sha3(ecdhe_shared_secret + shared_secret) # mac-secret = sha3(ecdhe-shared-secret || aes-secret) self.mac_secret = sha3(ecdhe_shared_secret + self.aes_secret) # setup sha3 instances for the MACs # egress-mac = sha3.update(mac-secret ^ recipient-nonce || auth-sent-init) mac1 = sha3_256( sxor(self.mac_secret, self.responder_nonce) + self.auth_init) # ingress-mac = sha3.update(mac-secret ^ initiator-nonce || auth-recvd-ack) mac2 = sha3_256( sxor(self.mac_secret, self.initiator_nonce) + self.auth_ack) if self.is_initiator: self.egress_mac, self.ingress_mac = mac1, mac2 else: self.egress_mac, self.ingress_mac = mac2, mac1 ciphername = 'aes-256-ctr' iv = "\x00" * 16 assert len(iv) == 16 self.aes_enc = pyelliptic.Cipher(self.aes_secret, iv, 1, ciphername=ciphername) self.aes_dec = pyelliptic.Cipher(self.aes_secret, iv, 0, ciphername=ciphername) self.mac_enc = AES.AESCipher(self.mac_secret, AES.MODE_ECB).encrypt self.is_ready = True
def encrypt(self, data: bytes, raw_pubkey: bytes, shared_mac_data: bytes = b'') -> bytes: """ ECIES Encrypt, where P = recipient public key is: 1) generate r = random value 2) generate shared-secret = kdf( ecdhAgree(r, P) ) 3) generate R = rG [same op as generating a public key] 4) send 0x04 || R || AES(shared-secret, plaintext) || tag """ enc_key, mac_key, ephem_pubkey = \ self.key_manager.get_ephem_key(raw_pubkey) iv = pyelliptic.Cipher.gen_IV(self.CIPHERNAME) assert len(iv) == 16 cipher = pyelliptic.Cipher(enc_key, iv, 1, self.CIPHERNAME) ciphertext = cipher.ciphering(data) assert len(ciphertext) == len(data) msg = ephem_pubkey + iv + ciphertext tag = pyelliptic.hmac_sha256(mac_key, msg[1 + 64:] + shared_mac_data) assert len(tag) == 32 msg += tag assert len(msg) == self.OVERHEAD + len(data) return msg
def encrypt(self, raw): raw = self.pad(raw) iv = pyelliptic.Cipher.gen_IV('aes-256-cfb') ctx = pyelliptic.Cipher(self.key, iv, 1, ciphername='aes-256-cfb') ciphertext = ctx.update(raw) ciphertext += ctx.final() return (iv + ciphertext).encode("hex")
def ecies_encrypt(cls, data, raw_pubkey, shared_mac_data=''): """ ECIES Encrypt, where P = recipient public key is: 1) generate r = random value 2) generate shared-secret = kdf( ecdhAgree(r, P) ) 3) generate R = rG [same op as generating a public key] 4) send 0x04 || R || AsymmetricEncrypt(shared-secret, plaintext) || tag currently used by go: ECIES_AES128_SHA256 = &ECIESParams{ Hash: sha256.New, hashAlgo: crypto.SHA256, Cipher: aes.NewCipher, BlockSize: aes.BlockSize, KeyLen: 16, } """ # 1) generate r = random value ephem = cls(None) # 2) generate shared-secret = kdf( ecdhAgree(r, P) ) key_material = ephem.raw_get_ecdh_key(pubkey_x=raw_pubkey[:32], pubkey_y=raw_pubkey[32:]) assert len(key_material) == 32 key = eciesKDF(key_material, 32) assert len(key) == 32 key_enc, key_mac = key[:16], key[16:] key_mac = hashlib.sha256(key_mac).digest() # !!! assert len(key_mac) == 32 # 3) generate R = rG [same op as generating a public key] ephem_pubkey = ephem.raw_pubkey # encrypt iv = pyelliptic.Cipher.gen_IV(cls.ecies_ciphername) assert len(iv) == 16 ctx = pyelliptic.Cipher(key_enc, iv, 1, cls.ecies_ciphername) ciphertext = ctx.ciphering(data) assert len(ciphertext) == len(data) # 4) send 0x04 || R || AsymmetricEncrypt(shared-secret, plaintext) # || tag msg = rlp_utils.ascii_chr(0x04) + ephem_pubkey + iv + ciphertext # the MAC of a message (called the tag) as per SEC 1, 3.5. tag = pyelliptic.hmac_sha256( key_mac, msg[1 + 64:] + rlp_utils.str_to_bytes(shared_mac_data)) assert len(tag) == 32 msg += tag assert len(msg) == 1 + 64 + 16 + 32 + len(data) == 113 + len(data) assert len(msg) - cls.ecies_encrypt_overhead_length == len(data) return msg
def something(): ################## # send authentication if not yet if not self._authentication_sent: remote_node = RemoteNode(remote_pubkey) # FIXME LOOKUP self.send_authentication(remote_node) # - success -> AcknowledgeAuthentication self.acknowledge_authentication(other, remote_pubkey, remote_ecdhe_pubkey) # ecdhe_shared_secret = ecdh.agree(ecdhe-random, ecdhe-random-public) # Compute public key with the local private key and return a 512bits shared key ecdhe_shared_secret = self.ephemeral_ecc.get_ecdh_key(remote_pubkey) ecdhe_pubkey = self.ephemeral_ecc.get_pubkey() # shared-secret = sha3(ecdhe-shared-secret || sha3(nonce || remote-nonce)) shared_secret = sha3(ecdhe_shared_secret + sha3(ienc(self.nonce) + ienc(remote_nonce))) self.aes_secret = sha3(ecdhe_shared_secret + shared_secret) self.mac_secret = sha3(ecdhe_shared_secret + self.aes_secret) # egress-mac = sha3(mac-secret^nonce || auth) self.egress_mac = sha3(sxor(self.mac_secret, self.nonce) + ciphertext) # ingress-mac = sha3(mac-secret^remote-nonce || auth) self.ingress_mac = sha3( sxor(self.mac_secret, remote_nonce) + ciphertext) self.token = sha3(shared_secret) iv = pyelliptic.Cipher.gen_IV('aes-256-ctr') self.aes_enc = pyelliptic.Cipher(self.aes_secret, iv, 1, ciphername='aes-256-ctr') self.aes_dec = pyelliptic.Cipher(self.aes_secret, iv, 0, ciphername='aes-256-ctr') self.is_ready = True
def ecies_decrypt(self, data, shared_mac_data=b''): """ Decrypt data with ECIES method using the local private key ECIES Decrypt (performed by recipient): 1) generate shared-secret = kdf( ecdhAgree(myPrivKey, msg[1:65]) ) 2) verify tag 3) decrypt ecdhAgree(r, recipientPublic) == ecdhAgree(recipientPrivate, R) [where R = r*G, and recipientPublic = recipientPrivate*G] """ if data[:1] != b'\x04': raise exceptions.DecryptionError("wrong ecies header") # 1) generate shared-secret = kdf( ecdhAgree(myPrivKey, msg[1:65]) ) _shared = data[1:1 + 64] # FIXME, check that _shared_pub is a valid one (on curve) key_material = self.raw_get_ecdh_key(pubkey_x=_shared[:32], pubkey_y=_shared[32:]) assert len(key_material) == 32 key = eciesKDF(key_material, 32) assert len(key) == 32 key_enc, key_mac = key[:16], key[16:] key_mac = hashlib.sha256(key_mac).digest() assert len(key_mac) == 32 tag = data[-32:] assert len(tag) == 32 # 2) verify tag hmaced_data = pyelliptic.hmac_sha256( key_mac, data[1 + 64:-32] + shared_mac_data) if not pyelliptic.equals(hmaced_data, tag): raise exceptions.DecryptionError("Fail to verify data") # 3) decrypt blocksize = pyelliptic.OpenSSL.get_cipher( self.ecies_ciphername).get_blocksize() # noqa iv = data[1 + 64:1 + 64 + blocksize] assert len(iv) == 16 ciphertext = data[1 + 64 + blocksize:-32] assert 1 + len(_shared) + len(iv) + len(ciphertext) + len(tag) == len( data) # noqa ctx = pyelliptic.Cipher(key_enc, iv, 0, self.ecies_ciphername) return ctx.ciphering(ciphertext)
def decrypt(self, data, raw_privkey, shared_mac_data=b''): """ Decrypt data with ECIES method using the local private key ECIES Decrypt (performed by recipient): 1) generate shared-secret = kdf( ecdhAgree(myPrivKey, msg[1:65]) ) 2) verify tag 3) decrypt ecdhAgree(r, recipientPublic) == ecdhAgree(recipientPrivate, R) [where R = r*G, and recipientPublic = recipientPrivate*G] """ if data[:1] != b'\x04': raise exceptions.DecryptionError("Wrong ECIES header") # 1) generate shared-secret ephem_pubkey = data[:1 + 64] key_material = self.key_manager.ecdh(HashablePrivateKey(raw_privkey), ephem_pubkey) assert len(key_material) == 32 enc_key, mac_key = self.key_manager.get_derived_keys(key_material) tag = data[-32:] assert len(tag) == 32 # 2) verify tag hmaced_data = pyelliptic.hmac_sha256( mac_key, data[1 + 64:-32] + shared_mac_data) if not pyelliptic.equals(hmaced_data, tag): raise exceptions.DecryptionError("Tag verification failed") # 3) decrypt iv = data[1 + 64:1 + 64 + self.BLOCK_SIZE] assert len(iv) == 16 ciphertext = data[1 + 64 + self.BLOCK_SIZE:-32] assert len(ephem_pubkey) + len(iv) + len(ciphertext) + len(tag) \ == len(data) cipher = pyelliptic.Cipher(enc_key, iv, 0, self.CIPHERNAME) msg = cipher.ciphering(ciphertext) assert len(msg) == len(ciphertext) return msg
def decrypt(self, data, shared_mac_data=b""): """ Decrypt data with ECIES method using the local private key ECIES Decrypt (performed by recipient): 1) generate shared-secret = kdf( ecdhAgree(myPrivKey, msg[1:65]) ) 2) verify tag 3) decrypt ecdhAgree(r, recipientPublic) == ecdhAgree(recipientPrivate, R) [where R = r*G, and recipientPublic = recipientPrivate*G] :param data: data to decrypt :param shared_mac_data: shared mac :return: decrypted data """ if not data: raise ValueError("Data is required") if data[:eth_common_constants. ECIES_HEADER_LEN] != eth_common_constants.ECIES_HEADER_BYTE: raise DecryptionError("Wrong ECIES header") # 1) generate shared-secret = kdf( ecdhAgree(myPrivKey, msg[1:65]) ) shared = data[eth_common_constants. ECIES_HEADER_LEN:eth_common_constants.ECIES_HEADER_LEN + eth_common_constants.PUBLIC_KEY_LEN] shared_pubkey_x = shared[:eth_common_constants.PUBLIC_KEY_X_Y_LEN] shared_pubkey_y = shared[eth_common_constants.PUBLIC_KEY_X_Y_LEN:] key_material = self.raw_get_ecdh_key(pubkey_x=shared_pubkey_x, pubkey_y=shared_pubkey_y) assert len(key_material) == eth_common_constants.KEY_MATERIAL_LEN key = crypto_utils.ecies_kdf(key_material, eth_common_constants.SHARED_KEY_LEN) assert len(key) == eth_common_constants.SHARED_KEY_LEN key_enc, key_mac = key[:eth_common_constants.ENC_KEY_LEN], key[ eth_common_constants.ENC_KEY_LEN:] key_mac = hashlib.sha256(key_mac).digest() assert len(key_mac) == eth_common_constants.MAC_LEN tag = data[-eth_common_constants.MAC_LEN:] assert len(tag) == eth_common_constants.MAC_LEN # 2) verify tag header_len = eth_common_constants.ECIES_HEADER_LEN + eth_common_constants.PUBLIC_KEY_LEN mac_data = data[header_len:- eth_common_constants.MAC_LEN] + \ shared_mac_data if not pyelliptic.equals(pyelliptic.hmac_sha256(key_mac, mac_data), tag): raise DecryptionError("Fail to verify data") # 3) decrypt block_size = pyelliptic.OpenSSL.get_cipher( eth_common_constants.ECIES_CIPHER_NAME).get_blocksize() iv = data[header_len:header_len + block_size] cipher_text = data[header_len + block_size:-eth_common_constants.MAC_LEN] assert eth_common_constants.ECIES_HEADER_LEN + len(shared) + len( iv) + len(cipher_text) + len(tag) == len(data) ctx = pyelliptic.Cipher(key_enc, iv, eth_common_constants.CIPHER_DECRYPT_DO, eth_common_constants.ECIES_CIPHER_NAME) return ctx.ciphering(cipher_text)
def receive_authentication(self, other, ciphertext): """ Verification (function, upon receive of PresetAuthentication): 3. remote generates ecdhe-random and nonce and creates auth 4. remote receives auth and decrypts (ECIES performs authentication before decryption) - If address is known, lookup token and public key to be authenticated - derive signature-message = sha3(token || addr^addrRemote) - success -> AcknowledgeAuthentication 5. remote sends auth 6. remote derives shared-secret, aes-secret, mac-secret, ingress-mac, egress-mac """ # eciesEncrypt(remote-pubk, sign(privkey, token^nonce) || 0x80 || ecdhe-random || nonce ) data = self.node.decrypt(ciphertext) assert len(data) == 64 + 1 + 64 + 32 signature = data[:65] assert data[65] == '0x80' remote_ecdhe_pubkey = data[65:65 + 64] token_or_nonce = idec(data[-32:]) # verify signature if not self.node.verify(signature, token_or_nonce): return self.disconnect() # recover remote pubkey remote_pubkey = ecdsa_recover(token_or_nonce, signature) # lookup pubkey and related token token_database = dict() # FIXME token = token_database.get(remote_pubkey, None) if token and token != token_or_nonce: # something fishy # FIXME reset node reputation pass remote_nonce = token_or_nonce # send authentication if not yet if not self._authentication_sent: remote_node = RemoteNode(remote_pubkey) # FIXME LOOKUP self.send_authentication(remote_node) # - success -> AcknowledgeAuthentication self.acknowledge_authentication(other, remote_pubkey, remote_ecdhe_pubkey) # ecdhe_shared_secret = ecdh.agree(ecdhe-random, ecdhe-random-public) # Compute public key with the local private key and return a 512bits shared key ecdhe_shared_secret = self.ephemeral_ecc.get_ecdh_key(remote_pubkey) ecdhe_pubkey = ephemeral_ecc.get_pubkey() # shared-secret = sha3(ecdhe-shared-secret || sha3(nonce || remote-nonce)) shared_secret = sha3(ecdhe_shared_secret + sha3(ienc(self.nonce) + ienc(remote_nonce))) self.aes_secret = sha3_256(ecdhe_shared_secret + shared_secret) self.mac_secret = sha3_256(ecdhe_shared_secret + self.aes_secret) # egress-mac = sha3(mac-secret^nonce || auth) self.egress_mac = sha3_256( sxor(self.mac_secret, self.nonce) + ciphertext) # ingress-mac = sha3(mac-secret^remote-nonce || auth) self.ingress_mac = sha3_256( sxor(self.mac_secret, remote_nonce) + ciphertext) self.token = sha3(shared_secret) iv = pyelliptic.Cipher.gen_IV('aes-256-ctr') self.aes_enc = pyelliptic.Cipher(self.aes_secret, iv, 1, ciphername='aes-256-ctr') self.aes_dec = pyelliptic.Cipher(self.aes_secret, iv, 0, ciphername='aes-256-ctr') self.is_ready = True
import pyelliptic # Symmetric encryption iv = pyelliptic.Cipher.gen_IV('aes-256-cfb') ctx = pyelliptic.Cipher("secretkey", iv, 1, ciphername='aes-256-cfb') ciphertext = ctx.update('test1') ciphertext += ctx.update('test2') ciphertext += ctx.final() ctx2 = pyelliptic.Cipher("secretkey", iv, 0, ciphername='aes-256-cfb') print ctx2.ciphering(ciphertext) # Asymmetric encryption alice = pyelliptic.ECC(curve='secp256k1') bob = pyelliptic.ECC(curve='secp256k1') ciphertext = alice.encrypt("Hello bbBob", bob.get_pubkey()) print bob.decrypt(ciphertext) signature = bob.sign("Hello Alice") # alice's job : print pyelliptic.ECC(pubkey=bob.get_pubkey()).verify(signature, "Hello Alice") # ERROR !!! try: key = alice.get_ecdh_key(bob.get_pubkey()) except: print( "For ECDH key agreement, the keys must be defined on the same curve !")
def decrypt_aes(encrypted_data, key, iv, ciphername=DEFAUL_CIPHERNAME): ctx = pyelliptic.Cipher(key, iv, 0, ciphername=ciphername) return ctx.ciphering(encrypted_data)
def encrypt_aes(data, key, ciphername=DEFAUL_CIPHERNAME): iv = pyelliptic.Cipher.gen_IV(ciphername) ctx = pyelliptic.Cipher(key, iv, 1, ciphername=ciphername) ciphertext = ctx.update(data) ciphertext += ctx.final() return hexlify(ciphertext), hexlify(iv)
def encrypt(cls, data, raw_public_key, shared_mac_data=""): """ ECIES Encrypt, where P = recipient public key is: 1) generate r = random value 2) generate shared-secret = kdf( ecdhAgree(r, P) ) 3) generate R = rG [same op as generating a public key] 4) send 0x04 || R || AsymmetricEncrypt(shared-secret, plaintext) || tag currently used by go: ECIES_AES128_SHA256 = &ECIESParams{ Hash: sha256.New, hashAlgo: crypto.SHA256, Cipher: aes.NewCipher, BlockSize: aes.BlockSize, KeyLen: 16, } :param data: data to encrypt :param raw_public_key: public key used of encryption :param shared_mac_data: shared mac :return: encrypted data """ if not data: raise ValueError("Data is required") if len(raw_public_key) != eth_common_constants.PUBLIC_KEY_LEN: raise ValueError( "Public key of len {0} is expected but was {1}".format( eth_common_constants.PUBLIC_KEY_LEN, len(raw_public_key))) # 1) generate r = random value ephem = ECCx() # 2) generate shared-secret = kdf( ecdhAgree(r, P) ) pubkey_x = raw_public_key[:eth_common_constants.PUBLIC_KEY_X_Y_LEN] pubkey_y = raw_public_key[eth_common_constants.PUBLIC_KEY_X_Y_LEN:] key_material = ephem.raw_get_ecdh_key(pubkey_x=pubkey_x, pubkey_y=pubkey_y) key = crypto_utils.ecies_kdf(key_material, eth_common_constants.SHARED_KEY_LEN) assert len(key) == eth_common_constants.SHARED_KEY_LEN key_enc, key_mac = key[:eth_common_constants.ENC_KEY_LEN], key[ eth_common_constants.ENC_KEY_LEN:] key_mac = hashlib.sha256(key_mac).digest() # 3) generate R = rG [same op as generating a public key] ephem_pubkey = ephem.get_raw_public_key() # encrypt iv = pyelliptic.Cipher.gen_IV(eth_common_constants.ECIES_CIPHER_NAME) assert len(iv) == eth_common_constants.IV_LEN ctx = pyelliptic.Cipher(key_enc, iv, eth_common_constants.CIPHER_ENCRYPT_DO, eth_common_constants.ECIES_CIPHER_NAME) cipher_text = ctx.ciphering(data) assert len(cipher_text) == len(data) # 4) send 0x04 || R || AsymmetricEncrypt(shared-secret, plaintext) || tag msg = rlp_utils.ascii_chr(eth_common_constants.ECIES_HEADER ) + ephem_pubkey + iv + cipher_text # the MAC of a message (called the tag) as per SEC 1, 3.5. tag = pyelliptic.hmac_sha256( key_mac, msg[eth_common_constants.ECIES_HEADER_LEN + eth_common_constants.PUBLIC_KEY_LEN:] + rlp_utils.str_to_bytes(shared_mac_data)) assert len(tag) == eth_common_constants.MAC_LEN msg += tag assert len( msg) - eth_common_constants.ECIES_ENCRYPT_OVERHEAD_LENGTH == len( data) return msg
def decrypt(self, enc): enc = enc.decode("hex") (iv, enc) = enc[:16], enc[16:] ctx = pyelliptic.Cipher(self.key, iv, 0, ciphername='aes-256-cfb') return self.unpad(ctx.ciphering(enc))
ecc = pyelliptic.ECC(privkey=myPrivkey, pubkey=myPubkey, curve='secp521r1') #Get Receiver public key r = requests.get(url + "/values/pubkey.json") receiverPubkey = unhexlify(r.json()["pubkey"]) #Generate Shared key sharedKey = ecc.get_ecdh_key(receiverPubkey) #Sign Message signature = ecc.sign(message) #Encrypt Message # Symmetric encryption iv = pyelliptic.Cipher.gen_IV('aes-256-cfb') ctx = pyelliptic.Cipher(sharedKey, iv, 1, ciphername='aes-256-cfb') ciphertext = ctx.update(message) ciphertext += ctx.final() print "Shared Key: ", hexlify(sharedKey) #Send Signature, Ciphertext and Public Key payload = { "ciphertext": ciphertext, "signature": signature, "pubkey": hexlify(ecc.get_pubkey()) } r = requests.post(url + "/receive", data=payload) print r.text
def setup_cipher(self): """ Sets up cipher parameters. Needs to be called after initial authentication handshake """ assert self._responder_nonce assert self._initiator_nonce assert self._auth_init assert self._auth_ack assert self._remote_ephemeral_pubkey if not self._ecc.is_valid_key(self._remote_ephemeral_pubkey): raise InvalidKeyError("Invalid remote ephemeral pubkey") # derive base secrets from ephemeral key agreement # ecdhe-shared-secret = ecdh.agree(ephemeral-privkey, remote-ephemeral-pubk) ecdhe_shared_secret = self._ephemeral_ecc.get_ecdh_key( self._remote_ephemeral_pubkey) # shared-secret = sha3(ecdhe-shared-secret || sha3(nonce || initiator-nonce)) shared_secret = eth_common_utils.keccak_hash( ecdhe_shared_secret + eth_common_utils.keccak_hash(self._responder_nonce + self._initiator_nonce)) self.ecdhe_shared_secret = ecdhe_shared_secret # used in tests self.shared_secret = shared_secret # used in tests # token = sha3(shared-secret) self._token = eth_common_utils.keccak_hash(shared_secret) # aes-secret = sha3(ecdhe-shared-secret || shared-secret) self._aes_secret = eth_common_utils.keccak_hash(ecdhe_shared_secret + shared_secret) # mac-secret = sha3(ecdhe-shared-secret || aes-secret) self.mac_secret = eth_common_utils.keccak_hash(ecdhe_shared_secret + self._aes_secret) # setup sha3 instances for the MACs # egress-mac = sha3.update(mac-secret ^ recipient-nonce || auth-sent-init) mac1 = crypto_utils.get_sha3_calculator( crypto_utils.string_xor(self.mac_secret, self._responder_nonce) + self._auth_init) # ingress-mac = sha3.update(mac-secret ^ initiator-nonce || auth-recvd-ack) mac2 = crypto_utils.get_sha3_calculator( crypto_utils.string_xor(self.mac_secret, self._initiator_nonce) + self._auth_ack) if self._is_initiator: self._egress_mac, self._ingress_mac = mac1, mac2 else: self._egress_mac, self._ingress_mac = mac2, mac1 iv = "\x00" * eth_common_constants.IV_LEN self._aes_enc = pyelliptic.Cipher( self._aes_secret, iv, eth_common_constants.CIPHER_ENCRYPT_DO, ciphername=eth_common_constants.RLPX_CIPHER_NAME) self._aes_dec = pyelliptic.Cipher( self._aes_secret, iv, eth_common_constants.CIPHER_DECRYPT_DO, ciphername=eth_common_constants.RLPX_CIPHER_NAME) self._mac_enc = AES.new(self.mac_secret, AES.MODE_ECB).encrypt self._is_ready = True