sr_srv_calc_ref.py (2712B)
1 # This is a reference implementation of the SRV calculation for prop250. We 2 # use it to generate a test vector for the test_sr_compute_srv() unittest. 3 # (./test shared-random/sr_compute_srv) 4 # 5 # Here is the SRV computation formula: 6 # 7 # HASHED_REVEALS = H(ID_a | R_a | ID_b | R_b | ..) 8 # 9 # SRV = SHA3-256("shared-random" | INT_8(reveal_num) | INT_4(version) | 10 # HASHED_REVEALS | previous_SRV) 11 # 12 13 # Future imports for Python 2.7, mandatory in 3.0 14 from __future__ import division 15 from __future__ import print_function 16 from __future__ import unicode_literals 17 18 import sys 19 import hashlib 20 import struct 21 22 # Python 3.6+, the SHA3 is available in hashlib natively. Else this requires 23 # the pysha3 package (pip install pysha3). 24 if sys.version_info < (3, 6): 25 import sha3 26 27 # Test vector to make sure the right sha3 version will be used. pysha3 < 1.0 28 # used the old Keccak implementation. During the finalization of SHA3, NIST 29 # changed the delimiter suffix from 0x01 to 0x06. The Keccak sponge function 30 # stayed the same. pysha3 1.0 provides the previous Keccak hash, too. 31 TEST_VALUE = "e167f68d6563d75bb25f3aa49c29ef612d41352dc00606de7cbd630bb2665f51" 32 if TEST_VALUE != sha3.sha3_256(b"Hello World").hexdigest(): 33 print("pysha3 version is < 1.0. Please install from:") 34 print("https://github.com/tiran/pysha3https://github.com/tiran/pysha3") 35 sys.exit(1) 36 37 # In this example, we use three reveal values. 38 reveal_num = 3 39 version = 1 40 41 # We set directly the ascii value because memset(buf, 'A', 20) makes it to 20 42 # times "41" in the final string. 43 44 # Identity and reveal value of dirauth a 45 ID_a = 20 * "41" # RSA identity of 40 base16 bytes. 46 R_a = 56 * 'A' # 56 base64 characters 47 48 # Identity and reveal value of dirauth b 49 ID_b = 20 * "42" # RSA identity of 40 base16 bytes. 50 R_b = 56 * 'B' # 56 base64 characters 51 52 # Identity and reveal value of dirauth c 53 ID_c = 20 * "43" # RSA identity of 40 base16 bytes. 54 R_c = 56 * 'C' # 56 base64 characters 55 56 # Concatenate them all together and hash them to form HASHED_REVEALS. 57 REVEALS = (ID_a + R_a + ID_b + R_b + ID_c + R_c).encode() 58 hashed_reveals_object = hashlib.sha3_256(REVEALS) 59 hashed_reveals = hashed_reveals_object.digest() 60 61 previous_SRV = (32 * 'Z').encode() 62 63 # Now form the message. 64 #srv_msg = struct.pack('13sQL256ss', "shared-random", reveal_num, version, 65 # hashed_reveals, previous_SRV) 66 invariant_token = b"shared-random" 67 srv_msg = invariant_token + \ 68 struct.pack('!QL', reveal_num, version) + \ 69 hashed_reveals + \ 70 previous_SRV 71 72 # Now calculate the HMAC 73 srv = hashlib.sha3_256(srv_msg) 74 print("%s" % srv.hexdigest().upper()) 75 76 # 2A9B1D6237DAB312A40F575DA85C147663E7ED3F80E9555395F15B515C74253D