def generatePublicKey(privateKeyBytes): """uncompressed public key, 65 sized byte array, starting with 04 followed by the x and y coord""" privateKeyValue = int(privateKeyBytes.hex(), 16) publicKeyPoint = EccMultiply(GPoint, privateKeyValue) (x, y) = publicKeyPoint return paddedBytes(4, 1) + paddedBytes(x, 32) + paddedBytes(y, 32)
def tx(self, txHash): txHashBytes = paddedBytes(int(txHash, base=16), 32) for (_, block) in self.relayNode.blocks.items(): for tx in block.transactions: if tx.toHash() == txHashBytes: return tx
def _base58Decode(address): result = 0 for c in address: result *= 58 result += codeLookup[c] return paddedBytes(result, 25)
def compressPublicKey(publicKeyBytes): """compressed public key is 33 bytes starting with 02 or 03""" if (len(publicKeyBytes) != 65 or publicKeyBytes[0] != 4): raise ValueError("Uncompressed public key must start with 04 byte followed by 64 bytes.") xBytes = publicKeyBytes[1:33] yBytes = publicKeyBytes[33:] leadingByte = paddedBytes(2 + int(yBytes.hex(), base=16) % 2, 1) return leadingByte + xBytes
def uncompressPublicKey(compressedPublicKeyBytes): if (len(compressedPublicKeyBytes) != 33): raise ValueError("Compressed public key must be 33 bytes long.") leadingByte = compressedPublicKeyBytes[0] if (leadingByte != 2 and leadingByte != 3): raise ValueError("Leading byte of compressed public key must begin with 02 or 03 byte.") x = int(compressedPublicKeyBytes[1:].hex(), base=16) y_square = (pow(x, 3, Pcurve) + Bcurve) % Pcurve # https://stackoverflow.com/questions/43629265/deriving-an-ecdsa-uncompressed-public-key-from-a-compressed-one/43654055 y_sq_sq_rt = pow(y_square, (Pcurve + 1) // 4, Pcurve) # if leadingByte and odd/evenness do not match we negate y_sq_sq_rt if ((leadingByte == 2 and y_sq_sq_rt % 2 == 1) or (leadingByte == 3 and y_sq_sq_rt % 2 == 0)): y = (-y_sq_sq_rt) % Pcurve else: y = y_sq_sq_rt return paddedBytes(4, 1) + paddedBytes(x, 32) + paddedBytes(y, 32)
def block(self, blockHash): blockHashBytes = paddedBytes(int(blockHash, base=16), 32) return self.relayNode.blocks[blockHashBytes]
def toHash(self): return sha256(self.toBytes() + paddedBytes(self.blockHeight)).digest()
def toBytes(self): return paddedBytes(self.amount, 8) + self.address.encode()
def toBytes(self): return self.prevTxHash + paddedBytes(self.prevTxOutIndex, 4)
def generatePrivateKey(): """private key as a 32 sized byte array""" privateKey = random.getrandbits(256) return paddedBytes(privateKey, 32)