Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/mcdallas/cryptotools
https://github.com/mcdallas/cryptotools
bitcoin cryptography ecdsa elliptic-curves rsa
Last synced: 20 days ago
JSON representation
- Host: GitHub
- URL: https://github.com/mcdallas/cryptotools
- Owner: mcdallas
- License: mit
- Created: 2018-01-30T15:11:38.000Z (almost 7 years ago)
- Default Branch: master
- Last Pushed: 2024-06-29T19:34:37.000Z (6 months ago)
- Last Synced: 2024-11-13T01:35:13.650Z (about 1 month ago)
- Topics: bitcoin, cryptography, ecdsa, elliptic-curves, rsa
- Language: Python
- Size: 383 KB
- Stars: 206
- Watchers: 16
- Forks: 80
- Open Issues: 5
-
Metadata Files:
- Readme: README.rst
- License: LICENSE
Awesome Lists containing this project
- stars - mcdallas/cryptotools - (Python)
README
About this repo
---------------Barebones Python 3.6+ implementation (no dependencies/standard lib only) of some common cryptographic functions for educational purposes.
Feel free to fork the repo and play around with it. Performance is ..abysmal but otherwise it works fine. Please do not
use this for anything serious because I am not a security expert.Install
-------.. code-block:: bash
$ pip install git+https://github.com/mcdallas/cryptotools.git@master#egg=cryptotools
Examples
--------HD Wallets
.. code-block:: Python
from cryptotools.BTC import Xprv
>>> m = Xprv.from_mnemonic('impulse prize erode winner pupil fun off addict ...')
>>> m.encode()
'xprv9s21ZrQH143K38bNJiHY54kkjio8o6aw3bRjCbzi8KgRxNy98avUribz1wk85ToSUV2VwVuc73NJWc2YGwpMtqz7bBFUh9Q77RtJeuh2zvy'>>> m/44/0/0/0
Xprv(path=m/44/0/0/0, key=L1WKXyMwKnp8wPwAtjwiKWunACY5RSUXAzmS6jDRRHcHnDbeRiKu)>>> m/0./123/5. # Use floats for hardened path, alternative is // e.g m//0/123//5
Xprv(path=m/0h/123/5h, key=L3qskbdzgNu4kwjx2QU63q59khpEHVaSbqd2Pc268Jngiha6mbfQ)>>> M = m.to_xpub()
>>> (m/123/456).to_xpub() == M/123/456
True>>> (m/44./0./0./0/0).address('P2PKH') # bip44
'1BTYXdyrBh1yRCDpqyDhoQG896bnzqtaPz'>>> (m/84./0./0./0/0).address('P2WPKH') # bip84
'bc1qjnx8cq32z2t72tsmuwql3wz22lywlpcm3w52lk'BIP39 checksum
Say you lost the first of your 12 mnemonic words and you want to filter out the possible mnemonics from 2048 to 128 by veryfing the checksum
.. code-block:: Python
from cryptotools.BTC.HD import check, WORDS
phrase = "{x} decrease enjoy credit fold prepare school midnight flower wrong false already"
for word in WORDS:
mnemonic = phrase.format(x=word)
if check(mnemonic):
print(mnemonic)Sign/Verify message:
.. code-block:: Python
import secrets
from cryptotools.ECDSA.secp256k1 import generate_keypair, Messageprivate, public = generate_keypair()
>>> message = Message(secrets.token_bytes(32))
>>> sig1 = message.sign(private) # ECDSA
>>> sig2 = message.sign_schnorr(private) # Schnorr
>>> message.verify(sig1, public)
True
>>> message.verify(sig2, public)
TrueVerify a transaction:
.. code-block:: Python
from cryptotools.BTC import Transaction
tx = Transaction.get('454e575aa1ed4427985a9732d753b37dc711675eb7c977637b1eea7f600ed214')
>>> tx
Transaction(inputs=1, outputs=2)>>> tx.outputs
[Output(type=P2SH, value=0.0266 BTC),
Output(type=P2WSH, value=0.00468 BTC)]>>> tx.verify() # this runs the bitcoin script
TrueCreate a transaction and submit it automatically
.. code-block:: Python
import os
os.environ['CRYPTOTOOLS_NETWORK'] = 'test' # sets network to testnet (before library import)from cryptotools.BTC import PrivateKey, send
key = PrivateKey.from_hex('mysupersecretkey')
>>> send(source='n4SbPWR6EmQMsWaQVYYFXiJgjweGKE4XnQ', to={'n2NGrooSecJaiD6ssp4YqFoj9eZ7GrCJ66': 0.46}, fee=0.01, private=key)
'907b92969cb3a16ddb45591bf2530f177b7f10cef4e62c331596a84f66c3b8c3' # txidCreate and broadcast manually
.. code-block:: Python
import os
os.environ['CRYPTOTOOLS_NETWORK'] = 'test'from cryptotools.BTC import PrivateKey, Address
private = PrivateKey.from_hex('mysupersecretkey')
address = Address('n2NGrooSecJaiD6ssp4YqFoj9eZ7GrCJ66')>>> address.balance()
0.55>>> send_to = {'n4SbPWR6EmQMsWaQVYYFXiJgjweGKE4XnQ': 0.1, 'n2NGrooSecJaiD6ssp4YqFoj9eZ7GrCJ66': 0.4}
>>> tx = address.send(to=send_to, fee=0.05, private=private)>>> tx
Transaction(inputs=1, outputs=2)>>> tx.inputs[0].is_signed()
True>>> tx.verify() # Make sure transaction is valid before broadcasting
True>>> tx.broadcast()
'Transaction Submitted'Create keys/addresses (including segwit)
.. code-block:: Python
from cryptotools.BTC import generate_keypair, push, script_to_address, OP
private, public = generate_keypair()>>> private.hex()
'de4f177274d29f88a5805333e10525f5dd41634455dfadc8849b977802481ccd'>>> private.wif(compressed=False)
'5KWCAYLo35uZ9ibPTzTUDXESTE6ne8p1eXviYMHwaoS4tpvYCAp'>>> public.hex()
'047e30fd478b44869850352daef8f5f7a7b5233044018d465431afdc0b436c973e8df1244189d25ae73d90c90cc0f998eb9784adecaecc46e8c536d7d6845fa26e'>>> public.to_address('P2PKH')
'19dFXDxiD4KrUTNFfcgeekFpQmUC553GzW'# Simple script
>>> script = push(public.encode(compressed=True)) + OP.CHECKSIG.byte
>>> script_to_address(script, 'P2WSH')
'bc1q8yh8l8ft3220q328hlapqhflpzy6xvkq6u36mctk8gq5pyxm3rwqv5h5dg'# nested P2WSH into P2SH -- use with caution
>>> script_to_address(script, 'P2WSH-P2SH')
'34eBzenHJEdk5PK9ojuuBZvCRtNhvvysYZ'.. code-block:: Python
from cryptotools.ECDSA.secp256k1 import CURVE, PrivateKey
private = PrivateKey.random()>>> private.int()
8034465994996476238286561766373949549982328752707977290709076444881813294372>>> public = private.to_public()
>>> public
PublicKey(102868560361119050321154887315228169307787313299675114268359376451780341556078, 83001804479408277471207716276761041184203185393579361784723900699449806360826)>>> public.point in CURVE
True>>> public.to_address('P2WPKH')
'bc1qh2egksgfejqpktc3kkdtuqqrukrpzzp9lr0phn'Configuration
--------By default the library communicates with the bitcoin network (for fetching transactions) via a block
explorer but as an alternative you can use a bitcoin node via it's RPC interface. Just set the following
enviromental variables.. code-block:: bash
CRYPTOTOOLS_BACKEND=rpc
CRYPTOTOOLS_RPC_HOST=localhost
CRYPTOTOOLS_RPC_PORT=8332and optionally
.. code-block:: bash
CRYPTOTOOLS_RPC_USER=myuser
CRYPTOTOOLS_RPC_PW=mypasswordto switch the network to Testnet set
.. code-block:: bash
CRYPTOTOOLS_NETWORK=test
to run tests
.. code-block:: bash
$ python -m unittest
from the project directory