Skip to content

Commit 79dd966

Browse files
stratosphersipa
andcommitted
Add functions to compute ellswift encoding, x-only ECDH
Co-authored-by: Pieter Wuille <pieter.wuille@gmail.com>
1 parent 91ddb51 commit 79dd966

File tree

1 file changed

+31
-1
lines changed

1 file changed

+31
-1
lines changed

test/functional/test_framework/ellswift.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import random
1111
import unittest
1212

13-
from .key import FE, GE
13+
from .key import FE, GE, SECP256K1_G
1414

1515
MINUS_3_SQRT = FE(-3).sqrt()
1616

@@ -56,6 +56,28 @@ def xswiftec_inv(x, u, case):
5656
w = -w
5757
return w * (u * (MINUS_3_SQRT - 1) / 2 - v)
5858

59+
def xelligatorswift(x):
60+
"""Given a field element X on the curve, find (u, t) that encode them."""
61+
while True:
62+
u = FE(random.randrange(1, GE.ORDER))
63+
case = random.randrange(0, 8)
64+
t = xswiftec_inv(x, u, case)
65+
if t is not None:
66+
return u, t
67+
68+
def ellswift_create():
69+
"""Generate a (privkey, ellswift_pubkey) pair."""
70+
priv = random.randrange(1, GE.ORDER)
71+
u, t = xelligatorswift((priv * SECP256K1_G).x)
72+
return priv.to_bytes(32, 'big'), u.to_bytes() + t.to_bytes()
73+
74+
def ellswift_ecdh_xonly(pubkey_theirs, privkey):
75+
"""Compute X coordinate of shared ECDH point between ellswift pubkey and privkey."""
76+
u = FE(int.from_bytes(pubkey_theirs[:32], 'big'))
77+
t = FE(int.from_bytes(pubkey_theirs[32:], 'big'))
78+
d = int.from_bytes(privkey, 'big')
79+
return (d * GE.lift_x(xswiftec(u, t))).x.to_bytes()
80+
5981
class TestFrameworkEllSwift(unittest.TestCase):
6082
def test_elligator_forward(self):
6183
"""Verify that xswiftec maps all inputs to the curve."""
@@ -77,3 +99,11 @@ def test_elligator_roundtrip(self):
7799
u, t = xelligatorswift(x)
78100
x2 = xswiftec(u, t)
79101
self.assertEqual(x2, x)
102+
103+
def test_ellswift_ecdh_xonly(self):
104+
for _ in range(32):
105+
privkey1, encoding1 = ellswift_create()
106+
privkey2, encoding2 = ellswift_create()
107+
shared_secret1 = ellswift_ecdh_xonly(encoding1, privkey2)
108+
shared_secret2 = ellswift_ecdh_xonly(encoding2, privkey1)
109+
assert shared_secret1 == shared_secret2

0 commit comments

Comments
 (0)