Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

multisig-hmac

Package Overview
Dependencies
Maintainers
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

multisig-hmac

multisig HMAC

  • 0.2.4
  • PyPI
  • Socket score

Maintainers
1

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.BYTES signature length in bytes (default)
  • MultisigHMAC.KEYBYTES key length in bytes (default)
  • MultisigHMAC.PRIMITIVE is sha256 (default)

So far, the implementation supports the following specific algorithms:

  • MultisigHMAC.SHA256_BYTES signature length in bytes
  • MultisigHMAC.SHA256_KEYBYTES key length in bytes
  • MultisigHMAC.SHA256_PRIMITIVE is sha256
  • MultisigHMAC.SHA512_BYTES signature length in bytes
  • MultisigHMAC.SHA512_KEYBYTES key length in bytes
  • MultisigHMAC.SHA512_PRIMITIVE is sha512
  • MultisigHMAC.SHA384_BYTES signature length in bytes
  • MultisigHMAC.SHA384_KEYBYTES key length in bytes
  • MultisigHMAC.SHA384_PRIMITIVE is sha384

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

ISC

FAQs


Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc