Skip to content
    Decrypt Transaction Message@radixtalk
    main.py
    Packager files
    poetry.lock
    pyproject.toml
    import bech32
    import ecdsa
    import hashlib

    from ecdsa.curves import SECP256k1
    from ecdsa.keys import SigningKey, VerifyingKey
    from Crypto.Protocol.KDF import scrypt
    from Crypto.Cipher import AES


    encrypted_message = "01ff02663a6aaf4d5ec607330b9b74a840bf5c13b0a7357202fa85be56b1326065561657d6ee46d4d84e94ec615b425a472dd8c813bad125335a097d29b64b72319357406b2b04491b4ca1a5a05fe8772b0c05f4633b399914348c5b03af58445d42c2f740f8407e572775a571805e582c6b96ffd4ccca764f2002510abddaab735ee4fb0b18c26d"
    alice_wallet_address = "rdx1qsp8n0nx0muaewav2ksx99wwsu9swq5mlndjmn3gm9vl9q2mzmup0xqm2ylge"
    bob_private_key_hex = "0000000000000000000000000000000000000000000000000000000000000002"


    _hrp, alice_readdr_5bit = bech32.bech32_decode(alice_wallet_address)
    alice_readdr_bytes = bech32.convertbits(alice_readdr_5bit, 5, 8, pad=False)

    ## Remove the REAddr 04 prefix byte
    alice_public_key_bytes = bytes(alice_readdr_bytes)[1:34]

    alice_public_key_hex = bytes(alice_public_key_bytes).hex()
    print("Alice Public Key:", alice_public_key_hex)

    alice_public_key = VerifyingKey.from_string(bytearray.fromhex(alice_public_key_hex), curve=SECP256k1, hashfunc=hashlib.sha256 )

    bob_private_key_hex = "0000000000000000000000000000000000000000000000000000000000000002"
    bob_private_key = SigningKey.from_string(bytearray.fromhex(bob_private_key_hex), curve=SECP256k1, hashfunc=hashlib.sha256)

    # Diffie-Hellman - we need to use lower level functions here so that we get back dh as a curve point
    dh = alice_public_key.pubkey.point * bob_private_key.privkey.secret_multiplier

    # Message Type: 01 (1 byte)
    message_type = encrypted_message[0:2]

    # Encryption Type: ff (1 byte)
    encryption_type = encrypted_message[2:4]

    # Ephemeral Public Key: 02663a6aaf4d5ec607330b9b74a840bf5c13b0a7357202fa85be56b13260655616 (33 bytes)
    ephemeral_public_key = encrypted_message[4:70]

    # Nonce: 57d6ee46d4d84e94ec615b42 (12 bytes)
    nonce = encrypted_message[70:94]

    # Auth Tag: 5a472dd8c813bad125335a097d29b64b (16 bytes)
    auth_tag = encrypted_message[94:126]

    # Ciphertext: 72319357406b2b04491b4ca1a5a05fe8772b0c05f4633b399914348c5b03af58445d42c2f740f8407e572775a571805e582c6b96ffd4ccca764f2002510abddaab735ee4fb0b18c26d
    ciphertext = encrypted_message[126:]

    # Convert Ephemeral Public key into a Curve Point
    ephemeral_curve = VerifyingKey.from_string(bytearray.fromhex(ephemeral_public_key), curve=ecdsa.SECP256k1, hashfunc=hashlib.sha256)
    ephemeral_point = ephemeral_curve.pubkey.point

    # Elliptic Curve Point Addition
    shared_secret_point = dh + ephemeral_point

    shared_secret_integer = shared_secret_point.x()
    shared_secret_hex = hex(shared_secret_integer)[2:]

    print("Shared Secret:", shared_secret_hex)

    # Create the Scrypt salt from the SHA256 of the nonce
    salt = hashlib.sha256(bytearray.fromhex(nonce)).digest()

    # Get the Decryption Key
    key = scrypt(bytearray.fromhex(shared_secret_hex), salt, 32, 8192, 8 ,1)

    print("Decryption Key:", key.hex())

    decrypt = AES.new(key, AES.MODE_GCM, nonce=bytearray.fromhex(nonce))

    decrypt.update(bytearray.fromhex(ephemeral_public_key))

    msg = decrypt.decrypt_and_verify(bytearray.fromhex(ciphertext), bytearray.fromhex(auth_tag))

    print("Plaintext Message:", msg)