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)
5 # Here is the SRV computation formula:
7 # HASHED_REVEALS = H(ID_a | R_a | ID_b | R_b | ..)
9 # SRV = SHA3-256("shared-random" | INT_8(reveal_num) | INT_4(version) |
10 # HASHED_REVEALS | previous_SRV)
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
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):
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")
37 # In this example, we use three reveal values.
41 # We set directly the ascii value because memset(buf, 'A', 20) makes it to 20
42 # times "41" in the final string.
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
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
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
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()
61 previous_SRV
= (32 * 'Z').encode()
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
) + \
72 # Now calculate the HMAC
73 srv
= hashlib
.sha3_256(srv_msg
)
74 print("%s" % srv
.hexdigest().upper())
76 # 2A9B1D6237DAB312A40F575DA85C147663E7ED3F80E9555395F15B515C74253D