Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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)
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
}
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
}