From 7c644e1835020d9e449478f88cc25de8e3f2cd81 Mon Sep 17 00:00:00 2001 From: callebtc <93376500+callebtc@users.noreply.github.com> Date: Thu, 15 Feb 2024 09:45:45 +0100 Subject: [PATCH] Adjust new domain separator (#421) * adjust new domain separator * Update cashu/core/crypto/b_dhke.py Co-authored-by: Lagrang3 <32647090+Lagrang3@users.noreply.github.com> * slightly adjust comment --------- Co-authored-by: Lagrang3 <32647090+Lagrang3@users.noreply.github.com> --- cashu/core/crypto/b_dhke.py | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/cashu/core/crypto/b_dhke.py b/cashu/core/crypto/b_dhke.py index df0bcccf..4abf1b77 100644 --- a/cashu/core/crypto/b_dhke.py +++ b/cashu/core/crypto/b_dhke.py @@ -71,24 +71,34 @@ def hash_to_curve(message: bytes) -> PublicKey: return point -DOMAIN_SEPARATOR = b"Secp256k1_HashToCurve_" +DOMAIN_SEPARATOR = b"Secp256k1_HashToCurve_Cashu_" def hash_to_curve_domain_separated(message: bytes) -> PublicKey: - """Generates a point from the message hash and checks if the point lies on the curve. - If it does not, iteratively tries to compute a new point from the hash.""" - point = None - msg_to_hash = DOMAIN_SEPARATOR + message + """Generates a secp256k1 point from a message. + + The point is generated by hashing the message with a domain separator and then + iteratively trying to compute a point from the hash. An increasing uint32 counter + (byte order little endian) is appended to the hash until a point is found that lies on the curve. + + The chance of finding a valid point is 50% for every iteration. The maximum number of iterations + is 2**16. If no valid point is found after 2**16 iterations, a ValueError is raised (this should + never happen in practice). + + The domain separator is b"Secp256k1_HashToCurve_Cashu_" or + bytes.fromhex("536563703235366b315f48617368546f43757276655f43617368755f"). + """ + msg_to_hash = hashlib.sha256(DOMAIN_SEPARATOR + message).digest() counter = 0 - while point is None: - _hash = hashlib.sha256(msg_to_hash + str(counter).encode()).digest() + while counter < 2**16: + _hash = hashlib.sha256(msg_to_hash + counter.to_bytes(4, "little")).digest() try: # will error if point does not lie on curve - point = PublicKey(b"\x02" + _hash, raw=True) + return PublicKey(b"\x02" + _hash, raw=True) except Exception: - msg_to_hash = _hash counter += 1 - return point + # it should never reach this point + raise ValueError("No valid point found") def step1_alice(