|
11 | 11 | #include "field.h" |
12 | 12 | #include "group.h" |
13 | 13 |
|
14 | | -/* These points can be generated in sage as follows: |
| 14 | +/* These exhaustive group test orders and generators are chosen such that: |
| 15 | + * - The field size is equal to that of secp256k1, so field code is the same. |
| 16 | + * - The curve equation is of the form y^2=x^3+B for some constant B. |
| 17 | + * - The order is less than 1000 to permit exhaustive testing. |
| 18 | + * - The order is a multiple of 3 plus 1, enabling the endomorphism optimization. |
| 19 | + * - The generator is 2*P, where P has X coefficient equal to 1. |
15 | 20 | * |
16 | | - * 0. Setup a worksheet with the following parameters. |
17 | | - * b = 4 # whatever secp256k1_fe_const_b will be set to |
18 | | - * F = FiniteField (0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F) |
19 | | - * C = EllipticCurve ([F (0), F (b)]) |
| 21 | + * They can generated with the following Sage code: |
20 | 22 | * |
21 | | - * 1. Determine all the small orders available to you. (If there are |
22 | | - * no satisfactory ones, go back and change b.) |
23 | | - * print C.order().factor(limit=1000) |
| 23 | + * # Define field size and field |
| 24 | + * P = 2^256 - 2^32 - 977 |
| 25 | + * F = GF(P) |
24 | 26 | * |
25 | | - * 2. Choose an order as one of the prime factors listed in the above step. |
26 | | - * (You can also multiply some to get a composite order, though the |
27 | | - * tests will crash trying to invert scalars during signing.) We take a |
28 | | - * random point and scale it to drop its order to the desired value. |
29 | | - * There is some probability this won't work; just try again. |
30 | | - * order = 199 |
31 | | - * P = C.random_point() |
32 | | - * P = (int(P.order()) / int(order)) * P |
33 | | - * assert(P.order() == order) |
| 27 | + * orders_done = set() |
| 28 | + * first = True |
| 29 | + * for b in range(1, P): |
| 30 | + * E = EllipticCurve(F, [0, b]) |
| 31 | + * n = E.order() |
| 32 | + * # Skip curves isomorphic to the real secp256k1 |
| 33 | + * if n.is_pseudoprime(): |
| 34 | + * continue |
| 35 | + * # Skip curves with an order we've already tried |
| 36 | + * if n in orders_done: |
| 37 | + * continue |
| 38 | + * orders_done.add(n) |
34 | 39 | * |
35 | | - * 3. Print the values. You'll need to use a vim macro or something to |
36 | | - * split the hex output into 4-byte chunks. |
37 | | - * print "%x %x" % P.xy() |
| 40 | + * # Find what prime subgroups exist |
| 41 | + * for f, _ in n.factor(): |
| 42 | + * # Skip subgroups of order >1000 |
| 43 | + * if f > 1000: |
| 44 | + * continue |
| 45 | + * # Skip subgroups that are not 3n+1 (needed for endomorphism) |
| 46 | + * if f % 3 != 1: |
| 47 | + * continue |
| 48 | + * |
| 49 | + * for x in range(1, P): |
| 50 | + * if (F(x)^3+F(b)).is_square(): |
| 51 | + * # X coordinate x exists on curve y^2=x^3+b |
| 52 | + * G = E.lift_x(F(x)) |
| 53 | + * # We need a point whose order is at (a multiple of) our desired order |
| 54 | + * if (G.order() % f): |
| 55 | + * continue |
| 56 | + * # Project into subgroup of desired order |
| 57 | + * G = G * (G.order() // f) |
| 58 | + * assert G.order() == f |
| 59 | + * |
| 60 | + * # Now look for an isomorphism of the curve that gives this generator X |
| 61 | + * # coordinate equal to 1. |
| 62 | + * # 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. |
| 63 | + * # So look for m=a^2=1/x. |
| 64 | + * m = F(1)/G[0] |
| 65 | + * if not m.is_square(): |
| 66 | + * continue |
| 67 | + * rb = b*m^3 |
| 68 | + * RE = EllipticCurve(F, [0, rb]) |
| 69 | + * # Use as generator twice the point with this low X coordinate (like secp256k1!) |
| 70 | + * RG = RE.lift_x(1) * 2 |
| 71 | + * # And even Y coordinate. |
| 72 | + * if int(RG[1]) % 2: |
| 73 | + * RG = -RG |
| 74 | + * |
| 75 | + * if first: |
| 76 | + * print("# if EXHAUSTIVE_TEST_ORDER == %i" % f) |
| 77 | + * first = False |
| 78 | + * else: |
| 79 | + * print("# elif EXHAUSTIVE_TEST_ORDER == %i" % f) |
| 80 | + * print("static const secp256k1_ge secp256k1_ge_const_g = SECP256K1_GE_CONST(") |
| 81 | + * print(" 0x%08x, 0x%08x, 0x%08x, 0x%08x," % tuple((int(RG[0]) >> (32 * (7 - i))) & 0xffffffff for i in range(4))) |
| 82 | + * print(" 0x%08x, 0x%08x, 0x%08x, 0x%08x," % tuple((int(RG[0]) >> (32 * (7 - i))) & 0xffffffff for i in range(4, 8))) |
| 83 | + * print(" 0x%08x, 0x%08x, 0x%08x, 0x%08x," % tuple((int(RG[1]) >> (32 * (7 - i))) & 0xffffffff for i in range(4))) |
| 84 | + * print(" 0x%08x, 0x%08x, 0x%08x, 0x%08x" % tuple((int(RG[1]) >> (32 * (7 - i))) & 0xffffffff for i in range(4, 8))) |
| 85 | + * print(");") |
| 86 | + * print("static const secp256k1_fe secp256k1_fe_const_b = SECP256K1_FE_CONST(") |
| 87 | + * print(" 0x%08x, 0x%08x, 0x%08x, 0x%08x," % tuple((int(rb) >> (32 * (7 - i))) & 0xffffffff for i in range(4))) |
| 88 | + * print(" 0x%08x, 0x%08x, 0x%08x, 0x%08x" % tuple((int(rb) >> (32 * (7 - i))) & 0xffffffff for i in range(4, 8))) |
| 89 | + * print(");") |
| 90 | + * break |
| 91 | + * |
| 92 | + * if len(orders_done) == 5: |
| 93 | + * break |
| 94 | + * |
| 95 | + * print("# else") |
| 96 | + * print("# error No known generator for the specified exhaustive test group order.") |
| 97 | + * print("# endif") |
38 | 98 | */ |
39 | 99 | #if defined(EXHAUSTIVE_TEST_ORDER) |
40 | | -# if EXHAUSTIVE_TEST_ORDER == 199 |
| 100 | +# if EXHAUSTIVE_TEST_ORDER == 13 |
41 | 101 | static const secp256k1_ge secp256k1_ge_const_g = SECP256K1_GE_CONST( |
42 | | - 0xFA7CC9A7, 0x0737F2DB, 0xA749DD39, 0x2B4FB069, |
43 | | - 0x3B017A7D, 0xA808C2F1, 0xFB12940C, 0x9EA66C18, |
44 | | - 0x78AC123A, 0x5ED8AEF3, 0x8732BC91, 0x1F3A2868, |
45 | | - 0x48DF246C, 0x808DAE72, 0xCFE52572, 0x7F0501ED |
| 102 | + 0xc3459c3d, 0x35326167, 0xcd86cce8, 0x07a2417f, |
| 103 | + 0x5b8bd567, 0xde8538ee, 0x0d507b0c, 0xd128f5bb, |
| 104 | + 0x8e467fec, 0xcd30000a, 0x6cc1184e, 0x25d382c2, |
| 105 | + 0xa2f4494e, 0x2fbe9abc, 0x8b64abac, 0xd005fb24 |
46 | 106 | ); |
47 | | - |
48 | | -static const secp256k1_fe secp256k1_fe_const_b = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 4); |
49 | | - |
50 | | -# elif EXHAUSTIVE_TEST_ORDER == 13 |
| 107 | +static const secp256k1_fe secp256k1_fe_const_b = SECP256K1_FE_CONST( |
| 108 | + 0x3d3486b2, 0x159a9ca5, 0xc75638be, 0xb23a69bc, |
| 109 | + 0x946a45ab, 0x24801247, 0xb4ed2b8e, 0x26b6a417 |
| 110 | +); |
| 111 | +# elif EXHAUSTIVE_TEST_ORDER == 199 |
51 | 112 | static const secp256k1_ge secp256k1_ge_const_g = SECP256K1_GE_CONST( |
52 | | - 0xedc60018, 0xa51a786b, 0x2ea91f4d, 0x4c9416c0, |
53 | | - 0x9de54c3b, 0xa1316554, 0x6cf4345c, 0x7277ef15, |
54 | | - 0x54cb1b6b, 0xdc8c1273, 0x087844ea, 0x43f4603e, |
55 | | - 0x0eaf9a43, 0xf6effe55, 0x939f806d, 0x37adf8ac |
| 113 | + 0x226e653f, 0xc8df7744, 0x9bacbf12, 0x7d1dcbf9, |
| 114 | + 0x87f05b2a, 0xe7edbd28, 0x1f564575, 0xc48dcf18, |
| 115 | + 0xa13872c2, 0xe933bb17, 0x5d9ffd5b, 0xb5b6e10c, |
| 116 | + 0x57fe3c00, 0xbaaaa15a, 0xe003ec3e, 0x9c269bae |
| 117 | +); |
| 118 | +static const secp256k1_fe secp256k1_fe_const_b = SECP256K1_FE_CONST( |
| 119 | + 0x2cca28fa, 0xfc614b80, 0x2a3db42b, 0x00ba00b1, |
| 120 | + 0xbea8d943, 0xdace9ab2, 0x9536daea, 0x0074defb |
| 121 | +); |
| 122 | +# elif EXHAUSTIVE_TEST_ORDER == 7 |
| 123 | +static const secp256k1_ge secp256k1_ge_const_g = SECP256K1_GE_CONST( |
| 124 | + 0x3629054c, 0x34e70740, 0x5d009072, 0x3172630c, |
| 125 | + 0x3b93b9fe, 0x53d21c61, 0x3fd29d22, 0xed48a4ca, |
| 126 | + 0x165c881d, 0x0a95ff40, 0xc81b3e2d, 0xa9be43e0, |
| 127 | + 0xca5a8953, 0xa2fd0196, 0xf718e5cb, 0x21d245d8 |
| 128 | +); |
| 129 | +static const secp256k1_fe secp256k1_fe_const_b = SECP256K1_FE_CONST( |
| 130 | + 0x168b921c, 0xe98a84e1, 0x2e977057, 0x29f0a9c1, |
| 131 | + 0x5bce37e9, 0x94c30aed, 0xde3460ff, 0x71ac095f |
56 | 132 | ); |
57 | | - |
58 | | -static const secp256k1_fe secp256k1_fe_const_b = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 2); |
59 | | - |
60 | 133 | # else |
61 | 134 | # error No known generator for the specified exhaustive test group order. |
62 | 135 | # endif |
|
0 commit comments