def deserialize_amount_non_xrp(scanner: Scanner) -> str: bits = from_bytes(scanner.take(8)) not_xrp_bit = bits & (1 << 63) assert not_xrp_bit sign_bit = bits & (1 << 62) unsigned_exponent = ((bits >> 54) & 0xFF) mantissa = bits & ((1 << 54) - 1) if not sign_bit and not unsigned_exponent and not mantissa: return '0' value = str(mantissa) exponent = unsigned_exponent - 97 if exponent > 0: padding = '0' * exponent value += padding else: places = -exponent if places > len(value): padding = '0' * (places - len(value)) value = '0.' + padding + value else: value = value[:exponent] + '.' + value[exponent:] if value[0] == '.': value = '0' + value value = value.rstrip('0') if value[-1] == '.': value = value[:-1] if not sign_bit: value = '-' + value return value
def derive_private_key(seed: bytes) -> int: sequence = 0 while True: buffer = seed + to_bytes(sequence, 4) private_key = from_bytes(hashes.sha512half(buffer)) if private_key != 0 and private_key < GROUP_ORDER: return private_key sequence += 1
def deserialize_amount(scanner: Scanner) -> Amount: byte1 = scanner.bite() # Most-significant bit is the format bit. 1 means "is not XRP". if not byte1 & (1 << 7): # Second most-significant bit is the sign bit. 1 means "is positive". sign = 1 if byte1 & (1 << 6) else -1 # Format bit is already cleared, but clear both top bits regardless. magnitude = from_bytes(scanner.take(8)) & ~(0b11 << 62) return str(sign * magnitude) value = deserialize_amount_non_xrp(scanner) currency = deserialize_currency(scanner) issuer = DEFAULT_CODEC.encode_address(t.cast(AccountId, scanner.take(20))) return {'value': value, 'currency': currency, 'issuer': issuer}
from fastecdsa import curve, ecdsa, keys from fastecdsa.encoding.der import DEREncoder # We use ecdsa only for verifying, until we can decode DER with fastecdsa: # https://github.com/AntonKueltz/fastecdsa/issues/47 from ecdsa import curves, VerifyingKey from ecdsa.util import sigdecode_der from xpring import hashes from xpring.algorithms.signing import Seed, PrivateKey, PublicKey, Signature from xpring.bits import from_bytes, to_bytes SEED_PREFIX = b'\x21' FAMILY = bytes(4) GROUP_ORDER = from_bytes( bytes. fromhex('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141') ) assert curve.secp256k1.q == GROUP_ORDER def derive_private_key(seed: bytes) -> int: sequence = 0 while True: buffer = seed + to_bytes(sequence, 4) private_key = from_bytes(hashes.sha512half(buffer)) if private_key != 0 and private_key < GROUP_ORDER: return private_key sequence += 1 def compress_ecdsa_point(point) -> PublicKey:
def deserialize_uint(bits: int, scanner: Scanner) -> int: return from_bytes(scanner.take(bits // 8))
def deserialize_transaction_type(scanner: Scanner) -> str: return TRANSACTION_TYPES_BY_CODE[from_bytes(scanner.take(2))]