File size: 7,562 Bytes
1d1124e d75dabd 1d1124e d75dabd 1d1124e d75dabd 1d1124e d75dabd 1d1124e d75dabd 1d1124e d75dabd 1d1124e d75dabd 1d1124e d75dabd 1d1124e d75dabd 1d1124e d75dabd 1d1124e 0fdd317 1d1124e |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 |
# Contains a set of useful functions
import pandas as pd
from concrete import fhe
from config import circuit_filepath, keys_filepath
import streamlit as st
import folium
from streamlit_folium import st_folium
def set_up_server():
"""Load a server instance from a specified circuit file
Raises:
OSError: If there is an issue loading the FHE server.
Returns:
concrete.fhe.compilation.server.Server: A server instance loaded from the circuit file.
"""
try:
server = fhe.Server.load(circuit_filepath)
except OSError as e:
raise OSError(f"Something went wrong with the circuit. Make sure that the circuit \
exists in {circuit_filepath}.If not run python generate_circuit.py.") from e
return server
def set_up_client(serialized_client_specs):
"""Generate a client instance from a specified circuit file
Args:
serialized_client_specs (bytes): A serialized client specs
Returns:
concrete.fhe.compilation.client.Client: A client instance created from the client specs
"""
client_specs = fhe.ClientSpecs.deserialize(serialized_client_specs)
client = fhe.Client(client_specs)
return client
def display_encrypted(encrypted_object):
"""Display a truncated representation of an encrypted object as a hexadecimal string
Args:
encrypted_object (bytes): A serialized encrypted object to display
Returns:
str: A truncated hexadecimal representation of the encrypted object
"""
encoded_text = encrypted_object.hex()
res = '...' + encoded_text[-10:]
return res
def compute_shortest_path(nodes_nb, client, server):
"""Calculate the shortest path between two nodes
Args:
nodes_nb (int): The number of nodes in the network
client (concrete.fhe.compilation.client.Client): A client instance
server (concrete.fhe.compilation.server.Server): A server instance
Returns:
List[bytes]: A list of encrypted values representing the path
"""
deserialized_origin = fhe.Value.deserialize(st.session_state['encrypted_origin'])
deserialized_destination = fhe.Value.deserialize(st.session_state['encrypted_destination'])
deserialized_evaluation_keys = fhe.EvaluationKeys.deserialize(st.session_state['evaluation_key'])
client.keys.load_if_exists_generate_and_save_otherwise(keys_filepath)
origin = st.session_state['origin_node']
destination = st.session_state['destination_node']
encrypted_path = [st.session_state['encrypted_origin'], ]
o, d = deserialized_origin, deserialized_destination
for _ in range(nodes_nb):
if origin == destination:
break
o = server.run(o, d, evaluation_keys=deserialized_evaluation_keys)
origin = client.decrypt(o)
encrypted_path.append(o.serialize())
return encrypted_path
def generate_path(shortest_path, roads):
"""Generate a path from a list of nodes using road data.
Args:
shortest_path (List[int]): A list of nodes representing the shortest path.
roads (geopandas.DataFrame): A DataFrame containing the ways between the nodes.
Returns:
pandas.DataFrame: A DataFrame representing the road segments that form the shortest path.
"""
pairs_list = []
for i in range(len(shortest_path) - 1):
current_element = shortest_path[i]
next_element = shortest_path[i + 1]
result = roads.groupby('way_id').filter(lambda x: set([current_element, next_element]).issubset(x['node_id']))
pairs_list.append(result)
final_result = pd.concat(pairs_list)
return final_result
def decrypt_shortest_path(client):
"""Decrypt and store the shortest path in the session state
Args:
client (concrete.fhe.compilation.client.Client): A client instance
"""
client.keys.load_if_exists_generate_and_save_otherwise(keys_filepath)
path = []
for enc_value in st.session_state['encrypted_shortest_path']:
deserialized_result = fhe.Value.deserialize(enc_value)
path.append(client.decrypt(deserialized_result))
st.session_state['decrypted_result'] = path
def init_session():
"""Initialize the Streamlit session and layout configuration.
Returns:
Streamlit.columns: A tuple of Streamlit columns for layout customization.
"""
st.set_page_config(layout="wide")
if 'markers' not in st.session_state:
st.session_state['markers'] = []
if 'server_side' not in st.session_state:
st.session_state['server_side'] = []
if 'client_side' not in st.session_state:
st.session_state['client_side'] = []
c1, c2, c3 = st.columns([1, 3, 1])
return c1, c2, c3
def add_marker(coordinates, name):
"""Add a marker with coordinates and a name to the Streamlit session.
Args:
coordinates (Point): The coordinates of the marker
name (str): The name or label for the marker
"""
data = {'coordinates': coordinates, 'name': name}
st.session_state['markers'].append(data)
def display_map(nodes, returned_objects=None, path=None):
"""Display the map with nodes and optional markers and paths.
Args:
nodes (geopandas.DataFrame): A dataframe containing the nodes to display
returned_objects (List[str], optional): Objects to be returned when interacting with the map. Defaults to None.
path (pandas.DataFrame, optional): A DataFrame representing the road segments that form the shortest path. Defaults to None.
Returns:
Streamlit.FoliumMap: An interactive map displaying nodes, markers, and paths
"""
m = nodes.explore(
color="red",
marker_kwds=dict(radius=5, fill=True, name='node_id'),
tooltip="node_id",
tooltip_kwds=dict(labels=False),
zoom_control=False,
)
if 'markers' in st.session_state:
for mrk in st.session_state['markers']:
folium.Marker([mrk['coordinates'].y, mrk['coordinates'].x], popup=mrk['name'], tooltip=mrk['name']).add_to(m)
if path is not None:
path.explore(
m=m,
color="green",
style_kwds = {"weight":5},
tooltip="name",
popup=["name"],
name="Quadratic-Paris",
)
return st_folium(m, width=725, key="origin", returned_objects=returned_objects)
def add_to_server_side(message):
"""Add a message to the server side of the view
Args:
message (str): The message to be added to the server side
"""
st.session_state['server_side'].append(message)
def add_to_client_side(message):
"""Add a message to the client side of the view
Args:
message (str): The message to be added to the client side
"""
st.session_state['client_side'].append(message)
def display_server_side():
"""Display the messages stored in the server-side view.
"""
st.write("**Server-side**")
for message in st.session_state['server_side']:
st.write(message)
def display_client_side():
"""Display the messages stored in the client-side view.
"""
st.write("**Client-side**")
for message in st.session_state['client_side']:
st.write(message)
def restart_session():
"""Clear the session state to restart
"""
if st.button('Restart'):
for key in st.session_state.items():
if key[0] != 'evaluation_key':
del st.session_state[key[0]]
st.rerun()
|