1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-18 05:28:40 +00:00
trezor-firmware/core/src/apps/stellar/helpers.py

51 lines
1.4 KiB
Python
Raw Normal View History

2018-07-10 14:39:17 +00:00
import ustruct
2018-05-29 10:16:28 +00:00
from trezor.crypto import base32
2018-06-14 12:05:41 +00:00
from trezor.wire import ProcessError
2018-05-29 10:16:28 +00:00
2018-06-14 12:05:41 +00:00
def public_key_from_address(address: str) -> bytes:
"""Extracts public key from an address
Stellar address is in format:
<1-byte version> <32-bytes ed25519 public key> <2-bytes CRC-16 checksum>
"""
b = base32.decode(address)
_crc16_checksum_verify(b[:-2], b[-2:])
return b[1:-2]
def address_from_public_key(pubkey: bytes) -> str:
2018-05-29 10:16:28 +00:00
"""Returns the base32-encoded version of public key bytes (G...)"""
address = bytearray()
address.append(6 << 3) # version -> 'G'
address.extend(pubkey)
2018-06-14 12:05:41 +00:00
address.extend(_crc16_checksum(bytes(address))) # checksum
2018-05-29 10:16:28 +00:00
return base32.encode(address)
def _crc16_checksum_verify(data: bytes, checksum: bytes) -> None:
2018-06-14 12:05:41 +00:00
if _crc16_checksum(data) != checksum:
2018-07-10 14:39:17 +00:00
raise ProcessError("Invalid address checksum")
2018-06-14 12:05:41 +00:00
def _crc16_checksum(data: bytes) -> bytes:
2018-05-29 10:16:28 +00:00
"""Returns the CRC-16 checksum of bytearray bytes
Ported from Java implementation at: http://introcs.cs.princeton.edu/java/61data/CRC16CCITT.java.html
Initial value changed to 0x0000 to match Stellar configuration.
"""
crc = 0x0000
polynomial = 0x1021
for byte in data:
for i in range(8):
2018-07-10 14:39:17 +00:00
bit = (byte >> (7 - i) & 1) == 1
c15 = (crc >> 15 & 1) == 1
2018-05-29 10:16:28 +00:00
crc <<= 1
if c15 ^ bit:
crc ^= polynomial
return ustruct.pack("<H", crc & 0xFFFF)