|
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