sr_srv_calc_ref.py 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  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. import sys
  13. import hashlib
  14. import struct
  15. # Python 3.6+, the SHA3 is available in hashlib natively. Else this requires
  16. # the pysha3 package (pip install pysha3).
  17. if sys.version_info < (3, 6):
  18. import sha3
  19. # Test vector to make sure the right sha3 version will be used. pysha3 < 1.0
  20. # used the old Keccak implementation. During the finalization of SHA3, NIST
  21. # changed the delimiter suffix from 0x01 to 0x06. The Keccak sponge function
  22. # stayed the same. pysha3 1.0 provides the previous Keccak hash, too.
  23. TEST_VALUE = "e167f68d6563d75bb25f3aa49c29ef612d41352dc00606de7cbd630bb2665f51"
  24. if TEST_VALUE != sha3.sha3_256(b"Hello World").hexdigest():
  25. print("pysha3 version is < 1.0. Please install from:")
  26. print("https://github.com/tiran/pysha3https://github.com/tiran/pysha3")
  27. sys.exit(1)
  28. # In this example, we use three reveal values.
  29. reveal_num = 3
  30. version = 1
  31. # We set directly the ascii value because memset(buf, 'A', 20) makes it to 20
  32. # times "41" in the final string.
  33. # Identity and reveal value of dirauth a
  34. ID_a = 20 * "41" # RSA identity of 40 base16 bytes.
  35. R_a = 56 * 'A' # 56 base64 characters
  36. # Identity and reveal value of dirauth b
  37. ID_b = 20 * "42" # RSA identity of 40 base16 bytes.
  38. R_b = 56 * 'B' # 56 base64 characters
  39. # Identity and reveal value of dirauth c
  40. ID_c = 20 * "43" # RSA identity of 40 base16 bytes.
  41. R_c = 56 * 'C' # 56 base64 characters
  42. # Concatenate them all together and hash them to form HASHED_REVEALS.
  43. REVEALS = (ID_a + R_a + ID_b + R_b + ID_c + R_c).encode()
  44. hashed_reveals_object = hashlib.sha3_256(REVEALS)
  45. hashed_reveals = hashed_reveals_object.digest()
  46. previous_SRV = (32 * 'Z').encode()
  47. # Now form the message.
  48. #srv_msg = struct.pack('13sQL256ss', "shared-random", reveal_num, version,
  49. # hashed_reveals, previous_SRV)
  50. invariant_token = b"shared-random"
  51. srv_msg = invariant_token + \
  52. struct.pack('!QL', reveal_num, version) + \
  53. hashed_reveals + \
  54. previous_SRV
  55. # Now calculate the HMAC
  56. srv = hashlib.sha3_256(srv_msg)
  57. print("%s" % srv.hexdigest().upper())
  58. # 2A9B1D6237DAB312A40F575DA85C147663E7ED3F80E9555395F15B515C74253D