diff --git a/internal/api/gen/proto/go/kmsetsi/kmsetsiproto.pb.go b/internal/api/gen/proto/go/kmsetsi/kmsetsiproto.pb.go
index 69adc0800285ac2fb4ff2ad07a5d5feb0febc8ac..80cf822b317b6a457997549b0dd6b7342046b459 100644
--- a/internal/api/gen/proto/go/kmsetsi/kmsetsiproto.pb.go
+++ b/internal/api/gen/proto/go/kmsetsi/kmsetsiproto.pb.go
@@ -20,17 +20,19 @@ const (
 	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
 )
 
-// The request message containing the user's name.
-type ETSICapabilitiesRequest struct {
+// NB for myself: this be used to link QLE mit KMS-Session!
+type QuantumElementInfo struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	MyKmsName string `protobuf:"bytes,1,opt,name=myKmsName,proto3" json:"myKmsName,omitempty"`
+	Timestamp int64  `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
+	QleID     uint64 `protobuf:"varint,2,opt,name=qleID,proto3" json:"qleID,omitempty"`
+	UdpAddr   string `protobuf:"bytes,3,opt,name=udpAddr,proto3" json:"udpAddr,omitempty"`
 }
 
-func (x *ETSICapabilitiesRequest) Reset() {
-	*x = ETSICapabilitiesRequest{}
+func (x *QuantumElementInfo) Reset() {
+	*x = QuantumElementInfo{}
 	if protoimpl.UnsafeEnabled {
 		mi := &file_kmsetsi_kmsetsiproto_proto_msgTypes[0]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -38,13 +40,13 @@ func (x *ETSICapabilitiesRequest) Reset() {
 	}
 }
 
-func (x *ETSICapabilitiesRequest) String() string {
+func (x *QuantumElementInfo) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*ETSICapabilitiesRequest) ProtoMessage() {}
+func (*QuantumElementInfo) ProtoMessage() {}
 
-func (x *ETSICapabilitiesRequest) ProtoReflect() protoreflect.Message {
+func (x *QuantumElementInfo) ProtoReflect() protoreflect.Message {
 	mi := &file_kmsetsi_kmsetsiproto_proto_msgTypes[0]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -56,29 +58,44 @@ func (x *ETSICapabilitiesRequest) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use ETSICapabilitiesRequest.ProtoReflect.Descriptor instead.
-func (*ETSICapabilitiesRequest) Descriptor() ([]byte, []int) {
+// Deprecated: Use QuantumElementInfo.ProtoReflect.Descriptor instead.
+func (*QuantumElementInfo) Descriptor() ([]byte, []int) {
 	return file_kmsetsi_kmsetsiproto_proto_rawDescGZIP(), []int{0}
 }
 
-func (x *ETSICapabilitiesRequest) GetMyKmsName() string {
+func (x *QuantumElementInfo) GetTimestamp() int64 {
 	if x != nil {
-		return x.MyKmsName
+		return x.Timestamp
+	}
+	return 0
+}
+
+func (x *QuantumElementInfo) GetQleID() uint64 {
+	if x != nil {
+		return x.QleID
+	}
+	return 0
+}
+
+func (x *QuantumElementInfo) GetUdpAddr() string {
+	if x != nil {
+		return x.UdpAddr
 	}
 	return ""
 }
 
-// The response message containing the greetings
-type ETSICapabilitiesReply struct {
+// The request message containing the user's name.
+type ETSICapabilitiesRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	PeerKmsName string `protobuf:"bytes,1,opt,name=peerKmsName,proto3" json:"peerKmsName,omitempty"`
+	Timestamp int64  `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
+	MyKmsName string `protobuf:"bytes,2,opt,name=myKmsName,proto3" json:"myKmsName,omitempty"`
 }
 
-func (x *ETSICapabilitiesReply) Reset() {
-	*x = ETSICapabilitiesReply{}
+func (x *ETSICapabilitiesRequest) Reset() {
+	*x = ETSICapabilitiesRequest{}
 	if protoimpl.UnsafeEnabled {
 		mi := &file_kmsetsi_kmsetsiproto_proto_msgTypes[1]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -86,13 +103,13 @@ func (x *ETSICapabilitiesReply) Reset() {
 	}
 }
 
-func (x *ETSICapabilitiesReply) String() string {
+func (x *ETSICapabilitiesRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*ETSICapabilitiesReply) ProtoMessage() {}
+func (*ETSICapabilitiesRequest) ProtoMessage() {}
 
-func (x *ETSICapabilitiesReply) ProtoReflect() protoreflect.Message {
+func (x *ETSICapabilitiesRequest) ProtoReflect() protoreflect.Message {
 	mi := &file_kmsetsi_kmsetsiproto_proto_msgTypes[1]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -104,26 +121,37 @@ func (x *ETSICapabilitiesReply) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use ETSICapabilitiesReply.ProtoReflect.Descriptor instead.
-func (*ETSICapabilitiesReply) Descriptor() ([]byte, []int) {
+// Deprecated: Use ETSICapabilitiesRequest.ProtoReflect.Descriptor instead.
+func (*ETSICapabilitiesRequest) Descriptor() ([]byte, []int) {
 	return file_kmsetsi_kmsetsiproto_proto_rawDescGZIP(), []int{1}
 }
 
-func (x *ETSICapabilitiesReply) GetPeerKmsName() string {
+func (x *ETSICapabilitiesRequest) GetTimestamp() int64 {
 	if x != nil {
-		return x.PeerKmsName
+		return x.Timestamp
+	}
+	return 0
+}
+
+func (x *ETSICapabilitiesRequest) GetMyKmsName() string {
+	if x != nil {
+		return x.MyKmsName
 	}
 	return ""
 }
 
-type ETSIKMSQuantumInterfaceListRequest struct {
+// The response message containing the greetings
+type ETSICapabilitiesReply struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
+
+	Timestamp   int64  `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
+	PeerKmsName string `protobuf:"bytes,2,opt,name=peerKmsName,proto3" json:"peerKmsName,omitempty"`
 }
 
-func (x *ETSIKMSQuantumInterfaceListRequest) Reset() {
-	*x = ETSIKMSQuantumInterfaceListRequest{}
+func (x *ETSICapabilitiesReply) Reset() {
+	*x = ETSICapabilitiesReply{}
 	if protoimpl.UnsafeEnabled {
 		mi := &file_kmsetsi_kmsetsiproto_proto_msgTypes[2]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -131,13 +159,13 @@ func (x *ETSIKMSQuantumInterfaceListRequest) Reset() {
 	}
 }
 
-func (x *ETSIKMSQuantumInterfaceListRequest) String() string {
+func (x *ETSICapabilitiesReply) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*ETSIKMSQuantumInterfaceListRequest) ProtoMessage() {}
+func (*ETSICapabilitiesReply) ProtoMessage() {}
 
-func (x *ETSIKMSQuantumInterfaceListRequest) ProtoReflect() protoreflect.Message {
+func (x *ETSICapabilitiesReply) ProtoReflect() protoreflect.Message {
 	mi := &file_kmsetsi_kmsetsiproto_proto_msgTypes[2]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -149,23 +177,35 @@ func (x *ETSIKMSQuantumInterfaceListRequest) ProtoReflect() protoreflect.Message
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use ETSIKMSQuantumInterfaceListRequest.ProtoReflect.Descriptor instead.
-func (*ETSIKMSQuantumInterfaceListRequest) Descriptor() ([]byte, []int) {
+// Deprecated: Use ETSICapabilitiesReply.ProtoReflect.Descriptor instead.
+func (*ETSICapabilitiesReply) Descriptor() ([]byte, []int) {
 	return file_kmsetsi_kmsetsiproto_proto_rawDescGZIP(), []int{2}
 }
 
-// NB for myself: this be used to link QLE mit KMS-Session!
-type QuantumElementInfo struct {
+func (x *ETSICapabilitiesReply) GetTimestamp() int64 {
+	if x != nil {
+		return x.Timestamp
+	}
+	return 0
+}
+
+func (x *ETSICapabilitiesReply) GetPeerKmsName() string {
+	if x != nil {
+		return x.PeerKmsName
+	}
+	return ""
+}
+
+type ETSIKMSQuantumInterfaceListRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	QleID   uint64 `protobuf:"varint,1,opt,name=qleID,proto3" json:"qleID,omitempty"`
-	UdpAddr string `protobuf:"bytes,2,opt,name=udpAddr,proto3" json:"udpAddr,omitempty"`
+	Timestamp int64 `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
 }
 
-func (x *QuantumElementInfo) Reset() {
-	*x = QuantumElementInfo{}
+func (x *ETSIKMSQuantumInterfaceListRequest) Reset() {
+	*x = ETSIKMSQuantumInterfaceListRequest{}
 	if protoimpl.UnsafeEnabled {
 		mi := &file_kmsetsi_kmsetsiproto_proto_msgTypes[3]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -173,13 +213,13 @@ func (x *QuantumElementInfo) Reset() {
 	}
 }
 
-func (x *QuantumElementInfo) String() string {
+func (x *ETSIKMSQuantumInterfaceListRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*QuantumElementInfo) ProtoMessage() {}
+func (*ETSIKMSQuantumInterfaceListRequest) ProtoMessage() {}
 
-func (x *QuantumElementInfo) ProtoReflect() protoreflect.Message {
+func (x *ETSIKMSQuantumInterfaceListRequest) ProtoReflect() protoreflect.Message {
 	mi := &file_kmsetsi_kmsetsiproto_proto_msgTypes[3]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -191,31 +231,25 @@ func (x *QuantumElementInfo) ProtoReflect() protoreflect.Message {
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use QuantumElementInfo.ProtoReflect.Descriptor instead.
-func (*QuantumElementInfo) Descriptor() ([]byte, []int) {
+// Deprecated: Use ETSIKMSQuantumInterfaceListRequest.ProtoReflect.Descriptor instead.
+func (*ETSIKMSQuantumInterfaceListRequest) Descriptor() ([]byte, []int) {
 	return file_kmsetsi_kmsetsiproto_proto_rawDescGZIP(), []int{3}
 }
 
-func (x *QuantumElementInfo) GetQleID() uint64 {
+func (x *ETSIKMSQuantumInterfaceListRequest) GetTimestamp() int64 {
 	if x != nil {
-		return x.QleID
+		return x.Timestamp
 	}
 	return 0
 }
 
-func (x *QuantumElementInfo) GetUdpAddr() string {
-	if x != nil {
-		return x.UdpAddr
-	}
-	return ""
-}
-
 type ETSIKMSQuantumInterfaceListReply struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	QlElementInfo []*QuantumElementInfo `protobuf:"bytes,1,rep,name=qlElementInfo,proto3" json:"qlElementInfo,omitempty"`
+	Timestamp     int64                 `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
+	QlElementInfo []*QuantumElementInfo `protobuf:"bytes,2,rep,name=qlElementInfo,proto3" json:"qlElementInfo,omitempty"`
 }
 
 func (x *ETSIKMSQuantumInterfaceListReply) Reset() {
@@ -250,6 +284,13 @@ func (*ETSIKMSQuantumInterfaceListReply) Descriptor() ([]byte, []int) {
 	return file_kmsetsi_kmsetsiproto_proto_rawDescGZIP(), []int{4}
 }
 
+func (x *ETSIKMSQuantumInterfaceListReply) GetTimestamp() int64 {
+	if x != nil {
+		return x.Timestamp
+	}
+	return 0
+}
+
 func (x *ETSIKMSQuantumInterfaceListReply) GetQlElementInfo() []*QuantumElementInfo {
 	if x != nil {
 		return x.QlElementInfo
@@ -262,8 +303,9 @@ type ETSIKMSPeerRequest struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	KmsPeerSocket string `protobuf:"bytes,1,opt,name=kmsPeerSocket,proto3" json:"kmsPeerSocket,omitempty"`
-	KmsLocalQLEId uint32 `protobuf:"varint,2,opt,name=kmsLocalQLEId,proto3" json:"kmsLocalQLEId,omitempty"`
+	Timestamp     int64  `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
+	KmsPeerSocket string `protobuf:"bytes,2,opt,name=kmsPeerSocket,proto3" json:"kmsPeerSocket,omitempty"`
+	KmsLocalQLEId uint32 `protobuf:"varint,3,opt,name=kmsLocalQLEId,proto3" json:"kmsLocalQLEId,omitempty"`
 }
 
 func (x *ETSIKMSPeerRequest) Reset() {
@@ -298,6 +340,13 @@ func (*ETSIKMSPeerRequest) Descriptor() ([]byte, []int) {
 	return file_kmsetsi_kmsetsiproto_proto_rawDescGZIP(), []int{5}
 }
 
+func (x *ETSIKMSPeerRequest) GetTimestamp() int64 {
+	if x != nil {
+		return x.Timestamp
+	}
+	return 0
+}
+
 func (x *ETSIKMSPeerRequest) GetKmsPeerSocket() string {
 	if x != nil {
 		return x.KmsPeerSocket
@@ -317,7 +366,8 @@ type ETSIKMSPeerReply struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	KmsPeerName string `protobuf:"bytes,1,opt,name=kmsPeerName,proto3" json:"kmsPeerName,omitempty"`
+	Timestamp   int64  `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
+	KmsPeerName string `protobuf:"bytes,2,opt,name=kmsPeerName,proto3" json:"kmsPeerName,omitempty"`
 }
 
 func (x *ETSIKMSPeerReply) Reset() {
@@ -352,6 +402,13 @@ func (*ETSIKMSPeerReply) Descriptor() ([]byte, []int) {
 	return file_kmsetsi_kmsetsiproto_proto_rawDescGZIP(), []int{6}
 }
 
+func (x *ETSIKMSPeerReply) GetTimestamp() int64 {
+	if x != nil {
+		return x.Timestamp
+	}
+	return 0
+}
+
 func (x *ETSIKMSPeerReply) GetKmsPeerName() string {
 	if x != nil {
 		return x.KmsPeerName
@@ -363,6 +420,8 @@ type ETSIKMSPeerListRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
+
+	Timestamp int64 `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
 }
 
 func (x *ETSIKMSPeerListRequest) Reset() {
@@ -397,13 +456,21 @@ func (*ETSIKMSPeerListRequest) Descriptor() ([]byte, []int) {
 	return file_kmsetsi_kmsetsiproto_proto_rawDescGZIP(), []int{7}
 }
 
+func (x *ETSIKMSPeerListRequest) GetTimestamp() int64 {
+	if x != nil {
+		return x.Timestamp
+	}
+	return 0
+}
+
 type ETSIKMSPeer struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	PeerName   string `protobuf:"bytes,1,opt,name=peerName,proto3" json:"peerName,omitempty"`
-	PeerStatus string `protobuf:"bytes,2,opt,name=peerStatus,proto3" json:"peerStatus,omitempty"`
+	Timestamp  int64  `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
+	PeerName   string `protobuf:"bytes,2,opt,name=peerName,proto3" json:"peerName,omitempty"`
+	PeerStatus string `protobuf:"bytes,3,opt,name=peerStatus,proto3" json:"peerStatus,omitempty"`
 }
 
 func (x *ETSIKMSPeer) Reset() {
@@ -438,6 +505,13 @@ func (*ETSIKMSPeer) Descriptor() ([]byte, []int) {
 	return file_kmsetsi_kmsetsiproto_proto_rawDescGZIP(), []int{8}
 }
 
+func (x *ETSIKMSPeer) GetTimestamp() int64 {
+	if x != nil {
+		return x.Timestamp
+	}
+	return 0
+}
+
 func (x *ETSIKMSPeer) GetPeerName() string {
 	if x != nil {
 		return x.PeerName
@@ -601,106 +675,385 @@ func (x *ETSIGetEncryptKeys256BitReply) GetKey() []byte {
 	return nil
 }
 
+type ETSIAssignForwardingRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Timestamp int64  `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
+	PathId    string `protobuf:"bytes,2,opt,name=pathId,proto3" json:"pathId,omitempty"`
+	PrevHop   string `protobuf:"bytes,3,opt,name=prevHop,proto3" json:"prevHop,omitempty"`
+	NextHop   string `protobuf:"bytes,4,opt,name=nextHop,proto3" json:"nextHop,omitempty"`
+}
+
+func (x *ETSIAssignForwardingRequest) Reset() {
+	*x = ETSIAssignForwardingRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_kmsetsi_kmsetsiproto_proto_msgTypes[12]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ETSIAssignForwardingRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ETSIAssignForwardingRequest) ProtoMessage() {}
+
+func (x *ETSIAssignForwardingRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_kmsetsi_kmsetsiproto_proto_msgTypes[12]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ETSIAssignForwardingRequest.ProtoReflect.Descriptor instead.
+func (*ETSIAssignForwardingRequest) Descriptor() ([]byte, []int) {
+	return file_kmsetsi_kmsetsiproto_proto_rawDescGZIP(), []int{12}
+}
+
+func (x *ETSIAssignForwardingRequest) GetTimestamp() int64 {
+	if x != nil {
+		return x.Timestamp
+	}
+	return 0
+}
+
+func (x *ETSIAssignForwardingRequest) GetPathId() string {
+	if x != nil {
+		return x.PathId
+	}
+	return ""
+}
+
+func (x *ETSIAssignForwardingRequest) GetPrevHop() string {
+	if x != nil {
+		return x.PrevHop
+	}
+	return ""
+}
+
+func (x *ETSIAssignForwardingRequest) GetNextHop() string {
+	if x != nil {
+		return x.NextHop
+	}
+	return ""
+}
+
+type ETSIAssignForwardingReply struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Timestamp int64 `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
+}
+
+func (x *ETSIAssignForwardingReply) Reset() {
+	*x = ETSIAssignForwardingReply{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_kmsetsi_kmsetsiproto_proto_msgTypes[13]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ETSIAssignForwardingReply) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ETSIAssignForwardingReply) ProtoMessage() {}
+
+func (x *ETSIAssignForwardingReply) ProtoReflect() protoreflect.Message {
+	mi := &file_kmsetsi_kmsetsiproto_proto_msgTypes[13]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ETSIAssignForwardingReply.ProtoReflect.Descriptor instead.
+func (*ETSIAssignForwardingReply) Descriptor() ([]byte, []int) {
+	return file_kmsetsi_kmsetsiproto_proto_rawDescGZIP(), []int{13}
+}
+
+func (x *ETSIAssignForwardingReply) GetTimestamp() int64 {
+	if x != nil {
+		return x.Timestamp
+	}
+	return 0
+}
+
+type ETSISendPayloadRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Timestamp int64  `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
+	PathId    string `protobuf:"bytes,2,opt,name=pathId,proto3" json:"pathId,omitempty"`
+	Payload   string `protobuf:"bytes,3,opt,name=payload,proto3" json:"payload,omitempty"`
+}
+
+func (x *ETSISendPayloadRequest) Reset() {
+	*x = ETSISendPayloadRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_kmsetsi_kmsetsiproto_proto_msgTypes[14]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ETSISendPayloadRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ETSISendPayloadRequest) ProtoMessage() {}
+
+func (x *ETSISendPayloadRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_kmsetsi_kmsetsiproto_proto_msgTypes[14]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ETSISendPayloadRequest.ProtoReflect.Descriptor instead.
+func (*ETSISendPayloadRequest) Descriptor() ([]byte, []int) {
+	return file_kmsetsi_kmsetsiproto_proto_rawDescGZIP(), []int{14}
+}
+
+func (x *ETSISendPayloadRequest) GetTimestamp() int64 {
+	if x != nil {
+		return x.Timestamp
+	}
+	return 0
+}
+
+func (x *ETSISendPayloadRequest) GetPathId() string {
+	if x != nil {
+		return x.PathId
+	}
+	return ""
+}
+
+func (x *ETSISendPayloadRequest) GetPayload() string {
+	if x != nil {
+		return x.Payload
+	}
+	return ""
+}
+
+type ETSISendPayloadResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Timestamp int64 `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
+}
+
+func (x *ETSISendPayloadResponse) Reset() {
+	*x = ETSISendPayloadResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_kmsetsi_kmsetsiproto_proto_msgTypes[15]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ETSISendPayloadResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ETSISendPayloadResponse) ProtoMessage() {}
+
+func (x *ETSISendPayloadResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_kmsetsi_kmsetsiproto_proto_msgTypes[15]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ETSISendPayloadResponse.ProtoReflect.Descriptor instead.
+func (*ETSISendPayloadResponse) Descriptor() ([]byte, []int) {
+	return file_kmsetsi_kmsetsiproto_proto_rawDescGZIP(), []int{15}
+}
+
+func (x *ETSISendPayloadResponse) GetTimestamp() int64 {
+	if x != nil {
+		return x.Timestamp
+	}
+	return 0
+}
+
 var File_kmsetsi_kmsetsiproto_proto protoreflect.FileDescriptor
 
 var file_kmsetsi_kmsetsiproto_proto_rawDesc = []byte{
 	0x0a, 0x1a, 0x6b, 0x6d, 0x73, 0x65, 0x74, 0x73, 0x69, 0x2f, 0x6b, 0x6d, 0x73, 0x65, 0x74, 0x73,
 	0x69, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x6b, 0x6d,
-	0x73, 0x65, 0x74, 0x73, 0x69, 0x22, 0x37, 0x0a, 0x17, 0x45, 0x54, 0x53, 0x49, 0x43, 0x61, 0x70,
-	0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
-	0x12, 0x1c, 0x0a, 0x09, 0x6d, 0x79, 0x4b, 0x6d, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x79, 0x4b, 0x6d, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x39,
-	0x0a, 0x15, 0x45, 0x54, 0x53, 0x49, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69,
-	0x65, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x65, 0x65, 0x72, 0x4b,
-	0x6d, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x65,
-	0x65, 0x72, 0x4b, 0x6d, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x24, 0x0a, 0x22, 0x45, 0x54, 0x53,
+	0x73, 0x65, 0x74, 0x73, 0x69, 0x22, 0x62, 0x0a, 0x12, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x75, 0x6d,
+	0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x74,
+	0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09,
+	0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x6c, 0x65,
+	0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x71, 0x6c, 0x65, 0x49, 0x44, 0x12,
+	0x18, 0x0a, 0x07, 0x75, 0x64, 0x70, 0x41, 0x64, 0x64, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x07, 0x75, 0x64, 0x70, 0x41, 0x64, 0x64, 0x72, 0x22, 0x55, 0x0a, 0x17, 0x45, 0x54, 0x53,
+	0x49, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d,
+	0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61,
+	0x6d, 0x70, 0x12, 0x1c, 0x0a, 0x09, 0x6d, 0x79, 0x4b, 0x6d, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x18,
+	0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x79, 0x4b, 0x6d, 0x73, 0x4e, 0x61, 0x6d, 0x65,
+	0x22, 0x57, 0x0a, 0x15, 0x45, 0x54, 0x53, 0x49, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69,
+	0x74, 0x69, 0x65, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d,
+	0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69,
+	0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x65, 0x65, 0x72, 0x4b,
+	0x6d, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x65,
+	0x65, 0x72, 0x4b, 0x6d, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x42, 0x0a, 0x22, 0x45, 0x54, 0x53,
 	0x49, 0x4b, 0x4d, 0x53, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x75, 0x6d, 0x49, 0x6e, 0x74, 0x65, 0x72,
-	0x66, 0x61, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22,
-	0x44, 0x0a, 0x12, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x75, 0x6d, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e,
-	0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x6c, 0x65, 0x49, 0x44, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x71, 0x6c, 0x65, 0x49, 0x44, 0x12, 0x18, 0x0a, 0x07, 0x75,
-	0x64, 0x70, 0x41, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x75, 0x64,
-	0x70, 0x41, 0x64, 0x64, 0x72, 0x22, 0x65, 0x0a, 0x20, 0x45, 0x54, 0x53, 0x49, 0x4b, 0x4d, 0x53,
-	0x51, 0x75, 0x61, 0x6e, 0x74, 0x75, 0x6d, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65,
-	0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x41, 0x0a, 0x0d, 0x71, 0x6c, 0x45,
-	0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
-	0x32, 0x1b, 0x2e, 0x6b, 0x6d, 0x73, 0x65, 0x74, 0x73, 0x69, 0x2e, 0x51, 0x75, 0x61, 0x6e, 0x74,
-	0x75, 0x6d, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0d, 0x71,
-	0x6c, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x60, 0x0a, 0x12,
-	0x45, 0x54, 0x53, 0x49, 0x4b, 0x4d, 0x53, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65,
-	0x73, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x6b, 0x6d, 0x73, 0x50, 0x65, 0x65, 0x72, 0x53, 0x6f, 0x63,
-	0x6b, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6b, 0x6d, 0x73, 0x50, 0x65,
-	0x65, 0x72, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x6b, 0x6d, 0x73, 0x4c,
-	0x6f, 0x63, 0x61, 0x6c, 0x51, 0x4c, 0x45, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52,
-	0x0d, 0x6b, 0x6d, 0x73, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x51, 0x4c, 0x45, 0x49, 0x64, 0x22, 0x34,
-	0x0a, 0x10, 0x45, 0x54, 0x53, 0x49, 0x4b, 0x4d, 0x53, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x70,
-	0x6c, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x6b, 0x6d, 0x73, 0x50, 0x65, 0x65, 0x72, 0x4e, 0x61, 0x6d,
-	0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6b, 0x6d, 0x73, 0x50, 0x65, 0x65, 0x72,
-	0x4e, 0x61, 0x6d, 0x65, 0x22, 0x18, 0x0a, 0x16, 0x45, 0x54, 0x53, 0x49, 0x4b, 0x4d, 0x53, 0x50,
-	0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x49,
-	0x0a, 0x0b, 0x45, 0x54, 0x53, 0x49, 0x4b, 0x4d, 0x53, 0x50, 0x65, 0x65, 0x72, 0x12, 0x1a, 0x0a,
-	0x08, 0x70, 0x65, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
-	0x08, 0x70, 0x65, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x65, 0x65,
-	0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70,
-	0x65, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x40, 0x0a, 0x14, 0x45, 0x54, 0x53,
-	0x49, 0x4b, 0x4d, 0x53, 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6c,
-	0x79, 0x12, 0x28, 0x0a, 0x04, 0x70, 0x65, 0x65, 0x72, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32,
-	0x14, 0x2e, 0x6b, 0x6d, 0x73, 0x65, 0x74, 0x73, 0x69, 0x2e, 0x45, 0x54, 0x53, 0x49, 0x4b, 0x4d,
-	0x53, 0x50, 0x65, 0x65, 0x72, 0x52, 0x04, 0x70, 0x65, 0x65, 0x72, 0x22, 0x39, 0x0a, 0x1f, 0x45,
-	0x54, 0x53, 0x49, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x4b, 0x65, 0x79,
-	0x73, 0x32, 0x35, 0x36, 0x42, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16,
-	0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06,
-	0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x47, 0x0a, 0x1d, 0x45, 0x54, 0x53, 0x49, 0x47, 0x65,
-	0x74, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x32, 0x35, 0x36, 0x42,
-	0x69, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x6b, 0x65, 0x79, 0x49, 0x44,
-	0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x6b, 0x65, 0x79, 0x49, 0x44, 0x12, 0x10, 0x0a,
-	0x03, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x32,
-	0xb7, 0x04, 0x0a, 0x07, 0x4b, 0x6d, 0x73, 0x45, 0x54, 0x53, 0x49, 0x12, 0x56, 0x0a, 0x10, 0x45,
-	0x54, 0x53, 0x49, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12,
-	0x20, 0x2e, 0x6b, 0x6d, 0x73, 0x65, 0x74, 0x73, 0x69, 0x2e, 0x45, 0x54, 0x53, 0x49, 0x43, 0x61,
-	0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
-	0x74, 0x1a, 0x1e, 0x2e, 0x6b, 0x6d, 0x73, 0x65, 0x74, 0x73, 0x69, 0x2e, 0x45, 0x54, 0x53, 0x49,
-	0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x52, 0x65, 0x70, 0x6c,
-	0x79, 0x22, 0x00, 0x12, 0x74, 0x0a, 0x18, 0x45, 0x54, 0x53, 0x49, 0x47, 0x65, 0x74, 0x51, 0x75,
-	0x61, 0x6e, 0x74, 0x75, 0x6d, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x12,
-	0x2b, 0x2e, 0x6b, 0x6d, 0x73, 0x65, 0x74, 0x73, 0x69, 0x2e, 0x45, 0x54, 0x53, 0x49, 0x4b, 0x4d,
-	0x53, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x75, 0x6d, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63,
-	0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x6b,
-	0x6d, 0x73, 0x65, 0x74, 0x73, 0x69, 0x2e, 0x45, 0x54, 0x53, 0x49, 0x4b, 0x4d, 0x53, 0x51, 0x75,
-	0x61, 0x6e, 0x74, 0x75, 0x6d, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x4c, 0x69,
-	0x73, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x4a, 0x0a, 0x0e, 0x45, 0x54, 0x53,
-	0x49, 0x41, 0x64, 0x64, 0x4b, 0x4d, 0x53, 0x50, 0x65, 0x65, 0x72, 0x12, 0x1b, 0x2e, 0x6b, 0x6d,
-	0x73, 0x65, 0x74, 0x73, 0x69, 0x2e, 0x45, 0x54, 0x53, 0x49, 0x4b, 0x4d, 0x53, 0x50, 0x65, 0x65,
-	0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x6b, 0x6d, 0x73, 0x65, 0x74,
-	0x73, 0x69, 0x2e, 0x45, 0x54, 0x53, 0x49, 0x4b, 0x4d, 0x53, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65,
-	0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x4d, 0x0a, 0x11, 0x45, 0x54, 0x53, 0x49, 0x52, 0x65, 0x6d,
-	0x6f, 0x76, 0x65, 0x4b, 0x4d, 0x53, 0x50, 0x65, 0x65, 0x72, 0x12, 0x1b, 0x2e, 0x6b, 0x6d, 0x73,
-	0x65, 0x74, 0x73, 0x69, 0x2e, 0x45, 0x54, 0x53, 0x49, 0x4b, 0x4d, 0x53, 0x50, 0x65, 0x65, 0x72,
-	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x6b, 0x6d, 0x73, 0x65, 0x74, 0x73,
-	0x69, 0x2e, 0x45, 0x54, 0x53, 0x49, 0x4b, 0x4d, 0x53, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x70,
-	0x6c, 0x79, 0x22, 0x00, 0x12, 0x53, 0x0a, 0x0f, 0x45, 0x54, 0x53, 0x49, 0x47, 0x65, 0x74, 0x50,
-	0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x1f, 0x2e, 0x6b, 0x6d, 0x73, 0x65, 0x74, 0x73,
-	0x69, 0x2e, 0x45, 0x54, 0x53, 0x49, 0x4b, 0x4d, 0x53, 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73,
-	0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6b, 0x6d, 0x73, 0x65, 0x74,
-	0x73, 0x69, 0x2e, 0x45, 0x54, 0x53, 0x49, 0x4b, 0x4d, 0x53, 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69,
-	0x73, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x6e, 0x0a, 0x18, 0x45, 0x54, 0x53,
-	0x49, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x32,
-	0x35, 0x36, 0x42, 0x69, 0x74, 0x12, 0x28, 0x2e, 0x6b, 0x6d, 0x73, 0x65, 0x74, 0x73, 0x69, 0x2e,
-	0x45, 0x54, 0x53, 0x49, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x4b, 0x65,
-	0x79, 0x73, 0x32, 0x35, 0x36, 0x42, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
-	0x26, 0x2e, 0x6b, 0x6d, 0x73, 0x65, 0x74, 0x73, 0x69, 0x2e, 0x45, 0x54, 0x53, 0x49, 0x47, 0x65,
-	0x74, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x32, 0x35, 0x36, 0x42,
-	0x69, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x42, 0x98, 0x01, 0x0a, 0x0b, 0x63, 0x6f,
-	0x6d, 0x2e, 0x6b, 0x6d, 0x73, 0x65, 0x74, 0x73, 0x69, 0x42, 0x11, 0x4b, 0x6d, 0x73, 0x65, 0x74,
-	0x73, 0x69, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3a,
-	0x63, 0x6f, 0x64, 0x65, 0x2e, 0x66, 0x62, 0x69, 0x2e, 0x68, 0x2d, 0x64, 0x61, 0x2e, 0x64, 0x65,
-	0x2f, 0x64, 0x65, 0x6d, 0x6f, 0x71, 0x75, 0x61, 0x6e, 0x64, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74,
-	0x6f, 0x2d, 0x6b, 0x6d, 0x73, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f,
-	0x67, 0x6f, 0x2f, 0x6b, 0x6d, 0x73, 0x65, 0x74, 0x73, 0x69, 0xa2, 0x02, 0x03, 0x4b, 0x58, 0x58,
-	0xaa, 0x02, 0x07, 0x4b, 0x6d, 0x73, 0x65, 0x74, 0x73, 0x69, 0xca, 0x02, 0x07, 0x4b, 0x6d, 0x73,
-	0x65, 0x74, 0x73, 0x69, 0xe2, 0x02, 0x13, 0x4b, 0x6d, 0x73, 0x65, 0x74, 0x73, 0x69, 0x5c, 0x47,
-	0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x07, 0x4b, 0x6d, 0x73,
-	0x65, 0x74, 0x73, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x66, 0x61, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
+	0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x83, 0x01,
+	0x0a, 0x20, 0x45, 0x54, 0x53, 0x49, 0x4b, 0x4d, 0x53, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x75, 0x6d,
+	0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x70,
+	0x6c, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
+	0x12, 0x41, 0x0a, 0x0d, 0x71, 0x6c, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66,
+	0x6f, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6b, 0x6d, 0x73, 0x65, 0x74, 0x73,
+	0x69, 0x2e, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x75, 0x6d, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74,
+	0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0d, 0x71, 0x6c, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x49,
+	0x6e, 0x66, 0x6f, 0x22, 0x7e, 0x0a, 0x12, 0x45, 0x54, 0x53, 0x49, 0x4b, 0x4d, 0x53, 0x50, 0x65,
+	0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d,
+	0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69,
+	0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x24, 0x0a, 0x0d, 0x6b, 0x6d, 0x73, 0x50, 0x65,
+	0x65, 0x72, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d,
+	0x6b, 0x6d, 0x73, 0x50, 0x65, 0x65, 0x72, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x24, 0x0a,
+	0x0d, 0x6b, 0x6d, 0x73, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x51, 0x4c, 0x45, 0x49, 0x64, 0x18, 0x03,
+	0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x6b, 0x6d, 0x73, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x51, 0x4c,
+	0x45, 0x49, 0x64, 0x22, 0x52, 0x0a, 0x10, 0x45, 0x54, 0x53, 0x49, 0x4b, 0x4d, 0x53, 0x50, 0x65,
+	0x65, 0x72, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73,
+	0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65,
+	0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x20, 0x0a, 0x0b, 0x6b, 0x6d, 0x73, 0x50, 0x65, 0x65, 0x72,
+	0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6b, 0x6d, 0x73, 0x50,
+	0x65, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x36, 0x0a, 0x16, 0x45, 0x54, 0x53, 0x49, 0x4b,
+	0x4d, 0x53, 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22,
+	0x67, 0x0a, 0x0b, 0x45, 0x54, 0x53, 0x49, 0x4b, 0x4d, 0x53, 0x50, 0x65, 0x65, 0x72, 0x12, 0x1c,
+	0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1a, 0x0a, 0x08,
+	0x70, 0x65, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08,
+	0x70, 0x65, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x65, 0x65, 0x72,
+	0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x65,
+	0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x40, 0x0a, 0x14, 0x45, 0x54, 0x53, 0x49,
+	0x4b, 0x4d, 0x53, 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79,
+	0x12, 0x28, 0x0a, 0x04, 0x70, 0x65, 0x65, 0x72, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14,
+	0x2e, 0x6b, 0x6d, 0x73, 0x65, 0x74, 0x73, 0x69, 0x2e, 0x45, 0x54, 0x53, 0x49, 0x4b, 0x4d, 0x53,
+	0x50, 0x65, 0x65, 0x72, 0x52, 0x04, 0x70, 0x65, 0x65, 0x72, 0x22, 0x39, 0x0a, 0x1f, 0x45, 0x54,
+	0x53, 0x49, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x4b, 0x65, 0x79, 0x73,
+	0x32, 0x35, 0x36, 0x42, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a,
+	0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x61,
+	0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x47, 0x0a, 0x1d, 0x45, 0x54, 0x53, 0x49, 0x47, 0x65, 0x74,
+	0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x32, 0x35, 0x36, 0x42, 0x69,
+	0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x6b, 0x65, 0x79, 0x49, 0x44, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x6b, 0x65, 0x79, 0x49, 0x44, 0x12, 0x10, 0x0a, 0x03,
+	0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x87,
+	0x01, 0x0a, 0x1b, 0x45, 0x54, 0x53, 0x49, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x46, 0x6f, 0x72,
+	0x77, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c,
+	0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x16, 0x0a, 0x06,
+	0x70, 0x61, 0x74, 0x68, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x61,
+	0x74, 0x68, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x65, 0x76, 0x48, 0x6f, 0x70, 0x18,
+	0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x65, 0x76, 0x48, 0x6f, 0x70, 0x12, 0x18,
+	0x0a, 0x07, 0x6e, 0x65, 0x78, 0x74, 0x48, 0x6f, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x07, 0x6e, 0x65, 0x78, 0x74, 0x48, 0x6f, 0x70, 0x22, 0x39, 0x0a, 0x19, 0x45, 0x54, 0x53, 0x49,
+	0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67,
+	0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61,
+	0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74,
+	0x61, 0x6d, 0x70, 0x22, 0x68, 0x0a, 0x16, 0x45, 0x54, 0x53, 0x49, 0x53, 0x65, 0x6e, 0x64, 0x50,
+	0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a,
+	0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03,
+	0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x70,
+	0x61, 0x74, 0x68, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x61, 0x74,
+	0x68, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x03,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x37, 0x0a,
+	0x17, 0x45, 0x54, 0x53, 0x49, 0x53, 0x65, 0x6e, 0x64, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64,
+	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65,
+	0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d,
+	0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x32, 0xf3, 0x05, 0x0a, 0x07, 0x4b, 0x6d, 0x73, 0x45, 0x54,
+	0x53, 0x49, 0x12, 0x56, 0x0a, 0x10, 0x45, 0x54, 0x53, 0x49, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69,
+	0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x20, 0x2e, 0x6b, 0x6d, 0x73, 0x65, 0x74, 0x73, 0x69,
+	0x2e, 0x45, 0x54, 0x53, 0x49, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65,
+	0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x6b, 0x6d, 0x73, 0x65, 0x74,
+	0x73, 0x69, 0x2e, 0x45, 0x54, 0x53, 0x49, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74,
+	0x69, 0x65, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x74, 0x0a, 0x18, 0x45, 0x54,
+	0x53, 0x49, 0x47, 0x65, 0x74, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x75, 0x6d, 0x49, 0x6e, 0x74, 0x65,
+	0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x12, 0x2b, 0x2e, 0x6b, 0x6d, 0x73, 0x65, 0x74, 0x73, 0x69,
+	0x2e, 0x45, 0x54, 0x53, 0x49, 0x4b, 0x4d, 0x53, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x75, 0x6d, 0x49,
+	0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x6b, 0x6d, 0x73, 0x65, 0x74, 0x73, 0x69, 0x2e, 0x45, 0x54,
+	0x53, 0x49, 0x4b, 0x4d, 0x53, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x75, 0x6d, 0x49, 0x6e, 0x74, 0x65,
+	0x72, 0x66, 0x61, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00,
+	0x12, 0x4a, 0x0a, 0x0e, 0x45, 0x54, 0x53, 0x49, 0x41, 0x64, 0x64, 0x4b, 0x4d, 0x53, 0x50, 0x65,
+	0x65, 0x72, 0x12, 0x1b, 0x2e, 0x6b, 0x6d, 0x73, 0x65, 0x74, 0x73, 0x69, 0x2e, 0x45, 0x54, 0x53,
+	0x49, 0x4b, 0x4d, 0x53, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
+	0x19, 0x2e, 0x6b, 0x6d, 0x73, 0x65, 0x74, 0x73, 0x69, 0x2e, 0x45, 0x54, 0x53, 0x49, 0x4b, 0x4d,
+	0x53, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x4d, 0x0a, 0x11,
+	0x45, 0x54, 0x53, 0x49, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x4d, 0x53, 0x50, 0x65, 0x65,
+	0x72, 0x12, 0x1b, 0x2e, 0x6b, 0x6d, 0x73, 0x65, 0x74, 0x73, 0x69, 0x2e, 0x45, 0x54, 0x53, 0x49,
+	0x4b, 0x4d, 0x53, 0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19,
+	0x2e, 0x6b, 0x6d, 0x73, 0x65, 0x74, 0x73, 0x69, 0x2e, 0x45, 0x54, 0x53, 0x49, 0x4b, 0x4d, 0x53,
+	0x50, 0x65, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x53, 0x0a, 0x0f, 0x45,
+	0x54, 0x53, 0x49, 0x47, 0x65, 0x74, 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x1f,
+	0x2e, 0x6b, 0x6d, 0x73, 0x65, 0x74, 0x73, 0x69, 0x2e, 0x45, 0x54, 0x53, 0x49, 0x4b, 0x4d, 0x53,
+	0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
+	0x1d, 0x2e, 0x6b, 0x6d, 0x73, 0x65, 0x74, 0x73, 0x69, 0x2e, 0x45, 0x54, 0x53, 0x49, 0x4b, 0x4d,
+	0x53, 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00,
+	0x12, 0x6e, 0x0a, 0x18, 0x45, 0x54, 0x53, 0x49, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x63, 0x72, 0x79,
+	0x70, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x32, 0x35, 0x36, 0x42, 0x69, 0x74, 0x12, 0x28, 0x2e, 0x6b,
+	0x6d, 0x73, 0x65, 0x74, 0x73, 0x69, 0x2e, 0x45, 0x54, 0x53, 0x49, 0x47, 0x65, 0x74, 0x45, 0x6e,
+	0x63, 0x72, 0x79, 0x70, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x32, 0x35, 0x36, 0x42, 0x69, 0x74, 0x52,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x6b, 0x6d, 0x73, 0x65, 0x74, 0x73, 0x69,
+	0x2e, 0x45, 0x54, 0x53, 0x49, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x4b,
+	0x65, 0x79, 0x73, 0x32, 0x35, 0x36, 0x42, 0x69, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00,
+	0x12, 0x62, 0x0a, 0x14, 0x45, 0x54, 0x53, 0x49, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x46, 0x6f,
+	0x72, 0x77, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x24, 0x2e, 0x6b, 0x6d, 0x73, 0x65, 0x74,
+	0x73, 0x69, 0x2e, 0x45, 0x54, 0x53, 0x49, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x46, 0x6f, 0x72,
+	0x77, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22,
+	0x2e, 0x6b, 0x6d, 0x73, 0x65, 0x74, 0x73, 0x69, 0x2e, 0x45, 0x54, 0x53, 0x49, 0x41, 0x73, 0x73,
+	0x69, 0x67, 0x6e, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x70,
+	0x6c, 0x79, 0x22, 0x00, 0x12, 0x56, 0x0a, 0x0f, 0x45, 0x54, 0x53, 0x49, 0x53, 0x65, 0x6e, 0x64,
+	0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x1f, 0x2e, 0x6b, 0x6d, 0x73, 0x65, 0x74, 0x73,
+	0x69, 0x2e, 0x45, 0x54, 0x53, 0x49, 0x53, 0x65, 0x6e, 0x64, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61,
+	0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6b, 0x6d, 0x73, 0x65, 0x74,
+	0x73, 0x69, 0x2e, 0x45, 0x54, 0x53, 0x49, 0x53, 0x65, 0x6e, 0x64, 0x50, 0x61, 0x79, 0x6c, 0x6f,
+	0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x98, 0x01, 0x0a,
+	0x0b, 0x63, 0x6f, 0x6d, 0x2e, 0x6b, 0x6d, 0x73, 0x65, 0x74, 0x73, 0x69, 0x42, 0x11, 0x4b, 0x6d,
+	0x73, 0x65, 0x74, 0x73, 0x69, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50,
+	0x01, 0x5a, 0x3a, 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x66, 0x62, 0x69, 0x2e, 0x68, 0x2d, 0x64, 0x61,
+	0x2e, 0x64, 0x65, 0x2f, 0x64, 0x65, 0x6d, 0x6f, 0x71, 0x75, 0x61, 0x6e, 0x64, 0x74, 0x2f, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x6b, 0x6d, 0x73, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x6b, 0x6d, 0x73, 0x65, 0x74, 0x73, 0x69, 0xa2, 0x02, 0x03,
+	0x4b, 0x58, 0x58, 0xaa, 0x02, 0x07, 0x4b, 0x6d, 0x73, 0x65, 0x74, 0x73, 0x69, 0xca, 0x02, 0x07,
+	0x4b, 0x6d, 0x73, 0x65, 0x74, 0x73, 0x69, 0xe2, 0x02, 0x13, 0x4b, 0x6d, 0x73, 0x65, 0x74, 0x73,
+	0x69, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x07,
+	0x4b, 0x6d, 0x73, 0x65, 0x74, 0x73, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
@@ -715,12 +1068,12 @@ func file_kmsetsi_kmsetsiproto_proto_rawDescGZIP() []byte {
 	return file_kmsetsi_kmsetsiproto_proto_rawDescData
 }
 
-var file_kmsetsi_kmsetsiproto_proto_msgTypes = make([]protoimpl.MessageInfo, 12)
+var file_kmsetsi_kmsetsiproto_proto_msgTypes = make([]protoimpl.MessageInfo, 16)
 var file_kmsetsi_kmsetsiproto_proto_goTypes = []interface{}{
-	(*ETSICapabilitiesRequest)(nil),            // 0: kmsetsi.ETSICapabilitiesRequest
-	(*ETSICapabilitiesReply)(nil),              // 1: kmsetsi.ETSICapabilitiesReply
-	(*ETSIKMSQuantumInterfaceListRequest)(nil), // 2: kmsetsi.ETSIKMSQuantumInterfaceListRequest
-	(*QuantumElementInfo)(nil),                 // 3: kmsetsi.QuantumElementInfo
+	(*QuantumElementInfo)(nil),                 // 0: kmsetsi.QuantumElementInfo
+	(*ETSICapabilitiesRequest)(nil),            // 1: kmsetsi.ETSICapabilitiesRequest
+	(*ETSICapabilitiesReply)(nil),              // 2: kmsetsi.ETSICapabilitiesReply
+	(*ETSIKMSQuantumInterfaceListRequest)(nil), // 3: kmsetsi.ETSIKMSQuantumInterfaceListRequest
 	(*ETSIKMSQuantumInterfaceListReply)(nil),   // 4: kmsetsi.ETSIKMSQuantumInterfaceListReply
 	(*ETSIKMSPeerRequest)(nil),                 // 5: kmsetsi.ETSIKMSPeerRequest
 	(*ETSIKMSPeerReply)(nil),                   // 6: kmsetsi.ETSIKMSPeerReply
@@ -729,24 +1082,32 @@ var file_kmsetsi_kmsetsiproto_proto_goTypes = []interface{}{
 	(*ETSIKMSPeerListReply)(nil),               // 9: kmsetsi.ETSIKMSPeerListReply
 	(*ETSIGetEncryptKeys256BitRequest)(nil),    // 10: kmsetsi.ETSIGetEncryptKeys256BitRequest
 	(*ETSIGetEncryptKeys256BitReply)(nil),      // 11: kmsetsi.ETSIGetEncryptKeys256BitReply
+	(*ETSIAssignForwardingRequest)(nil),        // 12: kmsetsi.ETSIAssignForwardingRequest
+	(*ETSIAssignForwardingReply)(nil),          // 13: kmsetsi.ETSIAssignForwardingReply
+	(*ETSISendPayloadRequest)(nil),             // 14: kmsetsi.ETSISendPayloadRequest
+	(*ETSISendPayloadResponse)(nil),            // 15: kmsetsi.ETSISendPayloadResponse
 }
 var file_kmsetsi_kmsetsiproto_proto_depIdxs = []int32{
-	3,  // 0: kmsetsi.ETSIKMSQuantumInterfaceListReply.qlElementInfo:type_name -> kmsetsi.QuantumElementInfo
+	0,  // 0: kmsetsi.ETSIKMSQuantumInterfaceListReply.qlElementInfo:type_name -> kmsetsi.QuantumElementInfo
 	8,  // 1: kmsetsi.ETSIKMSPeerListReply.peer:type_name -> kmsetsi.ETSIKMSPeer
-	0,  // 2: kmsetsi.KmsETSI.ETSICapabilities:input_type -> kmsetsi.ETSICapabilitiesRequest
-	2,  // 3: kmsetsi.KmsETSI.ETSIGetQuantumInterfaces:input_type -> kmsetsi.ETSIKMSQuantumInterfaceListRequest
+	1,  // 2: kmsetsi.KmsETSI.ETSICapabilities:input_type -> kmsetsi.ETSICapabilitiesRequest
+	3,  // 3: kmsetsi.KmsETSI.ETSIGetQuantumInterfaces:input_type -> kmsetsi.ETSIKMSQuantumInterfaceListRequest
 	5,  // 4: kmsetsi.KmsETSI.ETSIAddKMSPeer:input_type -> kmsetsi.ETSIKMSPeerRequest
 	5,  // 5: kmsetsi.KmsETSI.ETSIRemoveKMSPeer:input_type -> kmsetsi.ETSIKMSPeerRequest
 	7,  // 6: kmsetsi.KmsETSI.ETSIGetPeerList:input_type -> kmsetsi.ETSIKMSPeerListRequest
 	10, // 7: kmsetsi.KmsETSI.ETSIGetEncryptKeys256Bit:input_type -> kmsetsi.ETSIGetEncryptKeys256BitRequest
-	1,  // 8: kmsetsi.KmsETSI.ETSICapabilities:output_type -> kmsetsi.ETSICapabilitiesReply
-	4,  // 9: kmsetsi.KmsETSI.ETSIGetQuantumInterfaces:output_type -> kmsetsi.ETSIKMSQuantumInterfaceListReply
-	6,  // 10: kmsetsi.KmsETSI.ETSIAddKMSPeer:output_type -> kmsetsi.ETSIKMSPeerReply
-	6,  // 11: kmsetsi.KmsETSI.ETSIRemoveKMSPeer:output_type -> kmsetsi.ETSIKMSPeerReply
-	9,  // 12: kmsetsi.KmsETSI.ETSIGetPeerList:output_type -> kmsetsi.ETSIKMSPeerListReply
-	11, // 13: kmsetsi.KmsETSI.ETSIGetEncryptKeys256Bit:output_type -> kmsetsi.ETSIGetEncryptKeys256BitReply
-	8,  // [8:14] is the sub-list for method output_type
-	2,  // [2:8] is the sub-list for method input_type
+	12, // 8: kmsetsi.KmsETSI.ETSIAssignForwarding:input_type -> kmsetsi.ETSIAssignForwardingRequest
+	14, // 9: kmsetsi.KmsETSI.ETSISendPayload:input_type -> kmsetsi.ETSISendPayloadRequest
+	2,  // 10: kmsetsi.KmsETSI.ETSICapabilities:output_type -> kmsetsi.ETSICapabilitiesReply
+	4,  // 11: kmsetsi.KmsETSI.ETSIGetQuantumInterfaces:output_type -> kmsetsi.ETSIKMSQuantumInterfaceListReply
+	6,  // 12: kmsetsi.KmsETSI.ETSIAddKMSPeer:output_type -> kmsetsi.ETSIKMSPeerReply
+	6,  // 13: kmsetsi.KmsETSI.ETSIRemoveKMSPeer:output_type -> kmsetsi.ETSIKMSPeerReply
+	9,  // 14: kmsetsi.KmsETSI.ETSIGetPeerList:output_type -> kmsetsi.ETSIKMSPeerListReply
+	11, // 15: kmsetsi.KmsETSI.ETSIGetEncryptKeys256Bit:output_type -> kmsetsi.ETSIGetEncryptKeys256BitReply
+	13, // 16: kmsetsi.KmsETSI.ETSIAssignForwarding:output_type -> kmsetsi.ETSIAssignForwardingReply
+	15, // 17: kmsetsi.KmsETSI.ETSISendPayload:output_type -> kmsetsi.ETSISendPayloadResponse
+	10, // [10:18] is the sub-list for method output_type
+	2,  // [2:10] is the sub-list for method input_type
 	2,  // [2:2] is the sub-list for extension type_name
 	2,  // [2:2] is the sub-list for extension extendee
 	0,  // [0:2] is the sub-list for field type_name
@@ -759,7 +1120,7 @@ func file_kmsetsi_kmsetsiproto_proto_init() {
 	}
 	if !protoimpl.UnsafeEnabled {
 		file_kmsetsi_kmsetsiproto_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*ETSICapabilitiesRequest); i {
+			switch v := v.(*QuantumElementInfo); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -771,7 +1132,7 @@ func file_kmsetsi_kmsetsiproto_proto_init() {
 			}
 		}
 		file_kmsetsi_kmsetsiproto_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*ETSICapabilitiesReply); i {
+			switch v := v.(*ETSICapabilitiesRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -783,7 +1144,7 @@ func file_kmsetsi_kmsetsiproto_proto_init() {
 			}
 		}
 		file_kmsetsi_kmsetsiproto_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*ETSIKMSQuantumInterfaceListRequest); i {
+			switch v := v.(*ETSICapabilitiesReply); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -795,7 +1156,7 @@ func file_kmsetsi_kmsetsiproto_proto_init() {
 			}
 		}
 		file_kmsetsi_kmsetsiproto_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*QuantumElementInfo); i {
+			switch v := v.(*ETSIKMSQuantumInterfaceListRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -902,6 +1263,54 @@ func file_kmsetsi_kmsetsiproto_proto_init() {
 				return nil
 			}
 		}
+		file_kmsetsi_kmsetsiproto_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ETSIAssignForwardingRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_kmsetsi_kmsetsiproto_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ETSIAssignForwardingReply); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_kmsetsi_kmsetsiproto_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ETSISendPayloadRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_kmsetsi_kmsetsiproto_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ETSISendPayloadResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
 	}
 	type x struct{}
 	out := protoimpl.TypeBuilder{
@@ -909,7 +1318,7 @@ func file_kmsetsi_kmsetsiproto_proto_init() {
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
 			RawDescriptor: file_kmsetsi_kmsetsiproto_proto_rawDesc,
 			NumEnums:      0,
-			NumMessages:   12,
+			NumMessages:   16,
 			NumExtensions: 0,
 			NumServices:   1,
 		},
diff --git a/internal/api/gen/proto/go/kmsetsi/kmsetsiproto_grpc.pb.go b/internal/api/gen/proto/go/kmsetsi/kmsetsiproto_grpc.pb.go
index 20e30c30fb5c949365073f3e2d9fd31d607830eb..45417929f9c36c7db2c3a535b9ffe23065d4224a 100644
--- a/internal/api/gen/proto/go/kmsetsi/kmsetsiproto_grpc.pb.go
+++ b/internal/api/gen/proto/go/kmsetsi/kmsetsiproto_grpc.pb.go
@@ -25,6 +25,8 @@ const (
 	KmsETSI_ETSIRemoveKMSPeer_FullMethodName        = "/kmsetsi.KmsETSI/ETSIRemoveKMSPeer"
 	KmsETSI_ETSIGetPeerList_FullMethodName          = "/kmsetsi.KmsETSI/ETSIGetPeerList"
 	KmsETSI_ETSIGetEncryptKeys256Bit_FullMethodName = "/kmsetsi.KmsETSI/ETSIGetEncryptKeys256Bit"
+	KmsETSI_ETSIAssignForwarding_FullMethodName     = "/kmsetsi.KmsETSI/ETSIAssignForwarding"
+	KmsETSI_ETSISendPayload_FullMethodName          = "/kmsetsi.KmsETSI/ETSISendPayload"
 )
 
 // KmsETSIClient is the client API for KmsETSI service.
@@ -38,6 +40,8 @@ type KmsETSIClient interface {
 	ETSIRemoveKMSPeer(ctx context.Context, in *ETSIKMSPeerRequest, opts ...grpc.CallOption) (*ETSIKMSPeerReply, error)
 	ETSIGetPeerList(ctx context.Context, in *ETSIKMSPeerListRequest, opts ...grpc.CallOption) (*ETSIKMSPeerListReply, error)
 	ETSIGetEncryptKeys256Bit(ctx context.Context, in *ETSIGetEncryptKeys256BitRequest, opts ...grpc.CallOption) (*ETSIGetEncryptKeys256BitReply, error)
+	ETSIAssignForwarding(ctx context.Context, in *ETSIAssignForwardingRequest, opts ...grpc.CallOption) (*ETSIAssignForwardingReply, error)
+	ETSISendPayload(ctx context.Context, in *ETSISendPayloadRequest, opts ...grpc.CallOption) (*ETSISendPayloadResponse, error)
 }
 
 type kmsETSIClient struct {
@@ -102,6 +106,24 @@ func (c *kmsETSIClient) ETSIGetEncryptKeys256Bit(ctx context.Context, in *ETSIGe
 	return out, nil
 }
 
+func (c *kmsETSIClient) ETSIAssignForwarding(ctx context.Context, in *ETSIAssignForwardingRequest, opts ...grpc.CallOption) (*ETSIAssignForwardingReply, error) {
+	out := new(ETSIAssignForwardingReply)
+	err := c.cc.Invoke(ctx, KmsETSI_ETSIAssignForwarding_FullMethodName, in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *kmsETSIClient) ETSISendPayload(ctx context.Context, in *ETSISendPayloadRequest, opts ...grpc.CallOption) (*ETSISendPayloadResponse, error) {
+	out := new(ETSISendPayloadResponse)
+	err := c.cc.Invoke(ctx, KmsETSI_ETSISendPayload_FullMethodName, in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
 // KmsETSIServer is the server API for KmsETSI service.
 // All implementations must embed UnimplementedKmsETSIServer
 // for forward compatibility
@@ -113,6 +135,8 @@ type KmsETSIServer interface {
 	ETSIRemoveKMSPeer(context.Context, *ETSIKMSPeerRequest) (*ETSIKMSPeerReply, error)
 	ETSIGetPeerList(context.Context, *ETSIKMSPeerListRequest) (*ETSIKMSPeerListReply, error)
 	ETSIGetEncryptKeys256Bit(context.Context, *ETSIGetEncryptKeys256BitRequest) (*ETSIGetEncryptKeys256BitReply, error)
+	ETSIAssignForwarding(context.Context, *ETSIAssignForwardingRequest) (*ETSIAssignForwardingReply, error)
+	ETSISendPayload(context.Context, *ETSISendPayloadRequest) (*ETSISendPayloadResponse, error)
 	mustEmbedUnimplementedKmsETSIServer()
 }
 
@@ -138,6 +162,12 @@ func (UnimplementedKmsETSIServer) ETSIGetPeerList(context.Context, *ETSIKMSPeerL
 func (UnimplementedKmsETSIServer) ETSIGetEncryptKeys256Bit(context.Context, *ETSIGetEncryptKeys256BitRequest) (*ETSIGetEncryptKeys256BitReply, error) {
 	return nil, status.Errorf(codes.Unimplemented, "method ETSIGetEncryptKeys256Bit not implemented")
 }
+func (UnimplementedKmsETSIServer) ETSIAssignForwarding(context.Context, *ETSIAssignForwardingRequest) (*ETSIAssignForwardingReply, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method ETSIAssignForwarding not implemented")
+}
+func (UnimplementedKmsETSIServer) ETSISendPayload(context.Context, *ETSISendPayloadRequest) (*ETSISendPayloadResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method ETSISendPayload not implemented")
+}
 func (UnimplementedKmsETSIServer) mustEmbedUnimplementedKmsETSIServer() {}
 
 // UnsafeKmsETSIServer may be embedded to opt out of forward compatibility for this service.
@@ -259,6 +289,42 @@ func _KmsETSI_ETSIGetEncryptKeys256Bit_Handler(srv interface{}, ctx context.Cont
 	return interceptor(ctx, in, info, handler)
 }
 
+func _KmsETSI_ETSIAssignForwarding_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(ETSIAssignForwardingRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(KmsETSIServer).ETSIAssignForwarding(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: KmsETSI_ETSIAssignForwarding_FullMethodName,
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(KmsETSIServer).ETSIAssignForwarding(ctx, req.(*ETSIAssignForwardingRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _KmsETSI_ETSISendPayload_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(ETSISendPayloadRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(KmsETSIServer).ETSISendPayload(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: KmsETSI_ETSISendPayload_FullMethodName,
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(KmsETSIServer).ETSISendPayload(ctx, req.(*ETSISendPayloadRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
 // KmsETSI_ServiceDesc is the grpc.ServiceDesc for KmsETSI service.
 // It's only intended for direct use with grpc.RegisterService,
 // and not to be introspected or modified (even as a copy)
@@ -290,6 +356,14 @@ var KmsETSI_ServiceDesc = grpc.ServiceDesc{
 			MethodName: "ETSIGetEncryptKeys256Bit",
 			Handler:    _KmsETSI_ETSIGetEncryptKeys256Bit_Handler,
 		},
+		{
+			MethodName: "ETSIAssignForwarding",
+			Handler:    _KmsETSI_ETSIAssignForwarding_Handler,
+		},
+		{
+			MethodName: "ETSISendPayload",
+			Handler:    _KmsETSI_ETSISendPayload_Handler,
+		},
 	},
 	Streams:  []grpc.StreamDesc{},
 	Metadata: "kmsetsi/kmsetsiproto.proto",
diff --git a/internal/api/gen/proto/go/kmsintercom/kmsintercom.pb.go b/internal/api/gen/proto/go/kmsintercom/kmsintercom.pb.go
index 41fb9571aa6618d4ba597acae171d875c97969da..d066cb40e0039b8964fa9f9ba57fb6a5d89b02b6 100644
--- a/internal/api/gen/proto/go/kmsintercom/kmsintercom.pb.go
+++ b/internal/api/gen/proto/go/kmsintercom/kmsintercom.pb.go
@@ -27,7 +27,8 @@ type InterComCapabilitiesRequest struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	MyKmsName string `protobuf:"bytes,1,opt,name=myKmsName,proto3" json:"myKmsName,omitempty"`
+	Timestamp int64  `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
+	MyKmsName string `protobuf:"bytes,2,opt,name=myKmsName,proto3" json:"myKmsName,omitempty"`
 }
 
 func (x *InterComCapabilitiesRequest) Reset() {
@@ -62,6 +63,13 @@ func (*InterComCapabilitiesRequest) Descriptor() ([]byte, []int) {
 	return file_kmsintercom_kmsintercom_proto_rawDescGZIP(), []int{0}
 }
 
+func (x *InterComCapabilitiesRequest) GetTimestamp() int64 {
+	if x != nil {
+		return x.Timestamp
+	}
+	return 0
+}
+
 func (x *InterComCapabilitiesRequest) GetMyKmsName() string {
 	if x != nil {
 		return x.MyKmsName
@@ -75,7 +83,8 @@ type InterComCapabilitiesReply struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	PeerKmsName string `protobuf:"bytes,1,opt,name=peerKmsName,proto3" json:"peerKmsName,omitempty"`
+	Timestamp   int64  `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
+	PeerKmsName string `protobuf:"bytes,2,opt,name=peerKmsName,proto3" json:"peerKmsName,omitempty"`
 }
 
 func (x *InterComCapabilitiesReply) Reset() {
@@ -110,6 +119,13 @@ func (*InterComCapabilitiesReply) Descriptor() ([]byte, []int) {
 	return file_kmsintercom_kmsintercom_proto_rawDescGZIP(), []int{1}
 }
 
+func (x *InterComCapabilitiesReply) GetTimestamp() int64 {
+	if x != nil {
+		return x.Timestamp
+	}
+	return 0
+}
+
 func (x *InterComCapabilitiesReply) GetPeerKmsName() string {
 	if x != nil {
 		return x.PeerKmsName
@@ -117,18 +133,18 @@ func (x *InterComCapabilitiesReply) GetPeerKmsName() string {
 	return ""
 }
 
-// KeyTransportSessionHandling
-// The request message containing the requesting kms' name.
-type InterComKeyTransportSessionHandlingRequest struct {
+type SyncQkdBulkRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	RequestedKey string `protobuf:"bytes,1,opt,name=requestedKey,proto3" json:"requestedKey,omitempty"`
+	Timestamp    int64   `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
+	InterComAddr string  `protobuf:"bytes,2,opt,name=interComAddr,proto3" json:"interComAddr,omitempty"`
+	BulkId       []int64 `protobuf:"varint,3,rep,packed,name=bulkId,proto3" json:"bulkId,omitempty"` //string bulkHash = 4;
 }
 
-func (x *InterComKeyTransportSessionHandlingRequest) Reset() {
-	*x = InterComKeyTransportSessionHandlingRequest{}
+func (x *SyncQkdBulkRequest) Reset() {
+	*x = SyncQkdBulkRequest{}
 	if protoimpl.UnsafeEnabled {
 		mi := &file_kmsintercom_kmsintercom_proto_msgTypes[2]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -136,13 +152,13 @@ func (x *InterComKeyTransportSessionHandlingRequest) Reset() {
 	}
 }
 
-func (x *InterComKeyTransportSessionHandlingRequest) String() string {
+func (x *SyncQkdBulkRequest) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*InterComKeyTransportSessionHandlingRequest) ProtoMessage() {}
+func (*SyncQkdBulkRequest) ProtoMessage() {}
 
-func (x *InterComKeyTransportSessionHandlingRequest) ProtoReflect() protoreflect.Message {
+func (x *SyncQkdBulkRequest) ProtoReflect() protoreflect.Message {
 	mi := &file_kmsintercom_kmsintercom_proto_msgTypes[2]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -154,29 +170,43 @@ func (x *InterComKeyTransportSessionHandlingRequest) ProtoReflect() protoreflect
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use InterComKeyTransportSessionHandlingRequest.ProtoReflect.Descriptor instead.
-func (*InterComKeyTransportSessionHandlingRequest) Descriptor() ([]byte, []int) {
+// Deprecated: Use SyncQkdBulkRequest.ProtoReflect.Descriptor instead.
+func (*SyncQkdBulkRequest) Descriptor() ([]byte, []int) {
 	return file_kmsintercom_kmsintercom_proto_rawDescGZIP(), []int{2}
 }
 
-func (x *InterComKeyTransportSessionHandlingRequest) GetRequestedKey() string {
+func (x *SyncQkdBulkRequest) GetTimestamp() int64 {
+	if x != nil {
+		return x.Timestamp
+	}
+	return 0
+}
+
+func (x *SyncQkdBulkRequest) GetInterComAddr() string {
 	if x != nil {
-		return x.RequestedKey
+		return x.InterComAddr
 	}
 	return ""
 }
 
-// The response message containing the replying kms' name.
-type InterComKeyTransportSessionHandlingReply struct {
+func (x *SyncQkdBulkRequest) GetBulkId() []int64 {
+	if x != nil {
+		return x.BulkId
+	}
+	return nil
+}
+
+type SyncQkdBulkResponse struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	UsedKey string `protobuf:"bytes,1,opt,name=usedKey,proto3" json:"usedKey,omitempty"`
+	Timestamp int64 `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
+	BulkId    int64 `protobuf:"varint,2,opt,name=bulkId,proto3" json:"bulkId,omitempty"`
 }
 
-func (x *InterComKeyTransportSessionHandlingReply) Reset() {
-	*x = InterComKeyTransportSessionHandlingReply{}
+func (x *SyncQkdBulkResponse) Reset() {
+	*x = SyncQkdBulkResponse{}
 	if protoimpl.UnsafeEnabled {
 		mi := &file_kmsintercom_kmsintercom_proto_msgTypes[3]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -184,13 +214,13 @@ func (x *InterComKeyTransportSessionHandlingReply) Reset() {
 	}
 }
 
-func (x *InterComKeyTransportSessionHandlingReply) String() string {
+func (x *SyncQkdBulkResponse) String() string {
 	return protoimpl.X.MessageStringOf(x)
 }
 
-func (*InterComKeyTransportSessionHandlingReply) ProtoMessage() {}
+func (*SyncQkdBulkResponse) ProtoMessage() {}
 
-func (x *InterComKeyTransportSessionHandlingReply) ProtoReflect() protoreflect.Message {
+func (x *SyncQkdBulkResponse) ProtoReflect() protoreflect.Message {
 	mi := &file_kmsintercom_kmsintercom_proto_msgTypes[3]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -202,70 +232,337 @@ func (x *InterComKeyTransportSessionHandlingReply) ProtoReflect() protoreflect.M
 	return mi.MessageOf(x)
 }
 
-// Deprecated: Use InterComKeyTransportSessionHandlingReply.ProtoReflect.Descriptor instead.
-func (*InterComKeyTransportSessionHandlingReply) Descriptor() ([]byte, []int) {
+// Deprecated: Use SyncQkdBulkResponse.ProtoReflect.Descriptor instead.
+func (*SyncQkdBulkResponse) Descriptor() ([]byte, []int) {
 	return file_kmsintercom_kmsintercom_proto_rawDescGZIP(), []int{3}
 }
 
-func (x *InterComKeyTransportSessionHandlingReply) GetUsedKey() string {
+func (x *SyncQkdBulkResponse) GetTimestamp() int64 {
+	if x != nil {
+		return x.Timestamp
+	}
+	return 0
+}
+
+func (x *SyncQkdBulkResponse) GetBulkId() int64 {
+	if x != nil {
+		return x.BulkId
+	}
+	return 0
+}
+
+// Beim aushandeln
+type InterComTransportKeyNegotiationRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Timestamp int64  `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
+	PathID    string `protobuf:"bytes,2,opt,name=pathID,proto3" json:"pathID,omitempty"`
+	KeyToUse  uint64 `protobuf:"varint,3,opt,name=keyToUse,proto3" json:"keyToUse,omitempty"`
+}
+
+func (x *InterComTransportKeyNegotiationRequest) Reset() {
+	*x = InterComTransportKeyNegotiationRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_kmsintercom_kmsintercom_proto_msgTypes[4]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *InterComTransportKeyNegotiationRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*InterComTransportKeyNegotiationRequest) ProtoMessage() {}
+
+func (x *InterComTransportKeyNegotiationRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_kmsintercom_kmsintercom_proto_msgTypes[4]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use InterComTransportKeyNegotiationRequest.ProtoReflect.Descriptor instead.
+func (*InterComTransportKeyNegotiationRequest) Descriptor() ([]byte, []int) {
+	return file_kmsintercom_kmsintercom_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *InterComTransportKeyNegotiationRequest) GetTimestamp() int64 {
+	if x != nil {
+		return x.Timestamp
+	}
+	return 0
+}
+
+func (x *InterComTransportKeyNegotiationRequest) GetPathID() string {
+	if x != nil {
+		return x.PathID
+	}
+	return ""
+}
+
+func (x *InterComTransportKeyNegotiationRequest) GetKeyToUse() uint64 {
+	if x != nil {
+		return x.KeyToUse
+	}
+	return 0
+}
+
+type InterComTransportKeyNegotiationResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Timestamp int64 `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
+}
+
+func (x *InterComTransportKeyNegotiationResponse) Reset() {
+	*x = InterComTransportKeyNegotiationResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_kmsintercom_kmsintercom_proto_msgTypes[5]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *InterComTransportKeyNegotiationResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*InterComTransportKeyNegotiationResponse) ProtoMessage() {}
+
+func (x *InterComTransportKeyNegotiationResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_kmsintercom_kmsintercom_proto_msgTypes[5]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use InterComTransportKeyNegotiationResponse.ProtoReflect.Descriptor instead.
+func (*InterComTransportKeyNegotiationResponse) Descriptor() ([]byte, []int) {
+	return file_kmsintercom_kmsintercom_proto_rawDescGZIP(), []int{5}
+}
+
+func (x *InterComTransportKeyNegotiationResponse) GetTimestamp() int64 {
+	if x != nil {
+		return x.Timestamp
+	}
+	return 0
+}
+
+type KeyForwardingRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Timestamp int64  `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
+	PathId    string `protobuf:"bytes,2,opt,name=pathId,proto3" json:"pathId,omitempty"`
+	Payload   string `protobuf:"bytes,3,opt,name=payload,proto3" json:"payload,omitempty"`
+}
+
+func (x *KeyForwardingRequest) Reset() {
+	*x = KeyForwardingRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_kmsintercom_kmsintercom_proto_msgTypes[6]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *KeyForwardingRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*KeyForwardingRequest) ProtoMessage() {}
+
+func (x *KeyForwardingRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_kmsintercom_kmsintercom_proto_msgTypes[6]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use KeyForwardingRequest.ProtoReflect.Descriptor instead.
+func (*KeyForwardingRequest) Descriptor() ([]byte, []int) {
+	return file_kmsintercom_kmsintercom_proto_rawDescGZIP(), []int{6}
+}
+
+func (x *KeyForwardingRequest) GetTimestamp() int64 {
+	if x != nil {
+		return x.Timestamp
+	}
+	return 0
+}
+
+func (x *KeyForwardingRequest) GetPathId() string {
 	if x != nil {
-		return x.UsedKey
+		return x.PathId
 	}
 	return ""
 }
 
+func (x *KeyForwardingRequest) GetPayload() string {
+	if x != nil {
+		return x.Payload
+	}
+	return ""
+}
+
+type KeyForwardingResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Timestamp int64 `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
+}
+
+func (x *KeyForwardingResponse) Reset() {
+	*x = KeyForwardingResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_kmsintercom_kmsintercom_proto_msgTypes[7]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *KeyForwardingResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*KeyForwardingResponse) ProtoMessage() {}
+
+func (x *KeyForwardingResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_kmsintercom_kmsintercom_proto_msgTypes[7]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use KeyForwardingResponse.ProtoReflect.Descriptor instead.
+func (*KeyForwardingResponse) Descriptor() ([]byte, []int) {
+	return file_kmsintercom_kmsintercom_proto_rawDescGZIP(), []int{7}
+}
+
+func (x *KeyForwardingResponse) GetTimestamp() int64 {
+	if x != nil {
+		return x.Timestamp
+	}
+	return 0
+}
+
 var File_kmsintercom_kmsintercom_proto protoreflect.FileDescriptor
 
 var file_kmsintercom_kmsintercom_proto_rawDesc = []byte{
 	0x0a, 0x1d, 0x6b, 0x6d, 0x73, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6d, 0x2f, 0x6b, 0x6d,
 	0x73, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12,
-	0x0b, 0x6b, 0x6d, 0x73, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6d, 0x22, 0x3b, 0x0a, 0x1b,
+	0x0b, 0x6b, 0x6d, 0x73, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6d, 0x22, 0x59, 0x0a, 0x1b,
 	0x49, 0x6e, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69,
-	0x74, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6d,
-	0x79, 0x4b, 0x6d, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09,
-	0x6d, 0x79, 0x4b, 0x6d, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x3d, 0x0a, 0x19, 0x49, 0x6e, 0x74,
-	0x65, 0x72, 0x43, 0x6f, 0x6d, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65,
-	0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x65, 0x65, 0x72, 0x4b, 0x6d,
-	0x73, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x65, 0x65,
-	0x72, 0x4b, 0x6d, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x50, 0x0a, 0x2a, 0x49, 0x6e, 0x74, 0x65,
-	0x72, 0x43, 0x6f, 0x6d, 0x4b, 0x65, 0x79, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74,
-	0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x69, 0x6e, 0x67, 0x52,
-	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x22, 0x0a, 0x0c, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73,
-	0x74, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65,
-	0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x22, 0x44, 0x0a, 0x28, 0x49, 0x6e,
-	0x74, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x4b, 0x65, 0x79, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f,
-	0x72, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x69, 0x6e,
-	0x67, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x64, 0x4b, 0x65,
-	0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x75, 0x73, 0x65, 0x64, 0x4b, 0x65, 0x79,
-	0x32, 0x91, 0x02, 0x0a, 0x09, 0x4b, 0x6d, 0x73, 0x54, 0x61, 0x6c, 0x6b, 0x65, 0x72, 0x12, 0x6a,
-	0x0a, 0x14, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69,
-	0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x28, 0x2e, 0x6b, 0x6d, 0x73, 0x69, 0x6e, 0x74, 0x65,
-	0x72, 0x63, 0x6f, 0x6d, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x43, 0x61, 0x70,
-	0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
-	0x1a, 0x26, 0x2e, 0x6b, 0x6d, 0x73, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6d, 0x2e, 0x49,
-	0x6e, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74,
-	0x69, 0x65, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x97, 0x01, 0x0a, 0x23, 0x49,
-	0x6e, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x4b, 0x65, 0x79, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70,
-	0x6f, 0x72, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x69,
-	0x6e, 0x67, 0x12, 0x37, 0x2e, 0x6b, 0x6d, 0x73, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6d,
-	0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x4b, 0x65, 0x79, 0x54, 0x72, 0x61, 0x6e,
-	0x73, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x48, 0x61, 0x6e, 0x64,
-	0x6c, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x6b, 0x6d,
+	0x74, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74,
+	0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09,
+	0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1c, 0x0a, 0x09, 0x6d, 0x79, 0x4b,
+	0x6d, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x79,
+	0x4b, 0x6d, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x5b, 0x0a, 0x19, 0x49, 0x6e, 0x74, 0x65, 0x72,
+	0x43, 0x6f, 0x6d, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x52,
+	0x65, 0x70, 0x6c, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d,
+	0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61,
+	0x6d, 0x70, 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x65, 0x65, 0x72, 0x4b, 0x6d, 0x73, 0x4e, 0x61, 0x6d,
+	0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x65, 0x65, 0x72, 0x4b, 0x6d, 0x73,
+	0x4e, 0x61, 0x6d, 0x65, 0x22, 0x6e, 0x0a, 0x12, 0x53, 0x79, 0x6e, 0x63, 0x51, 0x6b, 0x64, 0x42,
+	0x75, 0x6c, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69,
+	0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74,
+	0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x22, 0x0a, 0x0c, 0x69, 0x6e, 0x74, 0x65,
+	0x72, 0x43, 0x6f, 0x6d, 0x41, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c,
+	0x69, 0x6e, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x41, 0x64, 0x64, 0x72, 0x12, 0x16, 0x0a, 0x06,
+	0x62, 0x75, 0x6c, 0x6b, 0x49, 0x64, 0x18, 0x03, 0x20, 0x03, 0x28, 0x03, 0x52, 0x06, 0x62, 0x75,
+	0x6c, 0x6b, 0x49, 0x64, 0x22, 0x4b, 0x0a, 0x13, 0x53, 0x79, 0x6e, 0x63, 0x51, 0x6b, 0x64, 0x42,
+	0x75, 0x6c, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74,
+	0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09,
+	0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x75, 0x6c,
+	0x6b, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x62, 0x75, 0x6c, 0x6b, 0x49,
+	0x64, 0x22, 0x7a, 0x0a, 0x26, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x54, 0x72, 0x61,
+	0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x4b, 0x65, 0x79, 0x4e, 0x65, 0x67, 0x6f, 0x74, 0x69, 0x61,
+	0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74,
+	0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09,
+	0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x61, 0x74,
+	0x68, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x61, 0x74, 0x68, 0x49,
+	0x44, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x54, 0x6f, 0x55, 0x73, 0x65, 0x18, 0x03, 0x20,
+	0x01, 0x28, 0x04, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x54, 0x6f, 0x55, 0x73, 0x65, 0x22, 0x47, 0x0a,
+	0x27, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f,
+	0x72, 0x74, 0x4b, 0x65, 0x79, 0x4e, 0x65, 0x67, 0x6f, 0x74, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65,
+	0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d,
+	0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x66, 0x0a, 0x14, 0x4b, 0x65, 0x79, 0x46, 0x6f, 0x72,
+	0x77, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c,
+	0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x16, 0x0a, 0x06,
+	0x70, 0x61, 0x74, 0x68, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x61,
+	0x74, 0x68, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18,
+	0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x35,
+	0x0a, 0x15, 0x4b, 0x65, 0x79, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x52,
+	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73,
+	0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65,
+	0x73, 0x74, 0x61, 0x6d, 0x70, 0x32, 0xb6, 0x03, 0x0a, 0x09, 0x4b, 0x6d, 0x73, 0x54, 0x61, 0x6c,
+	0x6b, 0x65, 0x72, 0x12, 0x6a, 0x0a, 0x14, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x43,
+	0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x28, 0x2e, 0x6b, 0x6d,
 	0x73, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6d, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x43,
-	0x6f, 0x6d, 0x4b, 0x65, 0x79, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x65,
-	0x73, 0x73, 0x69, 0x6f, 0x6e, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x70,
-	0x6c, 0x79, 0x22, 0x00, 0x42, 0xaf, 0x01, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x2e, 0x6b, 0x6d, 0x73,
-	0x69, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6d, 0x42, 0x10, 0x4b, 0x6d, 0x73, 0x69, 0x6e, 0x74,
-	0x65, 0x72, 0x63, 0x6f, 0x6d, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3e, 0x63, 0x6f,
-	0x64, 0x65, 0x2e, 0x66, 0x62, 0x69, 0x2e, 0x68, 0x2d, 0x64, 0x61, 0x2e, 0x64, 0x65, 0x2f, 0x64,
-	0x65, 0x6d, 0x6f, 0x71, 0x75, 0x61, 0x6e, 0x64, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d,
-	0x6b, 0x6d, 0x73, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f,
-	0x2f, 0x6b, 0x6d, 0x73, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6d, 0xa2, 0x02, 0x03, 0x4b,
-	0x58, 0x58, 0xaa, 0x02, 0x0b, 0x4b, 0x6d, 0x73, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6d,
-	0xca, 0x02, 0x0b, 0x4b, 0x6d, 0x73, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6d, 0xe2, 0x02,
-	0x17, 0x4b, 0x6d, 0x73, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6d, 0x5c, 0x47, 0x50, 0x42,
-	0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0b, 0x4b, 0x6d, 0x73, 0x69, 0x6e,
-	0x74, 0x65, 0x72, 0x63, 0x6f, 0x6d, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x6f, 0x6d, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x6b, 0x6d, 0x73, 0x69, 0x6e, 0x74, 0x65, 0x72,
+	0x63, 0x6f, 0x6d, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x43, 0x61, 0x70, 0x61,
+	0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12,
+	0x52, 0x0a, 0x0b, 0x53, 0x79, 0x6e, 0x63, 0x51, 0x6b, 0x64, 0x42, 0x75, 0x6c, 0x6b, 0x12, 0x1f,
+	0x2e, 0x6b, 0x6d, 0x73, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6d, 0x2e, 0x53, 0x79, 0x6e,
+	0x63, 0x51, 0x6b, 0x64, 0x42, 0x75, 0x6c, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
+	0x20, 0x2e, 0x6b, 0x6d, 0x73, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6d, 0x2e, 0x53, 0x79,
+	0x6e, 0x63, 0x51, 0x6b, 0x64, 0x42, 0x75, 0x6c, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+	0x65, 0x22, 0x00, 0x12, 0x8e, 0x01, 0x0a, 0x1f, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6d,
+	0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x4b, 0x65, 0x79, 0x4e, 0x65, 0x67, 0x6f,
+	0x74, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x33, 0x2e, 0x6b, 0x6d, 0x73, 0x69, 0x6e, 0x74,
+	0x65, 0x72, 0x63, 0x6f, 0x6d, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x54, 0x72,
+	0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x4b, 0x65, 0x79, 0x4e, 0x65, 0x67, 0x6f, 0x74, 0x69,
+	0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x6b,
+	0x6d, 0x73, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6d, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72,
+	0x43, 0x6f, 0x6d, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x4b, 0x65, 0x79, 0x4e,
+	0x65, 0x67, 0x6f, 0x74, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x22, 0x00, 0x12, 0x58, 0x0a, 0x0d, 0x4b, 0x65, 0x79, 0x46, 0x6f, 0x72, 0x77, 0x61,
+	0x72, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x21, 0x2e, 0x6b, 0x6d, 0x73, 0x69, 0x6e, 0x74, 0x65, 0x72,
+	0x63, 0x6f, 0x6d, 0x2e, 0x4b, 0x65, 0x79, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x69, 0x6e,
+	0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x6b, 0x6d, 0x73, 0x69, 0x6e,
+	0x74, 0x65, 0x72, 0x63, 0x6f, 0x6d, 0x2e, 0x4b, 0x65, 0x79, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72,
+	0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0xaf,
+	0x01, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x2e, 0x6b, 0x6d, 0x73, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x63,
+	0x6f, 0x6d, 0x42, 0x10, 0x4b, 0x6d, 0x73, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6d, 0x50,
+	0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3e, 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x66, 0x62, 0x69,
+	0x2e, 0x68, 0x2d, 0x64, 0x61, 0x2e, 0x64, 0x65, 0x2f, 0x64, 0x65, 0x6d, 0x6f, 0x71, 0x75, 0x61,
+	0x6e, 0x64, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x6b, 0x6d, 0x73, 0x2f, 0x67, 0x65,
+	0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x6b, 0x6d, 0x73, 0x69, 0x6e,
+	0x74, 0x65, 0x72, 0x63, 0x6f, 0x6d, 0xa2, 0x02, 0x03, 0x4b, 0x58, 0x58, 0xaa, 0x02, 0x0b, 0x4b,
+	0x6d, 0x73, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6d, 0xca, 0x02, 0x0b, 0x4b, 0x6d, 0x73,
+	0x69, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6d, 0xe2, 0x02, 0x17, 0x4b, 0x6d, 0x73, 0x69, 0x6e,
+	0x74, 0x65, 0x72, 0x63, 0x6f, 0x6d, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61,
+	0x74, 0x61, 0xea, 0x02, 0x0b, 0x4b, 0x6d, 0x73, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x6f, 0x6d,
+	0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
@@ -280,20 +577,28 @@ func file_kmsintercom_kmsintercom_proto_rawDescGZIP() []byte {
 	return file_kmsintercom_kmsintercom_proto_rawDescData
 }
 
-var file_kmsintercom_kmsintercom_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
+var file_kmsintercom_kmsintercom_proto_msgTypes = make([]protoimpl.MessageInfo, 8)
 var file_kmsintercom_kmsintercom_proto_goTypes = []interface{}{
-	(*InterComCapabilitiesRequest)(nil),                // 0: kmsintercom.InterComCapabilitiesRequest
-	(*InterComCapabilitiesReply)(nil),                  // 1: kmsintercom.InterComCapabilitiesReply
-	(*InterComKeyTransportSessionHandlingRequest)(nil), // 2: kmsintercom.InterComKeyTransportSessionHandlingRequest
-	(*InterComKeyTransportSessionHandlingReply)(nil),   // 3: kmsintercom.InterComKeyTransportSessionHandlingReply
+	(*InterComCapabilitiesRequest)(nil),             // 0: kmsintercom.InterComCapabilitiesRequest
+	(*InterComCapabilitiesReply)(nil),               // 1: kmsintercom.InterComCapabilitiesReply
+	(*SyncQkdBulkRequest)(nil),                      // 2: kmsintercom.SyncQkdBulkRequest
+	(*SyncQkdBulkResponse)(nil),                     // 3: kmsintercom.SyncQkdBulkResponse
+	(*InterComTransportKeyNegotiationRequest)(nil),  // 4: kmsintercom.InterComTransportKeyNegotiationRequest
+	(*InterComTransportKeyNegotiationResponse)(nil), // 5: kmsintercom.InterComTransportKeyNegotiationResponse
+	(*KeyForwardingRequest)(nil),                    // 6: kmsintercom.KeyForwardingRequest
+	(*KeyForwardingResponse)(nil),                   // 7: kmsintercom.KeyForwardingResponse
 }
 var file_kmsintercom_kmsintercom_proto_depIdxs = []int32{
 	0, // 0: kmsintercom.KmsTalker.InterComCapabilities:input_type -> kmsintercom.InterComCapabilitiesRequest
-	2, // 1: kmsintercom.KmsTalker.InterComKeyTransportSessionHandling:input_type -> kmsintercom.InterComKeyTransportSessionHandlingRequest
-	1, // 2: kmsintercom.KmsTalker.InterComCapabilities:output_type -> kmsintercom.InterComCapabilitiesReply
-	3, // 3: kmsintercom.KmsTalker.InterComKeyTransportSessionHandling:output_type -> kmsintercom.InterComKeyTransportSessionHandlingReply
-	2, // [2:4] is the sub-list for method output_type
-	0, // [0:2] is the sub-list for method input_type
+	2, // 1: kmsintercom.KmsTalker.SyncQkdBulk:input_type -> kmsintercom.SyncQkdBulkRequest
+	4, // 2: kmsintercom.KmsTalker.InterComTransportKeyNegotiation:input_type -> kmsintercom.InterComTransportKeyNegotiationRequest
+	6, // 3: kmsintercom.KmsTalker.KeyForwarding:input_type -> kmsintercom.KeyForwardingRequest
+	1, // 4: kmsintercom.KmsTalker.InterComCapabilities:output_type -> kmsintercom.InterComCapabilitiesReply
+	3, // 5: kmsintercom.KmsTalker.SyncQkdBulk:output_type -> kmsintercom.SyncQkdBulkResponse
+	5, // 6: kmsintercom.KmsTalker.InterComTransportKeyNegotiation:output_type -> kmsintercom.InterComTransportKeyNegotiationResponse
+	7, // 7: kmsintercom.KmsTalker.KeyForwarding:output_type -> kmsintercom.KeyForwardingResponse
+	4, // [4:8] is the sub-list for method output_type
+	0, // [0:4] is the sub-list for method input_type
 	0, // [0:0] is the sub-list for extension type_name
 	0, // [0:0] is the sub-list for extension extendee
 	0, // [0:0] is the sub-list for field type_name
@@ -330,7 +635,7 @@ func file_kmsintercom_kmsintercom_proto_init() {
 			}
 		}
 		file_kmsintercom_kmsintercom_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*InterComKeyTransportSessionHandlingRequest); i {
+			switch v := v.(*SyncQkdBulkRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -342,7 +647,55 @@ func file_kmsintercom_kmsintercom_proto_init() {
 			}
 		}
 		file_kmsintercom_kmsintercom_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*InterComKeyTransportSessionHandlingReply); i {
+			switch v := v.(*SyncQkdBulkResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_kmsintercom_kmsintercom_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*InterComTransportKeyNegotiationRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_kmsintercom_kmsintercom_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*InterComTransportKeyNegotiationResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_kmsintercom_kmsintercom_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*KeyForwardingRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_kmsintercom_kmsintercom_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*KeyForwardingResponse); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -360,7 +713,7 @@ func file_kmsintercom_kmsintercom_proto_init() {
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
 			RawDescriptor: file_kmsintercom_kmsintercom_proto_rawDesc,
 			NumEnums:      0,
-			NumMessages:   4,
+			NumMessages:   8,
 			NumExtensions: 0,
 			NumServices:   1,
 		},
diff --git a/internal/api/gen/proto/go/kmsintercom/kmsintercom_grpc.pb.go b/internal/api/gen/proto/go/kmsintercom/kmsintercom_grpc.pb.go
index 41dac93ae286b25d52cd099f75f07c40377a6b8c..82c323ca685b105982bc6ef7e950c228a91f6319 100644
--- a/internal/api/gen/proto/go/kmsintercom/kmsintercom_grpc.pb.go
+++ b/internal/api/gen/proto/go/kmsintercom/kmsintercom_grpc.pb.go
@@ -19,8 +19,10 @@ import (
 const _ = grpc.SupportPackageIsVersion7
 
 const (
-	KmsTalker_InterComCapabilities_FullMethodName                = "/kmsintercom.KmsTalker/InterComCapabilities"
-	KmsTalker_InterComKeyTransportSessionHandling_FullMethodName = "/kmsintercom.KmsTalker/InterComKeyTransportSessionHandling"
+	KmsTalker_InterComCapabilities_FullMethodName            = "/kmsintercom.KmsTalker/InterComCapabilities"
+	KmsTalker_SyncQkdBulk_FullMethodName                     = "/kmsintercom.KmsTalker/SyncQkdBulk"
+	KmsTalker_InterComTransportKeyNegotiation_FullMethodName = "/kmsintercom.KmsTalker/InterComTransportKeyNegotiation"
+	KmsTalker_KeyForwarding_FullMethodName                   = "/kmsintercom.KmsTalker/KeyForwarding"
 )
 
 // KmsTalkerClient is the client API for KmsTalker service.
@@ -28,7 +30,9 @@ const (
 // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
 type KmsTalkerClient interface {
 	InterComCapabilities(ctx context.Context, in *InterComCapabilitiesRequest, opts ...grpc.CallOption) (*InterComCapabilitiesReply, error)
-	InterComKeyTransportSessionHandling(ctx context.Context, in *InterComKeyTransportSessionHandlingRequest, opts ...grpc.CallOption) (*InterComKeyTransportSessionHandlingReply, error)
+	SyncQkdBulk(ctx context.Context, in *SyncQkdBulkRequest, opts ...grpc.CallOption) (*SyncQkdBulkResponse, error)
+	InterComTransportKeyNegotiation(ctx context.Context, in *InterComTransportKeyNegotiationRequest, opts ...grpc.CallOption) (*InterComTransportKeyNegotiationResponse, error)
+	KeyForwarding(ctx context.Context, in *KeyForwardingRequest, opts ...grpc.CallOption) (*KeyForwardingResponse, error)
 }
 
 type kmsTalkerClient struct {
@@ -48,9 +52,27 @@ func (c *kmsTalkerClient) InterComCapabilities(ctx context.Context, in *InterCom
 	return out, nil
 }
 
-func (c *kmsTalkerClient) InterComKeyTransportSessionHandling(ctx context.Context, in *InterComKeyTransportSessionHandlingRequest, opts ...grpc.CallOption) (*InterComKeyTransportSessionHandlingReply, error) {
-	out := new(InterComKeyTransportSessionHandlingReply)
-	err := c.cc.Invoke(ctx, KmsTalker_InterComKeyTransportSessionHandling_FullMethodName, in, out, opts...)
+func (c *kmsTalkerClient) SyncQkdBulk(ctx context.Context, in *SyncQkdBulkRequest, opts ...grpc.CallOption) (*SyncQkdBulkResponse, error) {
+	out := new(SyncQkdBulkResponse)
+	err := c.cc.Invoke(ctx, KmsTalker_SyncQkdBulk_FullMethodName, in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *kmsTalkerClient) InterComTransportKeyNegotiation(ctx context.Context, in *InterComTransportKeyNegotiationRequest, opts ...grpc.CallOption) (*InterComTransportKeyNegotiationResponse, error) {
+	out := new(InterComTransportKeyNegotiationResponse)
+	err := c.cc.Invoke(ctx, KmsTalker_InterComTransportKeyNegotiation_FullMethodName, in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *kmsTalkerClient) KeyForwarding(ctx context.Context, in *KeyForwardingRequest, opts ...grpc.CallOption) (*KeyForwardingResponse, error) {
+	out := new(KeyForwardingResponse)
+	err := c.cc.Invoke(ctx, KmsTalker_KeyForwarding_FullMethodName, in, out, opts...)
 	if err != nil {
 		return nil, err
 	}
@@ -62,7 +84,9 @@ func (c *kmsTalkerClient) InterComKeyTransportSessionHandling(ctx context.Contex
 // for forward compatibility
 type KmsTalkerServer interface {
 	InterComCapabilities(context.Context, *InterComCapabilitiesRequest) (*InterComCapabilitiesReply, error)
-	InterComKeyTransportSessionHandling(context.Context, *InterComKeyTransportSessionHandlingRequest) (*InterComKeyTransportSessionHandlingReply, error)
+	SyncQkdBulk(context.Context, *SyncQkdBulkRequest) (*SyncQkdBulkResponse, error)
+	InterComTransportKeyNegotiation(context.Context, *InterComTransportKeyNegotiationRequest) (*InterComTransportKeyNegotiationResponse, error)
+	KeyForwarding(context.Context, *KeyForwardingRequest) (*KeyForwardingResponse, error)
 	mustEmbedUnimplementedKmsTalkerServer()
 }
 
@@ -73,8 +97,14 @@ type UnimplementedKmsTalkerServer struct {
 func (UnimplementedKmsTalkerServer) InterComCapabilities(context.Context, *InterComCapabilitiesRequest) (*InterComCapabilitiesReply, error) {
 	return nil, status.Errorf(codes.Unimplemented, "method InterComCapabilities not implemented")
 }
-func (UnimplementedKmsTalkerServer) InterComKeyTransportSessionHandling(context.Context, *InterComKeyTransportSessionHandlingRequest) (*InterComKeyTransportSessionHandlingReply, error) {
-	return nil, status.Errorf(codes.Unimplemented, "method InterComKeyTransportSessionHandling not implemented")
+func (UnimplementedKmsTalkerServer) SyncQkdBulk(context.Context, *SyncQkdBulkRequest) (*SyncQkdBulkResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method SyncQkdBulk not implemented")
+}
+func (UnimplementedKmsTalkerServer) InterComTransportKeyNegotiation(context.Context, *InterComTransportKeyNegotiationRequest) (*InterComTransportKeyNegotiationResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method InterComTransportKeyNegotiation not implemented")
+}
+func (UnimplementedKmsTalkerServer) KeyForwarding(context.Context, *KeyForwardingRequest) (*KeyForwardingResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method KeyForwarding not implemented")
 }
 func (UnimplementedKmsTalkerServer) mustEmbedUnimplementedKmsTalkerServer() {}
 
@@ -107,20 +137,56 @@ func _KmsTalker_InterComCapabilities_Handler(srv interface{}, ctx context.Contex
 	return interceptor(ctx, in, info, handler)
 }
 
-func _KmsTalker_InterComKeyTransportSessionHandling_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(InterComKeyTransportSessionHandlingRequest)
+func _KmsTalker_SyncQkdBulk_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(SyncQkdBulkRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(KmsTalkerServer).SyncQkdBulk(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: KmsTalker_SyncQkdBulk_FullMethodName,
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(KmsTalkerServer).SyncQkdBulk(ctx, req.(*SyncQkdBulkRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _KmsTalker_InterComTransportKeyNegotiation_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(InterComTransportKeyNegotiationRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(KmsTalkerServer).InterComTransportKeyNegotiation(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: KmsTalker_InterComTransportKeyNegotiation_FullMethodName,
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(KmsTalkerServer).InterComTransportKeyNegotiation(ctx, req.(*InterComTransportKeyNegotiationRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _KmsTalker_KeyForwarding_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(KeyForwardingRequest)
 	if err := dec(in); err != nil {
 		return nil, err
 	}
 	if interceptor == nil {
-		return srv.(KmsTalkerServer).InterComKeyTransportSessionHandling(ctx, in)
+		return srv.(KmsTalkerServer).KeyForwarding(ctx, in)
 	}
 	info := &grpc.UnaryServerInfo{
 		Server:     srv,
-		FullMethod: KmsTalker_InterComKeyTransportSessionHandling_FullMethodName,
+		FullMethod: KmsTalker_KeyForwarding_FullMethodName,
 	}
 	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(KmsTalkerServer).InterComKeyTransportSessionHandling(ctx, req.(*InterComKeyTransportSessionHandlingRequest))
+		return srv.(KmsTalkerServer).KeyForwarding(ctx, req.(*KeyForwardingRequest))
 	}
 	return interceptor(ctx, in, info, handler)
 }
@@ -137,8 +203,16 @@ var KmsTalker_ServiceDesc = grpc.ServiceDesc{
 			Handler:    _KmsTalker_InterComCapabilities_Handler,
 		},
 		{
-			MethodName: "InterComKeyTransportSessionHandling",
-			Handler:    _KmsTalker_InterComKeyTransportSessionHandling_Handler,
+			MethodName: "SyncQkdBulk",
+			Handler:    _KmsTalker_SyncQkdBulk_Handler,
+		},
+		{
+			MethodName: "InterComTransportKeyNegotiation",
+			Handler:    _KmsTalker_InterComTransportKeyNegotiation_Handler,
+		},
+		{
+			MethodName: "KeyForwarding",
+			Handler:    _KmsTalker_KeyForwarding_Handler,
 		},
 	},
 	Streams:  []grpc.StreamDesc{},
diff --git a/internal/api/kmsetsi/kmsetsi/kmsetsiproto.proto b/internal/api/kmsetsi/kmsetsi/kmsetsiproto.proto
index 9f0cc1e77236d1435a4bf1c21b129256ffd0ec15..261dd51b19f928ed0d9bb1ce6ab05da8b500ab6f 100644
--- a/internal/api/kmsetsi/kmsetsi/kmsetsiproto.proto
+++ b/internal/api/kmsetsi/kmsetsi/kmsetsiproto.proto
@@ -2,65 +2,74 @@ syntax = "proto3";
 
 package kmsetsi;
 
-service KmsETSI {
+// TODO: this can be removed
+service KmsETSI{
 	// Sends a greeting
-	rpc ETSICapabilities (ETSICapabilitiesRequest) returns (ETSICapabilitiesReply) {}
-  rpc ETSIGetQuantumInterfaces(ETSIKMSQuantumInterfaceListRequest) returns (ETSIKMSQuantumInterfaceListReply) {}
-  rpc ETSIAddKMSPeer(ETSIKMSPeerRequest) returns (ETSIKMSPeerReply) {}
-  rpc ETSIRemoveKMSPeer(ETSIKMSPeerRequest) returns (ETSIKMSPeerReply) {}
-  rpc ETSIGetPeerList(ETSIKMSPeerListRequest) returns (ETSIKMSPeerListReply) {}
-  rpc ETSIGetEncryptKeys256Bit (ETSIGetEncryptKeys256BitRequest) returns (ETSIGetEncryptKeys256BitReply) {}
+    rpc ETSICapabilities(ETSICapabilitiesRequest) returns (ETSICapabilitiesReply) {}
+    rpc ETSIGetQuantumInterfaces(ETSIKMSQuantumInterfaceListRequest) returns (ETSIKMSQuantumInterfaceListReply) {}
+    rpc ETSIAddKMSPeer(ETSIKMSPeerRequest) returns (ETSIKMSPeerReply) {}
+    rpc ETSIRemoveKMSPeer(ETSIKMSPeerRequest) returns (ETSIKMSPeerReply) {}
+    rpc ETSIGetPeerList(ETSIKMSPeerListRequest) returns (ETSIKMSPeerListReply) {}
+    rpc ETSIGetEncryptKeys256Bit(ETSIGetEncryptKeys256BitRequest) returns (ETSIGetEncryptKeys256BitReply) {}
+    rpc ETSIAssignForwarding(ETSIAssignForwardingRequest) returns (ETSIAssignForwardingReply) {}
+    rpc ETSISendPayload(ETSISendPayloadRequest) returns (ETSISendPayloadResponse) {}
   }
 
+// NB for myself: this be used to link QLE mit KMS-Session!
+message QuantumElementInfo {
+	int64 timestamp = 1;
+    uint64 qleID = 2;
+    string udpAddr = 3;
+}
+
   // The request message containing the user's name.
 message ETSICapabilitiesRequest {
-	string myKmsName = 1;
+	int64 timestamp = 1;
+	string myKmsName = 2;
 }
 
   // The response message containing the greetings
   message ETSICapabilitiesReply {
-	string peerKmsName = 1;
+	int64 timestamp = 1;
+	string peerKmsName = 2;
 }
 
 message ETSIKMSQuantumInterfaceListRequest {
-
-}
-
-// NB for myself: this be used to link QLE mit KMS-Session!
-message QuantumElementInfo {
-  uint64 qleID = 1;
-  string udpAddr = 2;
+	int64 timestamp = 1;
 }
 
 message ETSIKMSQuantumInterfaceListReply {
-  repeated QuantumElementInfo qlElementInfo = 1;
+	int64 timestamp = 1;
+    repeated QuantumElementInfo qlElementInfo = 2;
 }
 
-
 message ETSIKMSPeerRequest {
-  string kmsPeerSocket = 1;
-  uint32 kmsLocalQLEId = 2;
+	int64 timestamp = 1;
+    string kmsPeerSocket = 2;
+    uint32 kmsLocalQLEId = 3;
 }
 
 message ETSIKMSPeerReply {
-  string kmsPeerName  = 1;
+	int64 timestamp = 1;
+    string kmsPeerName  = 2;
 }
 
 message ETSIKMSPeerListRequest {
+	int64 timestamp = 1;
 }
 
 message ETSIKMSPeer {
-  string peerName = 1;
-  string peerStatus = 2;
-
+	int64 timestamp = 1;
+    string peerName = 2;
+    string peerStatus = 3;
 }
 
 message ETSIKMSPeerListReply {
-  repeated ETSIKMSPeer peer = 1;
+    repeated ETSIKMSPeer peer = 1;
 }
 
 message ETSIGetEncryptKeys256BitRequest {
-  int64 amount = 1;
+    int64 amount = 1;
 }
 
 /* out kms-keystore.go
@@ -74,3 +83,24 @@ message ETSIGetEncryptKeys256BitReply {
   uint64 keyID = 1;
   bytes key = 2;
 }
+
+message ETSIAssignForwardingRequest {
+    int64 timestamp = 1;
+    string pathId = 2;
+    string prevHop= 3;
+    string nextHop= 4;
+}
+
+message ETSIAssignForwardingReply {
+    int64 timestamp = 1;
+}
+
+message ETSISendPayloadRequest {
+    int64 timestamp = 1;
+    string pathId = 2;
+    string payload = 3;
+}
+
+message ETSISendPayloadResponse {
+    int64 timestamp = 1;
+}
diff --git a/internal/api/kmsintercom/kmsintercom/kmsintercom.proto b/internal/api/kmsintercom/kmsintercom/kmsintercom.proto
index 52af6f1e24f6dbd018a3a361349aa59446a1f686..f668ce7e88896a49dcb082347743383fe730b533 100644
--- a/internal/api/kmsintercom/kmsintercom/kmsintercom.proto
+++ b/internal/api/kmsintercom/kmsintercom/kmsintercom.proto
@@ -2,29 +2,57 @@ syntax = "proto3";
 
 package kmsintercom;
 
+// should be renamed to InterCom or KMSInterCom
 service KmsTalker {
 	rpc InterComCapabilities (InterComCapabilitiesRequest) returns (InterComCapabilitiesReply) {}
-	rpc InterComKeyTransportSessionHandling(InterComKeyTransportSessionHandlingRequest) returns (InterComKeyTransportSessionHandlingReply) {}
+    rpc SyncQkdBulk(SyncQkdBulkRequest) returns (SyncQkdBulkResponse) {}
+	rpc InterComTransportKeyNegotiation(InterComTransportKeyNegotiationRequest) returns (InterComTransportKeyNegotiationResponse) {}
+    rpc KeyForwarding(KeyForwardingRequest) returns (KeyForwardingResponse) {}
 }
 
 // Capabilities
 // The request message containing the requesting kms' name.
 message InterComCapabilitiesRequest {
-	string myKmsName = 1;
-  }
+	int64 timestamp = 1;
+	string myKmsName = 2;
+}
 
 // The response message containing the replying kms' name.
 message InterComCapabilitiesReply {
-	string peerKmsName= 1;
+	int64 timestamp = 1;
+	string peerKmsName= 2;
 }
 
-// KeyTransportSessionHandling
-// The request message containing the requesting kms' name.
-message InterComKeyTransportSessionHandlingRequest {
-	string requestedKey = 1;
-  }
+message SyncQkdBulkRequest {
+	int64 timestamp = 1;
+    string interComAddr = 2;
+	repeated int64 bulkId = 3;
+	//string bulkHash = 4;
+}
 
-// The response message containing the replying kms' name.
-message InterComKeyTransportSessionHandlingReply {
-	string usedKey = 1;
+message SyncQkdBulkResponse {
+	int64 timestamp = 1;
+    int64 bulkId = 2;
 }
+
+// Beim aushandeln
+message InterComTransportKeyNegotiationRequest {
+	int64 timestamp = 1;
+    string pathID = 2;
+    uint64 keyToUse = 3;
+}
+
+message InterComTransportKeyNegotiationResponse {
+	int64 timestamp = 1;
+}
+
+message KeyForwardingRequest {
+	int64 timestamp = 1;
+	string pathId = 2;
+	string payload = 3;
+}
+
+message KeyForwardingResponse {
+	int64 timestamp = 1;
+}
+
diff --git a/internal/docs/grpcurl-sheet.md b/internal/docs/grpcurl-sheet.md
new file mode 100644
index 0000000000000000000000000000000000000000..dd4e8447a98cdb4388c73241dbd35a71a09022de
--- /dev/null
+++ b/internal/docs/grpcurl-sheet.md
@@ -0,0 +1,32 @@
+# Info for testing with grpcurl
+
+https://github.com/fullstorydev/grpcurl
+
+###
+
+'grpcurl -d '{"myKmsName" : "grpcurl"}' --import-path ./kmsetsiproto --proto kmsetsiproto.proto  --plaintext localhost:50900  kmsetsiproto.KmsETSI.ETSICapabilities
+{  "peerKmsName": "whatever"}'
+
+'grpcurl -d '{"kmsPeerSocket" : "127.0.0.1:50901"}' --import-path ./kmsetsiproto --proto kmsetsiproto.proto  --plaintext localhost:50900  kmsetsiproto.KmsETSI.ETSIAddKMSPeer'
+
+## Assign Forwarding for example
+'grpcurl -d '{"kmsPeerSocket" : "127.0.0.1:50901"}' --import-path ./kmsetsiproto --proto kmsetsiproto.proto  --plaintext localhost:50900  kmsetsiproto.KmsETSI.ETSIAddKMSPeer'
+
+### From left to middle
+`grpcurl -d '{"pathId" : "f6a575e5-c7f9-4765-8890-134ae5b8f451", "nextHop" : "[::1]:50932"}' --import-path ./kmsetsi --proto kmsetsiproto.proto  --plaintext [::1]:50900  kmsetsi.KmsETSI.ETSIAssignForwarding`
+### Left is endpoint
+`grpcurl -d '{"pathId" : "f6a575e5-c7f9-4765-8890-134ae5b8f451", "nextHop" : "", "previousHop" : "[::1]50932"}' --import-path ./kmsetsi --proto kmsetsiproto.proto  --plaintext [::1]:50900  kmsetsi.KmsETSI.ETSIAssignForwarding`
+### From right to middle
+`grpcurl -d '{"pathId" : "f6a575e5-c7f9-4765-8890-134ae5b8f451", "nextHop" : "[::1]:50932"}' --import-path ./kmsetsi --proto kmsetsiproto.proto  --plaintext [::1]:50901  kmsetsi.KmsETSI.ETSIAssignForwarding`
+### Right is endpoint
+`grpcurl -d '{"pathId" : "f6a575e5-c7f9-4765-8890-134ae5b8f451", "nextHop" : "", "previousHop" : "[::1]50932"}' --import-path ./kmsetsi --proto kmsetsiproto.proto  --plaintext [::1]:50901  kmsetsi.KmsETSI.ETSIAssignForwarding`
+### From middle to left
+`grpcurl -d '{"pathId" : "f6a575e5-c7f9-4765-8890-134ae5b8f451", "nextHop" : "[::1]:50930", "previousHop": "[::1]:50931"}' --import-path ./kmsetsi --proto kmsetsiproto.proto  --plaintext [::1]:50902  kmsetsi.KmsETSI.ETSIAssignForwarding`
+### From middle to right
+`grpcurl -d '{"pathId" : "f6a575e5-c7f9-4765-8890-134ae5b8f451", "nextHop" : "[::1]:50931", "previousHop": "[::1]:50930"}' --import-path ./kmsetsi --proto kmsetsiproto.proto  --plaintext [::1]:50902  kmsetsi.KmsETSI.ETSIAssignForwarding`
+
+## Send a payload for example
+### send from left
+`grpcurl -d '{"pathId" : "f6a575e5-c7f9-4765-8890-134ae5b8f451", "payload" : "a_simple_test"}' --import-path ./kmsetsi --proto kmsetsiproto.proto  --plaintext [::1]:50900  kmsetsi.KmsETSI.ETSISendPayload`
+### send from right
+`grpcurl -d '{"pathId" : "f6a575e5-c7f9-4765-8890-134ae5b8f451", "payload" : "a_simple_test"}' --import-path ./kmsetsi --proto kmsetsiproto.proto  --plaintext [::1]:50901  kmsetsi.KmsETSI.ETSISendPayload`
diff --git a/internal/docs/run.sh b/internal/docs/run.sh
new file mode 100755
index 0000000000000000000000000000000000000000..1d8c279948e159d298295bc764eb17be891ec018
--- /dev/null
+++ b/internal/docs/run.sh
@@ -0,0 +1,3 @@
+grpcurl -d '{"pathId" : "f6a575e5-c7f9-4765-8890-134ae5b8f451", "nextHop" : "", "prevHop" : "[::1]:50932"}' --import-path ../api/kmsetsi/kmsetsi --proto kmsetsiproto.proto  --plaintext [::1]:50901  kmsetsi.KmsETSI.ETSIAssignForwarding
+grpcurl -d '{"pathId" : "f6a575e5-c7f9-4765-8890-134ae5b8f451", "nextHop" : "[::1]:50931", "prevHop": "[::1]:50930"}' --import-path ../api/kmsetsi//kmsetsi --proto kmsetsiproto.proto  --plaintext [::1]:50902  kmsetsi.KmsETSI.ETSIAssignForwarding
+grpcurl -d '{"pathId" : "f6a575e5-c7f9-4765-8890-134ae5b8f451", "nextHop" : "[::1]:50932"}' --import-path ../api/kmsetsi//kmsetsi --proto kmsetsiproto.proto  --plaintext [::1]:50900  kmsetsi.KmsETSI.ETSIAssignForwarding
diff --git a/internal/kms/crypto.go b/internal/kms/crypto.go
new file mode 100644
index 0000000000000000000000000000000000000000..c4fb91cdd196f9f777cce8bbb854ebdd99a9aae8
--- /dev/null
+++ b/internal/kms/crypto.go
@@ -0,0 +1,63 @@
+package kms
+
+import (
+	"crypto/aes"
+	"crypto/cipher"
+	"crypto/rand"
+	"errors"
+	"io"
+)
+
+type CryptoAlgorithm interface {
+	Encrypt(plaintext []byte, key []byte) ([]byte, error)
+	Decrypt(ciphertext []byte, key []byte) ([]byte, error)
+}
+
+// AES.
+type AES struct {
+}
+
+func NewAES() *AES {
+	return &AES{}
+}
+
+// Implementation is from:
+// https://astaxie.gitbooks.io/build-web-application-with-golang/content/en/09.6.html
+func (a *AES) Encrypt(plaintext []byte, key []byte) ([]byte, error) {
+	c, err := aes.NewCipher(key)
+	if err != nil {
+		return nil, err
+	}
+
+	gcm, err := cipher.NewGCM(c)
+	if err != nil {
+		return nil, err
+	}
+
+	nonce := make([]byte, gcm.NonceSize())
+	if _, err = io.ReadFull(rand.Reader, nonce); err != nil {
+		return nil, err
+	}
+
+	return gcm.Seal(nonce, nonce, plaintext, nil), nil
+}
+
+func (a *AES) Decrypt(ciphertext []byte, key []byte) ([]byte, error) {
+	c, err := aes.NewCipher(key)
+	if err != nil {
+		return nil, err
+	}
+
+	gcm, err := cipher.NewGCM(c)
+	if err != nil {
+		return nil, err
+	}
+
+	nonceSize := gcm.NonceSize()
+	if len(ciphertext) < nonceSize {
+		return nil, errors.New("ciphertext is too short")
+	}
+
+	nonce, ciphertext := ciphertext[:nonceSize], ciphertext[nonceSize:]
+	return gcm.Open(nil, nonce, ciphertext, nil)
+}
diff --git a/internal/kms/grpcurl-sheet.md b/internal/kms/grpcurl-sheet.md
deleted file mode 100644
index 4aa7776be086d815e9b4b64cdc59847949ea83d5..0000000000000000000000000000000000000000
--- a/internal/kms/grpcurl-sheet.md
+++ /dev/null
@@ -1,10 +0,0 @@
-# Info for testing with grpcurl
-
-https://github.com/fullstorydev/grpcurl
-
-### 
-
-'grpcurl -d '{"myKmsName" : "grpcurl"}' --import-path ./kmsetsiproto --proto kmsetsiproto.proto  --plaintext localhost:50900  kmsetsiproto.KmsETSI.ETSICapabilities
-{  "peerKmsName": "whatever"}'
-
-'grpcurl -d '{"kmsPeerSocket" : "127.0.0.1:50901"}' --import-path ./kmsetsiproto --proto kmsetsiproto.proto  --plaintext localhost:50900  kmsetsiproto.KmsETSI.ETSIAddKMSPeer'
\ No newline at end of file
diff --git a/internal/kms/kms-keystore.go b/internal/kms/kms-keystore.go
index 8ba83293b298320482f9d5ef47e74d57f9847707..6ee0925516dcb8a9a749710f2bb1f628adb9afac 100644
--- a/internal/kms/kms-keystore.go
+++ b/internal/kms/kms-keystore.go
@@ -2,6 +2,7 @@ package kms
 
 import (
 	"errors"
+	"fmt"
 	"sync"
 
 	log "github.com/sirupsen/logrus"
@@ -9,15 +10,25 @@ import (
 	"code.fbi.h-da.de/danet/proto-kms/quantumlayer"
 )
 
+type Status int
+
+const (
+	RESERVED = iota
+	AVAILABLE
+	UNKNOWN
+	USED
+)
+
 type kmsKS interface {
-	KeyChopper256Bit(bulkKey *quantumlayer.QuantumLayerBulkKey) (err error)
+	KeyChopper(bulkKey *quantumlayer.QuantumLayerBulkKey) (err error)
 	addKey(int64, [8]byte)
 }
 
 // holds a single ready to bit key, length can be configured
 type kmsKSElement struct {
-	keyID uint64
-	key   []byte // a key
+	keyID  uint64
+	key    []byte // a key
+	status Status
 }
 
 type kmsKeyStore struct {
@@ -25,33 +36,54 @@ type kmsKeyStore struct {
 	underlyingBulkId int64
 	keyStore         map[uint64]*kmsKSElement
 	keySingleSize    uint // the size of a single key, given as unit of bits
+	indexCounter     uint64
 }
 
-func NewKmsKeyStore(desiredkeySingleSizeLength uint) kmsKeyStore {
-	return kmsKeyStore{
+func NewKmsKeyStore(desiredkeySingleSizeLength uint) *kmsKeyStore {
+	return &kmsKeyStore{
 		underlyingBulkId: 0,
 		keyStore:         make(map[uint64]*kmsKSElement),
 		keySingleSize:    desiredkeySingleSizeLength,
+		indexCounter:     0,
 	}
 }
 
 func (ks *kmsKeyStore) addKey(keyId uint64, keyToadd []byte) {
-	newKeyElement := kmsKSElement{}
-
-	//generate keyID out of bulkKeyId and has of keyToadd
-	newKeyElement.keyID = keyId
-	newKeyElement.key = keyToadd
-
 	ks.keyStoreMutex.Lock()
 	defer ks.keyStoreMutex.Unlock()
+
 	// test for collisions
-	if _, notThere := ks.keyStore[newKeyElement.keyID]; notThere {
-		log.Errorf("Whop: addKey collission of key id %s for bulkKeyID %d", newKeyElement.keyID, ks.underlyingBulkId)
+	if _, notThere := ks.keyStore[keyId]; notThere {
+		log.Errorf("Whop: addKey collission of key id %s for bulkKeyID %d", keyId, ks.underlyingBulkId)
 		return
 	}
+
+	newKeyElement := &kmsKSElement{
+		keyID:  keyId,
+		key:    keyToadd,
+		status: AVAILABLE,
+	}
 	// ok to add
-	ks.keyStore[newKeyElement.keyID] = &newKeyElement
+	ks.keyStore[newKeyElement.keyID] = newKeyElement
+}
+
+func (ks *kmsKeyStore) GetKey() (*kmsKSElement, error) {
+	ks.keyStoreMutex.Lock()
+	defer ks.keyStoreMutex.Unlock()
 
+	key, ok := ks.keyStore[ks.indexCounter]
+	if !ok {
+		return nil, fmt.Errorf("Could not find a key for id: %d", ks.indexCounter)
+	}
+	if key.status == AVAILABLE {
+		// change status of key to reserved
+		key.status = RESERVED
+		// increase index counter
+		ks.indexCounter = ks.indexCounter + 1
+
+		return key, nil
+	}
+	return nil, fmt.Errorf("Key with index: %d is already reserved.", ks.indexCounter)
 }
 
 // Takes a bulk of keys and chops them in chopFactor keys each
diff --git a/internal/kms/kms.go b/internal/kms/kms.go
index e76e079a98f1cabd90db593e6edd487bb0eae36b..2cb9be31947eea8572085597cad6b88eb6a18ba8 100644
--- a/internal/kms/kms.go
+++ b/internal/kms/kms.go
@@ -7,6 +7,7 @@ package kms
 import (
 	"crypto/rand"
 	"encoding/binary"
+	"fmt"
 	"io"
 	"sync"
 	"time"
@@ -30,6 +31,11 @@ type Qkdnkms interface {
 	FindPeerUuid(uuid.UUID) *kmsPeer
 }
 
+type Route struct {
+	Previous *kmsPeer
+	Next     *kmsPeer
+}
+
 type BitKeyLength string
 
 const (
@@ -40,12 +46,16 @@ const (
 
 // The general emulated KMS
 type EKMS struct {
-	kmsName                 string
-	kmsUUID                 uuid.UUID
-	qleMapMutex             sync.Mutex
-	QuantumElements         map[uint32]*QuantumElement
-	externalNotifierQLE     chan uint32
-	kmsPeersMutex           sync.Mutex
+	kmsName             string
+	kmsUUID             uuid.UUID
+	interComAddr        string
+	qleMapMutex         sync.Mutex
+	QuantumElements     map[uint32]*QuantumElement
+	externalNotifierQLE chan uint32
+	kmsPeersMutex       sync.Mutex
+	// TODO(maba): find a better name for this
+	keysForPathId           map[uuid.UUID]string
+	routingTable            map[uuid.UUID]*Route
 	KmsPeers                map[string]*kmsPeer
 	externalNotifierKMSPeer chan string
 	pbETSI.UnimplementedKmsETSIServer
@@ -66,12 +76,11 @@ type QuantumElement struct {
 	QuantumElementLink *quantumlayer.QuantumlayerEmuPRNG // contains information about the quantum links
 	//key stores of unchopped bulk keys go here
 	rawBulkKeysMutex sync.Mutex
-	rawBulkKeys      []*quantumlayer.QuantumLayerBulkKey
+	rawBulkKeys      map[int64]*quantumlayer.QuantumLayerBulkKey
 	keyStorePeer     *kmsKeyStore // the keys used between two peers.
 }
 
-func NewEKMS(kmsName string, kmsUUID uuid.UUID, logOutput io.Writer, logLevel log.Level, logInJson bool) (newEKMS *EKMS) {
-
+func NewEKMS(kmsName string, kmsUUID uuid.UUID, logOutput io.Writer, logLevel log.Level, logInJson bool, interComAddr string) (newEKMS *EKMS) {
 	/*
 	 * Setup logging
 	 */
@@ -92,10 +101,12 @@ func NewEKMS(kmsName string, kmsUUID uuid.UUID, logOutput io.Writer, logLevel lo
 		log.SetReportCaller(false)
 	}
 
-	createdEKMS := EKMS{
+	createdEKMS := &EKMS{
 		kmsName:                 kmsName,
 		kmsUUID:                 kmsUUID,
+		interComAddr:            interComAddr,
 		QuantumElements:         make(map[uint32]*QuantumElement),
+		routingTable:            make(map[uuid.UUID]*Route),
 		KmsPeers:                make(map[string]*kmsPeer),
 		externalNotifierQLE:     nil, // just be surely set to nil!
 		externalNotifierKMSPeer: nil, // just be surely set to nil!
@@ -104,7 +115,10 @@ func NewEKMS(kmsName string, kmsUUID uuid.UUID, logOutput io.Writer, logLevel lo
 
 	createdEKMS.supportedKeyLengths[BitKeyLen256] = true
 
-	return &createdEKMS
+	// start the inter communication gRPC server
+	go StartInterComm(interComAddr, createdEKMS)
+
+	return createdEKMS
 }
 
 func (kms *EKMS) AddQuantumElement(kmsUDPAddrr string, generateKeys bool, logOutput io.Writer, logLevel log.Level, logInJson bool) *QuantumElement {
@@ -116,6 +130,7 @@ func (kms *EKMS) AddQuantumElement(kmsUDPAddrr string, generateKeys bool, logOut
 
 	qle := QuantumElement{
 		QuantumElementLink: ql,
+		rawBulkKeys:        make(map[int64]*quantumlayer.QuantumLayerBulkKey),
 		// keyStorePeer:   not set, will be set later on, if key size is negotiated.
 	}
 
@@ -134,7 +149,6 @@ func (kms *EKMS) AddQuantumElement(kmsUDPAddrr string, generateKeys bool, logOut
 
 // TODO: Name of this function is misleading, as it only reads the bulk keys, but nothing more else
 func (kms *EKMS) GlobalKeyHandler(waitTime time.Duration) error {
-
 	// periodically walk through QuantumElements and retrieve the
 	// - key bulk buffer for each peer
 	// feed this into the corresponding key buffers of the kmss
@@ -149,7 +163,8 @@ func (kms *EKMS) GlobalKeyHandler(waitTime time.Duration) error {
 				// Add to the slice, but not process yet.
 				log.Debugf("%s produced %d bytes of key", kms.kmsName, bulkKeys.BulkKeyLength)
 				kms.QuantumElements[currentQE].rawBulkKeysMutex.Lock()
-				kms.QuantumElements[currentQE].rawBulkKeys = append(kms.QuantumElements[currentQE].rawBulkKeys, &bulkKeys)
+				//kms.QuantumElements[currentQE].rawBulkKeys = append(kms.QuantumElements[currentQE].rawBulkKeys, &bulkKeys)
+				kms.QuantumElements[currentQE].rawBulkKeys[bulkKeys.BulkKeyId] = &bulkKeys
 				kms.QuantumElements[currentQE].rawBulkKeysMutex.Unlock()
 
 				//kms.QuantumElements[currentQE].keyStorePeer.KeyChopper256Bit(&bulkKeys)
@@ -185,21 +200,24 @@ func (kms *EKMS) GenerateNewQleID() (uint32, error) {
 	}
 }
 
-// TODO/XXX error handling
-func (kms *EKMS) AddPeer(kmsPeerSocket string, servingQLE *QuantumElement) {
+func (kms *EKMS) AddPeer(kmsPeerSocket string, servingQLE *QuantumElement) (*kmsPeer, error) {
 	//check if peer exists
 	if _, there := kms.KmsPeers[kmsPeerSocket]; there {
 		log.Errorf("Trying to add existing peer %s", kmsPeerSocket)
-		return
+		return nil, fmt.Errorf("Trying to add existing peer %s", kmsPeerSocket)
+	}
+	peer, err := NewKmsPeer(servingQLE, kmsPeerSocket, kms.externalNotifierKMSPeer)
+	if err != nil {
+		return nil, err
 	}
-	peer := NewKmsPeer(servingQLE, kms.externalNotifierKMSPeer)
 	peer.tcpSocketStr = kmsPeerSocket
 
 	kms.kmsPeersMutex.Lock()
-	kms.KmsPeers[kmsPeerSocket] = &peer
+	kms.KmsPeers[kmsPeerSocket] = peer
 	kms.kmsPeersMutex.Unlock()
 
-	go peer.PeerHandler(kms.kmsName)
+	//go peer.PeerHandler(kms.kmsName)
+	return peer, nil
 }
 
 // TODO/XXX error handling
diff --git a/internal/kms/kmsetsi.go b/internal/kms/kmsetsi.go
index 297ca3e926313fbeb2e049a9e642af114c0ae48f..b51275dacba15bc2781a4a84b6637f03157c3678 100644
--- a/internal/kms/kmsetsi.go
+++ b/internal/kms/kmsetsi.go
@@ -2,13 +2,13 @@ package kms
 
 import (
 	"context"
-	"encoding/base64"
 	"errors"
 	"flag"
 	"fmt"
 	"net"
-	"os/exec"
+	"time"
 
+	"github.com/google/uuid"
 	log "github.com/sirupsen/logrus"
 
 	pb "code.fbi.h-da.de/danet/proto-kms/api/gen/proto/go/kmsetsi"
@@ -98,42 +98,97 @@ func (es *etsiServer) ETSIGetPeerList(ctx context.Context, in *pb.ETSIKMSPeerLis
 	return r, nil
 }
 
-func (es *etsiServer) ETSIGetEncryptKeys256Bit(ctx context.Context, in *pb.ETSIGetEncryptKeys256BitRequest) (*pb.ETSIGetEncryptKeys256BitReply, error) {
-	log.Printf("Received request for n=%d keys", in.GetAmount())
-
-	var randomKey *kmsKSElement
-	var err error
-	// NOTE: change change change!
-	for _, qe := range es.handlingEkms.QuantumElements {
-		quantumElementLocalKeyStore := qe.keyStorePeer
-		randomKey, err = randomItemFromMap[uint64, *kmsKSElement](quantumElementLocalKeyStore.keyStore, es.visitedKeys)
-		if err != nil {
-			return nil, status.Errorf(codes.Internal, "%v", err)
+func (es *etsiServer) ETSIAssignForwarding(ctx context.Context, in *pb.ETSIAssignForwardingRequest) (*pb.ETSIAssignForwardingReply, error) {
+	pathId, err := uuid.Parse(in.GetPathId())
+	if err != nil {
+		return nil, status.Errorf(codes.InvalidArgument, "The given path id %s is no uuid; err = ", in.GetPathId(), err)
+	}
+
+	var previousHop *kmsPeer
+	var nextHop *kmsPeer
+	var ok bool
+	if in.GetPrevHop() != "" {
+		previousHop, ok = es.handlingEkms.KmsPeers[in.GetPrevHop()]
+		if !ok {
+			return nil, status.Errorf(codes.InvalidArgument, "No peer for %s", in.GetPrevHop())
+		}
+	}
+	if in.GetNextHop() != "" {
+		nextHop, ok = es.handlingEkms.KmsPeers[in.GetNextHop()]
+		if !ok {
+			return nil, status.Errorf(codes.InvalidArgument, "No peer for %s", in.GetNextHop())
 		}
-		es.visitedKeys[randomKey] = true
 	}
 
-	// TODO: Remove/move ssh-kind prototype code below
-	keyAsString := base64.StdEncoding.EncodeToString(randomKey.key)
-	// push the key to the encryptor via ssh
-	ssh := "ssh"
-	complexArg := fmt.Sprintf("(rc=$(sed \"12 c PresharedKey = %s\" /etc/wireguard/wg0.conf); echo \"$rc\" > /etc/wireguard/wg0.conf)", keyAsString)
-	args := []string{"root@172.20.0.5", "-oStrictHostKeyChecking=no", complexArg}
+	// set the route within routing table
+	es.handlingEkms.routingTable[pathId] = &Route{
+		Previous: previousHop,
+		Next:     nextHop,
+	}
+
+	log.Info("ROUTINGTABLE: ", es.handlingEkms.routingTable)
 
-	cmd := exec.Command(ssh, args...)
-	err = cmd.Run()
+	return &pb.ETSIAssignForwardingReply{
+		Timestamp: time.Now().Unix(),
+	}, nil
+}
+
+func (es *etsiServer) ETSISendPayload(ctx context.Context, in *pb.ETSISendPayloadRequest) (*pb.ETSISendPayloadResponse, error) {
+	pathId, err := uuid.Parse(in.GetPathId())
 	if err != nil {
-		log.Errorf("could not execute ssh command with parameters")
-		return nil, status.Errorf(codes.Internal, "%v", err)
+		return nil, status.Errorf(codes.InvalidArgument, "The given path id %s is no uuid; err = ", in.GetPathId(), err)
+	}
+
+	route, ok := es.handlingEkms.routingTable[pathId]
+	if !ok {
+		return nil, status.Errorf(codes.Internal, "No route found for path id: %s", in.GetPathId())
 	}
 
-	// Construct any response
-	return &pb.ETSIGetEncryptKeys256BitReply{
-		KeyID: randomKey.keyID,
-		Key:   randomKey.key,
+	if err := route.Next.SendPayload([]byte(in.GetPayload()), pathId); err != nil {
+		return nil, status.Errorf(codes.Internal, "Failed to send payload: ", err)
+	}
+
+	return &pb.ETSISendPayloadResponse{
+		Timestamp: time.Now().Unix(),
 	}, nil
 }
 
+//func (es *etsiServer) ETSIGetEncryptKeys256Bit(ctx context.Context, in *pb.ETSIGetEncryptKeys256BitRequest) (*pb.ETSIGetEncryptKeys256BitReply, error) {
+//	log.Printf("Received request for n=%d keys", in.GetAmount())
+//
+//	var randomKey *kmsKSElement
+//	var err error
+//	// NOTE: change change change!
+//	for _, qe := range es.handlingEkms.QuantumElements {
+//		quantumElementLocalKeyStore := qe.keyStorePeer
+//		randomKey, err = randomItemFromMap[uint64, *kmsKSElement](quantumElementLocalKeyStore.keyStore, es.visitedKeys)
+//		if err != nil {
+//			return nil, status.Errorf(codes.Internal, "%v", err)
+//		}
+//		es.visitedKeys[randomKey] = true
+//	}
+//
+//	// TODO: Remove/move ssh-kind prototype code below
+//	keyAsString := base64.StdEncoding.EncodeToString(randomKey.key)
+//	// push the key to the encryptor via ssh
+//	ssh := "ssh"
+//	complexArg := fmt.Sprintf("(rc=$(sed \"12 c PresharedKey = %s\" /etc/wireguard/wg0.conf); echo \"$rc\" > /etc/wireguard/wg0.conf)", keyAsString)
+//	args := []string{"root@172.20.0.5", "-oStrictHostKeyChecking=no", complexArg}
+//
+//	cmd := exec.Command(ssh, args...)
+//	err = cmd.Run()
+//	if err != nil {
+//		log.Errorf("could not execute ssh command with parameters")
+//		return nil, status.Errorf(codes.Internal, "%v", err)
+//	}
+//
+//	// Construct any response
+//	return &pb.ETSIGetEncryptKeys256BitReply{
+//		KeyID: randomKey.keyID,
+//		Key:   randomKey.key,
+//	}, nil
+//}
+
 func StartETSI(listenAddr string, callingKMS *EKMS) {
 	flag.Parse()
 
diff --git a/internal/kms/kmsintercom.go b/internal/kms/kmsintercom.go
index 4a6843833864fda5374d2cf73ebe6308168f4747..42695d31eee913fc1b998252168966db551dc232 100644
--- a/internal/kms/kmsintercom.go
+++ b/internal/kms/kmsintercom.go
@@ -2,18 +2,27 @@ package kms
 
 import (
 	"context"
+	"encoding/base64"
 	"flag"
 	"fmt"
 	"net"
+	"time"
 
+	"github.com/google/uuid"
 	log "github.com/sirupsen/logrus"
 
 	pb "code.fbi.h-da.de/danet/proto-kms/api/gen/proto/go/kmsintercom"
 	"google.golang.org/grpc"
+	"google.golang.org/grpc/codes"
+	"google.golang.org/grpc/health"
+	healthpb "google.golang.org/grpc/health/grpc_health_v1"
+	"google.golang.org/grpc/status"
 )
 
 type kmsTalkerServer struct {
 	pb.UnimplementedKmsTalkerServer
+	keyNegotiationMap map[uuid.UUID]*kmsKSElement
+	eKMS              *EKMS
 }
 
 // This must somehow find out and agree to a specific key lenght
@@ -23,30 +32,136 @@ func (s *kmsTalkerServer) InterComCapabilities(ctx context.Context, in *pb.Inter
 	// TODO: Call to ksp := NewKmsKeyStore(<desired-size-of-each-key-in-bits)
 	// this to be stored in the serving QLE QuantumElement struct under keyStorePeer
 	// Further, the KMS peers have to agree on a ready-to-be-used keyBulk based on the bulkId
-	// This requires to go through the rawBulkKeys of type QuantumElement and lookup a bulkId both side do know
-	// Once agreed upon on keyBulk, this here has to call KeyChopper of the actual NewKmsKeyStore
+	// This requires to go through the rawBulkKeys of type QuantumElement and lookup a bulkId both side do know Once agreed upon on keyBulk, this here has to call KeyChopper of the actual NewKmsKeyStore
 
 	return &pb.InterComCapabilitiesReply{
 		PeerKmsName: "whatever",
 	}, nil
 }
 
-func (s *kmsTalkerServer) InterComKeyTransportSessionHandling(ctx context.Context, in *pb.InterComKeyTransportSessionHandlingRequest) (*pb.InterComKeyTransportSessionHandlingReply, error) {
+func (s *kmsTalkerServer) SyncQkdBulk(ctx context.Context, in *pb.SyncQkdBulkRequest) (*pb.SyncQkdBulkResponse, error) {
+	// check if a peer exists
+	peer, ok := s.eKMS.KmsPeers[in.GetInterComAddr()]
+	if !ok {
+		//TODO: proper error message
+		return nil, status.Errorf(codes.Internal, "peer does not exist")
+	}
 
-	return &pb.InterComKeyTransportSessionHandlingReply{
-		UsedKey: "whatever",
-	}, nil
+	for _, bulkId := range in.BulkId {
+		rawBulkKeyIds := keysOfMap[int64](peer.servingQLE.rawBulkKeys)
+		log.Info("PEER BULK KEYS: ", rawBulkKeyIds)
+		if bulk, ok := peer.servingQLE.rawBulkKeys[bulkId]; ok {
+			peer.servingQLE.keyStorePeer = NewKmsKeyStore(256)
+			if err := peer.servingQLE.keyStorePeer.KeyChopper(bulk); err != nil {
+				//TODO: proper error message
+				return nil, status.Errorf(codes.Internal, "chopping failed")
+			}
+
+			return &pb.SyncQkdBulkResponse{
+				Timestamp: time.Now().Unix(),
+				BulkId:    bulkId,
+			}, nil
+		}
+	}
+
+	return nil, status.Errorf(codes.Unimplemented, "method SyncQkdBulk not implemented")
+}
+
+func (s *kmsTalkerServer) InterComTransportKeyNegotiation(ctx context.Context, in *pb.InterComTransportKeyNegotiationRequest) (capReply *pb.InterComTransportKeyNegotiationResponse, err error) {
+	// NOTE: For the current prototype it is assumed that a negotiation request
+	// is always valid. In the future an incoming negotiation request should
+	// also check for a suitable forwarding assignment from the controller.
+	keyID := in.KeyToUse
+	pathId, err := uuid.Parse(in.PathID)
+	if err != nil {
+		return nil, status.Errorf(codes.InvalidArgument, "")
+	}
+
+	route, ok := s.eKMS.routingTable[pathId]
+	if !ok {
+		return nil, status.Errorf(codes.Internal, "There is no route for the given pathID: %s .", in.PathID)
+	}
+
+	//TODO: This limits a pathId so that it is only possible to send one single
+	//payload.
+	//if _, ok := s.keyNegotiationMap[pathId]; ok {
+	//	return nil, status.Errorf(codes.Internal, "A transport key for pathID: %s has already been negotiated.", in.PathID)
+	//}
+
+	quantumElementRemoteKeyStore := route.Previous.servingQLE.keyStorePeer
+
+	key, ok := quantumElementRemoteKeyStore.keyStore[keyID]
+	if !ok {
+		return nil, status.Errorf(codes.Internal, "Key with ID: %s could not be found.", keyID)
+	}
+
+	s.keyNegotiationMap[pathId] = key
+
+	return &pb.InterComTransportKeyNegotiationResponse{Timestamp: time.Now().Unix()}, nil
+}
+
+func (s *kmsTalkerServer) KeyForwarding(ctx context.Context, in *pb.KeyForwardingRequest) (capReply *pb.KeyForwardingResponse, err error) {
+	pathId, err := uuid.Parse(in.PathId)
+	if err != nil {
+		return nil, status.Errorf(codes.InvalidArgument, "")
+	}
+
+	decryptKey, ok := s.keyNegotiationMap[pathId]
+	if !ok {
+		return nil, status.Errorf(codes.InvalidArgument, "")
+	}
+
+	route, ok := s.eKMS.routingTable[pathId]
+	if !ok {
+		return nil, status.Errorf(codes.Internal, "There is no route for the given pathID: %s .", in.PathId)
+	}
+
+	payloadAsByte, err := base64.StdEncoding.DecodeString(in.Payload)
+	if err != nil {
+		return nil, status.Errorf(codes.Internal, "%s", err)
+	}
+
+	decryptedPayload, err := route.Previous.et.Decrypt(payloadAsByte, decryptKey.key)
+	if err != nil {
+		return nil, status.Errorf(codes.Internal, "%s", err)
+	}
+
+	log.Infof("The eKMS: %s received the Payload: %s", s.eKMS.kmsName, decryptedPayload)
+
+	if route.Next != nil {
+		log.Info("SEEEENDING: ", s.eKMS.kmsName)
+		go route.Next.SendPayload(decryptedPayload, pathId)
+	} else {
+		fmt.Println("THE DECRYPTED PAYLOAD: ", string(decryptedPayload))
+	}
+
+	return &pb.KeyForwardingResponse{Timestamp: time.Now().Unix()}, nil
 }
 
-func StartInterComm(interComPort int) {
+func StartInterComm(addr string, eKMS *EKMS) {
 	flag.Parse()
 
-	lis, err := net.Listen("tcp", fmt.Sprintf(":%d", interComPort))
+	lis, err := net.Listen("tcp", addr)
 	if err != nil {
 		log.Fatalf("failed to listen: %v", err)
 	}
 	s := grpc.NewServer()
-	pb.RegisterKmsTalkerServer(s, &kmsTalkerServer{})
+	healthCheck := health.NewServer()
+
+	healthpb.RegisterHealthServer(s, healthCheck)
+	pb.RegisterKmsTalkerServer(s, &kmsTalkerServer{
+		keyNegotiationMap: make(map[uuid.UUID]*kmsKSElement),
+		eKMS:              eKMS,
+	})
+
+	go func() {
+		// set status to serving
+		healthCheck.SetServingStatus(pb.KmsTalker_ServiceDesc.ServiceName, healthpb.HealthCheckResponse_SERVING)
+		// TODO: add logic for adjusting health status based on operating status of
+		// the services
+		//    for{}
+	}()
+
 	log.Infof("server listening at %v", lis.Addr())
 	if err := s.Serve(lis); err != nil {
 		log.Fatalf("failed to serve: %v", err)
diff --git a/internal/kms/kmspeers.go b/internal/kms/kmspeers.go
index da559860cde9049c792ec32b6da7dcbb906f0878..24288321884b7e0029660dc233e6de40654fcaeb 100644
--- a/internal/kms/kmspeers.go
+++ b/internal/kms/kmspeers.go
@@ -5,13 +5,12 @@ import (
 	"encoding/base64"
 	"fmt"
 	"net"
-	"os/exec"
 	"time"
 
-	log "github.com/sirupsen/logrus"
-
-	pb "code.fbi.h-da.de/danet/proto-kms/api/gen/proto/go/kmsetsi"
+	pbIC "code.fbi.h-da.de/danet/proto-kms/api/gen/proto/go/kmsintercom"
 	"github.com/google/uuid"
+	"github.com/sirupsen/logrus"
+	log "github.com/sirupsen/logrus"
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/credentials/insecure"
 )
@@ -34,133 +33,230 @@ type kmsPeerInfo interface {
 
 type kmsPeer struct {
 	externalNotifierKMSPeer chan string
+	peerClient              pbIC.KmsTalkerClient
 	peerStatus              KmsPeerStatus
 	servingQLE              *QuantumElement
 	tcpSocket               net.TCPAddr // the IP address and TCP port (aka socket) of the kms peer
 	tcpSocketStr            string      // string rep. of tcpSocket
-	name                    string      // the name of the kms peer
-	id                      uuid.UUID   // uuid of the peer
-	quit                    chan bool   // cancel the peer goroutine
+	et                      CryptoAlgorithm
+	name                    string    // the name of the kms peer
+	id                      uuid.UUID // uuid of the peer
+	quit                    chan bool // cancel the peer goroutine
 }
 
-func NewKmsPeer(servQLE *QuantumElement, in chan string) (peer kmsPeer) {
-	return kmsPeer{
+func NewKmsPeer(servQLE *QuantumElement, tcpSocketStr string, in chan string) (peer *kmsPeer, err error) {
+	newPeerConn, err := grpc.Dial(tcpSocketStr, grpc.WithTransportCredentials(insecure.NewCredentials()))
+	if err != nil {
+		return nil, err
+	}
+	peerClient := pbIC.NewKmsTalkerClient(newPeerConn)
+
+	return &kmsPeer{
+		externalNotifierKMSPeer: in,
+		peerClient:              peerClient,
 		peerStatus:              KmsPeerUnknown,
 		servingQLE:              servQLE,
+		tcpSocketStr:            tcpSocketStr,
+		et:                      NewAES(),
 		id:                      uuid.New(),
-		externalNotifierKMSPeer: in,
 		quit:                    make(chan bool),
-	}
+	}, nil
 }
 
 // Handles everything with respect to a specific KMS peer
-func (ph *kmsPeer) PeerHandler(kmsName string) {
-	log.Infof("%s started PeerHandler for %s:", kmsName, ph.tcpSocketStr)
+//func (ph *kmsPeer) PeerHandler(kmsName string) {
+//	//	log.Infof("%s started PeerHandler for %s:", kmsName, ph.tcpSocketStr)
+//
+//	// contact peer
+//	newPeerConn, err := grpc.Dial(ph.tcpSocketStr, grpc.WithTransportCredentials(insecure.NewCredentials()))
+//	if err != nil {
+//		log.Errorf("%s: did not connect: %v", kmsName, err)
+//		ph.peerStatus = KmsPeerDown
+//		return
+//	}
+//	defer newPeerConn.Close()
+//
+//	c := pb.NewKmsETSIClient(newPeerConn)
+//
+//	// Contact the server and print out its response.
+//	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
+//	defer cancel()
+//	r, err := c.ETSICapabilities(ctx, &pb.ETSICapabilitiesRequest{MyKmsName: kmsName})
+//	if err != nil {
+//		log.Errorf("%s: could not greet: %v", kmsName, err)
+//		ph.peerStatus = KmsPeerDown
+//		// Send notification about change
+//		if ph.externalNotifierKMSPeer != nil {
+//			ph.externalNotifierKMSPeer <- ph.tcpSocketStr
+//		}
+//	}
+// // NOTE: If a session is created, we also request a encryption key for now
+//	//quantumElementRequest, err := c.ETSIGetQuantumInterfaces(ctx, &pb.ETSIKMSQuantumInterfaceListRequest{})
+//	//if err != nil {
+//	//	log.Println("Could not request quantum elements: ", err)
+//	//	ph.peerStatus = KmsPeerDown
+//	//	// Send notification about change
+//	//	if ph.externalNotifierKMSPeer != nil {
+//	//		ph.externalNotifierKMSPeer <- ph.tcpSocketStr
+//	//	}
+//	//	return
+//	//}
+//
+//	//if quantumElementRequest.QlElementInfo != nil {
+//	//	peerQuantumElement := quantumElementRequest.QlElementInfo[0].QleID
+//	//} else {
+//	//	// return error?!
+//	//}
+//
+//	// Works and peer moves to kmsPeerUp
+//	ph.peerStatus = KmsPeerUp
+//
+//	encryptKeyRequest, err := c.ETSIGetEncryptKeys256Bit(ctx, &pb.ETSIGetEncryptKeys256BitRequest{Amount: 1})
+//	if err != nil {
+//		log.Errorf("%s: could not request a encryption key: %s", kmsName, err)
+//		ph.peerStatus = KmsPeerDown
+//		// Send notification about change
+//		if ph.externalNotifierKMSPeer != nil {
+//			ph.externalNotifierKMSPeer <- ph.tcpSocketStr
+//		}
+//		return
+//	}
+//
+//	// check if key is in KeyStore
+//	if key, ok := ph.servingQLE.keyStorePeer.keyStore[encryptKeyRequest.KeyID]; ok {
+//		keyAsString := base64.StdEncoding.EncodeToString(key.key)
+//		log.Debugf("Agreed Key: %s", keyAsString)
+//
+//		// TODO: Remove/move ssh-kind prototype code below
+//		// push the key to the encryptor via ssh
+//		ssh := "ssh"
+//		complexArg := fmt.Sprintf("(rc=$(sed \"12 c PresharedKey = %s\" /etc/wireguard/wg0.conf); echo \"$rc\" > /etc/wireguard/wg0.conf)", keyAsString)
+//		args := []string{"root@172.20.0.4", "-oStrictHostKeyChecking=no", complexArg}
+//
+//		cmd := exec.Command(ssh, args...)
+//		err := cmd.Run()
+//		if err != nil {
+//			log.Errorf("%s: could not execute ssh command with parameters", kmsName)
+//			return
+//		}
+//	}
+//
+//	// Send notification about change
+//	if ph.externalNotifierKMSPeer != nil {
+//		ph.externalNotifierKMSPeer <- ph.tcpSocketStr
+//	}
+//
+//	log.Printf("Greeting: %s which is now in peerStatus %d", r.GetPeerKmsName(), ph.peerStatus)
+//
+//	// NOTE: should be possible to cancel!
+//	// By now, do check only the liveliness of the peer, nothing else.
+//	//for {
+//	//	select {
+//	//	case <-ph.quit:
+//	//		return
+//	//	default:
+//	//		// Contact the server and print out its response.
+//	//		ctx, cancel := context.WithTimeout(context.Background(), time.Second)
+//	//		defer cancel()
+//	//		_, err := c.ETSICapabilities(ctx, &pb.ETSICapabilitiesRequest{MyKmsName: kmsName})
+//	//		if err != nil {
+//	//			log.Printf("could not greet: %v", err)
+//	//			ph.peerStatus = KmsPeerDown
+//	//			// Send notification about change
+//	//			if ph.externalNotifierKMSPeer != nil {
+//	//				ph.externalNotifierKMSPeer <- ph.tcpSocketStr
+//	//			}
+//	//		}
+//	//		time.Sleep(30 * time.Second)
+//	//	}
+//	//}
+//}
 
-	// contact peer
-	newPeerConn, err := grpc.Dial(ph.tcpSocketStr, grpc.WithTransportCredentials(insecure.NewCredentials()))
+func (ph *kmsPeer) SyncBulkKeys(interComAddr string) error {
+	rawBulkKeyIds := keysOfMap[int64](ph.servingQLE.rawBulkKeys)
+	logrus.Info("FOUND BULKS: ", rawBulkKeyIds)
+
+	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
+	defer cancel()
+	initialPeerSetupResponse, err := ph.peerClient.SyncQkdBulk(ctx, &pbIC.SyncQkdBulkRequest{
+		Timestamp:    time.Now().Unix(),
+		InterComAddr: interComAddr,
+		BulkId:       rawBulkKeyIds,
+	})
 	if err != nil {
-		log.Errorf("%s: did not connect: %v", kmsName, err)
-		ph.peerStatus = KmsPeerDown
-		return
+		return err
+	}
+
+	bulkKey, ok := ph.servingQLE.rawBulkKeys[initialPeerSetupResponse.BulkId]
+	if !ok {
+		// TODO: add proper error message
+		return fmt.Errorf("")
 	}
-	defer newPeerConn.Close()
 
-	c := pb.NewKmsETSIClient(newPeerConn)
+	// TODO: Initially the peer partners should discuss about the key length,
+	// for now it is hardcoded.
+	ph.servingQLE.keyStorePeer = NewKmsKeyStore(256)
 
-	// Contact the server and print out its response.
+	if err := ph.servingQLE.keyStorePeer.KeyChopper(bulkKey); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// TransportKeyNegotiation sends a request for a transport key negotiation to
+// the peer KMS. The key that was agreed upon, is used to create a encrypted
+// payload.
+func (ph *kmsPeer) TransportKeyNegotiation() error {
+	//ctx, cancel := context.WithTimeout(context.Background(), time.Second)
+	//req, err := ph.peerClient.InterComTransportKeyNegotiation()
+	return nil
+}
+
+func (ph *kmsPeer) SendPayload(payload []byte, pathId uuid.UUID) error {
+	// select a key from key store
+	key, err := ph.servingQLE.keyStorePeer.GetKey()
+	if err != nil {
+		return err
+	}
+
+	// Start the negotiation process for a transport key
 	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
 	defer cancel()
-	r, err := c.ETSICapabilities(ctx, &pb.ETSICapabilitiesRequest{MyKmsName: kmsName})
+	_, err = ph.peerClient.InterComTransportKeyNegotiation(ctx, &pbIC.InterComTransportKeyNegotiationRequest{
+		Timestamp: time.Now().Unix(),
+		PathID:    pathId.String(),
+		KeyToUse:  key.keyID,
+	})
 	if err != nil {
-		log.Errorf("%s: could not greet: %v", kmsName, err)
-		ph.peerStatus = KmsPeerDown
-		// Send notification about change
-		if ph.externalNotifierKMSPeer != nil {
-			ph.externalNotifierKMSPeer <- ph.tcpSocketStr
-		}
+		return err
 	}
+	// TODO: delete key?
+
+	// TODO: would be better to update the index counter here (to keep it
+	// synchronized).
 
-	// NOTE: If a session is created, we also request a encryption key for now
-	//quantumElementRequest, err := c.ETSIGetQuantumInterfaces(ctx, &pb.ETSIKMSQuantumInterfaceListRequest{})
-	//if err != nil {
-	//	log.Println("Could not request quantum elements: ", err)
-	//	ph.peerStatus = KmsPeerDown
-	//	// Send notification about change
-	//	if ph.externalNotifierKMSPeer != nil {
-	//		ph.externalNotifierKMSPeer <- ph.tcpSocketStr
-	//	}
-	//	return
-	//}
-
-	//if quantumElementRequest.QlElementInfo != nil {
-	//	peerQuantumElement := quantumElementRequest.QlElementInfo[0].QleID
-	//} else {
-	//	// return error?!
-	//}
-
-	// Works and peer moves to kmsPeerUp
-	ph.peerStatus = KmsPeerUp
-
-	encryptKeyRequest, err := c.ETSIGetEncryptKeys256Bit(ctx, &pb.ETSIGetEncryptKeys256BitRequest{Amount: 1})
+	encryptedPayload, err := ph.et.Encrypt(payload, key.key)
 	if err != nil {
-		log.Errorf("%s: could not request a encryption key: %s", kmsName, err)
-		ph.peerStatus = KmsPeerDown
-		// Send notification about change
-		if ph.externalNotifierKMSPeer != nil {
-			ph.externalNotifierKMSPeer <- ph.tcpSocketStr
-		}
-		return
+		return err
 	}
 
-	// check if key is in KeyStore
-	if key, ok := ph.servingQLE.keyStorePeer.keyStore[encryptKeyRequest.KeyID]; ok {
-		keyAsString := base64.StdEncoding.EncodeToString(key.key)
-		log.Debugf("Agreed Key: %s", keyAsString)
-
-		// TODO: Remove/move ssh-kind prototype code below
-		// push the key to the encryptor via ssh
-		ssh := "ssh"
-		complexArg := fmt.Sprintf("(rc=$(sed \"12 c PresharedKey = %s\" /etc/wireguard/wg0.conf); echo \"$rc\" > /etc/wireguard/wg0.conf)", keyAsString)
-		args := []string{"root@172.20.0.4", "-oStrictHostKeyChecking=no", complexArg}
-
-		cmd := exec.Command(ssh, args...)
-		err := cmd.Run()
-		if err != nil {
-			log.Errorf("%s: could not execute ssh command with parameters", kmsName)
-			return
-		}
-	}
+	encryptedPayloadAsString := base64.StdEncoding.EncodeToString(encryptedPayload)
+
+	log.Infof("Sent encrypted Payload: %s", encryptedPayloadAsString)
 
-	// Send notification about change
-	if ph.externalNotifierKMSPeer != nil {
-		ph.externalNotifierKMSPeer <- ph.tcpSocketStr
+	ctx2, cancel2 := context.WithTimeout(context.Background(), time.Second)
+	defer cancel2()
+	_, err = ph.peerClient.KeyForwarding(ctx2, &pbIC.KeyForwardingRequest{
+		Timestamp: time.Now().Unix(),
+		PathId:    pathId.String(),
+		Payload:   encryptedPayloadAsString,
+	})
+	if err != nil {
+		return err
 	}
 
-	log.Printf("Greeting: %s which is now in peerStatus %d", r.GetPeerKmsName(), ph.peerStatus)
-
-	// NOTE: should be possible to cancel!
-	// By now, do check only the liveliness of the peer, nothing else.
-	//for {
-	//	select {
-	//	case <-ph.quit:
-	//		return
-	//	default:
-	//		// Contact the server and print out its response.
-	//		ctx, cancel := context.WithTimeout(context.Background(), time.Second)
-	//		defer cancel()
-	//		_, err := c.ETSICapabilities(ctx, &pb.ETSICapabilitiesRequest{MyKmsName: kmsName})
-	//		if err != nil {
-	//			log.Printf("could not greet: %v", err)
-	//			ph.peerStatus = KmsPeerDown
-	//			// Send notification about change
-	//			if ph.externalNotifierKMSPeer != nil {
-	//				ph.externalNotifierKMSPeer <- ph.tcpSocketStr
-	//			}
-	//		}
-	//		time.Sleep(30 * time.Second)
-	//	}
-	//}
+	return nil
 }
 
 func (ph *kmsPeer) GetKmsPeerStatus() KmsPeerStatus {
diff --git a/internal/kms/util.go b/internal/kms/util.go
index b9b5c35056b54c27409fb6a35aa35ad51f58560e..2fed2dd510b61e370401c79d0483a81893d67995 100644
--- a/internal/kms/util.go
+++ b/internal/kms/util.go
@@ -2,15 +2,33 @@ package kms
 
 import "fmt"
 
-// Ewww... don't
-func randomItemFromMap[T, M comparable](m map[T]M, v map[M]bool) (M, error) {
+func randomItemFromMap[T comparable, M any](m map[T]M) (M, error) {
 	for _, item := range m {
-		if v[item] {
-			continue
-		}
 		return item, nil
 	}
 
 	var r M
 	return r, fmt.Errorf("Could not return a random item from map %v", m)
 }
+
+func randomItemFromMapAndRemove[T comparable, M any](m map[T]M) (M, error) {
+	for key, item := range m {
+		delete(m, key)
+		return item, nil
+	}
+
+	var r M
+	return r, fmt.Errorf("Could not return a random item from map %v and delete it.", m)
+}
+
+func keysOfMap[T comparable, M any](m map[T]M) []T {
+	keys := make([]T, len(m))
+
+	i := 0
+	for k := range m {
+		keys[i] = k
+		i++
+	}
+
+	return keys
+}
diff --git a/internal/main_test.go b/internal/main_test.go
index af1d98a32779e6426c4ef9761616f107383a4fb5..0c42d3bdb99917c32a5dbd2f0bffeebc9d373d78 100644
--- a/internal/main_test.go
+++ b/internal/main_test.go
@@ -16,8 +16,6 @@ import (
 	"github.com/google/uuid"
 )
 
-//func main() {
-
 func TestMain(m *testing.M) {
 	// run a self-test if set to yes
 	var selfTesting bool
@@ -53,20 +51,21 @@ func TestMain(m *testing.M) {
 
 	if selfTesting == true {
 		log.Infof("%s in self-testing mode", ql1Name)
-		go emulatedKMS(ql2Name, udpQL2AddrString, udpQL1AddrString, true)
-		emulatedKMS(ql1Name, udpQL1AddrString, udpQL2AddrString, false)
+		go emulatedKMS("leftKMS", "[::1]:50900", "[::1]:50930", "[::1]:50910", "[::1]:50932")
+		go emulatedKMS("rightKMS", "[::1]:50901", "[::1]:50931", "[::1]:50911", "[::1]:50932")
+		middleKMS("middleKMS", "[::1]:50902", "[::1]:50932", "[::1]:50900", "[::1]:50930", "[::1]:50901", "[::1]:50931")
 	} else {
-		log.Infof("%s in regular mode of operation", ql1Name)
-		emulatedKMS(ql1Name, udpQL1AddrString, udpQL2AddrString, false)
+		//	log.Infof("%s in regular mode of operation", ql1Name)
+		//	emulatedKMS(ql1Name, udpQL1AddrString, udpQL2AddrString)
 	}
 }
 
-func emulatedKMS(myName string, myUDPAddr string, peerUDPAddr string, generatedKeys bool) {
+func emulatedKMS(myName, myUDPAddr, myInterComAddr, peerUDPAddr, peerInterComAddr string) {
 	// Attach to eKMS
-	emuKMS := kms.NewEKMS(myName, uuid.New(), os.Stdout, log.TraceLevel, false)
+	emuKMS := kms.NewEKMS(myName, uuid.New(), os.Stdout, log.TraceLevel, false, myInterComAddr)
 
 	// Fire up Quantum LinK
-	myQL := emuKMS.AddQuantumElement(myUDPAddr, generatedKeys, os.Stdout, log.TraceLevel, false)
+	myQL := emuKMS.AddQuantumElement(myUDPAddr, false, os.Stdout, log.TraceLevel, false)
 
 	udpQL2Addr, err := net.ResolveUDPAddr("udp", peerUDPAddr)
 	if err != nil {
@@ -76,9 +75,65 @@ func emulatedKMS(myName string, myUDPAddr string, peerUDPAddr string, generatedK
 
 	myQL.QuantumElementLink.AddPeer(udpQL2Addr)
 
+	_, err = emuKMS.AddPeer(peerInterComAddr, myQL)
+	if err != nil {
+		log.Println("PEERERROR: ", err)
+	}
+
 	// Start the SDN/management and key retrieval interface
-	go kms.StartETSI(peerUDPAddr, emuKMS)
+	go kms.StartETSI(myUDPAddr, emuKMS)
 
 	// TODO/XXX catch errors!
 	emuKMS.GlobalKeyHandler(7 * time.Second)
 }
+
+func middleKMS(myName, myUDPAddr, myInterComAddr, leftUDPAddr, leftInterComAddr, rightUDPAddr, rightInterComAddr string) {
+	// Attach to eKMS
+	emuKMS := kms.NewEKMS(myName, uuid.New(), os.Stdout, log.TraceLevel, false, myInterComAddr)
+
+	// create two quantum modules that generate keys
+	qlForLeft := emuKMS.AddQuantumElement("[::1]:50910", true, os.Stdout, log.TraceLevel, false)
+	qlForRight := emuKMS.AddQuantumElement("[::1]:50911", true, os.Stdout, log.TraceLevel, false)
+
+	netLeftUDPAddr, err := net.ResolveUDPAddr("udp", leftUDPAddr)
+	if err != nil {
+		log.Fatalf("%s: QuantumlayerEmuPRNG UDP failure: %s", myName, err)
+		return
+	}
+
+	netRightUDPAddr, err := net.ResolveUDPAddr("udp", rightUDPAddr)
+	if err != nil {
+		log.Fatalf("%s: QuantumlayerEmuPRNG UDP failure: %s", myName, err)
+		return
+	}
+
+	qlForLeft.QuantumElementLink.AddPeer(netLeftUDPAddr)
+	qlForRight.QuantumElementLink.AddPeer(netRightUDPAddr)
+
+	peerLeft, err := emuKMS.AddPeer(leftInterComAddr, qlForLeft)
+	if err != nil {
+		log.Println(err)
+	}
+
+	peerRight, err := emuKMS.AddPeer(rightInterComAddr, qlForRight)
+	if err != nil {
+		log.Println(err)
+	}
+
+	// Start the SDN/management and key retrieval interface
+	go kms.StartETSI(myUDPAddr, emuKMS)
+
+	// TODO/XXX catch errors!
+	go emuKMS.GlobalKeyHandler(7 * time.Second)
+
+	time.Sleep(time.Second * 15)
+	if err := peerLeft.SyncBulkKeys(myInterComAddr); err != nil {
+		log.Println("SYNC ERROR: ", err)
+	}
+	if err := peerRight.SyncBulkKeys(myInterComAddr); err != nil {
+		log.Println("SYNC ERROR: ", err)
+	}
+
+	for {
+	}
+}
diff --git a/internal/quantumlayer/quantumlayer-emu-prng.go b/internal/quantumlayer/quantumlayer-emu-prng.go
index 50ca518ca167f4eeba93f9b8dd1c3949f2f6035d..b2a2013b144d2adcdc94aee94dfcfed3d3d84a3d 100644
--- a/internal/quantumlayer/quantumlayer-emu-prng.go
+++ b/internal/quantumlayer/quantumlayer-emu-prng.go
@@ -272,8 +272,11 @@ func (qlemuprng *QuantumlayerEmuPRNG) GetKeyBulkPeer() (QuantumLayerBulkKey, err
 	return qlemuprng.peerNumbers.GetBulk()
 }
 
-func (qlemuprng *QuantumlayerEmuPRNG) GetStatus() (poweredOn bool) {
-	return qlemuprng.poweron
+// GetStatus returns the current status of the QuantumLayerEmuPRNG. This
+// includes the information if the QLE is powered, aswell as if the QLE is
+// enabled for key generation.
+func (qlemuprng *QuantumlayerEmuPRNG) GetStatus() (poweredOn, enabled bool) {
+	return qlemuprng.poweron, qlemuprng.generateKeys
 }
 
 type NumberStore struct {
diff --git a/internal/quantumlayer/quantumlayer.go b/internal/quantumlayer/quantumlayer.go
index feaf7994227b38dee09f5aacd77cf5246ce46f30..3399b6b956d942e4a71592819dad4a0f1b91af4b 100644
--- a/internal/quantumlayer/quantumlayer.go
+++ b/internal/quantumlayer/quantumlayer.go
@@ -5,9 +5,11 @@
 package quantumlayer
 
 type QuantumLayerBulkKey struct {
-	BulkKeyId     int64   // the unique ID of this bulk of keys
-	BulkKeyLength int     // the length, counted in bytes, of bulkKey
-	BulkKey       *[]byte // the bulk key
+	BulkKeyId     int64 // the unique ID of this bulk of keys
+	BulkKeyLength int   // the length, counted in bytes, of bulkKey
+	// TODO: Pointer of slice should have a well thought reason;
+	// ask Martin if this is really necessary here
+	BulkKey *[]byte // the bulk key
 }
 
 type QuantumLayer interface {