From 9459c5a5c2e5b8c8aeb281891d4d53a83278507e Mon Sep 17 00:00:00 2001 From: Andrew Kozlik Date: Wed, 24 Jun 2020 14:25:48 +0200 Subject: [PATCH] core/common: Add BytearrayReader and basic reader functions. --- core/src/apps/bitcoin/readers.py | 25 +++++++++++++++++ core/src/apps/common/readers.py | 47 ++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 core/src/apps/bitcoin/readers.py create mode 100644 core/src/apps/common/readers.py diff --git a/core/src/apps/bitcoin/readers.py b/core/src/apps/bitcoin/readers.py new file mode 100644 index 000000000..7c53f08c7 --- /dev/null +++ b/core/src/apps/bitcoin/readers.py @@ -0,0 +1,25 @@ +from apps.common.readers import BytearrayReader, read_bitcoin_varint + + +def read_bytes_prefixed(r: BytearrayReader) -> bytes: + n = read_bitcoin_varint(r) + return r.read(n) + + +def read_op_push(r: BytearrayReader) -> int: + prefix = r.get() + if prefix < 0x4C: + n = prefix + elif prefix == 0x4C: + n = r.get() + elif prefix == 0x4D: + n = r.get() + n += r.get() << 8 + elif prefix == 0x4E: + n = r.get() + n += r.get() << 8 + n += r.get() << 16 + n += r.get() << 24 + else: + raise ValueError + return n diff --git a/core/src/apps/common/readers.py b/core/src/apps/common/readers.py new file mode 100644 index 000000000..12bb2f52f --- /dev/null +++ b/core/src/apps/common/readers.py @@ -0,0 +1,47 @@ +if False: + from typing import Optional + + +class BytearrayReader: + def __init__(self, data: bytes): + self.data = data + self.offset = 0 + + def get(self) -> int: + ret = self.data[self.offset] + self.offset += 1 + return ret + + def peek(self) -> int: + return self.data[self.offset] + + def read(self, i: Optional[int] = None) -> bytes: + if i is None: + ret = self.data[self.offset :] + self.offset = len(self.data) + elif 0 <= i <= len(self.data) - self.offset: + ret = self.data[self.offset : self.offset + i] + self.offset += i + else: + raise IndexError + return ret + + def remaining_count(self) -> int: + return len(self.data) - self.offset + + +def read_bitcoin_varint(r: BytearrayReader) -> int: + prefix = r.get() + if prefix < 253: + n = prefix + elif prefix == 253: + n = r.get() + n += r.get() << 8 + elif prefix == 254: + n = r.get() + n += r.get() << 8 + n += r.get() << 16 + n += r.get() << 24 + else: + raise ValueError + return n