identity

This modules provides cryptographic primitives to interact with blockchain.

>>> from mainsail import identity

KeyRing Objects

class KeyRing(cSecp256k1.KeyRing)

Subclass of cSecp256K1.KeyRing allowing secure filesystem saving and loading. It is also linked to mainsail network configuration to select appropriate Schnorr signature specification (bcrypto 4.10 or BIP 340) to be applied.

>>> import os
>>> signer = identity.KeyRing.create(int.from_bytes(os.urandom(32)))
>>> signer  # KeyRing is a subclass of builtin int
40367812022907163119325945335177282621496014100307111368749805816184299969919
>>> sig = signer.sign("simple message")
>>> puk = signer.puk()  # compute associated public key
>>> signer.verify(puk, "simple message", sig)
True
>>> type(signer)  # bcrypto 4.10 specification used
<class 'mainsail.identity.Bcrpt410'>

KeyRing.dump

def dump(pin: Union[bytes, List[int]]) -> None

Securely dump KeyRing into filesystem using pin code. Override existing file if any.

Arguments:

  • pin bytes|List[int] - pin code used to _encrypt KeyRing. Pin code may be a list of short (0 < int < 255) or a bytes string.
>>> signer.dump([0, 0, 0, 0])  # dump into filesystem using pin 0000
>>> signer.dump(b"\x00\x00\x00\x00")  # equivalent

KeyRing.load

@staticmethod
def load(pin: Union[bytes, List[int]])

Securely load KeyRing from filesystem using pin code.

Arguments:

  • pin bytes|List[int] - pin code used to _encrypt KeyRing. Pin code may be a list of short (0 < int < 255) or a bytes string.

Returns:

  • Schnorr|Bcrpt410 - signer object.
>>> identity.KeyRing.load([0, 0, 0, 0])
40367812022907163119325945335177282621496014100307111368749805816184299969919
>>> identity.KeyRing.load(b"\x00\x00\x00\x00")
40367812022907163119325945335177282621496014100307111368749805816184299969919

KeyRing.create

@staticmethod
def create(obj: int = None)

Create a KeyRing signer subclass with the appropriate schnorr signature specification.

Arguments:

  • obj int - the value of the private key.

Returns:

  • Schnorr|Bcrpt410 - signer object.

get_signer

def get_signer()

Returns the the network appropriate signer.

bip39_hash

def bip39_hash(secret: str, passphrase: str = "") -> bytes

Returns bip39 hash bytes string. This function does not check mnemonic integrity.

Arguments:

  • secret str - a mnemonic string.
  • passphrase str - salt string.

Returns:

  • bytes - 64 length bytes string.

sign

def sign(data: Union[str, bytes],
         prk: Union[KeyRing, List[int], str, int] = None,
         format: str = "raw") -> str

Compute Schnorr signature from data using private key according to bcrypto 4.10 spec or BIP340 specification. Signature format is RAW by defaul but can also be specified a DER.

>>> prk = identity.KeyRing.load([0,0,0,0])
>>> identity.sign("simple message", [0, 0, 0, 0])
'5993cfb3d7dafdfe58a29e0dfc9ef332acc7bb1429ba720b20e7ea6b4a961dd0026ed229f5095581188816bf120bcad0d25cdada03a3add04bd539ab2ba3becb'
>>> identity.sign("simple message", prk)
'5993cfb3d7dafdfe58a29e0dfc9ef332acc7bb1429ba720b20e7ea6b4a961dd0026ed229f5095581188816bf120bcad0d25cdada03a3add04bd539ab2ba3becb'
>>> identity.sign("simple message", 40367812022907163119325945335177282621496014100307111368749805816184299969919)
'5993cfb3d7dafdfe58a29e0dfc9ef332acc7bb1429ba720b20e7ea6b4a961dd0026ed229f5095581188816bf120bcad0d25cdada03a3add04bd539ab2ba3becb'
>>> identity.sign("simple message", prk, "der")
'304402205993cfb3d7dafdfe58a29e0dfc9ef332acc7bb1429ba720b20e7ea6b4a961dd00220026ed229f5095581188816bf120bcad0d25cdada03a3add04bd539ab2ba3becb'

Arguments:

  • data str|bytes - data used for signature computation.
  • prk KeyRing|List[int]|str|int - private key, keyring or pin code.
  • format str - raw or der to determine signature format output.

Returns:

  • str - Schnorr signature in raw format (ie r | s) by default.

user_keys

def user_keys(secret: Union[int, str]) -> dict

Generate keyring containing secp256k1 keys-pair and wallet import format (WIF).

Arguments:

  • secret str|int - anything that could issue a private key on secp256k1 curve.

Returns:

  • dict - public, private and WIF keys.

wif_keys

def wif_keys(seed: bytes) -> Union[str, None]

Compute WIF key from seed.

Arguments:

  • seed bytes - a 32 length bytes string.

Returns:

  • str - the WIF key.