aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoradrien1018 <adrien1018@users.noreply.github.com>2019-06-09 11:38:40 +0800
committeradrien1018 <adrien1018@users.noreply.github.com>2019-06-09 11:38:40 +0800
commit4f012eb453bfe6376fc7c119dec4e048fbefd9ab (patch)
tree6af0bba9321113c1bc837e22cfa254eb3295892d
parent7f8531a76356f7c8332ee816c0e35cd974c80f5f (diff)
downloadcns-final-tor-store-4f012eb453bfe6376fc7c119dec4e048fbefd9ab.tar
cns-final-tor-store-4f012eb453bfe6376fc7c119dec4e048fbefd9ab.tar.gz
cns-final-tor-store-4f012eb453bfe6376fc7c119dec4e048fbefd9ab.tar.bz2
cns-final-tor-store-4f012eb453bfe6376fc7c119dec4e048fbefd9ab.tar.lz
cns-final-tor-store-4f012eb453bfe6376fc7c119dec4e048fbefd9ab.tar.xz
cns-final-tor-store-4f012eb453bfe6376fc7c119dec4e048fbefd9ab.tar.zst
cns-final-tor-store-4f012eb453bfe6376fc7c119dec4e048fbefd9ab.zip
Revise key generator & add data fetching
-rwxr-xr-xforge_key.py55
-rwxr-xr-xget_data.py37
2 files changed, 62 insertions, 30 deletions
diff --git a/forge_key.py b/forge_key.py
index 7fbd46d..850f2b1 100755
--- a/forge_key.py
+++ b/forge_key.py
@@ -17,7 +17,7 @@ def main():
# Generate RSA key pair
data_len = 100
data = random.getrandbits(data_len * 8).to_bytes(data_len, 'little')
- print(data)
+ print('Data:', base64.b64encode(data).decode())
key = forge_rsa_key(data)
# Public hidden service
@@ -49,35 +49,34 @@ NONCE_LEN = 200
KEY_LEN = 1024
def forge_rsa_key(data: bytes):
- # Generate RSA key with p=3.
+ # Generate RSA key with p = 11.
# By Cramer's conjecture (which is likely to be true),
- # the maximum prime gap for a 1024-bit number should be around 5*10**5.
- # We choose a 800-bit data size, and a 200-bit nonce, which allows a maximum
- # gap of 2^(1023-1000)/5 ~ 10**6 and a collision probability of 2^(-100).
+ # the maximum prime gap for a 1024-bit number should be around 500000.
+ # We choose a 800-bit data size and a 200-bit nonce, which allows a maximum
+ # gap of 2^(1023-1000)/11 ~ 760000 and a collision probability of ~2^(-100).
assert(len(data) == DATA_LEN // 8)
# let the highest bit be 1
- n_expect = 1 << (KEY_LEN - 1) | \
- int.from_bytes(data, 'little') << (KEY_LEN - 1 - DATA_LEN) | \
- random.getrandbits(NONCE_LEN) << (KEY_LEN - 1 - DATA_LEN - NONCE_LEN)
while True:
- p = 5
- q = next_prime((n_expect - 1) // p + 1)
- n = p * q
- # final (paranoid) correctness check,
- # should be true given the conjecture is true
- if (n >> (KEY_LEN - 1 - DATA_LEN)) == \
- (n_expect >> (KEY_LEN - 1 - DATA_LEN)): break
-
- # Compute RSA components
- e = 65537
- d = int(gmpy2.invert(e, (p - 1) * (q - 1)))
-
- # Library reference
- # https://pycryptodome.readthedocs.io/en/latest/src/public_key/rsa.html
- key = RSA.construct(
- (n, e, d),
- consistency_check=True,
- )
+ n_expect = 1 << (KEY_LEN - 1) | \
+ int.from_bytes(data, 'little') << (KEY_LEN - 1 - DATA_LEN) | \
+ random.getrandbits(NONCE_LEN) << (KEY_LEN - 1 - DATA_LEN - NONCE_LEN)
+ while True:
+ p = 11
+ q = next_prime((n_expect - 1) // p + 1)
+ n = p * q
+ # final (paranoid) correctness check,
+ # should be true given the conjecture is true
+ if (n >> (KEY_LEN - 1 - DATA_LEN)) == \
+ (n_expect >> (KEY_LEN - 1 - DATA_LEN)): break
+ # Compute RSA components
+ e = 65537
+ d = int(gmpy2.invert(e, (p - 1) * (q - 1)))
+ # Library reference
+ # https://pycryptodome.readthedocs.io/en/latest/src/public_key/rsa.html
+ # if get an invalid key (prob ~1/11), retry with another nonce
+ try: key = RSA.construct((n, e, d), consistency_check=True)
+ except ValueError: continue
+ break
# Tor accepts DER-encoded, then base64 encoded RSA key
# https://github.com/torproject/tor/blob/a462ca7cce3699f488b5e2f2921738c944cb29c7/src/feature/control/control_cmd.c#L1968
@@ -85,9 +84,5 @@ def forge_rsa_key(data: bytes):
ret = str(base64.b64encode(der), 'ASCII')
return ret
-def data_from_public_key(n):
- data_num = (n - (1 << (KEY_LEN - 1))) >> (KEY_LEN - 1 - DATA_LEN)
- return data_num.to_bytes(DATA_LEN // 8, 'little')
-
if __name__ == '__main__':
main()
diff --git a/get_data.py b/get_data.py
new file mode 100755
index 0000000..e509180
--- /dev/null
+++ b/get_data.py
@@ -0,0 +1,37 @@
+#!/usr/bin/env python3
+import argparse
+import os, sys
+import shutil
+import base64
+import random
+
+import gmpy2
+import asn1
+from Crypto.PublicKey import RSA
+from stem.control import Controller
+
+
+def main(name):
+ controller = Controller.from_port()
+ controller.authenticate()
+ a = str(controller.get_hidden_service_descriptor(name))
+ public = a[a.find('PUBLIC KEY-----')+15:a.find('-----END')].replace('\n', '')
+ decoder = asn1.Decoder()
+ decoder.start(base64.b64decode(public))
+ decoder.start(decoder.read()[1])
+ data = data_from_public_key(decoder.read()[1])
+ print(base64.b64encode(data).decode())
+
+DATA_LEN = 800
+NONCE_LEN = 200
+KEY_LEN = 1024
+
+def data_from_public_key(n):
+ data_num = (n - (1 << (KEY_LEN - 1))) >> (KEY_LEN - 1 - DATA_LEN)
+ return data_num.to_bytes(DATA_LEN // 8, 'little')
+
+if __name__ == '__main__':
+ if len(sys.argv) < 2:
+ print(sys.argv[0], '[hidden service name]')
+ sys.exit(1)
+ main(sys.argv[1])