# Service for Deploying Digital Twins of QKD Networks
## 4 Implementation
### QKD Module Software  
As discussed in Section 3.2, the implemented QKD network module is structured into different layers that communicate with one another via a specifically designed API. The upper layer of the QKD node and the client applications communicate with each other through the QKD API, designed and implemented for this purpose, and aligned with the ETSI API described in [27]. Within the QKD module, the other two specific APIs are implemented and used between the layers that form the QKD Key Manager Peer of different nodes. Lastly, the bottom layer emulates the quantum components of the node that enable the creation of quantum keys and uses the protocol implemented in the emulator itself to communicate with the layer above it and with the matching layers in other nodes. The Python package developed for the QKD network module follows the architecture shown in Figure 5 and is the main component of the system. It runs all the functional layers on the node described in Section 3.2. From top to bottom, the QKD module package is structured as follows. The upper layer of the QKD module, the Key Management layer, is formed by three software components. First, a Key Management application asynchronous interface is included, where the three functions defined by ETSI QKD 004 [27] are implemented using gRPC [50], a modern open source solution used to connect multiple services in an environment. This is the element that enables the communication between the QKD module and the client applications. The implemented API enables three methods of execution, corresponding to the three functions defined in [27]:  
* _open_connect_: This instruction indicates that a new stream of QKD-generated keys must be created with another node. To call this method, information about the applications that will access nodes involved in the new stream and other parameters, such as the lifetime of the keys, must be included. Once this method has been executed, a Key Stream ID (KSID), which can be used by the application to identify the key stream in subsequent calls to other methods, is generated. After calling this method on both nodes, the nodes start to continuously exchange and buffer keys for this key stream. * _get_key_: This method is used to retrieve a key from a particular key stream identified by its KSID. If no new key is available yet, an error code is returned. This method additionally allows the user to optionally send an \"index\" parameter to specify the key in the key stream it wants to retrieve for synchronization purposes. Figure 4: Left, steps followed by the QKD Network Digital Twin orchestrator application when a pre-deployed machines pool exists. Right, steps followed when the OSM is used to deploy the QKD network machines. _close_: This instruction closes and frees a particular key stream identified by its KSID. Beware this is just a quick and simplified overview of the interface. For the complete picture and details, please refer to the specification document [27]. Below this interface, the Key Manager itself is found. It is responsible for managing key flows, i.e., it is the element that receives requests from applications and performs actions based on these requests, including the delivery of the requested keys to the applications. Lastly, a component named the Key Management inter-management application asynchronous interface is added to enable communication between Key Managers of different sites. The next layer in the designed architecture of the QKD module is the Key Synchronization layer. This layer counts with a principal component named Key Synchronization tasks that ensures, while it may appear redundant, the proper synchronization in the key formation and delivery processes. This can be achieved because the quantum emulator assigns an identifier to each qubit, allowing it to pinpoint precisely each of them and easing the synchronization inside the QKD module.