This commit is contained in:
number571 2026-05-17 06:57:21 +07:00
parent 409eb944fe
commit ffb4744794
56 changed files with 766 additions and 429 deletions

View File

@ -3,7 +3,7 @@ package adapters
import ( import (
"context" "context"
"github.com/number571/go-peer/pkg/message/layer1" "github.com/number571/go-peer/pkg/crypto/hybrid/layer1"
) )
var ( var (

View File

@ -5,7 +5,7 @@ import (
"context" "context"
"testing" "testing"
"github.com/number571/go-peer/pkg/message/layer1" "github.com/number571/go-peer/pkg/crypto/hybrid/layer1"
"github.com/number571/go-peer/pkg/payload" "github.com/number571/go-peer/pkg/payload"
) )

View File

@ -3,7 +3,7 @@ package adapters
import ( import (
"context" "context"
"github.com/number571/go-peer/pkg/message/layer1" "github.com/number571/go-peer/pkg/crypto/hybrid/layer1"
) )
type IAdapter interface { type IAdapter interface {

View File

@ -11,10 +11,9 @@ import (
"github.com/number571/go-peer/pkg/anonymity/qb/queue" "github.com/number571/go-peer/pkg/anonymity/qb/queue"
"github.com/number571/go-peer/pkg/crypto/hashing" "github.com/number571/go-peer/pkg/crypto/hashing"
"github.com/number571/go-peer/pkg/crypto/hybrid" "github.com/number571/go-peer/pkg/crypto/hybrid"
"github.com/number571/go-peer/pkg/crypto/hybrid/layer1"
"github.com/number571/go-peer/pkg/crypto/random" "github.com/number571/go-peer/pkg/crypto/random"
"github.com/number571/go-peer/pkg/logger" "github.com/number571/go-peer/pkg/logger"
"github.com/number571/go-peer/pkg/message/layer1"
"github.com/number571/go-peer/pkg/message/layer2"
"github.com/number571/go-peer/pkg/payload" "github.com/number571/go-peer/pkg/payload"
"github.com/number571/go-peer/pkg/state" "github.com/number571/go-peer/pkg/state"
"github.com/number571/go-peer/pkg/storage/database" "github.com/number571/go-peer/pkg/storage/database"
@ -234,7 +233,7 @@ func (p *sNode) consumeMessage(pCtx context.Context, pNetMsg layer1.IMessage) er
// check network message on correct format // check network message on correct format
if ok := p.checkMessageLayer1(pNetMsg); !ok { if ok := p.checkMessageLayer1(pNetMsg); !ok {
// another network mask || message settings // another network mask || message settings on adapter's side
p.fLogger.PushWarn(logBuilder.WithType(anon_logger.CLogWarnIncorrectLayer1)) p.fLogger.PushWarn(logBuilder.WithType(anon_logger.CLogWarnIncorrectLayer1))
return ErrInvalidLayer1Message return ErrInvalidLayer1Message
} }
@ -242,11 +241,10 @@ func (p *sNode) consumeMessage(pCtx context.Context, pNetMsg layer1.IMessage) er
scheme := p.fQBProcessor.GetScheme() scheme := p.fQBProcessor.GetScheme()
encMsg := pNetMsg.GetPayload().GetBody() encMsg := pNetMsg.GetPayload().GetBody()
// load encrypted message without decryption try // check size on static payload structure.
if _, err := layer2.LoadMessage(scheme.GetMessageSize(), encMsg); err != nil { if uint64(len(encMsg)) != scheme.GetMessageSize() {
// problem from sender's side (invalid structure)
p.fLogger.PushWarn(logBuilder.WithType(anon_logger.CLogWarnMessageNull)) p.fLogger.PushWarn(logBuilder.WithType(anon_logger.CLogWarnMessageNull))
return errors.Join(ErrLoadMessage, err) return ErrInvalidPayloadSize
} }
// try store hash of message // try store hash of message

View File

@ -15,11 +15,11 @@ import (
"github.com/number571/go-peer/pkg/anonymity/qb/queue" "github.com/number571/go-peer/pkg/anonymity/qb/queue"
"github.com/number571/go-peer/pkg/crypto/asymmetric" "github.com/number571/go-peer/pkg/crypto/asymmetric"
"github.com/number571/go-peer/pkg/crypto/hybrid" "github.com/number571/go-peer/pkg/crypto/hybrid"
"github.com/number571/go-peer/pkg/crypto/hybrid/layer1"
"github.com/number571/go-peer/pkg/crypto/hybrid/macro" "github.com/number571/go-peer/pkg/crypto/hybrid/macro"
"github.com/number571/go-peer/pkg/crypto/random" "github.com/number571/go-peer/pkg/crypto/random"
"github.com/number571/go-peer/pkg/encoding" "github.com/number571/go-peer/pkg/encoding"
"github.com/number571/go-peer/pkg/logger" "github.com/number571/go-peer/pkg/logger"
"github.com/number571/go-peer/pkg/message/layer1"
"github.com/number571/go-peer/pkg/network" "github.com/number571/go-peer/pkg/network"
"github.com/number571/go-peer/pkg/payload" "github.com/number571/go-peer/pkg/payload"
"github.com/number571/go-peer/pkg/storage/cache" "github.com/number571/go-peer/pkg/storage/cache"

View File

@ -19,7 +19,7 @@ var (
ErrRetryLimit = &SAnonymityError{"retry limit"} ErrRetryLimit = &SAnonymityError{"retry limit"}
ErrEnqueueMessage = &SAnonymityError{"enqueue message"} ErrEnqueueMessage = &SAnonymityError{"enqueue message"}
ErrUnknownType = &SAnonymityError{"unknown type"} ErrUnknownType = &SAnonymityError{"unknown type"}
ErrLoadMessage = &SAnonymityError{"load message"} ErrInvalidPayloadSize = &SAnonymityError{"invalid payload size"}
ErrInvalidLayer1Message = &SAnonymityError{"invalid layer1 message"} ErrInvalidLayer1Message = &SAnonymityError{"invalid layer1 message"}
ErrStoreHashIntoDatabase = &SAnonymityError{"store hash into database"} ErrStoreHashIntoDatabase = &SAnonymityError{"store hash into database"}
ErrStoreHashWithProduce = &SAnonymityError{"store hash with produce"} ErrStoreHashWithProduce = &SAnonymityError{"store hash with produce"}

View File

@ -1,3 +1,5 @@
//go:build !symmetric
package main package main
import ( import (
@ -11,9 +13,10 @@ import (
anon_logger "github.com/number571/go-peer/pkg/anonymity/qb/logger" anon_logger "github.com/number571/go-peer/pkg/anonymity/qb/logger"
"github.com/number571/go-peer/pkg/anonymity/qb/queue" "github.com/number571/go-peer/pkg/anonymity/qb/queue"
"github.com/number571/go-peer/pkg/crypto/asymmetric" "github.com/number571/go-peer/pkg/crypto/asymmetric"
"github.com/number571/go-peer/pkg/crypto/hybrid"
"github.com/number571/go-peer/pkg/crypto/hybrid/layer1"
"github.com/number571/go-peer/pkg/crypto/hybrid/macro" "github.com/number571/go-peer/pkg/crypto/hybrid/macro"
"github.com/number571/go-peer/pkg/logger" "github.com/number571/go-peer/pkg/logger"
"github.com/number571/go-peer/pkg/message/layer1"
"github.com/number571/go-peer/pkg/network" "github.com/number571/go-peer/pkg/network"
"github.com/number571/go-peer/pkg/network/conn" "github.com/number571/go-peer/pkg/network/conn"
"github.com/number571/go-peer/pkg/storage/cache" "github.com/number571/go-peer/pkg/storage/cache"
@ -29,7 +32,11 @@ const (
type sNode struct { type sNode struct {
fNetwork network.INode fNetwork network.INode
fAnonymity anonymity.INode fAnonymity anonymity.INode
fPrivKey asymmetric.IPrivKey fKey hybrid.IParticipantKey
}
func printTagVersion() {
fmt.Println("build_tag: asymmetric (default)")
} }
func newNode(serviceName, address string) *sNode { func newNode(serviceName, address string) *sNode {
@ -126,5 +133,15 @@ func newNode(serviceName, address string) *sNode {
), ),
), ),
) )
return &sNode{networkNode, anonymityNode, privKey} return &sNode{networkNode, anonymityNode, privKey.GetPubKey()}
}
func exchangeKeys(node1, node2 *sNode) (hybrid.IParticipantKey, hybrid.IParticipantKey) {
pubKey1 := node1.fKey.(asymmetric.IPubKey)
pubKey2 := node2.fKey.(asymmetric.IPubKey)
node1.fAnonymity.GetKeysContainer().(asymmetric.IMapPubKeys).SetPubKey(pubKey2)
node2.fAnonymity.GetKeysContainer().(asymmetric.IMapPubKeys).SetPubKey(pubKey1)
return pubKey1, pubKey2
} }

View File

@ -0,0 +1,146 @@
//go:build symmetric
package main
import (
"context"
"fmt"
"os"
"time"
anonymity "github.com/number571/go-peer/pkg/anonymity/qb"
"github.com/number571/go-peer/pkg/anonymity/qb/adapters"
anon_logger "github.com/number571/go-peer/pkg/anonymity/qb/logger"
"github.com/number571/go-peer/pkg/anonymity/qb/queue"
"github.com/number571/go-peer/pkg/crypto/hybrid"
"github.com/number571/go-peer/pkg/crypto/hybrid/layer1"
"github.com/number571/go-peer/pkg/crypto/hybrid/micro"
"github.com/number571/go-peer/pkg/crypto/random"
"github.com/number571/go-peer/pkg/crypto/symmetric"
"github.com/number571/go-peer/pkg/logger"
"github.com/number571/go-peer/pkg/network"
"github.com/number571/go-peer/pkg/network/conn"
"github.com/number571/go-peer/pkg/storage/cache"
"github.com/number571/go-peer/pkg/storage/database"
)
const (
networkMask = uint32(0x11223344)
msgSize = uint64(128)
workSize = uint64(10)
)
type sNode struct {
fNetwork network.INode
fAnonymity anonymity.INode
fKey hybrid.IParticipantKey // not used
}
func printTagVersion() {
fmt.Println("build_tag: symmetric")
}
func newNode(serviceName, address string) *sNode {
msgChan := make(chan layer1.IMessage)
scheme := micro.NewScheme(msgSize)
networkNode := network.NewNode(
network.NewSettings(&network.SSettings{
FAddress: address,
FMaxConnects: 256,
FReadTimeout: time.Minute,
FWriteTimeout: time.Minute,
FConnSettings: conn.NewSettings(&conn.SSettings{
FMessageSettings: layer1.NewSettings(&layer1.SSettings{
FWorkSizeBits: workSize,
}),
FLimitMessageSizeBytes: msgSize,
FWaitReadTimeout: time.Hour,
FDialTimeout: time.Minute,
FReadTimeout: time.Minute,
FWriteTimeout: time.Minute,
}),
}),
cache.NewLRUCache(1024),
).HandleFunc(
networkMask,
func(ctx context.Context, _ network.INode, _ conn.IConn, msg layer1.IMessage) error {
msgChan <- msg
return nil
},
)
anonymityNode := anonymity.NewNode(
anonymity.NewSettings(&anonymity.SSettings{
FServiceName: serviceName,
FFetchTimeout: time.Minute,
}),
logger.NewLogger(
logger.NewSettings(&logger.SSettings{
FInfo: os.Stdout,
FWarn: os.Stdout,
FErro: os.Stderr,
}),
func(ia logger.ILogArg) string {
logGetter, ok := ia.(anon_logger.ILogGetter)
if !ok {
panic("got invalid log arg")
}
return fmt.Sprintf(
"name=%s code=%02x hash=%X proof=%08d bytes=%d",
logGetter.GetService(),
logGetter.GetType(),
logGetter.GetHash()[:16],
logGetter.GetProof(),
logGetter.GetSize(),
)
},
),
adapters.NewAdapterByFuncs(
func(ctx context.Context, msg layer1.IMessage) error {
return networkNode.BroadcastMessage(ctx, msg)
},
func(ctx context.Context) (layer1.IMessage, error) {
select {
case <-ctx.Done():
return nil, ctx.Err()
case msg := <-msgChan:
_ = networkNode.BroadcastMessage(ctx, msg)
return msg, nil
}
},
),
func() database.IKVDatabase {
db, err := database.NewKVDatabase("./database_" + serviceName + ".db")
if err != nil {
panic(err)
}
return db
}(),
symmetric.NewListCiphers(),
queue.NewQBProblemProcessor(
queue.NewSettings(&queue.SSettings{
FMessageConstructSettings: layer1.NewConstructSettings(&layer1.SConstructSettings{
FSettings: layer1.NewSettings(&layer1.SSettings{
FWorkSizeBits: workSize,
}),
}),
FNetworkMask: networkMask,
FQueuePeriod: 2 * time.Second,
FConsumersCap: 1,
FQueuePoolCap: [2]uint64{32, 32},
}),
scheme,
),
)
return &sNode{networkNode, anonymityNode, nil}
}
func exchangeKeys(node1, node2 *sNode) (hybrid.IParticipantKey, hybrid.IParticipantKey) {
key := random.NewRandom().GetBytes(symmetric.CCipherKeySize)
cipher := symmetric.NewCipher(key)
node1.fAnonymity.GetKeysContainer().(symmetric.IListCiphers).Add(cipher)
node2.fAnonymity.GetKeysContainer().(symmetric.IListCiphers).Add(cipher)
return cipher, cipher
}

View File

@ -6,7 +6,6 @@ import (
"time" "time"
anonymity "github.com/number571/go-peer/pkg/anonymity/qb" anonymity "github.com/number571/go-peer/pkg/anonymity/qb"
"github.com/number571/go-peer/pkg/crypto/asymmetric"
"github.com/number571/go-peer/pkg/crypto/hybrid" "github.com/number571/go-peer/pkg/crypto/hybrid"
"github.com/number571/go-peer/pkg/payload" "github.com/number571/go-peer/pkg/payload"
) )
@ -16,17 +15,21 @@ const (
nodeRouter = uint32(0xA557711A) nodeRouter = uint32(0xA557711A)
) )
func init() {
printTagVersion()
}
func main() { func main() {
nodeService := runServiceNode() nodeService := runServiceNode()
nodeClient := runClientNode() nodeClient := runClientNode()
pubKeyService, _ := exchangeKeys(nodeService, nodeClient) keyToService, _ := exchangeKeys(nodeService, nodeClient)
ctx := context.Background() ctx := context.Background()
for { for {
resp, _ := nodeClient.fAnonymity.FetchPayload( resp, _ := nodeClient.fAnonymity.FetchPayload(
ctx, ctx,
pubKeyService, keyToService,
payload.NewPayload32(nodeRouter, []byte("hello, world!")), payload.NewPayload32(nodeRouter, []byte("hello, world!")),
) )
fmt.Println(string(resp)) fmt.Println(string(resp))
@ -59,13 +62,3 @@ func runServiceNode() *sNode {
time.Sleep(time.Second) // wait listener time.Sleep(time.Second) // wait listener
return node return node
} }
func exchangeKeys(node1, node2 *sNode) (asymmetric.IPubKey, asymmetric.IPubKey) {
pubKey1 := node1.fPrivKey.GetPubKey()
pubKey2 := node2.fPrivKey.GetPubKey()
node1.fAnonymity.GetKeysContainer().(asymmetric.IMapPubKeys).SetPubKey(pubKey2)
node2.fAnonymity.GetKeysContainer().(asymmetric.IMapPubKeys).SetPubKey(pubKey1)
return pubKey1, pubKey2
}

View File

@ -1,3 +1,5 @@
//go:build !symmetric
package main package main
import ( import (
@ -11,9 +13,10 @@ import (
anon_logger "github.com/number571/go-peer/pkg/anonymity/qb/logger" anon_logger "github.com/number571/go-peer/pkg/anonymity/qb/logger"
"github.com/number571/go-peer/pkg/anonymity/qb/queue" "github.com/number571/go-peer/pkg/anonymity/qb/queue"
"github.com/number571/go-peer/pkg/crypto/asymmetric" "github.com/number571/go-peer/pkg/crypto/asymmetric"
"github.com/number571/go-peer/pkg/crypto/hybrid"
"github.com/number571/go-peer/pkg/crypto/hybrid/layer1"
"github.com/number571/go-peer/pkg/crypto/hybrid/macro" "github.com/number571/go-peer/pkg/crypto/hybrid/macro"
"github.com/number571/go-peer/pkg/logger" "github.com/number571/go-peer/pkg/logger"
"github.com/number571/go-peer/pkg/message/layer1"
"github.com/number571/go-peer/pkg/network" "github.com/number571/go-peer/pkg/network"
"github.com/number571/go-peer/pkg/network/conn" "github.com/number571/go-peer/pkg/network/conn"
"github.com/number571/go-peer/pkg/storage/cache" "github.com/number571/go-peer/pkg/storage/cache"
@ -29,7 +32,11 @@ const (
type sNode struct { type sNode struct {
fNetwork network.INode fNetwork network.INode
fAnonymity anonymity.INode fAnonymity anonymity.INode
fPrivKey asymmetric.IPrivKey fKey hybrid.IParticipantKey
}
func printTagVersion() {
fmt.Println("build_tag: asymmetric (default)")
} }
func newNode(serviceName, address string) *sNode { func newNode(serviceName, address string) *sNode {
@ -126,5 +133,15 @@ func newNode(serviceName, address string) *sNode {
), ),
), ),
) )
return &sNode{networkNode, anonymityNode, privKey} return &sNode{networkNode, anonymityNode, privKey.GetPubKey()}
}
func exchangeKeys(node1, node2 *sNode) (hybrid.IParticipantKey, hybrid.IParticipantKey) {
pubKey1 := node1.fKey.(asymmetric.IPubKey)
pubKey2 := node2.fKey.(asymmetric.IPubKey)
node1.fAnonymity.GetKeysContainer().(asymmetric.IMapPubKeys).SetPubKey(pubKey2)
node2.fAnonymity.GetKeysContainer().(asymmetric.IMapPubKeys).SetPubKey(pubKey1)
return pubKey1, pubKey2
} }

View File

@ -0,0 +1,146 @@
//go:build symmetric
package main
import (
"context"
"fmt"
"os"
"time"
anonymity "github.com/number571/go-peer/pkg/anonymity/qb"
"github.com/number571/go-peer/pkg/anonymity/qb/adapters"
anon_logger "github.com/number571/go-peer/pkg/anonymity/qb/logger"
"github.com/number571/go-peer/pkg/anonymity/qb/queue"
"github.com/number571/go-peer/pkg/crypto/hybrid"
"github.com/number571/go-peer/pkg/crypto/hybrid/layer1"
"github.com/number571/go-peer/pkg/crypto/hybrid/micro"
"github.com/number571/go-peer/pkg/crypto/random"
"github.com/number571/go-peer/pkg/crypto/symmetric"
"github.com/number571/go-peer/pkg/logger"
"github.com/number571/go-peer/pkg/network"
"github.com/number571/go-peer/pkg/network/conn"
"github.com/number571/go-peer/pkg/storage/cache"
"github.com/number571/go-peer/pkg/storage/database"
)
const (
networkMask = uint32(0x11223344)
msgSize = uint64(128)
workSize = uint64(10)
)
type sNode struct {
fNetwork network.INode
fAnonymity anonymity.INode
fKey hybrid.IParticipantKey // not used
}
func printTagVersion() {
fmt.Println("build_tag: symmetric")
}
func newNode(serviceName, address string) *sNode {
msgChan := make(chan layer1.IMessage)
networkNode := network.NewNode(
network.NewSettings(&network.SSettings{
FAddress: address,
FMaxConnects: 256,
FReadTimeout: time.Minute,
FWriteTimeout: time.Minute,
FConnSettings: conn.NewSettings(&conn.SSettings{
FMessageSettings: layer1.NewSettings(&layer1.SSettings{
FWorkSizeBits: workSize,
}),
FLimitMessageSizeBytes: msgSize,
FWaitReadTimeout: time.Hour,
FDialTimeout: time.Minute,
FReadTimeout: time.Minute,
FWriteTimeout: time.Minute,
}),
}),
cache.NewLRUCache(1024),
).HandleFunc(
networkMask,
func(ctx context.Context, _ network.INode, _ conn.IConn, msg layer1.IMessage) error {
msgChan <- msg
return nil
},
)
anonymityNode := anonymity.NewNode(
anonymity.NewSettings(&anonymity.SSettings{
FServiceName: serviceName,
FFetchTimeout: time.Minute,
}),
logger.NewLogger(
logger.NewSettings(&logger.SSettings{
FInfo: os.Stdout,
FWarn: os.Stdout,
FErro: os.Stderr,
}),
func(ia logger.ILogArg) string {
logGetter, ok := ia.(anon_logger.ILogGetter)
if !ok {
panic("got invalid log arg")
}
return fmt.Sprintf(
"name=%s code=%02x hash=%X proof=%08d bytes=%d",
logGetter.GetService(),
logGetter.GetType(),
logGetter.GetHash()[:16],
logGetter.GetProof(),
logGetter.GetSize(),
)
},
),
adapters.NewAdapterByFuncs(
func(ctx context.Context, msg layer1.IMessage) error {
return networkNode.BroadcastMessage(ctx, msg)
},
func(ctx context.Context) (layer1.IMessage, error) {
select {
case <-ctx.Done():
return nil, ctx.Err()
case msg := <-msgChan:
_ = networkNode.BroadcastMessage(ctx, msg)
return msg, nil
}
},
),
func() database.IKVDatabase {
db, err := database.NewKVDatabase("./database_" + serviceName + ".db")
if err != nil {
panic(err)
}
return db
}(),
symmetric.NewListCiphers(),
queue.NewQBProblemProcessor(
queue.NewSettings(&queue.SSettings{
FMessageConstructSettings: layer1.NewConstructSettings(&layer1.SConstructSettings{
FSettings: layer1.NewSettings(&layer1.SSettings{
FWorkSizeBits: workSize,
}),
}),
FNetworkMask: networkMask,
FQueuePeriod: 2 * time.Second,
FConsumersCap: 1,
FQueuePoolCap: [2]uint64{32, 32},
}),
micro.NewScheme(
msgSize,
),
),
)
return &sNode{networkNode, anonymityNode, nil}
}
func exchangeKeys(node1, node2 *sNode) (hybrid.IParticipantKey, hybrid.IParticipantKey) {
key := random.NewRandom().GetBytes(symmetric.CCipherKeySize)
cipher := symmetric.NewCipher(key)
node1.fAnonymity.GetKeysContainer().(symmetric.IListCiphers).Add(cipher)
node2.fAnonymity.GetKeysContainer().(symmetric.IListCiphers).Add(cipher)
return cipher, cipher
}

View File

@ -6,7 +6,6 @@ import (
"time" "time"
anonymity "github.com/number571/go-peer/pkg/anonymity/qb" anonymity "github.com/number571/go-peer/pkg/anonymity/qb"
"github.com/number571/go-peer/pkg/crypto/asymmetric"
"github.com/number571/go-peer/pkg/crypto/hybrid" "github.com/number571/go-peer/pkg/crypto/hybrid"
"github.com/number571/go-peer/pkg/encoding" "github.com/number571/go-peer/pkg/encoding"
"github.com/number571/go-peer/pkg/payload" "github.com/number571/go-peer/pkg/payload"
@ -39,16 +38,20 @@ var (
} }
) )
func init() {
printTagVersion()
}
func main() { func main() {
nodeService := runServiceNode() nodeService := runServiceNode()
nodeClient := runClientNode() nodeClient := runClientNode()
pubKeyService, _ := exchangeKeys(nodeService, nodeClient) keyService, _ := exchangeKeys(nodeService, nodeClient)
numBytes := encoding.Uint64ToBytes(0) numBytes := encoding.Uint64ToBytes(0)
_ = nodeClient.fAnonymity.SendPayload( _ = nodeClient.fAnonymity.SendPayload(
context.Background(), context.Background(),
pubKeyService, keyService,
payload.NewPayload64(uint64(nodeRouter), numBytes[:]), payload.NewPayload64(uint64(nodeRouter), numBytes[:]),
) )
@ -77,13 +80,3 @@ func runServiceNode() *sNode {
time.Sleep(time.Second) // wait listener time.Sleep(time.Second) // wait listener
return node return node
} }
func exchangeKeys(node1, node2 *sNode) (asymmetric.IPubKey, asymmetric.IPubKey) {
pubKey1 := node1.fPrivKey.GetPubKey()
pubKey2 := node2.fPrivKey.GetPubKey()
node1.fAnonymity.GetKeysContainer().(asymmetric.IMapPubKeys).SetPubKey(pubKey2)
node2.fAnonymity.GetKeysContainer().(asymmetric.IMapPubKeys).SetPubKey(pubKey1)
return pubKey1, pubKey2
}

View File

@ -9,9 +9,8 @@ import (
"github.com/number571/go-peer/pkg/anonymity/qb/queue" "github.com/number571/go-peer/pkg/anonymity/qb/queue"
"github.com/number571/go-peer/pkg/crypto/asymmetric" "github.com/number571/go-peer/pkg/crypto/asymmetric"
"github.com/number571/go-peer/pkg/crypto/hybrid/layer1"
"github.com/number571/go-peer/pkg/crypto/hybrid/macro" "github.com/number571/go-peer/pkg/crypto/hybrid/macro"
"github.com/number571/go-peer/pkg/message/layer1"
"github.com/number571/go-peer/pkg/message/layer2"
"github.com/number571/go-peer/pkg/payload" "github.com/number571/go-peer/pkg/payload"
) )
@ -60,13 +59,12 @@ func main() {
if netMsg == nil { if netMsg == nil {
panic("net message is nil") panic("net message is nil")
} }
msg, err := layer2.LoadMessage(q.GetScheme().GetMessageSize(), netMsg.GetPayload().GetBody()) if uint64(len(netMsg.GetPayload().GetBody())) != (q.GetScheme().GetMessageSize()) {
if err != nil { panic("payload size is invalid")
panic(err)
} }
pubKey, decMsg, err := q.GetScheme().DecryptMessage( pubKey, decMsg, err := q.GetScheme().DecryptMessage(
asymmetric.NewMapPubKeys(privKey.GetPubKey()), asymmetric.NewMapPubKeys(privKey.GetPubKey()),
msg.ToBytes(), netMsg.GetPayload().GetBody(),
) )
if err != nil { if err != nil {
panic(err) panic(err)

View File

@ -9,9 +9,9 @@ import (
"github.com/number571/go-peer/pkg/crypto/hashing" "github.com/number571/go-peer/pkg/crypto/hashing"
"github.com/number571/go-peer/pkg/crypto/hybrid" "github.com/number571/go-peer/pkg/crypto/hybrid"
"github.com/number571/go-peer/pkg/crypto/hybrid/layer1"
"github.com/number571/go-peer/pkg/crypto/random" "github.com/number571/go-peer/pkg/crypto/random"
"github.com/number571/go-peer/pkg/encoding" "github.com/number571/go-peer/pkg/encoding"
"github.com/number571/go-peer/pkg/message/layer1"
"github.com/number571/go-peer/pkg/payload" "github.com/number571/go-peer/pkg/payload"
"github.com/number571/go-peer/pkg/state" "github.com/number571/go-peer/pkg/state"
) )

View File

@ -10,8 +10,8 @@ import (
"time" "time"
"github.com/number571/go-peer/pkg/crypto/asymmetric" "github.com/number571/go-peer/pkg/crypto/asymmetric"
"github.com/number571/go-peer/pkg/crypto/hybrid/layer1"
"github.com/number571/go-peer/pkg/crypto/hybrid/macro" "github.com/number571/go-peer/pkg/crypto/hybrid/macro"
"github.com/number571/go-peer/pkg/message/layer1"
"github.com/number571/go-peer/pkg/payload" "github.com/number571/go-peer/pkg/payload"
testutils "github.com/number571/go-peer/test/utils" testutils "github.com/number571/go-peer/test/utils"
) )

View File

@ -3,7 +3,7 @@ package queue
import ( import (
"time" "time"
"github.com/number571/go-peer/pkg/message/layer1" "github.com/number571/go-peer/pkg/crypto/hybrid/layer1"
) )
var ( var (

View File

@ -5,7 +5,7 @@ import (
"time" "time"
"github.com/number571/go-peer/pkg/crypto/hybrid" "github.com/number571/go-peer/pkg/crypto/hybrid"
"github.com/number571/go-peer/pkg/message/layer1" "github.com/number571/go-peer/pkg/crypto/hybrid/layer1"
"github.com/number571/go-peer/pkg/types" "github.com/number571/go-peer/pkg/types"
) )

View File

@ -1,6 +1,6 @@
// Package message is used to create network messages for the purpose of confirming integrity and proof of work. // Package message is used to create network messages for the purpose of confirming integrity and proof of work.
// //
// The main purpose of the message is the possibility of retransmission with verification by the network key and hide the structure of the true message. // The main purpose of the message is the possibility of retransmission with verification by the network key and hide the structure of the true layer2.
/* /*
NETWORK MESSAGE FORMAT NETWORK MESSAGE FORMAT
@ -14,6 +14,6 @@
P - proof of work P - proof of work
E - encrypt E - encrypt
Scheme: https://github.com/number571/go-peer/blob/master/images/go-peer_layer1_message.jpg Scheme: https://github.com/number571/go-peer/blob/master/images/go-peer_layer1_layer2.jpg
*/ */
package layer1 package layer1

View File

@ -1,7 +1,7 @@
package layer1 package layer1
const ( const (
errPrefix = "pkg/message/layer1 = " errPrefix = "pkg/crypto/hybrid/layer1 = "
) )
type SMessageError struct { type SMessageError struct {

View File

@ -8,7 +8,6 @@ import (
"github.com/number571/go-peer/pkg/crypto/hybrid" "github.com/number571/go-peer/pkg/crypto/hybrid"
"github.com/number571/go-peer/pkg/crypto/random" "github.com/number571/go-peer/pkg/crypto/random"
"github.com/number571/go-peer/pkg/crypto/symmetric" "github.com/number571/go-peer/pkg/crypto/symmetric"
"github.com/number571/go-peer/pkg/message/layer2"
"github.com/number571/go-peer/pkg/payload/joiner" "github.com/number571/go-peer/pkg/payload/joiner"
) )
@ -85,7 +84,7 @@ func (p *sScheme) EncryptMessage(pRecv hybrid.IParticipantKey, pMsg []byte) ([]b
} }
// Decrypt message with private key of receiver. // Decrypt message with private key of receiver.
// No one else except the sender will be able to decrypt the message. // No one else except the sender will be able to decrypt the layer2.
func (p *sScheme) DecryptMessage(pMapPubKeys hybrid.IKeysContainer, pMsg []byte) (hybrid.IParticipantKey, []byte, error) { func (p *sScheme) DecryptMessage(pMapPubKeys hybrid.IKeysContainer, pMsg []byte) (hybrid.IParticipantKey, []byte, error) {
mapPubKeys, ok := pMapPubKeys.(asymmetric.IMapPubKeys) mapPubKeys, ok := pMapPubKeys.(asymmetric.IMapPubKeys)
if !ok { if !ok {
@ -93,7 +92,7 @@ func (p *sScheme) DecryptMessage(pMapPubKeys hybrid.IKeysContainer, pMsg []byte)
} }
// Load message's structure from encrypted bytes. // Load message's structure from encrypted bytes.
msg, err := layer2.LoadMessage(p.fMessageSize, pMsg) msg, err := loadMessage(p.fMessageSize, pMsg)
if err != nil { if err != nil {
return nil, nil, ErrInitCheckMessage return nil, nil, ErrInitCheckMessage
} }
@ -173,7 +172,7 @@ func (p *sScheme) encryptWithPadding(
} }
cipher := symmetric.NewCipher(sk) cipher := symmetric.NewCipher(sk)
return layer2.NewMessage( return newMessage(
ct, ct,
cipher.EncryptBytes(joiner.NewBytesJoiner32([][]byte{ cipher.EncryptBytes(joiner.NewBytesJoiner32([][]byte{
pkey.GetHasher().ToBytes(), pkey.GetHasher().ToBytes(),

View File

@ -11,7 +11,6 @@ import (
"github.com/number571/go-peer/pkg/crypto/random" "github.com/number571/go-peer/pkg/crypto/random"
"github.com/number571/go-peer/pkg/crypto/symmetric" "github.com/number571/go-peer/pkg/crypto/symmetric"
"github.com/number571/go-peer/pkg/encoding" "github.com/number571/go-peer/pkg/encoding"
"github.com/number571/go-peer/pkg/message/layer2"
"github.com/number571/go-peer/pkg/payload/joiner" "github.com/number571/go-peer/pkg/payload/joiner"
) )
@ -274,7 +273,7 @@ func tcEncryptWithParamsInvalidPKID(
} }
cipher := symmetric.NewCipher(sk) cipher := symmetric.NewCipher(sk)
return layer2.NewMessage( return newMessage(
ct, ct,
cipher.EncryptBytes(joiner.NewBytesJoiner32([][]byte{ cipher.EncryptBytes(joiner.NewBytesJoiner32([][]byte{
[]byte("123"), []byte("123"),

View File

@ -1,6 +1,15 @@
// Package client makes it possible to encrypt and decrypt messages using a monolithic cryptographic protocol. // Package client makes it possible to encrypt and decrypt messages using a monolithic cryptographic protocol.
// //
/* /*
MESSAGE FORMAT
E( PubK, K ) || E( K, M )
where
PubK - public key
K - secret key
M - message bytes
E - encrypt
CLIENT MESSAGE PROTOCOL CLIENT MESSAGE PROTOCOL
Protocol participants: Protocol participants:
@ -42,6 +51,6 @@
IF , than protocol is interrupted. IF , than protocol is interrupted.
More information in article: https://github.com/number571/go-peer/blob/master/docs/monolithic_cryptographic_protocol.pdf More information in article: https://github.com/number571/go-peer/blob/master/docs/monolithic_cryptographic_protocol.pdf
Scheme: https://github.com/number571/go-peer/blob/master/images/go-peer_layer2_message.jpg Scheme: https://github.com/number571/go-peer/blob/master/images/go-peer_layer2_layer2.jpg
*/ */
package macro package macro

View File

@ -23,4 +23,7 @@ var (
ErrInvalidHashSign = &SSchemeError{"invalid hash sign"} ErrInvalidHashSign = &SSchemeError{"invalid hash sign"}
ErrEncryptSymmetricKey = &SSchemeError{"encrypt symmetric key"} ErrEncryptSymmetricKey = &SSchemeError{"encrypt symmetric key"}
ErrDecodeBytesJoiner = &SSchemeError{"decode bytes joiner"} ErrDecodeBytesJoiner = &SSchemeError{"decode bytes joiner"}
ErrUnknownMessageType = &SSchemeError{"unknown type of message"}
ErrLoadMessageBytes = &SSchemeError{"load message bytes"}
ErrSizeMessageBytes = &SSchemeError{"size message bytes"}
) )

View File

@ -1,4 +1,4 @@
package layer2 package macro
import ( import (
"bytes" "bytes"
@ -17,7 +17,7 @@ type sMessage struct {
fEncd []byte fEncd []byte
} }
func NewMessage(pEnck, pEncd []byte) IMessage { func newMessage(pEnck, pEncd []byte) IMessage {
if len(pEnck) != asymmetric.CKEMCiphertextSize { if len(pEnck) != asymmetric.CKEMCiphertextSize {
panic(`len(pEnck) != asymmetric.CKEMCiphertextSize`) panic(`len(pEnck) != asymmetric.CKEMCiphertextSize`)
} }
@ -28,7 +28,7 @@ func NewMessage(pEnck, pEncd []byte) IMessage {
} }
// Message can be created only with client module. // Message can be created only with client module.
func LoadMessage(pSize uint64, pMsg interface{}) (IMessage, error) { func loadMessage(pSize uint64, pMsg interface{}) (IMessage, error) {
kSize := uint64(asymmetric.CKEMCiphertextSize) kSize := uint64(asymmetric.CKEMCiphertextSize)
if kSize >= pSize { if kSize >= pSize {
return nil, ErrSizeMessageBytes return nil, ErrSizeMessageBytes
@ -45,7 +45,7 @@ func LoadMessage(pSize uint64, pMsg interface{}) (IMessage, error) {
if uint64(len(recvMsg)) != pSize { if uint64(len(recvMsg)) != pSize {
return nil, ErrLoadMessageBytes return nil, ErrLoadMessageBytes
} }
return NewMessage(recvMsg[:kSize], recvMsg[kSize:]), nil return newMessage(recvMsg[:kSize], recvMsg[kSize:]), nil
} }
func (p *sMessage) GetEnck() []byte { func (p *sMessage) GetEnck() []byte {

View File

@ -1,4 +1,4 @@
package layer2 package macro
import ( import (
"bytes" "bytes"
@ -17,18 +17,7 @@ var (
tgStringMessage string tgStringMessage string
) )
func TestError(t *testing.T) { func TestPanicnewMessage(t *testing.T) {
t.Parallel()
str := "value"
err := &SMessageError{str}
if err.Error() != errPrefix+str {
t.Error("incorrect err.Error()")
return
}
}
func TestPanicNewMessage(t *testing.T) {
t.Parallel() t.Parallel()
defer func() { defer func() {
@ -38,7 +27,7 @@ func TestPanicNewMessage(t *testing.T) {
} }
}() }()
_ = NewMessage([]byte{}, []byte{}) _ = newMessage([]byte{}, []byte{})
} }
func TestInvalidMessage(t *testing.T) { func TestInvalidMessage(t *testing.T) {
@ -46,23 +35,23 @@ func TestInvalidMessage(t *testing.T) {
msgSize := uint64(2 << 10) msgSize := uint64(2 << 10)
if _, err := LoadMessage(msgSize, struct{}{}); err == nil { if _, err := loadMessage(msgSize, struct{}{}); err == nil {
t.Error("success load message with unknown type") t.Error("success load message with unknown type")
return return
} }
if _, err := LoadMessage(msgSize, []byte{123}); err == nil { if _, err := loadMessage(msgSize, []byte{123}); err == nil {
t.Error("success load invalid message") t.Error("success load invalid message")
return return
} }
msgBytes := joiner.NewBytesJoiner32([][]byte{[]byte("aaa"), []byte("bbb")}) msgBytes := joiner.NewBytesJoiner32([][]byte{[]byte("aaa"), []byte("bbb")})
if _, err := LoadMessage(msgSize, msgBytes); err == nil { if _, err := loadMessage(msgSize, msgBytes); err == nil {
t.Error("success load invalid message") t.Error("success load invalid message")
return return
} }
if _, err := LoadMessage(1, msgBytes); err == nil { if _, err := loadMessage(1, msgBytes); err == nil {
t.Error("success load message with keysize > msgsize") t.Error("success load message with keysize > msgsize")
return return
} }
@ -73,14 +62,14 @@ func TestMessage(t *testing.T) {
msgSize := uint64(8 << 10) msgSize := uint64(8 << 10)
msg1, err := LoadMessage(msgSize, tgBinaryMessage) msg1, err := loadMessage(msgSize, tgBinaryMessage)
if err != nil { if err != nil {
t.Error(err) t.Error(err)
return return
} }
testMessage(t, msgSize, msg1) testMessage(t, msgSize, msg1)
msg2, err := LoadMessage(msgSize, tgStringMessage) msg2, err := loadMessage(msgSize, tgStringMessage)
if err != nil { if err != nil {
t.Error(err) t.Error(err)
return return
@ -100,7 +89,7 @@ func testMessage(t *testing.T, msgSize uint64, msg IMessage) {
} }
msgBytes := bytes.Join([][]byte{msg.GetEnck(), msg.GetEncd()}, []byte{}) msgBytes := bytes.Join([][]byte{msg.GetEnck(), msg.GetEncd()}, []byte{})
if _, err := LoadMessage(msgSize, msgBytes); err != nil { if _, err := loadMessage(msgSize, msgBytes); err != nil {
t.Error("new message is invalid") t.Error("new message is invalid")
return return
} }

View File

@ -1,8 +1,6 @@
package layer2 package macro
import ( import "github.com/number571/go-peer/pkg/types"
"github.com/number571/go-peer/pkg/types"
)
type IMessage interface { type IMessage interface {
types.IConverter types.IConverter

View File

@ -8,7 +8,6 @@ import (
"github.com/number571/go-peer/pkg/crypto/random" "github.com/number571/go-peer/pkg/crypto/random"
"github.com/number571/go-peer/pkg/crypto/symmetric" "github.com/number571/go-peer/pkg/crypto/symmetric"
"github.com/number571/go-peer/pkg/encoding" "github.com/number571/go-peer/pkg/encoding"
"github.com/number571/go-peer/pkg/types"
) )
var ( var (
@ -29,8 +28,8 @@ func NewScheme(pMessageSize uint64) hybrid.IScheme {
fMessageSize: pMessageSize, fMessageSize: pMessageSize,
} }
tmpKey := random.NewRandom().GetBytes(symmetric.CCipherKeySize) tmpCipher := symmetric.NewCipher(random.NewRandom().GetBytes(symmetric.CCipherKeySize))
encMsg, err := scheme.encryptWithPadding(tmpKey, []byte{}, 0) encMsg, err := scheme.encryptWithPadding(tmpCipher, []byte{}, 0)
if err != nil { if err != nil {
panic(err) panic(err)
} }
@ -45,7 +44,7 @@ func NewScheme(pMessageSize uint64) hybrid.IScheme {
} }
func (p *sScheme) GetRandomKey() hybrid.IParticipantKey { func (p *sScheme) GetRandomKey() hybrid.IParticipantKey {
return types.NewConverter(random.NewRandom().GetBytes(symmetric.CCipherKeySize)) return symmetric.NewCipher(random.NewRandom().GetBytes(symmetric.CCipherKeySize))
} }
func (p *sScheme) GetMessageSize() uint64 { func (p *sScheme) GetMessageSize() uint64 {
@ -56,9 +55,9 @@ func (p *sScheme) GetPayloadLimit() uint64 {
return p.fPayloadLimit return p.fPayloadLimit
} }
func (p *sScheme) EncryptMessage(pKey hybrid.IParticipantKey, pMsg []byte) ([]byte, error) { func (p *sScheme) EncryptMessage(pRecv hybrid.IParticipantKey, pMsg []byte) ([]byte, error) {
recv := pKey.ToBytes() recv, ok := pRecv.(symmetric.ICipher)
if len(recv) != symmetric.CCipherKeySize { if !ok {
return nil, ErrInvalidKeyType return nil, ErrInvalidKeyType
} }
var ( var (
@ -72,19 +71,16 @@ func (p *sScheme) EncryptMessage(pKey hybrid.IParticipantKey, pMsg []byte) ([]by
} }
func (p *sScheme) DecryptMessage(pListKeys hybrid.IKeysContainer, pMsg []byte) (hybrid.IParticipantKey, []byte, error) { func (p *sScheme) DecryptMessage(pListKeys hybrid.IKeysContainer, pMsg []byte) (hybrid.IParticipantKey, []byte, error) {
listKeys, ok := pListKeys.([]hybrid.IParticipantKey)
if !ok {
return nil, nil, ErrInvalidKeyType
}
if uint64(len(pMsg)) != p.fMessageSize { if uint64(len(pMsg)) != p.fMessageSize {
return nil, nil, ErrMessageSize return nil, nil, ErrMessageSize
} }
for _, k := range listKeys { listCiphers, ok := pListKeys.(symmetric.IListCiphers)
cipher := symmetric.NewCipher(k.ToBytes()) if !ok {
if cipher == nil { return nil, nil, ErrInvalidKeyType
continue
} }
dec := cipher.DecryptBytes(pMsg) list := listCiphers.Get()
for _, c := range list {
dec := c.DecryptBytes(pMsg)
if len(dec) <= cSaltSize+hashing.CHasherSize+encoding.CSizeUint32 { if len(dec) <= cSaltSize+hashing.CHasherSize+encoding.CSizeUint32 {
continue continue
} }
@ -93,7 +89,7 @@ func (p *sScheme) DecryptMessage(pListKeys hybrid.IKeysContainer, pMsg []byte) (
hmac = dec[cSaltSize : cSaltSize+hashing.CHasherSize] hmac = dec[cSaltSize : cSaltSize+hashing.CHasherSize]
data = dec[cSaltSize+hashing.CHasherSize:] data = dec[cSaltSize+hashing.CHasherSize:]
) )
check := hashing.NewHMACHasher(k.ToBytes(), bytes.Join( check := hashing.NewHMACHasher(c.ToBytes(), bytes.Join(
[][]byte{salt, data}, [][]byte{salt, data},
[]byte{}, []byte{},
)).ToBytes() )).ToBytes()
@ -107,13 +103,13 @@ func (p *sScheme) DecryptMessage(pListKeys hybrid.IKeysContainer, pMsg []byte) (
if msgSize > uint32(len(msg)) { // nolint: gosec if msgSize > uint32(len(msg)) { // nolint: gosec
return nil, nil, ErrDecodeMessage return nil, nil, ErrDecodeMessage
} }
return k, msg[:msgSize], nil return c, msg[:msgSize], nil
} }
return nil, nil, ErrDecryptMessage return nil, nil, ErrDecryptMessage
} }
func (p *sScheme) encryptWithPadding( func (p *sScheme) encryptWithPadding(
pKey []byte, pCipher symmetric.ICipher,
pMsg []byte, pMsg []byte,
pPadd uint64, pPadd uint64,
) ([]byte, error) { ) ([]byte, error) {
@ -123,11 +119,10 @@ func (p *sScheme) encryptWithPadding(
) )
lenb := encoding.Uint32ToBytes(uint32(len(pMsg))) // nolint: gosec lenb := encoding.Uint32ToBytes(uint32(len(pMsg))) // nolint: gosec
data := bytes.Join([][]byte{lenb[:], pMsg, rand.GetBytes(pPadd)}, []byte{}) data := bytes.Join([][]byte{lenb[:], pMsg, rand.GetBytes(pPadd)}, []byte{})
cipher := symmetric.NewCipher(pKey) return pCipher.EncryptBytes(bytes.Join(
return cipher.EncryptBytes(bytes.Join(
[][]byte{ [][]byte{
salt, salt,
hashing.NewHMACHasher(pKey, bytes.Join( hashing.NewHMACHasher(pCipher.ToBytes(), bytes.Join(
[][]byte{salt, data}, [][]byte{salt, data},
[]byte{}, []byte{},
)).ToBytes(), )).ToBytes(),

View File

@ -1,47 +1,6 @@
// Package client makes it possible to encrypt and decrypt messages using a monolithic cryptographic protocol. // Package client makes it possible to encrypt and decrypt messages using a monolithic cryptographic protocol.
// //
/* /*
CLIENT MESSAGE PROTOCOL
Protocol participants:
A - sender,
B - receiver.
Steps of participant A:
1. K = G( N ), R = G( N ),
where
G - generator pseudo random bytes,
N - count of bytes for generator,
K - encryption session key,
R - pseudo random bytes (salt).
2. HP = H( R || P || PubKA || PubKB ),
where
HP - message hash,
H - hash function,
P - plaintext,
PubKX - public key of X participant.
3. CP = [ E( PubKB, K ), E( K, PubKA ), E( K, R ), E( K, P ), E( K, HP ), E( K, S( PrivKA, HP ) ) ],
where
CP - encrypted message,
E - encryption function,
S - sign function,
PrivKX - private key of X participant.
Steps of participant B:
4. K = D( PrivKB, E( PubKB, K ) ),
where
D - decryption function.
IF , than protocol is interrupted.
5. PubKA = D( K, E( K, PubKA ) ).
IF , than protocol is interrupted.
6. HP = V( PubKA, D( K, E( K, S( PrivKA, D( K, E( K, HP) ) ) ) ) ),
where
V - signature verification function.
IF , than protocol is interrupted.
7. HP = H( D( K, E( K, R ) ) || D( K, E( K, P ) ) || PubKA || PubKB ),
IF , than protocol is interrupted.
More information in article: https://github.com/number571/go-peer/blob/master/docs/monolithic_cryptographic_protocol.pdf
Scheme: https://github.com/number571/go-peer/blob/master/images/go-peer_layer2_message.jpg
*/ */
package micro package micro

View File

@ -5,27 +5,28 @@ import (
"fmt" "fmt"
"testing" "testing"
"github.com/number571/go-peer/pkg/crypto/hybrid"
"github.com/number571/go-peer/pkg/crypto/random" "github.com/number571/go-peer/pkg/crypto/random"
"github.com/number571/go-peer/pkg/crypto/symmetric" "github.com/number571/go-peer/pkg/crypto/symmetric"
"github.com/number571/go-peer/pkg/types"
) )
func TestScheme(t *testing.T) { func TestScheme(t *testing.T) {
t.Parallel() t.Parallel()
var ( var (
key = types.NewConverter(random.NewRandom().GetBytes(symmetric.CCipherKeySize)) key = symmetric.NewCipher(random.NewRandom().GetBytes(symmetric.CCipherKeySize))
msg = []byte("hello, world!") msg = []byte("hello, world!")
) )
scheme := NewScheme(200) scheme := NewScheme(128)
encMsg, err := scheme.EncryptMessage(key, msg) encMsg, err := scheme.EncryptMessage(key, msg)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
gotKey, gotMsg, err := scheme.DecryptMessage([]hybrid.IParticipantKey{key}, encMsg) listCiphers := symmetric.NewListCiphers()
listCiphers.Add(symmetric.NewCipher(key.ToBytes()))
gotKey, gotMsg, err := scheme.DecryptMessage(listCiphers, encMsg)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -38,7 +39,7 @@ func TestScheme(t *testing.T) {
t.Fatal("msgs are diff") t.Fatal("msgs are diff")
} }
// fmt.Println(scheme.GetMessageSize()) fmt.Println(scheme.GetMessageSize())
// fmt.Println(scheme.GetMessageSize() - scheme.GetPayloadLimit()) fmt.Println(scheme.GetMessageSize() - scheme.GetPayloadLimit())
// fmt.Println(scheme.GetPayloadLimit()) fmt.Println(scheme.GetPayloadLimit())
} }

View File

@ -5,6 +5,7 @@ import (
"crypto/cipher" "crypto/cipher"
"github.com/number571/go-peer/pkg/crypto/random" "github.com/number571/go-peer/pkg/crypto/random"
"github.com/number571/go-peer/pkg/encoding"
) )
var ( var (
@ -17,6 +18,7 @@ const (
) )
type sAESCipher struct { type sAESCipher struct {
fKey []byte
fBlock cipher.Block fBlock cipher.Block
} }
@ -25,7 +27,7 @@ func NewCipher(pKey []byte) ICipher {
return nil return nil
} }
block, _ := aes.NewCipher(pKey) block, _ := aes.NewCipher(pKey)
return &sAESCipher{fBlock: block} return &sAESCipher{fKey: pKey, fBlock: block}
} }
func (p *sAESCipher) EncryptBytes(pMsg []byte) []byte { func (p *sAESCipher) EncryptBytes(pMsg []byte) []byte {
@ -52,3 +54,11 @@ func (p *sAESCipher) DecryptBytes(pMsg []byte) []byte {
stream.XORKeyStream(result, pMsg[blockSize:]) stream.XORKeyStream(result, pMsg[blockSize:])
return result return result
} }
func (p *sAESCipher) ToBytes() []byte {
return p.fKey
}
func (p *sAESCipher) ToString() string {
return encoding.HexEncode(p.fKey)
}

View File

@ -0,0 +1,71 @@
package symmetric
import (
"sync"
)
var (
_ IListCiphers = &sListCiphers{}
)
type sListCiphers struct {
fMtx *sync.RWMutex
fMap map[string]interface{}
fList []ICipher
}
func NewListCiphers(pCiphers ...ICipher) IListCiphers {
listCiphers := &sListCiphers{
fMtx: &sync.RWMutex{},
fMap: make(map[string]interface{}, 128),
fList: make([]ICipher, 0, 128),
}
for _, v := range pCiphers {
listCiphers.Add(v)
}
return listCiphers
}
func (p *sListCiphers) Add(pCipher ICipher) bool {
p.fMtx.Lock()
defer p.fMtx.Unlock()
strKey := pCipher.ToString()
if _, ok := p.fMap[strKey]; ok {
return false
}
p.fMap[strKey] = struct{}{}
p.fList = append(p.fList, pCipher)
return true
}
func (p *sListCiphers) Del(pCipher ICipher) bool {
p.fMtx.Lock()
defer p.fMtx.Unlock()
strKey := pCipher.ToString()
if _, ok := p.fMap[strKey]; !ok {
return false
}
for i, v := range p.fList {
if strKey != v.ToString() {
continue
}
p.fList = append(p.fList[:i], p.fList[i+1:]...)
delete(p.fMap, strKey)
return true
}
panic("cipher not found in list (but exist in map)")
}
func (p *sListCiphers) Get() []ICipher {
p.fMtx.RLock()
defer p.fMtx.RUnlock()
list := make([]ICipher, len(p.fList))
copy(list, p.fList)
return list
}

View File

@ -1,6 +1,16 @@
package symmetric package symmetric
import "github.com/number571/go-peer/pkg/types"
type IListCiphers interface {
Get() []ICipher
Add(ICipher) bool
Del(ICipher) bool
}
type ICipher interface { type ICipher interface {
types.IConverter
EncryptBytes(pMsg []byte) []byte EncryptBytes(pMsg []byte) []byte
DecryptBytes(pMsg []byte) []byte DecryptBytes(pMsg []byte) []byte
} }

View File

@ -1,15 +0,0 @@
// Package message used as an encapsulated ciphertext.
//
/*
MESSAGE FORMAT
E( PubK, K ) || E( K, M )
where
PubK - public key
K - secret key
M - message bytes
E - encrypt
More information in pkg/client
*/
package layer2

View File

@ -1,19 +0,0 @@
package layer2
const (
errPrefix = "pkg/message/layer2 = "
)
type SMessageError struct {
str string
}
func (err *SMessageError) Error() string {
return errPrefix + err.str
}
var (
ErrUnknownMessageType = &SMessageError{"unknown type of message"}
ErrLoadMessageBytes = &SMessageError{"load message bytes"}
ErrSizeMessageBytes = &SMessageError{"size message bytes"}
)

View File

@ -8,8 +8,8 @@ import (
"sync" "sync"
"time" "time"
"github.com/number571/go-peer/pkg/crypto/hybrid/layer1"
"github.com/number571/go-peer/pkg/encoding" "github.com/number571/go-peer/pkg/encoding"
"github.com/number571/go-peer/pkg/message/layer1"
"github.com/number571/go-peer/pkg/payload/joiner" "github.com/number571/go-peer/pkg/payload/joiner"
) )

View File

@ -11,9 +11,9 @@ import (
"testing" "testing"
"time" "time"
"github.com/number571/go-peer/pkg/crypto/hybrid/layer1"
"github.com/number571/go-peer/pkg/crypto/random" "github.com/number571/go-peer/pkg/crypto/random"
"github.com/number571/go-peer/pkg/encoding" "github.com/number571/go-peer/pkg/encoding"
"github.com/number571/go-peer/pkg/message/layer1"
"github.com/number571/go-peer/pkg/payload" "github.com/number571/go-peer/pkg/payload"
testutils "github.com/number571/go-peer/test/utils" testutils "github.com/number571/go-peer/test/utils"
) )

View File

@ -3,7 +3,7 @@ package conn
import ( import (
"time" "time"
"github.com/number571/go-peer/pkg/message/layer1" "github.com/number571/go-peer/pkg/crypto/hybrid/layer1"
) )
var ( var (

View File

@ -6,7 +6,7 @@ import (
"net" "net"
"time" "time"
"github.com/number571/go-peer/pkg/message/layer1" "github.com/number571/go-peer/pkg/crypto/hybrid/layer1"
) )
type IConn interface { type IConn interface {

View File

@ -8,7 +8,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/number571/go-peer/pkg/message/layer1" "github.com/number571/go-peer/pkg/crypto/hybrid/layer1"
"github.com/number571/go-peer/pkg/network" "github.com/number571/go-peer/pkg/network"
"github.com/number571/go-peer/pkg/network/conn" "github.com/number571/go-peer/pkg/network/conn"
"github.com/number571/go-peer/pkg/storage/cache" "github.com/number571/go-peer/pkg/storage/cache"

View File

@ -5,7 +5,7 @@ import (
"fmt" "fmt"
"time" "time"
"github.com/number571/go-peer/pkg/message/layer1" "github.com/number571/go-peer/pkg/crypto/hybrid/layer1"
"github.com/number571/go-peer/pkg/network" "github.com/number571/go-peer/pkg/network"
"github.com/number571/go-peer/pkg/network/conn" "github.com/number571/go-peer/pkg/network/conn"
"github.com/number571/go-peer/pkg/payload" "github.com/number571/go-peer/pkg/payload"

View File

@ -5,7 +5,7 @@ import (
"fmt" "fmt"
"time" "time"
"github.com/number571/go-peer/pkg/message/layer1" "github.com/number571/go-peer/pkg/crypto/hybrid/layer1"
"github.com/number571/go-peer/pkg/network" "github.com/number571/go-peer/pkg/network"
"github.com/number571/go-peer/pkg/network/conn" "github.com/number571/go-peer/pkg/network/conn"
"github.com/number571/go-peer/pkg/payload" "github.com/number571/go-peer/pkg/payload"

View File

@ -6,7 +6,7 @@ import (
"strconv" "strconv"
"time" "time"
"github.com/number571/go-peer/pkg/message/layer1" "github.com/number571/go-peer/pkg/crypto/hybrid/layer1"
"github.com/number571/go-peer/pkg/network" "github.com/number571/go-peer/pkg/network"
"github.com/number571/go-peer/pkg/network/conn" "github.com/number571/go-peer/pkg/network/conn"
"github.com/number571/go-peer/pkg/payload" "github.com/number571/go-peer/pkg/payload"

View File

@ -7,8 +7,8 @@ import (
"sync" "sync"
"time" "time"
"github.com/number571/go-peer/pkg/crypto/hybrid/layer1"
"github.com/number571/go-peer/pkg/encoding" "github.com/number571/go-peer/pkg/encoding"
"github.com/number571/go-peer/pkg/message/layer1"
"github.com/number571/go-peer/pkg/network/conn" "github.com/number571/go-peer/pkg/network/conn"
"github.com/number571/go-peer/pkg/storage/cache" "github.com/number571/go-peer/pkg/storage/cache"
) )

View File

@ -10,7 +10,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/number571/go-peer/pkg/message/layer1" "github.com/number571/go-peer/pkg/crypto/hybrid/layer1"
"github.com/number571/go-peer/pkg/network/conn" "github.com/number571/go-peer/pkg/network/conn"
"github.com/number571/go-peer/pkg/payload" "github.com/number571/go-peer/pkg/payload"
"github.com/number571/go-peer/pkg/storage/cache" "github.com/number571/go-peer/pkg/storage/cache"

View File

@ -4,7 +4,7 @@ import (
"context" "context"
"time" "time"
"github.com/number571/go-peer/pkg/message/layer1" "github.com/number571/go-peer/pkg/crypto/hybrid/layer1"
"github.com/number571/go-peer/pkg/network/conn" "github.com/number571/go-peer/pkg/network/conn"
"github.com/number571/go-peer/pkg/storage/cache" "github.com/number571/go-peer/pkg/storage/cache"
"github.com/number571/go-peer/pkg/types" "github.com/number571/go-peer/pkg/types"

View File

@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="96" height="20" role="img" aria-label="code lines: 11707"><title>code lines: 11707</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="96" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="57" height="20" fill="#555"/><rect x="57" width="40" height="20" fill="#4682b4"/><rect width="96" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text aria-hidden="true" x="295" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="510">code lines</text><text x="295" y="140" transform="scale(.1)" fill="#fff" textLength="510">code lines</text><text aria-hidden="true" x="770" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="320">11707</text><text x="770" y="140" transform="scale(.1)" fill="#fff" textLength="320">11707</text></g></svg> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="96" height="20" role="img" aria-label="code lines: 11224"><title>code lines: 11224</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="96" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="57" height="20" fill="#555"/><rect x="57" width="40" height="20" fill="#4682b4"/><rect width="96" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text aria-hidden="true" x="295" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="510">code lines</text><text x="295" y="140" transform="scale(.1)" fill="#fff" textLength="510">code lines</text><text aria-hidden="true" x="770" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="320">11224</text><text x="770" y="140" transform="scale(.1)" fill="#fff" textLength="320">11224</text></g></svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="96" height="20" role="img" aria-label="coverage: 96%"><title>coverage: 96%</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="96" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="61" height="20" fill="#555"/><rect x="61" width="35" height="20" fill="#97ca00"/><rect width="96" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text aria-hidden="true" x="315" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="510">coverage</text><text x="315" y="140" transform="scale(.1)" fill="#fff" textLength="510">coverage</text><text aria-hidden="true" x="775" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="250">96%</text><text x="775" y="140" transform="scale(.1)" fill="#fff" textLength="250">96%</text></g></svg> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="96" height="20" role="img" aria-label="coverage: 95%"><title>coverage: 95%</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="96" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="61" height="20" fill="#555"/><rect x="61" width="35" height="20" fill="#97ca00"/><rect width="96" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text aria-hidden="true" x="315" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="510">coverage</text><text x="315" y="140" transform="scale(.1)" fill="#fff" textLength="510">coverage</text><text aria-hidden="true" x="775" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="250">95%</text><text x="775" y="140" transform="scale(.1)" fill="#fff" textLength="250">95%</text></g></svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -7,7 +7,7 @@
> >
<g> <g>
<rect x="20.000000" y="20.000000" width="988.000000" height="600.000000" style="fill: rgb(8, 122, 64);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="20.000000" y="20.000000" width="988.000000" height="600.000000" style="fill: rgb(9, 125, 66);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
@ -20,7 +20,7 @@
<g> <g>
<rect x="28.000000" y="41.600000" width="961.582993" height="570.400000" style="fill: rgb(8, 122, 64);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="28.000000" y="41.600000" width="961.808000" height="570.400000" style="fill: rgb(10, 125, 66);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
@ -33,18 +33,18 @@
<g> <g>
<rect x="997.582993" y="41.600000" width="2.417007" height="570.400000" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="997.808000" y="41.600000" width="2.192000" height="570.400000" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
</g> </g>
<g> <g>
<rect x="36.000000" y="63.200000" width="510.560008" height="267.234043" style="fill: rgb(3, 114, 60);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="365.244960" y="63.200000" width="466.205271" height="286.478049" style="fill: rgb(3, 114, 60);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(44.000000,78.800000) scale(1.000000)" transform="translate(373.244960,78.800000) scale(1.000000)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">anonymity/qb</text> data-math="N">anonymity/qb</text>
@ -52,25 +52,25 @@
<g> <g>
<rect x="36.000000" y="338.434043" width="510.560008" height="265.565957" style="fill: rgb(16, 136, 72);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="36.000000" y="63.200000" width="321.244960" height="540.800000" style="fill: rgb(20, 142, 75);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(44.000000,354.034043) scale(1.000000)" transform="translate(44.000000,78.800000) scale(1.000000)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(0, 0, 0); fill-opacity: 1.00; white-space: pre;"
data-math="N">crypto</text> data-math="N">crypto</text>
</g> </g>
<g> <g>
<rect x="774.515449" y="493.350922" width="94.065953" height="110.649078" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="839.450231" y="445.952821" width="142.357769" height="70.802051" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(782.515449,508.950922) scale(1.000000)" transform="translate(847.450231,461.552821) scale(1.000000)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">encoding</text> data-math="N">encoding</text>
@ -78,12 +78,12 @@
<g> <g>
<rect x="889.414548" y="346.547826" width="92.168445" height="138.803096" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="839.450231" y="350.264615" width="142.357769" height="87.688205" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(897.414548,362.147826) scale(1.000000)" transform="translate(847.450231,365.864615) scale(1.000000)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">logger</text> data-math="N">logger</text>
@ -91,25 +91,12 @@
<g> <g>
<rect x="554.560008" y="346.547826" width="211.955442" height="133.574493" style="fill: rgb(2, 110, 58);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="365.244960" y="357.678049" width="466.205271" height="246.321951" style="fill: rgb(8, 122, 64);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(562.560008,362.147826) scale(1.000000)" transform="translate(373.244960,373.278049) scale(1.000000)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">message</text>
</g>
<g>
<rect x="554.560008" y="63.200000" width="427.022985" height="275.347826" style="fill: rgb(10, 126, 66);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text
data-notex="1"
text-anchor="start"
transform="translate(562.560008,78.800000) scale(1.000000)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">network</text> data-math="N">network</text>
@ -117,12 +104,12 @@
<g> <g>
<rect x="774.515449" y="346.547826" width="106.899098" height="138.803096" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="839.450231" y="240.504615" width="142.357769" height="101.760000" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(782.515449,362.147826) scale(1.000000)" transform="translate(847.450231,256.104615) scale(1.000000)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">payload</text> data-math="N">payload</text>
@ -130,12 +117,12 @@
<g> <g>
<rect x="876.581402" y="493.350922" width="105.001590" height="68.547792" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="839.450231" y="524.754872" width="89.005012" height="79.245128" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(884.581402,508.950922) scale(1.000000)" transform="translate(847.450231,540.354872) scale(1.000000)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">state</text> data-math="N">state</text>
@ -143,12 +130,12 @@
<g> <g>
<rect x="554.560008" y="488.122319" width="211.955442" height="115.877681" style="fill: rgb(6, 119, 63);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="839.450231" y="63.200000" width="142.357769" height="169.304615" style="fill: rgb(6, 119, 63);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(562.560008,503.722319) scale(1.000000)" transform="translate(847.450231,78.800000) scale(1.000000)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">storage</text> data-math="N">storage</text>
@ -156,12 +143,12 @@
<g> <g>
<rect x="876.581402" y="569.898714" width="105.001590" height="34.101286" style="fill: rgb(23, 148, 78);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="936.455243" y="524.754872" width="45.352757" height="79.245128" style="fill: rgb(23, 148, 78);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(884.581402,585.498714) scale(0.515056)" transform="translate(944.455243,540.354872) scale(0.169865)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(0, 0, 0); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(0, 0, 0); fill-opacity: 1.00; white-space: pre;"
data-math="N">types/converter.go</text> data-math="N">types/converter.go</text>
@ -169,24 +156,31 @@
<g> <g>
<rect x="440.204285" y="256.572058" width="52.774699" height="28.930992" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="734.481209" y="270.029405" width="47.410870" height="31.824322" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
</g>
<g>
<rect x="500.978984" y="297.606494" width="26.185768" height="24.827549" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
</g>
<g>
<rect x="44.000000" y="84.800000" width="276.784004" height="237.634043" style="fill: rgb(2, 111, 59);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(52.000000,100.400000) scale(1.000000)" transform="translate(742.481209,285.629405) scale(0.363552)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">action.go</text>
</g>
<g>
<rect x="789.892079" y="314.278651" width="23.168614" height="27.399397" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
</g>
<g>
<rect x="373.244960" y="84.800000" width="251.649653" height="256.878049" style="fill: rgb(2, 111, 59);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text
data-notex="1"
text-anchor="start"
transform="translate(381.244960,100.400000) scale(1.000000)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">anonymity.go</text> data-math="N">anonymity.go</text>
@ -194,18 +188,18 @@
<g> <g>
<rect x="535.164752" y="297.606494" width="3.395256" height="24.827549" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="821.060693" y="314.278651" width="2.389538" height="27.399397" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
</g> </g>
<g> <g>
<rect x="500.978984" y="256.572058" width="37.581024" height="33.034436" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="789.892079" y="270.029405" width="33.558152" height="36.249247" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(508.978984,272.172058) scale(0.321146)" transform="translate(797.892079,285.629405) scale(0.261282)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">head.go</text> data-math="N">head.go</text>
@ -213,12 +207,12 @@
<g> <g>
<rect x="328.784004" y="256.572058" width="103.420281" height="65.861985" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="632.894614" y="270.029405" width="93.586595" height="71.648644" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(336.784004,272.172058) scale(0.433632)" transform="translate(640.894614,285.629405) scale(0.384854)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">logger/log_builder.go</text> data-math="N">logger/log_builder.go</text>
@ -226,12 +220,12 @@
<g> <g>
<rect x="328.784004" y="84.800000" width="209.776003" height="163.772058" style="fill: rgb(8, 123, 65);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="632.894614" y="84.800000" width="190.555617" height="177.229405" style="fill: rgb(8, 123, 65);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(336.784004,100.400000) scale(1.000000)" transform="translate(640.894614,100.400000) scale(1.000000)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">queue</text> data-math="N">queue</text>
@ -239,18 +233,25 @@
<g> <g>
<rect x="440.204285" y="293.503050" width="52.774699" height="28.930992" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="734.481209" y="309.853727" width="47.410870" height="31.824322" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text
data-notex="1"
text-anchor="start"
transform="translate(742.481209,325.453727) scale(0.297451)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">settings.go</text>
</g> </g>
<g> <g>
<rect x="44.000000" y="360.034043" width="194.249759" height="235.965957" style="fill: rgb(2, 111, 59);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="44.000000" y="295.155035" width="154.788720" height="300.844965" style="fill: rgb(2, 111, 59);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(52.000000,375.634043) scale(1.000000)" transform="translate(52.000000,310.755035) scale(1.000000)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">asymmetric</text> data-math="N">asymmetric</text>
@ -258,12 +259,12 @@
<g> <g>
<rect x="407.130249" y="459.228992" width="63.599065" height="91.194950" style="fill: rgb(12, 129, 68);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="206.788720" y="512.865420" width="71.407460" height="83.134580" style="fill: rgb(12, 129, 68);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(415.130249,474.828992) scale(0.708319)" transform="translate(214.788720,528.465420) scale(0.824516)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">hashing</text> data-math="N">hashing</text>
@ -271,12 +272,12 @@
<g> <g>
<rect x="246.249759" y="360.034043" width="152.880490" height="235.965957" style="fill: rgb(84, 179, 93);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="44.000000" y="84.800000" width="305.244960" height="202.355035" style="fill: rgb(23, 148, 78);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(254.249759,375.634043) scale(1.000000)" transform="translate(52.000000,100.400000) scale(1.000000)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(0, 0, 0); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(0, 0, 0); fill-opacity: 1.00; white-space: pre;"
data-math="N">hybrid</text> data-math="N">hybrid</text>
@ -284,18 +285,18 @@
<g> <g>
<rect x="530.156507" y="558.423942" width="8.403501" height="37.576058" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="286.196180" y="593.278285" width="63.048780" height="2.721715" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
</g> </g>
<g> <g>
<rect x="407.130249" y="360.034043" width="131.429758" height="91.194950" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="206.788720" y="419.199324" width="142.456241" height="85.666096" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(415.130249,375.634043) scale(0.751496)" transform="translate(214.788720,434.799324) scale(0.823283)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">puzzle/puzzle.go</text> data-math="N">puzzle/puzzle.go</text>
@ -303,12 +304,12 @@
<g> <g>
<rect x="407.130249" y="558.423942" width="115.026257" height="37.576058" style="fill: rgb(16, 136, 71);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="286.196180" y="512.865420" width="63.048780" height="72.412865" style="fill: rgb(16, 136, 71);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(415.130249,574.023942) scale(0.644702)" transform="translate(294.196180,528.465420) scale(0.306307)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">random/random.go</text> data-math="N">random/random.go</text>
@ -316,25 +317,25 @@
<g> <g>
<rect x="478.729314" y="459.228992" width="59.830693" height="91.194950" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="206.788720" y="295.155035" width="142.456241" height="116.044289" style="fill: rgb(157, 213, 105);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(486.729314,474.828992) scale(0.207532)" transform="translate(214.788720,310.755035) scale(1.000000)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(0, 0, 0); fill-opacity: 1.00; white-space: pre;"
data-math="N">symmetric/symmetric.go</text> data-math="N">symmetric</text>
</g> </g>
<g> <g>
<rect x="782.515449" y="514.950922" width="52.752437" height="46.065511" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="847.450231" y="467.552821" width="49.581901" height="41.202051" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(790.515449,530.550922) scale(0.478547)" transform="translate(855.450231,483.152821) scale(0.437264)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">bytes.go</text> data-math="N">bytes.go</text>
@ -342,37 +343,43 @@
<g> <g>
<rect x="843.267887" y="514.950922" width="17.313515" height="46.065511" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="953.017050" y="508.554530" width="20.790950" height="0.200342" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
</g>
<g>
<rect x="905.032132" y="467.552821" width="39.984917" height="16.601026" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
</g>
<g>
<rect x="905.032132" y="492.153846" width="39.984917" height="16.601026" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
</g>
<g>
<rect x="953.017050" y="467.552821" width="20.790950" height="33.001709" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(851.267887,530.550922) scale(0.022804)" transform="translate(961.017050,483.152821) scale(0.029356)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">hex.go</text> data-math="N">serialize_yaml.go</text>
</g> </g>
<g> <g>
<rect x="782.515449" y="569.016434" width="31.120888" height="26.983566" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="847.450231" y="371.864615" width="106.599273" height="58.088205" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
</g>
<g>
<rect x="821.636337" y="569.016434" width="31.120888" height="26.983566" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
</g>
<g>
<rect x="897.414548" y="368.147826" width="76.168445" height="91.967347" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(905.414548,383.747826) scale(0.696394)" transform="translate(855.450231,387.464615) scale(1.000000)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">logger.go</text> data-math="N">logger.go</text>
@ -380,44 +387,18 @@
<g> <g>
<rect x="897.414548" y="468.115173" width="76.168445" height="9.235749" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="962.049505" y="371.864615" width="11.758495" height="58.088205" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
</g> </g>
<g> <g>
<rect x="562.560008" y="368.147826" width="142.133867" height="103.974493" style="fill: rgb(3, 113, 59);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="595.112776" y="379.278049" width="146.342828" height="216.721951" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(570.560008,383.747826) scale(1.000000)" transform="translate(603.112776,394.878049) scale(1.000000)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">layer1</text>
</g>
<g>
<rect x="712.693875" y="368.147826" width="45.821575" height="103.974493" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text
data-notex="1"
text-anchor="start"
transform="translate(720.693875,383.747826) scale(0.517736)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">layer2</text>
</g>
<g>
<rect x="765.455348" y="84.800000" width="208.127645" height="157.712866" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text
data-notex="1"
text-anchor="start"
transform="translate(773.455348,100.400000) scale(1.000000)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">conn</text> data-math="N">conn</text>
@ -425,12 +406,12 @@
<g> <g>
<rect x="765.455348" y="250.512866" width="140.322894" height="80.034960" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="749.455604" y="379.278049" width="73.994627" height="146.220947" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(773.455348,266.112866) scale(1.000000)" transform="translate(757.455604,394.878049) scale(0.604111)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">connkeeper</text> data-math="N">connkeeper</text>
@ -438,12 +419,12 @@
<g> <g>
<rect x="562.560008" y="84.800000" width="194.895340" height="245.747826" style="fill: rgb(24, 149, 78);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="373.244960" y="379.278049" width="213.867815" height="216.721951" style="fill: rgb(20, 142, 75);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(570.560008,100.400000) scale(1.000000)" transform="translate(381.244960,394.878049) scale(1.000000)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(0, 0, 0); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(0, 0, 0); fill-opacity: 1.00; white-space: pre;"
data-math="N">network.go</text> data-math="N">network.go</text>
@ -451,12 +432,12 @@
<g> <g>
<rect x="913.778241" y="250.512866" width="59.804751" height="74.532775" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="749.455604" y="533.498996" width="68.869963" height="62.501004" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(921.778241,266.112866) scale(0.414818)" transform="translate(757.455604,549.098996) scale(0.500663)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">settings.go</text> data-math="N">settings.go</text>
@ -464,12 +445,12 @@
<g> <g>
<rect x="782.515449" y="368.147826" width="90.899098" height="49.098944" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="847.450231" y="262.104615" width="57.456349" height="72.160000" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(790.515449,383.747826) scale(1.000000)" transform="translate(855.450231,277.704615) scale(0.719728)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">joiner</text> data-math="N">joiner</text>
@ -477,12 +458,12 @@
<g> <g>
<rect x="782.515449" y="425.246770" width="41.449549" height="52.104152" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="912.906580" y="262.104615" width="60.901420" height="32.080000" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(790.515449,440.846770) scale(0.220916)" transform="translate(920.906580,277.704615) scale(0.389769)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">payload32.go</text> data-math="N">payload32.go</text>
@ -490,12 +471,12 @@
<g> <g>
<rect x="831.964999" y="425.246770" width="41.449549" height="52.104152" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="912.906580" y="302.184615" width="60.901420" height="32.080000" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(839.964999,440.846770) scale(0.220916)" transform="translate(920.906580,317.784615) scale(0.389769)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">payload64.go</text> data-math="N">payload64.go</text>
@ -503,12 +484,12 @@
<g> <g>
<rect x="884.581402" y="514.950922" width="84.151511" height="38.947792" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="847.450231" y="546.354872" width="68.954762" height="49.645128" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(892.581402,530.550922) scale(0.887389)" transform="translate(855.450231,561.954872) scale(0.689515)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">state.go</text> data-math="N">state.go</text>
@ -516,12 +497,12 @@
<g> <g>
<rect x="692.055526" y="509.722319" width="66.459923" height="86.277681" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="847.450231" y="178.580708" width="126.357769" height="45.923907" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(700.055526,525.322319) scale(0.438020)" transform="translate(855.450231,194.180708) scale(0.957967)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">cache/lru.go</text> data-math="N">cache/lru.go</text>
@ -529,12 +510,12 @@
<g> <g>
<rect x="562.560008" y="509.722319" width="121.495519" height="86.277681" style="fill: rgb(11, 128, 67);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="847.450231" y="84.800000" width="126.357769" height="85.780708" style="fill: rgb(11, 128, 67);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(570.560008,525.322319) scale(1.000000)" transform="translate(855.450231,100.400000) scale(1.000000)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">database</text> data-math="N">database</text>
@ -542,18 +523,18 @@
<g> <g>
<rect x="506.275847" y="239.686304" width="24.284161" height="0.885754" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="794.241332" y="252.302567" width="21.208899" height="1.726838" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
</g> </g>
<g> <g>
<rect x="336.784004" y="106.400000" width="161.491843" height="134.172058" style="fill: rgb(10, 126, 67);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="640.894614" y="106.400000" width="145.346719" height="147.629405" style="fill: rgb(10, 126, 67);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(344.784004,122.000000) scale(1.000000)" transform="translate(648.894614,122.000000) scale(1.000000)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">queue.go</text> data-math="N">queue.go</text>
@ -561,12 +542,12 @@
<g> <g>
<rect x="506.275847" y="106.400000" width="24.284161" height="125.286304" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="794.241332" y="106.400000" width="21.208899" height="137.902567" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(514.275847,122.000000) scale(0.078448)" transform="translate(802.241332,122.000000) scale(0.049327)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">settings.go</text> data-math="N">settings.go</text>
@ -574,12 +555,12 @@
<g> <g>
<rect x="168.132203" y="381.634043" width="62.117556" height="130.038685" style="fill: rgb(6, 119, 63);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="52.000000" y="428.876120" width="66.559350" height="125.276006" style="fill: rgb(6, 119, 63);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(176.132203,397.234043) scale(0.800652)" transform="translate(60.000000,444.476120) scale(0.877766)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">dsa.go</text> data-math="N">dsa.go</text>
@ -587,12 +568,12 @@
<g> <g>
<rect x="52.000000" y="519.672727" width="114.845586" height="68.327273" style="fill: rgb(6, 119, 63);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="126.559350" y="428.876120" width="64.229370" height="125.276006" style="fill: rgb(6, 119, 63);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(60.000000,535.272727) scale(1.000000)" transform="translate(134.559350,444.476120) scale(0.837315)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">kem.go</text> data-math="N">kem.go</text>
@ -600,12 +581,12 @@
<g> <g>
<rect x="52.000000" y="381.634043" width="108.132203" height="130.038685" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="52.000000" y="316.755035" width="138.788720" height="104.121084" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(60.000000,397.234043) scale(1.000000)" transform="translate(60.000000,332.355035) scale(1.000000)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">key.go</text> data-math="N">key.go</text>
@ -613,25 +594,18 @@
<g> <g>
<rect x="174.845586" y="519.672727" width="55.404173" height="68.327273" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="52.000000" y="562.152125" width="138.788720" height="25.847875" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text
data-notex="1"
text-anchor="start"
transform="translate(182.845586,535.272727) scale(0.293186)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">map_pubkeys.go</text>
</g> </g>
<g> <g>
<rect x="415.130249" y="480.828992" width="47.599065" height="32.291813" style="fill: rgb(23, 148, 78);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="214.788720" y="534.465420" width="28.709582" height="53.534580" style="fill: rgb(23, 148, 78);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(423.130249,496.428992) scale(0.329157)" transform="translate(222.788720,550.065420) scale(0.132391)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(0, 0, 0); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(0, 0, 0); fill-opacity: 1.00; white-space: pre;"
data-math="N">hashing.go</text> data-math="N">hashing.go</text>
@ -639,18 +613,38 @@
<g> <g>
<rect x="415.130249" y="521.120805" width="47.599065" height="21.303137" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="251.498302" y="534.465420" width="18.697878" height="53.534580" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text
data-notex="1"
text-anchor="start"
transform="translate(259.498302,550.065420) scale(0.040147)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">hmac.go</text>
</g> </g>
<g> <g>
<rect x="254.249759" y="381.634043" width="136.880490" height="104.286930" style="fill: rgb(13, 130, 68);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="177.427064" y="106.400000" width="163.817896" height="87.800169" style="fill: rgb(3, 113, 59);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(262.249759,397.234043) scale(1.000000)" transform="translate(185.427064,122.000000) scale(1.000000)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">layer1</text>
</g>
<g>
<rect x="52.000000" y="106.400000" width="117.427064" height="172.755035" style="fill: rgb(8, 123, 65);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text
data-notex="1"
text-anchor="start"
transform="translate(60.000000,122.000000) scale(1.000000)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">macro</text> data-math="N">macro</text>
@ -658,12 +652,12 @@
<g> <g>
<rect x="254.249759" y="493.920973" width="136.880490" height="94.079027" style="fill: rgb(166, 217, 106);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="177.427064" y="202.200169" width="163.817896" height="76.954867" style="fill: rgb(138, 205, 102);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(262.249759,509.520973) scale(1.000000)" transform="translate(185.427064,217.800169) scale(1.000000)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(0, 0, 0); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(0, 0, 0); fill-opacity: 1.00; white-space: pre;"
data-math="N">micro</text> data-math="N">micro</text>
@ -671,51 +665,38 @@
<g> <g>
<rect x="570.560008" y="389.747826" width="98.294762" height="74.374493" style="fill: rgb(4, 115, 61);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="294.364862" y="316.755035" width="46.880098" height="86.444289" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(578.560008,405.347826) scale(0.857237)" transform="translate(302.364862,332.355035) scale(0.357409)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">message.go</text> data-math="N">cipher.go</text>
</g> </g>
<g> <g>
<rect x="676.854770" y="389.747826" width="19.839104" height="66.885903" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="214.788720" y="316.755035" width="71.576143" height="86.444289" style="fill: rgb(250, 253, 182);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(684.854770,405.347826) scale(0.036355)" transform="translate(222.788720,332.355035) scale(0.385945)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(0, 0, 0); fill-opacity: 1.00; white-space: pre;"
data-math="N">settings.go</text> data-math="N">list_ciphers.go</text>
</g> </g>
<g> <g>
<rect x="720.693875" y="389.747826" width="29.821575" height="70.038993" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="603.112776" y="400.878049" width="130.342828" height="144.439024" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(728.693875,405.347826) scale(0.143975)" transform="translate(611.112776,416.478049) scale(1.000000)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">message.go</text>
</g>
<g>
<rect x="773.455348" y="106.400000" width="148.349723" height="128.112866" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text
data-notex="1"
text-anchor="start"
transform="translate(781.455348,122.000000) scale(1.000000)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">conn.go</text> data-math="N">conn.go</text>
@ -723,12 +704,12 @@
<g> <g>
<rect x="929.805070" y="106.400000" width="35.777922" height="121.631301" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="603.112776" y="553.317073" width="123.755074" height="34.682927" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(937.805070,122.000000) scale(0.187291)" transform="translate(611.112776,568.917073) scale(1.000000)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">settings.go</text> data-math="N">settings.go</text>
@ -736,12 +717,12 @@
<g> <g>
<rect x="773.455348" y="272.112866" width="90.297007" height="50.434960" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="757.455604" y="400.878049" width="57.994627" height="84.575561" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(781.455348,287.712866) scale(0.595329)" transform="translate(765.455604,416.478049) scale(0.336495)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">connkeeper.go</text> data-math="N">connkeeper.go</text>
@ -749,31 +730,31 @@
<g> <g>
<rect x="871.752354" y="272.112866" width="26.025887" height="43.942187" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="757.455604" y="493.453609" width="50.661891" height="24.045386" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
</g>
<g>
<rect x="855.450231" y="283.704615" width="41.456349" height="39.898947" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(879.752354,287.712866) scale(0.094942)" transform="translate(863.450231,299.304615) scale(0.241064)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">settings.go</text> data-math="N">joiner32.go</text>
</g> </g>
<g> <g>
<rect x="790.515449" y="389.747826" width="70.535988" height="19.498944" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="855.450231" y="106.400000" width="107.398825" height="56.180708" style="fill: rgb(12, 128, 68);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
</g>
<g>
<rect x="570.560008" y="531.322319" width="102.658131" height="56.677681" style="fill: rgb(12, 128, 68);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(578.560008,546.922319) scale(0.820626)" transform="translate(863.450231,122.000000) scale(0.865519)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">database.go</text> data-math="N">database.go</text>
@ -781,12 +762,38 @@
<g> <g>
<rect x="262.249759" y="403.234043" width="118.537209" height="74.686930" style="fill: rgb(13, 130, 69);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="185.427064" y="128.000000" width="115.478333" height="58.200169" style="fill: rgb(4, 115, 61);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(270.249759,418.834043) scale(1.000000)" transform="translate(193.427064,143.600000) scale(1.000000)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">message.go</text>
</g>
<g>
<rect x="308.905397" y="128.000000" width="24.339563" height="52.181971" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text
data-notex="1"
text-anchor="start"
transform="translate(316.905397,143.600000) scale(0.078973)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">settings.go</text>
</g>
<g>
<rect x="60.000000" y="128.000000" width="101.427064" height="103.813314" style="fill: rgb(13, 130, 69);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text
data-notex="1"
text-anchor="start"
transform="translate(68.000000,143.600000) scale(0.988739)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">client.go</text> data-math="N">client.go</text>
@ -794,12 +801,25 @@
<g> <g>
<rect x="262.249759" y="515.520973" width="118.302880" height="64.479027" style="fill: rgb(157, 213, 105);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" /> <rect x="60.000000" y="239.813314" width="95.667745" height="31.341721" style="fill: rgb(0, 104, 55);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text <text
data-notex="1" data-notex="1"
text-anchor="start" text-anchor="start"
transform="translate(270.249759,531.120973) scale(1.000000)" transform="translate(68.000000,255.413314) scale(0.829872)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(255, 255, 255); fill-opacity: 1.00; white-space: pre;"
data-math="N">message.go</text>
</g>
<g>
<rect x="185.427064" y="223.800169" width="144.502622" height="47.354867" style="fill: rgb(127, 200, 101);opacity:1;fill-opacity:1.00;stroke:rgb(128,128,128);stroke-width:1px;stroke-opacity:1.00;" />
<text
data-notex="1"
text-anchor="start"
transform="translate(193.427064,239.400169) scale(1.000000)"
style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(0, 0, 0); fill-opacity: 1.00; white-space: pre;" style="font-family: Open Sans, verdana, arial, sans-serif !important; font-size: 12px; fill: rgb(0, 0, 0); fill-opacity: 1.00; white-space: pre;"
data-math="N">client.go</text> data-math="N">client.go</text>

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 31 KiB