def sign(msg_hash, pk, k): msg_hash = bytes_to_int(msg_hash) r, y = mul(CURVE.G, k) s = inverse(k, CURVE.n) * (msg_hash + r * bytes_to_int(pk)) % CURVE.n _v = (y % 2) ^ (0 if s * 2 < CURVE.n else 1) s = s if s * 2 < CURVE.n else CURVE.n - s v = '01' if _v == 1 else '00' sig = int_to_bytes32(r) + int_to_bytes32(s) assert len(sig) == 64 return sig.hex() + v
async def recover(msg_hash, sig): r, s, v = parse_curve(sig) x = r a = ((x * x * x) + (CURVE.a * x) + CURVE.b) % CURVE.p b = pow(a, (CURVE.p + 1) // 4, CURVE.p) y = b if (b - (v % 2)) % 2 == 0 else CURVE.p - b e = bytes_to_int(msg_hash) mg = mtx_mul((CURVE.Gx, CURVE.Gy, 1), (CURVE.n - e) % CURVE.n) xy = mtx_mul((x, y, 1), s) _xy = mtx_add(mg, xy) mtx = mtx_mul(_xy, inverse(r, CURVE.n)) p, q = from_mtx(mtx) return int_to_bytes32(p) + int_to_bytes32(q)
def commit(self, block: BaseBlock): self.db.put(Lookup.top_header(), int_to_bytes32(block.header.num_height)) # not padding. self.db.put(int_to_bytes32(block.header.num_height), self.serialize(block.header)) self.db.put(block.hash, self.serialize(block)) # Lookup(height, index) -> # block tx root -> Trie.root = root hash -> Trie.get(index-key) for index, tx in enumerate(block.list_transactions): self._set_transaction_from_lookup( block.height, index, tx ) for index, vote in enumerate(block.list_vote): self._set_vote_from_lookup( block.height, index, vote )
def make_hash_root(list_obj): trie = prepare_single_trie() for seek_index, obj in enumerate(list_obj): trie_key = get_trie_key(int_to_bytes32(seek_index)) trie.put(trie_key, obj.to_dict()) return trie
def get_transaction_from_lookup(self, tx_hash) -> BaseTransaction: lookup = Lookup.transaction(tx_hash) if lookup in self.db: height, seek_index = loads(self.db.get(lookup)) header = self.get_header_from_height(height) tx_root = header.hash_transaction_root trie = prepare_trie(tx_root, self.db) trie_key = get_trie_key(int_to_bytes32(seek_index)) tx = trie.get(trie_key) return tx
def get_receipt(self, tx_hash): lookup = Lookup.transaction(tx_hash) if lookup in self.db: height, seek_index = loads(self.db.get(lookup)) header = self.get_header_from_height(height) receipt_root = header.hash_receipt_root trie = prepare_trie(receipt_root, self.db) trie_key = get_trie_key(int_to_bytes32(seek_index)) receipt = trie.get(trie_key) return receipt
def get_vote_from_lookup(self, vote_hash) -> BaseVote: lookup = Lookup.vote(vote_hash) if lookup in self.db: height, seek_index = loads(self.db.get(lookup)) header = self.get_header_from_height(height) vote_root = header.hash_vote_root trie = prepare_trie(vote_root, self.db) trie_key = get_trie_key(int_to_bytes32(seek_index)) vote = trie.get(trie_key) return vote
def set_minimum(self, value): self._db.put(Lookup.minimum(), int_to_bytes32(value))
def get_header_from_height(self, height) -> BaseHeader: raw_header = self.db.get(int_to_bytes32(height)) return self.deserialize(raw_header, HEADER_CONTEXT)