|
6 | 6 | anything but tests.""" |
7 | 7 |
|
8 | 8 | import random |
| 9 | +import secrets |
9 | 10 | import unittest |
10 | 11 |
|
11 | 12 | from .key import modsqrt, SECP256K1, SECP256K1_FIELD_SIZE, SECP256K1_G, SECP256K1_ORDER |
@@ -103,35 +104,47 @@ def r(x,y,i): |
103 | 104 |
|
104 | 105 | def encode(P): |
105 | 106 | while True: |
106 | | - u = field_random() |
107 | | - T = curve_negate(f(u)) |
108 | | - Q = curve_add(T, P) |
109 | | - if is_infinity(Q): Q = T |
| 107 | + u = fe(random.randrange(1, SECP256K1_ORDER)) |
| 108 | + fe1 = f(u) |
| 109 | + # convert fe1 to jacobian form for EC operations |
| 110 | + fe1 = (fe1[0].val, fe1[1].val, 1) |
| 111 | + T = SECP256K1.negate(fe1) |
| 112 | + Q = SECP256K1.add(T, P) |
| 113 | + if SECP256K1.on_curve(Q) is None: |
| 114 | + Q = T |
110 | 115 | j = secrets.choice([1,2,3,4]) |
111 | | - v = r(Q, j) |
112 | | - if v is not Nothing: return (u, v) |
| 116 | + Q = SECP256K1.affine(Q) |
| 117 | + v = r(fe(Q[0]), fe(Q[1]), j) |
| 118 | + if v is not None: |
| 119 | + return (u, v) |
113 | 120 |
|
114 | 121 | def decode(u, v): |
115 | | - T = f(u) |
116 | | - P = curve_add(T, f(v)) |
117 | | - if is_infinity(P): P = T |
118 | | - return P |
| 122 | + fe1 = f(u) |
| 123 | + fe2 = f(v) |
| 124 | + # convert fe1 and fe2 to jacobian form for EC operations |
| 125 | + jac1 = (fe1[0].val, fe1[1].val, 1) |
| 126 | + jac2 = (fe2[0].val, fe2[1].val, 1) |
| 127 | + T = jac1 |
| 128 | + S = jac2 |
| 129 | + P = SECP256K1.affine(SECP256K1.add(T, S)) |
| 130 | + if P is None: |
| 131 | + P = T # affine() returns None if at infinity. |
| 132 | + return (fe(P[0]), fe(P[1])) |
119 | 133 |
|
120 | 134 | P = SECP256K1_FIELD_SIZE |
121 | 135 | FIELD_BITS = P.bit_length() |
122 | 136 | FIELD_BYTES = (FIELD_BITS + 7) // 8 |
123 | | -PAD_BITS = FIELD_BYTES*8 - FIELD_BITS |
124 | 137 |
|
125 | 138 | def encode_bytes(P): |
126 | 139 | u, v = encode(P) |
127 | | - up = u + secrets.randbits(PAD_BITS) << FIELD_BITS |
128 | | - vp = v + secrets.randbits(PAD_BITS) << FIELD_BITS |
| 140 | + up = u.val # since, PAD_BITS is 0, padding and masking can be left out |
| 141 | + vp = v.val |
129 | 142 | return up.to_bytes(FIELD_BYTES, 'big') + vp.to_bytes(FIELD_BYTES, 'big') |
130 | 143 |
|
131 | 144 | def decode_bytes(enc): |
132 | 145 | u = (int.from_bytes(enc[:FIELD_BYTES], 'big') & ((1 << FIELD_BITS) - 1)) % P |
133 | 146 | v = (int.from_bytes(enc[FIELD_BYTES:], 'big') & ((1 << FIELD_BITS) - 1)) % P |
134 | | - return decode(u, v) |
| 147 | + return decode(fe(u), fe(v)) |
135 | 148 |
|
136 | 149 | def SECP256K1_FE_CONST(d7, d6, d5, d4, d3, d2, d1, d0): |
137 | 150 | n = [] |
|
0 commit comments