Skip to content

Commit 5e49618

Browse files
committed
test_onion.py: control generate/decode from command line
1 parent da5d3e3 commit 5e49618

File tree

1 file changed

+59
-43
lines changed

1 file changed

+59
-43
lines changed

test/test_onion.py

Lines changed: 59 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#!/usr/bin/env python
22

3+
import argparse
34
import sys
5+
import time
46

57
from hashlib import sha256
68
from binascii import hexlify, unhexlify
@@ -139,6 +141,16 @@ def get_pos_y_for_x(pubkey_x, yneg=0):
139141
if pub_key_x is not None: OpenSSL.BN_free(pub_key_x)
140142
if pub_key_y is not None: OpenSSL.BN_free(pub_key_y)
141143

144+
def ec_decompress(pubkey, curve='secp256k1'):
145+
if pubkey[0] == '\x02' or pubkey[0] == '\x03':
146+
yneg = ord(pubkey[0]) & 1
147+
pubkey = "\x04" + pubkey[1:] + get_pos_y_for_x(pubkey[1:], yneg=yneg)
148+
elif pubkey[0] == '\x04':
149+
pass
150+
else:
151+
raise Exception("Unrecognised pubkey format: %s" % (pubkey,))
152+
return pubkey
153+
142154
class Onion(object):
143155
HMAC_LEN = 32
144156
PKEY_LEN = 32
@@ -282,48 +294,52 @@ def __init__(self, msgs, pubkeys):
282294
msgenc += hmac_sha256(hmacs[i], msgenc)
283295
self.onion = msgenc
284296

285-
def decode_from_file(f):
286-
keys = []
287-
msg = ""
288-
for ln in f.readlines():
289-
if ln.startswith(" * Keypair "):
290-
w = ln.strip().split()
291-
idx = int(w[2].strip(":"))
292-
priv = unhexlify(w[3])
293-
pub = unhexlify(w[4])
294-
assert idx == len(keys)
295-
keys.append(ecc.ECC(privkey=priv, pubkey=pub, curve='secp256k1'))
296-
elif ln.startswith(" * Message:"):
297-
msg = unhexlify(ln[11:].strip())
298-
elif ln.startswith("Decrypting"):
299-
pass
300-
else:
301-
print ln
302-
assert ln.strip() == ""
303-
304-
assert msg != ""
305-
for k in keys:
306-
o = OnionDecrypt(msg, k)
307-
o.decrypt()
308-
print o.msg
309-
msg = o.fwd
310-
print "done"
297+
def generate(args):
298+
server_keys = []
299+
msgs = []
300+
for k in args.pubkeys:
301+
k = unhexlify(k)
302+
msgs.append("Message for %s..." % (hexlify(k[1:21]),))
303+
k = ec_decompress(k)
304+
server_keys.append(k)
305+
o = OnionEncrypt(msgs, server_keys)
306+
sys.stdout.write(o.onion)
307+
return
308+
309+
def decode(args):
310+
msg = sys.stdin.read()
311+
key = ecc.ECC(privkey=unhexlify(args.seckey),
312+
pubkey=ec_decompress(unhexlify(args.pubkey)),
313+
curve='secp256k1')
314+
o = OnionDecrypt(msg, key)
315+
o.decrypt()
316+
#sys.stderr.write("Message: \"%s\"\n" % (o.msg,))
317+
want_msg = "Message for %s..." % (args.pubkey[2:42])
318+
if o.msg != want_msg + "\0"*(Onion.MSG_LEN - len(want_msg)):
319+
raise Exception("Unexpected message: \"%s\" (wanted: %s)" % (o.msg, want_msg))
320+
321+
sys.stdout.write(o.fwd)
322+
323+
def main(argv):
324+
parser = argparse.ArgumentParser(description="Process some integers.")
325+
sp = parser.add_subparsers()
326+
p = sp.add_parser("generate")
327+
p.add_argument("pubkeys", nargs='+', help="public keys of recipients")
328+
p.set_defaults(func=generate)
329+
330+
p = sp.add_parser("decode")
331+
p.add_argument("seckey", help="secret key for router")
332+
p.add_argument("pubkey", help="public key for router")
333+
p.set_defaults(func=decode)
334+
335+
args = parser.parse_args(argv)
336+
337+
return args.func(args)
338+
339+
340+
311341

312342
if __name__ == "__main__":
313-
if len(sys.argv) > 1 and sys.argv[1] == "generate":
314-
if len(sys.argv) == 3:
315-
n = int(sys.argv[2])
316-
else:
317-
n = 20
318-
servers = [ecc.ECC(curve='secp256k1') for _ in range(n)]
319-
server_pubs = [s.get_pubkey() for s in servers]
320-
msgs = ["Howzit %d..." % (i,) for i in range(n)]
321-
322-
o = OnionEncrypt(msgs, server_pubs)
323-
324-
for i, s in enumerate(servers):
325-
print " * Keypair %d: %s %s" % (
326-
i, hexlify(s.privkey), hexlify(s.get_pubkey()))
327-
print " * Message: %s" % (hexlify(o.onion))
328-
else:
329-
decode_from_file(sys.stdin)
343+
main(sys.argv[1:])
344+
sys.exit(0)
345+

0 commit comments

Comments
 (0)