forked from ElementsProject/elements
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge #20147: Update libsecp256k1 (endomorphism, test improvements)
52380bf Squashed 'src/secp256k1/' changes from 8ab24e8dad..c6b6b8f1bb (Pieter Wuille) Pull request description: This updates the libsecp256k1 subtree to the latest master, which includes: * Enabling the GLV endomorphism optimization by default (and removing support for the non-GLV EC multiplication) * Added a proof for the correctness of the lambda split algorithm by roconnor-blockstream (other code was relying on the fact that it always outputs 128 bit results, which isn't at all obvious). * Improved exhaustive tests, in particular for the Schnorr signature module * Various other testing and CI improvements ACKs for top commit: fanquake: ACK 9e5626d - performed a squash and checked that the changes were the same. The non-endomorphism code has now been ripped out. benthecarman: ACK 9e5626d Tree-SHA512: 50fda5f3f934ee525f01cfc15e4f5efbc5261a97f2b77fe1b3453ee0edcf1281ad74ab4532a2fe1fe907652dd47023beff8cf3d73bf34f65ac914a694b9e7110
- Loading branch information
Showing
39 changed files
with
1,586 additions
and
947 deletions.
There are no files selected for viewing
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
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
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
# Define field size and field | ||
P = 2^256 - 2^32 - 977 | ||
F = GF(P) | ||
BETA = F(0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee) | ||
|
||
assert(BETA != F(1) and BETA^3 == F(1)) | ||
|
||
orders_done = set() | ||
results = {} | ||
first = True | ||
for b in range(1, P): | ||
# There are only 6 curves (up to isomorphism) of the form y^2=x^3+B. Stop once we have tried all. | ||
if len(orders_done) == 6: | ||
break | ||
|
||
E = EllipticCurve(F, [0, b]) | ||
print("Analyzing curve y^2 = x^3 + %i" % b) | ||
n = E.order() | ||
# Skip curves with an order we've already tried | ||
if n in orders_done: | ||
print("- Isomorphic to earlier curve") | ||
continue | ||
orders_done.add(n) | ||
# Skip curves isomorphic to the real secp256k1 | ||
if n.is_pseudoprime(): | ||
print(" - Isomorphic to secp256k1") | ||
continue | ||
|
||
print("- Finding subgroups") | ||
|
||
# Find what prime subgroups exist | ||
for f, _ in n.factor(): | ||
print("- Analyzing subgroup of order %i" % f) | ||
# Skip subgroups of order >1000 | ||
if f < 4 or f > 1000: | ||
print(" - Bad size") | ||
continue | ||
|
||
# Iterate over X coordinates until we find one that is on the curve, has order f, | ||
# and for which curve isomorphism exists that maps it to X coordinate 1. | ||
for x in range(1, P): | ||
# Skip X coordinates not on the curve, and construct the full point otherwise. | ||
if not E.is_x_coord(x): | ||
continue | ||
G = E.lift_x(F(x)) | ||
|
||
print(" - Analyzing (multiples of) point with X=%i" % x) | ||
|
||
# Skip points whose order is not a multiple of f. Project the point to have | ||
# order f otherwise. | ||
if (G.order() % f): | ||
print(" - Bad order") | ||
continue | ||
G = G * (G.order() // f) | ||
|
||
# Find lambda for endomorphism. Skip if none can be found. | ||
lam = None | ||
for l in Integers(f)(1).nth_root(3, all=True): | ||
if int(l)*G == E(BETA*G[0], G[1]): | ||
lam = int(l) | ||
break | ||
if lam is None: | ||
print(" - No endomorphism for this subgroup") | ||
break | ||
|
||
# Now look for an isomorphism of the curve that gives this point an X | ||
# coordinate equal to 1. | ||
# If (x,y) is on y^2 = x^3 + b, then (a^2*x, a^3*y) is on y^2 = x^3 + a^6*b. | ||
# So look for m=a^2=1/x. | ||
m = F(1)/G[0] | ||
if not m.is_square(): | ||
print(" - No curve isomorphism maps it to a point with X=1") | ||
continue | ||
a = m.sqrt() | ||
rb = a^6*b | ||
RE = EllipticCurve(F, [0, rb]) | ||
|
||
# Use as generator twice the image of G under the above isormorphism. | ||
# This means that generator*(1/2 mod f) will have X coordinate 1. | ||
RG = RE(1, a^3*G[1]) * 2 | ||
# And even Y coordinate. | ||
if int(RG[1]) % 2: | ||
RG = -RG | ||
assert(RG.order() == f) | ||
assert(lam*RG == RE(BETA*RG[0], RG[1])) | ||
|
||
# We have found curve RE:y^2=x^3+rb with generator RG of order f. Remember it | ||
results[f] = {"b": rb, "G": RG, "lambda": lam} | ||
print(" - Found solution") | ||
break | ||
|
||
print("") | ||
|
||
print("") | ||
print("") | ||
print("/* To be put in src/group_impl.h: */") | ||
first = True | ||
for f in sorted(results.keys()): | ||
b = results[f]["b"] | ||
G = results[f]["G"] | ||
print("# %s EXHAUSTIVE_TEST_ORDER == %i" % ("if" if first else "elif", f)) | ||
first = False | ||
print("static const secp256k1_ge secp256k1_ge_const_g = SECP256K1_GE_CONST(") | ||
print(" 0x%08x, 0x%08x, 0x%08x, 0x%08x," % tuple((int(G[0]) >> (32 * (7 - i))) & 0xffffffff for i in range(4))) | ||
print(" 0x%08x, 0x%08x, 0x%08x, 0x%08x," % tuple((int(G[0]) >> (32 * (7 - i))) & 0xffffffff for i in range(4, 8))) | ||
print(" 0x%08x, 0x%08x, 0x%08x, 0x%08x," % tuple((int(G[1]) >> (32 * (7 - i))) & 0xffffffff for i in range(4))) | ||
print(" 0x%08x, 0x%08x, 0x%08x, 0x%08x" % tuple((int(G[1]) >> (32 * (7 - i))) & 0xffffffff for i in range(4, 8))) | ||
print(");") | ||
print("static const secp256k1_fe secp256k1_fe_const_b = SECP256K1_FE_CONST(") | ||
print(" 0x%08x, 0x%08x, 0x%08x, 0x%08x," % tuple((int(b) >> (32 * (7 - i))) & 0xffffffff for i in range(4))) | ||
print(" 0x%08x, 0x%08x, 0x%08x, 0x%08x" % tuple((int(b) >> (32 * (7 - i))) & 0xffffffff for i in range(4, 8))) | ||
print(");") | ||
print("# else") | ||
print("# error No known generator for the specified exhaustive test group order.") | ||
print("# endif") | ||
|
||
print("") | ||
print("") | ||
print("/* To be put in src/scalar_impl.h: */") | ||
first = True | ||
for f in sorted(results.keys()): | ||
lam = results[f]["lambda"] | ||
print("# %s EXHAUSTIVE_TEST_ORDER == %i" % ("if" if first else "elif", f)) | ||
first = False | ||
print("# define EXHAUSTIVE_TEST_LAMBDA %i" % lam) | ||
print("# else") | ||
print("# error No known lambda for the specified exhaustive test group order.") | ||
print("# endif") | ||
print("") |
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
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
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
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
Oops, something went wrong.