refactor ed25519 a little; only _string variants, not _bytes of deserializers and some imports

This commit is contained in:
meejah 2019-06-24 15:31:34 -06:00
parent e5b892d700
commit 05f6b7fea0
4 changed files with 29 additions and 44 deletions

View File

@ -53,19 +53,6 @@ def create_signing_keypair():
return private_key, private_key.public_key() return private_key, private_key.public_key()
def signing_keypair_from_bytes(private_bytes):
"""
Creates a ed25519 keypair from serialized bytes
:returns: 2-tuple of (private_key, public_key)
"""
if not isinstance(private_bytes, six.binary_type):
raise ValueError('private_bytes must be bytes')
private_key = Ed25519PrivateKey.from_private_bytes(private_bytes)
return private_key, private_key.public_key()
def bytes_from_signing_key(private_key): def bytes_from_signing_key(private_key):
""" """
Turn a private signing key into serialized bytes Turn a private signing key into serialized bytes
@ -92,7 +79,7 @@ def sign_data(private_key, data):
:param private_key: the private part returned from :param private_key: the private part returned from
`create_signing_keypair` or from `create_signing_keypair` or from
`signing_keypair_from_bytes` `signing_keypair_from_string`
:param bytes data: the data to sign :param bytes data: the data to sign
@ -107,11 +94,11 @@ def sign_data(private_key, data):
def string_from_signing_key(private_key): def string_from_signing_key(private_key):
""" """
Encode a private key to a string Encode a private key to a string of unicode
:param private_key: the private part returned from :param private_key: the private part returned from
`create_signing_keypair` or from `create_signing_keypair` or from
`signing_keypair_from_bytes` `signing_keypair_from_string`
:returns: string representing this key :returns: string representing this key
""" """
@ -119,27 +106,21 @@ def string_from_signing_key(private_key):
return PRIVATE_KEY_PREFIX + b2a(bytes_from_signing_key(private_key)) return PRIVATE_KEY_PREFIX + b2a(bytes_from_signing_key(private_key))
def signing_keypair_from_string(private_key_str): def signing_keypair_from_string(private_key_bytes):
""" """
Load a signing keypair from a string Load a signing keypair from a string of bytes (which includes the
PRIVATE_KEY_PREFIX)
:returns: a 2-tuple of (private_key, public_key) :returns: a 2-tuple of (private_key, public_key)
""" """
return signing_keypair_from_bytes( if not isinstance(private_key_bytes, six.binary_type):
a2b(remove_prefix(private_key_str, PRIVATE_KEY_PREFIX)) raise ValueError('private_key_bytes must be bytes')
private_key = Ed25519PrivateKey.from_private_bytes(
a2b(remove_prefix(private_key_bytes, PRIVATE_KEY_PREFIX))
) )
return private_key, private_key.public_key()
def verifying_key_from_bytes(public_key_bytes):
"""
Load a verifying key from bytes
:returns: a public_key
"""
if not isinstance(public_key_bytes, six.binary_type):
raise ValueError('public_key_bytes must be bytes')
return Ed25519PublicKey.from_public_bytes(public_key_bytes)
def bytes_from_verifying_key(public_key): def bytes_from_verifying_key(public_key):
@ -148,7 +129,7 @@ def bytes_from_verifying_key(public_key):
:param public_key: the public part of a key returned from :param public_key: the public part of a key returned from
`create_signing_keypair` or from `create_signing_keypair` or from
`signing_keypair_from_bytes` `signing_keypair_from_string`
:returns: bytes representing this key :returns: bytes representing this key
""" """
@ -184,14 +165,18 @@ def verify_signature(public_key, alleged_signature, data):
raise BadSignature() raise BadSignature()
def verifying_key_from_string(public_key_str): def verifying_key_from_string(public_key_bytes):
""" """
Load a verifying key from a string Load a verifying key from a string of bytes (which includes the
PUBLIC_KEY_PREFIX)
:returns: a public_key :returns: a public_key
""" """
return verifying_key_from_bytes( if not isinstance(public_key_bytes, six.binary_type):
a2b(remove_prefix(public_key_str, PUBLIC_KEY_PREFIX)) raise ValueError('public_key_bytes must be bytes')
return Ed25519PublicKey.from_public_bytes(
a2b(remove_prefix(public_key_bytes, PUBLIC_KEY_PREFIX))
) )

View File

@ -1,6 +1,6 @@
import re import re
import json import json
from allmydata import crypto from allmydata.crypto.util import remove_prefix
from allmydata.crypto import ed25519 from allmydata.crypto import ed25519
from allmydata.util import base32, rrefutil from allmydata.util import base32, rrefutil
@ -52,7 +52,7 @@ def unsign_from_foolscap(ann_t):
raise UnknownKeyError("only v0- keys recognized") raise UnknownKeyError("only v0- keys recognized")
claimed_key = ed25519.verifying_key_from_string("pub-" + claimed_key_vs) claimed_key = ed25519.verifying_key_from_string("pub-" + claimed_key_vs)
sig_bytes = base32.a2b(crypto.remove_prefix(sig_vs, "v0-")) sig_bytes = base32.a2b(remove_prefix(sig_vs, "v0-"))
ed25519.verify_signature(claimed_key, sig_bytes, msg) ed25519.verify_signature(claimed_key, sig_bytes, msg)
key_vs = claimed_key_vs key_vs = claimed_key_vs
ann = json.loads(msg.decode("utf-8")) ann = json.loads(msg.decode("utf-8"))

View File

@ -734,8 +734,7 @@ class Admin(unittest.TestCase):
self.failUnlessEqual(pubkey_bits[0], vk_header, lines[1]) self.failUnlessEqual(pubkey_bits[0], vk_header, lines[1])
self.failUnless(privkey_bits[1].startswith("priv-v0-"), lines[0]) self.failUnless(privkey_bits[1].startswith("priv-v0-"), lines[0])
self.failUnless(pubkey_bits[1].startswith("pub-v0-"), lines[1]) self.failUnless(pubkey_bits[1].startswith("pub-v0-"), lines[1])
sk_bytes = base32.a2b(remove_prefix(privkey_bits[1], "priv-v0-")) sk, pk = ed25519.signing_keypair_from_string(privkey_bits[1])
sk, pk = ed25519.signing_keypair_from_bytes(sk_bytes)
vk_bytes = base32.a2b(remove_prefix(pubkey_bits[1], "pub-v0-")) vk_bytes = base32.a2b(remove_prefix(pubkey_bits[1], "pub-v0-"))
self.failUnlessEqual( self.failUnlessEqual(
ed25519.bytes_from_verifying_key(pk), ed25519.bytes_from_verifying_key(pk),

View File

@ -9,9 +9,10 @@ from allmydata.crypto import (
aes, aes,
ed25519, ed25519,
rsa, rsa,
remove_prefix,
BadPrefixError
) )
from allmydata.crypto.util import remove_prefix
from allmydata.crypto.error import BadPrefixError
RESOURCE_DIR = path.join(path.dirname(__file__), 'data') RESOURCE_DIR = path.join(path.dirname(__file__), 'data')
@ -306,7 +307,7 @@ class TestEd25519(unittest.TestCase):
serialized key must be bytes serialized key must be bytes
''' '''
with self.assertRaises(ValueError) as ctx: with self.assertRaises(ValueError) as ctx:
ed25519.signing_keypair_from_bytes(six.text_type("not bytes")) ed25519.signing_keypair_from_string(six.text_type("not bytes"))
self.assertIn( self.assertIn(
"must be bytes", "must be bytes",
str(ctx.exception) str(ctx.exception)
@ -317,7 +318,7 @@ class TestEd25519(unittest.TestCase):
serialized key must be bytes serialized key must be bytes
''' '''
with self.assertRaises(ValueError) as ctx: with self.assertRaises(ValueError) as ctx:
ed25519.verifying_key_from_bytes(six.text_type("not bytes")) ed25519.verifying_key_from_string(six.text_type("not bytes"))
self.assertIn( self.assertIn(
"must be bytes", "must be bytes",
str(ctx.exception) str(ctx.exception)