Last active
October 14, 2015 17:53
-
-
Save infinity0/a8a46081a29e47164603 to your computer and use it in GitHub Desktop.
how to combine two x25519 private keys
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python3 -i | |
from nacl.bindings import * | |
from binascii import b2a_hex | |
BO = "little" | |
order_b = 2**252 + 27742317777372353535851937790883648493 | |
order = 8 * order_b | |
to_canonical_i = lambda x: x & 0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8 | 0x4000000000000000000000000000000000000000000000000000000000000000 | |
to_canonical = lambda s: to_canonical_i(int.from_bytes(s, byteorder=BO)).to_bytes(32, byteorder=BO) | |
j = crypto_box_keypair() | |
k = crypto_box_keypair() | |
assert j[0] == crypto_scalarmult_base(to_canonical(j[1])) | |
assert k[0] == crypto_scalarmult_base(to_canonical(k[1])) | |
expected = crypto_scalarmult(j[1], crypto_scalarmult_base(k[1])) | |
assert crypto_scalarmult(k[1], crypto_scalarmult_base(j[1])) == expected | |
# the above is standard DH agreement | |
s_mult_base = lambda i: crypto_scalarmult_base(i.to_bytes(32, BO)) | |
s_mult = lambda i, p: crypto_scalarmult(i.to_bytes(32, BO), p) | |
ji = int.from_bytes(to_canonical(j[1]), byteorder=BO) | |
ki = int.from_bytes(to_canonical(k[1]), byteorder=BO) | |
mi = (ji * ki) % order | |
print("DH exchange between 2 values: %s" % b2a_hex(expected)) | |
if mi != to_canonical_i(mi): | |
print("j*k is not a canonical secret key, so this will not work with real x25519 APIs :( try again...") | |
else: | |
assert s_mult_base(mi) == expected | |
print("combining 2 values, then exp: %s" % b2a_hex(s_mult_base(mi))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment