def run(self): while True: item = self.queue.get() if item is None: break message, signature, pubkey = item ok = ed25519.verify(signature, message, pubkey) assert ok
seed_ref10 = binascii.unhexlify(x[0][:64]) #public_key_ref10 = binascii.unhexlify(x[0][64:]) sk_ref10 = binascii.unhexlify(x[0]) sk = ed25519.privkey_from_ref10(sk_ref10) pk = ed25519.get_pubkey(sk) assert x[1] == pk.hex() assert x[0] == (seed_ref10 + pk).hex() m = binascii.unhexlify(x[2]) s = ed25519.sign(m, pk, sk) assert ed25519.verify(s, m, pk) if x[3] != (s + m).hex(): sys.stdout.write('\n') sys.stdout.write('! ') sys.stdout.write(line) sys.stdout.write('\n') """ # This part is broken in the original code if len(m) == 0: forgedm = b'x' else: forgedmlen = len(m) print(m.hex()) forgedm = bytes([m[i]+(i==forgedmlen-1) for i in range(forgedmlen)])
destination = rainumbers.decode_account(block['destination']) balance = bytes.fromhex(block['balance']) hashables = [previous, destination, balance] elif type == 'receive': previous = bytes.fromhex(block['previous']) source = bytes.fromhex(block['source']) hashables = [previous, source] elif type == 'open': source = bytes.fromhex(block['source']) representative = rainumbers.decode_account(block['representative']) a = rainumbers.decode_account(block['account']) assert a == account hashables = [source, representative, account] elif type == 'change': previous = bytes.fromhex(block['previous']) representative = rainumbers.decode_account(block['representative']) hashables = [previous, representative] # utx: account, previous, representative, balance, link d = hashlib.blake2b(digest_size=32) for h in hashables: d.update(h) blockhash_computed = d.digest() print('block hash (from file name) :', blockhash.lower()) print('block hash (computed) :', blockhash_computed.hex()) ok = ed25519.verify(signature, blockhash_computed, pubkey) print('Signature:', 'VERIFIED' if ok else 'FAILED')
def handle_packet(self, data, address): if len(data) < 1: return opcode, data = data[0], data[1:] # time if opcode == TIME_SYNC: if len(data) != 32: print("TIME_SYNC packet received with incorrect size") return nonce = data timestamp = struct.pack("!Q", int(time.time() * 1000)) message = timestamp message += ed25519.sign(nonce + timestamp, self.public_key, self.private_key) self.socket.sendto(TIME_SYNC + message, address) elif opcode == CERT_REQUEST_INIT: if len(data) != 96: print("CERT_REQUEST_INIT packet received with incorrect size") return nonce, username, proposed_pubkey = data[:32], data[32:64], data[ 64:96] username = struct.unpack("32p", username)[0] message = ed25519.sign(nonce + username + proposed_pubkey, self.public_key, self.private_key) self.socket.sendto(CERT_REQUEST_INIT + message, address) self.certificate_requests[nonce] = (time.time() + 10, username, proposed_pubkey) elif opcode == CERT_REQUEST_CONFIRM: if len(data) != (32 + 20 + 64): print( "CERT_REQUEST_CONFIRM packet received with incorrect size") return nonce, auth, signature = data[:32], data[32:52], data[52:] if nonce not in self.certificate_requests: print("received CERT_REQUEST_CONFIRM with unknown nonce") return # we don't need to check the timeout - that's done elsewhere timeout, username, proposed_pubkey = self.certificate_requests[ nonce] # only allow one response del self.certificate_requests[nonce] # invalid authentication if username not in self.accounts or hashlib.sha1( nonce + self.accounts[username][1]).digest() != auth: message = nonce message += ed25519.sign(nonce, self.public_key, self.private_key) self.socket.sendto(CERT_REQUEST_INVALID_AUTH + message, address) return if not ed25519.verify(signature, nonce + auth, proposed_pubkey): print("received CERT_REQUEST_CONFIRM with invalid signature") return scalar = ed25519.create_seed() pubkey = ed25519.add_scalar(scalar, proposed_pubkey) userid = struct.pack(">L", self.accounts[username][0]) expiry = struct.pack(">H", round((time.time() / (60 * 60 * 24 * 7)) + 1)) # one week message = scalar message += userid message += expiry message += ed25519.sign(pubkey + userid + expiry, self.public_key, self.private_key) self.socket.sendto(CERT_REQUEST_CONFIRM + message, address)
#!/usr/bin/env python3 import ed25519 message = b'Hello world!' seed = ed25519.create_seed() pubkey, privkey = ed25519.create_keypair(seed) derived_pubkey = ed25519.get_pubkey(privkey) assert derived_pubkey == pubkey signature = ed25519.sign(message, pubkey, privkey) assert len(signature) == 64 res = ed25519.verify(signature, message, pubkey) assert res signature = bytes([255 - signature[0]]) + signature[1:] res = ed25519.verify(signature, message, pubkey) assert not res
def handle_packet(self, data, address): if len(data) < 1: return opcode, data = data[0], data[1:] # time if opcode == TIME_SYNC: if len(data) != 32: print("TIME_SYNC packet received with incorrect size") return nonce = data timestamp = struct.pack("!Q", int(time.time() * 1000)) message = timestamp message += ed25519.sign(nonce + timestamp, self.public_key, self.private_key) self.socket.sendto(TIME_SYNC + message, address) elif opcode == CERT_REQUEST_INIT: if len(data) != 96: print("CERT_REQUEST_INIT packet received with incorrect size") return nonce, username, proposed_pubkey = data[:32], data[32:64], data[64:96] username = struct.unpack("32p", username)[0] message = ed25519.sign(nonce + username + proposed_pubkey, self.public_key, self.private_key) self.socket.sendto(CERT_REQUEST_INIT + message, address) self.certificate_requests[nonce] = (time.time() + 10, username, proposed_pubkey) elif opcode == CERT_REQUEST_CONFIRM: if len(data) != (32 + 20 + 64): print("CERT_REQUEST_CONFIRM packet received with incorrect size") return nonce, auth, signature = data[:32], data[32:52], data[52:] if nonce not in self.certificate_requests: print("received CERT_REQUEST_CONFIRM with unknown nonce") return # we don't need to check the timeout - that's done elsewhere timeout, username, proposed_pubkey = self.certificate_requests[nonce] # only allow one response del self.certificate_requests[nonce] # invalid authentication if username not in self.accounts or hashlib.sha1(nonce + self.accounts[username][1]).digest() != auth: message = nonce message += ed25519.sign(nonce, self.public_key, self.private_key) self.socket.sendto(CERT_REQUEST_INVALID_AUTH + message, address) return if not ed25519.verify(signature, nonce + auth, proposed_pubkey): print("received CERT_REQUEST_CONFIRM with invalid signature") return scalar = ed25519.create_seed() pubkey = ed25519.add_scalar(scalar, proposed_pubkey) userid = struct.pack(">L", self.accounts[username][0]) expiry = struct.pack(">H", round((time.time() / (60 * 60 * 24 * 7)) + 1)) # one week message = scalar message += userid message += expiry message += ed25519.sign(pubkey + userid + expiry, self.public_key, self.private_key) self.socket.sendto(CERT_REQUEST_CONFIRM + message, address)
def handle_packet(self, data, address): if len(data) < 1: return opcode, data = data[0], data[1:] # time sync if opcode == TIME_SYNC: if len(data) != (8 + 64): print("TIME_SYNC packet received with incorrect size") return timestamp, signature = data[:8], data[8:] # make sure the time is actually from the CA AND contains the correct nonce # this implicitly rejects too old responses, because the nonce would have changed already if not ed25519.verify(signature, self.last_network_time_request_nonce + timestamp, self.ca_public_key): return now = time.time() latency_correction = (now - self.last_network_time_request_time) / 2 self.network_time_offset = struct.unpack("!Q", timestamp)[0] / 1000. - latency_correction - now # certificate request reply from the CA elif opcode == CERT_REQUEST_INIT: if len(data) != 64: print("CERT_REQUEST_INIT packet received with incorrect size") return check_message = self.last_certificate_request_nonce + self.username + self.last_certificate_request_public_key signature = data if not ed25519.verify(signature, check_message, self.ca_public_key): print("Got wrong CERT_REQUEST_INIT signature") return message = self.last_certificate_request_nonce message += hashlib.sha1(self.last_certificate_request_nonce + self.password_key).digest() message += ed25519.sign(message, self.last_certificate_request_public_key, self.last_certificate_request_private_key) self.socket.sendto(CERT_REQUEST_CONFIRM + message, address) elif opcode == CERT_REQUEST_CONFIRM: if len(data) != (32 + 4 + 2 + 64): print("Got wrong CERT_REQUEST_CONFIRM signature") return scalar, user_id, expiry, certificate = data[:32], data[32:36], data[36:38], data[38:] public_key, private_key = ed25519.add_scalar(scalar, self.last_certificate_request_public_key, self.last_certificate_request_private_key) if ed25519.verify(certificate, public_key + user_id + expiry, self.ca_public_key): self.public_key = public_key self.private_key = private_key self.certificate = certificate self.user_id = struct.unpack(">L", user_id)[0] expiry = struct.unpack("@H", expiry)[0] print("\nIdentification successful") print("-------------------------") print("User ID: {}".format(self.user_id)) print("Public key: " + binascii.hexlify(self.public_key)) print("Certificate: " + binascii.hexlify(self.certificate)) elif opcode == CERT_REQUEST_INVALID_AUTH: nonce, signature = data[:32], data[32:] # correct signature? if not ed25519.verify(signature, nonce, self.ca_public_key): return # our nonce? if nonce != self.last_certificate_request_nonce: return print("Invalid username or password.") sys.exit(0)
def handle_packet(self, data, address): if len(data) < 1: return opcode, data = data[0], data[1:] # time sync if opcode == TIME_SYNC: if len(data) != (8 + 64): print("TIME_SYNC packet received with incorrect size") return timestamp, signature = data[:8], data[8:] # make sure the time is actually from the CA AND contains the correct nonce # this implicitly rejects too old responses, because the nonce would have changed already if not ed25519.verify( signature, self.last_network_time_request_nonce + timestamp, self.ca_public_key): return now = time.time() latency_correction = (now - self.last_network_time_request_time) / 2 self.network_time_offset = struct.unpack( "!Q", timestamp)[0] / 1000. - latency_correction - now # certificate request reply from the CA elif opcode == CERT_REQUEST_INIT: if len(data) != 64: print("CERT_REQUEST_INIT packet received with incorrect size") return check_message = self.last_certificate_request_nonce + self.username + self.last_certificate_request_public_key signature = data if not ed25519.verify(signature, check_message, self.ca_public_key): print("Got wrong CERT_REQUEST_INIT signature") return message = self.last_certificate_request_nonce message += hashlib.sha1(self.last_certificate_request_nonce + self.password_key).digest() message += ed25519.sign(message, self.last_certificate_request_public_key, self.last_certificate_request_private_key) self.socket.sendto(CERT_REQUEST_CONFIRM + message, address) elif opcode == CERT_REQUEST_CONFIRM: if len(data) != (32 + 4 + 2 + 64): print("Got wrong CERT_REQUEST_CONFIRM signature") return scalar, user_id, expiry, certificate = data[:32], data[ 32:36], data[36:38], data[38:] public_key, private_key = ed25519.add_scalar( scalar, self.last_certificate_request_public_key, self.last_certificate_request_private_key) if ed25519.verify(certificate, public_key + user_id + expiry, self.ca_public_key): self.public_key = public_key self.private_key = private_key self.certificate = certificate self.user_id = struct.unpack(">L", user_id)[0] expiry = struct.unpack("@H", expiry)[0] print("\nIdentification successful") print("-------------------------") print("User ID: {}".format(self.user_id)) print("Public key: " + binascii.hexlify(self.public_key)) print("Certificate: " + binascii.hexlify(self.certificate)) elif opcode == CERT_REQUEST_INVALID_AUTH: nonce, signature = data[:32], data[32:] # correct signature? if not ed25519.verify(signature, nonce, self.ca_public_key): return # our nonce? if nonce != self.last_certificate_request_nonce: return print("Invalid username or password.") sys.exit(0)