Skip to content
Snippets Groups Projects
quantumlayer-emulator.go 2.25 KiB
Newer Older
  • Learn to ignore specific revisions
  • package quantumlayer
    
    import (
    	"context"
    	"strconv"
    	"time"
    
    	pb "code.fbi.h-da.de/danet/quipsec/gen/go/quipsec"
    	"github.com/sirupsen/logrus"
    )
    
    type QuantumlayerEmulator struct {
    	kmsClient          pb.KmsQkdmCommunicationServiceClient
    	randomNumberSource RandomNumberSource
    }
    
    func NewQuantumlayerEmulator(client pb.KmsQkdmCommunicationServiceClient, randomNumberSource RandomNumberSource) (newql *QuantumlayerEmulator) {
    	return &QuantumlayerEmulator{
    		kmsClient:          client,
    		randomNumberSource: randomNumberSource,
    	}
    }
    
    func (ql *QuantumlayerEmulator) Start() {
    	iteration := 0
    	ql.synchronizeOffline()
    	lastSnyc := time.Now()
    
    	for {
    		// Synchronize with the other quantumlayer every hour
    		if time.Since(lastSnyc) > time.Hour {
    			ql.synchronizeOffline()
    			lastSnyc = time.Now()
    		}
    
    		data, length, err := ql.randomNumberSource.GenerateRandomBytes()
    		if err != nil {
    			logrus.Error("Error generating random numbers: ", err)
    
    
    		for {
    			err = ql.sendDatatoKMS(data, length, iteration)
    			if err != nil {
    				logrus.Error("Error sending data to KMS, will retry: ", err)
    
    				time.Sleep(1 * time.Second)
    				continue
    
    		}
    		logrus.Infof("Iteration %d: Sent %d bytes to KMS", iteration, length)
    		iteration++
    	}
    }
    
    // Used to synchronize with the other quantumlayer without communicating. Waits until the next given time in seconds of (00, 20, 40). This is not a perfect solution, for a better one we need an online synchronization.
    func (ql *QuantumlayerEmulator) synchronizeOffline() {
    	logrus.Info("Synchronizing offline with the other quantumlayer")
    
    	currentTime := time.Now()
    
    	// Calculate the time to wait until the next synchronization point
    	timeUntilNextSync := time.Duration(20-currentTime.Second()%20) * time.Second
    	logrus.Infof("Waiting %s to synchronize", timeUntilNextSync)
    
    	time.Sleep(timeUntilNextSync)
    }
    
    func (ql *QuantumlayerEmulator) sendDatatoKMS(data []byte, length int, keyID int) error {
    	_, err := ql.kmsClient.PushKeys(context.Background(), &pb.PushKeysRequest{
    		Timestamp: time.Now().Unix(),
    		KeyBulk: &pb.KeyBulk{
    			KeyId:     strconv.FormatInt(int64(keyID), 10),
    			KeyLength: uint64(length),
    			Keys:      data,
    		},
    	})
    	if err != nil {
    		logrus.Error("Error sending data to KMS: ", err)
    		return err
    	}
    
    	return nil
    }