keypair from secret

This commit is contained in:
diminator 2017-03-21 15:26:57 +01:00
parent 43f779a18b
commit b8d70f34d3
No known key found for this signature in database
GPG Key ID: C3D8590E6D0D439A
2 changed files with 58 additions and 3 deletions

View File

@ -1,10 +1,10 @@
# Separate all crypto code so that we can easily test several implementations # Separate all crypto code so that we can easily test several implementations
from collections import namedtuple from collections import namedtuple
import nacl.signing
import sha3 import sha3
from cryptoconditions import crypto from cryptoconditions import crypto
CryptoKeypair = namedtuple('CryptoKeypair', ('private_key', 'public_key')) CryptoKeypair = namedtuple('CryptoKeypair', ('private_key', 'public_key'))
@ -13,8 +13,46 @@ def hash_data(data):
return sha3.sha3_256(data.encode()).hexdigest() return sha3.sha3_256(data.encode()).hexdigest()
def generate_key_pair(): class Ed25519SigningKeyFromHash(crypto.Ed25519SigningKey):
def __init__(self, key, encoding='base58'):
super().__init__(key, encoding=encoding)
@classmethod
def generate(cls, hash_bytes):
return cls(nacl.signing.SigningKey(hash_bytes).encode(encoder=crypto.Base58Encoder))
def ed25519_generate_key_pair_from_secret(secret):
"""
Generate a new key pair.
Args:
secret (:class:`string`): A secret that serves as a seed
Returns:
A tuple of (private_key, public_key) encoded in base58.
"""
# if you want to do this correctly, use a key derivation function!
if not isinstance(secret, bytes):
secret = secret.encode()
hash_bytes = sha3.keccak_256(secret).digest()
sk = Ed25519SigningKeyFromHash.generate(hash_bytes=hash_bytes)
# Private key
private_value_base58 = sk.encode(encoding='base58')
# Public key
public_value_compressed_base58 = sk.get_verifying_key().encode(encoding='base58')
return private_value_base58, public_value_compressed_base58
def generate_key_pair(secret=None):
"""Generates a cryptographic key pair. """Generates a cryptographic key pair.
Args:
secret (:class:`string`): A secret that serves as a seed
Returns: Returns:
:class:`~bigchaindb.common.crypto.CryptoKeypair`: A :class:`~bigchaindb.common.crypto.CryptoKeypair`: A
@ -23,9 +61,13 @@ def generate_key_pair():
:attr:`~bigchaindb.common.crypto.CryptoKeypair.public_key`. :attr:`~bigchaindb.common.crypto.CryptoKeypair.public_key`.
""" """
if secret:
keypair_raw = ed25519_generate_key_pair_from_secret(secret)
else:
keypair_raw = crypto.ed25519_generate_key_pair()
# TODO FOR CC: Adjust interface so that this function becomes unnecessary # TODO FOR CC: Adjust interface so that this function becomes unnecessary
return CryptoKeypair( return CryptoKeypair(
*(k.decode() for k in crypto.ed25519_generate_key_pair())) *(k.decode() for k in keypair_raw))
PrivateKey = crypto.Ed25519SigningKey PrivateKey = crypto.Ed25519SigningKey

View File

@ -0,0 +1,13 @@
def test_crypto_keypair():
from bigchaindb.common.crypto import generate_key_pair
secret = 'much secret'
keypair = generate_key_pair(secret=secret)
assert len(keypair.public_key) == len(generate_key_pair().public_key)
# TODO: 43 !== 44 -> need to check why
# assert len(keypair.private_key) == len(generate_key_pair().private_key)
assert keypair.public_key == generate_key_pair(secret).public_key
assert keypair.private_key == generate_key_pair(secret).private_key