#!/usr/bin/python
from tinyec import registry
from Crypto.Cipher import AES
import secrets, binascii
curve = registry.get_curve('secp256r1')
#mobile random generate ecdh key pair
mobile_dh_privKey = secrets.randbelow(curve.field.n)
print("mobile_dh_privKey: " + hex(mobile_dh_privKey))
mobile_dh_pubKey = mobile_dh_privKey * curve.g
print("mobile_dh_pubKey: " + hex(mobile_dh_pubKey.x) + " , " + hex(mobile_dh_pubKey.y))
#bsrm random generate ecdh key pair
bsrm_dh_privKey = secrets.randbelow(curve.field.n)
print("bsrm_dh_privKey: " + hex(bsrm_dh_privKey))
bsrm_dh_pubKey = bsrm_dh_privKey * curve.g
print("bsrm_dh_pubKey: " + hex(bsrm_dh_pubKey.x) + " , " + hex(bsrm_dh_pubKey.y))
#communication message
msg = b'fortest'
print("\noriginal msg: " + str(msg) + "\n")
### {{ mobile
# mobile get bsrm_dh_pubKey from the hello message, calculate the Pre_Master_Secret
mobile_pre_master_secret = mobile_dh_privKey * bsrm_dh_pubKey
print("mobile_pre_master_secret: " + hex(mobile_pre_master_secret.x) + " , " + hex(mobile_pre_master_secret.y))
#the first 128bits of x-coordinate of Pre_Master_Secret
mobile_aes_gcm_key = (hex(mobile_pre_master_secret.x))[2:34]
#the first 96bits of y-coordinate of Pre_Master_Secret
mobile_aes_gcm_iv = (hex(mobile_pre_master_secret.y))[2:26]
print("mobile aes gcm key: " + mobile_aes_gcm_key + " , mobile aes gcm iv: " + mobile_aes_gcm_iv)
#mobile encrypt message, send the ciphertext and authTag to bsrm
aesCipher = AES.new(binascii.unhexlify(mobile_aes_gcm_key), AES.MODE_GCM, nonce = binascii.unhexlify(mobile_aes_gcm_iv))
ciphertext, authTag = aesCipher.encrypt_and_digest(msg)
print("\nmobile->bsrm ciphertext: " + str(binascii.hexlify(ciphertext)))
print("mobile->bsrm authTag: " + str(binascii.hexlify(authTag)) + "\n")
### }}
### {{ bsrm
# bsrm get mobile_dh_pubKey from the hello message, calculate the Pre_Master_Secret
bsrm_pre_master_secret = bsrm_dh_privKey * mobile_dh_pubKey
print("bsrm_pre_master_secret: " + hex(bsrm_pre_master_secret.x) + " , " + hex(bsrm_pre_master_secret.y))
#the first 128bits of x-coordinate of Pre_Master_Secret
bsrm_aes_gcm_key = (hex(bsrm_pre_master_secret.x))[2:34]
#the first 96bits of y-coordinate of Pre_Master_Secret
bsrm_aes_gcm_iv = (hex(bsrm_pre_master_secret.y))[2:26]
print("bsrm aes gcm key: " + bsrm_aes_gcm_key + " , bsrm aes gcm iv: " + bsrm_aes_gcm_iv)
#bsrm receive ciphertext and authTag from mobile, decrypt to plaintext message
aesCipher = AES.new(binascii.unhexlify(bsrm_aes_gcm_key), AES.MODE_GCM, nonce = binascii.unhexlify(bsrm_aes_gcm_iv))
plaintext = aesCipher.decrypt_and_verify(ciphertext, authTag)
print("\nbsrm decrypt plaintext: " + str(plaintext))
### }}