|
8 | 8 | import random
|
9 | 9 | import unittest
|
10 | 10 |
|
11 |
| -from .key import modsqrt, SECP256K1, SECP256K1_G, SECP256K1_ORDER |
| 11 | +from .key import modsqrt, SECP256K1, SECP256K1_FIELD_SIZE, SECP256K1_G, SECP256K1_ORDER |
12 | 12 |
|
13 | 13 | class fe:
|
14 | 14 | """Prime field over 2^256 - 2^32 - 977"""
|
@@ -101,6 +101,38 @@ def r(x,y,i):
|
101 | 101 | else:
|
102 | 102 | return -u
|
103 | 103 |
|
| 104 | +def encode(P): |
| 105 | + 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 |
| 110 | + j = secrets.choice([1,2,3,4]) |
| 111 | + v = r(Q, j) |
| 112 | + if v is not Nothing: return (u, v) |
| 113 | + |
| 114 | +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 |
| 119 | + |
| 120 | +P = SECP256K1_FIELD_SIZE |
| 121 | +FIELD_BITS = P.bit_length() |
| 122 | +FIELD_BYTES = (FIELD_BITS + 7) // 8 |
| 123 | +PAD_BITS = FIELD_BYTES*8 - FIELD_BITS |
| 124 | + |
| 125 | +def encode_bytes(P): |
| 126 | + u, v = encode(P) |
| 127 | + up = u + secrets.randbits(PAD_BITS) << FIELD_BITS |
| 128 | + vp = v + secrets.randbits(PAD_BITS) << FIELD_BITS |
| 129 | + return up.to_bytes(FIELD_BYTES, 'big') + vp.to_bytes(FIELD_BYTES, 'big') |
| 130 | + |
| 131 | +def decode_bytes(enc): |
| 132 | + u = (int.from_bytes(enc[:FIELD_BYTES], 'big') & ((1 << FIELD_BITS) - 1)) % P |
| 133 | + v = (int.from_bytes(enc[FIELD_BYTES:], 'big') & ((1 << FIELD_BITS) - 1)) % P |
| 134 | + return decode(u, v) |
| 135 | + |
104 | 136 | def SECP256K1_FE_CONST(d7, d6, d5, d4, d3, d2, d1, d0):
|
105 | 137 | n = []
|
106 | 138 | n.append(d0 | (((d1) & 0xFFFFF) << 32))
|
|
0 commit comments