coinex-api 0.0.89__py3-none-any.whl → 0.0.110__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of coinex-api might be problematic. Click here for more details.
- coinex/ccxt/__init__.py +1 -1
- coinex/ccxt/async_support/__init__.py +1 -1
- coinex/ccxt/async_support/base/exchange.py +139 -10
- coinex/ccxt/async_support/base/throttler.py +1 -1
- coinex/ccxt/async_support/base/ws/cache.py +1 -0
- coinex/ccxt/async_support/base/ws/client.py +26 -4
- coinex/ccxt/async_support/coinex.py +2 -2
- coinex/ccxt/base/exchange.py +587 -91
- coinex/ccxt/base/types.py +11 -2
- coinex/ccxt/coinex.py +2 -2
- coinex/ccxt/pro/__init__.py +1 -1
- coinex/ccxt/pro/coinex.py +10 -7
- coinex/ccxt/static_dependencies/bip/__init__.py +6 -0
- coinex/ccxt/static_dependencies/bip/addr/P2PKH_addr.py +205 -0
- coinex/ccxt/static_dependencies/bip/addr/__init__.py +5 -0
- coinex/ccxt/static_dependencies/bip/addr/addr_dec_utils.py +125 -0
- coinex/ccxt/static_dependencies/bip/addr/addr_key_validator.py +162 -0
- coinex/ccxt/static_dependencies/bip/addr/iaddr_decoder.py +48 -0
- coinex/ccxt/static_dependencies/bip/addr/iaddr_encoder.py +50 -0
- coinex/ccxt/static_dependencies/bip/base58/__init__.py +3 -0
- coinex/ccxt/static_dependencies/bip/base58/base58.py +207 -0
- coinex/ccxt/static_dependencies/bip/base58/base58_ex.py +25 -0
- coinex/ccxt/static_dependencies/bip/base58/base58_xmr.py +155 -0
- coinex/ccxt/static_dependencies/bip/bech32/__init__.py +4 -0
- coinex/ccxt/static_dependencies/bip/bech32/bch_bech32.py +220 -0
- coinex/ccxt/static_dependencies/bip/bech32/bech32.py +235 -0
- coinex/ccxt/static_dependencies/bip/bech32/bech32_base.py +246 -0
- coinex/ccxt/static_dependencies/bip/bech32/bech32_ex.py +25 -0
- coinex/ccxt/static_dependencies/bip/bech32/segwit_bech32.py +173 -0
- coinex/ccxt/static_dependencies/bip/bip32/__init__.py +14 -0
- coinex/ccxt/static_dependencies/bip/bip32/base/__init__.py +3 -0
- coinex/ccxt/static_dependencies/bip/bip32/base/bip32_base.py +581 -0
- coinex/ccxt/static_dependencies/bip/bip32/base/ibip32_key_derivator.py +83 -0
- coinex/ccxt/static_dependencies/bip/bip32/base/ibip32_mst_key_generator.py +47 -0
- coinex/ccxt/static_dependencies/bip/bip32/bip32_const.py +35 -0
- coinex/ccxt/static_dependencies/bip/bip32/bip32_ex.py +29 -0
- coinex/ccxt/static_dependencies/bip/bip32/bip32_key_data.py +500 -0
- coinex/ccxt/static_dependencies/bip/bip32/bip32_key_net_ver.py +83 -0
- coinex/ccxt/static_dependencies/bip/bip32/bip32_key_ser.py +294 -0
- coinex/ccxt/static_dependencies/bip/bip32/bip32_keys.py +457 -0
- coinex/ccxt/static_dependencies/bip/bip32/bip32_path.py +247 -0
- coinex/ccxt/static_dependencies/bip/bip32/bip32_utils.py +72 -0
- coinex/ccxt/static_dependencies/bip/bip32/kholaw/__init__.py +4 -0
- coinex/ccxt/static_dependencies/bip/bip32/kholaw/bip32_kholaw_ed25519.py +82 -0
- coinex/ccxt/static_dependencies/bip/bip32/kholaw/bip32_kholaw_ed25519_key_derivator.py +118 -0
- coinex/ccxt/static_dependencies/bip/bip32/kholaw/bip32_kholaw_key_derivator_base.py +204 -0
- coinex/ccxt/static_dependencies/bip/bip32/kholaw/bip32_kholaw_mst_key_generator.py +119 -0
- coinex/ccxt/static_dependencies/bip/bip32/slip10/__init__.py +1 -0
- coinex/ccxt/static_dependencies/bip/bip32/slip10/bip32_slip10_key_derivator.py +200 -0
- coinex/ccxt/static_dependencies/bip/bip32/slip10/bip32_slip10_mst_key_generator.py +168 -0
- coinex/ccxt/static_dependencies/bip/bip32/slip10/bip32_slip10_secp256k1.py +82 -0
- coinex/ccxt/static_dependencies/bip/bip44/__init__.py +1 -0
- coinex/ccxt/static_dependencies/bip/bip44/bip44.py +265 -0
- coinex/ccxt/static_dependencies/bip/bip44_base/__init__.py +3 -0
- coinex/ccxt/static_dependencies/bip/bip44_base/bip44_base.py +624 -0
- coinex/ccxt/static_dependencies/bip/bip44_base/bip44_base_ex.py +25 -0
- coinex/ccxt/static_dependencies/bip/bip44_base/bip44_keys.py +225 -0
- coinex/ccxt/static_dependencies/bip/coin_conf/__init__.py +2 -0
- coinex/ccxt/static_dependencies/bip/coin_conf/coin_conf.py +68 -0
- coinex/ccxt/static_dependencies/bip/coin_conf/coins_conf.py +890 -0
- coinex/ccxt/static_dependencies/bip/conf/__init__.py +0 -0
- coinex/ccxt/static_dependencies/bip/conf/bip44/__init__.py +3 -0
- coinex/ccxt/static_dependencies/bip/conf/bip44/bip44_coins.py +126 -0
- coinex/ccxt/static_dependencies/bip/conf/bip44/bip44_conf.py +1360 -0
- coinex/ccxt/static_dependencies/bip/conf/bip44/bip44_conf_getter.py +153 -0
- coinex/ccxt/static_dependencies/bip/conf/bip49/__init__.py +3 -0
- coinex/ccxt/static_dependencies/bip/conf/bip49/bip49_coins.py +53 -0
- coinex/ccxt/static_dependencies/bip/conf/bip49/bip49_conf.py +366 -0
- coinex/ccxt/static_dependencies/bip/conf/bip49/bip49_conf_getter.py +80 -0
- coinex/ccxt/static_dependencies/bip/conf/bip84/__init__.py +3 -0
- coinex/ccxt/static_dependencies/bip/conf/bip84/bip84_coins.py +39 -0
- coinex/ccxt/static_dependencies/bip/conf/bip84/bip84_conf.py +113 -0
- coinex/ccxt/static_dependencies/bip/conf/bip84/bip84_conf_getter.py +66 -0
- coinex/ccxt/static_dependencies/bip/conf/bip86/__init__.py +3 -0
- coinex/ccxt/static_dependencies/bip/conf/bip86/bip86_coins.py +37 -0
- coinex/ccxt/static_dependencies/bip/conf/bip86/bip86_conf.py +83 -0
- coinex/ccxt/static_dependencies/bip/conf/bip86/bip86_conf_getter.py +64 -0
- coinex/ccxt/static_dependencies/bip/conf/common/__init__.py +8 -0
- coinex/ccxt/static_dependencies/bip/conf/common/atom_addr.py +104 -0
- coinex/ccxt/static_dependencies/bip/conf/common/bip_bitcoin_cash_conf.py +106 -0
- coinex/ccxt/static_dependencies/bip/conf/common/bip_coin_conf.py +217 -0
- coinex/ccxt/static_dependencies/bip/conf/common/bip_coins.py +28 -0
- coinex/ccxt/static_dependencies/bip/conf/common/bip_conf_const.py +30 -0
- coinex/ccxt/static_dependencies/bip/conf/common/bip_litecoin_conf.py +121 -0
- coinex/ccxt/static_dependencies/bip/ecc/__init__.py +42 -0
- coinex/ccxt/static_dependencies/bip/ecc/common/__init__.py +0 -0
- coinex/ccxt/static_dependencies/bip/ecc/common/dummy_point.py +219 -0
- coinex/ccxt/static_dependencies/bip/ecc/common/ikeys.py +263 -0
- coinex/ccxt/static_dependencies/bip/ecc/common/ipoint.py +190 -0
- coinex/ccxt/static_dependencies/bip/ecc/conf.py +28 -0
- coinex/ccxt/static_dependencies/bip/ecc/curve/__init__.py +0 -0
- coinex/ccxt/static_dependencies/bip/ecc/curve/elliptic_curve.py +121 -0
- coinex/ccxt/static_dependencies/bip/ecc/curve/elliptic_curve_getter.py +74 -0
- coinex/ccxt/static_dependencies/bip/ecc/curve/elliptic_curve_types.py +37 -0
- coinex/ccxt/static_dependencies/bip/ecc/ecdsa/__init__.py +0 -0
- coinex/ccxt/static_dependencies/bip/ecc/ecdsa/ecdsa_keys.py +36 -0
- coinex/ccxt/static_dependencies/bip/ecc/secp256k1/__init__.py +0 -0
- coinex/ccxt/static_dependencies/bip/ecc/secp256k1/secp256k1.py +36 -0
- coinex/ccxt/static_dependencies/bip/ecc/secp256k1/secp256k1_const.py +59 -0
- coinex/ccxt/static_dependencies/bip/ecc/secp256k1/secp256k1_keys_ecdsa.py +248 -0
- coinex/ccxt/static_dependencies/bip/ecc/secp256k1/secp256k1_point_ecdsa.py +234 -0
- coinex/ccxt/static_dependencies/bip/slip/__init__.py +0 -0
- coinex/ccxt/static_dependencies/bip/slip/slip173/__init__.py +1 -0
- coinex/ccxt/static_dependencies/bip/slip/slip173/slip173.py +60 -0
- coinex/ccxt/static_dependencies/bip/slip/slip32/__init__.py +4 -0
- coinex/ccxt/static_dependencies/bip/slip/slip32/slip32.py +322 -0
- coinex/ccxt/static_dependencies/bip/slip/slip32/slip32_key_net_ver.py +62 -0
- coinex/ccxt/static_dependencies/bip/slip/slip44/__init__.py +1 -0
- coinex/ccxt/static_dependencies/bip/slip/slip44/slip44.py +81 -0
- coinex/ccxt/static_dependencies/bip/utils/__init__.py +0 -0
- coinex/ccxt/static_dependencies/bip/utils/conf/__init__.py +1 -0
- coinex/ccxt/static_dependencies/bip/utils/conf/coin_names.py +59 -0
- coinex/ccxt/static_dependencies/bip/utils/crypto/__init__.py +10 -0
- coinex/ccxt/static_dependencies/bip/utils/crypto/aes_ecb.py +152 -0
- coinex/ccxt/static_dependencies/bip/utils/crypto/blake2.py +191 -0
- coinex/ccxt/static_dependencies/bip/utils/crypto/chacha20_poly1305.py +101 -0
- coinex/ccxt/static_dependencies/bip/utils/crypto/hash160.py +57 -0
- coinex/ccxt/static_dependencies/bip/utils/crypto/hmac.py +118 -0
- coinex/ccxt/static_dependencies/bip/utils/crypto/pbkdf2.py +66 -0
- coinex/ccxt/static_dependencies/bip/utils/crypto/ripemd.py +58 -0
- coinex/ccxt/static_dependencies/bip/utils/crypto/scrypt.py +66 -0
- coinex/ccxt/static_dependencies/bip/utils/crypto/sha2.py +182 -0
- coinex/ccxt/static_dependencies/bip/utils/crypto/sha3.py +99 -0
- coinex/ccxt/static_dependencies/bip/utils/misc/__init__.py +7 -0
- coinex/ccxt/static_dependencies/bip/utils/misc/algo.py +108 -0
- coinex/ccxt/static_dependencies/bip/utils/misc/base32.py +151 -0
- coinex/ccxt/static_dependencies/bip/utils/misc/bit.py +115 -0
- coinex/ccxt/static_dependencies/bip/utils/misc/bytes.py +200 -0
- coinex/ccxt/static_dependencies/bip/utils/misc/data_bytes.py +181 -0
- coinex/ccxt/static_dependencies/bip/utils/misc/integer.py +97 -0
- coinex/ccxt/static_dependencies/bip/utils/misc/string.py +54 -0
- coinex/ccxt/static_dependencies/bip/utils/typing/__init__.py +1 -0
- coinex/ccxt/static_dependencies/bip/utils/typing/literal.py +27 -0
- coinex/ccxt/static_dependencies/bip/wif/__init__.py +1 -0
- coinex/ccxt/static_dependencies/bip/wif/wif.py +144 -0
- coinex/ccxt/static_dependencies/dydx_v4_client/amino/amino_pb2.py +31 -0
- coinex/ccxt/static_dependencies/dydx_v4_client/cosmos/base/v1beta1/coin_pb2.py +47 -0
- coinex/ccxt/static_dependencies/dydx_v4_client/cosmos/crypto/multisig/keys_pb2.py +33 -0
- coinex/ccxt/static_dependencies/dydx_v4_client/cosmos/crypto/multisig/v1beta1/multisig_pb2.py +33 -0
- coinex/ccxt/static_dependencies/dydx_v4_client/cosmos/crypto/secp256k1/keys_pb2.py +34 -0
- coinex/ccxt/static_dependencies/dydx_v4_client/cosmos/msg/v1/msg_pb2.py +27 -0
- coinex/ccxt/static_dependencies/dydx_v4_client/cosmos/tx/signing/v1beta1/signing_pb2.py +38 -0
- coinex/ccxt/static_dependencies/dydx_v4_client/cosmos/tx/v1beta1/tx_pb2.py +75 -0
- coinex/ccxt/static_dependencies/dydx_v4_client/cosmos_proto/cosmos_pb2.py +36 -0
- coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/accountplus/accountplus_pb2.py +31 -0
- coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/accountplus/genesis_pb2.py +40 -0
- coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/accountplus/models_pb2.py +26 -0
- coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/accountplus/params_pb2.py +29 -0
- coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/accountplus/query_pb2.py +57 -0
- coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/accountplus/tx_pb2.py +51 -0
- coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/clob/block_rate_limit_config_pb2.py +37 -0
- coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/clob/clob_pair_pb2.py +41 -0
- coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/clob/equity_tier_limit_config_pb2.py +35 -0
- coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/clob/finalize_block_pb2.py +27 -0
- coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/clob/liquidations_config_pb2.py +39 -0
- coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/clob/liquidations_pb2.py +38 -0
- coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/clob/matches_pb2.py +55 -0
- coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/clob/mev_pb2.py +49 -0
- coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/clob/operation_pb2.py +32 -0
- coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/clob/order_pb2.py +86 -0
- coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/clob/order_removals_pb2.py +32 -0
- coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/clob/process_proposer_matches_events_pb2.py +42 -0
- coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/clob/query_pb2.py +124 -0
- coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/clob/streaming_pb2.py +29 -0
- coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/clob/tx_pb2.py +117 -0
- coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/sending/genesis_pb2.py +26 -0
- coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/sending/query_pb2.py +26 -0
- coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/sending/transfer_pb2.py +61 -0
- coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/sending/tx_pb2.py +37 -0
- coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/subaccounts/asset_position_pb2.py +29 -0
- coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/subaccounts/genesis_pb2.py +30 -0
- coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/subaccounts/perpetual_position_pb2.py +33 -0
- coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/subaccounts/query_pb2.py +63 -0
- coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/subaccounts/streaming_pb2.py +31 -0
- coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/subaccounts/subaccount_pb2.py +33 -0
- coinex/ccxt/static_dependencies/dydx_v4_client/gogoproto/gogo_pb2.py +102 -0
- coinex/ccxt/static_dependencies/dydx_v4_client/registry.py +38 -0
- coinex/ccxt/static_dependencies/ecdsa/ellipticcurve.py +842 -0
- coinex/ccxt/static_dependencies/ecdsa/keys.py +15 -4
- coinex/ccxt/static_dependencies/mnemonic/__init__.py +4 -0
- coinex/ccxt/static_dependencies/mnemonic/mnemonic.py +282 -0
- coinex/ccxt/static_dependencies/mnemonic/py.typed +1 -0
- coinex/ccxt/static_dependencies/mnemonic/wordlist/chinese_simplified.txt +2048 -0
- coinex/ccxt/static_dependencies/mnemonic/wordlist/chinese_traditional.txt +2048 -0
- coinex/ccxt/static_dependencies/mnemonic/wordlist/czech.txt +2048 -0
- coinex/ccxt/static_dependencies/mnemonic/wordlist/english.txt +2048 -0
- coinex/ccxt/static_dependencies/mnemonic/wordlist/french.txt +2048 -0
- coinex/ccxt/static_dependencies/mnemonic/wordlist/italian.txt +2048 -0
- coinex/ccxt/static_dependencies/mnemonic/wordlist/japanese.txt +2048 -0
- coinex/ccxt/static_dependencies/mnemonic/wordlist/korean.txt +2048 -0
- coinex/ccxt/static_dependencies/mnemonic/wordlist/portuguese.txt +2048 -0
- coinex/ccxt/static_dependencies/mnemonic/wordlist/russian.txt +2048 -0
- coinex/ccxt/static_dependencies/mnemonic/wordlist/spanish.txt +2048 -0
- coinex/ccxt/static_dependencies/mnemonic/wordlist/turkish.txt +2048 -0
- {coinex_api-0.0.89.dist-info → coinex_api-0.0.110.dist-info}/METADATA +3 -3
- {coinex_api-0.0.89.dist-info → coinex_api-0.0.110.dist-info}/RECORD +197 -17
- {coinex_api-0.0.89.dist-info → coinex_api-0.0.110.dist-info}/WHEEL +1 -1
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
# Copyright (c) 2021 Emanuele Bellocchia
|
|
2
|
+
#
|
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
8
|
+
# furnished to do so, subject to the following conditions:
|
|
9
|
+
#
|
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
|
11
|
+
# all copies or substantial portions of the Software.
|
|
12
|
+
#
|
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
19
|
+
# THE SOFTWARE.
|
|
20
|
+
|
|
21
|
+
"""
|
|
22
|
+
Module for BitcoinCash bech32 decoding/encoding.
|
|
23
|
+
Reference: https://github.com/bitcoincashorg/bitcoincash.org/blob/master/spec/cashaddr.md
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
# Imports
|
|
27
|
+
from typing import List, Tuple
|
|
28
|
+
|
|
29
|
+
from .bech32_base import Bech32BaseUtils, Bech32DecoderBase, Bech32EncoderBase
|
|
30
|
+
from ..utils.misc import BytesUtils, IntegerUtils
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class BchBech32Const:
|
|
34
|
+
"""Class container for Bitcoin Cash Bech32 constants."""
|
|
35
|
+
|
|
36
|
+
# Separator
|
|
37
|
+
SEPARATOR: str = ":"
|
|
38
|
+
# Checksum length
|
|
39
|
+
CHECKSUM_STR_LEN: int = 8
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class BchBech32Utils:
|
|
43
|
+
"""Class container for Bitcoin Cash utility functions."""
|
|
44
|
+
|
|
45
|
+
@staticmethod
|
|
46
|
+
def PolyMod(values: List[int]) -> int:
|
|
47
|
+
"""
|
|
48
|
+
Computes the polynomial modulus.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
values (list[int]): List of polynomial coefficients
|
|
52
|
+
|
|
53
|
+
Returns:
|
|
54
|
+
int: Computed modulus
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
# Generator polynomial
|
|
58
|
+
generator = [
|
|
59
|
+
(0x01, 0x98f2bc8e61),
|
|
60
|
+
(0x02, 0x79b76d99e2),
|
|
61
|
+
(0x04, 0xf33e5fb3c4),
|
|
62
|
+
(0x08, 0xae2eabe2a8),
|
|
63
|
+
(0x10, 0x1e4f43e470)
|
|
64
|
+
]
|
|
65
|
+
# Compute modulus
|
|
66
|
+
chk = 1
|
|
67
|
+
for value in values:
|
|
68
|
+
top = chk >> 35
|
|
69
|
+
chk = ((chk & 0x07ffffffff) << 5) ^ value
|
|
70
|
+
for i in generator:
|
|
71
|
+
if top & i[0] != 0:
|
|
72
|
+
chk ^= i[1]
|
|
73
|
+
|
|
74
|
+
return chk ^ 1
|
|
75
|
+
|
|
76
|
+
@staticmethod
|
|
77
|
+
def HrpExpand(hrp: str) -> List[int]:
|
|
78
|
+
"""
|
|
79
|
+
Expand the HRP into values for checksum computation.
|
|
80
|
+
|
|
81
|
+
Args:
|
|
82
|
+
hrp (str): HRP
|
|
83
|
+
|
|
84
|
+
Returns:
|
|
85
|
+
list[int]: Expanded HRP values
|
|
86
|
+
"""
|
|
87
|
+
# [lower 5 bits of each character] + [0]
|
|
88
|
+
return [ord(x) & 0x1f for x in hrp] + [0]
|
|
89
|
+
|
|
90
|
+
@staticmethod
|
|
91
|
+
def ComputeChecksum(hrp: str,
|
|
92
|
+
data: List[int]) -> List[int]:
|
|
93
|
+
"""
|
|
94
|
+
Compute the checksum from the specified HRP and data.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
hrp (str) : HRP
|
|
98
|
+
data (list[int]): Data part
|
|
99
|
+
|
|
100
|
+
Returns:
|
|
101
|
+
list[int]: Computed checksum
|
|
102
|
+
"""
|
|
103
|
+
values = BchBech32Utils.HrpExpand(hrp) + data
|
|
104
|
+
polymod = BchBech32Utils.PolyMod(values + [0, 0, 0, 0, 0, 0, 0, 0])
|
|
105
|
+
return [(polymod >> 5 * (7 - i)) & 0x1f for i in range(BchBech32Const.CHECKSUM_STR_LEN)]
|
|
106
|
+
|
|
107
|
+
@staticmethod
|
|
108
|
+
def VerifyChecksum(hrp: str,
|
|
109
|
+
data: List[int]) -> bool:
|
|
110
|
+
"""
|
|
111
|
+
Verify the checksum from the specified HRP and converted data characters.
|
|
112
|
+
|
|
113
|
+
Args:
|
|
114
|
+
hrp (str) : HRP
|
|
115
|
+
data (list[int]): Data part
|
|
116
|
+
|
|
117
|
+
Returns:
|
|
118
|
+
bool: True if valid, false otherwise
|
|
119
|
+
"""
|
|
120
|
+
return BchBech32Utils.PolyMod(BchBech32Utils.HrpExpand(hrp) + data) == 0
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
class BchBech32Encoder(Bech32EncoderBase):
|
|
124
|
+
"""
|
|
125
|
+
Bitcoin Cash Bech32 encoder class.
|
|
126
|
+
It provides methods for encoding to Bitcoin Cash Bech32 format.
|
|
127
|
+
"""
|
|
128
|
+
|
|
129
|
+
@classmethod
|
|
130
|
+
def Encode(cls,
|
|
131
|
+
hrp: str,
|
|
132
|
+
net_ver: bytes,
|
|
133
|
+
data: bytes) -> str:
|
|
134
|
+
"""
|
|
135
|
+
Encode to Bitcoin Cash Bech32.
|
|
136
|
+
|
|
137
|
+
Args:
|
|
138
|
+
hrp (str) : HRP
|
|
139
|
+
net_ver (bytes): Net version
|
|
140
|
+
data (bytes) : Data
|
|
141
|
+
|
|
142
|
+
Returns:
|
|
143
|
+
str: Encoded address
|
|
144
|
+
|
|
145
|
+
Raises:
|
|
146
|
+
ValueError: If the data is not valid
|
|
147
|
+
"""
|
|
148
|
+
return cls._EncodeBech32(hrp,
|
|
149
|
+
Bech32BaseUtils.ConvertToBase32(net_ver + data),
|
|
150
|
+
BchBech32Const.SEPARATOR)
|
|
151
|
+
|
|
152
|
+
@staticmethod
|
|
153
|
+
def _ComputeChecksum(hrp: str,
|
|
154
|
+
data: List[int]) -> List[int]:
|
|
155
|
+
"""
|
|
156
|
+
Compute the checksum from the specified HRP and data.
|
|
157
|
+
|
|
158
|
+
Args:
|
|
159
|
+
hrp (str) : HRP
|
|
160
|
+
data (list[int]): Data part
|
|
161
|
+
|
|
162
|
+
Returns:
|
|
163
|
+
list[int]: Computed checksum
|
|
164
|
+
"""
|
|
165
|
+
return BchBech32Utils.ComputeChecksum(hrp, data)
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
class BchBech32Decoder(Bech32DecoderBase):
|
|
169
|
+
"""
|
|
170
|
+
Bitcoin Cash Bech32 decoder class.
|
|
171
|
+
It provides methods for decoding Bitcoin Cash Bech32 format.
|
|
172
|
+
"""
|
|
173
|
+
|
|
174
|
+
@classmethod
|
|
175
|
+
def Decode(cls,
|
|
176
|
+
hrp: str,
|
|
177
|
+
addr: str) -> Tuple[bytes, bytes]:
|
|
178
|
+
"""
|
|
179
|
+
Decode from Bitcoin Cash Bech32.
|
|
180
|
+
|
|
181
|
+
Args:
|
|
182
|
+
hrp (str) : Human readable part
|
|
183
|
+
addr (str): Address
|
|
184
|
+
|
|
185
|
+
Returns:
|
|
186
|
+
tuple[bytes, bytes]: Net version (index 0) and data (index 1)
|
|
187
|
+
|
|
188
|
+
Raises:
|
|
189
|
+
ValueError: If the bech32 string is not valid
|
|
190
|
+
Bech32ChecksumError: If the checksum is not valid
|
|
191
|
+
"""
|
|
192
|
+
|
|
193
|
+
# Decode string
|
|
194
|
+
hrp_got, data = cls._DecodeBech32(addr,
|
|
195
|
+
BchBech32Const.SEPARATOR,
|
|
196
|
+
BchBech32Const.CHECKSUM_STR_LEN)
|
|
197
|
+
|
|
198
|
+
# Check HRP
|
|
199
|
+
if hrp != hrp_got:
|
|
200
|
+
raise ValueError(f"Invalid format (HRP not valid, expected {hrp}, got {hrp_got})")
|
|
201
|
+
|
|
202
|
+
# Convert back from base32
|
|
203
|
+
conv_data = Bech32BaseUtils.ConvertFromBase32(data)
|
|
204
|
+
|
|
205
|
+
return IntegerUtils.ToBytes(conv_data[0]), BytesUtils.FromList(conv_data[1:])
|
|
206
|
+
|
|
207
|
+
@staticmethod
|
|
208
|
+
def _VerifyChecksum(hrp: str,
|
|
209
|
+
data: List[int]) -> bool:
|
|
210
|
+
"""
|
|
211
|
+
Verify the checksum from the specified HRP and converted data characters.
|
|
212
|
+
|
|
213
|
+
Args:
|
|
214
|
+
hrp (str) : HRP
|
|
215
|
+
data (list[int]): Data part
|
|
216
|
+
|
|
217
|
+
Returns:
|
|
218
|
+
bool: True if valid, false otherwise
|
|
219
|
+
"""
|
|
220
|
+
return BchBech32Utils.VerifyChecksum(hrp, data)
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
# Copyright (c) 2021 Emanuele Bellocchia
|
|
2
|
+
#
|
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
8
|
+
# furnished to do so, subject to the following conditions:
|
|
9
|
+
#
|
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
|
11
|
+
# all copies or substantial portions of the Software.
|
|
12
|
+
#
|
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
19
|
+
# THE SOFTWARE.
|
|
20
|
+
|
|
21
|
+
"""
|
|
22
|
+
Module for bech32/bech32m decoding/encoding.
|
|
23
|
+
|
|
24
|
+
References:
|
|
25
|
+
https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki
|
|
26
|
+
https://github.com/bitcoin/bips/blob/master/bip-0350.mediawiki
|
|
27
|
+
https://github.com/sipa/bech32/blob/master/ref/python/segwit_addr.py
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
# Imports
|
|
31
|
+
from enum import Enum, auto, unique
|
|
32
|
+
from typing import Dict, List
|
|
33
|
+
|
|
34
|
+
from .bech32_base import Bech32BaseUtils, Bech32DecoderBase, Bech32EncoderBase
|
|
35
|
+
from ..utils.misc import BytesUtils
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@unique
|
|
39
|
+
class Bech32Encodings(Enum):
|
|
40
|
+
"""Enumerative for Bech32 encoding types."""
|
|
41
|
+
|
|
42
|
+
BECH32 = auto()
|
|
43
|
+
BECH32M = auto()
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class Bech32Const:
|
|
47
|
+
"""Class container for Bech32 constants."""
|
|
48
|
+
|
|
49
|
+
# Separator
|
|
50
|
+
SEPARATOR: str = "1"
|
|
51
|
+
# Checksum length
|
|
52
|
+
CHECKSUM_STR_LEN: int = 6
|
|
53
|
+
# Encoding checksum constants
|
|
54
|
+
ENCODING_CHECKSUM_CONST: Dict[Bech32Encodings, int] = {
|
|
55
|
+
Bech32Encodings.BECH32: 1,
|
|
56
|
+
Bech32Encodings.BECH32M: 0x2bc830a3,
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class Bech32Utils:
|
|
61
|
+
"""Class container for Bech32 utility functions."""
|
|
62
|
+
|
|
63
|
+
@staticmethod
|
|
64
|
+
def PolyMod(values: List[int]) -> int:
|
|
65
|
+
"""
|
|
66
|
+
Computes the polynomial modulus.
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
values (list[int]): List of polynomial coefficients
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
int: Computed modulus
|
|
73
|
+
"""
|
|
74
|
+
|
|
75
|
+
# Generator polynomial
|
|
76
|
+
generator = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3]
|
|
77
|
+
|
|
78
|
+
# Compute modulus
|
|
79
|
+
chk = 1
|
|
80
|
+
for value in values:
|
|
81
|
+
top = chk >> 25
|
|
82
|
+
chk = (chk & 0x1ffffff) << 5 ^ value
|
|
83
|
+
for i in range(5):
|
|
84
|
+
chk ^= generator[i] if ((top >> i) & 1) else 0
|
|
85
|
+
return chk
|
|
86
|
+
|
|
87
|
+
@staticmethod
|
|
88
|
+
def HrpExpand(hrp: str) -> List[int]:
|
|
89
|
+
"""
|
|
90
|
+
Expand the HRP into values for checksum computation.
|
|
91
|
+
|
|
92
|
+
Args:
|
|
93
|
+
hrp (str): HRP
|
|
94
|
+
|
|
95
|
+
Returns:
|
|
96
|
+
list[int]: Expanded HRP values
|
|
97
|
+
"""
|
|
98
|
+
# [upper 3 bits of each character] + [0] + [lower 5 bits of each character]
|
|
99
|
+
return [ord(x) >> 5 for x in hrp] + [0] + [ord(x) & 0x1f for x in hrp]
|
|
100
|
+
|
|
101
|
+
@staticmethod
|
|
102
|
+
def ComputeChecksum(hrp: str,
|
|
103
|
+
data: List[int],
|
|
104
|
+
encoding: Bech32Encodings = Bech32Encodings.BECH32) -> List[int]:
|
|
105
|
+
"""
|
|
106
|
+
Compute the checksum from the specified HRP and data.
|
|
107
|
+
|
|
108
|
+
Args:
|
|
109
|
+
hrp (str) : HRP
|
|
110
|
+
data (list[int]) : Data part
|
|
111
|
+
encoding (Bech32Encodings, optional): Encoding type (BECH32 by default)
|
|
112
|
+
|
|
113
|
+
Returns:
|
|
114
|
+
list[int]: Computed checksum
|
|
115
|
+
"""
|
|
116
|
+
values = Bech32Utils.HrpExpand(hrp) + data
|
|
117
|
+
polymod = Bech32Utils.PolyMod(values + [0, 0, 0, 0, 0, 0]) ^ Bech32Const.ENCODING_CHECKSUM_CONST[encoding]
|
|
118
|
+
return [(polymod >> 5 * (5 - i)) & 0x1f for i in range(Bech32Const.CHECKSUM_STR_LEN)]
|
|
119
|
+
|
|
120
|
+
@staticmethod
|
|
121
|
+
def VerifyChecksum(hrp: str,
|
|
122
|
+
data: List[int],
|
|
123
|
+
encoding: Bech32Encodings = Bech32Encodings.BECH32) -> bool:
|
|
124
|
+
"""
|
|
125
|
+
Verify the checksum from the specified HRP and converted data characters.
|
|
126
|
+
|
|
127
|
+
Args:
|
|
128
|
+
hrp (str) : HRP
|
|
129
|
+
data (list[int]) : Data part
|
|
130
|
+
encoding (Bech32Encodings, optional): Encoding type (BECH32 by default)
|
|
131
|
+
|
|
132
|
+
Returns:
|
|
133
|
+
bool: True if valid, false otherwise
|
|
134
|
+
"""
|
|
135
|
+
polymod = Bech32Utils.PolyMod(Bech32Utils.HrpExpand(hrp) + data)
|
|
136
|
+
return polymod == Bech32Const.ENCODING_CHECKSUM_CONST[encoding]
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
class Bech32Encoder(Bech32EncoderBase):
|
|
140
|
+
"""
|
|
141
|
+
Bech32 encoder class.
|
|
142
|
+
It provides methods for encoding to Bech32 format.
|
|
143
|
+
"""
|
|
144
|
+
|
|
145
|
+
@classmethod
|
|
146
|
+
def Encode(cls,
|
|
147
|
+
hrp: str,
|
|
148
|
+
data: bytes) -> str:
|
|
149
|
+
"""
|
|
150
|
+
Encode to Bech32.
|
|
151
|
+
|
|
152
|
+
Args:
|
|
153
|
+
hrp (str) : HRP
|
|
154
|
+
data (bytes): Data
|
|
155
|
+
|
|
156
|
+
Returns:
|
|
157
|
+
str: Encoded address
|
|
158
|
+
|
|
159
|
+
Raises:
|
|
160
|
+
ValueError: If the data is not valid
|
|
161
|
+
"""
|
|
162
|
+
return cls._EncodeBech32(hrp,
|
|
163
|
+
Bech32BaseUtils.ConvertToBase32(data),
|
|
164
|
+
Bech32Const.SEPARATOR)
|
|
165
|
+
|
|
166
|
+
@staticmethod
|
|
167
|
+
def _ComputeChecksum(hrp: str,
|
|
168
|
+
data: List[int]) -> List[int]:
|
|
169
|
+
"""
|
|
170
|
+
Compute the checksum from the specified HRP and data.
|
|
171
|
+
|
|
172
|
+
Args:
|
|
173
|
+
hrp (str) : HRP
|
|
174
|
+
data (list[int]): Data part
|
|
175
|
+
|
|
176
|
+
Returns:
|
|
177
|
+
list[int]: Computed checksum
|
|
178
|
+
"""
|
|
179
|
+
|
|
180
|
+
# Same as Segwit
|
|
181
|
+
return Bech32Utils.ComputeChecksum(hrp, data)
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
class Bech32Decoder(Bech32DecoderBase):
|
|
185
|
+
"""
|
|
186
|
+
Bech32 decoder class.
|
|
187
|
+
It provides methods for decoding Bech32 format.
|
|
188
|
+
"""
|
|
189
|
+
|
|
190
|
+
@classmethod
|
|
191
|
+
def Decode(cls,
|
|
192
|
+
hrp: str,
|
|
193
|
+
addr: str) -> bytes:
|
|
194
|
+
"""
|
|
195
|
+
Decode from Bech32.
|
|
196
|
+
|
|
197
|
+
Args:
|
|
198
|
+
hrp (str) : Human readable part
|
|
199
|
+
addr (str): Address
|
|
200
|
+
|
|
201
|
+
Returns:
|
|
202
|
+
bytes: Decoded address
|
|
203
|
+
|
|
204
|
+
Raises:
|
|
205
|
+
ValueError: If the bech32 string is not valid
|
|
206
|
+
Bech32ChecksumError: If the checksum is not valid
|
|
207
|
+
"""
|
|
208
|
+
|
|
209
|
+
# Decode string
|
|
210
|
+
hrp_got, data = cls._DecodeBech32(addr,
|
|
211
|
+
Bech32Const.SEPARATOR,
|
|
212
|
+
Bech32Const.CHECKSUM_STR_LEN)
|
|
213
|
+
# Check HRP
|
|
214
|
+
if hrp != hrp_got:
|
|
215
|
+
raise ValueError(f"Invalid format (HRP not valid, expected {hrp}, got {hrp_got})")
|
|
216
|
+
|
|
217
|
+
# Convert back from base32
|
|
218
|
+
return BytesUtils.FromList(
|
|
219
|
+
Bech32BaseUtils.ConvertFromBase32(data)
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
@staticmethod
|
|
223
|
+
def _VerifyChecksum(hrp: str,
|
|
224
|
+
data: List[int]) -> bool:
|
|
225
|
+
"""
|
|
226
|
+
Verify the checksum from the specified HRP and converted data characters.
|
|
227
|
+
|
|
228
|
+
Args:
|
|
229
|
+
hrp (str) : HRP
|
|
230
|
+
data (list[int]): Data part
|
|
231
|
+
|
|
232
|
+
Returns:
|
|
233
|
+
bool: True if valid, false otherwise
|
|
234
|
+
"""
|
|
235
|
+
return Bech32Utils.VerifyChecksum(hrp, data)
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
# Copyright (c) 2021 Emanuele Bellocchia
|
|
2
|
+
#
|
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
8
|
+
# furnished to do so, subject to the following conditions:
|
|
9
|
+
#
|
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
|
11
|
+
# all copies or substantial portions of the Software.
|
|
12
|
+
#
|
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
19
|
+
# THE SOFTWARE.
|
|
20
|
+
|
|
21
|
+
"""Module for base bech32 decoding/encoding."""
|
|
22
|
+
|
|
23
|
+
# Imports
|
|
24
|
+
from abc import ABC, abstractmethod
|
|
25
|
+
from typing import List, Optional, Tuple, Union
|
|
26
|
+
|
|
27
|
+
from .bech32_ex import Bech32ChecksumError
|
|
28
|
+
from ..utils.misc import AlgoUtils
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class Bech32BaseConst:
|
|
32
|
+
"""Class container for Bech32 constants."""
|
|
33
|
+
|
|
34
|
+
# Character set
|
|
35
|
+
CHARSET: str = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class Bech32BaseUtils:
|
|
39
|
+
"""Class container for Bech32 utility functions."""
|
|
40
|
+
|
|
41
|
+
@staticmethod
|
|
42
|
+
def ConvertToBase32(data: Union[List[int], bytes]) -> List[int]:
|
|
43
|
+
"""
|
|
44
|
+
Convert data to base32.
|
|
45
|
+
|
|
46
|
+
Args:
|
|
47
|
+
data (list[int] or bytes): Data to be converted
|
|
48
|
+
|
|
49
|
+
Returns:
|
|
50
|
+
list[int]: Converted data
|
|
51
|
+
|
|
52
|
+
Raises:
|
|
53
|
+
ValueError: If the string is not valid
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
# Convert to base32
|
|
57
|
+
conv_data = Bech32BaseUtils.ConvertBits(data, 8, 5)
|
|
58
|
+
if conv_data is None:
|
|
59
|
+
raise ValueError("Invalid data, cannot perform conversion to base32")
|
|
60
|
+
|
|
61
|
+
return conv_data
|
|
62
|
+
|
|
63
|
+
@staticmethod
|
|
64
|
+
def ConvertFromBase32(data: Union[List[int], bytes]) -> List[int]:
|
|
65
|
+
"""
|
|
66
|
+
Convert data from base32.
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
data (list[int] or bytes): Data to be converted
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
list[int]: Converted data
|
|
73
|
+
|
|
74
|
+
Raises:
|
|
75
|
+
ValueError: If the string is not valid
|
|
76
|
+
"""
|
|
77
|
+
|
|
78
|
+
# Convert from base32
|
|
79
|
+
conv_data = Bech32BaseUtils.ConvertBits(data, 5, 8, False)
|
|
80
|
+
if conv_data is None:
|
|
81
|
+
raise ValueError("Invalid data, cannot perform conversion from base32")
|
|
82
|
+
|
|
83
|
+
return conv_data
|
|
84
|
+
|
|
85
|
+
@staticmethod
|
|
86
|
+
def ConvertBits(data: Union[bytes, List[int]],
|
|
87
|
+
from_bits: int,
|
|
88
|
+
to_bits: int,
|
|
89
|
+
pad: bool = True) -> Optional[List[int]]:
|
|
90
|
+
"""
|
|
91
|
+
Perform bit conversion.
|
|
92
|
+
The function takes the input data (list of integers or byte sequence) and convert every value from
|
|
93
|
+
the specified number of bits to the specified one.
|
|
94
|
+
It returns a list of integer where every number is less than 2^to_bits.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
data (list[int] or bytes): Data to be converted
|
|
98
|
+
from_bits (int) : Number of bits to start from
|
|
99
|
+
to_bits (int) : Number of bits to end with
|
|
100
|
+
pad (bool, optional) : True if data must be padded with zeros, false otherwise
|
|
101
|
+
|
|
102
|
+
Returns:
|
|
103
|
+
list[int]: List of converted values, None in case of errors
|
|
104
|
+
"""
|
|
105
|
+
max_out_val = (1 << to_bits) - 1
|
|
106
|
+
max_acc = (1 << (from_bits + to_bits - 1)) - 1
|
|
107
|
+
|
|
108
|
+
acc = 0
|
|
109
|
+
bits = 0
|
|
110
|
+
ret = []
|
|
111
|
+
|
|
112
|
+
for value in data:
|
|
113
|
+
# Value shall not be less than zero or greater than 2^from_bits
|
|
114
|
+
if value < 0 or (value >> from_bits):
|
|
115
|
+
return None
|
|
116
|
+
# Continue accumulating until greater than to_bits
|
|
117
|
+
acc = ((acc << from_bits) | value) & max_acc
|
|
118
|
+
bits += from_bits
|
|
119
|
+
while bits >= to_bits:
|
|
120
|
+
bits -= to_bits
|
|
121
|
+
ret.append((acc >> bits) & max_out_val)
|
|
122
|
+
if pad:
|
|
123
|
+
if bits:
|
|
124
|
+
# Pad the value with zeros to reach to_bits
|
|
125
|
+
ret.append((acc << (to_bits - bits)) & max_out_val)
|
|
126
|
+
elif bits >= from_bits or ((acc << (to_bits - bits)) & max_out_val):
|
|
127
|
+
return None
|
|
128
|
+
|
|
129
|
+
return ret
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
class Bech32EncoderBase(ABC):
|
|
133
|
+
"""
|
|
134
|
+
Bech32 encoder base class.
|
|
135
|
+
It provides methods for encoding to Bech32 format.
|
|
136
|
+
"""
|
|
137
|
+
|
|
138
|
+
@classmethod
|
|
139
|
+
def _EncodeBech32(cls,
|
|
140
|
+
hrp: str,
|
|
141
|
+
data: List[int],
|
|
142
|
+
sep: str) -> str:
|
|
143
|
+
"""
|
|
144
|
+
Encode a Bech32 string from the specified HRP and data.
|
|
145
|
+
|
|
146
|
+
Args:
|
|
147
|
+
hrp (str) : HRP
|
|
148
|
+
data (list[int]): Data part
|
|
149
|
+
sep (str) : Bech32 separator
|
|
150
|
+
|
|
151
|
+
Returns:
|
|
152
|
+
str: Encoded data
|
|
153
|
+
"""
|
|
154
|
+
|
|
155
|
+
# Add checksum to data
|
|
156
|
+
data += cls._ComputeChecksum(hrp, data)
|
|
157
|
+
# Encode to alphabet
|
|
158
|
+
return hrp + sep + "".join([Bech32BaseConst.CHARSET[d] for d in data])
|
|
159
|
+
|
|
160
|
+
@staticmethod
|
|
161
|
+
@abstractmethod
|
|
162
|
+
def _ComputeChecksum(hrp: str,
|
|
163
|
+
data: List[int]) -> List[int]:
|
|
164
|
+
"""
|
|
165
|
+
Compute the checksum from the specified HRP and data.
|
|
166
|
+
|
|
167
|
+
Args:
|
|
168
|
+
hrp (str) : HRP
|
|
169
|
+
data (list[int]): Data part
|
|
170
|
+
|
|
171
|
+
Returns:
|
|
172
|
+
list[int]: Computed checksum
|
|
173
|
+
"""
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
class Bech32DecoderBase(ABC):
|
|
177
|
+
"""
|
|
178
|
+
Bech32 decoder base class.
|
|
179
|
+
It provides methods for decoding Bech32 format.
|
|
180
|
+
"""
|
|
181
|
+
|
|
182
|
+
@classmethod
|
|
183
|
+
def _DecodeBech32(cls,
|
|
184
|
+
bech_str: str,
|
|
185
|
+
sep: str,
|
|
186
|
+
checksum_len: int) -> Tuple[str, List[int]]:
|
|
187
|
+
"""
|
|
188
|
+
Decode and validate a Bech32 string, determining its HRP and data.
|
|
189
|
+
|
|
190
|
+
Args:
|
|
191
|
+
bech_str (str) : Bech32 string
|
|
192
|
+
sep (str) : Bech32 separator
|
|
193
|
+
checksum_len (int): Checksum length
|
|
194
|
+
|
|
195
|
+
Returns:
|
|
196
|
+
tuple[str, list[int]]: HRP (index 0) and data part (index 1)
|
|
197
|
+
|
|
198
|
+
Raises:
|
|
199
|
+
ValueError: If the string is not valid
|
|
200
|
+
Bech32ChecksumError: If the checksum is not valid
|
|
201
|
+
"""
|
|
202
|
+
|
|
203
|
+
# Check string length and case
|
|
204
|
+
if AlgoUtils.IsStringMixed(bech_str):
|
|
205
|
+
raise ValueError("Invalid bech32 format (string is mixed case)")
|
|
206
|
+
|
|
207
|
+
# Lower string
|
|
208
|
+
bech_str = bech_str.lower()
|
|
209
|
+
|
|
210
|
+
# Find separator and check its position
|
|
211
|
+
sep_pos = bech_str.rfind(sep)
|
|
212
|
+
if sep_pos == -1:
|
|
213
|
+
raise ValueError("Invalid bech32 format (no separator found)")
|
|
214
|
+
|
|
215
|
+
# Get HRP and check it
|
|
216
|
+
hrp = bech_str[:sep_pos]
|
|
217
|
+
if len(hrp) == 0 or any(ord(x) < 33 or ord(x) > 126 for x in hrp):
|
|
218
|
+
raise ValueError(f"Invalid bech32 format (HRP not valid: {hrp})")
|
|
219
|
+
|
|
220
|
+
# Get data and check it
|
|
221
|
+
data_part = bech_str[sep_pos + 1:]
|
|
222
|
+
if (len(data_part) < (checksum_len + 1)
|
|
223
|
+
or not all(x in Bech32BaseConst.CHARSET for x in data_part)):
|
|
224
|
+
raise ValueError("Invalid bech32 format (data part not valid)")
|
|
225
|
+
|
|
226
|
+
# Convert back from alphabet and verify checksum
|
|
227
|
+
int_data = [Bech32BaseConst.CHARSET.find(x) for x in data_part]
|
|
228
|
+
if not cls._VerifyChecksum(hrp, int_data):
|
|
229
|
+
raise Bech32ChecksumError("Invalid bech32 checksum")
|
|
230
|
+
|
|
231
|
+
return hrp, int_data[:-checksum_len]
|
|
232
|
+
|
|
233
|
+
@staticmethod
|
|
234
|
+
@abstractmethod
|
|
235
|
+
def _VerifyChecksum(hrp: str,
|
|
236
|
+
data: List[int]) -> bool:
|
|
237
|
+
"""
|
|
238
|
+
Verify the checksum from the specified HRP and converted data characters.
|
|
239
|
+
|
|
240
|
+
Args:
|
|
241
|
+
hrp (str) : HRP
|
|
242
|
+
data (list[int]): Data part
|
|
243
|
+
|
|
244
|
+
Returns:
|
|
245
|
+
bool: True if valid, false otherwise
|
|
246
|
+
"""
|