tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

hs_build_address.py (1859B)


      1 # Future imports for Python 2.7, mandatory in 3.0
      2 from __future__ import division
      3 from __future__ import print_function
      4 from __future__ import unicode_literals
      5 
      6 import sys
      7 import hashlib
      8 import struct
      9 import base64
     10 
     11 # Python 3.6+, the SHA3 is available in hashlib natively. Else this requires
     12 # the pysha3 package (pip install pysha3).
     13 TEST_INPUT = b"Hello World"
     14 if sys.version_info < (3, 6):
     15    import sha3
     16    m = sha3.sha3_256(TEST_INPUT)
     17 else:
     18    m = hashlib.sha3_256(TEST_INPUT)
     19 
     20 # Test vector to make sure the right sha3 version will be used. pysha3 < 1.0
     21 # used the old Keccak implementation. During the finalization of SHA3, NIST
     22 # changed the delimiter suffix from 0x01 to 0x06. The Keccak sponge function
     23 # stayed the same. pysha3 1.0 provides the previous Keccak hash, too.
     24 TEST_VALUE = "e167f68d6563d75bb25f3aa49c29ef612d41352dc00606de7cbd630bb2665f51"
     25 if TEST_VALUE != m.hexdigest():
     26    print("pysha3 version is < 1.0. Please install from:")
     27    print("https://github.com/tiran/pysha3")
     28    sys.exit(1)
     29 
     30 # Checksum is built like so:
     31 #   CHECKSUM = SHA3(".onion checksum" || PUBKEY || VERSION)
     32 PREFIX = ".onion checksum".encode()
     33 # 32 bytes ed25519 pubkey from first test vector of
     34 # https://tools.ietf.org/html/draft-josefsson-eddsa-ed25519-02#section-6
     35 PUBKEY_STRING = "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a"
     36 if sys.version_info < (3, 0):
     37    PUBKEY = PUBKEY_STRING.decode('hex')
     38 else:
     39    PUBKEY = bytes.fromhex(PUBKEY_STRING)
     40 # Version 3 is proposal224
     41 VERSION = 3
     42 
     43 data = struct.pack('15s32sb', PREFIX, PUBKEY, VERSION)
     44 checksum = hashlib.sha3_256(data).digest()
     45 
     46 # Onion address is built like so:
     47 #   onion_address = base32(PUBKEY || CHECKSUM || VERSION) + ".onion"
     48 address = struct.pack('!32s2sb', PUBKEY, checksum, VERSION)
     49 onion_addr = base64.b32encode(address).decode().lower()
     50 
     51 print("%s" % (onion_addr))