Skip to content
Snippets Groups Projects
Commit 1d0be139 authored by Benjamin Wenger's avatar Benjamin Wenger
Browse files

removed context from health tracker and key exchange

delete globals, it was old
parent 5830e4f0
No related branches found
No related tags found
No related merge requests found
Showing
with 75 additions and 729 deletions
package context package context
import ( import (
"gitlab.com/elixxir/client/context/switchboard"
"gitlab.com/elixxir/client/storage" "gitlab.com/elixxir/client/storage"
"gitlab.com/elixxir/client/switchboard"
"gitlab.com/elixxir/crypto/fastRNG" "gitlab.com/elixxir/crypto/fastRNG"
) )
......
////////////////////////////////////////////////////////////////////////////////
// Copyright © 2019 Privategrity Corporation /
// /
// All rights reserved. /
////////////////////////////////////////////////////////////////////////////////
package globals
import (
jww "github.com/spf13/jwalterweatherman"
"io"
"io/ioutil"
"log"
"os"
)
// Log is logging everything to this notepad so that the CUI can replace it
// with its own notepad and get logging statements from the client
var Log = jww.NewNotepad(jww.LevelInfo, jww.LevelInfo, os.Stdout,
ioutil.Discard, "CLIENT", log.Ldate|log.Ltime)
// InitLog initializes logging thresholds and the log path.
// verbose turns on debug logging, setting the log path to nil
// uses std out.
func InitLog(verbose bool, logPath string) *jww.Notepad {
logLevel := jww.LevelInfo
logFlags := (log.Ldate | log.Ltime)
stdOut := io.Writer(os.Stdout)
logFile := ioutil.Discard
// If the verbose flag is set, print all logs and
// print microseconds as well
if verbose {
logLevel = jww.LevelDebug
logFlags = (log.Ldate | log.Ltime | log.Lmicroseconds)
}
// If the logpath is empty or not set to - (stdout),
// set up the log file and do not log to stdout
if logPath != "" && logPath != "-" {
// Create log file, overwrites if existing
lF, err := os.OpenFile(logPath,
os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
Log.WARN.Println("Invalid or missing log path," +
" stdout used.")
} else {
logFile = io.Writer(lF)
stdOut = ioutil.Discard
}
}
return jww.NewNotepad(logLevel, logLevel, stdOut, logFile,
"CLIENT", logFlags)
}
package globals
//Registration
const REG_KEYGEN = 1 //Generating Cryptographic Keys
const REG_PRECAN = 2 //Doing a Precanned Registration (Not Secure)
const REG_UID_GEN = 3 //Generating User ID
const REG_PERM = 4 //Validating User Identity With Permissioning Server
const REG_NODE = 5 //Registering with Nodes
const REG_FAIL = 6 //Failed to Register with Nodes
const REG_SECURE_STORE = 7 //Creating Local Secure Session
const REG_SAVE = 8 //Storing Session
//UDB registration
const UDB_REG_PUSHKEY = 9 //Pushing Cryptographic Material to the User Discovery Bot
const UDB_REG_PUSHUSER = 10 //Registering User with the User Discovery Bot
//UDB Search
const UDB_SEARCH_LOOK = 11 //Searching for User in User Discovery
const UDB_SEARCH_GETKEY = 12 //Getting Keying Material From User Discovery
const UDB_SEARCH_BUILD_CREDS = 13 //Building secure end to end relationship
////////////////////////////////////////////////////////////////////////////////
// Copyright © 2019 Privategrity Corporation /
// /
// All rights reserved. /
////////////////////////////////////////////////////////////////////////////////
package globals
import (
"os"
"sync"
)
const (
NoSave uint8 = iota
LocationA
LocationB
)
type Storage interface {
SetLocation(string, string) error
GetLocation() (string, string)
SaveA([]byte) error
SaveB([]byte) error
LoadA() []byte
LoadB() []byte
IsEmpty() bool
}
type DefaultStorage struct {
locationA string
locationB string
sync.Mutex
}
func (ds *DefaultStorage) SetLocation(locationA, locationB string) error {
ds.Lock()
ds.locationA = locationA
ds.locationB = locationB
ds.Unlock()
return nil
}
func (ds *DefaultStorage) GetLocation() (string, string) {
ds.Lock()
defer ds.Unlock()
return ds.locationA, ds.locationB
}
func (ds *DefaultStorage) IsEmpty() bool {
_, err := os.Stat(ds.locationA)
firstEmpty := err != nil && os.IsNotExist(err)
_, err = os.Stat(ds.locationB)
secondEmpty := err != nil && os.IsNotExist(err)
return firstEmpty && secondEmpty
}
func (ds *DefaultStorage) SaveA(data []byte) error {
return dsSaveHelper(ds.locationA, data)
}
func (ds *DefaultStorage) LoadA() []byte {
return dsLoadHelper(ds.locationA)
}
func (ds *DefaultStorage) SaveB(data []byte) error {
return dsSaveHelper(ds.locationB, data)
}
func (ds *DefaultStorage) LoadB() []byte {
return dsLoadHelper(ds.locationB)
}
type RamStorage struct {
DataA []byte
DataB []byte
}
func (rs *RamStorage) SetLocation(string, string) error {
return nil
}
func (rs *RamStorage) GetLocation() (string, string) {
return "", ""
}
func (rs *RamStorage) SaveA(data []byte) error {
rs.DataA = make([]byte, len(data))
copy(rs.DataA, data)
return nil
}
func (rs *RamStorage) SaveB(data []byte) error {
rs.DataB = make([]byte, len(data))
copy(rs.DataB, data)
return nil
}
func (rs *RamStorage) LoadA() []byte {
b := make([]byte, len(rs.DataA))
copy(b, rs.DataA)
return b
}
func (rs *RamStorage) LoadB() []byte {
b := make([]byte, len(rs.DataB))
copy(b, rs.DataB)
return b
}
func (rs *RamStorage) IsEmpty() bool {
return (rs.DataA == nil || len(rs.DataA) == 0) && (rs.DataB == nil || len(rs.DataB) == 0)
}
func dsLoadHelper(loc string) []byte {
// Check if the file exists, return nil if it does not
finfo, err1 := os.Stat(loc)
if err1 != nil {
Log.ERROR.Printf("Default Storage Load: Unknown Error Occurred on"+
" file check: \n %v", err1.Error())
return nil
}
b := make([]byte, finfo.Size())
// Open the file, return nil if it cannot be opened
f, err2 := os.Open(loc)
defer func() {
if f != nil {
f.Close()
} else {
Log.WARN.Println("Could not close file, file is nil")
}
}()
if err2 != nil {
Log.ERROR.Printf("Default Storage Load: Unknown Error Occurred on"+
" file open: \n %v", err2.Error())
return nil
}
// Read the data from the file, return nil if read fails
_, err3 := f.Read(b)
if err3 != nil {
Log.ERROR.Printf("Default Storage Load: Unknown Error Occurred on"+
" file read: \n %v", err3.Error())
return nil
}
return b
}
func dsSaveHelper(loc string, data []byte) error {
//check if the file exists, delete if it does
_, err1 := os.Stat(loc)
if err1 == nil {
errRmv := os.Remove(loc)
if errRmv != nil {
Log.WARN.Printf("Could not remove Storage File B: %s", errRmv)
}
} else if !os.IsNotExist(err1) {
Log.ERROR.Printf("Default Storage Save: Unknown Error Occurred on"+
" file check: \n %v",
err1.Error())
return err1
}
//create new file
f, err2 := os.Create(loc)
defer func() {
if f != nil {
f.Close()
} else {
Log.WARN.Println("Could not close file, file is nil")
}
}()
if err2 != nil {
Log.ERROR.Printf("Default Storage Save: Unknown Error Occurred on"+
" file creation: \n %v", err2.Error())
return err2
}
//Save to file
_, err3 := f.Write(data)
if err3 != nil {
Log.ERROR.Printf("Default Storage Save: Unknown Error Occurred on"+
" file write: \n %v", err3.Error())
return err3
}
return nil
}
////////////////////////////////////////////////////////////////////////////////
// Copyright © 2019 Privategrity Corporation /
// /
// All rights reserved. /
////////////////////////////////////////////////////////////////////////////////
package globals
import (
"os"
"reflect"
"testing"
)
func TestInitStorage(t *testing.T) {
TestDataA := []byte{12, 14, 54}
TestDataB := []byte{69, 42, 32}
TestSaveLocA := "testStorageA.data"
TestSaveLocB := "testStorageB.data"
// Test DefaultStorage initialization without existing storage
storage := &DefaultStorage{}
//Check that storage is empty prior to any Save calls
if !storage.IsEmpty() {
t.Errorf("ds.IsEmpty failed to detect an empty storage")
}
storage.SetLocation(TestSaveLocA, TestSaveLocB)
// Test DS saveA
err := storage.SaveA(TestDataA)
if err != nil {
t.Errorf("ds.Save failed to create a save file A at: %v",
TestSaveLocA)
}
// Check that save file was made
if !exists(TestSaveLocA) {
t.Errorf("ds.Save failed to create a save file A at: %v",
TestSaveLocA)
}
//Check that the storage is not empty after a saveA call
if storage.IsEmpty() {
t.Errorf("ds.IsEmpty failed to detect a non-empty storage")
}
// Test DS loadA
actualData := storage.LoadA()
if reflect.DeepEqual(actualData, TestDataA) != true {
t.Errorf("ds.Load failed to load expected data on A. Expected:%v Actual:%v",
TestDataA, actualData)
}
// Test DS saveB
err = storage.SaveB(TestDataB)
if err != nil {
t.Errorf("ds.Save failed to create a save file B at: %v",
TestSaveLocB)
}
// Check that save file was made
if !exists(TestSaveLocB) {
t.Errorf("ds.Save failed to create a save file B at: %v",
TestSaveLocB)
}
// Test DS loadA
actualData = storage.LoadB()
if reflect.DeepEqual(actualData, TestDataB) != true {
t.Errorf("ds.Load failed to load expected data on B. Expected:%v Actual:%v",
TestDataB, actualData)
}
// Test RamStorage
store := RamStorage{}
actualData = nil
// Test A
store.SaveA(TestDataA)
actualData = store.LoadA()
if reflect.DeepEqual(actualData, TestDataA) != true {
t.Errorf("rs.Load failed to load expected data A. Expected:%v Actual:%v",
TestDataA, actualData)
}
//Test B
store.SaveB(TestDataB)
actualData = store.LoadB()
if reflect.DeepEqual(actualData, TestDataB) != true {
t.Errorf("rs.Load failed to load expected data B. Expected:%v Actual:%v",
TestDataB, actualData)
}
os.Remove(TestSaveLocA)
os.Remove(TestSaveLocB)
}
// exists returns whether the given file or directory exists or not
func exists(path string) bool {
_, err := os.Stat(path)
if err == nil {
return true
}
if os.IsNotExist(err) {
return false
}
return true
}
func TestDefaultStorage_GetLocation(t *testing.T) {
locationA := "hi"
locationB := "hi2"
ds := DefaultStorage{locationA: locationA, locationB: locationB}
recievedLocA, recievedLocB := ds.GetLocation()
if recievedLocA != locationA {
t.Errorf("defaultStorage.GetLocation returned incorrect location A. Expected:%v Actual:%v",
locationA, recievedLocA)
}
if recievedLocB != locationB {
t.Errorf("defaultStorage.GetLocation returned incorrect location B. Expected:%v Actual:%v",
locationB, recievedLocB)
}
}
func TestRamStorage_GetLocation(t *testing.T) {
ds := RamStorage{}
a, b := ds.GetLocation()
if a != "" && b != "" {
t.Errorf("RamStorage.GetLocation returned incorrect location. Actual: '', ''; Expected:'%v','%v'",
a, b)
}
}
func Test_dsLoadHelper_LocError(t *testing.T) {
testLoc := "~a/test"
result := dsLoadHelper(testLoc)
if result != nil {
t.Errorf("dsLoadHelper() did not error on invalid path.")
}
}
////////////////////////////////////////////////////////////////////////////////
// Copyright © 2019 Privategrity Corporation /
// /
// All rights reserved. /
////////////////////////////////////////////////////////////////////////////////
package globals
import (
"time"
)
type ThreadTerminator chan chan bool
func NewThreadTerminator() ThreadTerminator {
t := make(chan chan bool, 1)
return t
}
func (t ThreadTerminator) Terminate() {
t <- nil
}
// Try's to kill a thread controlled by a termination channel for the length of
// the timeout, returns its success. pass 0 for no timeout
func (t ThreadTerminator) BlockingTerminate(timeout uint64) bool {
killNotify := make(chan bool)
defer close(killNotify)
if timeout != 0 {
timer := time.NewTimer(time.Duration(timeout) * time.Millisecond)
defer timer.Stop()
t <- killNotify
select {
case _ = <-killNotify:
return true
case <-timer.C:
return false
}
} else {
_ = <-killNotify
return true
}
}
////////////////////////////////////////////////////////////////////////////////
// Copyright © 2019 Privategrity Corporation /
// /
// All rights reserved. /
////////////////////////////////////////////////////////////////////////////////
package globals
import (
"testing"
"time"
)
func TestNewThreadTerminator(t *testing.T) {
term := NewThreadTerminator()
var success bool
go func(term ThreadTerminator) {
term <- nil
}(term)
timer := time.NewTimer(time.Duration(1000) * time.Millisecond)
defer timer.Stop()
select {
case _ = <-term:
success = true
case <-timer.C:
success = false
}
if !success {
t.Errorf("NewThreadTerminator: Could not use the ThreadTerminator to" +
" stop a thread")
}
}
func TestBlockingTerminate(t *testing.T) {
term := NewThreadTerminator()
go func(term ThreadTerminator) {
var killNotify chan<- bool
q := false
for !q {
select {
case killNotify = <-term:
q = true
}
close(term)
killNotify <- true
}
}(term)
success := term.BlockingTerminate(1000)
if !success {
t.Errorf("BlockingTerminate: Thread did not terminate in time")
}
}
// Code generated by go generate; DO NOT EDIT.
// This file was generated by robots at
// 2020-08-10 10:05:18.2662998 -0700 PDT m=+0.116012701
package globals
const GITVERSION = `127a946 Merge branch 'XX-2415/NodeKeys' into 'Optimus/ClientStorage'`
const SEMVER = "1.4.0"
const DEPENDENCIES = `module gitlab.com/elixxir/client
go 1.13
require (
github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3
github.com/golang/protobuf v1.4.2
github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00 // indirect
github.com/pelletier/go-toml v1.6.0 // indirect
github.com/pkg/errors v0.9.1
github.com/smartystreets/assertions v1.0.1 // indirect
github.com/spf13/afero v1.2.2 // indirect
github.com/spf13/cast v1.3.1 // indirect
github.com/spf13/cobra v1.0.0
github.com/spf13/jwalterweatherman v1.1.0
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.6.2
gitlab.com/elixxir/comms v0.0.0-20200805174832-240bba97beaa
gitlab.com/elixxir/crypto v0.0.0-20200805174804-bdf909f2a16d
gitlab.com/elixxir/ekv v0.1.1
gitlab.com/elixxir/primitives v0.0.0-20200805174810-86b366d1dd2d
gitlab.com/xx_network/comms v0.0.0-20200805174823-841427dd5023
gitlab.com/xx_network/primitives v0.0.0-20200804183002-f99f7a7284da
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de
golang.org/x/sys v0.0.0-20200806125547-5acd03effb82 // indirect
gopkg.in/ini.v1 v1.52.0 // indirect
)
replace google.golang.org/grpc => github.com/grpc/grpc-go v1.27.1
`
...@@ -10,7 +10,6 @@ package health ...@@ -10,7 +10,6 @@ package health
import ( import (
jww "github.com/spf13/jwalterweatherman" jww "github.com/spf13/jwalterweatherman"
"gitlab.com/elixxir/client/context"
"gitlab.com/elixxir/client/context/stoppable" "gitlab.com/elixxir/client/context/stoppable"
"gitlab.com/elixxir/comms/network" "gitlab.com/elixxir/comms/network"
"sync" "sync"
...@@ -32,10 +31,10 @@ type Tracker struct { ...@@ -32,10 +31,10 @@ type Tracker struct {
} }
// Creates a single HealthTracker thread, starts it, and returns a tracker and a stoppable // Creates a single HealthTracker thread, starts it, and returns a tracker and a stoppable
func Init(ctx *context.Context, timeout time.Duration) *Tracker { func Init(instance *network.Instance, timeout time.Duration) *Tracker {
tracker := newTracker(timeout) tracker := newTracker(timeout)
ctx.Manager.GetInstance().SetNetworkHealthChan(tracker.heartbeat) instance.SetNetworkHealthChan(tracker.heartbeat)
return tracker return tracker
} }
......
...@@ -40,5 +40,4 @@ func TestNewTracker(t *testing.T) { ...@@ -40,5 +40,4 @@ func TestNewTracker(t *testing.T) {
quit := make(chan struct{}) quit := make(chan struct{})
go tracker.start(quit) go tracker.start(quit)
} }
package internal package internal
import ( import (
"gitlab.com/elixxir/client/context"
"gitlab.com/elixxir/client/network/health" "gitlab.com/elixxir/client/network/health"
"gitlab.com/elixxir/client/storage"
"gitlab.com/elixxir/client/switchboard"
"gitlab.com/elixxir/comms/client" "gitlab.com/elixxir/comms/client"
"gitlab.com/elixxir/comms/network" "gitlab.com/elixxir/comms/network"
"gitlab.com/elixxir/crypto/fastRNG"
"gitlab.com/xx_network/primitives/id" "gitlab.com/xx_network/primitives/id"
) )
type Internal struct { type Internal struct {
*context.Context Session *storage.Session
Switchboard *switchboard.Switchboard
//generic RNG for client
Rng *fastRNG.StreamGenerator
// Comms pointer to send/recv messages // Comms pointer to send/recv messages
Comms *client.Comms Comms *client.Comms
......
...@@ -4,25 +4,25 @@ import ( ...@@ -4,25 +4,25 @@ import (
"github.com/golang/protobuf/proto" "github.com/golang/protobuf/proto"
"github.com/pkg/errors" "github.com/pkg/errors"
jww "github.com/spf13/jwalterweatherman" jww "github.com/spf13/jwalterweatherman"
"gitlab.com/elixxir/client/context"
"gitlab.com/elixxir/client/context/message" "gitlab.com/elixxir/client/context/message"
"gitlab.com/elixxir/client/context/stoppable" "gitlab.com/elixxir/client/context/stoppable"
"gitlab.com/elixxir/client/storage"
"gitlab.com/elixxir/client/storage/e2e" "gitlab.com/elixxir/client/storage/e2e"
) )
func startConfirm(ctx *context.Context, c chan message.Receive, func startConfirm(sess *storage.Session, c chan message.Receive,
stop *stoppable.Single) { stop *stoppable.Single) {
for true { for true {
select { select {
case <-stop.Quit(): case <-stop.Quit():
return return
case confirmation := <-c: case confirmation := <-c:
handleConfirm(ctx, confirmation) handleConfirm(sess, confirmation)
} }
} }
} }
func handleConfirm(ctx *context.Context, confirmation message.Receive) { func handleConfirm(sess *storage.Session, confirmation message.Receive) {
//ensure the message was encrypted properly //ensure the message was encrypted properly
if confirmation.Encryption != message.E2E { if confirmation.Encryption != message.E2E {
jww.ERROR.Printf("Received non-e2e encrypted Key Exchange "+ jww.ERROR.Printf("Received non-e2e encrypted Key Exchange "+
...@@ -31,7 +31,7 @@ func handleConfirm(ctx *context.Context, confirmation message.Receive) { ...@@ -31,7 +31,7 @@ func handleConfirm(ctx *context.Context, confirmation message.Receive) {
} }
//Get the partner //Get the partner
partner, err := ctx.Session.E2e().GetPartner(confirmation.Sender) partner, err := sess.E2e().GetPartner(confirmation.Sender)
if err != nil { if err != nil {
jww.ERROR.Printf("Received Key Exchange Confirmation with unknown "+ jww.ERROR.Printf("Received Key Exchange Confirmation with unknown "+
"partner %s", confirmation.Sender) "partner %s", confirmation.Sender)
......
...@@ -4,6 +4,8 @@ import ( ...@@ -4,6 +4,8 @@ import (
"gitlab.com/elixxir/client/context" "gitlab.com/elixxir/client/context"
"gitlab.com/elixxir/client/context/message" "gitlab.com/elixxir/client/context/message"
"gitlab.com/elixxir/client/context/stoppable" "gitlab.com/elixxir/client/context/stoppable"
"gitlab.com/elixxir/client/storage"
"gitlab.com/elixxir/client/switchboard"
"gitlab.com/xx_network/primitives/id" "gitlab.com/xx_network/primitives/id"
"time" "time"
) )
...@@ -12,39 +14,40 @@ const keyExchangeTriggerName = "KeyExchangeTrigger" ...@@ -12,39 +14,40 @@ const keyExchangeTriggerName = "KeyExchangeTrigger"
const keyExchangeConfirmName = "KeyExchangeConfirm" const keyExchangeConfirmName = "KeyExchangeConfirm"
const keyExchangeMulti = "KeyExchange" const keyExchangeMulti = "KeyExchange"
func Start(ctx *context.Context, garbledMessageTrigger chan<- struct{}) stoppable.Stoppable { func Start(switchboard *switchboard.Switchboard, sess *storage.Session,
net context.NetworkManager, garbledMessageTrigger chan<- struct{}) stoppable.Stoppable {
// register the rekey trigger thread // register the rekey trigger thread
triggerCh := make(chan message.Receive, 100) triggerCh := make(chan message.Receive, 100)
triggerID := ctx.Switchboard.RegisterChannel(keyExchangeTriggerName, triggerID := switchboard.RegisterChannel(keyExchangeTriggerName,
&id.ID{}, message.KeyExchangeTrigger, triggerCh) &id.ID{}, message.KeyExchangeTrigger, triggerCh)
// create the trigger stoppable // create the trigger stoppable
triggerStop := stoppable.NewSingle(keyExchangeTriggerName) triggerStop := stoppable.NewSingle(keyExchangeTriggerName)
triggerStopCleanup := stoppable.NewCleanup(triggerStop, triggerStopCleanup := stoppable.NewCleanup(triggerStop,
func(duration time.Duration) error { func(duration time.Duration) error {
ctx.Switchboard.Unregister(triggerID) switchboard.Unregister(triggerID)
return nil return nil
}) })
// start the trigger thread // start the trigger thread
go startTrigger(ctx, triggerCh, triggerStop, garbledMessageTrigger) go startTrigger(sess, net, triggerCh, triggerStop, garbledMessageTrigger)
//register the rekey confirm thread //register the rekey confirm thread
confirmCh := make(chan message.Receive, 100) confirmCh := make(chan message.Receive, 100)
confirmID := ctx.Switchboard.RegisterChannel(keyExchangeConfirmName, confirmID := switchboard.RegisterChannel(keyExchangeConfirmName,
&id.ID{}, message.KeyExchangeConfirm, confirmCh) &id.ID{}, message.KeyExchangeConfirm, confirmCh)
// register the confirm stoppable // register the confirm stoppable
confirmStop := stoppable.NewSingle(keyExchangeConfirmName) confirmStop := stoppable.NewSingle(keyExchangeConfirmName)
confirmStopCleanup := stoppable.NewCleanup(confirmStop, confirmStopCleanup := stoppable.NewCleanup(confirmStop,
func(duration time.Duration) error { func(duration time.Duration) error {
ctx.Switchboard.Unregister(confirmID) switchboard.Unregister(confirmID)
return nil return nil
}) })
// start the confirm thread // start the confirm thread
go startConfirm(ctx, confirmCh, confirmStop) go startConfirm(sess, confirmCh, confirmStop)
//bundle the stoppables and return //bundle the stoppables and return
exchangeStop := stoppable.NewMulti(keyExchangeMulti) exchangeStop := stoppable.NewMulti(keyExchangeMulti)
......
...@@ -10,21 +10,25 @@ import ( ...@@ -10,21 +10,25 @@ import (
"github.com/golang/protobuf/proto" "github.com/golang/protobuf/proto"
"github.com/pkg/errors" "github.com/pkg/errors"
jww "github.com/spf13/jwalterweatherman" jww "github.com/spf13/jwalterweatherman"
"gitlab.com/elixxir/client/context"
"gitlab.com/elixxir/client/context/message" "gitlab.com/elixxir/client/context/message"
"gitlab.com/elixxir/client/context/params" "gitlab.com/elixxir/client/context/params"
"gitlab.com/elixxir/client/context/utility" "gitlab.com/elixxir/client/context/utility"
"gitlab.com/elixxir/client/storage"
"gitlab.com/elixxir/client/storage/e2e" "gitlab.com/elixxir/client/storage/e2e"
"gitlab.com/elixxir/comms/network"
ds "gitlab.com/elixxir/comms/network/dataStructures" ds "gitlab.com/elixxir/comms/network/dataStructures"
"gitlab.com/elixxir/crypto/diffieHellman" "gitlab.com/elixxir/crypto/diffieHellman"
"gitlab.com/elixxir/primitives/states" "gitlab.com/elixxir/primitives/states"
"gitlab.com/xx_network/primitives/id"
"time" "time"
) )
func CheckKeyExchanges(ctx *context.Context, manager *e2e.Manager) { type SendE2E func(msg message.Send, param params.E2E) ([]id.Round, error)
func CheckKeyExchanges(instance *network.Instance, sendE2E SendE2E, sess *storage.Session, manager *e2e.Manager) {
sessions := manager.TriggerNegotiations() sessions := manager.TriggerNegotiations()
for _, ses := range sessions { for _, session := range sessions {
go trigger(ctx, manager, ses) go trigger(instance, sendE2E, sess, manager, session)
} }
} }
...@@ -32,7 +36,7 @@ func CheckKeyExchanges(ctx *context.Context, manager *e2e.Manager) { ...@@ -32,7 +36,7 @@ func CheckKeyExchanges(ctx *context.Context, manager *e2e.Manager) {
// session and negotiation, or resenting a negotiation for an already created // session and negotiation, or resenting a negotiation for an already created
// session. They run the same negotiation, the former does it on a newly created // session. They run the same negotiation, the former does it on a newly created
// session while the latter on an extand // session while the latter on an extand
func trigger(ctx *context.Context, manager *e2e.Manager, session *e2e.Session) { func trigger(instance *network.Instance, sendE2E SendE2E, sess *storage.Session, manager *e2e.Manager, session *e2e.Session) {
var negotiatingSession *e2e.Session var negotiatingSession *e2e.Session
switch session.NegotiationStatus() { switch session.NegotiationStatus() {
// If the passed session is triggering a negotiation on a new session to // If the passed session is triggering a negotiation on a new session to
...@@ -52,7 +56,7 @@ func trigger(ctx *context.Context, manager *e2e.Manager, session *e2e.Session) { ...@@ -52,7 +56,7 @@ func trigger(ctx *context.Context, manager *e2e.Manager, session *e2e.Session) {
} }
// send the rekey notification to the partner // send the rekey notification to the partner
err := negotiate(ctx, negotiatingSession) err := negotiate(instance, sendE2E, sess, negotiatingSession)
// if sending the negotiation fails, revert the state of the session to // if sending the negotiation fails, revert the state of the session to
// unconfirmed so it will be triggered in the future // unconfirmed so it will be triggered in the future
if err != nil { if err != nil {
...@@ -61,8 +65,8 @@ func trigger(ctx *context.Context, manager *e2e.Manager, session *e2e.Session) { ...@@ -61,8 +65,8 @@ func trigger(ctx *context.Context, manager *e2e.Manager, session *e2e.Session) {
} }
} }
func negotiate(ctx *context.Context, session *e2e.Session) error { func negotiate(instance *network.Instance, sendE2E SendE2E, sess *storage.Session, session *e2e.Session) error {
e2eStore := ctx.Session.E2e() e2eStore := sess.E2e()
//generate public key //generate public key
pubKey := diffieHellman.GeneratePublicKey(session.GetMyPrivKey(), pubKey := diffieHellman.GeneratePublicKey(session.GetMyPrivKey(),
...@@ -91,7 +95,7 @@ func negotiate(ctx *context.Context, session *e2e.Session) error { ...@@ -91,7 +95,7 @@ func negotiate(ctx *context.Context, session *e2e.Session) error {
e2eParams := params.GetDefaultE2E() e2eParams := params.GetDefaultE2E()
e2eParams.Type = params.KeyExchange e2eParams.Type = params.KeyExchange
rounds, err := ctx.Manager.SendE2E(m, e2eParams) rounds, err := sendE2E(m, e2eParams)
// If the send fails, returns the error so it can be handled. The caller // If the send fails, returns the error so it can be handled. The caller
// should ensure the calling session is in a state where the Rekey will // should ensure the calling session is in a state where the Rekey will
// be triggered next time a key is used // be triggered next time a key is used
...@@ -104,7 +108,7 @@ func negotiate(ctx *context.Context, session *e2e.Session) error { ...@@ -104,7 +108,7 @@ func negotiate(ctx *context.Context, session *e2e.Session) error {
sendResults := make(chan ds.EventReturn, len(rounds)) sendResults := make(chan ds.EventReturn, len(rounds))
//Register the event for all rounds //Register the event for all rounds
roundEvents := ctx.Manager.GetInstance().GetRoundEvents() roundEvents := instance.GetRoundEvents()
for _, r := range rounds { for _, r := range rounds {
roundEvents.AddRoundEventChan(r, sendResults, 1*time.Minute, roundEvents.AddRoundEventChan(r, sendResults, 1*time.Minute,
states.COMPLETED, states.FAILED) states.COMPLETED, states.FAILED)
......
...@@ -10,6 +10,7 @@ import ( ...@@ -10,6 +10,7 @@ import (
"gitlab.com/elixxir/client/context/params" "gitlab.com/elixxir/client/context/params"
"gitlab.com/elixxir/client/context/stoppable" "gitlab.com/elixxir/client/context/stoppable"
"gitlab.com/elixxir/client/context/utility" "gitlab.com/elixxir/client/context/utility"
"gitlab.com/elixxir/client/storage"
"gitlab.com/elixxir/client/storage/e2e" "gitlab.com/elixxir/client/storage/e2e"
ds "gitlab.com/elixxir/comms/network/dataStructures" ds "gitlab.com/elixxir/comms/network/dataStructures"
"gitlab.com/elixxir/crypto/cyclic" "gitlab.com/elixxir/crypto/cyclic"
...@@ -22,14 +23,14 @@ const ( ...@@ -22,14 +23,14 @@ const (
errUnknown = "unknown trigger from partner %s" errUnknown = "unknown trigger from partner %s"
) )
func startTrigger(ctx *context.Context, c chan message.Receive, func startTrigger(sess *storage.Session, net context.NetworkManager, c chan message.Receive,
stop *stoppable.Single, garbledMessageTrigger chan<- struct{}) { stop *stoppable.Single, garbledMessageTrigger chan<- struct{}) {
for true { for true {
select { select {
case <-stop.Quit(): case <-stop.Quit():
return return
case request := <-c: case request := <-c:
err := handleTrigger(ctx, request, garbledMessageTrigger) err := handleTrigger(sess, net, request, garbledMessageTrigger)
if err != nil { if err != nil {
jww.ERROR.Printf("Failed to handle rekey trigger: %s", jww.ERROR.Printf("Failed to handle rekey trigger: %s",
err) err)
...@@ -38,7 +39,7 @@ func startTrigger(ctx *context.Context, c chan message.Receive, ...@@ -38,7 +39,7 @@ func startTrigger(ctx *context.Context, c chan message.Receive,
} }
} }
func handleTrigger(ctx *context.Context, request message.Receive, func handleTrigger(sess *storage.Session, net context.NetworkManager, request message.Receive,
garbledMessageTrigger chan<- struct{}) error { garbledMessageTrigger chan<- struct{}) error {
//ensure the message was encrypted properly //ensure the message was encrypted properly
if request.Encryption != message.E2E { if request.Encryption != message.E2E {
...@@ -48,7 +49,7 @@ func handleTrigger(ctx *context.Context, request message.Receive, ...@@ -48,7 +49,7 @@ func handleTrigger(ctx *context.Context, request message.Receive,
} }
//Get the partner //Get the partner
partner, err := ctx.Session.E2e().GetPartner(request.Sender) partner, err := sess.E2e().GetPartner(request.Sender)
if err != nil { if err != nil {
errMsg := fmt.Sprintf(errUnknown, request.Sender) errMsg := fmt.Sprintf(errUnknown, request.Sender)
jww.ERROR.Printf(errMsg) jww.ERROR.Printf(errMsg)
...@@ -57,7 +58,7 @@ func handleTrigger(ctx *context.Context, request message.Receive, ...@@ -57,7 +58,7 @@ func handleTrigger(ctx *context.Context, request message.Receive,
//unmarshal the message //unmarshal the message
oldSessionID, PartnerPublicKey, err := unmarshalSource( oldSessionID, PartnerPublicKey, err := unmarshalSource(
ctx.Session.E2e().GetGroup(), request.Payload) sess.E2e().GetGroup(), request.Payload)
if err != nil { if err != nil {
jww.ERROR.Printf("could not unmarshal partner %s: %s", jww.ERROR.Printf("could not unmarshal partner %s: %s",
request.Sender, err) request.Sender, err)
...@@ -117,13 +118,13 @@ func handleTrigger(ctx *context.Context, request message.Receive, ...@@ -117,13 +118,13 @@ func handleTrigger(ctx *context.Context, request message.Receive,
// store in critical messages buffer first to ensure it is resent if the // store in critical messages buffer first to ensure it is resent if the
// send fails // send fails
ctx.Session.GetCriticalMessages().AddProcessing(m, e2eParams) sess.GetCriticalMessages().AddProcessing(m, e2eParams)
rounds, err := ctx.Manager.SendE2E(m, e2eParams) rounds, err := net.SendE2E(m, e2eParams)
//Register the event for all rounds //Register the event for all rounds
sendResults := make(chan ds.EventReturn, len(rounds)) sendResults := make(chan ds.EventReturn, len(rounds))
roundEvents := ctx.Manager.GetInstance().GetRoundEvents() roundEvents := net.GetInstance().GetRoundEvents()
for _, r := range rounds { for _, r := range rounds {
roundEvents.AddRoundEventChan(r, sendResults, 1*time.Minute, roundEvents.AddRoundEventChan(r, sendResults, 1*time.Minute,
states.COMPLETED, states.FAILED) states.COMPLETED, states.FAILED)
...@@ -140,13 +141,13 @@ func handleTrigger(ctx *context.Context, request message.Receive, ...@@ -140,13 +141,13 @@ func handleTrigger(ctx *context.Context, request message.Receive,
"transmit %v/%v paritions: %v round failures, %v timeouts", "transmit %v/%v paritions: %v round failures, %v timeouts",
session, numRoundFail+numTimeOut, len(rounds), numRoundFail, session, numRoundFail+numTimeOut, len(rounds), numRoundFail,
numTimeOut) numTimeOut)
ctx.Session.GetCriticalMessages().Failed(m) sess.GetCriticalMessages().Failed(m)
return nil return nil
} }
// otherwise, the transmission is a success and this should be denoted // otherwise, the transmission is a success and this should be denoted
// in the session and the log // in the session and the log
ctx.Session.GetCriticalMessages().Succeeded(m) sess.GetCriticalMessages().Succeeded(m)
jww.INFO.Printf("Key Negotiation transmission for %s sucesfull", jww.INFO.Printf("Key Negotiation transmission for %s sucesfull",
session) session)
......
...@@ -21,8 +21,11 @@ import ( ...@@ -21,8 +21,11 @@ import (
"gitlab.com/elixxir/client/network/node" "gitlab.com/elixxir/client/network/node"
"gitlab.com/elixxir/client/network/permissioning" "gitlab.com/elixxir/client/network/permissioning"
"gitlab.com/elixxir/client/network/rounds" "gitlab.com/elixxir/client/network/rounds"
"gitlab.com/elixxir/client/storage"
"gitlab.com/elixxir/client/switchboard"
"gitlab.com/elixxir/comms/client" "gitlab.com/elixxir/comms/client"
"gitlab.com/elixxir/comms/network" "gitlab.com/elixxir/comms/network"
"gitlab.com/elixxir/crypto/fastRNG"
"gitlab.com/xx_network/crypto/signature/rsa" "gitlab.com/xx_network/crypto/signature/rsa"
"gitlab.com/xx_network/primitives/id" "gitlab.com/xx_network/primitives/id"
"gitlab.com/xx_network/primitives/ndf" "gitlab.com/xx_network/primitives/ndf"
...@@ -49,25 +52,11 @@ type manager struct { ...@@ -49,25 +52,11 @@ type manager struct {
} }
// NewManager builds a new reception manager object using inputted key fields // NewManager builds a new reception manager object using inputted key fields
func NewManager(ctx *context.Context, params params.Network, ndf *ndf.NetworkDefinition) (context.NetworkManager, error) { func NewManager(session *storage.Session, switchboard *switchboard.Switchboard,
rng *fastRNG.StreamGenerator, comms *client.Comms,
//get the user from storage params params.Network, ndf *ndf.NetworkDefinition) (context.NetworkManager, error) {
user := ctx.Session.User()
cryptoUser := user.GetCryptographicIdentity()
//start comms
comms, err := client.NewClientComms(cryptoUser.GetUserID(),
rsa.CreatePublicKeyPem(cryptoUser.GetRSA().GetPublic()),
rsa.CreatePrivateKeyPem(cryptoUser.GetRSA()),
cryptoUser.GetSalt())
if err != nil {
return nil, errors.WithMessage(err, "failed to create"+
" client network manager")
}
//start network instance //start network instance
// TODO: Need to parse/retrieve the ntework string and load it
// from the context storage session!
instance, err := network.NewInstance(comms.ProtoComms, ndf, nil, nil) instance, err := network.NewInstance(comms.ProtoComms, ndf, nil, nil)
if err != nil { if err != nil {
return nil, errors.WithMessage(err, "failed to create"+ return nil, errors.WithMessage(err, "failed to create"+
...@@ -81,14 +70,16 @@ func NewManager(ctx *context.Context, params params.Network, ndf *ndf.NetworkDef ...@@ -81,14 +70,16 @@ func NewManager(ctx *context.Context, params params.Network, ndf *ndf.NetworkDef
} }
m.Internal = internal.Internal{ m.Internal = internal.Internal{
Session: session,
Switchboard: switchboard,
Rng: rng,
Comms: comms, Comms: comms,
Health: health.Init(ctx, 5*time.Second), Health: health.Init(instance, 5*time.Second),
NodeRegistration: make(chan network.NodeGateway, params.RegNodesBufferLen), NodeRegistration: make(chan network.NodeGateway, params.RegNodesBufferLen),
Instance: instance, Instance: instance,
Uid: session.User().GetCryptographicIdentity().GetUserID(),
} }
m.Internal.Context = ctx
//create sub managers //create sub managers
m.message = message.NewManager(m.Internal, m.param.Messages, m.NodeRegistration) m.message = message.NewManager(m.Internal, m.param.Messages, m.NodeRegistration)
m.round = rounds.NewManager(m.Internal, m.param.Rounds, m.message.GetMessageReceptionChannel()) m.round = rounds.NewManager(m.Internal, m.param.Rounds, m.message.GetMessageReceptionChannel())
......
...@@ -72,7 +72,7 @@ func (m *Manager) SendE2E(msg message.Send, param params.E2E) ([]id.Round, error ...@@ -72,7 +72,7 @@ func (m *Manager) SendE2E(msg message.Send, param params.E2E) ([]id.Round, error
// while waiting check if any rekeys need to happen and trigger them. This // while waiting check if any rekeys need to happen and trigger them. This
// can happen now because the key popping happens in this thread, // can happen now because the key popping happens in this thread,
// only the sending is parallelized // only the sending is parallelized
keyExchange.CheckKeyExchanges(m.Context, partner) keyExchange.CheckKeyExchanges(m.Instance, m.SendE2E, m.Session, partner)
wg.Wait() wg.Wait()
......
...@@ -8,14 +8,15 @@ import ( ...@@ -8,14 +8,15 @@ import (
"fmt" "fmt"
"github.com/pkg/errors" "github.com/pkg/errors"
jww "github.com/spf13/jwalterweatherman" jww "github.com/spf13/jwalterweatherman"
"gitlab.com/elixxir/client/context"
"gitlab.com/elixxir/client/context/stoppable" "gitlab.com/elixxir/client/context/stoppable"
"gitlab.com/elixxir/client/storage"
"gitlab.com/elixxir/client/storage/cmix" "gitlab.com/elixxir/client/storage/cmix"
"gitlab.com/elixxir/client/storage/user" "gitlab.com/elixxir/client/storage/user"
pb "gitlab.com/elixxir/comms/mixmessages" pb "gitlab.com/elixxir/comms/mixmessages"
"gitlab.com/elixxir/comms/network" "gitlab.com/elixxir/comms/network"
"gitlab.com/elixxir/crypto/csprng" "gitlab.com/elixxir/crypto/csprng"
"gitlab.com/elixxir/crypto/cyclic" "gitlab.com/elixxir/crypto/cyclic"
"gitlab.com/elixxir/crypto/fastRNG"
"gitlab.com/elixxir/crypto/hash" "gitlab.com/elixxir/crypto/hash"
"gitlab.com/elixxir/crypto/registration" "gitlab.com/elixxir/crypto/registration"
"gitlab.com/xx_network/comms/connect" "gitlab.com/xx_network/comms/connect"
...@@ -33,26 +34,25 @@ type RegisterNodeCommsInterface interface { ...@@ -33,26 +34,25 @@ type RegisterNodeCommsInterface interface {
message *pb.RequestRegistrationConfirmation) (*pb.RegistrationConfirmation, error) message *pb.RequestRegistrationConfirmation) (*pb.RegistrationConfirmation, error)
} }
func StartRegistration(ctx *context.Context, comms RegisterNodeCommsInterface, func StartRegistration(instance *network.Instance, session *storage.Session, rngGen *fastRNG.StreamGenerator, comms RegisterNodeCommsInterface,
c chan network.NodeGateway) stoppable.Stoppable { c chan network.NodeGateway) stoppable.Stoppable {
stop := stoppable.NewSingle("NodeRegistration") stop := stoppable.NewSingle("NodeRegistration")
instance := ctx.Manager.GetInstance()
instance.SetAddGatewayChan(c) instance.SetAddGatewayChan(c)
go registerNodes(ctx, comms, stop, c) go registerNodes(session, rngGen, comms, stop, c)
return stop return stop
} }
func registerNodes(ctx *context.Context, comms RegisterNodeCommsInterface, func registerNodes(session *storage.Session, rngGen *fastRNG.StreamGenerator, comms RegisterNodeCommsInterface,
stop *stoppable.Single, c chan network.NodeGateway) { stop *stoppable.Single, c chan network.NodeGateway) {
u := ctx.Session.User() u := session.User()
regSignature := u.GetRegistrationValidationSignature() regSignature := u.GetRegistrationValidationSignature()
uci := u.GetCryptographicIdentity() uci := u.GetCryptographicIdentity()
cmix := ctx.Session.Cmix() cmix := session.Cmix()
rng := ctx.Rng.GetStream() rng := rngGen.GetStream()
interval := time.Duration(500) * time.Millisecond interval := time.Duration(500) * time.Millisecond
t := time.NewTicker(interval) t := time.NewTicker(interval)
for true { for true {
......
...@@ -2,16 +2,12 @@ package node ...@@ -2,16 +2,12 @@ package node
import ( import (
"crypto/rand" "crypto/rand"
"gitlab.com/elixxir/client/context"
"gitlab.com/elixxir/client/context/message"
"gitlab.com/elixxir/client/context/params"
"gitlab.com/elixxir/client/context/stoppable" "gitlab.com/elixxir/client/context/stoppable"
"gitlab.com/elixxir/client/storage" "gitlab.com/elixxir/client/storage"
pb "gitlab.com/elixxir/comms/mixmessages" pb "gitlab.com/elixxir/comms/mixmessages"
"gitlab.com/elixxir/comms/network" "gitlab.com/elixxir/comms/network"
"gitlab.com/elixxir/crypto/csprng" "gitlab.com/elixxir/crypto/csprng"
"gitlab.com/elixxir/crypto/fastRNG" "gitlab.com/elixxir/crypto/fastRNG"
"gitlab.com/elixxir/primitives/format"
"gitlab.com/xx_network/comms/connect" "gitlab.com/xx_network/comms/connect"
"gitlab.com/xx_network/crypto/signature/rsa" "gitlab.com/xx_network/crypto/signature/rsa"
"gitlab.com/xx_network/primitives/id" "gitlab.com/xx_network/primitives/id"
...@@ -20,39 +16,6 @@ import ( ...@@ -20,39 +16,6 @@ import (
"time" "time"
) )
// Mock network manager for
type MockNetworkManager struct {
instance *network.Instance
}
func (nm *MockNetworkManager) SendE2E(m message.Send, p params.E2E) ([]id.Round, error) {
return nil, nil
}
func (nm *MockNetworkManager) SendUnsafe(m message.Send, p params.Unsafe) ([]id.Round, error) {
return nil, nil
}
func (nm *MockNetworkManager) SendCMIX(message format.Message, p params.CMIX) (id.Round, error) {
return id.Round(0), nil
}
func (nm *MockNetworkManager) GetInstance() *network.Instance {
return nm.instance
}
func (nm *MockNetworkManager) GetHealthTracker() context.HealthTracker {
return nil
}
func (nm *MockNetworkManager) GetRemoteVersion() (string, error) {
return "", nil
}
func (nm *MockNetworkManager) GetStoppable() stoppable.Stoppable {
return nil
}
func (nm *MockNetworkManager) RegisterWithPermissioning(string) ([]byte, error) {
return nil, nil
}
// Mock client comms object // Mock client comms object
type MockClientComms struct { type MockClientComms struct {
request chan bool request chan bool
...@@ -104,28 +67,19 @@ func TestRegisterNodes(t *testing.T) { ...@@ -104,28 +67,19 @@ func TestRegisterNodes(t *testing.T) {
//uid := id.NewIdFromString("zezima", id.User, t) //uid := id.NewIdFromString("zezima", id.User, t)
comms := NewMockClientComms() comms := NewMockClientComms()
def := getNDF()
instanceComms := &connect.ProtoComms{} instanceComms := &connect.ProtoComms{}
_, err = instanceComms.AddHost(&id.Permissioning, "0.0.0.0:420", []byte(pub), false, false) _, err = instanceComms.AddHost(&id.Permissioning, "0.0.0.0:420", []byte(pub), false, false)
if err != nil { if err != nil {
t.Errorf("Faield to add perm host: %+v", err) t.Errorf("Faield to add perm host: %+v", err)
} }
instance, err := network.NewInstanceTesting(instanceComms, def, def, nil, nil, t)
if err != nil {
t.Errorf("Failed to init test instance: %+v", err)
}
sess := storage.InitTestingSession(t) sess := storage.InitTestingSession(t)
ctx := context.Context{
Manager: &MockNetworkManager{ rng := fastRNG.NewStreamGenerator(7, 3, csprng.NewSystemRNG)
instance: instance,
},
Session: sess,
Rng: fastRNG.NewStreamGenerator(7, 3, csprng.NewSystemRNG),
}
stop := stoppable.NewSingle("test") stop := stoppable.NewSingle("test")
c := make(chan network.NodeGateway, 100) c := make(chan network.NodeGateway, 100)
go registerNodes(&ctx, comms, stop, c) go registerNodes(sess, rng, comms, stop, c)
c <- network.NodeGateway{ c <- network.NodeGateway{
Node: ndf.Node{ Node: ndf.Node{
...@@ -159,42 +113,3 @@ func TestRegisterNodes(t *testing.T) { ...@@ -159,42 +113,3 @@ func TestRegisterNodes(t *testing.T) {
t.Errorf("Failed to stop registration thread: %+v", err) t.Errorf("Failed to stop registration thread: %+v", err)
} }
} }
\ No newline at end of file
func getNDF() *ndf.NetworkDefinition {
return &ndf.NetworkDefinition{
E2E: ndf.Group{
Prime: "E2EE983D031DC1DB6F1A7A67DF0E9A8E5561DB8E8D49413394C049B" +
"7A8ACCEDC298708F121951D9CF920EC5D146727AA4AE535B0922C688B55B3DD2AE" +
"DF6C01C94764DAB937935AA83BE36E67760713AB44A6337C20E7861575E745D31F" +
"8B9E9AD8412118C62A3E2E29DF46B0864D0C951C394A5CBBDC6ADC718DD2A3E041" +
"023DBB5AB23EBB4742DE9C1687B5B34FA48C3521632C4A530E8FFB1BC51DADDF45" +
"3B0B2717C2BC6669ED76B4BDD5C9FF558E88F26E5785302BEDBCA23EAC5ACE9209" +
"6EE8A60642FB61E8F3D24990B8CB12EE448EEF78E184C7242DD161C7738F32BF29" +
"A841698978825B4111B4BC3E1E198455095958333D776D8B2BEEED3A1A1A221A6E" +
"37E664A64B83981C46FFDDC1A45E3D5211AAF8BFBC072768C4F50D7D7803D2D4F2" +
"78DE8014A47323631D7E064DE81C0C6BFA43EF0E6998860F1390B5D3FEACAF1696" +
"015CB79C3F9C2D93D961120CD0E5F12CBB687EAB045241F96789C38E89D796138E" +
"6319BE62E35D87B1048CA28BE389B575E994DCA755471584A09EC723742DC35873" +
"847AEF49F66E43873",
Generator: "2",
},
CMIX: ndf.Group{
Prime: "9DB6FB5951B66BB6FE1E140F1D2CE5502374161FD6538DF1648218642F0B5C48" +
"C8F7A41AADFA187324B87674FA1822B00F1ECF8136943D7C55757264E5A1A44F" +
"FE012E9936E00C1D3E9310B01C7D179805D3058B2A9F4BB6F9716BFE6117C6B5" +
"B3CC4D9BE341104AD4A80AD6C94E005F4B993E14F091EB51743BF33050C38DE2" +
"35567E1B34C3D6A5C0CEAA1A0F368213C3D19843D0B4B09DCB9FC72D39C8DE41" +
"F1BF14D4BB4563CA28371621CAD3324B6A2D392145BEBFAC748805236F5CA2FE" +
"92B871CD8F9C36D3292B5509CA8CAA77A2ADFC7BFD77DDA6F71125A7456FEA15" +
"3E433256A2261C6A06ED3693797E7995FAD5AABBCFBE3EDA2741E375404AE25B",
Generator: "5C7FF6B06F8F143FE8288433493E4769C4D988ACE5BE25A0E24809670716C613" +
"D7B0CEE6932F8FAA7C44D2CB24523DA53FBE4F6EC3595892D1AA58C4328A06C4" +
"6A15662E7EAA703A1DECF8BBB2D05DBE2EB956C142A338661D10461C0D135472" +
"085057F3494309FFA73C611F78B32ADBB5740C361C9F35BE90997DB2014E2EF5" +
"AA61782F52ABEB8BD6432C4DD097BC5423B285DAFB60DC364E8161F4A2A35ACA" +
"3A10B1C4D203CC76A470A33AFDCBDD92959859ABD8B56E1725252D78EAC66E71" +
"BA9AE3F1DD2487199874393CD4D832186800654760E1E34C09E4D155179F9EC0" +
"DC4473F996BDCE6EED1CABED8B6F116F7AD9CF505DF0F998E34AB27514B0FFE7",
},
}
}
File moved
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment