multisig HMAC
Project description
multisig-hmac
Multisig scheme for HMAC authentication. Python implementation of multisig-hmac.
Usage
Key management can happen in either of two modes, either by storing every of the component keys, or by storing a single master seed and using that to derive keys ad hoc.
The following two examples return true when they are executed, for example inside a virtual environment.
Using stored keys:
import multisig_hmac
from multisig_hmac.multisig_hmac import MultisigHMAC
import base64
m = MultisigHMAC()
# generate keys which need to be stored securely and need to be shared securely with each party
k0 = m.keygen(0)
k1 = m.keygen(1)
k2 = m.keygen(2)
# sign by each client
data = b'hello world'
s0 = m.sign(k0, data)
s2 = m.sign(k2, data)
# combine the used signatures
out = m.combine([s0, s2])
sent = (out[0], base64.urlsafe_b64encode(out[1]))
# --- network ---
received = (sent[0], base64.urlsafe_b64decode(sent[1]))
# verify on the server
threshold = 2
keys = [k0, k1, k2]
signature = received
print(m.verify(keys, signature, data, threshold))
Using a derived master key:
import multisig_hmac
from multisig_hmac.multisig_hmac import MultisigHMAC
import base64
m = MultisigHMAC()
# generate a master seed which needs to be stored securely
# this seed must NOT be shared with any other party
seed = m.seedgen()
k0 = m.deriveKey(seed, 0)
k1 = m.deriveKey(seed, 1)
k2 = m.deriveKey(seed, 2)
# sign by each client
data = b'hello world'
s0 = m.sign(k0, data)
s2 = m.sign(k2, data)
# combine the used signatures
out = m.combine([s0, s2])
sent = (out[0], base64.urlsafe_b64encode(out[1]))
# --- network ---
received = (sent[0], base64.urlsafe_b64decode(sent[1]))
# verify on the server, but now keys are dynamically derived
threshold = 2
signature = received
print(m.verifyDerived(seed, signature, data, threshold))
API
Constants
MultisigHMAC.BYTESsignature length in bytes (default)MultisigHMAC.KEYBYTESkey length in bytes (default)MultisigHMAC.PRIMITIVEissha256(default)
So far, the implementation supports the following specific algorithms:
MultisigHMAC.SHA256_BYTESsignature length in bytesMultisigHMAC.SHA256_KEYBYTESkey length in bytesMultisigHMAC.SHA256_PRIMITIVEissha256MultisigHMAC.SHA512_BYTESsignature length in bytesMultisigHMAC.SHA512_KEYBYTESkey length in bytesMultisigHMAC.SHA512_PRIMITIVEissha512MultisigHMAC.SHA384_BYTESsignature length in bytesMultisigHMAC.SHA384_KEYBYTESkey length in bytesMultisigHMAC.SHA384_PRIMITIVEissha384
n = MultisigHMAC.popcount(bitfield)
Returns the number of keys (i.e. high bits) in bitfield. bitfield must be a 32-bit unsigned integer. Example:
assert MultisigHMAC.popcount(5) == 2
xs = MultisigHMAC.keyIndexes(bitfield)
Returns the indexes of the keys (i.e. high bits) in bitfield as a list. bitfield must be a 32-bit unsigned integer. Example:
assert MultisigHMAC.keyIndexes(5) == [0,2]
m = MultisigHMAC([alg = MultisigHMAC.PRIMITIVE])
Creates a new instance of MultisigHMAC which can be used as a global singleton. Just sets the algorithm to be used for subsequent methods and associated constants. Example:
m = MultisigHMAC()
assert (m.popcount(5) == 2 and m.keyIndexes(5) == [0,2])
key = MultisigHMAC.keygen(index)
Generates a new cryptographically random key. The function returns { index: 32-bit unsigned integer, key: bytes of length KEYBYTES }.
Note: index should be counted from 0.
masterSeed = MultisigHMAC.seedgen()
Generates a new cryptographically random master seed.
key = MultisigHMAC.deriveKey(masterSeed, index)
Derives a new subkey from a master seed. index must be a 32-bit unsigned integer, but in practice you want to keep a much lower number, as the bitfield used with the signature has as many bits as the largest index. The function returns { index: 32-bit unsigned integer, key: bytes of length KEYBYTES }.
Note: index should be counted from 0.
Keys are derived using a KDF based on HMAC:
b[0...BYTES] = HMAC(Key = masterSeed, data = 'derive' || U32LE(index) || 0x00)
b[BYTES...] = HMAC(Key = masterSeed, b[0...BYTES] || 0x01)
signature = MultisigHMAC.sign(key, data)
Independently signs data with key. The function returns { bitfield: 32-bit unsigned integer, signature: bytes of length BYTES }. This object can be passed to the combine() function explained below.
signature = MultisigHMAC.combine([signatures...])
Combines a list of signatures which have all been signed independently. Only include each signature once, otherwise they will cancel out. Signatures can be combined in any order. The function returns { bitfield: 32-bit unsigned integer, signature: bytearray of length BYTES }.
valid = MultisigHMAC.verify(keys, signature, data, threshold)
Verifies a signature of data against a list of keys, over a given threshold. keys must be an array of keys. The function returns True or False.
valid = MultisigHMAC.verifyDerived(masterSeed, signature, data, threshold)
Verifies a signature of data against dynamically derived keys from masterSeed, over a given threshold. masterSeed must be bytes of length KEYBYTES. The function returns True or False.
Installation
$ pip install multisig-hmac
Running tests
$ pip install -U pytest
$ py.test
License
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 multisig-hmac-0.2.4.tar.gz.
File metadata
- Download URL: multisig-hmac-0.2.4.tar.gz
- Upload date:
- Size: 6.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.22.0 setuptools/45.2.0 requests-toolbelt/0.9.1 tqdm/4.36.1 CPython/3.7.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3f2770f845070917dd331d201376f4919229dd1809e4cc98da522bf9eb44d370
|
|
| MD5 |
314662f4754bf0f5eeefaed92bb290fb
|
|
| BLAKE2b-256 |
e347e3364e7b41dd140eeb42977b77dbd60fe33e537b3e0e5f2f796fb28f10c3
|
File details
Details for the file multisig_hmac-0.2.4-py3-none-any.whl.
File metadata
- Download URL: multisig_hmac-0.2.4-py3-none-any.whl
- Upload date:
- Size: 8.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.22.0 setuptools/45.2.0 requests-toolbelt/0.9.1 tqdm/4.36.1 CPython/3.7.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bc1d810022d6d30367a7626dfa42b160e9b1b804ff88242d7323cb4f826dce82
|
|
| MD5 |
2fba438d9ff34136d5411c527bb75418
|
|
| BLAKE2b-256 |
c7909dfad1435a629874e4d4f5acd6ab7331b55bfbc41455b218ec1e9226e138
|