diff --git a/context/context.go b/context/context.go index c9de4b8781eed4f47c21c994bbae81027fe0f977..896f641e50a3b6b9b59e58794d56a2696aa2ffb1 100644 --- a/context/context.go +++ b/context/context.go @@ -3,6 +3,7 @@ package context import ( "gitlab.com/elixxir/client/context/switchboard" "gitlab.com/elixxir/client/storage" + "gitlab.com/elixxir/crypto/fastRNG" ) type Context struct { @@ -12,4 +13,6 @@ type Context struct { // this interface allows it to be mocked for easy testing without the // loop Manager NetworkManager + + Rng *fastRNG.StreamGenerator } diff --git a/context/stoppable/single.go b/context/stoppable/single.go index bd0184656f86d56021e3cb1a351765dc56e40929..8b82c59f2a6121554f37de60e800e9472d0f2cd4 100644 --- a/context/stoppable/single.go +++ b/context/stoppable/single.go @@ -47,12 +47,11 @@ func (s *Single) Close(timeout time.Duration) error { defer atomic.StoreUint32(&s.running, 0) timer := time.NewTimer(timeout) select { + case s.quit <- struct{}{}: + return nil case <-timer.C: jww.ERROR.Printf("Stopper for %s failed to stop after "+ "timeout of %s", s.name, timeout) return errors.Errorf("%s failed to close", s.name) - case <-s.quit: - - return nil } } diff --git a/go.mod b/go.mod index adbd4d07551cd2a65a3d57cb31ad2522485e6703..8b362ab5f4e650d7ada1a5c3f89c508d1650dbe4 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( 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-20200909162307-0465eee5adb1 + gitlab.com/elixxir/comms v0.0.0-20200909214857-b106ce82d9e8 gitlab.com/elixxir/crypto v0.0.0-20200907171019-008a9d4aa264 gitlab.com/elixxir/ekv v0.1.1 gitlab.com/elixxir/primitives v0.0.0-20200907165319-16ed0124890b diff --git a/go.sum b/go.sum index ff20f5c2fa9475b98d9ff5a9f966e179f696b8b6..cbf5ad9dd66a594dd29b5abc8d1a9a7e2bdc49bc 100644 --- a/go.sum +++ b/go.sum @@ -179,6 +179,8 @@ gitlab.com/elixxir/comms v0.0.0-20200903181126-c92d7a304999 h1:fxrqseawjJ2q6Z3NZ gitlab.com/elixxir/comms v0.0.0-20200903181126-c92d7a304999/go.mod h1:HW3Ige10aeJeyb2fcQ/YOBPiyzY/4jHau1Cj6/1WBHc= gitlab.com/elixxir/comms v0.0.0-20200909162307-0465eee5adb1 h1:Ma2phdeDx+7HZjLz4gAKlZN/bNsiqSmMPWCFnX9FrDI= gitlab.com/elixxir/comms v0.0.0-20200909162307-0465eee5adb1/go.mod h1:Z97ZjbtBLT3ojpGrT4jqlBhgscEjHl8kjA/ktLnhmOo= +gitlab.com/elixxir/comms v0.0.0-20200909214857-b106ce82d9e8 h1:y+0aElewUD0ceZHvf96+s8oUZnfBMD9aflOBztMNlZ0= +gitlab.com/elixxir/comms v0.0.0-20200909214857-b106ce82d9e8/go.mod h1:ZMwe9xZbPY1s81CVvy51hh+96b/supA797uxXEJJqRE= gitlab.com/elixxir/crypto v0.0.0-20200804182833-984246dea2c4 h1:28ftZDeYEko7xptCZzeFWS1Iam95dj46TWFVVlKmw6A= gitlab.com/elixxir/crypto v0.0.0-20200804182833-984246dea2c4/go.mod h1:ucm9SFKJo+K0N2GwRRpaNr+tKXMIOVWzmyUD0SbOu2c= gitlab.com/elixxir/crypto v0.0.0-20200805174804-bdf909f2a16d/go.mod h1:cu6uNoANVLV0J6HyTL6KqVtVyh9SHU1RjJhytYlsbVQ= diff --git a/network/node/register.go b/network/node/register.go index 8f748bfa8a23ad41ef66d573b7b42979f21815c6..97f6e759cd1c715f1af70cb23581feb23f32eb46 100644 --- a/network/node/register.go +++ b/network/node/register.go @@ -3,100 +3,132 @@ package node import ( "crypto" "crypto/rand" + "crypto/sha256" + "encoding/binary" "fmt" "github.com/pkg/errors" "github.com/spf13/jwalterweatherman" "gitlab.com/elixxir/client/context" "gitlab.com/elixxir/client/context/stoppable" "gitlab.com/elixxir/client/globals" - "gitlab.com/elixxir/client/storage" "gitlab.com/elixxir/client/storage/cmix" "gitlab.com/elixxir/client/storage/user" - "gitlab.com/elixxir/comms/client" pb "gitlab.com/elixxir/comms/mixmessages" + "gitlab.com/elixxir/comms/network" "gitlab.com/elixxir/crypto/csprng" + "gitlab.com/elixxir/crypto/cyclic" "gitlab.com/elixxir/crypto/hash" "gitlab.com/elixxir/crypto/registration" + "gitlab.com/xx_network/comms/connect" "gitlab.com/xx_network/comms/messages" "gitlab.com/xx_network/crypto/signature/rsa" "gitlab.com/xx_network/primitives/id" - "gitlab.com/xx_network/primitives/ndf" "time" ) -func StartRegistration(ctx context.Context, comms client.Comms) stoppable.Stoppable { +type RegisterNodeCommsInterface interface { + GetHost(hostId *id.ID) (*connect.Host, bool) + SendRequestNonceMessage(host *connect.Host, + message *pb.NonceRequest) (*pb.Nonce, error) + SendConfirmNonceMessage(host *connect.Host, + message *pb.RequestRegistrationConfirmation) (*pb.RegistrationConfirmation, error) +} + +func StartRegistration(ctx context.Context, comms RegisterNodeCommsInterface) stoppable.Stoppable { + stop := stoppable.NewSingle("NodeRegistration") instance := ctx.Manager.GetInstance() - c := make(chan ndf.Gateway, 100) + c := make(chan network.NodeGateway, 100) instance.SetAddGatewayChan(c) + go RegisterNodes(ctx, comms, stop, c) + + return stop +} + +func RegisterNodes(ctx context.Context, comms RegisterNodeCommsInterface, + stop *stoppable.Single, c chan network.NodeGateway) { u := ctx.Session.User() regSignature := u.GetRegistrationValidationSignature() userCryptographicIdentity := u.GetCryptographicIdentity() ctx.Session.Cmix() - stop := stoppable.NewSingle("NodeRegistration") - - go func() { - for true { - select { - case <-stop.Quit(): - return - case gw := <-c: - err := registerWithNode(comms, gw, regSignature, userCryptographicIdentity, - ctx.Session.Cmix(), ctx.Session) - if err != nil { - jwalterweatherman.ERROR.Printf("Failed") - } - default: - time.Sleep(0.5) + rng := ctx.Rng.GetStream() + interval := time.Duration(500) * time.Millisecond + for true { + select { + case <-stop.Quit(): + return + case gw := <-c: + err := registerWithNode(comms, gw, regSignature, userCryptographicIdentity, + ctx.Session.Cmix(), rng) + if err != nil { + jwalterweatherman.ERROR.Printf("Failed") } + default: + time.Sleep(interval) } - }() - - return stop + } } //registerWithNode serves as a helper for RegisterWithNodes // It registers a user with a specific in the client's ndf. -func registerWithNode(comms client.Comms, gw ndf.Gateway, regHash []byte, - userCryptographicIdentity *user.CryptographicIdentity, store *cmix.Store, session *storage.Session) error { - +func registerWithNode(comms RegisterNodeCommsInterface, ngw network.NodeGateway, regSig []byte, + userCryptographicIdentity *user.CryptographicIdentity, store *cmix.Store, rng csprng.Source) error { + gw := ngw.Gateway gatewayID, err := id.Unmarshal(gw.ID) if err != nil { return err } - // Initialise blake2b hash for transmission keys and sha256 for reception - // keys - transmissionHash, _ := hash.NewCMixHash() + nodeID := gatewayID.DeepCopy() + nodeID.SetType(id.Node) - nonce, dhPub, err := requestNonce(comms, gatewayID, regHash, userCryptographicIdentity, store) + if store.IsRegistered(nodeID) { + return nil + } - // Load server DH pubkey - serverPubDH := store.GetGroup().NewIntFromBytes(dhPub) + var transmissionKey *cyclic.Int + if userCryptographicIdentity.IsPrecanned() { + userNum := binary.BigEndian.Uint64(userCryptographicIdentity.GetUserID().Bytes()) + h := sha256.New() + h.Reset() + h.Write([]byte(string(40000 + userNum))) + + transmissionKey = store.GetGroup().NewIntFromBytes(h.Sum(nil)) + } else { + // Initialise blake2b hash for transmission keys and sha256 for reception + // keys + transmissionHash, _ := hash.NewCMixHash() + + nonce, dhPub, err := requestNonce(comms, gatewayID, regSig, userCryptographicIdentity, store, rng) + if err != nil { + return errors.Errorf("Failed to request nonce: %+v", err) + } - // Confirm received nonce - globals.Log.INFO.Println("Register: Confirming received nonce") - err = confirmNonce(comms, userCryptographicIdentity.GetUserID().Bytes(), - nonce, userCryptographicIdentity.GetRSA(), gatewayID) - if err != nil { - errMsg := fmt.Sprintf("Register: Unable to confirm nonce: %v", err) - return errors.New(errMsg) + // Load server DH pubkey + serverPubDH := store.GetGroup().NewIntFromBytes(dhPub) + + // Confirm received nonce + globals.Log.INFO.Println("Register: Confirming received nonce") + err = confirmNonce(comms, userCryptographicIdentity.GetUserID().Bytes(), + nonce, userCryptographicIdentity.GetRSA(), gatewayID) + if err != nil { + errMsg := fmt.Sprintf("Register: Unable to confirm nonce: %v", err) + return errors.New(errMsg) + } + transmissionKey = registration.GenerateBaseKey(store.GetGroup(), + serverPubDH, store.GetDHPrivateKey(), transmissionHash) } - nodeID := gatewayID.DeepCopy() - nodeID.SetType(id.Node) - transmissionKey := registration.GenerateBaseKey(store.GetGroup(), - serverPubDH, store.GetDHPrivateKey(), transmissionHash) - session.Cmix().Add(nodeID, transmissionKey) + store.Add(nodeID, transmissionKey) return nil } -func requestNonce(comms client.Comms, gwId *id.ID, regHash []byte, - userCryptographicIdentity *user.CryptographicIdentity, store *cmix.Store) ([]byte, []byte, error) { +func requestNonce(comms RegisterNodeCommsInterface, gwId *id.ID, regHash []byte, + userCryptographicIdentity *user.CryptographicIdentity, store *cmix.Store, rng csprng.Source) ([]byte, []byte, error) { dhPub := store.GetDHPublicKey().Bytes() sha := crypto.SHA256 opts := rsa.NewDefaultOptions() @@ -106,7 +138,6 @@ func requestNonce(comms client.Comms, gwId *id.ID, regHash []byte, data := h.Sum(nil) // Sign DH pubkey - rng := csprng.NewSystemRNG() signed, err := rsa.Sign(rng, userCryptographicIdentity.GetRSA(), sha, data, opts) if err != nil { return nil, nil, err @@ -148,7 +179,7 @@ func requestNonce(comms client.Comms, gwId *id.ID, regHash []byte, // confirmNonce is a helper for the Register function // It signs a nonce and sends it for confirmation // Returns nil if successful, error otherwise -func confirmNonce(comms client.Comms, UID, nonce []byte, +func confirmNonce(comms RegisterNodeCommsInterface, UID, nonce []byte, privateKeyRSA *rsa.PrivateKey, gwID *id.ID) error { sha := crypto.SHA256 opts := rsa.NewDefaultOptions() diff --git a/network/node/register_test.go b/network/node/register_test.go new file mode 100644 index 0000000000000000000000000000000000000000..05e1a36b14d79e4e5f69ace2872ef56265446a38 --- /dev/null +++ b/network/node/register_test.go @@ -0,0 +1,188 @@ +package node + +import ( + "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/storage" + pb "gitlab.com/elixxir/comms/mixmessages" + "gitlab.com/elixxir/comms/network" + "gitlab.com/elixxir/crypto/csprng" + "gitlab.com/elixxir/crypto/fastRNG" + "gitlab.com/elixxir/primitives/format" + "gitlab.com/xx_network/comms/connect" + "gitlab.com/xx_network/crypto/signature/rsa" + "gitlab.com/xx_network/primitives/id" + "gitlab.com/xx_network/primitives/ndf" + "testing" + "time" +) + +// Mock network manager for +type MockNetworkManager struct { + instance *network.Instance +} + +func (nm *MockNetworkManager) SendE2E(m message.Send, e2eP params.E2E, cmixP params.CMIX) ([]id.Round, error) { + return nil, nil +} +func (nm *MockNetworkManager) SendUnsafe(m message.Send) ([]id.Round, error) { + return nil, nil +} +func (nm *MockNetworkManager) SendCMIX(message format.Message) (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 +} + +// Mock client comms object +type MockClientComms struct { + request chan bool + confirm chan bool +} + +func NewMockClientComms() *MockClientComms { + return &MockClientComms{ + request: make(chan bool, 1), + confirm: make(chan bool, 1), + } +} + +func (mcc *MockClientComms) GetHost(hostId *id.ID) (*connect.Host, bool) { + return &connect.Host{}, true +} +func (mcc *MockClientComms) SendRequestNonceMessage(host *connect.Host, + message *pb.NonceRequest) (*pb.Nonce, error) { + // Use this channel to confirm that request nonce was called + mcc.request <- true + return &pb.Nonce{ + Nonce: []byte("nonce"), + DHPubKey: []byte("dhpub"), + }, nil +} +func (mcc *MockClientComms) SendConfirmNonceMessage(host *connect.Host, + message *pb.RequestRegistrationConfirmation) (*pb.RegistrationConfirmation, error) { + // Use this channel to confirm that confirm nonce was called + mcc.confirm <- true + return &pb.RegistrationConfirmation{ + ClientSignedByServer: nil, + ClientGatewayKey: nil, + Error: "", + }, nil +} + +func TestRegisterNodes(t *testing.T) { + privKey, err := rsa.LoadPrivateKeyFromPem([]byte("-----BEGIN PRIVATE KEY-----\n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\nOaRA5ZbdE7g7vxKRV36jT3wvD7W+\n-----END PRIVATE KEY-----\n")) + if err != nil || privKey == nil { + t.Error("Failed to load privKey\n") + } + pub := "-----BEGIN CERTIFICATE-----\n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\n-----END CERTIFICATE-----\n" + + salt := make([]byte, 32) + _, err = rand.Read(salt) + if err != nil { + t.Errorf("Failed to generate salt: %+v", err) + } + //uid := id.NewIdFromString("zezima", id.User, t) + comms := NewMockClientComms() + + def := getNDF() + instanceComms := &connect.ProtoComms{} + _, err = instanceComms.AddHost(&id.Permissioning, "0.0.0.0:420", []byte(pub), false, false) + if err != nil { + 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) + ctx := context.Context{ + Manager: &MockNetworkManager{ + instance: instance, + }, + Session: sess, + Rng: fastRNG.NewStreamGenerator(7, 3, csprng.NewSystemRNG), + } + + stop := stoppable.NewSingle("test") + c := make(chan network.NodeGateway, 100) + go RegisterNodes(ctx, comms, stop, c) + + c <- network.NodeGateway{ + Node: ndf.Node{ + ID: id.NewIdFromString("zezima", id.Node, t).Bytes(), + Address: "0.0.0.0:420", + TlsCertificate: pub, + }, + Gateway: ndf.Gateway{ + ID: id.NewIdFromString("zezima", id.Gateway, t).Bytes(), + Address: "0.0.0.0:421", + TlsCertificate: pub, + }, + } + + timeout := time.NewTimer(time.Second * 5) + select { + case <-timeout.C: + t.Errorf("Timed out waiting for request nonce channel signal") + case <-comms.request: + } + + timeout.Reset(5 * time.Second) + select { + case <-timeout.C: + t.Errorf("Timed out waiting for confirm nonce channel signal") + case <-comms.confirm: + } + + err = stop.Close(5 * time.Second) + if err != nil { + t.Errorf("Failed to stop registration thread: %+v", err) + } +} + +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", + }, + } +} diff --git a/storage/cmix/store.go b/storage/cmix/store.go index b77b1733903f00e081086ec1105b95177b6eccb0..0dd31917f0b3c4cd46a0aba9e40defb5d3213236 100644 --- a/storage/cmix/store.go +++ b/storage/cmix/store.go @@ -175,6 +175,14 @@ func (s *Store) GetGroup() *cyclic.Group { return s.grp } +func (s *Store) IsRegistered(nid *id.ID) bool { + s.mux.RLock() + defer s.mux.RUnlock() + + _, ok := s.nodes[*nid] + return ok +} + // stores the cmix store func (s *Store) save() error { now := time.Now() diff --git a/storage/session.go b/storage/session.go index 53ff91e39354b24633dd0e1f41d22dc3880616ec..c5bf387e2948b8aad0e1d300a5a5a3965cbf58a7 100644 --- a/storage/session.go +++ b/storage/session.go @@ -19,6 +19,7 @@ import ( "gitlab.com/elixxir/client/storage/utility" "gitlab.com/elixxir/client/storage/versioned" "gitlab.com/elixxir/crypto/cyclic" + "gitlab.com/elixxir/crypto/large" "gitlab.com/elixxir/ekv" "gitlab.com/xx_network/crypto/signature/rsa" "gitlab.com/xx_network/primitives/id" @@ -220,7 +221,37 @@ func InitTestingSession(i interface{}) *Session { globals.Log.FATAL.Panicf("InitTestingSession is restricted to testing only. Got %T", i) } + privKey, _ := rsa.LoadPrivateKeyFromPem([]byte("-----BEGIN PRIVATE KEY-----\n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\nOaRA5ZbdE7g7vxKRV36jT3wvD7W+\n-----END PRIVATE KEY-----\n")) store := make(ekv.Memstore) - return &Session{kv: versioned.NewKV(store)} - + kv := versioned.NewKV(store) + s := &Session{kv: kv} + u, err := user.NewUser(kv, id.NewIdFromString("zezima", id.User, i), []byte("salt"), privKey, false) + if err != nil { + globals.Log.FATAL.Panicf("InitTestingSession failed to create dummy user: %+v", err) + } + u.SetRegistrationValidationSignature([]byte("sig")) + s.user = u + cmixGrp := cyclic.NewGroup( + large.NewIntFromString("9DB6FB5951B66BB6FE1E140F1D2CE5502374161FD6538DF1648218642F0B5C48"+ + "C8F7A41AADFA187324B87674FA1822B00F1ECF8136943D7C55757264E5A1A44F"+ + "FE012E9936E00C1D3E9310B01C7D179805D3058B2A9F4BB6F9716BFE6117C6B5"+ + "B3CC4D9BE341104AD4A80AD6C94E005F4B993E14F091EB51743BF33050C38DE2"+ + "35567E1B34C3D6A5C0CEAA1A0F368213C3D19843D0B4B09DCB9FC72D39C8DE41"+ + "F1BF14D4BB4563CA28371621CAD3324B6A2D392145BEBFAC748805236F5CA2FE"+ + "92B871CD8F9C36D3292B5509CA8CAA77A2ADFC7BFD77DDA6F71125A7456FEA15"+ + "3E433256A2261C6A06ED3693797E7995FAD5AABBCFBE3EDA2741E375404AE25B", 16), + large.NewIntFromString("5C7FF6B06F8F143FE8288433493E4769C4D988ACE5BE25A0E24809670716C613"+ + "D7B0CEE6932F8FAA7C44D2CB24523DA53FBE4F6EC3595892D1AA58C4328A06C4"+ + "6A15662E7EAA703A1DECF8BBB2D05DBE2EB956C142A338661D10461C0D135472"+ + "085057F3494309FFA73C611F78B32ADBB5740C361C9F35BE90997DB2014E2EF5"+ + "AA61782F52ABEB8BD6432C4DD097BC5423B285DAFB60DC364E8161F4A2A35ACA"+ + "3A10B1C4D203CC76A470A33AFDCBDD92959859ABD8B56E1725252D78EAC66E71"+ + "BA9AE3F1DD2487199874393CD4D832186800654760E1E34C09E4D155179F9EC0"+ + "DC4473F996BDCE6EED1CABED8B6F116F7AD9CF505DF0F998E34AB27514B0FFE7", 16)) + cmix, err := cmix.NewStore(cmixGrp, kv, cmixGrp.NewInt(2)) + if err != nil { + globals.Log.FATAL.Panicf("InitTestingSession failed to create dummy cmix session: %+v", err) + } + s.cmix = cmix + return s }