Skip to content

Commit

Permalink
refactor b_dhke and add domain separated test
Browse files Browse the repository at this point in the history
  • Loading branch information
callebtc committed Feb 21, 2024
1 parent edd38b7 commit 65df5f7
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 50 deletions.
28 changes: 23 additions & 5 deletions cashu/core/crypto/b_dhke.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,12 +136,17 @@ def verify(a: PrivateKey, C: PublicKey, secret_msg: str) -> bool:
valid = C == Y.mult(a) # type: ignore
# BEGIN: BACKWARDS COMPATIBILITY < 0.15.1
if not valid:
Y1: PublicKey = hash_to_curve_domain_separated(secret_msg.encode("utf-8"))
return C == Y1.mult(a) # type: ignore
return verify_domain_separated(a, C, secret_msg)
# END: BACKWARDS COMPATIBILITY < 0.15.1
return valid


def verify_domain_separated(a: PrivateKey, C: PublicKey, secret_msg: str) -> bool:
Y: PublicKey = hash_to_curve_domain_separated(secret_msg.encode("utf-8"))
valid = C == Y.mult(a) # type: ignore
return valid


def hash_e(*publickeys: PublicKey) -> bytes:
e_ = ""
for p in publickeys:
Expand Down Expand Up @@ -197,13 +202,26 @@ def carol_verify_dleq(
valid = alice_verify_dleq(B_, C_, e, s, A)
# BEGIN: BACKWARDS COMPATIBILITY < 0.15.1
if not valid:
Y1: PublicKey = hash_to_curve_domain_separated(secret_msg.encode("utf-8"))
B_1: PublicKey = Y1 + r.pubkey # type: ignore
return alice_verify_dleq(B_1, C_, e, s, A)
return carol_verify_dleq_domain_separated(secret_msg, r, C, e, s, A)
# END: BACKWARDS COMPATIBILITY < 0.15.1
return valid


def carol_verify_dleq_domain_separated(
secret_msg: str,
r: PrivateKey,
C: PublicKey,
e: PrivateKey,
s: PrivateKey,
A: PublicKey,
) -> bool:
Y: PublicKey = hash_to_curve_domain_separated(secret_msg.encode("utf-8"))
C_: PublicKey = C + A.mult(r) # type: ignore
B_: PublicKey = Y + r.pubkey # type: ignore
valid = alice_verify_dleq(B_, C_, e, s, A)
return valid


# Below is a test of a simple positive and negative case

# # Alice's keys
Expand Down
121 changes: 76 additions & 45 deletions tests/test_crypto.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from cashu.core.crypto.b_dhke import (
alice_verify_dleq,
carol_verify_dleq,
carol_verify_dleq_domain_separated,
hash_e,
hash_to_curve,
hash_to_curve_domain_separated,
Expand Down Expand Up @@ -48,30 +49,6 @@ def test_hash_to_curve_iteration():
)


def test_hash_to_curve_domain_separated():
result = hash_to_curve_domain_separated(
bytes.fromhex(
"0000000000000000000000000000000000000000000000000000000000000000"
)
)
assert (
result.serialize().hex()
== "024cce997d3b518f739663b757deaec95bcd9473c30a14ac2fd04023a739d1a725"
)


def test_hash_to_curve_domain_separated_iterative():
result = hash_to_curve_domain_separated(
bytes.fromhex(
"0000000000000000000000000000000000000000000000000000000000000001"
)
)
assert (
result.serialize().hex()
== "022e7158e11c9506f1aa4248bf531298daa7febd6194f003edcd9b93ade6253acf"
)


def test_step1():
secret_msg = "test_message"
B_, blinding_factor = step1_alice(
Expand All @@ -92,26 +69,6 @@ def test_step1():
)


def test_step1_domain_separated():
secret_msg = "test_message"
B_, blinding_factor = step1_alice_domain_separated(
secret_msg,
blinding_factor=PrivateKey(
privkey=bytes.fromhex(
"0000000000000000000000000000000000000000000000000000000000000001"
) # 32 bytes
),
)

assert (
B_.serialize().hex()
== "025cc16fe33b953e2ace39653efb3e7a7049711ae1d8a2f7a9108753f1cdea742b"
)
assert blinding_factor.private_key == bytes.fromhex(
"0000000000000000000000000000000000000000000000000000000000000001"
)


def test_step2():
B_, _ = step1_alice(
"test_message",
Expand Down Expand Up @@ -323,7 +280,7 @@ def test_dleq_alice_direct_verify_dleq():
assert alice_verify_dleq(B_, C_, e, s, A)


def test_dleq_carol_varify_from_bob():
def test_dleq_carol_verify_from_bob():
a = PrivateKey(
privkey=bytes.fromhex(
"0000000000000000000000000000000000000000000000000000000000000001"
Expand All @@ -346,3 +303,77 @@ def test_dleq_carol_varify_from_bob():

# carol does not know B_ and C_, but she receives C and r from Alice
assert carol_verify_dleq(secret_msg=secret_msg, C=C, r=r, e=e, s=s, A=A)


# TESTS FOR DOMAIN SEPARATED HASH TO CURVE


def test_hash_to_curve_domain_separated():
result = hash_to_curve_domain_separated(
bytes.fromhex(
"0000000000000000000000000000000000000000000000000000000000000000"
)
)
assert (
result.serialize().hex()
== "024cce997d3b518f739663b757deaec95bcd9473c30a14ac2fd04023a739d1a725"
)


def test_hash_to_curve_domain_separated_iterative():
result = hash_to_curve_domain_separated(
bytes.fromhex(
"0000000000000000000000000000000000000000000000000000000000000001"
)
)
assert (
result.serialize().hex()
== "022e7158e11c9506f1aa4248bf531298daa7febd6194f003edcd9b93ade6253acf"
)


def test_step1_domain_separated():
secret_msg = "test_message"
B_, blinding_factor = step1_alice_domain_separated(
secret_msg,
blinding_factor=PrivateKey(
privkey=bytes.fromhex(
"0000000000000000000000000000000000000000000000000000000000000001"
) # 32 bytes
),
)

assert (
B_.serialize().hex()
== "025cc16fe33b953e2ace39653efb3e7a7049711ae1d8a2f7a9108753f1cdea742b"
)
assert blinding_factor.private_key == bytes.fromhex(
"0000000000000000000000000000000000000000000000000000000000000001"
)


def test_dleq_carol_verify_from_bob_domain_separated():
a = PrivateKey(
privkey=bytes.fromhex(
"0000000000000000000000000000000000000000000000000000000000000001"
),
raw=True,
)
A = a.pubkey
assert A
secret_msg = "test_message"
r = PrivateKey(
privkey=bytes.fromhex(
"0000000000000000000000000000000000000000000000000000000000000001"
),
raw=True,
)
B_, _ = step1_alice_domain_separated(secret_msg, r)
C_, e, s = step2_bob(B_, a)
assert alice_verify_dleq(B_, C_, e, s, A)
C = step3_alice(C_, r, A)

# carol does not know B_ and C_, but she receives C and r from Alice
assert carol_verify_dleq_domain_separated(
secret_msg=secret_msg, C=C, r=r, e=e, s=s, A=A
)

0 comments on commit 65df5f7

Please sign in to comment.