mirror of
https://github.com/JoinMarket-Org/joinmarket-clientserver.git
synced 2026-08-18 13:17:51 +02:00
99 lines
2.4 KiB
Python
99 lines
2.4 KiB
Python
from __future__ import absolute_import, print_function
|
|
|
|
# A wrapper for public key
|
|
# authenticated encryption
|
|
# using Diffie Hellman key
|
|
# exchange to set up a
|
|
# symmetric encryption.
|
|
|
|
import binascii
|
|
import base64
|
|
import string
|
|
import random
|
|
|
|
|
|
from libnacl import public
|
|
|
|
class NaclError(Exception):
|
|
pass
|
|
|
|
def init_keypair(fname=None):
|
|
"""Create a new encryption
|
|
keypair; stored in file fname
|
|
if provided. The keypair object
|
|
is returned.
|
|
"""
|
|
kp = public.SecretKey()
|
|
if fname:
|
|
# Note: handles correct file permissions
|
|
kp.save(fname)
|
|
return kp
|
|
|
|
|
|
# the next two functions are useful
|
|
# for exchaging pubkeys with counterparty
|
|
def get_pubkey(kp, as_hex=False):
|
|
"""Given a keypair object,
|
|
return its public key,
|
|
optionally in hex."""
|
|
if not isinstance(kp, public.SecretKey):
|
|
raise NaclError("Object is not a nacl keypair")
|
|
return kp.hex_pk() if as_hex else kp.pk
|
|
|
|
|
|
def init_pubkey(hexpk, fname=None):
|
|
"""Create a pubkey object from a
|
|
hex formatted string.
|
|
Save to file fname if specified.
|
|
"""
|
|
try:
|
|
bin_pk = binascii.unhexlify(hexpk)
|
|
except TypeError:
|
|
raise NaclError("Invalid hex")
|
|
if not len(bin_pk) == 32:
|
|
raise NaclError("Public key must be 32 bytes")
|
|
pk = public.PublicKey(binascii.unhexlify(hexpk))
|
|
if fname:
|
|
pk.save(fname)
|
|
return pk
|
|
|
|
|
|
def as_init_encryption(kp, c_pk):
|
|
"""Given an initialised
|
|
keypair kp and a counterparty
|
|
pubkey c_pk, create a Box
|
|
ready for encryption/decryption.
|
|
"""
|
|
if not isinstance(c_pk, public.PublicKey):
|
|
raise NaclError("Object is not a public key")
|
|
if not isinstance(kp, public.SecretKey):
|
|
raise NaclError("Object is not a nacl keypair")
|
|
return public.Box(kp.sk, c_pk)
|
|
|
|
|
|
'''
|
|
After initialisation, it's possible
|
|
to use the box object returned from
|
|
as_init_encryption to directly change
|
|
from plaintext to ciphertext:
|
|
ciphertext = box.encrypt(plaintext)
|
|
plaintext = box.decrypt(ciphertext)
|
|
Notes:
|
|
1. use binary format for ctext/ptext
|
|
2. Nonce is handled at the implementation layer.
|
|
'''
|
|
|
|
|
|
# TODO: Sign, verify. At the moment we are using
|
|
# bitcoin signatures so it isn't necessary.
|
|
|
|
|
|
# encoding for passing over the wire
|
|
def encrypt_encode(msg, box):
|
|
encrypted = box.encrypt(msg)
|
|
return base64.b64encode(encrypted)
|
|
|
|
|
|
def decode_decrypt(msg, box):
|
|
decoded = base64.b64decode(msg)
|
|
return box.decrypt(decoded)
|