[tor-commits] [stem/master] Change KDF to a named tuple
atagar at torproject.org
atagar at torproject.org
Wed Feb 7 19:44:51 UTC 2018
commit 984add2da2e62b8c102f60a671717b240a004bac
Author: Damian Johnson <atagar at torproject.org>
Date: Wed Jan 31 11:57:51 2018 -0800
Change KDF to a named tuple
Been going back and forth on this but yeah, think it's a bit nicer this way.
---
stem/client/__init__.py | 46 +++++++++++++++------------------
test/settings.cfg | 2 +-
test/unit/client/__init__.py | 2 +-
test/unit/client/{kdf_tor.py => kdf.py} | 17 ++++--------
4 files changed, 28 insertions(+), 39 deletions(-)
diff --git a/stem/client/__init__.py b/stem/client/__init__.py
index 4c6bdb12..f3e842c6 100644
--- a/stem/client/__init__.py
+++ b/stem/client/__init__.py
@@ -12,7 +12,9 @@ a wrapper for :class:`~stem.socket.RelaySocket`, much the same way as
::
split - splits bytes into substrings
- KDF - KDF-TOR key derivative for TAP, CREATE_FAST handshakes, and hidden serivces
+
+ KDF - KDF-TOR derivatived attributes
+ +- from_value - parses key material
Field - Packable and unpackable datatype.
|- Size - Field of a static size.
@@ -107,6 +109,7 @@ a wrapper for :class:`~stem.socket.RelaySocket`, much the same way as
===================== ===========
"""
+import collections
import hashlib
import io
import struct
@@ -461,45 +464,38 @@ class Certificate(Field):
return _hash_attr(self, 'type_int', 'value')
-class KDF(object):
+class KDF(collections.namedtuple('KDF', ['key_hash', 'forward_digest', 'backward_digest', 'forward_key', 'backward_key'])):
"""
- Tor's derived key for TAP, CREATE_FAST handshakes, and hidden service
- protocols as defined tor-spec section 5.2.1.
+ Computed KDF-TOR derived values for TAP, CREATE_FAST handshakes, and hidden
+ service protocols as defined tor-spec section 5.2.1.
- :var bytes key_hash: expected derived key that proves knowledge of our shared
- computed key
+ :var bytes key_hash: hash that proves knowledge of our shared key
:var bytes forward_digest: forward digest hash seed
:var bytes backward_digest: backward digest hash seed
:var bytes forward_key: forward encryption key
:var bytes backward_key: backward encryption key
"""
- def __init__(self, key_material):
- value = KDF._value(key_material)
-
- self.key_hash, value = split(value, HASH_LEN)
- self.forward_digest, value = split(value, HASH_LEN)
- self.backward_digest, value = split(value, HASH_LEN)
- self.forward_key, value = split(value, KEY_LEN)
- self.backward_key, value = split(value, KEY_LEN)
-
@staticmethod
- def _value(key):
- """
- Computes the KDF-TOR value...
-
- K = H(K0 | [00]) | H(K0 | [01]) | H(K0 | [02]) | ...
- """
+ def from_value(key_material):
+ # Derived key material, as per...
+ #
+ # K = H(K0 | [00]) | H(K0 | [01]) | H(K0 | [02]) | ...
derived_key = ''
- derived_key_len = KEY_LEN * 2 + HASH_LEN * 3
counter = 0
- while len(derived_key) < derived_key_len:
- derived_key += hashlib.sha1(key + Size.CHAR.pack(counter)).digest()
+ while len(derived_key) < KEY_LEN * 2 + HASH_LEN * 3:
+ derived_key += hashlib.sha1(key_material + Size.CHAR.pack(counter)).digest()
counter += 1
- return derived_key[:derived_key_len]
+ key_hash, derived_key = split(derived_key, HASH_LEN)
+ forward_digest, derived_key = split(derived_key, HASH_LEN)
+ backward_digest, derived_key = split(derived_key, HASH_LEN)
+ forward_key, derived_key = split(derived_key, KEY_LEN)
+ backward_key, derived_key = split(derived_key, KEY_LEN)
+
+ return KDF(key_hash, forward_digest, backward_digest, forward_key, backward_key)
setattr(Size, 'CHAR', Size('CHAR', 1, '!B'))
diff --git a/test/settings.cfg b/test/settings.cfg
index 7af57181..4080ca2a 100644
--- a/test/settings.cfg
+++ b/test/settings.cfg
@@ -233,7 +233,7 @@ test.unit_tests
|test.unit.client.size.TestSize
|test.unit.client.address.TestAddress
|test.unit.client.certificate.TestCertificate
-|test.unit.client.kdf_tor.TestKdfTor
+|test.unit.client.kdf.TestKDF
|test.unit.client.cell.TestCell
|test.unit.connection.authentication.TestAuthenticate
|test.unit.connection.connect.TestConnect
diff --git a/test/unit/client/__init__.py b/test/unit/client/__init__.py
index ba93b3e6..91d3b2be 100644
--- a/test/unit/client/__init__.py
+++ b/test/unit/client/__init__.py
@@ -6,7 +6,7 @@ __all__ = [
'address',
'cell',
'certificate',
- 'kdf_tor',
+ 'kdf',
'size',
]
diff --git a/test/unit/client/kdf_tor.py b/test/unit/client/kdf.py
similarity index 59%
rename from test/unit/client/kdf_tor.py
rename to test/unit/client/kdf.py
index f356d2cd..56665d31 100644
--- a/test/unit/client/kdf_tor.py
+++ b/test/unit/client/kdf.py
@@ -1,5 +1,5 @@
"""
-Unit tests for stem.client.kdf_tor.
+Unit tests for stem.client.KDF.
"""
import unittest
@@ -9,24 +9,17 @@ import stem.client
KEY_1 = '\xec\xec.\xeb7R\xf2\n\xcb\xce\x97\xf4\x86\x82\x19#\x10\x0f\x08\xf0\xa2Z\xdeJ\x8f2\x8cc\xf6\xfa\x0e\t\x83f\xc5\xe2\xb3\x94\xa8\x13'
KEY_2 = '\xe0v\xe4\xfaTB\x91\x1c\x81Gz\xa0\tI\xcb{\xc56\xcfV\xc2\xa0\x19\x9c\x98\x9a\x06\x0e\xc5\xfa\xb0z\x83\xa6\x10\xf6r"<b'
-DERIVED_1 = '\xca+\x81\x05\x14\x9d)o\xa6\x82\xe9B\xa8?\xf2\xaf\x85\x1b]6\xac\xcc\xbc\x91\xb1\xaf\xd7\xe0\xe9\x9dF#\xd8\xdbz\xe8\xe6\xca\x83,*\xe5scX\xbb+\xca \xcb\xa4\xbc\xad\x0f\x95\x0cO\xcc\xac\xf1\xc3\xbe\xc9\xe1\xf4\x90f\xdai\xf3\xf3\xf5\x14\xb5\xb9\x03U\xaf\x1e\x1b\xb1q||\x86A<_\xf7\xa0%\x86'
-DERIVED_2 = '\xbc0\xf99\x8e;Te\xbb+\xdb\xabR3l\xb9f?\x07KZC8\xe7\xa15\xd1IS\xd9\xd4\x1e\x96\xf6\xcd\x82\x91\x0b}r\x7f\xc5\xc0\xb1/[\x97dW\xba\x82g\xe7m^\x06[\xe6\xf8\xb4\x83f>c\x8b\x0f\x03\xcc\x98\x1f~t\x88\xe1\x83\xec\xbf*_\x8cF\x0e1\xa9\x17\xce\xa6\xa3\xd1+]\x1f'
-
-class TestKdfTor(unittest.TestCase):
- def test_kdf_value(self):
- self.assertEqual(DERIVED_1, stem.client.KDF._value(KEY_1))
- self.assertEqual(DERIVED_2, stem.client.KDF._value(KEY_2))
-
- def test_kdf_attributes(self):
- k1 = stem.client.KDF(KEY_1)
+class TestKDF(unittest.TestCase):
+ def test_parsing(self):
+ k1 = stem.client.KDF.from_value(KEY_1)
self.assertEqual('\xca+\x81\x05\x14\x9d)o\xa6\x82\xe9B\xa8?\xf2\xaf\x85\x1b]6', k1.key_hash)
self.assertEqual('\xac\xcc\xbc\x91\xb1\xaf\xd7\xe0\xe9\x9dF#\xd8\xdbz\xe8\xe6\xca\x83,', k1.forward_digest)
self.assertEqual('*\xe5scX\xbb+\xca \xcb\xa4\xbc\xad\x0f\x95\x0cO\xcc\xac\xf1', k1.backward_digest)
self.assertEqual('\xc3\xbe\xc9\xe1\xf4\x90f\xdai\xf3\xf3\xf5\x14\xb5\xb9\x03', k1.forward_key)
self.assertEqual('U\xaf\x1e\x1b\xb1q||\x86A<_\xf7\xa0%\x86', k1.backward_key)
- k2 = stem.client.KDF(KEY_1)
+ k2 = stem.client.KDF.from_value(KEY_1)
self.assertEqual('\xca+\x81\x05\x14\x9d)o\xa6\x82\xe9B\xa8?\xf2\xaf\x85\x1b]6', k2.key_hash)
self.assertEqual('\xac\xcc\xbc\x91\xb1\xaf\xd7\xe0\xe9\x9dF#\xd8\xdbz\xe8\xe6\xca\x83,', k2.forward_digest)
self.assertEqual('*\xe5scX\xbb+\xca \xcb\xa4\xbc\xad\x0f\x95\x0cO\xcc\xac\xf1', k2.backward_digest)
More information about the tor-commits
mailing list