A tiny library to perform potentially unsafe cryptography with arithmetic operations on elliptic curves in pure micropython.
Project description
utinyec
A tiny library to perform potentially unsafe cryptography with arithmetic operations on elliptic curves in pure micropython. No dependencies.
This is not a library suitable for production. It is useful for security professionals to understand the inner workings of EC, and be able to play with pre-defined curves. No really, this module has not been tested for vulnerabilities. It should never be used in production. I am not accountable for what you choose to do with this module.
utinyec shows the mathematics behind eliptical curve cryptography (ECC) in pure python which is useful for educational purposes. C based solutions with python API can be compiled from these two libraries: ucryptography or ucrypto, they use C for the cryptography which is MUCH faster than pure python.
If you want to convert this from micropython to regular python then change "from uos import urandom" to "from os import urandom" in both ec.py AND cryptography.py, then change 'from ucryptolib import aes' to 'from cryptolib import aes' in cryptography.py. This package is very slow, and possibly unsafe as it has not been audited; if you need a cryptography solution in regular python please use pip install cryptography, or if you are using android you need to use 'apt install python-cryptography' as the rust dependency is dropped for functionality in Termux.
installation in Micropython
pip install utinyec
In Thonny you can find it in Tools -> Manage Packages, then search for utinyec.
usage
#Must be micropython, not regular python.
from utinyec import registry as reg
from utinyec.cryptography import uECcrypto
from utinyec import ec as tinyec
specified_private_key_int = None #use a previous ecc_session.get_private_key_int() in here to use the same key pair
curve_name = 'secp256r1' #see registry.py for a list of curve names
ecc_session = uECcrypto(curve_name, specified_private_key_int) #
#now we will generate a public_key position (x and y coordinates) which will represent the "other" public key being given to us
curve = reg.get_curve(curve_name)
keypair, other_public_key = tinyec.make_keypair(curve)
plaintext = 'This is AES cryptographic'
encrypted_cbc = ecc_session.encrypt(plaintext, other_public_key, "CBC")
decrypted_cbc = ecc_session.decrypt(encrypted_cbc, other_public_key, "CBC")
print('private_key:', ecc_session.keypair.priv)
print('public_key:', f"x{ecc_session.keypair.pub.x}y{ecc_session.keypair.pub.y}")
print('other_public_key:', other_public_key)
print('AES-CBC encrypted:', encrypted_cbc)
print('AES-CBC decrypted:', decrypted_cbc.strip())
PEM formatting
Using regular python (not micropython) you can use the cryptography module to convert from coordinate to standard PEM, or reverse. Conversion may be useful when communicating with non-microcontroller devices, as devices using regular python can convert public keys to coordinates before sending them. I do not know of a method to convert formats within micropython, and such a method is outside my personal use case for this project. Send the github repository a pull request if you write one!
converting to and from PEM format
#REGULAR python, NOT micropython
#I provide some public key coordinates for this example, but you should derive your own from the uECCrypto class
public_key_coordinates = (27080695663519936575286139140947921079432612852248858477930157300769994068404, 89650813448058425836500999002714743992773189021923677962194438343503940101997)
#the previous line is an EXAMPLE set of coordinates, you should use your own, see the next couple of lines which shows you where to get them
#public_key_coordinates = (ecc_session.keypair.pub.x, ecc_session.keypair.pub.y)
#public_key_coordinates = ecc_session.get_public_key()
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import ec
def get_pem_from_ecc_coordinates(public_key_coordinates):
#define curve SECP256R1 (for example)
curve = ec.SECP256R1()
x_coordinate, y_coordinate = public_key_coordinates
#create public key object
ec_public_key = ec.EllipticCurvePublicNumbers(x_coordinate, y_coordinate, curve).public_key()
#serialize public key to PEM format
return ec_public_key.public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo
)
def get_ecc_coordinates_from_pem(pem_data):
# deserialize PEM data to public key object
ec_public_key = serialization.load_pem_public_key(pem_data)
# extract public numbers from the public key
public_numbers = ec_public_key.public_numbers()
# return x and y coordinates
return (public_numbers.x, public_numbers.y)
#USAGE:
print("original coordinates:", public_key_coordinates)
#convert to PEM
pem = get_pem_from_ecc_coordinates(public_key_coordinates)
print("derived PEM:", pem.decode('utf-8')) #decode bytes to string format
#and convert back to coordinates
processed_public_key_coordinates = get_ecc_coordinates_from_pem(pem) #pem is given as bytes by the way, not a string!
print("derived coordinates:", public_key_coordinates)
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file utinyec-0.4.3.tar.gz.
File metadata
- Download URL: utinyec-0.4.3.tar.gz
- Upload date:
- Size: 27.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.11.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eaac0219bf78dc996707e909409c383f1073fb8b733522de4d9e52244ec57949
|
|
| MD5 |
f2ccefa1d6ae1aca62c5e60f88b943c2
|
|
| BLAKE2b-256 |
84957b2f6f6aa7efb68df6d6762cdfc3899b03b0cd8e366e2f6005326ff1acfe
|
File details
Details for the file utinyec-0.4.3-py3-none-any.whl.
File metadata
- Download URL: utinyec-0.4.3-py3-none-any.whl
- Upload date:
- Size: 23.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.11.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
68e1fd1faec9327f41b040bfa601536942020f7791621caab0b9a06840f67a94
|
|
| MD5 |
4db57fcc6e0ad2eae5572b266c7d03de
|
|
| BLAKE2b-256 |
7dc04708feb9c0ab56f11130fdb751362b0179af9b55551583302d6fb1b52ce0
|