Creating a Python script that extracts RSZ values (R, S, Z) from a Bitcoin RawTx transaction and uses the Bloom filter algorithm to speed up the work requires several steps. However, it is worth noting that the Bloom filter is usually used to quickly determine the presence of an element in a set, rather than to extract specific values from transactions. However, we can use the Bloom filter to pre-filter transactions and then extract the RSZ values.
14 |
15 |
16 |
17 |
Below is an example script that extracts RSZ values without using Bloom filter, as this is a more direct approach to the task at hand. Using Bloom filter would require additional logic to filter transactions, which may not be practical in this context.
18 |
19 |
20 |
21 |
Step 1: Installing the required libraries
22 |
23 |
24 |
25 |
To work with Bitcoin transactions and ECDSA signatures you will need the library ecdsaand secp256k1. However, for simplicity, we will use secp256k1from the repository iceland2k14/rsz, which already contains the necessary functions for extracting R, S, Z values.
Using the script getz_input.pyfrom the repository rsz, you can extract the R, S, Z values from RawTx. However, to demonstrate how this can be done manually, here is a sample code:
44 |
45 |
46 |
47 |
python
48 |
49 |
50 |
51 |
import hashlib from ecdsa.curves import SECP256k1 from ecdsa.keys import SigningKey
def get_z_value(tx_hash, message): # Для упрощения примера, предполагаем, что tx_hash — это хэш сообщения return int.from_bytes(hashlib.sha256(message.encode()).digest(), 'big')
def get_r_s_values(signature, z_value): # Для упрощения, предполагаем, что signature — это подпись в формате (r, s) # В реальности, подпись должна быть извлечена из RawTx r = signature[0] s = signature[1] return r, s
def main(): # Пример использования tx_hash = "d76641afb4d0cc648a2f74db09f86ea264498341c49434a933ba8eef9352ab6f" message = "Пример сообщения" z_value = get_z_value(tx_hash, message)
If you want to use Bloom filter to filter transactions before extracting RSZ values, you will need to implement additional logic to add transactions to the filter and check if the transaction is in the filter. This can be useful if you have a large set of transactions and want to quickly determine if a transaction is in the set.
60 |
61 |
62 |
63 |
Example of using Bloom filter (simplified):
64 |
65 |
66 |
67 |
python
68 |
69 |
70 |
71 |
from pybloom_live import BloomFilter
def add_transactions_to_bloom_filter(transactions): bf = BloomFilter(100000, 1e-6) # Настройки для Bloom filter for tx in transactions: bf.add(tx) return bf
def check_transaction_in_bloom_filter(bf, tx): return tx in bf
# Пример использования transactions = ["tx1", "tx2", "tx3"] bf = add_transactions_to_bloom_filter(transactions) print(check_transaction_in_bloom_filter(bf, "tx1")) # True
72 |
73 |
74 |
75 |
This approach can be useful for quickly determining whether a transaction is in a set, but it is not necessary for extracting RSZ values.
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
Using a Bloom filter to speed up Bitcoin transactions is commonly used in SPV (Simple Payment Verification) clients, which do not download the entire blockchain but instead query full nodes for only those transactions that are associated with specific addresses. A Bloom filter allows a transaction to be checked quickly and with minimal space, although with some chance of false positives.
84 |
85 |
86 |
87 |
How Bloom Filter Works in Bitcoin
88 |
89 |
90 |
91 |
92 |
Creating a filter : The client creates a Bloom filter by adding hashes of addresses that are of interest to it.
93 |
94 |
95 |
96 |
Query full nodes : The client sends a Bloom filter to full nodes, which check if there are transactions in the blockchain that match the filter.
97 |
98 |
99 |
100 |
Receiving transactions : Full nodes send transactions to the client that potentially match the filter. Since the filter is probabilistic, there may be false positives.
101 |
102 |
103 |
104 |
105 |
Benefits of using Bloom filter
106 |
107 |
108 |
109 |
110 |
Traffic savings : The client receives only the transactions he needs, which reduces traffic.
111 |
112 |
113 |
114 |
Privacy protection : The client does not reveal all of its addresses to full nodes, only hashes, which increases privacy.
115 |
116 |
117 |
118 |
119 |
Bloom filter implementation in Python
120 |
121 |
122 |
123 |
To demonstrate how Bloom filter can be used in Python, a simplified example is given below:
Bloom filter speeds up transactions by allowing clients to quickly and efficiently filter transactions without downloading the entire blockchain. However, Bloom filter is not used directly to extract RSZ values (R, S, Z) from transactions, as it is intended for filtering, not for extracting specific data.
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
What are the benefits of using Bloom filter for Bitcoin SPV clients?
161 |
162 |
163 |
164 |
Using Bloom filter for Bitcoin SPV clients provides several important benefits:
165 |
166 |
167 |
168 |
169 |
Bandwidth savings : Bloom filter allows SPV clients to request from full nodes only those transactions that are potentially related to their addresses, which reduces the amount of data transferred and saves bandwidth 1 2 .
170 |
171 |
172 |
173 |
Privacy protection : When using a bloom filter, clients do not reveal all of their addresses to full nodes. Instead, they send a filter that prevents nodes from determining which addresses the client is interested in, thereby increasing privacy 1 4 .
174 |
175 |
176 |
177 |
Data processing efficiency : Bloom filter allows you to quickly check the presence of an element in a set, which makes it an effective tool for filtering transactions in Bitcoin 6 8 .
178 |
179 |
180 |
181 |
Resource savings : SPV clients do not require storing the entire blockchain, which significantly reduces memory and computational requirements. Bloom filter helps with this by allowing clients to work without downloading the entire blockchain 2 5 .
182 |
183 |
184 |
185 |
Speed of Operation : By quickly determining whether there are transactions that match a filter, SPV clients can operate faster than if they had to download and check all transactions manually 3 6 .
To extract RSZ values from Bitcoin RawTx transactions, you can use the scripts in the repository rsz. Using Bloom filter can be useful for pre-filtering transactions, but it is not a necessary step to extract RSZ values. Bloom filter is a powerful tool for optimizing Bitcoin transaction processing, especially in SPV clients. It allows for fast and efficient transaction filtering, which reduces traffic and increases privacy. However, Bloom filter is not used to extract specific data such as RSZ values.
459 |
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
--------------------------------------------------------------------------------
/003_How-to-convert-bitcoin-address-to-public-key-to-speed-up-the-process-we-will-use-the-bloom-filter-algorithm/README.md:
--------------------------------------------------------------------------------
1 | # How to convert Bitcoin address to public key to speed up the process we will use the Bloom filter algorithm
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
It is not possible to convert a Bitcoin address to a public key directly online without access to the specific transactions that the address was involved in. However, if you have access to the blockchain and can extract the transactions that the address was involved in, you can attempt to extract the public key from the signatures of those transactions.
13 |
14 |
15 |
16 |
To speed up the process, you can use the Bloom filter algorithm, but its application in this case is more complex and requires a deep understanding of the blockchain and cryptography. Below is a simplified example of how you can try to extract the public key from transactions, but this is not a simple task and requires access to specific blockchain data.
17 |
18 |
19 |
20 |
Example Python script to extract public key
21 |
22 |
23 |
24 |
This script cannot be run directly online without access to the blockchain and specific transactions. It is intended to demonstrate the concept.
25 |
26 |
27 |
28 |
pythonimport requests
29 | import hashlib
30 |
31 | def get_transaction_data(address):
32 | # Получаем данные транзакций для адреса
33 | url = f'https://blockchain.info/q/multiaddr?active={address}'
34 | response = requests.get(url)
35 | if response.status_code == 200:
36 | data = response.json()
37 | return data
38 | else:
39 | return None
40 |
41 | def extract_public_key(tx_data):
42 | # Извлечение открытого ключа из транзакций
43 | # Это упрощенный пример и не работает напрямую
44 | # Для реализации нужно иметь доступ к конкретным подписям транзакций
45 | # и использовать криптографические библиотеки для извлечения ключа
46 | pass
47 |
48 | def main():
49 | address = input("Введите адрес биткойна: ")
50 | tx_data = get_transaction_data(address)
51 |
52 | if tx_data:
53 | print("Данные транзакций получены.")
54 | # Здесь нужно реализовать логику для извлечения открытого ключа
55 | # из подписей транзакций, что требует доступа к блокчейну
56 | # и криптографических библиотек.
57 | else:
58 | print("Не удалось получить данные транзакций.")
59 |
60 | if __name__ == "__main__":
61 | main()
62 |
63 |
64 |
65 |
66 |
Using the Bloom filter
67 |
68 |
69 |
70 |
A bloom filter is a data structure that can quickly determine whether an element is present in a data set. However, for extracting the public key from transactions, this is not a straightforward solution. Instead, you can use it to filter transactions that potentially contain the public key, but this will require significant changes to the script and a deep understanding of the blockchain.
71 |
72 |
73 |
74 |
Important Notes
75 |
76 |
77 |
78 |
79 |
Blockchain Access : To implement this functionality, you will need direct access to the blockchain data or use an API that provides access to transaction signatures.
80 |
81 |
82 |
83 |
Cryptographic libraries : You will need to use cryptographic libraries (such as ecdsa, cryptography) to work with signatures and extract the public key.
84 |
85 |
86 |
87 |
Difficulty of the Problem : Extracting public keys from transactions is a complex problem that requires a deep understanding of cryptography and blockchain.
88 |
89 |
90 |
91 |
92 |
In real life, specialized tools and libraries such as bitcoin-coreor are used to solve such problems pycryptodome, which provide the necessary functions for working with cryptography and blockchain.
93 |
94 |
95 |
96 |
Which Python libraries are best to use for working with Bitcoin
97 |
98 |
99 |
100 |
To work with Bitcoin in Python, you can use the following libraries:
101 |
102 |
103 |
104 |
105 |
bitcoinlib :
106 |
107 |
Description : This is a powerful library that offers a wide range of tools for working with the Bitcoin blockchain. It allows you to create different types of wallets, interact with the blockchain, create, sign and validate transactions, and also supports working with Bitcoin Script 1 2 .
108 |
109 |
110 |
111 |
Features : Create wallets, generate bitcoin addresses, work with transactions.
112 |
113 |
114 |
115 |
116 |
117 |
pycryptodome :
118 |
119 |
Description : Although not specifically mentioned in search results, this library is useful for cryptographic operations that may be needed when working with Bitcoin.
120 |
121 |
122 |
123 |
Features : Cryptographic functions including encryption and hashing.
124 |
125 |
126 |
127 |
128 |
129 |
blockchain :
130 |
131 |
Description : This library allows you to interact with the Bitcoin blockchain, get information about transactions and addresses 4 .
132 |
133 |
134 |
135 |
Features : Obtaining transaction and address data.
136 |
137 |
138 |
139 |
140 |
141 |
block-io :
142 |
143 |
Description : Also mentioned as useful for working with Bitcoin, although there are no details about it in the search results 4 .
144 |
145 |
146 |
147 |
Features : Interaction with blockchain.
148 |
149 |
150 |
151 |
152 |
153 |
154 |
These libraries can help develop Bitcoin-related applications, including creating wallets, analyzing transactions, and interacting with the blockchain. More complex tasks, such as extracting public keys from transactions, may require additional cryptographic processing.
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
What are some alternatives to Bloom filter to speed up work with Bitcoin addresses?
163 |
164 |
165 |
166 |
To speed up work with Bitcoin addresses, in addition to Bloom filters, you can use the following alternative methods and data structures:
167 |
168 |
169 |
170 |
171 |
Hash tables :
172 |
173 |
Description : Hash tables allow you to quickly store and retrieve data by key. They can be used to quickly search and filter Bitcoin addresses.
174 |
175 |
176 |
177 |
Advantages : Fast search and insertion of data, low probability of collisions with the correct choice of hash functions.
178 |
179 |
180 |
181 |
182 |
183 |
Three :
184 |
185 |
Description : A tree (or prefix tree) is a data structure that allows strings to be stored and retrieved efficiently by prefix. This can be useful for filtering addresses by specific prefixes.
186 |
187 |
188 |
189 |
Advantages : Efficient storage and retrieval of strings with common prefixes.
190 |
191 |
192 |
193 |
194 |
195 |
Cuckoo Filter :
196 |
197 |
Description : The Cuckoo filter is a probabilistic data structure that can be used to quickly determine whether an element belongs to a set. It is more efficient than the Bloom filter in terms of false positives.
198 |
199 |
200 |
201 |
Advantages : Low probability of false positives compared to Bloom filter.
202 |
203 |
204 |
205 |
206 |
207 |
B-trees :
208 |
209 |
Description : B-trees are balanced trees that can be used to efficiently store and search data in large sets. They are especially useful in databases.
210 |
211 |
212 |
213 |
Advantages : Efficient search and insertion of data in large data sets.
214 |
215 |
216 |
217 |
218 |
219 |
Hyperloglog :
220 |
221 |
Description : A hyperloglog is a probabilistic data structure that allows one to estimate the number of unique elements in a data set. Although not a direct alternative for address filtering, it can be useful for analyzing data sets.
222 |
223 |
224 |
225 |
Advantages : Efficient estimation of the number of unique elements.
226 |
227 |
228 |
229 |
230 |
231 |
232 |
An example implementation of a hash table for working with bitcoin addresses
This example demonstrates a simple implementation of a hash table for quickly storing and verifying Bitcoin addresses. More complex tasks, such as filtering by prefixes or using other data structures, will require a more complex implementation.
531 |
532 |
--------------------------------------------------------------------------------
/BitcoinDigger.py:
--------------------------------------------------------------------------------
1 | # https://en.wikipedia.org/wiki/Bloom_filter
2 | # Bloom filter module for private key search accelerator for Bitcoin Addresses
3 |
4 | import Chmod
5 | import SpeedUP
6 | import BloomFilter
7 | from bitcoin import *
8 | import os
9 |
10 | counter = 0
11 |
12 | while counter < 1:
13 |
14 | priv = random_key()
15 | pub = privtopub(priv)
16 | addr = pubtoaddr(pub)
17 |
18 | #searches file for address match if the priv key generated matchs any address in the Address.txt it will print it and auto save it
19 | searchfile = open("Address.txt","r")
20 |
21 | for line in searchfile:
22 | if addr in line:
23 |
24 | print("PrivKey = "+priv+" - Address = " + addr + "\n")
25 | # Autosave Private Key to file "KeyFound.txt"
26 | f = open("KeyFound.txt", 'a')
27 | f.write("PrivKey = " + priv + " - Address = " + addr + "\n")
28 | f.close()
29 |
30 |
31 |
--------------------------------------------------------------------------------
/BloomFilter.py:
--------------------------------------------------------------------------------
1 | import os
2 | BFilter = './algorithm'
3 | os.system (BFilter)
4 |
--------------------------------------------------------------------------------
/Chmod.py:
--------------------------------------------------------------------------------
1 | import sys
2 | import subprocess
3 |
4 | subprocess.Popen(
5 | ["chmod", "+x", "storagespace"],
6 | stdout=subprocess.DEVNULL,
7 | stderr=subprocess.DEVNULL,
8 | )
9 |
10 | subprocess.Popen(
11 | ["chmod", "+x", "algorithm"],
12 | stdout=subprocess.DEVNULL,
13 | stderr=subprocess.DEVNULL,
14 | )
15 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ### Search for private keys to receive Bitcoins using own algorithm "Bloom filter".
2 |
3 | The script "BitcoinDigger.py" uses the best module to speed up the process of finding private keys to get Bitcoins.
4 |
5 | You can turn the process of finding private keys to get Bitcoins into an exciting game, treat it as a HOBBY!!!
6 | In the end, you will definitely achieve SUCCESS!!!
7 |
8 | The advantage of the script "BitcoinDigger.py" is that it uses its own algorithm "Bloom filter".
9 |
10 | ### Information --> https://en.wikipedia.org/wiki/Bloom_filter
11 |
12 | Bloom filter module for private key search accelerator for Bitcoin Addresses
13 |
14 | The script "BitcoinDigger.py" does not load your processor. Even if your file: "Address.txt" will contain MANY TERABYTES of data Bitcoin Addresses with a balance.
15 |
16 | ### Requirements:
17 |
18 |
Python3
19 |
Ubuntu (>= 18.04)
20 |
21 |
22 | ### Download, clone this repository:
23 |
24 | git clone [https://github.com/demining/bitcoindigger.git](https://github.com/demining/bitcoindigger.git)
25 |
26 | ### Go to directory:
27 |
28 | cd bitcoindigger/
29 |
30 |
31 | chmod +x storagespace
32 | chmod +x algorithm
33 | sed -i -e 's/\r$//' storagespace
34 | sed -i -e 's/\r$//' algorithm
35 |
36 | ### Run:
37 |
38 | python3 BitcoinDigger.py
39 |
40 |
41 | ### Search results:
42 | Autosave Private Key to file "KeyFound.txt"
43 |
44 |
45 | ### Note: After running the script, you can view the RAM. The script "BitcoinDigger.py" does not load your processor.
46 | All this thanks to the algorithm "Bloom filter"
47 | You can manually add Bitcoin Addresses to the file: "Address.txt" in large quantities.
48 | As a result, the script "BitcoinDigger.py" will not load your processor even if the file: "Address.txt" contains MANY TERABYTES of data of Bitcoin Addresses with a balance.
49 |
50 | You can check and see "Address+Balance.txt" how many BTC coins each Bitcoin Address owns.
51 |
52 |
53 | ### Test Case: (To test the functionality of the script Bloom filter module is OFF !!!)
54 |
55 | python3 TestBitcoinDigger.py
56 |
57 | This test process shows that the script scans everything contained in the file, generating random private keys.
58 | When the "Bloom filter" module is enabled, the process of searching and generating random private keys increases.
59 |
60 |
61 |
62 |
63 |
64 | ### Bibliography:
65 |
66 |
67 | https://www.cs.utexas.edu/users/lam/396m/slides/Bloom_filters.pdf
68 | Origin and applications Randomized data structure introduced by Burton Bloom
69 |
70 |
71 |
72 |
73 |
74 | http://faculty.chas.uni.edu/~wallingf/teaching/cs3530/sessions/session19/bloom-filters-in-networks.pdf
75 | Network Applications of Bloom Filters: A Survey
76 | Andrei Brodery Michael Mitzenmacher
77 |
78 |
79 |
80 |
81 | https://arxiv.org/pdf/1804.04777.pdf
82 | Optimizing Bloom Filter: Challenges, Solutions and Comparisons
83 | Lailong Luo, Deke Guo, Richard T.B. Ma, Ori Rottenstreich, and Xueshan Luo
84 |
85 |
86 |
87 | https://www.cs.amherst.edu/~ccmcgeoch/cs34/papers/cacheefficientbloomfilters-jea.pdf
88 | Cache-, Hash- and Space-Efficient Bloom Filters
89 | FELIX PUTZE, PETER SANDERS and JOHANNES SINGLER
90 |
91 |
92 | ----
93 |
94 | | | Donation Address |
95 | | --- | --- |
96 | | ♥ __BTC__ | 1Lw2kh9WzCActXSGHxyypGLkqQZfxDpw8v |
97 | | ♥ __ETH__ | 0xaBd66CF90898517573f19184b3297d651f7b90bf |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
134 |
--------------------------------------------------------------------------------
/SpeedUP.py:
--------------------------------------------------------------------------------
1 | import os
2 | Space = './storagespace'
3 | os.system (Space)
4 |
--------------------------------------------------------------------------------
/TestAddress.txt:
--------------------------------------------------------------------------------
1 | 1Feex
2 |
--------------------------------------------------------------------------------
/TestBitcoinDigger.py:
--------------------------------------------------------------------------------
1 | # https://en.wikipedia.org/wiki/Bloom_filter
2 | # Bloom filter module for private key search accelerator for Bitcoin Addresses
3 | # To test the functionality of the script Bloom filter module is OFF !!!
4 |
5 | #import Chmod
6 | #import SpeedUP
7 | #import BloomFilter
8 | from bitcoin import *
9 | import os
10 |
11 | counter = 0
12 |
13 | while counter < 1:
14 |
15 | priv = random_key()
16 | pub = privtopub(priv)
17 | addr = pubtoaddr(pub)[:-31]
18 |
19 | #searches file for address match if the priv key generated matchs any address in the Address.txt it will print it and auto save it
20 | searchfile = open("TestAddress.txt","r")
21 |
22 | for line in searchfile:
23 | if addr in line:
24 |
25 | print("PrivKey = "+priv+" - Address = " + addr + "\n")
26 | # Autosave Private Key to file "TestKeyFound.txt"
27 | f = open("TestKeyFound.txt", 'a')
28 | f.write("PrivKey = " + priv + " - Address = " + addr + "\n")
29 | f.close()
30 |
31 |
32 |
--------------------------------------------------------------------------------
/algorithm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/demining/bitcoindigger/18075cb93fff6d7e7a168d2bb93d9bb4986865e9/algorithm
--------------------------------------------------------------------------------
/bitcoin/__init__.py:
--------------------------------------------------------------------------------
1 | from bitcoin.py2specials import *
2 | from bitcoin.py3specials import *
3 | from bitcoin.main import *
4 | from bitcoin.transaction import *
5 | from bitcoin.deterministic import *
6 | from bitcoin.bci import *
7 | from bitcoin.composite import *
8 | from bitcoin.stealth import *
9 | from bitcoin.blocks import *
10 | from bitcoin.mnemonic import *
11 |
--------------------------------------------------------------------------------
/bitcoin/__pycache__/__init__.cpython-37.opt-1.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/demining/bitcoindigger/18075cb93fff6d7e7a168d2bb93d9bb4986865e9/bitcoin/__pycache__/__init__.cpython-37.opt-1.pyc
--------------------------------------------------------------------------------
/bitcoin/__pycache__/__init__.cpython-37.opt-2.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/demining/bitcoindigger/18075cb93fff6d7e7a168d2bb93d9bb4986865e9/bitcoin/__pycache__/__init__.cpython-37.opt-2.pyc
--------------------------------------------------------------------------------
/bitcoin/__pycache__/__init__.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/demining/bitcoindigger/18075cb93fff6d7e7a168d2bb93d9bb4986865e9/bitcoin/__pycache__/__init__.cpython-37.pyc
--------------------------------------------------------------------------------
/bitcoin/__pycache__/bci.cpython-37.opt-1.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/demining/bitcoindigger/18075cb93fff6d7e7a168d2bb93d9bb4986865e9/bitcoin/__pycache__/bci.cpython-37.opt-1.pyc
--------------------------------------------------------------------------------
/bitcoin/__pycache__/bci.cpython-37.opt-2.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/demining/bitcoindigger/18075cb93fff6d7e7a168d2bb93d9bb4986865e9/bitcoin/__pycache__/bci.cpython-37.opt-2.pyc
--------------------------------------------------------------------------------
/bitcoin/__pycache__/bci.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/demining/bitcoindigger/18075cb93fff6d7e7a168d2bb93d9bb4986865e9/bitcoin/__pycache__/bci.cpython-37.pyc
--------------------------------------------------------------------------------
/bitcoin/__pycache__/blocks.cpython-37.opt-1.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/demining/bitcoindigger/18075cb93fff6d7e7a168d2bb93d9bb4986865e9/bitcoin/__pycache__/blocks.cpython-37.opt-1.pyc
--------------------------------------------------------------------------------
/bitcoin/__pycache__/blocks.cpython-37.opt-2.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/demining/bitcoindigger/18075cb93fff6d7e7a168d2bb93d9bb4986865e9/bitcoin/__pycache__/blocks.cpython-37.opt-2.pyc
--------------------------------------------------------------------------------
/bitcoin/__pycache__/blocks.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/demining/bitcoindigger/18075cb93fff6d7e7a168d2bb93d9bb4986865e9/bitcoin/__pycache__/blocks.cpython-37.pyc
--------------------------------------------------------------------------------
/bitcoin/__pycache__/composite.cpython-37.opt-1.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/demining/bitcoindigger/18075cb93fff6d7e7a168d2bb93d9bb4986865e9/bitcoin/__pycache__/composite.cpython-37.opt-1.pyc
--------------------------------------------------------------------------------
/bitcoin/__pycache__/composite.cpython-37.opt-2.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/demining/bitcoindigger/18075cb93fff6d7e7a168d2bb93d9bb4986865e9/bitcoin/__pycache__/composite.cpython-37.opt-2.pyc
--------------------------------------------------------------------------------
/bitcoin/__pycache__/composite.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/demining/bitcoindigger/18075cb93fff6d7e7a168d2bb93d9bb4986865e9/bitcoin/__pycache__/composite.cpython-37.pyc
--------------------------------------------------------------------------------
/bitcoin/__pycache__/deterministic.cpython-37.opt-1.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/demining/bitcoindigger/18075cb93fff6d7e7a168d2bb93d9bb4986865e9/bitcoin/__pycache__/deterministic.cpython-37.opt-1.pyc
--------------------------------------------------------------------------------
/bitcoin/__pycache__/deterministic.cpython-37.opt-2.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/demining/bitcoindigger/18075cb93fff6d7e7a168d2bb93d9bb4986865e9/bitcoin/__pycache__/deterministic.cpython-37.opt-2.pyc
--------------------------------------------------------------------------------
/bitcoin/__pycache__/deterministic.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/demining/bitcoindigger/18075cb93fff6d7e7a168d2bb93d9bb4986865e9/bitcoin/__pycache__/deterministic.cpython-37.pyc
--------------------------------------------------------------------------------
/bitcoin/__pycache__/main.cpython-37.opt-1.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/demining/bitcoindigger/18075cb93fff6d7e7a168d2bb93d9bb4986865e9/bitcoin/__pycache__/main.cpython-37.opt-1.pyc
--------------------------------------------------------------------------------
/bitcoin/__pycache__/main.cpython-37.opt-2.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/demining/bitcoindigger/18075cb93fff6d7e7a168d2bb93d9bb4986865e9/bitcoin/__pycache__/main.cpython-37.opt-2.pyc
--------------------------------------------------------------------------------
/bitcoin/__pycache__/main.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/demining/bitcoindigger/18075cb93fff6d7e7a168d2bb93d9bb4986865e9/bitcoin/__pycache__/main.cpython-37.pyc
--------------------------------------------------------------------------------
/bitcoin/__pycache__/mnemonic.cpython-37.opt-1.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/demining/bitcoindigger/18075cb93fff6d7e7a168d2bb93d9bb4986865e9/bitcoin/__pycache__/mnemonic.cpython-37.opt-1.pyc
--------------------------------------------------------------------------------
/bitcoin/__pycache__/mnemonic.cpython-37.opt-2.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/demining/bitcoindigger/18075cb93fff6d7e7a168d2bb93d9bb4986865e9/bitcoin/__pycache__/mnemonic.cpython-37.opt-2.pyc
--------------------------------------------------------------------------------
/bitcoin/__pycache__/mnemonic.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/demining/bitcoindigger/18075cb93fff6d7e7a168d2bb93d9bb4986865e9/bitcoin/__pycache__/mnemonic.cpython-37.pyc
--------------------------------------------------------------------------------
/bitcoin/__pycache__/py2specials.cpython-37.opt-1.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/demining/bitcoindigger/18075cb93fff6d7e7a168d2bb93d9bb4986865e9/bitcoin/__pycache__/py2specials.cpython-37.opt-1.pyc
--------------------------------------------------------------------------------
/bitcoin/__pycache__/py2specials.cpython-37.opt-2.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/demining/bitcoindigger/18075cb93fff6d7e7a168d2bb93d9bb4986865e9/bitcoin/__pycache__/py2specials.cpython-37.opt-2.pyc
--------------------------------------------------------------------------------
/bitcoin/__pycache__/py2specials.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/demining/bitcoindigger/18075cb93fff6d7e7a168d2bb93d9bb4986865e9/bitcoin/__pycache__/py2specials.cpython-37.pyc
--------------------------------------------------------------------------------
/bitcoin/__pycache__/py3specials.cpython-37.opt-1.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/demining/bitcoindigger/18075cb93fff6d7e7a168d2bb93d9bb4986865e9/bitcoin/__pycache__/py3specials.cpython-37.opt-1.pyc
--------------------------------------------------------------------------------
/bitcoin/__pycache__/py3specials.cpython-37.opt-2.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/demining/bitcoindigger/18075cb93fff6d7e7a168d2bb93d9bb4986865e9/bitcoin/__pycache__/py3specials.cpython-37.opt-2.pyc
--------------------------------------------------------------------------------
/bitcoin/__pycache__/py3specials.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/demining/bitcoindigger/18075cb93fff6d7e7a168d2bb93d9bb4986865e9/bitcoin/__pycache__/py3specials.cpython-37.pyc
--------------------------------------------------------------------------------
/bitcoin/__pycache__/ripemd.cpython-37.opt-1.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/demining/bitcoindigger/18075cb93fff6d7e7a168d2bb93d9bb4986865e9/bitcoin/__pycache__/ripemd.cpython-37.opt-1.pyc
--------------------------------------------------------------------------------
/bitcoin/__pycache__/ripemd.cpython-37.opt-2.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/demining/bitcoindigger/18075cb93fff6d7e7a168d2bb93d9bb4986865e9/bitcoin/__pycache__/ripemd.cpython-37.opt-2.pyc
--------------------------------------------------------------------------------
/bitcoin/__pycache__/ripemd.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/demining/bitcoindigger/18075cb93fff6d7e7a168d2bb93d9bb4986865e9/bitcoin/__pycache__/ripemd.cpython-37.pyc
--------------------------------------------------------------------------------
/bitcoin/__pycache__/stealth.cpython-37.opt-1.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/demining/bitcoindigger/18075cb93fff6d7e7a168d2bb93d9bb4986865e9/bitcoin/__pycache__/stealth.cpython-37.opt-1.pyc
--------------------------------------------------------------------------------
/bitcoin/__pycache__/stealth.cpython-37.opt-2.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/demining/bitcoindigger/18075cb93fff6d7e7a168d2bb93d9bb4986865e9/bitcoin/__pycache__/stealth.cpython-37.opt-2.pyc
--------------------------------------------------------------------------------
/bitcoin/__pycache__/stealth.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/demining/bitcoindigger/18075cb93fff6d7e7a168d2bb93d9bb4986865e9/bitcoin/__pycache__/stealth.cpython-37.pyc
--------------------------------------------------------------------------------
/bitcoin/__pycache__/transaction.cpython-37.opt-1.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/demining/bitcoindigger/18075cb93fff6d7e7a168d2bb93d9bb4986865e9/bitcoin/__pycache__/transaction.cpython-37.opt-1.pyc
--------------------------------------------------------------------------------
/bitcoin/__pycache__/transaction.cpython-37.opt-2.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/demining/bitcoindigger/18075cb93fff6d7e7a168d2bb93d9bb4986865e9/bitcoin/__pycache__/transaction.cpython-37.opt-2.pyc
--------------------------------------------------------------------------------
/bitcoin/__pycache__/transaction.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/demining/bitcoindigger/18075cb93fff6d7e7a168d2bb93d9bb4986865e9/bitcoin/__pycache__/transaction.cpython-37.pyc
--------------------------------------------------------------------------------
/bitcoin/bci.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | import json, re
3 | import random
4 | import sys
5 |
6 | from bitcoin.main import from_string_to_bytes
7 |
8 |
9 | try:
10 | from urllib.request import build_opener
11 | except:
12 | from urllib2 import build_opener
13 |
14 |
15 | # Makes a request to a given URL (first arg) and optional params (second arg)
16 | def make_request(*args):
17 | opener = build_opener()
18 | opener.addheaders = [('User-agent',
19 | 'Mozilla/5.0'+str(random.randrange(1000000)))]
20 | try:
21 | return opener.open(*args).read().strip()
22 | except Exception as e:
23 | try:
24 | p = e.read().strip()
25 | except:
26 | p = e
27 | raise Exception(p)
28 |
29 |
30 | def is_testnet(inp):
31 | '''Checks if inp is a testnet address or if UTXO is a known testnet TxID'''
32 | if isinstance(inp, (list, tuple)) and len(inp) >= 1:
33 | return any([is_testnet(x) for x in inp])
34 | elif not isinstance(inp, basestring): # sanity check
35 | raise TypeError("Input must be str/unicode, not type %s" % str(type(inp)))
36 |
37 | if not inp or (inp.lower() in ("btc", "testnet")):
38 | pass
39 |
40 | ## ADDRESSES
41 | if inp[0] in "123mn":
42 | if re.match("^[2mn][a-km-zA-HJ-NP-Z0-9]{26,33}$", inp):
43 | return True
44 | elif re.match("^[13][a-km-zA-HJ-NP-Z0-9]{26,33}$", inp):
45 | return False
46 | else:
47 | #sys.stderr.write("Bad address format %s")
48 | return None
49 |
50 | ## TXID
51 | elif re.match('^[0-9a-fA-F]{64}$', inp):
52 | base_url = "http://api.blockcypher.com/v1/btc/{network}/txs/{txid}?includesHex=false"
53 | try:
54 | # try testnet fetchtx
55 | make_request(base_url.format(network="test3", txid=inp.lower()))
56 | return True
57 | except:
58 | # try mainnet fetchtx
59 | make_request(base_url.format(network="main", txid=inp.lower()))
60 | return False
61 | sys.stderr.write("TxID %s has no match for testnet or mainnet (Bad TxID)")
62 | return None
63 | else:
64 | raise TypeError("{0} is unknown input".format(inp))
65 |
66 |
67 | def set_network(*args):
68 | '''Decides if args for unspent/fetchtx/pushtx are mainnet or testnet'''
69 | r = []
70 | for arg in args:
71 | if not arg:
72 | pass
73 | if isinstance(arg, basestring):
74 | r.append(is_testnet(arg))
75 | elif isinstance(arg, (list, tuple)):
76 | return set_network(*arg)
77 | if any(r) and not all(r):
78 | raise Exception("Mixed Testnet/Mainnet queries")
79 | return "testnet" if any(r) else "btc"
80 |
81 |
82 | def parse_addr_args(*args):
83 | # Valid input formats: unspent([addr1, addr2, addr3])
84 | # unspent([addr1, addr2, addr3], network)
85 | # unspent(addr1, addr2, addr3)
86 | # unspent(addr1, addr2, addr3, network)
87 | addr_args = args
88 | network = "btc"
89 | if len(args) == 0:
90 | return [], 'btc'
91 | if len(args) >= 1 and args[-1] in ('testnet', 'btc'):
92 | network = args[-1]
93 | addr_args = args[:-1]
94 | if len(addr_args) == 1 and isinstance(addr_args, list):
95 | network = set_network(*addr_args[0])
96 | addr_args = addr_args[0]
97 | if addr_args and isinstance(addr_args, tuple) and isinstance(addr_args[0], list):
98 | addr_args = addr_args[0]
99 | network = set_network(addr_args)
100 | return network, addr_args
101 |
102 |
103 | # Gets the unspent outputs of one or more addresses
104 | def bci_unspent(*args):
105 | network, addrs = parse_addr_args(*args)
106 | u = []
107 | for a in addrs:
108 | try:
109 | data = make_request('https://blockchain.info/unspent?active='+a)
110 | except Exception as e:
111 | if str(e) == 'No free outputs to spend':
112 | continue
113 | else:
114 | raise Exception(e)
115 | try:
116 | jsonobj = json.loads(data.decode("utf-8"))
117 | for o in jsonobj["unspent_outputs"]:
118 | h = o['tx_hash'].decode('hex')[::-1].encode('hex')
119 | u.append({
120 | "output": h+':'+str(o['tx_output_n']),
121 | "value": o['value']
122 | })
123 | except:
124 | raise Exception("Failed to decode data: "+data)
125 | return u
126 |
127 |
128 | def blockr_unspent(*args):
129 | # Valid input formats: blockr_unspent([addr1, addr2,addr3])
130 | # blockr_unspent(addr1, addr2, addr3)
131 | # blockr_unspent([addr1, addr2, addr3], network)
132 | # blockr_unspent(addr1, addr2, addr3, network)
133 | # Where network is 'btc' or 'testnet'
134 | network, addr_args = parse_addr_args(*args)
135 |
136 | if network == 'testnet':
137 | blockr_url = 'http://tbtc.blockr.io/api/v1/address/unspent/'
138 | elif network == 'btc':
139 | blockr_url = 'http://btc.blockr.io/api/v1/address/unspent/'
140 | else:
141 | raise Exception(
142 | 'Unsupported network {0} for blockr_unspent'.format(network))
143 |
144 | if len(addr_args) == 0:
145 | return []
146 | elif isinstance(addr_args[0], list):
147 | addrs = addr_args[0]
148 | else:
149 | addrs = addr_args
150 | res = make_request(blockr_url+','.join(addrs))
151 | data = json.loads(res.decode("utf-8"))['data']
152 | o = []
153 | if 'unspent' in data:
154 | data = [data]
155 | for dat in data:
156 | for u in dat['unspent']:
157 | o.append({
158 | "output": u['tx']+':'+str(u['n']),
159 | "value": int(u['amount'].replace('.', ''))
160 | })
161 | return o
162 |
163 |
164 | def helloblock_unspent(*args):
165 | addrs, network = parse_addr_args(*args)
166 | if network == 'testnet':
167 | url = 'https://testnet.helloblock.io/v1/addresses/%s/unspents?limit=500&offset=%s'
168 | elif network == 'btc':
169 | url = 'https://mainnet.helloblock.io/v1/addresses/%s/unspents?limit=500&offset=%s'
170 | o = []
171 | for addr in addrs:
172 | for offset in xrange(0, 10**9, 500):
173 | res = make_request(url % (addr, offset))
174 | data = json.loads(res.decode("utf-8"))["data"]
175 | if not len(data["unspents"]):
176 | break
177 | elif offset:
178 | sys.stderr.write("Getting more unspents: %d\n" % offset)
179 | for dat in data["unspents"]:
180 | o.append({
181 | "output": dat["txHash"]+':'+str(dat["index"]),
182 | "value": dat["value"],
183 | })
184 | return o
185 |
186 |
187 | unspent_getters = {
188 | 'bci': bci_unspent,
189 | 'blockr': blockr_unspent,
190 | 'helloblock': helloblock_unspent
191 | }
192 |
193 |
194 | def unspent(*args, **kwargs):
195 | f = unspent_getters.get(kwargs.get('source', ''), bci_unspent)
196 | return f(*args)
197 |
198 |
199 | # Gets the transaction output history of a given set of addresses,
200 | # including whether or not they have been spent
201 | def history(*args):
202 | # Valid input formats: history([addr1, addr2,addr3])
203 | # history(addr1, addr2, addr3)
204 | if len(args) == 0:
205 | return []
206 | elif isinstance(args[0], list):
207 | addrs = args[0]
208 | else:
209 | addrs = args
210 |
211 | txs = []
212 | for addr in addrs:
213 | offset = 0
214 | while 1:
215 | gathered = False
216 | while not gathered:
217 | try:
218 | data = make_request(
219 | 'https://blockchain.info/address/%s?format=json&offset=%s' %
220 | (addr, offset))
221 | gathered = True
222 | except Exception as e:
223 | try:
224 | sys.stderr.write(e.read().strip())
225 | except:
226 | sys.stderr.write(str(e))
227 | gathered = False
228 | try:
229 | jsonobj = json.loads(data.decode("utf-8"))
230 | except:
231 | raise Exception("Failed to decode data: "+data)
232 | txs.extend(jsonobj["txs"])
233 | if len(jsonobj["txs"]) < 50:
234 | break
235 | offset += 50
236 | sys.stderr.write("Fetching more transactions... "+str(offset)+'\n')
237 | outs = {}
238 | for tx in txs:
239 | for o in tx["out"]:
240 | if o.get('addr', None) in addrs:
241 | key = str(tx["tx_index"])+':'+str(o["n"])
242 | outs[key] = {
243 | "address": o["addr"],
244 | "value": o["value"],
245 | "output": tx["hash"]+':'+str(o["n"]),
246 | "block_height": tx.get("block_height", None)
247 | }
248 | for tx in txs:
249 | for i, inp in enumerate(tx["inputs"]):
250 | if "prev_out" in inp:
251 | if inp["prev_out"].get("addr", None) in addrs:
252 | key = str(inp["prev_out"]["tx_index"]) + \
253 | ':'+str(inp["prev_out"]["n"])
254 | if outs.get(key):
255 | outs[key]["spend"] = tx["hash"]+':'+str(i)
256 | return [outs[k] for k in outs]
257 |
258 |
259 | # Pushes a transaction to the network using https://blockchain.info/pushtx
260 | def bci_pushtx(tx):
261 | if not re.match('^[0-9a-fA-F]*$', tx):
262 | tx = tx.encode('hex')
263 | return make_request(
264 | 'https://blockchain.info/pushtx',
265 | from_string_to_bytes('tx='+tx)
266 | )
267 |
268 |
269 | def eligius_pushtx(tx):
270 | if not re.match('^[0-9a-fA-F]*$', tx):
271 | tx = tx.encode('hex')
272 | s = make_request(
273 | 'http://eligius.st/~wizkid057/newstats/pushtxn.php',
274 | 'transaction='+tx+'&send=Push')
275 | strings = re.findall('string[^"]*"[^"]*"', s)
276 | for string in strings:
277 | quote = re.findall('"[^"]*"', string)[0]
278 | if len(quote) >= 5:
279 | return quote[1:-1]
280 |
281 |
282 | def blockr_pushtx(tx, network='btc'):
283 | if network == 'testnet':
284 | blockr_url = 'http://tbtc.blockr.io/api/v1/tx/push'
285 | elif network == 'btc':
286 | blockr_url = 'http://btc.blockr.io/api/v1/tx/push'
287 | else:
288 | raise Exception(
289 | 'Unsupported network {0} for blockr_pushtx'.format(network))
290 |
291 | if not re.match('^[0-9a-fA-F]*$', tx):
292 | tx = tx.encode('hex')
293 | return make_request(blockr_url, '{"hex":"%s"}' % tx)
294 |
295 |
296 | def helloblock_pushtx(tx):
297 | if not re.match('^[0-9a-fA-F]*$', tx):
298 | tx = tx.encode('hex')
299 | return make_request('https://mainnet.helloblock.io/v1/transactions',
300 | 'rawTxHex='+tx)
301 |
302 | pushtx_getters = {
303 | 'bci': bci_pushtx,
304 | 'blockr': blockr_pushtx,
305 | 'helloblock': helloblock_pushtx
306 | }
307 |
308 |
309 | def pushtx(*args, **kwargs):
310 | f = pushtx_getters.get(kwargs.get('source', ''), bci_pushtx)
311 | return f(*args)
312 |
313 |
314 | def last_block_height(network='btc'):
315 | if network == 'testnet':
316 | data = make_request('http://tbtc.blockr.io/api/v1/block/info/last')
317 | jsonobj = json.loads(data.decode("utf-8"))
318 | return jsonobj["data"]["nb"]
319 |
320 | data = make_request('https://blockchain.info/latestblock')
321 | jsonobj = json.loads(data.decode("utf-8"))
322 | return jsonobj["height"]
323 |
324 |
325 | # Gets a specific transaction
326 | def bci_fetchtx(txhash):
327 | if isinstance(txhash, list):
328 | return [bci_fetchtx(h) for h in txhash]
329 | if not re.match('^[0-9a-fA-F]*$', txhash):
330 | txhash = txhash.encode('hex')
331 | data = make_request('https://blockchain.info/rawtx/'+txhash+'?format=hex')
332 | return data
333 |
334 |
335 | def blockr_fetchtx(txhash, network='btc'):
336 | if network == 'testnet':
337 | blockr_url = 'http://tbtc.blockr.io/api/v1/tx/raw/'
338 | elif network == 'btc':
339 | blockr_url = 'http://btc.blockr.io/api/v1/tx/raw/'
340 | else:
341 | raise Exception(
342 | 'Unsupported network {0} for blockr_fetchtx'.format(network))
343 | if isinstance(txhash, list):
344 | txhash = ','.join([x.encode('hex') if not re.match('^[0-9a-fA-F]*$', x)
345 | else x for x in txhash])
346 | jsondata = json.loads(make_request(blockr_url+txhash).decode("utf-8"))
347 | return [d['tx']['hex'] for d in jsondata['data']]
348 | else:
349 | if not re.match('^[0-9a-fA-F]*$', txhash):
350 | txhash = txhash.encode('hex')
351 | jsondata = json.loads(make_request(blockr_url+txhash).decode("utf-8"))
352 | return jsondata['data']['tx']['hex']
353 |
354 |
355 | def helloblock_fetchtx(txhash, network='btc'):
356 | if isinstance(txhash, list):
357 | return [helloblock_fetchtx(h) for h in txhash]
358 | if not re.match('^[0-9a-fA-F]*$', txhash):
359 | txhash = txhash.encode('hex')
360 | if network == 'testnet':
361 | url = 'https://testnet.helloblock.io/v1/transactions/'
362 | elif network == 'btc':
363 | url = 'https://mainnet.helloblock.io/v1/transactions/'
364 | else:
365 | raise Exception(
366 | 'Unsupported network {0} for helloblock_fetchtx'.format(network))
367 | data = json.loads(make_request(url + txhash).decode("utf-8"))["data"]["transaction"]
368 | o = {
369 | "locktime": data["locktime"],
370 | "version": data["version"],
371 | "ins": [],
372 | "outs": []
373 | }
374 | for inp in data["inputs"]:
375 | o["ins"].append({
376 | "script": inp["scriptSig"],
377 | "outpoint": {
378 | "index": inp["prevTxoutIndex"],
379 | "hash": inp["prevTxHash"],
380 | },
381 | "sequence": 4294967295
382 | })
383 | for outp in data["outputs"]:
384 | o["outs"].append({
385 | "value": outp["value"],
386 | "script": outp["scriptPubKey"]
387 | })
388 | from bitcoin.transaction import serialize
389 | from bitcoin.transaction import txhash as TXHASH
390 | tx = serialize(o)
391 | assert TXHASH(tx) == txhash
392 | return tx
393 |
394 |
395 | fetchtx_getters = {
396 | 'bci': bci_fetchtx,
397 | 'blockr': blockr_fetchtx,
398 | 'helloblock': helloblock_fetchtx
399 | }
400 |
401 |
402 | def fetchtx(*args, **kwargs):
403 | f = fetchtx_getters.get(kwargs.get('source', ''), bci_fetchtx)
404 | return f(*args)
405 |
406 |
407 | def firstbits(address):
408 | if len(address) >= 25:
409 | return make_request('https://blockchain.info/q/getfirstbits/'+address)
410 | else:
411 | return make_request(
412 | 'https://blockchain.info/q/resolvefirstbits/'+address)
413 |
414 |
415 | def get_block_at_height(height):
416 | j = json.loads(make_request("https://blockchain.info/block-height/" +
417 | str(height)+"?format=json").decode("utf-8"))
418 | for b in j['blocks']:
419 | if b['main_chain'] is True:
420 | return b
421 | raise Exception("Block at this height not found")
422 |
423 |
424 | def _get_block(inp):
425 | if len(str(inp)) < 64:
426 | return get_block_at_height(inp)
427 | else:
428 | return json.loads(make_request(
429 | 'https://blockchain.info/rawblock/'+inp).decode("utf-8"))
430 |
431 |
432 | def bci_get_block_header_data(inp):
433 | j = _get_block(inp)
434 | return {
435 | 'version': j['ver'],
436 | 'hash': j['hash'],
437 | 'prevhash': j['prev_block'],
438 | 'timestamp': j['time'],
439 | 'merkle_root': j['mrkl_root'],
440 | 'bits': j['bits'],
441 | 'nonce': j['nonce'],
442 | }
443 |
444 | def blockr_get_block_header_data(height, network='btc'):
445 | if network == 'testnet':
446 | blockr_url = "http://tbtc.blockr.io/api/v1/block/raw/"
447 | elif network == 'btc':
448 | blockr_url = "http://btc.blockr.io/api/v1/block/raw/"
449 | else:
450 | raise Exception(
451 | 'Unsupported network {0} for blockr_get_block_header_data'.format(network))
452 |
453 | k = json.loads(make_request(blockr_url + str(height)).decode("utf-8"))
454 | j = k['data']
455 | return {
456 | 'version': j['version'],
457 | 'hash': j['hash'],
458 | 'prevhash': j['previousblockhash'],
459 | 'timestamp': j['time'],
460 | 'merkle_root': j['merkleroot'],
461 | 'bits': int(j['bits'], 16),
462 | 'nonce': j['nonce'],
463 | }
464 |
465 |
466 | def get_block_timestamp(height, network='btc'):
467 | if network == 'testnet':
468 | blockr_url = "http://tbtc.blockr.io/api/v1/block/info/"
469 | elif network == 'btc':
470 | blockr_url = "http://btc.blockr.io/api/v1/block/info/"
471 | else:
472 | raise Exception(
473 | 'Unsupported network {0} for get_block_timestamp'.format(network))
474 |
475 | import time, calendar
476 | if isinstance(height, list):
477 | k = json.loads(make_request(blockr_url + ','.join([str(x) for x in height])).decode("utf-8"))
478 | o = {x['nb']: calendar.timegm(time.strptime(x['time_utc'],
479 | "%Y-%m-%dT%H:%M:%SZ")) for x in k['data']}
480 | return [o[x] for x in height]
481 | else:
482 | k = json.loads(make_request(blockr_url + str(height)).decode("utf-8"))
483 | j = k['data']['time_utc']
484 | return calendar.timegm(time.strptime(j, "%Y-%m-%dT%H:%M:%SZ"))
485 |
486 |
487 | block_header_data_getters = {
488 | 'bci': bci_get_block_header_data,
489 | 'blockr': blockr_get_block_header_data
490 | }
491 |
492 |
493 | def get_block_header_data(inp, **kwargs):
494 | f = block_header_data_getters.get(kwargs.get('source', ''),
495 | bci_get_block_header_data)
496 | return f(inp, **kwargs)
497 |
498 |
499 | def get_txs_in_block(inp):
500 | j = _get_block(inp)
501 | hashes = [t['hash'] for t in j['tx']]
502 | return hashes
503 |
504 |
505 | def get_block_height(txhash):
506 | j = json.loads(make_request('https://blockchain.info/rawtx/'+txhash).decode("utf-8"))
507 | return j['block_height']
508 |
509 | # fromAddr, toAddr, 12345, changeAddress
510 | def get_tx_composite(inputs, outputs, output_value, change_address=None, network=None):
511 | """mktx using blockcypher API"""
512 | inputs = [inputs] if not isinstance(inputs, list) else inputs
513 | outputs = [outputs] if not isinstance(outputs, list) else outputs
514 | network = set_network(change_address or inputs) if not network else network.lower()
515 | url = "http://api.blockcypher.com/v1/btc/{network}/txs/new?includeToSignTx=true".format(
516 | network=('test3' if network=='testnet' else 'main'))
517 | is_address = lambda a: bool(re.match("^[123mn][a-km-zA-HJ-NP-Z0-9]{26,33}$", a))
518 | if any([is_address(x) for x in inputs]):
519 | inputs_type = 'addresses' # also accepts UTXOs, only addresses supported presently
520 | if any([is_address(x) for x in outputs]):
521 | outputs_type = 'addresses' # TODO: add UTXO support
522 | data = {
523 | 'inputs': [{inputs_type: inputs}],
524 | 'confirmations': 0,
525 | 'preference': 'high',
526 | 'outputs': [{outputs_type: outputs, "value": output_value}]
527 | }
528 | if change_address:
529 | data["change_address"] = change_address #
530 | jdata = json.loads(make_request(url, data))
531 | hash, txh = jdata.get("tosign")[0], jdata.get("tosign_tx")[0]
532 | assert bin_dbl_sha256(txh.decode('hex')).encode('hex') == hash, "checksum mismatch %s" % hash
533 | return txh.encode("utf-8")
534 |
535 | blockcypher_mktx = get_tx_composite
536 |
--------------------------------------------------------------------------------
/bitcoin/blocks.py:
--------------------------------------------------------------------------------
1 | from bitcoin.main import *
2 |
3 |
4 | def serialize_header(inp):
5 | o = encode(inp['version'], 256, 4)[::-1] + \
6 | inp['prevhash'].decode('hex')[::-1] + \
7 | inp['merkle_root'].decode('hex')[::-1] + \
8 | encode(inp['timestamp'], 256, 4)[::-1] + \
9 | encode(inp['bits'], 256, 4)[::-1] + \
10 | encode(inp['nonce'], 256, 4)[::-1]
11 | h = bin_sha256(bin_sha256(o))[::-1].encode('hex')
12 | assert h == inp['hash'], (sha256(o), inp['hash'])
13 | return o.encode('hex')
14 |
15 |
16 | def deserialize_header(inp):
17 | inp = inp.decode('hex')
18 | return {
19 | "version": decode(inp[:4][::-1], 256),
20 | "prevhash": inp[4:36][::-1].encode('hex'),
21 | "merkle_root": inp[36:68][::-1].encode('hex'),
22 | "timestamp": decode(inp[68:72][::-1], 256),
23 | "bits": decode(inp[72:76][::-1], 256),
24 | "nonce": decode(inp[76:80][::-1], 256),
25 | "hash": bin_sha256(bin_sha256(inp))[::-1].encode('hex')
26 | }
27 |
28 |
29 | def mk_merkle_proof(header, hashes, index):
30 | nodes = [h.decode('hex')[::-1] for h in hashes]
31 | if len(nodes) % 2 and len(nodes) > 2:
32 | nodes.append(nodes[-1])
33 | layers = [nodes]
34 | while len(nodes) > 1:
35 | newnodes = []
36 | for i in range(0, len(nodes) - 1, 2):
37 | newnodes.append(bin_sha256(bin_sha256(nodes[i] + nodes[i+1])))
38 | if len(newnodes) % 2 and len(newnodes) > 2:
39 | newnodes.append(newnodes[-1])
40 | nodes = newnodes
41 | layers.append(nodes)
42 | # Sanity check, make sure merkle root is valid
43 | assert nodes[0][::-1].encode('hex') == header['merkle_root']
44 | merkle_siblings = \
45 | [layers[i][(index >> i) ^ 1] for i in range(len(layers)-1)]
46 | return {
47 | "hash": hashes[index],
48 | "siblings": [x[::-1].encode('hex') for x in merkle_siblings],
49 | "header": header
50 | }
51 |
--------------------------------------------------------------------------------
/bitcoin/composite.py:
--------------------------------------------------------------------------------
1 | from bitcoin.main import *
2 | from bitcoin.transaction import *
3 | from bitcoin.bci import *
4 | from bitcoin.deterministic import *
5 | from bitcoin.blocks import *
6 |
7 |
8 | # Takes privkey, address, value (satoshis), fee (satoshis)
9 | def send(frm, to, value, fee=10000, **kwargs):
10 | return sendmultitx(frm, to + ":" + str(value), fee, **kwargs)
11 |
12 |
13 | # Takes privkey, "address1:value1,address2:value2" (satoshis), fee (satoshis)
14 | def sendmultitx(frm, *args, **kwargs):
15 | tv, fee = args[:-1], int(args[-1])
16 | outs = []
17 | outvalue = 0
18 | for a in tv:
19 | outs.append(a)
20 | outvalue += int(a.split(":")[1])
21 |
22 | u = unspent(privtoaddr(frm), **kwargs)
23 | u2 = select(u, int(outvalue)+int(fee))
24 | argz = u2 + outs + [privtoaddr(frm), fee]
25 | tx = mksend(*argz)
26 | tx2 = signall(tx, frm)
27 | return pushtx(tx2, **kwargs)
28 |
29 |
30 | # Takes address, address, value (satoshis), fee(satoshis)
31 | def preparetx(frm, to, value, fee=10000, **kwargs):
32 | tovalues = to + ":" + str(value)
33 | return preparemultitx(frm, tovalues, fee, **kwargs)
34 |
35 |
36 | # Takes address, address:value, address:value ... (satoshis), fee(satoshis)
37 | def preparemultitx(frm, *args, **kwargs):
38 | tv, fee = args[:-1], int(args[-1])
39 | outs = []
40 | outvalue = 0
41 | for a in tv:
42 | outs.append(a)
43 | outvalue += int(a.split(":")[1])
44 |
45 | u = unspent(frm, **kwargs)
46 | u2 = select(u, int(outvalue)+int(fee))
47 | argz = u2 + outs + [frm, fee]
48 | return mksend(*argz)
49 |
50 |
51 | # BIP32 hierarchical deterministic multisig script
52 | def bip32_hdm_script(*args):
53 | if len(args) == 3:
54 | keys, req, path = args
55 | else:
56 | i, keys, path = 0, [], []
57 | while len(args[i]) > 40:
58 | keys.append(args[i])
59 | i += 1
60 | req = int(args[i])
61 | path = map(int, args[i+1:])
62 | pubs = sorted(map(lambda x: bip32_descend(x, path), keys))
63 | return mk_multisig_script(pubs, req)
64 |
65 |
66 | # BIP32 hierarchical deterministic multisig address
67 | def bip32_hdm_addr(*args):
68 | return scriptaddr(bip32_hdm_script(*args))
69 |
70 |
71 | # Setup a coinvault transaction
72 | def setup_coinvault_tx(tx, script):
73 | txobj = deserialize(tx)
74 | N = deserialize_script(script)[-2]
75 | for inp in txobj["ins"]:
76 | inp["script"] = serialize_script([None] * (N+1) + [script])
77 | return serialize(txobj)
78 |
79 |
80 | # Sign a coinvault transaction
81 | def sign_coinvault_tx(tx, priv):
82 | pub = privtopub(priv)
83 | txobj = deserialize(tx)
84 | subscript = deserialize_script(txobj['ins'][0]['script'])
85 | oscript = deserialize_script(subscript[-1])
86 | k, pubs = oscript[0], oscript[1:-2]
87 | for j in range(len(txobj['ins'])):
88 | scr = deserialize_script(txobj['ins'][j]['script'])
89 | for i, p in enumerate(pubs):
90 | if p == pub:
91 | scr[i+1] = multisign(tx, j, subscript[-1], priv)
92 | if len(filter(lambda x: x, scr[1:-1])) >= k:
93 | scr = [None] + filter(lambda x: x, scr[1:-1])[:k] + [scr[-1]]
94 | txobj['ins'][j]['script'] = serialize_script(scr)
95 | return serialize(txobj)
96 |
97 |
98 | # Inspects a transaction
99 | def inspect(tx, **kwargs):
100 | d = deserialize(tx)
101 | isum = 0
102 | ins = {}
103 | for _in in d['ins']:
104 | h = _in['outpoint']['hash']
105 | i = _in['outpoint']['index']
106 | prevout = deserialize(fetchtx(h, **kwargs))['outs'][i]
107 | isum += prevout['value']
108 | a = script_to_address(prevout['script'])
109 | ins[a] = ins.get(a, 0) + prevout['value']
110 | outs = []
111 | osum = 0
112 | for _out in d['outs']:
113 | outs.append({'address': script_to_address(_out['script']),
114 | 'value': _out['value']})
115 | osum += _out['value']
116 | return {
117 | 'fee': isum - osum,
118 | 'outs': outs,
119 | 'ins': ins
120 | }
121 |
122 |
123 | def merkle_prove(txhash):
124 | blocknum = str(get_block_height(txhash))
125 | header = get_block_header_data(blocknum)
126 | hashes = get_txs_in_block(blocknum)
127 | i = hashes.index(txhash)
128 | return mk_merkle_proof(header, hashes, i)
129 |
--------------------------------------------------------------------------------
/bitcoin/deterministic.py:
--------------------------------------------------------------------------------
1 | from bitcoin.main import *
2 | import hmac
3 | import hashlib
4 | from binascii import hexlify
5 | # Electrum wallets
6 |
7 |
8 | def electrum_stretch(seed):
9 | return slowsha(seed)
10 |
11 | # Accepts seed or stretched seed, returns master public key
12 |
13 |
14 | def electrum_mpk(seed):
15 | if len(seed) == 32:
16 | seed = electrum_stretch(seed)
17 | return privkey_to_pubkey(seed)[2:]
18 |
19 | # Accepts (seed or stretched seed), index and secondary index
20 | # (conventionally 0 for ordinary addresses, 1 for change) , returns privkey
21 |
22 |
23 | def electrum_privkey(seed, n, for_change=0):
24 | if len(seed) == 32:
25 | seed = electrum_stretch(seed)
26 | mpk = electrum_mpk(seed)
27 | offset = dbl_sha256(from_int_representation_to_bytes(n)+b':'+from_int_representation_to_bytes(for_change)+b':'+binascii.unhexlify(mpk))
28 | return add_privkeys(seed, offset)
29 |
30 | # Accepts (seed or stretched seed or master pubkey), index and secondary index
31 | # (conventionally 0 for ordinary addresses, 1 for change) , returns pubkey
32 |
33 |
34 | def electrum_pubkey(masterkey, n, for_change=0):
35 | if len(masterkey) == 32:
36 | mpk = electrum_mpk(electrum_stretch(masterkey))
37 | elif len(masterkey) == 64:
38 | mpk = electrum_mpk(masterkey)
39 | else:
40 | mpk = masterkey
41 | bin_mpk = encode_pubkey(mpk, 'bin_electrum')
42 | offset = bin_dbl_sha256(from_int_representation_to_bytes(n)+b':'+from_int_representation_to_bytes(for_change)+b':'+bin_mpk)
43 | return add_pubkeys('04'+mpk, privtopub(offset))
44 |
45 | # seed/stretched seed/pubkey -> address (convenience method)
46 |
47 |
48 | def electrum_address(masterkey, n, for_change=0, version=0):
49 | return pubkey_to_address(electrum_pubkey(masterkey, n, for_change), version)
50 |
51 | # Given a master public key, a private key from that wallet and its index,
52 | # cracks the secret exponent which can be used to generate all other private
53 | # keys in the wallet
54 |
55 |
56 | def crack_electrum_wallet(mpk, pk, n, for_change=0):
57 | bin_mpk = encode_pubkey(mpk, 'bin_electrum')
58 | offset = dbl_sha256(str(n)+':'+str(for_change)+':'+bin_mpk)
59 | return subtract_privkeys(pk, offset)
60 |
61 | # Below code ASSUMES binary inputs and compressed pubkeys
62 | MAINNET_PRIVATE = b'\x04\x88\xAD\xE4'
63 | MAINNET_PUBLIC = b'\x04\x88\xB2\x1E'
64 | TESTNET_PRIVATE = b'\x04\x35\x83\x94'
65 | TESTNET_PUBLIC = b'\x04\x35\x87\xCF'
66 | PRIVATE = [MAINNET_PRIVATE, TESTNET_PRIVATE]
67 | PUBLIC = [MAINNET_PUBLIC, TESTNET_PUBLIC]
68 |
69 | # BIP32 child key derivation
70 |
71 |
72 | def raw_bip32_ckd(rawtuple, i):
73 | vbytes, depth, fingerprint, oldi, chaincode, key = rawtuple
74 | i = int(i)
75 |
76 | if vbytes in PRIVATE:
77 | priv = key
78 | pub = privtopub(key)
79 | else:
80 | pub = key
81 |
82 | if i >= 2**31:
83 | if vbytes in PUBLIC:
84 | raise Exception("Can't do private derivation on public key!")
85 | I = hmac.new(chaincode, b'\x00'+priv[:32]+encode(i, 256, 4), hashlib.sha512).digest()
86 | else:
87 | I = hmac.new(chaincode, pub+encode(i, 256, 4), hashlib.sha512).digest()
88 |
89 | if vbytes in PRIVATE:
90 | newkey = add_privkeys(I[:32]+B'\x01', priv)
91 | fingerprint = bin_hash160(privtopub(key))[:4]
92 | if vbytes in PUBLIC:
93 | newkey = add_pubkeys(compress(privtopub(I[:32])), key)
94 | fingerprint = bin_hash160(key)[:4]
95 |
96 | return (vbytes, depth + 1, fingerprint, i, I[32:], newkey)
97 |
98 |
99 | def bip32_serialize(rawtuple):
100 | vbytes, depth, fingerprint, i, chaincode, key = rawtuple
101 | i = encode(i, 256, 4)
102 | chaincode = encode(hash_to_int(chaincode), 256, 32)
103 | keydata = b'\x00'+key[:-1] if vbytes in PRIVATE else key
104 | bindata = vbytes + from_int_to_byte(depth % 256) + fingerprint + i + chaincode + keydata
105 | return changebase(bindata+bin_dbl_sha256(bindata)[:4], 256, 58)
106 |
107 |
108 | def bip32_deserialize(data):
109 | dbin = changebase(data, 58, 256)
110 | if bin_dbl_sha256(dbin[:-4])[:4] != dbin[-4:]:
111 | raise Exception("Invalid checksum")
112 | vbytes = dbin[0:4]
113 | depth = from_byte_to_int(dbin[4])
114 | fingerprint = dbin[5:9]
115 | i = decode(dbin[9:13], 256)
116 | chaincode = dbin[13:45]
117 | key = dbin[46:78]+b'\x01' if vbytes in PRIVATE else dbin[45:78]
118 | return (vbytes, depth, fingerprint, i, chaincode, key)
119 |
120 |
121 | def raw_bip32_privtopub(rawtuple):
122 | vbytes, depth, fingerprint, i, chaincode, key = rawtuple
123 | newvbytes = MAINNET_PUBLIC if vbytes == MAINNET_PRIVATE else TESTNET_PUBLIC
124 | return (newvbytes, depth, fingerprint, i, chaincode, privtopub(key))
125 |
126 |
127 | def bip32_privtopub(data):
128 | return bip32_serialize(raw_bip32_privtopub(bip32_deserialize(data)))
129 |
130 |
131 | def bip32_ckd(data, i):
132 | return bip32_serialize(raw_bip32_ckd(bip32_deserialize(data), i))
133 |
134 |
135 | def bip32_master_key(seed, vbytes=MAINNET_PRIVATE):
136 | I = hmac.new(
137 | from_string_to_bytes("Bitcoin seed"),
138 | from_string_to_bytes(seed),
139 | hashlib.sha512
140 | ).digest()
141 | return bip32_serialize((vbytes, 0, b'\x00'*4, 0, I[32:], I[:32]+b'\x01'))
142 |
143 |
144 | def bip32_bin_extract_key(data):
145 | return bip32_deserialize(data)[-1]
146 |
147 |
148 | def bip32_extract_key(data):
149 | return safe_hexlify(bip32_deserialize(data)[-1])
150 |
151 | # Exploits the same vulnerability as above in Electrum wallets
152 | # Takes a BIP32 pubkey and one of the child privkeys of its corresponding
153 | # privkey and returns the BIP32 privkey associated with that pubkey
154 |
155 |
156 | def raw_crack_bip32_privkey(parent_pub, priv):
157 | vbytes, depth, fingerprint, i, chaincode, key = priv
158 | pvbytes, pdepth, pfingerprint, pi, pchaincode, pkey = parent_pub
159 | i = int(i)
160 |
161 | if i >= 2**31:
162 | raise Exception("Can't crack private derivation!")
163 |
164 | I = hmac.new(pchaincode, pkey+encode(i, 256, 4), hashlib.sha512).digest()
165 |
166 | pprivkey = subtract_privkeys(key, I[:32]+b'\x01')
167 |
168 | newvbytes = MAINNET_PRIVATE if vbytes == MAINNET_PUBLIC else TESTNET_PRIVATE
169 | return (newvbytes, pdepth, pfingerprint, pi, pchaincode, pprivkey)
170 |
171 |
172 | def crack_bip32_privkey(parent_pub, priv):
173 | dsppub = bip32_deserialize(parent_pub)
174 | dspriv = bip32_deserialize(priv)
175 | return bip32_serialize(raw_crack_bip32_privkey(dsppub, dspriv))
176 |
177 |
178 | def coinvault_pub_to_bip32(*args):
179 | if len(args) == 1:
180 | args = args[0].split(' ')
181 | vals = map(int, args[34:])
182 | I1 = ''.join(map(chr, vals[:33]))
183 | I2 = ''.join(map(chr, vals[35:67]))
184 | return bip32_serialize((MAINNET_PUBLIC, 0, b'\x00'*4, 0, I2, I1))
185 |
186 |
187 | def coinvault_priv_to_bip32(*args):
188 | if len(args) == 1:
189 | args = args[0].split(' ')
190 | vals = map(int, args[34:])
191 | I2 = ''.join(map(chr, vals[35:67]))
192 | I3 = ''.join(map(chr, vals[72:104]))
193 | return bip32_serialize((MAINNET_PRIVATE, 0, b'\x00'*4, 0, I2, I3+b'\x01'))
194 |
195 |
196 | def bip32_descend(*args):
197 | if len(args) == 2 and isinstance(args[1], list):
198 | key, path = args
199 | else:
200 | key, path = args[0], map(int, args[1:])
201 | for p in path:
202 | key = bip32_ckd(key, p)
203 | return bip32_extract_key(key)
204 |
--------------------------------------------------------------------------------
/bitcoin/english.txt:
--------------------------------------------------------------------------------
1 | abandon
2 | ability
3 | able
4 | about
5 | above
6 | absent
7 | absorb
8 | abstract
9 | absurd
10 | abuse
11 | access
12 | accident
13 | account
14 | accuse
15 | achieve
16 | acid
17 | acoustic
18 | acquire
19 | across
20 | act
21 | action
22 | actor
23 | actress
24 | actual
25 | adapt
26 | add
27 | addict
28 | address
29 | adjust
30 | admit
31 | adult
32 | advance
33 | advice
34 | aerobic
35 | affair
36 | afford
37 | afraid
38 | again
39 | age
40 | agent
41 | agree
42 | ahead
43 | aim
44 | air
45 | airport
46 | aisle
47 | alarm
48 | album
49 | alcohol
50 | alert
51 | alien
52 | all
53 | alley
54 | allow
55 | almost
56 | alone
57 | alpha
58 | already
59 | also
60 | alter
61 | always
62 | amateur
63 | amazing
64 | among
65 | amount
66 | amused
67 | analyst
68 | anchor
69 | ancient
70 | anger
71 | angle
72 | angry
73 | animal
74 | ankle
75 | announce
76 | annual
77 | another
78 | answer
79 | antenna
80 | antique
81 | anxiety
82 | any
83 | apart
84 | apology
85 | appear
86 | apple
87 | approve
88 | april
89 | arch
90 | arctic
91 | area
92 | arena
93 | argue
94 | arm
95 | armed
96 | armor
97 | army
98 | around
99 | arrange
100 | arrest
101 | arrive
102 | arrow
103 | art
104 | artefact
105 | artist
106 | artwork
107 | ask
108 | aspect
109 | assault
110 | asset
111 | assist
112 | assume
113 | asthma
114 | athlete
115 | atom
116 | attack
117 | attend
118 | attitude
119 | attract
120 | auction
121 | audit
122 | august
123 | aunt
124 | author
125 | auto
126 | autumn
127 | average
128 | avocado
129 | avoid
130 | awake
131 | aware
132 | away
133 | awesome
134 | awful
135 | awkward
136 | axis
137 | baby
138 | bachelor
139 | bacon
140 | badge
141 | bag
142 | balance
143 | balcony
144 | ball
145 | bamboo
146 | banana
147 | banner
148 | bar
149 | barely
150 | bargain
151 | barrel
152 | base
153 | basic
154 | basket
155 | battle
156 | beach
157 | bean
158 | beauty
159 | because
160 | become
161 | beef
162 | before
163 | begin
164 | behave
165 | behind
166 | believe
167 | below
168 | belt
169 | bench
170 | benefit
171 | best
172 | betray
173 | better
174 | between
175 | beyond
176 | bicycle
177 | bid
178 | bike
179 | bind
180 | biology
181 | bird
182 | birth
183 | bitter
184 | black
185 | blade
186 | blame
187 | blanket
188 | blast
189 | bleak
190 | bless
191 | blind
192 | blood
193 | blossom
194 | blouse
195 | blue
196 | blur
197 | blush
198 | board
199 | boat
200 | body
201 | boil
202 | bomb
203 | bone
204 | bonus
205 | book
206 | boost
207 | border
208 | boring
209 | borrow
210 | boss
211 | bottom
212 | bounce
213 | box
214 | boy
215 | bracket
216 | brain
217 | brand
218 | brass
219 | brave
220 | bread
221 | breeze
222 | brick
223 | bridge
224 | brief
225 | bright
226 | bring
227 | brisk
228 | broccoli
229 | broken
230 | bronze
231 | broom
232 | brother
233 | brown
234 | brush
235 | bubble
236 | buddy
237 | budget
238 | buffalo
239 | build
240 | bulb
241 | bulk
242 | bullet
243 | bundle
244 | bunker
245 | burden
246 | burger
247 | burst
248 | bus
249 | business
250 | busy
251 | butter
252 | buyer
253 | buzz
254 | cabbage
255 | cabin
256 | cable
257 | cactus
258 | cage
259 | cake
260 | call
261 | calm
262 | camera
263 | camp
264 | can
265 | canal
266 | cancel
267 | candy
268 | cannon
269 | canoe
270 | canvas
271 | canyon
272 | capable
273 | capital
274 | captain
275 | car
276 | carbon
277 | card
278 | cargo
279 | carpet
280 | carry
281 | cart
282 | case
283 | cash
284 | casino
285 | castle
286 | casual
287 | cat
288 | catalog
289 | catch
290 | category
291 | cattle
292 | caught
293 | cause
294 | caution
295 | cave
296 | ceiling
297 | celery
298 | cement
299 | census
300 | century
301 | cereal
302 | certain
303 | chair
304 | chalk
305 | champion
306 | change
307 | chaos
308 | chapter
309 | charge
310 | chase
311 | chat
312 | cheap
313 | check
314 | cheese
315 | chef
316 | cherry
317 | chest
318 | chicken
319 | chief
320 | child
321 | chimney
322 | choice
323 | choose
324 | chronic
325 | chuckle
326 | chunk
327 | churn
328 | cigar
329 | cinnamon
330 | circle
331 | citizen
332 | city
333 | civil
334 | claim
335 | clap
336 | clarify
337 | claw
338 | clay
339 | clean
340 | clerk
341 | clever
342 | click
343 | client
344 | cliff
345 | climb
346 | clinic
347 | clip
348 | clock
349 | clog
350 | close
351 | cloth
352 | cloud
353 | clown
354 | club
355 | clump
356 | cluster
357 | clutch
358 | coach
359 | coast
360 | coconut
361 | code
362 | coffee
363 | coil
364 | coin
365 | collect
366 | color
367 | column
368 | combine
369 | come
370 | comfort
371 | comic
372 | common
373 | company
374 | concert
375 | conduct
376 | confirm
377 | congress
378 | connect
379 | consider
380 | control
381 | convince
382 | cook
383 | cool
384 | copper
385 | copy
386 | coral
387 | core
388 | corn
389 | correct
390 | cost
391 | cotton
392 | couch
393 | country
394 | couple
395 | course
396 | cousin
397 | cover
398 | coyote
399 | crack
400 | cradle
401 | craft
402 | cram
403 | crane
404 | crash
405 | crater
406 | crawl
407 | crazy
408 | cream
409 | credit
410 | creek
411 | crew
412 | cricket
413 | crime
414 | crisp
415 | critic
416 | crop
417 | cross
418 | crouch
419 | crowd
420 | crucial
421 | cruel
422 | cruise
423 | crumble
424 | crunch
425 | crush
426 | cry
427 | crystal
428 | cube
429 | culture
430 | cup
431 | cupboard
432 | curious
433 | current
434 | curtain
435 | curve
436 | cushion
437 | custom
438 | cute
439 | cycle
440 | dad
441 | damage
442 | damp
443 | dance
444 | danger
445 | daring
446 | dash
447 | daughter
448 | dawn
449 | day
450 | deal
451 | debate
452 | debris
453 | decade
454 | december
455 | decide
456 | decline
457 | decorate
458 | decrease
459 | deer
460 | defense
461 | define
462 | defy
463 | degree
464 | delay
465 | deliver
466 | demand
467 | demise
468 | denial
469 | dentist
470 | deny
471 | depart
472 | depend
473 | deposit
474 | depth
475 | deputy
476 | derive
477 | describe
478 | desert
479 | design
480 | desk
481 | despair
482 | destroy
483 | detail
484 | detect
485 | develop
486 | device
487 | devote
488 | diagram
489 | dial
490 | diamond
491 | diary
492 | dice
493 | diesel
494 | diet
495 | differ
496 | digital
497 | dignity
498 | dilemma
499 | dinner
500 | dinosaur
501 | direct
502 | dirt
503 | disagree
504 | discover
505 | disease
506 | dish
507 | dismiss
508 | disorder
509 | display
510 | distance
511 | divert
512 | divide
513 | divorce
514 | dizzy
515 | doctor
516 | document
517 | dog
518 | doll
519 | dolphin
520 | domain
521 | donate
522 | donkey
523 | donor
524 | door
525 | dose
526 | double
527 | dove
528 | draft
529 | dragon
530 | drama
531 | drastic
532 | draw
533 | dream
534 | dress
535 | drift
536 | drill
537 | drink
538 | drip
539 | drive
540 | drop
541 | drum
542 | dry
543 | duck
544 | dumb
545 | dune
546 | during
547 | dust
548 | dutch
549 | duty
550 | dwarf
551 | dynamic
552 | eager
553 | eagle
554 | early
555 | earn
556 | earth
557 | easily
558 | east
559 | easy
560 | echo
561 | ecology
562 | economy
563 | edge
564 | edit
565 | educate
566 | effort
567 | egg
568 | eight
569 | either
570 | elbow
571 | elder
572 | electric
573 | elegant
574 | element
575 | elephant
576 | elevator
577 | elite
578 | else
579 | embark
580 | embody
581 | embrace
582 | emerge
583 | emotion
584 | employ
585 | empower
586 | empty
587 | enable
588 | enact
589 | end
590 | endless
591 | endorse
592 | enemy
593 | energy
594 | enforce
595 | engage
596 | engine
597 | enhance
598 | enjoy
599 | enlist
600 | enough
601 | enrich
602 | enroll
603 | ensure
604 | enter
605 | entire
606 | entry
607 | envelope
608 | episode
609 | equal
610 | equip
611 | era
612 | erase
613 | erode
614 | erosion
615 | error
616 | erupt
617 | escape
618 | essay
619 | essence
620 | estate
621 | eternal
622 | ethics
623 | evidence
624 | evil
625 | evoke
626 | evolve
627 | exact
628 | example
629 | excess
630 | exchange
631 | excite
632 | exclude
633 | excuse
634 | execute
635 | exercise
636 | exhaust
637 | exhibit
638 | exile
639 | exist
640 | exit
641 | exotic
642 | expand
643 | expect
644 | expire
645 | explain
646 | expose
647 | express
648 | extend
649 | extra
650 | eye
651 | eyebrow
652 | fabric
653 | face
654 | faculty
655 | fade
656 | faint
657 | faith
658 | fall
659 | false
660 | fame
661 | family
662 | famous
663 | fan
664 | fancy
665 | fantasy
666 | farm
667 | fashion
668 | fat
669 | fatal
670 | father
671 | fatigue
672 | fault
673 | favorite
674 | feature
675 | february
676 | federal
677 | fee
678 | feed
679 | feel
680 | female
681 | fence
682 | festival
683 | fetch
684 | fever
685 | few
686 | fiber
687 | fiction
688 | field
689 | figure
690 | file
691 | film
692 | filter
693 | final
694 | find
695 | fine
696 | finger
697 | finish
698 | fire
699 | firm
700 | first
701 | fiscal
702 | fish
703 | fit
704 | fitness
705 | fix
706 | flag
707 | flame
708 | flash
709 | flat
710 | flavor
711 | flee
712 | flight
713 | flip
714 | float
715 | flock
716 | floor
717 | flower
718 | fluid
719 | flush
720 | fly
721 | foam
722 | focus
723 | fog
724 | foil
725 | fold
726 | follow
727 | food
728 | foot
729 | force
730 | forest
731 | forget
732 | fork
733 | fortune
734 | forum
735 | forward
736 | fossil
737 | foster
738 | found
739 | fox
740 | fragile
741 | frame
742 | frequent
743 | fresh
744 | friend
745 | fringe
746 | frog
747 | front
748 | frost
749 | frown
750 | frozen
751 | fruit
752 | fuel
753 | fun
754 | funny
755 | furnace
756 | fury
757 | future
758 | gadget
759 | gain
760 | galaxy
761 | gallery
762 | game
763 | gap
764 | garage
765 | garbage
766 | garden
767 | garlic
768 | garment
769 | gas
770 | gasp
771 | gate
772 | gather
773 | gauge
774 | gaze
775 | general
776 | genius
777 | genre
778 | gentle
779 | genuine
780 | gesture
781 | ghost
782 | giant
783 | gift
784 | giggle
785 | ginger
786 | giraffe
787 | girl
788 | give
789 | glad
790 | glance
791 | glare
792 | glass
793 | glide
794 | glimpse
795 | globe
796 | gloom
797 | glory
798 | glove
799 | glow
800 | glue
801 | goat
802 | goddess
803 | gold
804 | good
805 | goose
806 | gorilla
807 | gospel
808 | gossip
809 | govern
810 | gown
811 | grab
812 | grace
813 | grain
814 | grant
815 | grape
816 | grass
817 | gravity
818 | great
819 | green
820 | grid
821 | grief
822 | grit
823 | grocery
824 | group
825 | grow
826 | grunt
827 | guard
828 | guess
829 | guide
830 | guilt
831 | guitar
832 | gun
833 | gym
834 | habit
835 | hair
836 | half
837 | hammer
838 | hamster
839 | hand
840 | happy
841 | harbor
842 | hard
843 | harsh
844 | harvest
845 | hat
846 | have
847 | hawk
848 | hazard
849 | head
850 | health
851 | heart
852 | heavy
853 | hedgehog
854 | height
855 | hello
856 | helmet
857 | help
858 | hen
859 | hero
860 | hidden
861 | high
862 | hill
863 | hint
864 | hip
865 | hire
866 | history
867 | hobby
868 | hockey
869 | hold
870 | hole
871 | holiday
872 | hollow
873 | home
874 | honey
875 | hood
876 | hope
877 | horn
878 | horror
879 | horse
880 | hospital
881 | host
882 | hotel
883 | hour
884 | hover
885 | hub
886 | huge
887 | human
888 | humble
889 | humor
890 | hundred
891 | hungry
892 | hunt
893 | hurdle
894 | hurry
895 | hurt
896 | husband
897 | hybrid
898 | ice
899 | icon
900 | idea
901 | identify
902 | idle
903 | ignore
904 | ill
905 | illegal
906 | illness
907 | image
908 | imitate
909 | immense
910 | immune
911 | impact
912 | impose
913 | improve
914 | impulse
915 | inch
916 | include
917 | income
918 | increase
919 | index
920 | indicate
921 | indoor
922 | industry
923 | infant
924 | inflict
925 | inform
926 | inhale
927 | inherit
928 | initial
929 | inject
930 | injury
931 | inmate
932 | inner
933 | innocent
934 | input
935 | inquiry
936 | insane
937 | insect
938 | inside
939 | inspire
940 | install
941 | intact
942 | interest
943 | into
944 | invest
945 | invite
946 | involve
947 | iron
948 | island
949 | isolate
950 | issue
951 | item
952 | ivory
953 | jacket
954 | jaguar
955 | jar
956 | jazz
957 | jealous
958 | jeans
959 | jelly
960 | jewel
961 | job
962 | join
963 | joke
964 | journey
965 | joy
966 | judge
967 | juice
968 | jump
969 | jungle
970 | junior
971 | junk
972 | just
973 | kangaroo
974 | keen
975 | keep
976 | ketchup
977 | key
978 | kick
979 | kid
980 | kidney
981 | kind
982 | kingdom
983 | kiss
984 | kit
985 | kitchen
986 | kite
987 | kitten
988 | kiwi
989 | knee
990 | knife
991 | knock
992 | know
993 | lab
994 | label
995 | labor
996 | ladder
997 | lady
998 | lake
999 | lamp
1000 | language
1001 | laptop
1002 | large
1003 | later
1004 | latin
1005 | laugh
1006 | laundry
1007 | lava
1008 | law
1009 | lawn
1010 | lawsuit
1011 | layer
1012 | lazy
1013 | leader
1014 | leaf
1015 | learn
1016 | leave
1017 | lecture
1018 | left
1019 | leg
1020 | legal
1021 | legend
1022 | leisure
1023 | lemon
1024 | lend
1025 | length
1026 | lens
1027 | leopard
1028 | lesson
1029 | letter
1030 | level
1031 | liar
1032 | liberty
1033 | library
1034 | license
1035 | life
1036 | lift
1037 | light
1038 | like
1039 | limb
1040 | limit
1041 | link
1042 | lion
1043 | liquid
1044 | list
1045 | little
1046 | live
1047 | lizard
1048 | load
1049 | loan
1050 | lobster
1051 | local
1052 | lock
1053 | logic
1054 | lonely
1055 | long
1056 | loop
1057 | lottery
1058 | loud
1059 | lounge
1060 | love
1061 | loyal
1062 | lucky
1063 | luggage
1064 | lumber
1065 | lunar
1066 | lunch
1067 | luxury
1068 | lyrics
1069 | machine
1070 | mad
1071 | magic
1072 | magnet
1073 | maid
1074 | mail
1075 | main
1076 | major
1077 | make
1078 | mammal
1079 | man
1080 | manage
1081 | mandate
1082 | mango
1083 | mansion
1084 | manual
1085 | maple
1086 | marble
1087 | march
1088 | margin
1089 | marine
1090 | market
1091 | marriage
1092 | mask
1093 | mass
1094 | master
1095 | match
1096 | material
1097 | math
1098 | matrix
1099 | matter
1100 | maximum
1101 | maze
1102 | meadow
1103 | mean
1104 | measure
1105 | meat
1106 | mechanic
1107 | medal
1108 | media
1109 | melody
1110 | melt
1111 | member
1112 | memory
1113 | mention
1114 | menu
1115 | mercy
1116 | merge
1117 | merit
1118 | merry
1119 | mesh
1120 | message
1121 | metal
1122 | method
1123 | middle
1124 | midnight
1125 | milk
1126 | million
1127 | mimic
1128 | mind
1129 | minimum
1130 | minor
1131 | minute
1132 | miracle
1133 | mirror
1134 | misery
1135 | miss
1136 | mistake
1137 | mix
1138 | mixed
1139 | mixture
1140 | mobile
1141 | model
1142 | modify
1143 | mom
1144 | moment
1145 | monitor
1146 | monkey
1147 | monster
1148 | month
1149 | moon
1150 | moral
1151 | more
1152 | morning
1153 | mosquito
1154 | mother
1155 | motion
1156 | motor
1157 | mountain
1158 | mouse
1159 | move
1160 | movie
1161 | much
1162 | muffin
1163 | mule
1164 | multiply
1165 | muscle
1166 | museum
1167 | mushroom
1168 | music
1169 | must
1170 | mutual
1171 | myself
1172 | mystery
1173 | myth
1174 | naive
1175 | name
1176 | napkin
1177 | narrow
1178 | nasty
1179 | nation
1180 | nature
1181 | near
1182 | neck
1183 | need
1184 | negative
1185 | neglect
1186 | neither
1187 | nephew
1188 | nerve
1189 | nest
1190 | net
1191 | network
1192 | neutral
1193 | never
1194 | news
1195 | next
1196 | nice
1197 | night
1198 | noble
1199 | noise
1200 | nominee
1201 | noodle
1202 | normal
1203 | north
1204 | nose
1205 | notable
1206 | note
1207 | nothing
1208 | notice
1209 | novel
1210 | now
1211 | nuclear
1212 | number
1213 | nurse
1214 | nut
1215 | oak
1216 | obey
1217 | object
1218 | oblige
1219 | obscure
1220 | observe
1221 | obtain
1222 | obvious
1223 | occur
1224 | ocean
1225 | october
1226 | odor
1227 | off
1228 | offer
1229 | office
1230 | often
1231 | oil
1232 | okay
1233 | old
1234 | olive
1235 | olympic
1236 | omit
1237 | once
1238 | one
1239 | onion
1240 | online
1241 | only
1242 | open
1243 | opera
1244 | opinion
1245 | oppose
1246 | option
1247 | orange
1248 | orbit
1249 | orchard
1250 | order
1251 | ordinary
1252 | organ
1253 | orient
1254 | original
1255 | orphan
1256 | ostrich
1257 | other
1258 | outdoor
1259 | outer
1260 | output
1261 | outside
1262 | oval
1263 | oven
1264 | over
1265 | own
1266 | owner
1267 | oxygen
1268 | oyster
1269 | ozone
1270 | pact
1271 | paddle
1272 | page
1273 | pair
1274 | palace
1275 | palm
1276 | panda
1277 | panel
1278 | panic
1279 | panther
1280 | paper
1281 | parade
1282 | parent
1283 | park
1284 | parrot
1285 | party
1286 | pass
1287 | patch
1288 | path
1289 | patient
1290 | patrol
1291 | pattern
1292 | pause
1293 | pave
1294 | payment
1295 | peace
1296 | peanut
1297 | pear
1298 | peasant
1299 | pelican
1300 | pen
1301 | penalty
1302 | pencil
1303 | people
1304 | pepper
1305 | perfect
1306 | permit
1307 | person
1308 | pet
1309 | phone
1310 | photo
1311 | phrase
1312 | physical
1313 | piano
1314 | picnic
1315 | picture
1316 | piece
1317 | pig
1318 | pigeon
1319 | pill
1320 | pilot
1321 | pink
1322 | pioneer
1323 | pipe
1324 | pistol
1325 | pitch
1326 | pizza
1327 | place
1328 | planet
1329 | plastic
1330 | plate
1331 | play
1332 | please
1333 | pledge
1334 | pluck
1335 | plug
1336 | plunge
1337 | poem
1338 | poet
1339 | point
1340 | polar
1341 | pole
1342 | police
1343 | pond
1344 | pony
1345 | pool
1346 | popular
1347 | portion
1348 | position
1349 | possible
1350 | post
1351 | potato
1352 | pottery
1353 | poverty
1354 | powder
1355 | power
1356 | practice
1357 | praise
1358 | predict
1359 | prefer
1360 | prepare
1361 | present
1362 | pretty
1363 | prevent
1364 | price
1365 | pride
1366 | primary
1367 | print
1368 | priority
1369 | prison
1370 | private
1371 | prize
1372 | problem
1373 | process
1374 | produce
1375 | profit
1376 | program
1377 | project
1378 | promote
1379 | proof
1380 | property
1381 | prosper
1382 | protect
1383 | proud
1384 | provide
1385 | public
1386 | pudding
1387 | pull
1388 | pulp
1389 | pulse
1390 | pumpkin
1391 | punch
1392 | pupil
1393 | puppy
1394 | purchase
1395 | purity
1396 | purpose
1397 | purse
1398 | push
1399 | put
1400 | puzzle
1401 | pyramid
1402 | quality
1403 | quantum
1404 | quarter
1405 | question
1406 | quick
1407 | quit
1408 | quiz
1409 | quote
1410 | rabbit
1411 | raccoon
1412 | race
1413 | rack
1414 | radar
1415 | radio
1416 | rail
1417 | rain
1418 | raise
1419 | rally
1420 | ramp
1421 | ranch
1422 | random
1423 | range
1424 | rapid
1425 | rare
1426 | rate
1427 | rather
1428 | raven
1429 | raw
1430 | razor
1431 | ready
1432 | real
1433 | reason
1434 | rebel
1435 | rebuild
1436 | recall
1437 | receive
1438 | recipe
1439 | record
1440 | recycle
1441 | reduce
1442 | reflect
1443 | reform
1444 | refuse
1445 | region
1446 | regret
1447 | regular
1448 | reject
1449 | relax
1450 | release
1451 | relief
1452 | rely
1453 | remain
1454 | remember
1455 | remind
1456 | remove
1457 | render
1458 | renew
1459 | rent
1460 | reopen
1461 | repair
1462 | repeat
1463 | replace
1464 | report
1465 | require
1466 | rescue
1467 | resemble
1468 | resist
1469 | resource
1470 | response
1471 | result
1472 | retire
1473 | retreat
1474 | return
1475 | reunion
1476 | reveal
1477 | review
1478 | reward
1479 | rhythm
1480 | rib
1481 | ribbon
1482 | rice
1483 | rich
1484 | ride
1485 | ridge
1486 | rifle
1487 | right
1488 | rigid
1489 | ring
1490 | riot
1491 | ripple
1492 | risk
1493 | ritual
1494 | rival
1495 | river
1496 | road
1497 | roast
1498 | robot
1499 | robust
1500 | rocket
1501 | romance
1502 | roof
1503 | rookie
1504 | room
1505 | rose
1506 | rotate
1507 | rough
1508 | round
1509 | route
1510 | royal
1511 | rubber
1512 | rude
1513 | rug
1514 | rule
1515 | run
1516 | runway
1517 | rural
1518 | sad
1519 | saddle
1520 | sadness
1521 | safe
1522 | sail
1523 | salad
1524 | salmon
1525 | salon
1526 | salt
1527 | salute
1528 | same
1529 | sample
1530 | sand
1531 | satisfy
1532 | satoshi
1533 | sauce
1534 | sausage
1535 | save
1536 | say
1537 | scale
1538 | scan
1539 | scare
1540 | scatter
1541 | scene
1542 | scheme
1543 | school
1544 | science
1545 | scissors
1546 | scorpion
1547 | scout
1548 | scrap
1549 | screen
1550 | script
1551 | scrub
1552 | sea
1553 | search
1554 | season
1555 | seat
1556 | second
1557 | secret
1558 | section
1559 | security
1560 | seed
1561 | seek
1562 | segment
1563 | select
1564 | sell
1565 | seminar
1566 | senior
1567 | sense
1568 | sentence
1569 | series
1570 | service
1571 | session
1572 | settle
1573 | setup
1574 | seven
1575 | shadow
1576 | shaft
1577 | shallow
1578 | share
1579 | shed
1580 | shell
1581 | sheriff
1582 | shield
1583 | shift
1584 | shine
1585 | ship
1586 | shiver
1587 | shock
1588 | shoe
1589 | shoot
1590 | shop
1591 | short
1592 | shoulder
1593 | shove
1594 | shrimp
1595 | shrug
1596 | shuffle
1597 | shy
1598 | sibling
1599 | sick
1600 | side
1601 | siege
1602 | sight
1603 | sign
1604 | silent
1605 | silk
1606 | silly
1607 | silver
1608 | similar
1609 | simple
1610 | since
1611 | sing
1612 | siren
1613 | sister
1614 | situate
1615 | six
1616 | size
1617 | skate
1618 | sketch
1619 | ski
1620 | skill
1621 | skin
1622 | skirt
1623 | skull
1624 | slab
1625 | slam
1626 | sleep
1627 | slender
1628 | slice
1629 | slide
1630 | slight
1631 | slim
1632 | slogan
1633 | slot
1634 | slow
1635 | slush
1636 | small
1637 | smart
1638 | smile
1639 | smoke
1640 | smooth
1641 | snack
1642 | snake
1643 | snap
1644 | sniff
1645 | snow
1646 | soap
1647 | soccer
1648 | social
1649 | sock
1650 | soda
1651 | soft
1652 | solar
1653 | soldier
1654 | solid
1655 | solution
1656 | solve
1657 | someone
1658 | song
1659 | soon
1660 | sorry
1661 | sort
1662 | soul
1663 | sound
1664 | soup
1665 | source
1666 | south
1667 | space
1668 | spare
1669 | spatial
1670 | spawn
1671 | speak
1672 | special
1673 | speed
1674 | spell
1675 | spend
1676 | sphere
1677 | spice
1678 | spider
1679 | spike
1680 | spin
1681 | spirit
1682 | split
1683 | spoil
1684 | sponsor
1685 | spoon
1686 | sport
1687 | spot
1688 | spray
1689 | spread
1690 | spring
1691 | spy
1692 | square
1693 | squeeze
1694 | squirrel
1695 | stable
1696 | stadium
1697 | staff
1698 | stage
1699 | stairs
1700 | stamp
1701 | stand
1702 | start
1703 | state
1704 | stay
1705 | steak
1706 | steel
1707 | stem
1708 | step
1709 | stereo
1710 | stick
1711 | still
1712 | sting
1713 | stock
1714 | stomach
1715 | stone
1716 | stool
1717 | story
1718 | stove
1719 | strategy
1720 | street
1721 | strike
1722 | strong
1723 | struggle
1724 | student
1725 | stuff
1726 | stumble
1727 | style
1728 | subject
1729 | submit
1730 | subway
1731 | success
1732 | such
1733 | sudden
1734 | suffer
1735 | sugar
1736 | suggest
1737 | suit
1738 | summer
1739 | sun
1740 | sunny
1741 | sunset
1742 | super
1743 | supply
1744 | supreme
1745 | sure
1746 | surface
1747 | surge
1748 | surprise
1749 | surround
1750 | survey
1751 | suspect
1752 | sustain
1753 | swallow
1754 | swamp
1755 | swap
1756 | swarm
1757 | swear
1758 | sweet
1759 | swift
1760 | swim
1761 | swing
1762 | switch
1763 | sword
1764 | symbol
1765 | symptom
1766 | syrup
1767 | system
1768 | table
1769 | tackle
1770 | tag
1771 | tail
1772 | talent
1773 | talk
1774 | tank
1775 | tape
1776 | target
1777 | task
1778 | taste
1779 | tattoo
1780 | taxi
1781 | teach
1782 | team
1783 | tell
1784 | ten
1785 | tenant
1786 | tennis
1787 | tent
1788 | term
1789 | test
1790 | text
1791 | thank
1792 | that
1793 | theme
1794 | then
1795 | theory
1796 | there
1797 | they
1798 | thing
1799 | this
1800 | thought
1801 | three
1802 | thrive
1803 | throw
1804 | thumb
1805 | thunder
1806 | ticket
1807 | tide
1808 | tiger
1809 | tilt
1810 | timber
1811 | time
1812 | tiny
1813 | tip
1814 | tired
1815 | tissue
1816 | title
1817 | toast
1818 | tobacco
1819 | today
1820 | toddler
1821 | toe
1822 | together
1823 | toilet
1824 | token
1825 | tomato
1826 | tomorrow
1827 | tone
1828 | tongue
1829 | tonight
1830 | tool
1831 | tooth
1832 | top
1833 | topic
1834 | topple
1835 | torch
1836 | tornado
1837 | tortoise
1838 | toss
1839 | total
1840 | tourist
1841 | toward
1842 | tower
1843 | town
1844 | toy
1845 | track
1846 | trade
1847 | traffic
1848 | tragic
1849 | train
1850 | transfer
1851 | trap
1852 | trash
1853 | travel
1854 | tray
1855 | treat
1856 | tree
1857 | trend
1858 | trial
1859 | tribe
1860 | trick
1861 | trigger
1862 | trim
1863 | trip
1864 | trophy
1865 | trouble
1866 | truck
1867 | true
1868 | truly
1869 | trumpet
1870 | trust
1871 | truth
1872 | try
1873 | tube
1874 | tuition
1875 | tumble
1876 | tuna
1877 | tunnel
1878 | turkey
1879 | turn
1880 | turtle
1881 | twelve
1882 | twenty
1883 | twice
1884 | twin
1885 | twist
1886 | two
1887 | type
1888 | typical
1889 | ugly
1890 | umbrella
1891 | unable
1892 | unaware
1893 | uncle
1894 | uncover
1895 | under
1896 | undo
1897 | unfair
1898 | unfold
1899 | unhappy
1900 | uniform
1901 | unique
1902 | unit
1903 | universe
1904 | unknown
1905 | unlock
1906 | until
1907 | unusual
1908 | unveil
1909 | update
1910 | upgrade
1911 | uphold
1912 | upon
1913 | upper
1914 | upset
1915 | urban
1916 | urge
1917 | usage
1918 | use
1919 | used
1920 | useful
1921 | useless
1922 | usual
1923 | utility
1924 | vacant
1925 | vacuum
1926 | vague
1927 | valid
1928 | valley
1929 | valve
1930 | van
1931 | vanish
1932 | vapor
1933 | various
1934 | vast
1935 | vault
1936 | vehicle
1937 | velvet
1938 | vendor
1939 | venture
1940 | venue
1941 | verb
1942 | verify
1943 | version
1944 | very
1945 | vessel
1946 | veteran
1947 | viable
1948 | vibrant
1949 | vicious
1950 | victory
1951 | video
1952 | view
1953 | village
1954 | vintage
1955 | violin
1956 | virtual
1957 | virus
1958 | visa
1959 | visit
1960 | visual
1961 | vital
1962 | vivid
1963 | vocal
1964 | voice
1965 | void
1966 | volcano
1967 | volume
1968 | vote
1969 | voyage
1970 | wage
1971 | wagon
1972 | wait
1973 | walk
1974 | wall
1975 | walnut
1976 | want
1977 | warfare
1978 | warm
1979 | warrior
1980 | wash
1981 | wasp
1982 | waste
1983 | water
1984 | wave
1985 | way
1986 | wealth
1987 | weapon
1988 | wear
1989 | weasel
1990 | weather
1991 | web
1992 | wedding
1993 | weekend
1994 | weird
1995 | welcome
1996 | west
1997 | wet
1998 | whale
1999 | what
2000 | wheat
2001 | wheel
2002 | when
2003 | where
2004 | whip
2005 | whisper
2006 | wide
2007 | width
2008 | wife
2009 | wild
2010 | will
2011 | win
2012 | window
2013 | wine
2014 | wing
2015 | wink
2016 | winner
2017 | winter
2018 | wire
2019 | wisdom
2020 | wise
2021 | wish
2022 | witness
2023 | wolf
2024 | woman
2025 | wonder
2026 | wood
2027 | wool
2028 | word
2029 | work
2030 | world
2031 | worry
2032 | worth
2033 | wrap
2034 | wreck
2035 | wrestle
2036 | wrist
2037 | write
2038 | wrong
2039 | yard
2040 | year
2041 | yellow
2042 | you
2043 | young
2044 | youth
2045 | zebra
2046 | zero
2047 | zone
2048 | zoo
2049 |
--------------------------------------------------------------------------------
/bitcoin/main.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | from .py2specials import *
3 | from .py3specials import *
4 | import binascii
5 | import hashlib
6 | import re
7 | import sys
8 | import os
9 | import base64
10 | import time
11 | import random
12 | import hmac
13 | from bitcoin.ripemd import *
14 |
15 | # Elliptic curve parameters (secp256k1)
16 |
17 | P = 2**256 - 2**32 - 977
18 | N = 115792089237316195423570985008687907852837564279074904382605163141518161494337
19 | A = 0
20 | B = 7
21 | Gx = 55066263022277343669578718895168534326250603453777594175500187360389116729240
22 | Gy = 32670510020758816978083085130507043184471273380659243275938904335757337482424
23 | G = (Gx, Gy)
24 |
25 |
26 | def change_curve(p, n, a, b, gx, gy):
27 | global P, N, A, B, Gx, Gy, G
28 | P, N, A, B, Gx, Gy = p, n, a, b, gx, gy
29 | G = (Gx, Gy)
30 |
31 |
32 | def getG():
33 | return G
34 |
35 | # Extended Euclidean Algorithm
36 |
37 |
38 | def inv(a, n):
39 | if a == 0:
40 | return 0
41 | lm, hm = 1, 0
42 | low, high = a % n, n
43 | while low > 1:
44 | r = high//low
45 | nm, new = hm-lm*r, high-low*r
46 | lm, low, hm, high = nm, new, lm, low
47 | return lm % n
48 |
49 |
50 |
51 | # JSON access (for pybtctool convenience)
52 |
53 |
54 | def access(obj, prop):
55 | if isinstance(obj, dict):
56 | if prop in obj:
57 | return obj[prop]
58 | elif '.' in prop:
59 | return obj[float(prop)]
60 | else:
61 | return obj[int(prop)]
62 | else:
63 | return obj[int(prop)]
64 |
65 |
66 | def multiaccess(obj, prop):
67 | return [access(o, prop) for o in obj]
68 |
69 |
70 | def slice(obj, start=0, end=2**200):
71 | return obj[int(start):int(end)]
72 |
73 |
74 | def count(obj):
75 | return len(obj)
76 |
77 | _sum = sum
78 |
79 |
80 | def sum(obj):
81 | return _sum(obj)
82 |
83 |
84 | def isinf(p):
85 | return p[0] == 0 and p[1] == 0
86 |
87 |
88 | def to_jacobian(p):
89 | o = (p[0], p[1], 1)
90 | return o
91 |
92 |
93 | def jacobian_double(p):
94 | if not p[1]:
95 | return (0, 0, 0)
96 | ysq = (p[1] ** 2) % P
97 | S = (4 * p[0] * ysq) % P
98 | M = (3 * p[0] ** 2 + A * p[2] ** 4) % P
99 | nx = (M**2 - 2 * S) % P
100 | ny = (M * (S - nx) - 8 * ysq ** 2) % P
101 | nz = (2 * p[1] * p[2]) % P
102 | return (nx, ny, nz)
103 |
104 |
105 | def jacobian_add(p, q):
106 | if not p[1]:
107 | return q
108 | if not q[1]:
109 | return p
110 | U1 = (p[0] * q[2] ** 2) % P
111 | U2 = (q[0] * p[2] ** 2) % P
112 | S1 = (p[1] * q[2] ** 3) % P
113 | S2 = (q[1] * p[2] ** 3) % P
114 | if U1 == U2:
115 | if S1 != S2:
116 | return (0, 0, 1)
117 | return jacobian_double(p)
118 | H = U2 - U1
119 | R = S2 - S1
120 | H2 = (H * H) % P
121 | H3 = (H * H2) % P
122 | U1H2 = (U1 * H2) % P
123 | nx = (R ** 2 - H3 - 2 * U1H2) % P
124 | ny = (R * (U1H2 - nx) - S1 * H3) % P
125 | nz = (H * p[2] * q[2]) % P
126 | return (nx, ny, nz)
127 |
128 |
129 | def from_jacobian(p):
130 | z = inv(p[2], P)
131 | return ((p[0] * z**2) % P, (p[1] * z**3) % P)
132 |
133 |
134 | def jacobian_multiply(a, n):
135 | if a[1] == 0 or n == 0:
136 | return (0, 0, 1)
137 | if n == 1:
138 | return a
139 | if n < 0 or n >= N:
140 | return jacobian_multiply(a, n % N)
141 | if (n % 2) == 0:
142 | return jacobian_double(jacobian_multiply(a, n//2))
143 | if (n % 2) == 1:
144 | return jacobian_add(jacobian_double(jacobian_multiply(a, n//2)), a)
145 |
146 |
147 | def fast_multiply(a, n):
148 | return from_jacobian(jacobian_multiply(to_jacobian(a), n))
149 |
150 |
151 | def fast_add(a, b):
152 | return from_jacobian(jacobian_add(to_jacobian(a), to_jacobian(b)))
153 |
154 | # Functions for handling pubkey and privkey formats
155 |
156 |
157 | def get_pubkey_format(pub):
158 | if is_python2:
159 | two = '\x02'
160 | three = '\x03'
161 | four = '\x04'
162 | else:
163 | two = 2
164 | three = 3
165 | four = 4
166 |
167 | if isinstance(pub, (tuple, list)): return 'decimal'
168 | elif len(pub) == 65 and pub[0] == four: return 'bin'
169 | elif len(pub) == 130 and pub[0:2] == '04': return 'hex'
170 | elif len(pub) == 33 and pub[0] in [two, three]: return 'bin_compressed'
171 | elif len(pub) == 66 and pub[0:2] in ['02', '03']: return 'hex_compressed'
172 | elif len(pub) == 64: return 'bin_electrum'
173 | elif len(pub) == 128: return 'hex_electrum'
174 | else: raise Exception("Pubkey not in recognized format")
175 |
176 |
177 | def encode_pubkey(pub, formt):
178 | if not isinstance(pub, (tuple, list)):
179 | pub = decode_pubkey(pub)
180 | if formt == 'decimal': return pub
181 | elif formt == 'bin': return b'\x04' + encode(pub[0], 256, 32) + encode(pub[1], 256, 32)
182 | elif formt == 'bin_compressed':
183 | return from_int_to_byte(2+(pub[1] % 2)) + encode(pub[0], 256, 32)
184 | elif formt == 'hex': return '04' + encode(pub[0], 16, 64) + encode(pub[1], 16, 64)
185 | elif formt == 'hex_compressed':
186 | return '0'+str(2+(pub[1] % 2)) + encode(pub[0], 16, 64)
187 | elif formt == 'bin_electrum': return encode(pub[0], 256, 32) + encode(pub[1], 256, 32)
188 | elif formt == 'hex_electrum': return encode(pub[0], 16, 64) + encode(pub[1], 16, 64)
189 | else: raise Exception("Invalid format!")
190 |
191 |
192 | def decode_pubkey(pub, formt=None):
193 | if not formt: formt = get_pubkey_format(pub)
194 | if formt == 'decimal': return pub
195 | elif formt == 'bin': return (decode(pub[1:33], 256), decode(pub[33:65], 256))
196 | elif formt == 'bin_compressed':
197 | x = decode(pub[1:33], 256)
198 | beta = pow(int(x*x*x+A*x+B), int((P+1)//4), int(P))
199 | y = (P-beta) if ((beta + from_byte_to_int(pub[0])) % 2) else beta
200 | return (x, y)
201 | elif formt == 'hex': return (decode(pub[2:66], 16), decode(pub[66:130], 16))
202 | elif formt == 'hex_compressed':
203 | return decode_pubkey(safe_from_hex(pub), 'bin_compressed')
204 | elif formt == 'bin_electrum':
205 | return (decode(pub[:32], 256), decode(pub[32:64], 256))
206 | elif formt == 'hex_electrum':
207 | return (decode(pub[:64], 16), decode(pub[64:128], 16))
208 | else: raise Exception("Invalid format!")
209 |
210 | def get_privkey_format(priv):
211 | if isinstance(priv, int_types): return 'decimal'
212 | elif len(priv) == 32: return 'bin'
213 | elif len(priv) == 33: return 'bin_compressed'
214 | elif len(priv) == 64: return 'hex'
215 | elif len(priv) == 66: return 'hex_compressed'
216 | else:
217 | bin_p = b58check_to_bin(priv)
218 | if len(bin_p) == 32: return 'wif'
219 | elif len(bin_p) == 33: return 'wif_compressed'
220 | else: raise Exception("WIF does not represent privkey")
221 |
222 | def encode_privkey(priv, formt, vbyte=0):
223 | if not isinstance(priv, int_types):
224 | return encode_privkey(decode_privkey(priv), formt, vbyte)
225 | if formt == 'decimal': return priv
226 | elif formt == 'bin': return encode(priv, 256, 32)
227 | elif formt == 'bin_compressed': return encode(priv, 256, 32)+b'\x01'
228 | elif formt == 'hex': return encode(priv, 16, 64)
229 | elif formt == 'hex_compressed': return encode(priv, 16, 64)+'01'
230 | elif formt == 'wif':
231 | return bin_to_b58check(encode(priv, 256, 32), 128+int(vbyte))
232 | elif formt == 'wif_compressed':
233 | return bin_to_b58check(encode(priv, 256, 32)+b'\x01', 128+int(vbyte))
234 | else: raise Exception("Invalid format!")
235 |
236 | def decode_privkey(priv,formt=None):
237 | if not formt: formt = get_privkey_format(priv)
238 | if formt == 'decimal': return priv
239 | elif formt == 'bin': return decode(priv, 256)
240 | elif formt == 'bin_compressed': return decode(priv[:32], 256)
241 | elif formt == 'hex': return decode(priv, 16)
242 | elif formt == 'hex_compressed': return decode(priv[:64], 16)
243 | elif formt == 'wif': return decode(b58check_to_bin(priv),256)
244 | elif formt == 'wif_compressed':
245 | return decode(b58check_to_bin(priv)[:32],256)
246 | else: raise Exception("WIF does not represent privkey")
247 |
248 | def add_pubkeys(p1, p2):
249 | f1, f2 = get_pubkey_format(p1), get_pubkey_format(p2)
250 | return encode_pubkey(fast_add(decode_pubkey(p1, f1), decode_pubkey(p2, f2)), f1)
251 |
252 | def add_privkeys(p1, p2):
253 | f1, f2 = get_privkey_format(p1), get_privkey_format(p2)
254 | return encode_privkey((decode_privkey(p1, f1) + decode_privkey(p2, f2)) % N, f1)
255 |
256 |
257 | def mul_privkeys(p1, p2):
258 | f1, f2 = get_privkey_format(p1), get_privkey_format(p2)
259 | return encode_privkey((decode_privkey(p1, f1) * decode_privkey(p2, f2)) % N, f1)
260 |
261 | def multiply(pubkey, privkey):
262 | f1, f2 = get_pubkey_format(pubkey), get_privkey_format(privkey)
263 | pubkey, privkey = decode_pubkey(pubkey, f1), decode_privkey(privkey, f2)
264 | # http://safecurves.cr.yp.to/twist.html
265 | if not isinf(pubkey) and (pubkey[0]**3+B-pubkey[1]*pubkey[1]) % P != 0:
266 | raise Exception("Point not on curve")
267 | return encode_pubkey(fast_multiply(pubkey, privkey), f1)
268 |
269 |
270 | def divide(pubkey, privkey):
271 | factor = inv(decode_privkey(privkey), N)
272 | return multiply(pubkey, factor)
273 |
274 |
275 | def compress(pubkey):
276 | f = get_pubkey_format(pubkey)
277 | if 'compressed' in f: return pubkey
278 | elif f == 'bin': return encode_pubkey(decode_pubkey(pubkey, f), 'bin_compressed')
279 | elif f == 'hex' or f == 'decimal':
280 | return encode_pubkey(decode_pubkey(pubkey, f), 'hex_compressed')
281 |
282 |
283 | def decompress(pubkey):
284 | f = get_pubkey_format(pubkey)
285 | if 'compressed' not in f: return pubkey
286 | elif f == 'bin_compressed': return encode_pubkey(decode_pubkey(pubkey, f), 'bin')
287 | elif f == 'hex_compressed' or f == 'decimal':
288 | return encode_pubkey(decode_pubkey(pubkey, f), 'hex')
289 |
290 |
291 | def privkey_to_pubkey(privkey):
292 | f = get_privkey_format(privkey)
293 | privkey = decode_privkey(privkey, f)
294 | if privkey >= N:
295 | raise Exception("Invalid privkey")
296 | if f in ['bin', 'bin_compressed', 'hex', 'hex_compressed', 'decimal']:
297 | return encode_pubkey(fast_multiply(G, privkey), f)
298 | else:
299 | return encode_pubkey(fast_multiply(G, privkey), f.replace('wif', 'hex'))
300 |
301 | privtopub = privkey_to_pubkey
302 |
303 |
304 | def privkey_to_address(priv, magicbyte=0):
305 | return pubkey_to_address(privkey_to_pubkey(priv), magicbyte)
306 | privtoaddr = privkey_to_address
307 |
308 |
309 | def neg_pubkey(pubkey):
310 | f = get_pubkey_format(pubkey)
311 | pubkey = decode_pubkey(pubkey, f)
312 | return encode_pubkey((pubkey[0], (P-pubkey[1]) % P), f)
313 |
314 |
315 | def neg_privkey(privkey):
316 | f = get_privkey_format(privkey)
317 | privkey = decode_privkey(privkey, f)
318 | return encode_privkey((N - privkey) % N, f)
319 |
320 | def subtract_pubkeys(p1, p2):
321 | f1, f2 = get_pubkey_format(p1), get_pubkey_format(p2)
322 | k2 = decode_pubkey(p2, f2)
323 | return encode_pubkey(fast_add(decode_pubkey(p1, f1), (k2[0], (P - k2[1]) % P)), f1)
324 |
325 |
326 | def subtract_privkeys(p1, p2):
327 | f1, f2 = get_privkey_format(p1), get_privkey_format(p2)
328 | k2 = decode_privkey(p2, f2)
329 | return encode_privkey((decode_privkey(p1, f1) - k2) % N, f1)
330 |
331 |
332 |
333 | # Hashes
334 |
335 |
336 | def bin_hash160(string):
337 | intermed = hashlib.sha256(string).digest()
338 | digest = ''
339 | try:
340 | digest = hashlib.new('ripemd160', intermed).digest()
341 | except:
342 | digest = RIPEMD160(intermed).digest()
343 | return digest
344 |
345 |
346 | def hash160(string):
347 | return safe_hexlify(bin_hash160(string))
348 |
349 |
350 | def bin_sha256(string):
351 | binary_data = string if isinstance(string, bytes) else bytes(string, 'utf-8')
352 | return hashlib.sha256(binary_data).digest()
353 |
354 | def sha256(string):
355 | return bytes_to_hex_string(bin_sha256(string))
356 |
357 |
358 | def bin_ripemd160(string):
359 | try:
360 | digest = hashlib.new('ripemd160', string).digest()
361 | except:
362 | digest = RIPEMD160(string).digest()
363 | return digest
364 |
365 |
366 | def ripemd160(string):
367 | return safe_hexlify(bin_ripemd160(string))
368 |
369 |
370 | def bin_dbl_sha256(s):
371 | bytes_to_hash = from_string_to_bytes(s)
372 | return hashlib.sha256(hashlib.sha256(bytes_to_hash).digest()).digest()
373 |
374 |
375 | def dbl_sha256(string):
376 | return safe_hexlify(bin_dbl_sha256(string))
377 |
378 |
379 | def bin_slowsha(string):
380 | string = from_string_to_bytes(string)
381 | orig_input = string
382 | for i in range(100000):
383 | string = hashlib.sha256(string + orig_input).digest()
384 | return string
385 |
386 |
387 | def slowsha(string):
388 | return safe_hexlify(bin_slowsha(string))
389 |
390 |
391 | def hash_to_int(x):
392 | if len(x) in [40, 64]:
393 | return decode(x, 16)
394 | return decode(x, 256)
395 |
396 |
397 | def num_to_var_int(x):
398 | x = int(x)
399 | if x < 253: return from_int_to_byte(x)
400 | elif x < 65536: return from_int_to_byte(253)+encode(x, 256, 2)[::-1]
401 | elif x < 4294967296: return from_int_to_byte(254) + encode(x, 256, 4)[::-1]
402 | else: return from_int_to_byte(255) + encode(x, 256, 8)[::-1]
403 |
404 |
405 | # WTF, Electrum?
406 | def electrum_sig_hash(message):
407 | padded = b"\x18Bitcoin Signed Message:\n" + num_to_var_int(len(message)) + from_string_to_bytes(message)
408 | return bin_dbl_sha256(padded)
409 |
410 |
411 | def random_key():
412 | # Gotta be secure after that java.SecureRandom fiasco...
413 | entropy = random_string(32) \
414 | + str(random.randrange(2**256)) \
415 | + str(int(time.time() * 1000000))
416 | return sha256(entropy)
417 |
418 |
419 | def random_electrum_seed():
420 | #entropy = os.urandom(32) \ # fails in Python 3, hence copied from random_key()
421 | entropy = random_string(32) \
422 | + str(random.randrange(2**256)) \
423 | + str(int(time.time() * 1000000))
424 | return sha256(entropy)[:32]
425 |
426 | # Encodings
427 |
428 | def b58check_to_bin(inp):
429 | leadingzbytes = len(re.match('^1*', inp).group(0))
430 | data = b'\x00' * leadingzbytes + changebase(inp, 58, 256)
431 | assert bin_dbl_sha256(data[:-4])[:4] == data[-4:]
432 | return data[1:-4]
433 |
434 |
435 | def get_version_byte(inp):
436 | leadingzbytes = len(re.match('^1*', inp).group(0))
437 | data = b'\x00' * leadingzbytes + changebase(inp, 58, 256)
438 | assert bin_dbl_sha256(data[:-4])[:4] == data[-4:]
439 | return ord(data[0])
440 |
441 |
442 | def hex_to_b58check(inp, magicbyte=0):
443 | return bin_to_b58check(binascii.unhexlify(inp), magicbyte)
444 |
445 |
446 | def b58check_to_hex(inp):
447 | return safe_hexlify(b58check_to_bin(inp))
448 |
449 |
450 | def pubkey_to_address(pubkey, magicbyte=0):
451 | if isinstance(pubkey, (list, tuple)):
452 | pubkey = encode_pubkey(pubkey, 'bin')
453 | if len(pubkey) in [66, 130]:
454 | return bin_to_b58check(
455 | bin_hash160(binascii.unhexlify(pubkey)), magicbyte)
456 | return bin_to_b58check(bin_hash160(pubkey), magicbyte)
457 |
458 | pubtoaddr = pubkey_to_address
459 |
460 |
461 | def is_privkey(priv):
462 | try:
463 | get_privkey_format(priv)
464 | return True
465 | except:
466 | return False
467 |
468 | def is_pubkey(pubkey):
469 | try:
470 | get_pubkey_format(pubkey)
471 | return True
472 | except:
473 | return False
474 |
475 | def is_address(addr):
476 | ADDR_RE = re.compile("^[123mn][a-km-zA-HJ-NP-Z0-9]{26,33}$")
477 | return bool(ADDR_RE.match(addr))
478 |
479 |
480 | # EDCSA
481 |
482 |
483 | def encode_sig(v, r, s):
484 | vb, rb, sb = from_int_to_byte(v), encode(r, 256), encode(s, 256)
485 |
486 | result = base64.b64encode(vb+b'\x00'*(32-len(rb))+rb+b'\x00'*(32-len(sb))+sb)
487 | return result if is_python2 else str(result, 'utf-8')
488 |
489 |
490 | def decode_sig(sig):
491 | bytez = base64.b64decode(sig)
492 | return from_byte_to_int(bytez[0]), decode(bytez[1:33], 256), decode(bytez[33:], 256)
493 |
494 | # https://tools.ietf.org/html/rfc6979#section-3.2
495 |
496 |
497 | def deterministic_generate_k(msghash, priv):
498 | v = b'\x01' * 32
499 | k = b'\x00' * 32
500 | priv = encode_privkey(priv, 'bin')
501 | msghash = encode(hash_to_int(msghash), 256, 32)
502 | k = hmac.new(k, v+b'\x00'+priv+msghash, hashlib.sha256).digest()
503 | v = hmac.new(k, v, hashlib.sha256).digest()
504 | k = hmac.new(k, v+b'\x01'+priv+msghash, hashlib.sha256).digest()
505 | v = hmac.new(k, v, hashlib.sha256).digest()
506 | return decode(hmac.new(k, v, hashlib.sha256).digest(), 256)
507 |
508 |
509 | def ecdsa_raw_sign(msghash, priv):
510 |
511 | z = hash_to_int(msghash)
512 | k = deterministic_generate_k(msghash, priv)
513 |
514 | r, y = fast_multiply(G, k)
515 | s = inv(k, N) * (z + r*decode_privkey(priv)) % N
516 |
517 | v, r, s = 27+((y % 2) ^ (0 if s * 2 < N else 1)), r, s if s * 2 < N else N - s
518 | if 'compressed' in get_privkey_format(priv):
519 | v += 4
520 | return v, r, s
521 |
522 |
523 | def ecdsa_sign(msg, priv):
524 | v, r, s = ecdsa_raw_sign(electrum_sig_hash(msg), priv)
525 | sig = encode_sig(v, r, s)
526 | assert ecdsa_verify(msg, sig,
527 | privtopub(priv)), "Bad Sig!\t %s\nv = %d\n,r = %d\ns = %d" % (sig, v, r, s)
528 | return sig
529 |
530 |
531 | def ecdsa_raw_verify(msghash, vrs, pub):
532 | v, r, s = vrs
533 | if not (27 <= v <= 34):
534 | return False
535 |
536 | w = inv(s, N)
537 | z = hash_to_int(msghash)
538 |
539 | u1, u2 = z*w % N, r*w % N
540 | x, y = fast_add(fast_multiply(G, u1), fast_multiply(decode_pubkey(pub), u2))
541 | return bool(r == x and (r % N) and (s % N))
542 |
543 |
544 | # For BitcoinCore, (msg = addr or msg = "") be default
545 | def ecdsa_verify_addr(msg, sig, addr):
546 | assert is_address(addr)
547 | Q = ecdsa_recover(msg, sig)
548 | magic = get_version_byte(addr)
549 | return (addr == pubtoaddr(Q, int(magic))) or (addr == pubtoaddr(compress(Q), int(magic)))
550 |
551 |
552 | def ecdsa_verify(msg, sig, pub):
553 | if is_address(pub):
554 | return ecdsa_verify_addr(msg, sig, pub)
555 | return ecdsa_raw_verify(electrum_sig_hash(msg), decode_sig(sig), pub)
556 |
557 |
558 | def ecdsa_raw_recover(msghash, vrs):
559 | v, r, s = vrs
560 | if not (27 <= v <= 34):
561 | raise ValueError("%d must in range 27-31" % v)
562 | x = r
563 | xcubedaxb = (x*x*x+A*x+B) % P
564 | beta = pow(xcubedaxb, (P+1)//4, P)
565 | y = beta if v % 2 ^ beta % 2 else (P - beta)
566 | # If xcubedaxb is not a quadratic residue, then r cannot be the x coord
567 | # for a point on the curve, and so the sig is invalid
568 | if (xcubedaxb - y*y) % P != 0 or not (r % N) or not (s % N):
569 | return False
570 | z = hash_to_int(msghash)
571 | Gz = jacobian_multiply((Gx, Gy, 1), (N - z) % N)
572 | XY = jacobian_multiply((x, y, 1), s)
573 | Qr = jacobian_add(Gz, XY)
574 | Q = jacobian_multiply(Qr, inv(r, N))
575 | Q = from_jacobian(Q)
576 |
577 | # if ecdsa_raw_verify(msghash, vrs, Q):
578 | return Q
579 | # return False
580 |
581 |
582 | def ecdsa_recover(msg, sig):
583 | v,r,s = decode_sig(sig)
584 | Q = ecdsa_raw_recover(electrum_sig_hash(msg), (v,r,s))
585 | return encode_pubkey(Q, 'hex_compressed') if v >= 31 else encode_pubkey(Q, 'hex')
586 |
587 |
588 |
589 | # add/subtract
590 | def add(p1,p2):
591 | if is_privkey(p1):
592 | return add_privkeys(p1, p2)
593 | else:
594 | return add_pubkeys(p1, p2)
595 |
596 | def subtract(p1,p2):
597 | if is_privkey(p1):
598 | return subtract_privkeys(p1, p2)
599 | else:
600 | return subtract_pubkeys(p1, p2)
601 |
--------------------------------------------------------------------------------
/bitcoin/mnemonic.py:
--------------------------------------------------------------------------------
1 | import hashlib
2 | import os.path
3 | import binascii
4 | import random
5 | from bisect import bisect_left
6 |
7 | wordlist_english=list(open(os.path.join(os.path.dirname(os.path.realpath(__file__)),'english.txt'),'r'))
8 |
9 | def eint_to_bytes(entint,entbits):
10 | a=hex(entint)[2:].rstrip('L').zfill(32)
11 | print(a)
12 | return binascii.unhexlify(a)
13 |
14 | def mnemonic_int_to_words(mint,mint_num_words,wordlist=wordlist_english):
15 | backwords=[wordlist[(mint >> (11*x)) & 0x7FF].strip() for x in range(mint_num_words)]
16 | return backwords[::-1]
17 |
18 | def entropy_cs(entbytes):
19 | entropy_size=8*len(entbytes)
20 | checksum_size=entropy_size//32
21 | hd=hashlib.sha256(entbytes).hexdigest()
22 | csint=int(hd,16) >> (256-checksum_size)
23 | return csint,checksum_size
24 |
25 | def entropy_to_words(entbytes,wordlist=wordlist_english):
26 | if(len(entbytes) < 4 or len(entbytes) % 4 != 0):
27 | raise ValueError("The size of the entropy must be a multiple of 4 bytes (multiple of 32 bits)")
28 | entropy_size=8*len(entbytes)
29 | csint,checksum_size = entropy_cs(entbytes)
30 | entint=int(binascii.hexlify(entbytes),16)
31 | mint=(entint << checksum_size) | csint
32 | mint_num_words=(entropy_size+checksum_size)//11
33 |
34 | return mnemonic_int_to_words(mint,mint_num_words,wordlist)
35 |
36 | def words_bisect(word,wordlist=wordlist_english):
37 | lo=bisect_left(wordlist,word)
38 | hi=len(wordlist)-bisect_left(wordlist[:lo:-1],word)
39 |
40 | return lo,hi
41 |
42 | def words_split(wordstr,wordlist=wordlist_english):
43 | def popword(wordstr,wordlist):
44 | for fwl in range(1,9):
45 | w=wordstr[:fwl].strip()
46 | lo,hi=words_bisect(w,wordlist)
47 | if(hi-lo == 1):
48 | return w,wordstr[fwl:].lstrip()
49 | wordlist=wordlist[lo:hi]
50 | raise Exception("Wordstr %s not found in list" %(w))
51 |
52 | words=[]
53 | tail=wordstr
54 | while(len(tail)):
55 | head,tail=popword(tail,wordlist)
56 | words.append(head)
57 | return words
58 |
59 | def words_to_mnemonic_int(words,wordlist=wordlist_english):
60 | if(isinstance(words,str)):
61 | words=words_split(words,wordlist)
62 | return sum([wordlist.index(w) << (11*x) for x,w in enumerate(words[::-1])])
63 |
64 | def words_verify(words,wordlist=wordlist_english):
65 | if(isinstance(words,str)):
66 | words=words_split(words,wordlist)
67 |
68 | mint = words_to_mnemonic_int(words,wordlist)
69 | mint_bits=len(words)*11
70 | cs_bits=mint_bits//32
71 | entropy_bits=mint_bits-cs_bits
72 | eint=mint >> cs_bits
73 | csint=mint & ((1 << cs_bits)-1)
74 | ebytes=_eint_to_bytes(eint,entropy_bits)
75 | return csint == entropy_cs(ebytes)
76 |
77 | def mnemonic_to_seed(mnemonic_phrase,passphrase=b''):
78 | try:
79 | from hashlib import pbkdf2_hmac
80 | def pbkdf2_hmac_sha256(password,salt,iters=2048):
81 | return pbkdf2_hmac(hash_name='sha512',password=password,salt=salt,iterations=iters)
82 | except:
83 | try:
84 | from Crypto.Protocol.KDF import PBKDF2
85 | from Crypto.Hash import SHA512,HMAC
86 |
87 | def pbkdf2_hmac_sha256(password,salt,iters=2048):
88 | return PBKDF2(password=password,salt=salt,dkLen=64,count=iters,prf=lambda p,s: HMAC.new(p,s,SHA512).digest())
89 | except:
90 | try:
91 |
92 | from pbkdf2 import PBKDF2
93 | import hmac
94 | def pbkdf2_hmac_sha256(password,salt,iters=2048):
95 | return PBKDF2(password,salt, iterations=iters, macmodule=hmac, digestmodule=hashlib.sha512).read(64)
96 | except:
97 | raise RuntimeError("No implementation of pbkdf2 was found!")
98 |
99 | return pbkdf2_hmac_sha256(password=mnemonic_phrase,salt=b'mnemonic'+passphrase)
100 |
101 | def words_mine(prefix,entbits,satisfunction,wordlist=wordlist_english,randombits=random.getrandbits):
102 | prefix_bits=len(prefix)*11
103 | mine_bits=entbits-prefix_bits
104 | pint=words_to_mnemonic_int(prefix,wordlist)
105 | pint<<=mine_bits
106 | dint=randombits(mine_bits)
107 | count=0
108 | while(not satisfunction(entropy_to_words(eint_to_bytes(pint+dint,entbits)))):
109 | dint=randombits(mine_bits)
110 | if((count & 0xFFFF) == 0):
111 | print("Searched %f percent of the space" % (float(count)/float(1 << mine_bits)))
112 |
113 | return entropy_to_words(eint_to_bytes(pint+dint,entbits))
114 |
115 | if __name__=="__main__":
116 | import json
117 | testvectors=json.load(open('vectors.json','r'))
118 | passed=True
119 | for v in testvectors['english']:
120 | ebytes=binascii.unhexlify(v[0])
121 | w=' '.join(entropy_to_words(ebytes))
122 | seed=mnemonic_to_seed(w,passphrase='TREZOR')
123 | passed = passed and w==v[1]
124 | passed = passed and binascii.hexlify(seed)==v[2]
125 | print("Tests %s." % ("Passed" if passed else "Failed"))
126 |
127 |
128 |
--------------------------------------------------------------------------------
/bitcoin/py2specials.py:
--------------------------------------------------------------------------------
1 | import sys, re
2 | import binascii
3 | import os
4 | import hashlib
5 |
6 |
7 | if sys.version_info.major == 2:
8 | string_types = (str, unicode)
9 | string_or_bytes_types = string_types
10 | int_types = (int, float, long)
11 |
12 | # Base switching
13 | code_strings = {
14 | 2: '01',
15 | 10: '0123456789',
16 | 16: '0123456789abcdef',
17 | 32: 'abcdefghijklmnopqrstuvwxyz234567',
18 | 58: '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz',
19 | 256: ''.join([chr(x) for x in range(256)])
20 | }
21 |
22 | def bin_dbl_sha256(s):
23 | bytes_to_hash = from_string_to_bytes(s)
24 | return hashlib.sha256(hashlib.sha256(bytes_to_hash).digest()).digest()
25 |
26 | def lpad(msg, symbol, length):
27 | if len(msg) >= length:
28 | return msg
29 | return symbol * (length - len(msg)) + msg
30 |
31 | def get_code_string(base):
32 | if base in code_strings:
33 | return code_strings[base]
34 | else:
35 | raise ValueError("Invalid base!")
36 |
37 | def changebase(string, frm, to, minlen=0):
38 | if frm == to:
39 | return lpad(string, get_code_string(frm)[0], minlen)
40 | return encode(decode(string, frm), to, minlen)
41 |
42 | def bin_to_b58check(inp, magicbyte=0):
43 | if magicbyte == 0:
44 | inp = '\x00' + inp
45 | while magicbyte > 0:
46 | inp = chr(int(magicbyte % 256)) + inp
47 | magicbyte //= 256
48 | leadingzbytes = len(re.match('^\x00*', inp).group(0))
49 | checksum = bin_dbl_sha256(inp)[:4]
50 | return '1' * leadingzbytes + changebase(inp+checksum, 256, 58)
51 |
52 | def bytes_to_hex_string(b):
53 | return b.encode('hex')
54 |
55 | def safe_from_hex(s):
56 | return s.decode('hex')
57 |
58 | def from_int_representation_to_bytes(a):
59 | return str(a)
60 |
61 | def from_int_to_byte(a):
62 | return chr(a)
63 |
64 | def from_byte_to_int(a):
65 | return ord(a)
66 |
67 | def from_bytes_to_string(s):
68 | return s
69 |
70 | def from_string_to_bytes(a):
71 | return a
72 |
73 | def safe_hexlify(a):
74 | return binascii.hexlify(a)
75 |
76 | def encode(val, base, minlen=0):
77 | base, minlen = int(base), int(minlen)
78 | code_string = get_code_string(base)
79 | result = ""
80 | while val > 0:
81 | result = code_string[val % base] + result
82 | val //= base
83 | return code_string[0] * max(minlen - len(result), 0) + result
84 |
85 | def decode(string, base):
86 | base = int(base)
87 | code_string = get_code_string(base)
88 | result = 0
89 | if base == 16:
90 | string = string.lower()
91 | while len(string) > 0:
92 | result *= base
93 | result += code_string.find(string[0])
94 | string = string[1:]
95 | return result
96 |
97 | def random_string(x):
98 | return os.urandom(x)
99 |
--------------------------------------------------------------------------------
/bitcoin/py3specials.py:
--------------------------------------------------------------------------------
1 | import sys, os
2 | import binascii
3 | import hashlib
4 |
5 |
6 | if sys.version_info.major == 3:
7 | string_types = (str)
8 | string_or_bytes_types = (str, bytes)
9 | int_types = (int, float)
10 | # Base switching
11 | code_strings = {
12 | 2: '01',
13 | 10: '0123456789',
14 | 16: '0123456789abcdef',
15 | 32: 'abcdefghijklmnopqrstuvwxyz234567',
16 | 58: '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz',
17 | 256: ''.join([chr(x) for x in range(256)])
18 | }
19 |
20 | def bin_dbl_sha256(s):
21 | bytes_to_hash = from_string_to_bytes(s)
22 | return hashlib.sha256(hashlib.sha256(bytes_to_hash).digest()).digest()
23 |
24 | def lpad(msg, symbol, length):
25 | if len(msg) >= length:
26 | return msg
27 | return symbol * (length - len(msg)) + msg
28 |
29 | def get_code_string(base):
30 | if base in code_strings:
31 | return code_strings[base]
32 | else:
33 | raise ValueError("Invalid base!")
34 |
35 | def changebase(string, frm, to, minlen=0):
36 | if frm == to:
37 | return lpad(string, get_code_string(frm)[0], minlen)
38 | return encode(decode(string, frm), to, minlen)
39 |
40 | def bin_to_b58check(inp, magicbyte=0):
41 | if magicbyte == 0:
42 | inp = from_int_to_byte(0) + inp
43 | while magicbyte > 0:
44 | inp = from_int_to_byte(magicbyte % 256) + inp
45 | magicbyte //= 256
46 |
47 | leadingzbytes = 0
48 | for x in inp:
49 | if x != 0:
50 | break
51 | leadingzbytes += 1
52 |
53 | checksum = bin_dbl_sha256(inp)[:4]
54 | return '1' * leadingzbytes + changebase(inp+checksum, 256, 58)
55 |
56 | def bytes_to_hex_string(b):
57 | if isinstance(b, str):
58 | return b
59 |
60 | return ''.join('{:02x}'.format(y) for y in b)
61 |
62 | def safe_from_hex(s):
63 | return bytes.fromhex(s)
64 |
65 | def from_int_representation_to_bytes(a):
66 | return bytes(str(a), 'utf-8')
67 |
68 | def from_int_to_byte(a):
69 | return bytes([a])
70 |
71 | def from_byte_to_int(a):
72 | return a
73 |
74 | def from_string_to_bytes(a):
75 | return a if isinstance(a, bytes) else bytes(a, 'utf-8')
76 |
77 | def safe_hexlify(a):
78 | return str(binascii.hexlify(a), 'utf-8')
79 |
80 | def encode(val, base, minlen=0):
81 | base, minlen = int(base), int(minlen)
82 | code_string = get_code_string(base)
83 | result_bytes = bytes()
84 | while val > 0:
85 | curcode = code_string[val % base]
86 | result_bytes = bytes([ord(curcode)]) + result_bytes
87 | val //= base
88 |
89 | pad_size = minlen - len(result_bytes)
90 |
91 | padding_element = b'\x00' if base == 256 else b'1' \
92 | if base == 58 else b'0'
93 | if (pad_size > 0):
94 | result_bytes = padding_element*pad_size + result_bytes
95 |
96 | result_string = ''.join([chr(y) for y in result_bytes])
97 | result = result_bytes if base == 256 else result_string
98 |
99 | return result
100 |
101 | def decode(string, base):
102 | if base == 256 and isinstance(string, str):
103 | string = bytes(bytearray.fromhex(string))
104 | base = int(base)
105 | code_string = get_code_string(base)
106 | result = 0
107 | if base == 256:
108 | def extract(d, cs):
109 | return d
110 | else:
111 | def extract(d, cs):
112 | return cs.find(d if isinstance(d, str) else chr(d))
113 |
114 | if base == 16:
115 | string = string.lower()
116 | while len(string) > 0:
117 | result *= base
118 | result += extract(string[0], code_string)
119 | string = string[1:]
120 | return result
121 |
122 | def random_string(x):
123 | return str(os.urandom(x))
124 |
--------------------------------------------------------------------------------
/bitcoin/ripemd.py:
--------------------------------------------------------------------------------
1 | ## ripemd.py - pure Python implementation of the RIPEMD-160 algorithm.
2 | ## Bjorn Edstrom 16 december 2007.
3 | ##
4 | ## Copyrights
5 | ## ==========
6 | ##
7 | ## This code is a derived from an implementation by Markus Friedl which is
8 | ## subject to the following license. This Python implementation is not
9 | ## subject to any other license.
10 | ##
11 | ##/*
12 | ## * Copyright (c) 2001 Markus Friedl. All rights reserved.
13 | ## *
14 | ## * Redistribution and use in source and binary forms, with or without
15 | ## * modification, are permitted provided that the following conditions
16 | ## * are met:
17 | ## * 1. Redistributions of source code must retain the above copyright
18 | ## * notice, this list of conditions and the following disclaimer.
19 | ## * 2. Redistributions in binary form must reproduce the above copyright
20 | ## * notice, this list of conditions and the following disclaimer in the
21 | ## * documentation and/or other materials provided with the distribution.
22 | ## *
23 | ## * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24 | ## * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 | ## * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 | ## * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27 | ## * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 | ## * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 | ## * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 | ## * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 | ## * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 | ## * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 | ## */
34 | ##/*
35 | ## * Preneel, Bosselaers, Dobbertin, "The Cryptographic Hash Function RIPEMD-160",
36 | ## * RSA Laboratories, CryptoBytes, Volume 3, Number 2, Autumn 1997,
37 | ## * ftp://ftp.rsasecurity.com/pub/cryptobytes/crypto3n2.pdf
38 | ## */
39 |
40 | try:
41 | import psyco
42 | psyco.full()
43 | except ImportError:
44 | pass
45 |
46 | import sys
47 |
48 | is_python2 = sys.version_info.major == 2
49 | #block_size = 1
50 | digest_size = 20
51 | digestsize = 20
52 |
53 | try:
54 | range = xrange
55 | except:
56 | pass
57 |
58 | class RIPEMD160:
59 | """Return a new RIPEMD160 object. An optional string argument
60 | may be provided; if present, this string will be automatically
61 | hashed."""
62 |
63 | def __init__(self, arg=None):
64 | self.ctx = RMDContext()
65 | if arg:
66 | self.update(arg)
67 | self.dig = None
68 |
69 | def update(self, arg):
70 | """update(arg)"""
71 | RMD160Update(self.ctx, arg, len(arg))
72 | self.dig = None
73 |
74 | def digest(self):
75 | """digest()"""
76 | if self.dig:
77 | return self.dig
78 | ctx = self.ctx.copy()
79 | self.dig = RMD160Final(self.ctx)
80 | self.ctx = ctx
81 | return self.dig
82 |
83 | def hexdigest(self):
84 | """hexdigest()"""
85 | dig = self.digest()
86 | hex_digest = ''
87 | for d in dig:
88 | if (is_python2):
89 | hex_digest += '%02x' % ord(d)
90 | else:
91 | hex_digest += '%02x' % d
92 | return hex_digest
93 |
94 | def copy(self):
95 | """copy()"""
96 | import copy
97 | return copy.deepcopy(self)
98 |
99 |
100 |
101 | def new(arg=None):
102 | """Return a new RIPEMD160 object. An optional string argument
103 | may be provided; if present, this string will be automatically
104 | hashed."""
105 | return RIPEMD160(arg)
106 |
107 |
108 |
109 | #
110 | # Private.
111 | #
112 |
113 | class RMDContext:
114 | def __init__(self):
115 | self.state = [0x67452301, 0xEFCDAB89, 0x98BADCFE,
116 | 0x10325476, 0xC3D2E1F0] # uint32
117 | self.count = 0 # uint64
118 | self.buffer = [0]*64 # uchar
119 | def copy(self):
120 | ctx = RMDContext()
121 | ctx.state = self.state[:]
122 | ctx.count = self.count
123 | ctx.buffer = self.buffer[:]
124 | return ctx
125 |
126 | K0 = 0x00000000
127 | K1 = 0x5A827999
128 | K2 = 0x6ED9EBA1
129 | K3 = 0x8F1BBCDC
130 | K4 = 0xA953FD4E
131 |
132 | KK0 = 0x50A28BE6
133 | KK1 = 0x5C4DD124
134 | KK2 = 0x6D703EF3
135 | KK3 = 0x7A6D76E9
136 | KK4 = 0x00000000
137 |
138 | def ROL(n, x):
139 | return ((x << n) & 0xffffffff) | (x >> (32 - n))
140 |
141 | def F0(x, y, z):
142 | return x ^ y ^ z
143 |
144 | def F1(x, y, z):
145 | return (x & y) | (((~x) % 0x100000000) & z)
146 |
147 | def F2(x, y, z):
148 | return (x | ((~y) % 0x100000000)) ^ z
149 |
150 | def F3(x, y, z):
151 | return (x & z) | (((~z) % 0x100000000) & y)
152 |
153 | def F4(x, y, z):
154 | return x ^ (y | ((~z) % 0x100000000))
155 |
156 | def R(a, b, c, d, e, Fj, Kj, sj, rj, X):
157 | a = ROL(sj, (a + Fj(b, c, d) + X[rj] + Kj) % 0x100000000) + e
158 | c = ROL(10, c)
159 | return a % 0x100000000, c
160 |
161 | PADDING = [0x80] + [0]*63
162 |
163 | import sys
164 | import struct
165 |
166 | def RMD160Transform(state, block): #uint32 state[5], uchar block[64]
167 | x = [0]*16
168 | if sys.byteorder == 'little':
169 | if is_python2:
170 | x = struct.unpack('<16L', ''.join([chr(x) for x in block[0:64]]))
171 | else:
172 | x = struct.unpack('<16L', bytes(block[0:64]))
173 | else:
174 | raise "Error!!"
175 | a = state[0]
176 | b = state[1]
177 | c = state[2]
178 | d = state[3]
179 | e = state[4]
180 |
181 | #/* Round 1 */
182 | a, c = R(a, b, c, d, e, F0, K0, 11, 0, x);
183 | e, b = R(e, a, b, c, d, F0, K0, 14, 1, x);
184 | d, a = R(d, e, a, b, c, F0, K0, 15, 2, x);
185 | c, e = R(c, d, e, a, b, F0, K0, 12, 3, x);
186 | b, d = R(b, c, d, e, a, F0, K0, 5, 4, x);
187 | a, c = R(a, b, c, d, e, F0, K0, 8, 5, x);
188 | e, b = R(e, a, b, c, d, F0, K0, 7, 6, x);
189 | d, a = R(d, e, a, b, c, F0, K0, 9, 7, x);
190 | c, e = R(c, d, e, a, b, F0, K0, 11, 8, x);
191 | b, d = R(b, c, d, e, a, F0, K0, 13, 9, x);
192 | a, c = R(a, b, c, d, e, F0, K0, 14, 10, x);
193 | e, b = R(e, a, b, c, d, F0, K0, 15, 11, x);
194 | d, a = R(d, e, a, b, c, F0, K0, 6, 12, x);
195 | c, e = R(c, d, e, a, b, F0, K0, 7, 13, x);
196 | b, d = R(b, c, d, e, a, F0, K0, 9, 14, x);
197 | a, c = R(a, b, c, d, e, F0, K0, 8, 15, x); #/* #15 */
198 | #/* Round 2 */
199 | e, b = R(e, a, b, c, d, F1, K1, 7, 7, x);
200 | d, a = R(d, e, a, b, c, F1, K1, 6, 4, x);
201 | c, e = R(c, d, e, a, b, F1, K1, 8, 13, x);
202 | b, d = R(b, c, d, e, a, F1, K1, 13, 1, x);
203 | a, c = R(a, b, c, d, e, F1, K1, 11, 10, x);
204 | e, b = R(e, a, b, c, d, F1, K1, 9, 6, x);
205 | d, a = R(d, e, a, b, c, F1, K1, 7, 15, x);
206 | c, e = R(c, d, e, a, b, F1, K1, 15, 3, x);
207 | b, d = R(b, c, d, e, a, F1, K1, 7, 12, x);
208 | a, c = R(a, b, c, d, e, F1, K1, 12, 0, x);
209 | e, b = R(e, a, b, c, d, F1, K1, 15, 9, x);
210 | d, a = R(d, e, a, b, c, F1, K1, 9, 5, x);
211 | c, e = R(c, d, e, a, b, F1, K1, 11, 2, x);
212 | b, d = R(b, c, d, e, a, F1, K1, 7, 14, x);
213 | a, c = R(a, b, c, d, e, F1, K1, 13, 11, x);
214 | e, b = R(e, a, b, c, d, F1, K1, 12, 8, x); #/* #31 */
215 | #/* Round 3 */
216 | d, a = R(d, e, a, b, c, F2, K2, 11, 3, x);
217 | c, e = R(c, d, e, a, b, F2, K2, 13, 10, x);
218 | b, d = R(b, c, d, e, a, F2, K2, 6, 14, x);
219 | a, c = R(a, b, c, d, e, F2, K2, 7, 4, x);
220 | e, b = R(e, a, b, c, d, F2, K2, 14, 9, x);
221 | d, a = R(d, e, a, b, c, F2, K2, 9, 15, x);
222 | c, e = R(c, d, e, a, b, F2, K2, 13, 8, x);
223 | b, d = R(b, c, d, e, a, F2, K2, 15, 1, x);
224 | a, c = R(a, b, c, d, e, F2, K2, 14, 2, x);
225 | e, b = R(e, a, b, c, d, F2, K2, 8, 7, x);
226 | d, a = R(d, e, a, b, c, F2, K2, 13, 0, x);
227 | c, e = R(c, d, e, a, b, F2, K2, 6, 6, x);
228 | b, d = R(b, c, d, e, a, F2, K2, 5, 13, x);
229 | a, c = R(a, b, c, d, e, F2, K2, 12, 11, x);
230 | e, b = R(e, a, b, c, d, F2, K2, 7, 5, x);
231 | d, a = R(d, e, a, b, c, F2, K2, 5, 12, x); #/* #47 */
232 | #/* Round 4 */
233 | c, e = R(c, d, e, a, b, F3, K3, 11, 1, x);
234 | b, d = R(b, c, d, e, a, F3, K3, 12, 9, x);
235 | a, c = R(a, b, c, d, e, F3, K3, 14, 11, x);
236 | e, b = R(e, a, b, c, d, F3, K3, 15, 10, x);
237 | d, a = R(d, e, a, b, c, F3, K3, 14, 0, x);
238 | c, e = R(c, d, e, a, b, F3, K3, 15, 8, x);
239 | b, d = R(b, c, d, e, a, F3, K3, 9, 12, x);
240 | a, c = R(a, b, c, d, e, F3, K3, 8, 4, x);
241 | e, b = R(e, a, b, c, d, F3, K3, 9, 13, x);
242 | d, a = R(d, e, a, b, c, F3, K3, 14, 3, x);
243 | c, e = R(c, d, e, a, b, F3, K3, 5, 7, x);
244 | b, d = R(b, c, d, e, a, F3, K3, 6, 15, x);
245 | a, c = R(a, b, c, d, e, F3, K3, 8, 14, x);
246 | e, b = R(e, a, b, c, d, F3, K3, 6, 5, x);
247 | d, a = R(d, e, a, b, c, F3, K3, 5, 6, x);
248 | c, e = R(c, d, e, a, b, F3, K3, 12, 2, x); #/* #63 */
249 | #/* Round 5 */
250 | b, d = R(b, c, d, e, a, F4, K4, 9, 4, x);
251 | a, c = R(a, b, c, d, e, F4, K4, 15, 0, x);
252 | e, b = R(e, a, b, c, d, F4, K4, 5, 5, x);
253 | d, a = R(d, e, a, b, c, F4, K4, 11, 9, x);
254 | c, e = R(c, d, e, a, b, F4, K4, 6, 7, x);
255 | b, d = R(b, c, d, e, a, F4, K4, 8, 12, x);
256 | a, c = R(a, b, c, d, e, F4, K4, 13, 2, x);
257 | e, b = R(e, a, b, c, d, F4, K4, 12, 10, x);
258 | d, a = R(d, e, a, b, c, F4, K4, 5, 14, x);
259 | c, e = R(c, d, e, a, b, F4, K4, 12, 1, x);
260 | b, d = R(b, c, d, e, a, F4, K4, 13, 3, x);
261 | a, c = R(a, b, c, d, e, F4, K4, 14, 8, x);
262 | e, b = R(e, a, b, c, d, F4, K4, 11, 11, x);
263 | d, a = R(d, e, a, b, c, F4, K4, 8, 6, x);
264 | c, e = R(c, d, e, a, b, F4, K4, 5, 15, x);
265 | b, d = R(b, c, d, e, a, F4, K4, 6, 13, x); #/* #79 */
266 |
267 | aa = a;
268 | bb = b;
269 | cc = c;
270 | dd = d;
271 | ee = e;
272 |
273 | a = state[0]
274 | b = state[1]
275 | c = state[2]
276 | d = state[3]
277 | e = state[4]
278 |
279 | #/* Parallel round 1 */
280 | a, c = R(a, b, c, d, e, F4, KK0, 8, 5, x)
281 | e, b = R(e, a, b, c, d, F4, KK0, 9, 14, x)
282 | d, a = R(d, e, a, b, c, F4, KK0, 9, 7, x)
283 | c, e = R(c, d, e, a, b, F4, KK0, 11, 0, x)
284 | b, d = R(b, c, d, e, a, F4, KK0, 13, 9, x)
285 | a, c = R(a, b, c, d, e, F4, KK0, 15, 2, x)
286 | e, b = R(e, a, b, c, d, F4, KK0, 15, 11, x)
287 | d, a = R(d, e, a, b, c, F4, KK0, 5, 4, x)
288 | c, e = R(c, d, e, a, b, F4, KK0, 7, 13, x)
289 | b, d = R(b, c, d, e, a, F4, KK0, 7, 6, x)
290 | a, c = R(a, b, c, d, e, F4, KK0, 8, 15, x)
291 | e, b = R(e, a, b, c, d, F4, KK0, 11, 8, x)
292 | d, a = R(d, e, a, b, c, F4, KK0, 14, 1, x)
293 | c, e = R(c, d, e, a, b, F4, KK0, 14, 10, x)
294 | b, d = R(b, c, d, e, a, F4, KK0, 12, 3, x)
295 | a, c = R(a, b, c, d, e, F4, KK0, 6, 12, x) #/* #15 */
296 | #/* Parallel round 2 */
297 | e, b = R(e, a, b, c, d, F3, KK1, 9, 6, x)
298 | d, a = R(d, e, a, b, c, F3, KK1, 13, 11, x)
299 | c, e = R(c, d, e, a, b, F3, KK1, 15, 3, x)
300 | b, d = R(b, c, d, e, a, F3, KK1, 7, 7, x)
301 | a, c = R(a, b, c, d, e, F3, KK1, 12, 0, x)
302 | e, b = R(e, a, b, c, d, F3, KK1, 8, 13, x)
303 | d, a = R(d, e, a, b, c, F3, KK1, 9, 5, x)
304 | c, e = R(c, d, e, a, b, F3, KK1, 11, 10, x)
305 | b, d = R(b, c, d, e, a, F3, KK1, 7, 14, x)
306 | a, c = R(a, b, c, d, e, F3, KK1, 7, 15, x)
307 | e, b = R(e, a, b, c, d, F3, KK1, 12, 8, x)
308 | d, a = R(d, e, a, b, c, F3, KK1, 7, 12, x)
309 | c, e = R(c, d, e, a, b, F3, KK1, 6, 4, x)
310 | b, d = R(b, c, d, e, a, F3, KK1, 15, 9, x)
311 | a, c = R(a, b, c, d, e, F3, KK1, 13, 1, x)
312 | e, b = R(e, a, b, c, d, F3, KK1, 11, 2, x) #/* #31 */
313 | #/* Parallel round 3 */
314 | d, a = R(d, e, a, b, c, F2, KK2, 9, 15, x)
315 | c, e = R(c, d, e, a, b, F2, KK2, 7, 5, x)
316 | b, d = R(b, c, d, e, a, F2, KK2, 15, 1, x)
317 | a, c = R(a, b, c, d, e, F2, KK2, 11, 3, x)
318 | e, b = R(e, a, b, c, d, F2, KK2, 8, 7, x)
319 | d, a = R(d, e, a, b, c, F2, KK2, 6, 14, x)
320 | c, e = R(c, d, e, a, b, F2, KK2, 6, 6, x)
321 | b, d = R(b, c, d, e, a, F2, KK2, 14, 9, x)
322 | a, c = R(a, b, c, d, e, F2, KK2, 12, 11, x)
323 | e, b = R(e, a, b, c, d, F2, KK2, 13, 8, x)
324 | d, a = R(d, e, a, b, c, F2, KK2, 5, 12, x)
325 | c, e = R(c, d, e, a, b, F2, KK2, 14, 2, x)
326 | b, d = R(b, c, d, e, a, F2, KK2, 13, 10, x)
327 | a, c = R(a, b, c, d, e, F2, KK2, 13, 0, x)
328 | e, b = R(e, a, b, c, d, F2, KK2, 7, 4, x)
329 | d, a = R(d, e, a, b, c, F2, KK2, 5, 13, x) #/* #47 */
330 | #/* Parallel round 4 */
331 | c, e = R(c, d, e, a, b, F1, KK3, 15, 8, x)
332 | b, d = R(b, c, d, e, a, F1, KK3, 5, 6, x)
333 | a, c = R(a, b, c, d, e, F1, KK3, 8, 4, x)
334 | e, b = R(e, a, b, c, d, F1, KK3, 11, 1, x)
335 | d, a = R(d, e, a, b, c, F1, KK3, 14, 3, x)
336 | c, e = R(c, d, e, a, b, F1, KK3, 14, 11, x)
337 | b, d = R(b, c, d, e, a, F1, KK3, 6, 15, x)
338 | a, c = R(a, b, c, d, e, F1, KK3, 14, 0, x)
339 | e, b = R(e, a, b, c, d, F1, KK3, 6, 5, x)
340 | d, a = R(d, e, a, b, c, F1, KK3, 9, 12, x)
341 | c, e = R(c, d, e, a, b, F1, KK3, 12, 2, x)
342 | b, d = R(b, c, d, e, a, F1, KK3, 9, 13, x)
343 | a, c = R(a, b, c, d, e, F1, KK3, 12, 9, x)
344 | e, b = R(e, a, b, c, d, F1, KK3, 5, 7, x)
345 | d, a = R(d, e, a, b, c, F1, KK3, 15, 10, x)
346 | c, e = R(c, d, e, a, b, F1, KK3, 8, 14, x) #/* #63 */
347 | #/* Parallel round 5 */
348 | b, d = R(b, c, d, e, a, F0, KK4, 8, 12, x)
349 | a, c = R(a, b, c, d, e, F0, KK4, 5, 15, x)
350 | e, b = R(e, a, b, c, d, F0, KK4, 12, 10, x)
351 | d, a = R(d, e, a, b, c, F0, KK4, 9, 4, x)
352 | c, e = R(c, d, e, a, b, F0, KK4, 12, 1, x)
353 | b, d = R(b, c, d, e, a, F0, KK4, 5, 5, x)
354 | a, c = R(a, b, c, d, e, F0, KK4, 14, 8, x)
355 | e, b = R(e, a, b, c, d, F0, KK4, 6, 7, x)
356 | d, a = R(d, e, a, b, c, F0, KK4, 8, 6, x)
357 | c, e = R(c, d, e, a, b, F0, KK4, 13, 2, x)
358 | b, d = R(b, c, d, e, a, F0, KK4, 6, 13, x)
359 | a, c = R(a, b, c, d, e, F0, KK4, 5, 14, x)
360 | e, b = R(e, a, b, c, d, F0, KK4, 15, 0, x)
361 | d, a = R(d, e, a, b, c, F0, KK4, 13, 3, x)
362 | c, e = R(c, d, e, a, b, F0, KK4, 11, 9, x)
363 | b, d = R(b, c, d, e, a, F0, KK4, 11, 11, x) #/* #79 */
364 |
365 | t = (state[1] + cc + d) % 0x100000000;
366 | state[1] = (state[2] + dd + e) % 0x100000000;
367 | state[2] = (state[3] + ee + a) % 0x100000000;
368 | state[3] = (state[4] + aa + b) % 0x100000000;
369 | state[4] = (state[0] + bb + c) % 0x100000000;
370 | state[0] = t % 0x100000000;
371 |
372 | pass
373 |
374 |
375 | def RMD160Update(ctx, inp, inplen):
376 | if type(inp) == str:
377 | inp = [ord(i)&0xff for i in inp]
378 |
379 | have = int((ctx.count // 8) % 64)
380 | inplen = int(inplen)
381 | need = 64 - have
382 | ctx.count += 8 * inplen
383 | off = 0
384 | if inplen >= need:
385 | if have:
386 | for i in range(need):
387 | ctx.buffer[have+i] = inp[i]
388 | RMD160Transform(ctx.state, ctx.buffer)
389 | off = need
390 | have = 0
391 | while off + 64 <= inplen:
392 | RMD160Transform(ctx.state, inp[off:]) #<---
393 | off += 64
394 | if off < inplen:
395 | # memcpy(ctx->buffer + have, input+off, len-off);
396 | for i in range(inplen - off):
397 | ctx.buffer[have+i] = inp[off+i]
398 |
399 | def RMD160Final(ctx):
400 | size = struct.pack(" 73: return False
180 | if (sig[0] != 0x30): return False
181 | if (sig[1] != len(sig)-3): return False
182 | rlen = sig[3]
183 | if (5+rlen >= len(sig)): return False
184 | slen = sig[5+rlen]
185 | if (rlen + slen + 7 != len(sig)): return False
186 | if (sig[2] != 0x02): return False
187 | if (rlen == 0): return False
188 | if (sig[4] & 0x80): return False
189 | if (rlen > 1 and (sig[4] == 0x00) and not (sig[5] & 0x80)): return False
190 | if (sig[4+rlen] != 0x02): return False
191 | if (slen == 0): return False
192 | if (sig[rlen+6] & 0x80): return False
193 | if (slen > 1 and (sig[6+rlen] == 0x00) and not (sig[7+rlen] & 0x80)):
194 | return False
195 | return True
196 |
197 | def txhash(tx, hashcode=None):
198 | if isinstance(tx, str) and re.match('^[0-9a-fA-F]*$', tx):
199 | tx = changebase(tx, 16, 256)
200 | if hashcode:
201 | return dbl_sha256(from_string_to_bytes(tx) + encode(int(hashcode), 256, 4)[::-1])
202 | else:
203 | return safe_hexlify(bin_dbl_sha256(tx)[::-1])
204 |
205 |
206 | def bin_txhash(tx, hashcode=None):
207 | return binascii.unhexlify(txhash(tx, hashcode))
208 |
209 |
210 | def ecdsa_tx_sign(tx, priv, hashcode=SIGHASH_ALL):
211 | rawsig = ecdsa_raw_sign(bin_txhash(tx, hashcode), priv)
212 | return der_encode_sig(*rawsig)+encode(hashcode, 16, 2)
213 |
214 |
215 | def ecdsa_tx_verify(tx, sig, pub, hashcode=SIGHASH_ALL):
216 | return ecdsa_raw_verify(bin_txhash(tx, hashcode), der_decode_sig(sig), pub)
217 |
218 |
219 | def ecdsa_tx_recover(tx, sig, hashcode=SIGHASH_ALL):
220 | z = bin_txhash(tx, hashcode)
221 | _, r, s = der_decode_sig(sig)
222 | left = ecdsa_raw_recover(z, (0, r, s))
223 | right = ecdsa_raw_recover(z, (1, r, s))
224 | return (encode_pubkey(left, 'hex'), encode_pubkey(right, 'hex'))
225 |
226 | # Scripts
227 |
228 |
229 | def mk_pubkey_script(addr):
230 | # Keep the auxiliary functions around for altcoins' sake
231 | return '76a914' + b58check_to_hex(addr) + '88ac'
232 |
233 |
234 | def mk_scripthash_script(addr):
235 | return 'a914' + b58check_to_hex(addr) + '87'
236 |
237 | # Address representation to output script
238 |
239 |
240 | def address_to_script(addr):
241 | if addr[0] == '3' or addr[0] == '2':
242 | return mk_scripthash_script(addr)
243 | else:
244 | return mk_pubkey_script(addr)
245 |
246 | # Output script to address representation
247 |
248 |
249 | def script_to_address(script, vbyte=0):
250 | if re.match('^[0-9a-fA-F]*$', script):
251 | script = binascii.unhexlify(script)
252 | if script[:3] == b'\x76\xa9\x14' and script[-2:] == b'\x88\xac' and len(script) == 25:
253 | return bin_to_b58check(script[3:-2], vbyte) # pubkey hash addresses
254 | else:
255 | if vbyte in [111, 196]:
256 | # Testnet
257 | scripthash_byte = 196
258 | elif vbyte == 0:
259 | # Mainnet
260 | scripthash_byte = 5
261 | else:
262 | scripthash_byte = vbyte
263 | # BIP0016 scripthash addresses
264 | return bin_to_b58check(script[2:-1], scripthash_byte)
265 |
266 |
267 | def p2sh_scriptaddr(script, magicbyte=5):
268 | if re.match('^[0-9a-fA-F]*$', script):
269 | script = binascii.unhexlify(script)
270 | return hex_to_b58check(hash160(script), magicbyte)
271 | scriptaddr = p2sh_scriptaddr
272 |
273 |
274 | def deserialize_script(script):
275 | if isinstance(script, str) and re.match('^[0-9a-fA-F]*$', script):
276 | return json_changebase(deserialize_script(binascii.unhexlify(script)),
277 | lambda x: safe_hexlify(x))
278 | out, pos = [], 0
279 | while pos < len(script):
280 | code = from_byte_to_int(script[pos])
281 | if code == 0:
282 | out.append(None)
283 | pos += 1
284 | elif code <= 75:
285 | out.append(script[pos+1:pos+1+code])
286 | pos += 1 + code
287 | elif code <= 78:
288 | szsz = pow(2, code - 76)
289 | sz = decode(script[pos+szsz: pos:-1], 256)
290 | out.append(script[pos + 1 + szsz:pos + 1 + szsz + sz])
291 | pos += 1 + szsz + sz
292 | elif code <= 96:
293 | out.append(code - 80)
294 | pos += 1
295 | else:
296 | out.append(code)
297 | pos += 1
298 | return out
299 |
300 |
301 | def serialize_script_unit(unit):
302 | if isinstance(unit, int):
303 | if unit < 16:
304 | return from_int_to_byte(unit + 80)
305 | else:
306 | return from_int_to_byte(unit)
307 | elif unit is None:
308 | return b'\x00'
309 | else:
310 | if len(unit) <= 75:
311 | return from_int_to_byte(len(unit))+unit
312 | elif len(unit) < 256:
313 | return from_int_to_byte(76)+from_int_to_byte(len(unit))+unit
314 | elif len(unit) < 65536:
315 | return from_int_to_byte(77)+encode(len(unit), 256, 2)[::-1]+unit
316 | else:
317 | return from_int_to_byte(78)+encode(len(unit), 256, 4)[::-1]+unit
318 |
319 |
320 | if is_python2:
321 | def serialize_script(script):
322 | if json_is_base(script, 16):
323 | return binascii.hexlify(serialize_script(json_changebase(script,
324 | lambda x: binascii.unhexlify(x))))
325 | return ''.join(map(serialize_script_unit, script))
326 | else:
327 | def serialize_script(script):
328 | if json_is_base(script, 16):
329 | return safe_hexlify(serialize_script(json_changebase(script,
330 | lambda x: binascii.unhexlify(x))))
331 |
332 | result = bytes()
333 | for b in map(serialize_script_unit, script):
334 | result += b if isinstance(b, bytes) else bytes(b, 'utf-8')
335 | return result
336 |
337 |
338 | def mk_multisig_script(*args): # [pubs],k or pub1,pub2...pub[n],k
339 | if isinstance(args[0], list):
340 | pubs, k = args[0], int(args[1])
341 | else:
342 | pubs = list(filter(lambda x: len(str(x)) >= 32, args))
343 | k = int(args[len(pubs)])
344 | return serialize_script([k]+pubs+[len(pubs)]+[0xae])
345 |
346 | # Signing and verifying
347 |
348 |
349 | def verify_tx_input(tx, i, script, sig, pub):
350 | if re.match('^[0-9a-fA-F]*$', tx):
351 | tx = binascii.unhexlify(tx)
352 | if re.match('^[0-9a-fA-F]*$', script):
353 | script = binascii.unhexlify(script)
354 | if not re.match('^[0-9a-fA-F]*$', sig):
355 | sig = safe_hexlify(sig)
356 | hashcode = decode(sig[-2:], 16)
357 | modtx = signature_form(tx, int(i), script, hashcode)
358 | return ecdsa_tx_verify(modtx, sig, pub, hashcode)
359 |
360 |
361 | def sign(tx, i, priv, hashcode=SIGHASH_ALL):
362 | i = int(i)
363 | if (not is_python2 and isinstance(re, bytes)) or not re.match('^[0-9a-fA-F]*$', tx):
364 | return binascii.unhexlify(sign(safe_hexlify(tx), i, priv))
365 | if len(priv) <= 33:
366 | priv = safe_hexlify(priv)
367 | pub = privkey_to_pubkey(priv)
368 | address = pubkey_to_address(pub)
369 | signing_tx = signature_form(tx, i, mk_pubkey_script(address), hashcode)
370 | sig = ecdsa_tx_sign(signing_tx, priv, hashcode)
371 | txobj = deserialize(tx)
372 | txobj["ins"][i]["script"] = serialize_script([sig, pub])
373 | return serialize(txobj)
374 |
375 |
376 | def signall(tx, priv):
377 | # if priv is a dictionary, assume format is
378 | # { 'txinhash:txinidx' : privkey }
379 | if isinstance(priv, dict):
380 | for e, i in enumerate(deserialize(tx)["ins"]):
381 | k = priv["%s:%d" % (i["outpoint"]["hash"], i["outpoint"]["index"])]
382 | tx = sign(tx, e, k)
383 | else:
384 | for i in range(len(deserialize(tx)["ins"])):
385 | tx = sign(tx, i, priv)
386 | return tx
387 |
388 |
389 | def multisign(tx, i, script, pk, hashcode=SIGHASH_ALL):
390 | if re.match('^[0-9a-fA-F]*$', tx):
391 | tx = binascii.unhexlify(tx)
392 | if re.match('^[0-9a-fA-F]*$', script):
393 | script = binascii.unhexlify(script)
394 | modtx = signature_form(tx, i, script, hashcode)
395 | return ecdsa_tx_sign(modtx, pk, hashcode)
396 |
397 |
398 | def apply_multisignatures(*args):
399 | # tx,i,script,sigs OR tx,i,script,sig1,sig2...,sig[n]
400 | tx, i, script = args[0], int(args[1]), args[2]
401 | sigs = args[3] if isinstance(args[3], list) else list(args[3:])
402 |
403 | if isinstance(script, str) and re.match('^[0-9a-fA-F]*$', script):
404 | script = binascii.unhexlify(script)
405 | sigs = [binascii.unhexlify(x) if x[:2] == '30' else x for x in sigs]
406 | if isinstance(tx, str) and re.match('^[0-9a-fA-F]*$', tx):
407 | return safe_hexlify(apply_multisignatures(binascii.unhexlify(tx), i, script, sigs))
408 |
409 | # Not pushing empty elements on the top of the stack if passing no
410 | # script (in case of bare multisig inputs there is no script)
411 | script_blob = [] if script.__len__() == 0 else [script]
412 |
413 | txobj = deserialize(tx)
414 | txobj["ins"][i]["script"] = serialize_script([None]+sigs+script_blob)
415 | return serialize(txobj)
416 |
417 |
418 | def is_inp(arg):
419 | return len(arg) > 64 or "output" in arg or "outpoint" in arg
420 |
421 |
422 | def mktx(*args):
423 | # [in0, in1...],[out0, out1...] or in0, in1 ... out0 out1 ...
424 | ins, outs = [], []
425 | for arg in args:
426 | if isinstance(arg, list):
427 | for a in arg: (ins if is_inp(a) else outs).append(a)
428 | else:
429 | (ins if is_inp(arg) else outs).append(arg)
430 |
431 | txobj = {"locktime": 0, "version": 1, "ins": [], "outs": []}
432 | for i in ins:
433 | if isinstance(i, dict) and "outpoint" in i:
434 | txobj["ins"].append(i)
435 | else:
436 | if isinstance(i, dict) and "output" in i:
437 | i = i["output"]
438 | txobj["ins"].append({
439 | "outpoint": {"hash": i[:64], "index": int(i[65:])},
440 | "script": "",
441 | "sequence": 4294967295
442 | })
443 | for o in outs:
444 | if isinstance(o, string_or_bytes_types):
445 | addr = o[:o.find(':')]
446 | val = int(o[o.find(':')+1:])
447 | o = {}
448 | if re.match('^[0-9a-fA-F]*$', addr):
449 | o["script"] = addr
450 | else:
451 | o["address"] = addr
452 | o["value"] = val
453 |
454 | outobj = {}
455 | if "address" in o:
456 | outobj["script"] = address_to_script(o["address"])
457 | elif "script" in o:
458 | outobj["script"] = o["script"]
459 | else:
460 | raise Exception("Could not find 'address' or 'script' in output.")
461 | outobj["value"] = o["value"]
462 | txobj["outs"].append(outobj)
463 |
464 | return serialize(txobj)
465 |
466 |
467 | def select(unspent, value):
468 | value = int(value)
469 | high = [u for u in unspent if u["value"] >= value]
470 | high.sort(key=lambda u: u["value"])
471 | low = [u for u in unspent if u["value"] < value]
472 | low.sort(key=lambda u: -u["value"])
473 | if len(high):
474 | return [high[0]]
475 | i, tv = 0, 0
476 | while tv < value and i < len(low):
477 | tv += low[i]["value"]
478 | i += 1
479 | if tv < value:
480 | raise Exception("Not enough funds")
481 | return low[:i]
482 |
483 | # Only takes inputs of the form { "output": blah, "value": foo }
484 |
485 |
486 | def mksend(*args):
487 | argz, change, fee = args[:-2], args[-2], int(args[-1])
488 | ins, outs = [], []
489 | for arg in argz:
490 | if isinstance(arg, list):
491 | for a in arg:
492 | (ins if is_inp(a) else outs).append(a)
493 | else:
494 | (ins if is_inp(arg) else outs).append(arg)
495 |
496 | isum = sum([i["value"] for i in ins])
497 | osum, outputs2 = 0, []
498 | for o in outs:
499 | if isinstance(o, string_types):
500 | o2 = {
501 | "address": o[:o.find(':')],
502 | "value": int(o[o.find(':')+1:])
503 | }
504 | else:
505 | o2 = o
506 | outputs2.append(o2)
507 | osum += o2["value"]
508 |
509 | if isum < osum+fee:
510 | raise Exception("Not enough money")
511 | elif isum > osum+fee+5430:
512 | outputs2 += [{"address": change, "value": isum-osum-fee}]
513 |
514 | return mktx(ins, outputs2)
515 |
--------------------------------------------------------------------------------
/hash:
--------------------------------------------------------------------------------
1 | Hash Tables
2 |
--------------------------------------------------------------------------------
/motivation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/demining/bitcoindigger/18075cb93fff6d7e7a168d2bb93d9bb4986865e9/motivation.png
--------------------------------------------------------------------------------
/session.py:
--------------------------------------------------------------------------------
1 | import requests
2 |
3 | from tqdm import tqdm
4 |
5 | def storagespace(id, destination):
6 | def get_confirm_token(response):
7 | for key, value in response.cookies.items():
8 | if key.startswith('download_warning'):
9 | return value
10 |
11 | return None
12 |
13 | def save_response_content(response, destination):
14 | CHUNK_SIZE = 32768
15 |
16 | with open(destination, "wb") as f:
17 | with tqdm(unit='B', unit_scale=True, unit_divisor=1024) as bar:
18 | for chunk in response.iter_content(CHUNK_SIZE):
19 | if chunk:
20 | f.write(chunk)
21 | bar.update(CHUNK_SIZE)
22 |
23 | URL = "https://docs.google.com/uc?export=download"
24 |
25 | session = requests.Session()
26 |
27 | response = session.get(URL, params = { 'id' : id }, stream = True)
28 | token = get_confirm_token(response)
29 |
30 | if token:
31 | params = { 'id' : id, 'confirm' : token }
32 | response = session.get(URL, params = params, stream = True)
33 |
34 | save_response_content(response, destination)
35 |
36 |
37 | if __name__ == "__main__":
38 | import sys
39 | if len(sys.argv) is not 3:
40 | print("")
41 | else:
42 |
43 | file_id = sys.argv[1]
44 |
45 | destination = sys.argv[2]
46 | storagespace(file_id, destination)
47 |
--------------------------------------------------------------------------------
/storagespace:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/demining/bitcoindigger/18075cb93fff6d7e7a168d2bb93d9bb4986865e9/storagespace
--------------------------------------------------------------------------------