def __init__(self, difficulty: int, nonce: int = 0, holder: int = 0, signature: Signature = Signature()) -> None: SendDifficulty.__init__(self, difficulty, nonce, holder) self.signature: Signature = signature
def __init__( self, version: int, last: bytes, contents: bytes, significant: int, sketchSalt: bytes, sketchCheck: bytes, miner: Union[int, bytes], time: int, proof: int = 0, signature: bytes = Signature().serialize()) -> None: self.version: int = version self.last: bytes = last self.contents: bytes = contents self.significant: int = significant self.sketchSalt: bytes = sketchSalt self.sketchCheck: bytes = sketchCheck self.newMiner: bool = isinstance(miner, bytes) if isinstance(miner, bytes): self.minerKey: bytes = miner else: self.minerNick: int = miner self.time: int = time self.proof: int = proof self.signature: bytes = signature self.rehash()
def __init__( self, txHash: bytes, holders: List[int] = [], signature: Signature = Signature()) -> None: VerificationPacket.__init__(self, txHash, holders) self.signature: Signature = signature
def __init__( self, txHash: bytes, holder: int = 0, signature: Signature = Signature() ) -> None: Verification.__init__(self, txHash, holder) self.signature: Signature = signature
def add(self, verif: SignedVerification) -> None: self.holders.append(verif.holder) if self.signature.isInf(): self.signature = verif.signature else: self.signature = Signature.aggregate( [self.signature, verif.signature])
def fromSignedJSON( json: Dict[str, Any] ) -> Any: return SignedVerification( bytes.fromhex(json["hash"]), json["holder"], Signature(bytes.fromhex(json["signature"])) )
def fromSignedJSON( json: Dict[str, Any] ) -> Any: return SignedDataDifficulty( bytes.fromhex(json["difficulty"]), json["nonce"], json["holder"], Signature(bytes.fromhex(json["signature"])) )
def __init__( self, packets: List[VerificationPacket] = [], elements: List[Element] = [], aggregate: Signature = Signature()) -> None: self.packets: List[VerificationPacket] = list(packets) self.packets.sort(key=lambda packet: packet.hash, reverse=True) self.elements: List[Element] = list(elements) self.aggregate: Signature = aggregate
def __init__(self, e1: Union[SignedVerification, SignedVerificationPacket, SignedSendDifficulty, SignedDataDifficulty], e2: Union[SignedVerification, SignedVerificationPacket, SignedSendDifficulty, SignedDataDifficulty], holder: int = -1) -> None: PartialMeritRemoval.__init__(self, e1, e2, holder) self.partial = False self.se1: SignedElement = e1 self.signature = Signature.aggregate([e1.signature, e2.signature])
def __init__( self, inputs: List[Tuple[bytes, int]], output: bytes, signature: bytes = Signature().serialize()) -> None: self.inputs: List[Tuple[bytes, int]] = inputs self.output: bytes = output self.amount: int = 0 self.signature: bytes = signature self.hash = blake2b(b'\1' + self.signature, digest_size=32).digest()
def fromSignedJSON( json: Dict[str, Any] ) -> Any: holders: List[bytes] = [] for holder in json["holders"]: holders.append(bytes.fromhex(holder)) return SignedMeritRemovalVerificationPacket( SignedVerificationPacket(bytes.fromhex(json["hash"])), holders, Signature(bytes.fromhex(json["signature"])) )
def sign(self, privKeys: List[PrivateKey]) -> None: signatures: List[Signature] = [ privKeys[0].sign(b'\1' + self.inputs[0][0] + self.inputs[0][1].to_bytes(1, "big") + self.output) ] for i in range(1, len(self.inputs)): signatures.append( privKeys[i].sign(b'\1' + self.inputs[i][0] + self.inputs[i][1].to_bytes(1, "big") + self.output)) self.signature = Signature.aggregate(signatures).serialize() self.hash = blake2b(b'\1' + self.signature, digest_size=32).digest()
def __init__( self, packets: List[VerificationPacket] = [], elements: List[Element] = [], aggregate: Signature = Signature()) -> None: self.packets: List[VerificationPacket] = list(packets) self.packets.sort(key=lambda packet: packet.hash, reverse=True) packetsMerkle: List[bytes] = [] for packet in packets: packetsMerkle.append( blake2b(packet.prefix + packet.serialize(), digest_size=32).digest()) self.packetsContents: bytes = merkle(packetsMerkle) self.elements: List[Element] = list(elements) self.aggregate: Signature = aggregate
def fromJSON(keys: Dict[bytes, int], json: Dict[str, Any]) -> Any: packets: List[VerificationPacket] = [] elements: List[Element] = [] for packet in json["transactions"]: packets.append( VerificationPacket(bytes.fromhex(packet["hash"]), packet["holders"])) for element in json["elements"]: if element["descendant"] == "SendDifficulty": elements.append(SendDifficulty.fromJSON(element)) elif element["descendant"] == "DataDifficulty": elements.append(DataDifficulty.fromJSON(element)) elif element["descendant"] == "MeritRemoval": elements.append(MeritRemoval.fromJSON(keys, element)) return BlockBody(packets, elements, Signature(bytes.fromhex(json["aggregate"])))
str(len(packetedChain.blocks)) + ".") #Create a MeritRemoval with random keys. packeted: SignedMeritRemoval = SignedMeritRemoval( SignedMeritRemovalVerificationPacket( SignedVerificationPacket(verifs[1].hash), [ blsPubKey.serialize(), PrivateKey(blake2b( b'\1', digest_size=32).digest()).toPublicKey().serialize(), PrivateKey(blake2b( b'\2', digest_size=32).digest()).toPublicKey().serialize() ], Signature.aggregate([ blsPrivKey.sign(verifs[1].signatureSerialize()), PrivateKey(blake2b(b'\1', digest_size=32).digest()).sign( verifs[1].signatureSerialize()), PrivateKey(blake2b(b'\2', digest_size=32).digest()).sign( verifs[1].signatureSerialize()) ])), SignedMeritRemovalVerificationPacket( SignedVerificationPacket(verifs[2].hash), [ blsPubKey.serialize(), PrivateKey(blake2b( b'\3', digest_size=32).digest()).toPublicKey().serialize(), PrivateKey(blake2b( b'\4', digest_size=32).digest()).toPublicKey().serialize() ], Signature.aggregate([ blsPrivKey.sign(verifs[2].signatureSerialize()), PrivateKey(blake2b(b'\3', digest_size=32).digest()).sign( verifs[2].signatureSerialize()),
def EightyEightTest(rpc: RPC) -> None: #Ed25519 key. edPrivKey: ed25519.SigningKey = ed25519.SigningKey(b'\0' * 32) edPubKey: ed25519.VerifyingKey = edPrivKey.get_verifying_key() #BLS key. blsPrivKey: PrivateKey = PrivateKey( blake2b(b'\0', digest_size=32).digest()) blsPubKey: str = blsPrivKey.toPublicKey().serialize().hex() #Blocks. file: IO[Any] = open("PythonTests/Vectors/Merit/BlankBlocks.json", "r") blocks: List[Dict[str, Any]] = json.loads(file.read()) file.close() #Merit. merit: Merit = Merit() #Spam Filter. dataFilter: SpamFilter = SpamFilter(bytes.fromhex("CC" * 32)) #Handshake with the node. rpc.meros.connect(254, 254, merit.blockchain.blocks[0].header.hash) #Send the first Block. block: Block = Block.fromJSON(merit.blockchain.keys, blocks[0]) merit.blockchain.add(block) rpc.meros.blockHeader(block.header) #Handle sync requests. reqHash: bytes = bytes() while True: msg: bytes = rpc.meros.recv() if MessageType(msg[0]) == MessageType.Syncing: rpc.meros.syncingAcknowledged() elif MessageType(msg[0]) == MessageType.BlockBodyRequest: reqHash = msg[1:33] if reqHash != block.header.hash: raise TestError( "Meros asked for a Block Body that didn't belong to the Block we just sent it." ) #Send the BlockBody. rpc.meros.blockBody(merit.state.nicks, block) elif MessageType(msg[0]) == MessageType.SyncingOver: pass elif MessageType(msg[0]) == MessageType.BlockHeader: break else: raise TestError("Unexpected message sent: " + msg.hex().upper()) #Create two Datas. datas: List[Data] = [Data(bytes(32), edPubKey.to_bytes())] datas.append(Data(datas[0].hash, b"Hello there! General Kenobi.")) for data in datas: #Sign them and have them beat the spam filter. data.sign(edPrivKey) data.beat(dataFilter) #Transmit them. rpc.meros.transaction(data) #Verify both. verifs: List[SignedVerification] = [ SignedVerification(datas[0].hash), SignedVerification(datas[1].hash) ] for verif in verifs: verif.sign(0, blsPrivKey) #Only transmit the second. rpc.meros.signedElement(verifs[1]) sleep(0.5) #Verify the block template has no verifications. if bytes.fromhex( rpc.call("merit", "getBlockTemplate", [blsPubKey])["header"])[36:68] != bytes(32): raise TestError("Block template has Verification Packets.") #Transmit the first signed verification. rpc.meros.signedElement(verifs[0]) sleep(0.5) #Verify the block template has both verifications. template: Dict[str, Any] = rpc.call("merit", "getBlockTemplate", [blsPubKey]) template["header"] = bytes.fromhex(template["header"]) packets: List[VerificationPacket] = [ VerificationPacket(datas[0].hash, [0]), VerificationPacket(datas[1].hash, [0]) ] if template["header"][36:68] != BlockHeader.createContents( merit.state.nicks, packets): raise TestError( "Block template doesn't have both Verification Packets.") #Mine the Block. block = Block( BlockHeader( 0, block.header.hash, BlockHeader.createContents(merit.state.nicks, packets), 1, template["header"][-43:-39], BlockHeader.createSketchCheck(template["header"][-43:-39], packets), 0, int.from_bytes(template["header"][-4:], byteorder="big"), ), BlockBody( packets, [], Signature.aggregate([verifs[0].signature, verifs[1].signature]))) if block.header.serializeHash()[:-4] != template["header"]: raise TestError("Failed to recreate the header.") if block.body.serialize(merit.state.nicks, block.header.sketchSalt, len(packets)) != bytes.fromhex(template["body"]): raise TestError("Failed to recreate the body.") block.mine(blsPrivKey, merit.blockchain.difficulty()) merit.blockchain.add(block) #Publish it. rpc.call("merit", "publishBlock", [ template["id"], (template["header"] + block.header.proof.to_bytes(4, byteorder="big") + block.header.signature + block.body.serialize( merit.state.nicks, block.header.sketchSalt, len(packets))).hex() ]) #Verify the Blockchain. verifyBlockchain(rpc, merit.blockchain)
verif: SignedVerification = SignedVerification(sends[s].hash) verif.sign(h, blsPrivKeys[h]) toAggregate.append(verif.signature) block: Block = Block( BlockHeader( 0, blockchain.last(), BlockHeader.createContents([], list(packets.values())), 1, bytes(4), BlockHeader.createSketchCheck(bytes(4), list(packets.values())), order[1], blockchain.blocks[-1].header.time + 1200 ), BlockBody(list(packets.values()), [], Signature.aggregate(toAggregate)) ) miner: Union[bytes, int] = order[1] if isinstance(miner, bytes): for k in range(len(blsPubKeys)): if miner == blsPubKeys[k].serialize(): block.mine(blsPrivKeys[k], blockchain.difficulty()) break else: block.mine(blsPrivKeys[miner], blockchain.difficulty()) blockchain.add(block) print("Generated Fifty Block " + str(len(blockchain.blocks) - 1) + ".") #Generate another 5 Blocks.
if s not in packets: packets[s] = VerificationPacket(sends[s].hash, []) packets[s].holders.append(h) verif: SignedVerification = SignedVerification(sends[s].hash) verif.sign(h, blsPrivKeys[h]) toAggregate.append(verif.signature) block: Block = Block( BlockHeader( 0, blockchain.last(), BlockHeader.createContents(list(packets.values())), 1, bytes(4), BlockHeader.createSketchCheck(bytes(4), list(packets.values())), order[1], blockchain.blocks[-1].header.time + 1200), BlockBody(list(packets.values()), [], Signature.aggregate(toAggregate))) miner: Union[bytes, int] = order[1] if isinstance(miner, bytes): for k in range(len(blsPubKeys)): if miner == blsPubKeys[k].serialize(): block.mine(blsPrivKeys[k], blockchain.difficulty()) break else: block.mine(blsPrivKeys[miner], blockchain.difficulty()) blockchain.add(block) print("Generated Fifty Block " + str(len(blockchain.blocks) - 1) + ".") #Generate another 5 Blocks. for _ in range(5):
0, blockchain.last(), BlockHeader.createContents([], packets, [mr]), 1, bytes(4), BlockHeader.createSketchCheck(bytes(4), packets), 0, blockchain.blocks[-1].header.time + 1200 ), BlockBody( packets, [mr], Signature.aggregate( [ verifs[0].signature, verifs[1].signature, verifs[2].signature, mr.signature ] ) ) ) #Mine it. block.mine(blsPrivKey, blockchain.difficulty()) #Add it. blockchain.add(block) print("Generated Verify Competing Block " + str(len(blockchain.blocks)) + ".") result: Dict[str, Any] = { "blockchain": blockchain.toJSON(), "datas": [datas[0].toJSON(), datas[1].toJSON(), datas[2].toJSON()],
packets: List[VerificationPacket] = [ VerificationPacket(first.hash, [0]), VerificationPacket(second.hash, [0]), ] #Generate another 6 Blocks. #Next block should have the packets. block: Block = Block( BlockHeader(0, merit.blockchain.last(), BlockHeader.createContents(packets), 1, bytes(4), BlockHeader.createSketchCheck(bytes(4), packets), 0, merit.blockchain.blocks[-1].header.time + 1200), BlockBody( packets, [], Signature.aggregate([firstVerif.signature, secondVerif.signature]))) for _ in range(6): #Mine it. block.mine(blsPrivKey, merit.blockchain.difficulty()) #Add it. merit.add(block) print("Generated Competing Finalized Block " + str(len(merit.blockchain.blocks) - 1) + ".") #Create the next Block. block = Block( BlockHeader(0, merit.blockchain.last(), bytes(32), 1, bytes(4), bytes(32), 0, merit.blockchain.blocks[-1].header.time + 1200), BlockBody())
def TElementTest(rpc: RPC) -> None: #BLS key. blsPrivKey: PrivateKey = PrivateKey( blake2b(b'\0', digest_size=32).digest()) blsPubKey: str = blsPrivKey.toPublicKey().serialize().hex() #Blocks. file: IO[Any] = open("PythonTests/Vectors/Merit/BlankBlocks.json", "r") blocks: List[Dict[str, Any]] = json.loads(file.read()) file.close() #Merit. merit: Merit = Merit() #Handshake with the node. rpc.meros.connect(254, 254, merit.blockchain.blocks[0].header.hash) #Send the first Block. block: Block = Block.fromJSON(merit.blockchain.keys, blocks[0]) merit.blockchain.add(block) rpc.meros.blockHeader(block.header) #Handle sync requests. reqHash: bytes = bytes() while True: msg: bytes = rpc.meros.recv() if MessageType(msg[0]) == MessageType.Syncing: rpc.meros.syncingAcknowledged() elif MessageType(msg[0]) == MessageType.BlockBodyRequest: reqHash = msg[1:33] if reqHash != block.header.hash: raise TestError( "Meros asked for a Block Body that didn't belong to the Block we just sent it." ) #Send the BlockBody. rpc.meros.blockBody(merit.state.nicks, block) elif MessageType(msg[0]) == MessageType.SyncingOver: pass elif MessageType(msg[0]) == MessageType.BlockHeader: break else: raise TestError("Unexpected message sent: " + msg.hex().upper()) #Create and transmit a DataDifficulty. dataDiff: SignedDataDifficulty = SignedDataDifficulty( bytes.fromhex("00" * 32), 0, 0) dataDiff.sign(0, blsPrivKey) rpc.meros.signedElement(dataDiff) sleep(0.5) #Verify the block template has the DataDifficulty. template: Dict[str, Any] = rpc.call("merit", "getBlockTemplate", [blsPubKey]) template["header"] = bytes.fromhex(template["header"]) if template["header"][36:68] != BlockHeader.createContents( merit.state.nicks, [], [dataDiff]): raise TestError("Block template doesn't have the Data Difficulty.") #Mine the Block. block = Block( BlockHeader( 0, block.header.hash, BlockHeader.createContents(merit.state.nicks, [], [dataDiff]), 1, template["header"][-43:-39], BlockHeader.createSketchCheck(template["header"][-43:-39], []), 0, int.from_bytes(template["header"][-4:], byteorder="big"), ), BlockBody([], [dataDiff], dataDiff.signature)) if block.header.serializeHash()[:-4] != template["header"]: raise TestError("Failed to recreate the header.") if block.body.serialize(merit.state.nicks, block.header.sketchSalt) != bytes.fromhex( template["body"]): raise TestError("Failed to recreate the body.") block.mine(blsPrivKey, merit.blockchain.difficulty()) merit.blockchain.add(block) #Publish it. rpc.call("merit", "publishBlock", [ template["id"], (template["header"] + block.header.proof.to_bytes(4, byteorder="big") + block.header.signature + block.body.serialize( merit.state.nicks, block.header.sketchSalt)).hex() ]) #Create and transmit a new DataDifficulty. dataDiff = SignedDataDifficulty(bytes.fromhex("AA" * 32), 1, 0) dataDiff.sign(0, blsPrivKey) rpc.meros.signedElement(dataDiff) sleep(0.5) #Verify the block template has the DataDifficulty. template = rpc.call("merit", "getBlockTemplate", [blsPubKey]) template["header"] = bytes.fromhex(template["header"]) if template["header"][36:68] != BlockHeader.createContents( merit.state.nicks, [], [dataDiff]): raise TestError("Block template doesn't have the new Data Difficulty.") #Create and transmit a new DataDifficulty reusing an existing nonce. signatures: List[Signature] = [dataDiff.signature] dataDiff = SignedDataDifficulty(bytes.fromhex("BB" * 32), 1, 0) dataDiff.sign(0, blsPrivKey) signatures.append(dataDiff.signature) rpc.meros.signedElement(dataDiff) sleep(0.5) #Verify the block template has a MeritRemoval. mr: MeritRemoval = MeritRemoval( SignedDataDifficulty(bytes.fromhex("AA" * 32), 1, 0), SignedDataDifficulty(bytes.fromhex("BB" * 32), 1, 0), False) template = rpc.call("merit", "getBlockTemplate", [blsPubKey]) template["header"] = bytes.fromhex(template["header"]) if template["header"][36:68] != BlockHeader.createContents( merit.state.nicks, [], [mr]): raise TestError("Block template doesn't have the Merit Removal.") #Mine the Block. block = Block( BlockHeader( 0, block.header.hash, BlockHeader.createContents(merit.state.nicks, [], [mr]), 1, template["header"][-43:-39], BlockHeader.createSketchCheck(template["header"][-43:-39], []), 0, int.from_bytes(template["header"][-4:], byteorder="big"), ), BlockBody([], [mr], Signature.aggregate(signatures))) if block.header.serializeHash()[:-4] != template["header"]: raise TestError("Failed to recreate the header.") if block.body.serialize(merit.state.nicks, block.header.sketchSalt) != bytes.fromhex( template["body"]): raise TestError("Failed to recreate the body.") block.mine(blsPrivKey, merit.blockchain.difficulty()) merit.blockchain.add(block) #Publish it. rpc.call("merit", "publishBlock", [ template["id"], (template["header"] + block.header.proof.to_bytes(4, byteorder="big") + block.header.signature + block.body.serialize( merit.state.nicks, block.header.sketchSalt)).hex() ]) #Verify the Blockchain. verifyBlockchain(rpc, merit.blockchain)
send.sign(edPrivKey) send.beat(sendFilter) transactions.add(send) packets.append(VerificationPacket(send.hash, [i])) verif = SignedVerification(send.hash) verif.sign(i, blsPrivKeys[i]) toAggregate.append(verif.signature) #Archive the Packets and close the Epoch. block = Block( BlockHeader(0, blockchain.last(), BlockHeader.createContents(packets), 1, bytes(4), BlockHeader.createSketchCheck(bytes(4), packets), 0, blockchain.blocks[-1].header.time + 1200), BlockBody(packets, [], Signature.aggregate(toAggregate))) for _ in range(6): #Mine it. block.mine(blsPrivKeys[0], blockchain.difficulty()) #Add it. blockchain.add(block) print("Generated Competing Block " + str(len(blockchain.blocks)) + ".") #Create the next Block. block = Block( BlockHeader(0, blockchain.last(), bytes(32), 1, bytes(4), bytes(32), 0, blockchain.blocks[-1].header.time + 1200), BlockBody()) #Save the appended data (3 Blocks and 12 Sends). result: Dict[str, Any] = {
#Verify them. verifs: List[List[SignedVerification]] = [] for data in datas: verifs.append( [SignedVerification(data.hash), SignedVerification(data.hash)]) for v in range(2): verifs[-1][v].sign(v, blsPrivKeys[v]) #Create the packets. packets: List[SignedVerificationPacket] = [] for packet in verifs: packets.append( SignedVerificationPacket( packet[0].hash, [0, 1], Signature.aggregate([packet[0].signature, packet[1].signature]))) #Create Blocks containing these packets. for packet in packets: block = Block( BlockHeader(0, merit.blockchain.last(), BlockHeader.createContents([], [packet]), 1, bytes(4), BlockHeader.createSketchCheck(bytes(4), [packet]), 1, merit.blockchain.blocks[-1].header.time + 1200), BlockBody([packet], [], packet.signature)) block.mine(blsPrivKeys[1], merit.blockchain.difficulty()) merit.add(block) print("Generated Aggregated Claim Block " + str(len(merit.blockchain.blocks) - 1) + ".") #Generate another 5 Blocks to close the Epochs.