A secp256k1 public key
| 219 | SECP256K1_ORDER_HALF = SECP256K1_ORDER // 2 |
| 220 | |
| 221 | class ECPubKey(): |
| 222 | """A secp256k1 public key""" |
| 223 | |
| 224 | def __init__(self): |
| 225 | """Construct an uninitialized public key""" |
| 226 | self.valid = False |
| 227 | |
| 228 | def set(self, data): |
| 229 | """Construct a public key from a serialization in compressed or uncompressed format""" |
| 230 | if (len(data) == 65 and data[0] == 0x04): |
| 231 | p = (int.from_bytes(data[1:33], 'big'), int.from_bytes(data[33:65], 'big'), 1) |
| 232 | self.valid = SECP256K1.on_curve(p) |
| 233 | if self.valid: |
| 234 | self.p = p |
| 235 | self.compressed = False |
| 236 | elif (len(data) == 33 and (data[0] == 0x02 or data[0] == 0x03)): |
| 237 | x = int.from_bytes(data[1:33], 'big') |
| 238 | if SECP256K1.is_x_coord(x): |
| 239 | p = SECP256K1.lift_x(x) |
| 240 | # Make the Y coordinate odd if required (lift_x always produces |
| 241 | # a point with an even Y coordinate). |
| 242 | if data[0] & 1: |
| 243 | p = SECP256K1.negate(p) |
| 244 | self.p = p |
| 245 | self.valid = True |
| 246 | self.compressed = True |
| 247 | else: |
| 248 | self.valid = False |
| 249 | else: |
| 250 | self.valid = False |
| 251 | |
| 252 | @property |
| 253 | def is_compressed(self): |
| 254 | return self.compressed |
| 255 | |
| 256 | @property |
| 257 | def is_valid(self): |
| 258 | return self.valid |
| 259 | |
| 260 | def get_bytes(self): |
| 261 | assert(self.valid) |
| 262 | p = SECP256K1.affine(self.p) |
| 263 | if p is None: |
| 264 | return None |
| 265 | if self.compressed: |
| 266 | return bytes([0x02 + (p[1] & 1)]) + p[0].to_bytes(32, 'big') |
| 267 | else: |
| 268 | return bytes([0x04]) + p[0].to_bytes(32, 'big') + p[1].to_bytes(32, 'big') |
| 269 | |
| 270 | def verify_ecdsa(self, sig, msg, low_s=True): |
| 271 | """Verify a strictly DER-encoded ECDSA signature against this pubkey. |
| 272 | |
| 273 | See https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm for the |
| 274 | ECDSA verifier algorithm""" |
| 275 | assert(self.valid) |
| 276 | |
| 277 | # Extract r and s from the DER formatted signature. Return false for |
| 278 | # any DER encoding errors. |
no outgoing calls
no test coverage detected