diff --git a/internal/kms/kms-keystore.go b/internal/kms/kms-keystore.go
new file mode 100644
index 0000000000000000000000000000000000000000..56d3f74b324bc40146f3a5af94a393f9ab53e451
--- /dev/null
+++ b/internal/kms/kms-keystore.go
@@ -0,0 +1,69 @@
+package kms
+
+import (
+	"crypto/sha256"
+	"errors"
+	"fmt"
+	"log"
+	"sync"
+
+	"code.fbi.h-da.de/m.stiemerling/proto-kms/quantumlayer"
+)
+
+type kmsKS interface {
+	KeyChopper256Bit(bulkKey *quantumlayer.QuantumLayerBulkKey) (err error)
+	addKey(int64, [8]byte)
+}
+
+// holds a single ready to use 256 bit key
+type kmsKSElement struct {
+	keyID string
+	key   []byte // a 256 bit key
+}
+
+type kmsKeyStore struct {
+	keyStoreMutex sync.Mutex
+	keyStore      map[string]kmsKSElement
+}
+
+func (ks *kmsKeyStore) addKey(bulkKeyId int64, keyToadd []byte) {
+	newKeyElement := kmsKSElement{}
+
+	//generate keyID out of bulkKeyId and has of keyToadd
+	h := sha256.New()
+	hasofkey := string(h.Sum(keyToadd[:]))
+	newKeyElement.keyID = fmt.Sprintf("%x.%x", bulkKeyId, hasofkey)
+	newKeyElement.key = keyToadd
+
+	ks.keyStoreMutex.Lock()
+	defer ks.keyStoreMutex.Unlock()
+	// test for collisions
+	if _, notThere := ks.keyStore[newKeyElement.keyID]; notThere {
+		log.Fatalf("Whop: addKey collission of key id %s for bulkKeyID %d", newKeyElement.keyID, bulkKeyId)
+		return
+	}
+	// ok to add
+	ks.keyStore[newKeyElement.keyID] = newKeyElement
+
+}
+
+// Takes a bulk of keys and chops them in 256bit keys each
+// Any remainder is discarded
+func (ks *kmsKeyStore) KeyChopper256Bit(bulkKey *quantumlayer.QuantumLayerBulkKey) (err error) {
+	if bulkKey.BulkKeyLength != len(*bulkKey.BulkKey) {
+		err = errors.New("bulkKey length mismatch")
+		return err
+	}
+
+	// Let's chop!
+	key := *bulkKey.BulkKey
+	for len(key) > 8 {
+		tmpkey := key[:8]
+		ks.addKey(bulkKey.BulkKeyId, tmpkey)
+		// shorten the key storage
+		key = key[8:]
+
+	}
+	return nil
+
+}
diff --git a/internal/kms/kms.go b/internal/kms/kms.go
index 586d8374c0e8a31d648f3edf467e9498cfe5a012..68a85dd32e448d66274837b261324f81feb6af2c 100644
--- a/internal/kms/kms.go
+++ b/internal/kms/kms.go
@@ -5,53 +5,132 @@
 package kms
 
 import (
+	"crypto/rand"
+	"log"
+	"math/big"
+	"sync"
+	"time"
+
 	"code.fbi.h-da.de/m.stiemerling/proto-kms/quantumlayer"
 	"github.com/google/uuid"
 )
 
 type Qkdnkms interface {
 	AddQuantumElement() *QuantumElement
+	GlobalKeyHandler(time.Duration) error
 }
 
-type qlElementId uuid.UUID
+type qlElementId uint64
 type qlElementLinkID int
 
 // The general emulated KMS
 type eKMS struct {
+	kmsName         string
+	kmsUUID         uuid.UUID
+	qleMapMutex     sync.Mutex
 	QuantumElements map[qlElementId]*QuantumElement
-	KeyStorages     map[qlElementId]map[qlElementLinkID]uint64
 }
 
 // Will keep information about the quantum elements that this eKMS is talking to
+// This actually constitutes a quantum element with only a single link
 type QuantumElement struct {
-	qlElementName       string                                         // the name of this Quantum Element
-	qlElementUUID       uuid.UUID                                      // the uuid for this device
-	QlElement           *quantumlayer.QuantumlayerEmuPRNG              // the actual quantum element
-	QuantumElementLinks map[qlElementLinkID]*quantumlayer.QuantumLayer // contains information about the quantum links
+	qlID               qlElementId
+	QuantumElementLink *quantumlayer.QuantumlayerEmuPRNG // contains information about the quantum links
+	//key stores go here
+	keyStoreLocal  *kmsKeyStore // the keys this local entity has produced and are ready to use
+	keyStoreRemote *kmsKeyStore // the keys th remote entity (peer) has produced and are ready to use
 }
 
-func NeweKMS() (newekms *eKMS) {
+func NeweKMS(kmsName string, kmsUUID uuid.UUID) (newekms *eKMS) {
 
 	return &eKMS{
+		kmsName:         kmsName,
+		kmsUUID:         kmsUUID,
 		QuantumElements: make(map[qlElementId]*QuantumElement),
-		KeyStorages:     make(map[qlElementId]map[qlElementLinkID]uint64),
 	}
 }
 
-func (kms *eKMS) AddQuantumElement(kmsName string, kmsUUID uuid.UUID, kmsUDPAddrr string) *QuantumElement {
+func (kms *eKMS) AddQuantumElement(kmsUDPAddrr string) *QuantumElement {
 
 	//Get an emulated Quantumlayer
 	ql := quantumlayer.NewQuantumlayerEmuPRNG()
 	ql.PowerOn(kmsUDPAddrr)
 
+	ksl := kmsKeyStore{
+		keyStore: make(map[string]kmsKSElement),
+	}
+	ksr := kmsKeyStore{
+		keyStore: make(map[string]kmsKSElement),
+	}
+
 	qle := QuantumElement{
-		qlElementName:       kmsName,
-		qlElementUUID:       kmsUUID,
-		QlElement:           ql,
-		QuantumElementLinks: make(map[qlElementLinkID]*quantumlayer.QuantumLayer),
+		QuantumElementLink: ql,
+		keyStoreLocal:      &ksl,
+		keyStoreRemote:     &ksr,
 	}
 
-	kms.QuantumElements[qlElementId(kmsUUID)] = &qle
+	// generate a ID for this quantum element that is unique locally
+	var randError error
+	qle.qlID, randError = kms.GenerateNewQleID()
+	if randError != nil {
+		log.Fatalf("GenerateNewQleID: %s", randError)
+		return nil
+	}
+
+	kms.QuantumElements[qle.qlID] = &qle
 
 	return &qle
 }
+
+func (kms *eKMS) GlobalKeyHandler(waitTime time.Duration) error {
+
+	// periodically walk through QuantumElements and retrieve their
+	// - local key bulk buffer
+	// - remote key bulk buffer
+	// feed this into the corresponding key buffers of the kmss
+	for {
+		for currentQE := range kms.QuantumElements {
+			log.Printf("%s GlobalKeyHandler reading...\n", kms.kmsName)
+
+			bulkKeysLocal, err := kms.QuantumElements[currentQE].QuantumElementLink.GetKeyBatchLocal()
+			if err != nil {
+				log.Printf("%s failed to retrieve local bulkkeys with error %s", kms.kmsName, err)
+			} else {
+				// process bulkKeysLocal
+				log.Printf("%s produced %d bytes of key locally", kms.kmsName, bulkKeysLocal.BulkKeyLength)
+				kms.QuantumElements[currentQE].keyStoreLocal.KeyChopper256Bit(&bulkKeysLocal)
+
+			}
+
+			bulkKeysRemote, err := kms.QuantumElements[currentQE].QuantumElementLink.GetKeyBatchPeer()
+			if err != nil {
+				log.Printf("%s failed to retrieve remote bulkkeys with error %s", kms.kmsName, err)
+			} else {
+				// process bulkKeysRemote
+				log.Printf("%s received %d bytes of key from remote peer", kms.kmsName, bulkKeysRemote.BulkKeyLength)
+				kms.QuantumElements[currentQE].keyStoreRemote.KeyChopper256Bit(&bulkKeysLocal)
+			}
+		}
+		time.Sleep(waitTime)
+	}
+}
+
+// This has a design flaw, as the generated ID is returned to the calling function and used there.
+// However, when being used a potential other caller might received the same qlElementId
+// TODO/XXX: This would be collision and must be eventually avoided
+func (kms *eKMS) GenerateNewQleID() (qlElementId, error) {
+	for { // this needs a condiction to stop!
+		bigRand, randError := rand.Int(rand.Reader, big.NewInt(100000))
+		if randError != nil {
+			return 0, randError
+		}
+
+		propopsedQlElementID := qlElementId(bigRand.Uint64())
+
+		// check if ID is already taken
+		if kms.QuantumElements[propopsedQlElementID] == nil {
+			return propopsedQlElementID, nil
+		}
+		//keep going....
+	}
+}
diff --git a/internal/main.go b/internal/main.go
index eb47a37eebba58c640d327b38b25bc7285901f37..eaee39da2650297dda71c8ce1feeddff8cd4aacf 100644
--- a/internal/main.go
+++ b/internal/main.go
@@ -4,6 +4,7 @@ import (
 	"flag"
 	"log"
 	"net"
+	"time"
 
 	"code.fbi.h-da.de/m.stiemerling/proto-kms/kms"
 	"github.com/google/uuid"
@@ -56,10 +57,10 @@ func main() {
 
 func emulatedKMS(myName string, myUDPAddr string, peerUDPAddr string) {
 	// Attach to eKMS
-	emuKMS := kms.NeweKMS()
+	emuKMS := kms.NeweKMS(myName, uuid.New())
 
 	// Fire up Quantum LinK
-	myQL := emuKMS.AddQuantumElement(myName, uuid.New(), myUDPAddr)
+	myQL := emuKMS.AddQuantumElement(myUDPAddr)
 
 	udpQL2Addr, err := net.ResolveUDPAddr("udp", peerUDPAddr)
 	if err != nil {
@@ -67,18 +68,8 @@ func emulatedKMS(myName string, myUDPAddr string, peerUDPAddr string) {
 		return
 	}
 
-	myQL.QlElement.AddPeer(*udpQL2Addr)
+	myQL.QuantumElementLink.AddPeer(*udpQL2Addr)
 
-	for {
-		resultQLLocal, err := myQL.QlElement.GetKeyBatchLocal()
-		if err == nil {
-			log.Printf("Current key IDs are for %s local %d:", myName, resultQLLocal.BulkKeyId)
-
-		}
-		resultQLRemote, err := myQL.QlElement.GetKeyBatchPeer()
-		if err == nil {
-			log.Printf("Current key IDs are for remote %d:", resultQLRemote.BulkKeyId)
-
-		}
-	}
+	// TODO/XXX catch errors!
+	emuKMS.GlobalKeyHandler(7 * time.Second)
 }