Pure python EC #15826
pull sipa wants to merge 2 commits into bitcoin:master from sipa:201904_pythonec changing 5 files +389 −230-
sipa commented at 7:27 am on April 16, 2019: memberThis removes the dependency on OpenSSL for the interaction tests, by providing a pure-Python toy implementation of secp256k1.
-
fanquake added the label Tests on Apr 16, 2019
-
jonasschnelli commented at 7:35 am on April 16, 2019: contributorConcept ACK
-
practicalswift commented at 8:53 am on April 16, 2019: contributor
Concept ACK
Excellent work! Thanks for doing this!
-
MarcoFalke commented at 11:44 am on April 16, 2019: member:heart: Makes it easier to run the tests on native windows, where I couldn’t figure out how to install that library. Will give it a try…
-
in test/functional/test_framework/key.py:245 in b567f723b9 outdated
409+ if self.compressed: 410+ return bytes([0x02 + (p[1] & 1)]) + p[0].to_bytes(32, 'big') 411+ else: 412+ return bytes([0x04]) + p[0].to_bytes(32, 'big') + p[1].to_bytes(32, 'big') 413+ 414+ def verify_ecdsa(self, sig, msg, low_s=True):
MarcoFalke commented at 11:47 am on April 16, 2019:Looks like this is never called. Could either:
- Remove it
- Update the python linter
- Call it in a smoke test
sdaftuar commented at 11:56 am on April 16, 2019: memberMakes it easier to run the tests on native windows, where I couldn’t figure out how to install that library
That seems like a good motivation for making a change like this, but I’m curious if there are other reasons as well?
sipa commented at 5:07 pm on April 16, 2019: member@sdaftuar The original motivation was that for testing a Schnorr signature implementation we’ll want a Python version to test against, which needs much of this logic anyway, and it felt silly to maintain two independent versions just for testing (especially as one relies on OpenSSL we’re trying to get rid of as a dependency). @MarcoFalke I added the verify_ecdsa function to test the sign_ecdsa code while writing it, but expect it may be useful to test against the Bitcoin Core signing code. I can either make the linter ignore it, or at a simple test that invokes it. Up to you.MarcoFalke commented at 7:26 pm on April 16, 2019: memberYeah, having a test thatverify_ecdsas a Bitcoin Core generated signature would be nicein test/functional/p2p_segwit.py:12 in b567f723b9 outdated
8@@ -9,7 +9,7 @@ 9 import time 10 11 from test_framework.blocktools import create_block, create_coinbase, add_witness_commitment, get_witness_script, WITNESS_COMMITMENT_HEADER 12-from test_framework.key import CECKey, CPubKey 13+from test_framework.key import ECKey, ECPubKey
jnewbery commented at 7:46 pm on April 16, 2019:unused importECPubKey
sipa commented at 8:00 pm on April 16, 2019:Gone.jnewbery commented at 7:47 pm on April 16, 2019: memberConcept ACK!sipa force-pushed on Apr 16, 2019sipa commented at 8:02 pm on April 16, 2019: memberI’ve added ecdsa_verify to the ignore list. I’ll try to write a test that actually uses it, but it’s not that trivial either.sipa force-pushed on Apr 16, 2019sipa force-pushed on Apr 16, 2019sipa force-pushed on Apr 16, 2019sipa force-pushed on Apr 16, 2019gmaxwell commented at 1:15 am on April 17, 2019: contributorAt a glance this looks fine, I was going to urge you to put a really strong warning on it, but the warning looks adequate. I’m not going to give this any cryptographic review because I don’t think it needs/deserves any.in test/functional/test_framework/key.py:35 in 048cbc4868 outdated
95 96+ See http://en.wikipedia.org/wiki/Jacobi_symbol 97+ """ 98+ if n == 0: 99+ return 0 100+ t = 1 if n > 0 else 0
jnewbery commented at 2:11 pm on April 17, 2019:Not that it matters for this application since you only call this with +ve n, but I believe this should be:
0t = 1 if n > 0 else -1
sipa commented at 3:04 pm on April 17, 2019:That would not be correct (I represent the “t” variable from the Wikipedia article as 0/1 rather than 1/-1, so that I can use xor operations to flip it).
jnewbery commented at 4:57 pm on April 17, 2019:As discussed on IRC, I believe this (and the wikipedia Lua code that it’s based on) is incorrect when passed -ve a (I believe the bug probably stems from the misunderstanding that % in python and lua represents the remainder, not the modulus, so a % n is negative when n is negative).
Simplest fix is:
0 assert k > 0 and k % 2 1 n = n % k 2 t = 1
sipa force-pushed on Apr 17, 2019sipa force-pushed on Apr 17, 2019MarcoFalke commented at 6:29 pm on April 17, 2019: memberThis will be merged next Monday unless there are objectionsin test/functional/test_framework/key.py:84 in c01a1b9e1e outdated
144+ def on_curve(self, p1): 145+ """Determine whether a Jacobian tuple p is on the curve (and not infinity)""" 146+ x1, y1, z1 = p1 147+ z2 = pow(z1, 2, self.p) 148+ z4 = pow(z2, 2, self.p) 149+ return z1 != 0 and (pow(x1, 3, self.p) + self.a * x1 * z2 + self.b * z2 * z4 - pow(y1, 2, self.p)) % self.p == 0
jnewbery commented at 7:57 pm on April 17, 2019:Again, not a problem for this application since a=0 in secp256k1, but I think this should be:
0return z1 != 0 and (pow(x1, 3, self.p) + self.a * x1 * z4 + self.b * z2 * z4 - pow(y1, 2, self.p)) % self.p == 0(ie the self.a term should be multiplied by
z4so that all terms in the eliptic curve equation have a common z^6 factor that can be cancelled)
sipa commented at 10:03 pm on April 17, 2019:Fixed.in test/functional/test_framework/key.py:344 in c01a1b9e1e outdated
539+ R = SECP256K1.affine(SECP256K1.mul([(SECP256K1_G, k)])) 540+ r = R[0] % SECP256K1_ORDER 541+ s = (modinv(k, SECP256K1_ORDER) * (z + self.secret * r)) % SECP256K1_ORDER 542+ if low_s and s > SECP256K1_ORDER_HALF: 543+ s = SECP256K1_ORDER - s 544+ rb = r.to_bytes((r.bit_length() + 8) // 8, 'big')
jnewbery commented at 9:06 pm on April 17, 2019:Note that you can also do ceiling division with-(-r.bit_length() // 8). I’m not sure if that’s any more readable though.
sipa commented at 9:13 pm on April 17, 2019:I don’t want a ceiling division; i want a flooring one plus 1 (255 should become 32, but 256 should become 33).
jnewbery commented at 5:13 pm on April 18, 2019:oops. Thanks!in test/functional/test_framework/key.py:1 in c01a1b9e1e outdated
0@@ -1,226 +1,343 @@ 1-# Copyright (c) 2011 Sam Rushing 2-"""ECC secp256k1 OpenSSL wrapper. 3+# Copyright (c) 2019 Pieter Wuille
jnewbery commented at 9:07 pm on April 17, 2019:Does the project have a policy on individual contributors’ copyright notices in source files? Do you also want to include the MIT license boilerplate here too?
sipa commented at 9:47 pm on April 17, 2019:There are a few files with individual author’s names. As the “Copyright The Bitcoin Core contributors” is likely meaningless I think listing actual authors is preferable when it’s a well-defined set of people, but I don’t feel strongly.sipa force-pushed on Apr 17, 2019in test/functional/test_framework/key.py:113 in 8cc786094f outdated
173+ s = (4*x1*y1_2) % self.p 174+ m = 3*x1_2 175+ if self.a: 176+ m += self.a * pow(z1, 4, self.p) 177+ m = m % self.p 178+ x3 = (m**2 - 2*s) % self.p
jnewbery commented at 5:38 pm on April 18, 2019:I’d have a slight preference for these to be namedx2,y2,z2
sipa commented at 6:58 pm on April 18, 2019:Done.in test/functional/test_framework/key.py:140 in 8cc786094f outdated
200+ h_2 = (h**2) % self.p 201+ h_3 = (h_2 * h) % self.p 202+ u1_h_2 = (x1 * h_2) % self.p 203+ x3 = (r**2 - h_3 - 2*u1_h_2) % self.p 204+ y3 = (r*(u1_h_2 - x3) - y1*h_3) % self.p 205+ z3 = (h*z1*z2) % self.p
jnewbery commented at 5:39 pm on April 18, 2019:nit: You could removez2here (since it’s 1 for an affine point)
sipa commented at 6:59 pm on April 18, 2019:Done.jnewbery commented at 5:50 pm on April 18, 2019: memberLooks good to me. A couple of nits inline, but otherwise ACK 8cc786094fb55907a25a4b46caa7f1f8fb512363
I added copious comments and notes for myself as I was reviewing. They’re here: https://github.com/jnewbery/bitcoin/commit/af36c8ad5ac3369c05c3e832fe28fd9c45b254b3. Feel free to take that commit for this PR.
8c7b9324caPure python EC
This removes the dependency on OpenSSL for the interaction tests, by providing a pure-Python toy implementation of secp256k1.
sipa force-pushed on Apr 18, 2019jnewbery commented at 8:07 pm on April 18, 2019: memberNice find for the quicker modinv().
utACK ac050deca0227fe44346f3f91c79d733ed5705d8
Add comments to Python ECDSA implementation b67978529asipa force-pushed on Apr 18, 2019jnewbery commented at 8:56 pm on April 18, 2019: memberutACK b67978529ad02fc2665f2362418dc53db2e25e17
Only change is correcting two small code comments.
MarcoFalke merged this on Apr 22, 2019MarcoFalke closed this on Apr 22, 2019
MarcoFalke referenced this in commit 08bd21a3bd on Apr 22, 2019sidhujag referenced this in commit d6998af219 on Apr 24, 2019MarcoFalke referenced this in commit d9fc969e71 on Jun 21, 2019MarcoFalke referenced this in commit af25a757e0 on Jun 26, 2019HashUnlimited referenced this in commit 00d8ea22a2 on Aug 23, 2019HashUnlimited referenced this in commit 2c4d5808d9 on Aug 23, 2019Bushstar referenced this in commit fefba58944 on Aug 24, 2019Bushstar referenced this in commit 5830e5b432 on Aug 24, 2019Bushstar referenced this in commit 0e94e71e47 on Aug 24, 2019Bushstar referenced this in commit f9c2111bda on Aug 24, 2019Bushstar referenced this in commit e4e5c1a993 on Aug 24, 2019Bushstar referenced this in commit ddee472465 on Aug 24, 2019Bushstar referenced this in commit df9a063170 on Aug 24, 2019Bushstar referenced this in commit 98771b9e71 on Aug 24, 2019laanwj referenced this in commit 6393da8fdc on Sep 25, 2019deadalnix referenced this in commit fb0ea54f2e on May 6, 2020ftrader referenced this in commit 7025e91ee1 on Aug 17, 2020PastaPastaPasta referenced this in commit 9565f4795a on Jun 27, 2021PastaPastaPasta referenced this in commit 1cb4a96635 on Jun 28, 2021PastaPastaPasta referenced this in commit 8aa73dcb1a on Jun 29, 2021PastaPastaPasta referenced this in commit 4c5e0add6f on Jul 1, 2021PastaPastaPasta referenced this in commit e24d40394c on Jul 1, 2021PastaPastaPasta referenced this in commit 7926be588d on Jul 12, 2021PastaPastaPasta referenced this in commit a947638130 on Jul 13, 2021vijaydasmp referenced this in commit c4913f39fb on Oct 23, 2021vijaydasmp referenced this in commit 4be1a71f6d on Oct 23, 2021vijaydasmp referenced this in commit 80fa0018bf on Oct 23, 2021vijaydasmp referenced this in commit 24779e36d8 on Oct 26, 2021vijaydasmp referenced this in commit ffe73aa19a on Oct 26, 2021vijaydasmp referenced this in commit 394689a23c on Oct 26, 2021vijaydasmp referenced this in commit 7f3940cd40 on Oct 29, 2021vijaydasmp referenced this in commit 7f8b4dce52 on Oct 30, 2021vijaydasmp referenced this in commit 2ab6f67bf3 on Nov 2, 2021vijaydasmp referenced this in commit 9b8131690f on Nov 7, 2021vijaydasmp referenced this in commit c7a6caec8e on Nov 11, 2021vijaydasmp referenced this in commit da58321301 on Nov 12, 2021vijaydasmp referenced this in commit d18976eff1 on Nov 13, 2021vijaydasmp referenced this in commit 83840754fd on Nov 14, 2021vijaydasmp referenced this in commit 790c9e784b on Nov 14, 2021MarcoFalke locked this on Dec 16, 2021
github-metadata-mirror
This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-01-27 06:13 UTC
This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me