Skip to content

Instantly share code, notes, and snippets.

@dhedey
Last active January 6, 2022 21:14
Show Gist options
  • Save dhedey/02d23e1ff480e355d68713e201c35f50 to your computer and use it in GitHub Desktop.
Save dhedey/02d23e1ff480e355d68713e201c35f50 to your computer and use it in GitHub Desktop.
Demonstrates the algorithm for decoding message bytes with legacy support
# NB - This is intended as pseudo-code and I haven't added exception handling.
# The message_bytes is schema less and can be anything, so you should assume any of these decodings can fail.
def decode_full_message_with_legacy_support(transaction_context, message_bytes):
if message_bytes[0] == 0x00:
post_header_bytes = message_bytes[1:]
return decode_message_after_header(transaction_context, "PLAINTEXT", post_header_bytes)
elif message_bytes[0] == 0x01:
post_header_bytes = message_bytes[1:]
return decode_message_after_header(transaction_context, "ENCRYPTED", post_header_bytes)
elif message_bytes[0] == 0x30: # The message uses the legacy doubly-encoded format
decoded_post_header_bytes = bytearray.fromhex(message_bytes[2:].decode("utf-8"))
if message_bytes[1] == 0x30: # Header is "3030" which was x00
return decode_message_after_header(transaction_context, "PLAINTEXT", decoded_post_header_bytes)
if message_bytes[1] == 0x31: # Header is "3031" which was x01
return decode_message_after_header(transaction_context, "ENCRYPTED", decoded_post_header_bytes)
else:
raise RuntimeError("message_bytes " + message_bytes + " does not contain a valid first byte")
def decode_message_after_header(transaction_context, message_type, post_header_bytes):
encryption_scheme = post_header_bytes[0]
payload = post_header_bytes[1:]
return {
"type": message_type,
"encryption_scheme": encryption_scheme,
"message": convert_to_message_string(transaction_context, message_type, encryption_scheme, payload)
}
def convert_to_message_string(transaction_context, message_type, encryption_scheme, payload):
if message_type == "PLAINTEXT":
if encryption_scheme == 0x00:
return payload.decode("utf-8")
else:
raise RuntimeError("Invalid")
elif message_type == "ENCRYPTED":
if encryption_scheme == 0x00:
raise RuntimeError("Invalid")
elif encryption_scheme == 0xff:
decrypt_with_DH_ADD_EPH_AESGCM256_SCRYPT_000(transaction_context, payload).decode("utf-8")
else:
raise RuntimeError("Not supported")
else:
raise ValueError("message_type has invalid value: " + message_type)
def decrypt_with_DH_ADD_EPH_AESGCM256_SCRYPT_000(transaction_context, payload):
# Will read various pub/private keys of transaction_context, and decrypt a payload
# See https://radixtalk.com/t/how-to-decrypt-an-encrypted-transaction-message-created-by-the-radix-wallet/189
raise NotImplementedError("Not implemented")
test_message_bytes = bytearray.fromhex("303030303734363537333734"); # Should decrypt to "test"
print(decode_full_message_with_legacy_support(None, test_message_bytes))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment