diff --git a/api/client.go b/api/client.go index 0f53ede47066554b33a287a34ec8aef3f3043e8d..20545312e0adecad7e4ec195e1395b8176d27bf3 100644 --- a/api/client.go +++ b/api/client.go @@ -82,7 +82,6 @@ func NewClient(ndfJSON, storageDir string, password []byte, registrationCode str // Use fastRNG for RNG ops (AES fortuna based RNG using system RNG) jww.INFO.Printf("RNG Creation") rngStreamGen := fastRNG.NewStreamGenerator(12, 3, csprng.NewSystemRNG) - rngStream := rngStreamGen.GetStream() jww.INFO.Printf("Parsing NDF") // Parse the NDF def, err := parseNDF(ndfJSON) @@ -92,7 +91,7 @@ func NewClient(ndfJSON, storageDir string, password []byte, registrationCode str jww.INFO.Printf("Decoding Groups") cmixGrp, e2eGrp := decodeGroups(def) jww.INFO.Printf("Creating New User") - protoUser := createNewUser(rngStream, cmixGrp, e2eGrp) + protoUser := createNewUser(rngStreamGen, cmixGrp, e2eGrp) jww.INFO.Printf("Setting Up Storage") err = checkVersionAndSetupStorage(def, storageDir, password, protoUser, cmixGrp, e2eGrp, rngStreamGen, false, registrationCode) diff --git a/api/user.go b/api/user.go index 48d7f992dfa32b48a3905752c55459ddc710e701..695ed3ed99e0742c313f585f5ec8a8faf946c315 100644 --- a/api/user.go +++ b/api/user.go @@ -12,6 +12,7 @@ import ( jww "github.com/spf13/jwalterweatherman" "gitlab.com/elixxir/client/interfaces/user" "gitlab.com/elixxir/crypto/cyclic" + "gitlab.com/elixxir/crypto/fastRNG" "gitlab.com/xx_network/crypto/csprng" "gitlab.com/xx_network/crypto/signature/rsa" "gitlab.com/xx_network/crypto/xx" @@ -29,58 +30,105 @@ const ( ) // createNewUser generates an identity for cMix -func createNewUser(rng csprng.Source, cmix, e2e *cyclic.Group) user.User { +func createNewUser(rng *fastRNG.StreamGenerator, cmix, e2e *cyclic.Group) user.User { // CMIX Keygen - // FIXME: Why 256 bits? -- this is spec but not explained, it has - // to do with optimizing operations on one side and still preserves - // decent security -- cite this. - cMixKeyBytes, err := csprng.GenerateInGroup(cmix.GetPBytes(), 256, rng) - if err != nil { - jww.FATAL.Panicf(err.Error()) - } + var transmissionRsaKey, receptionRsaKey *rsa.PrivateKey - // DH Keygen - // FIXME: Why 256 bits? -- this is spec but not explained, it has - // to do with optimizing operations on one side and still preserves - // decent security -- cite this. Why valid for BOTH e2e and cmix? - e2eKeyBytes, err := csprng.GenerateInGroup(e2e.GetPBytes(), 256, rng) - if err != nil { - jww.FATAL.Panicf(err.Error()) - } + var cMixKeyBytes, e2eKeyBytes, transmissionSalt, receptionSalt []byte + + wg := sync.WaitGroup{} + + wg.Add(6) + + go func(){ + defer wg.Done() + var err error + // FIXME: Why 256 bits? -- this is spec but not explained, it has + // to do with optimizing operations on one side and still preserves + // decent security -- cite this. + stream := rng.GetStream() + cMixKeyBytes, err = csprng.GenerateInGroup(cmix.GetPBytes(), 256, stream) + stream.Close() + if err != nil { + jww.FATAL.Panicf(err.Error()) + } + }() + + go func(){ + defer wg.Done() + var err error + // DH Keygen + // FIXME: Why 256 bits? -- this is spec but not explained, it has + // to do with optimizing operations on one side and still preserves + // decent security -- cite this. Why valid for BOTH e2e and cmix? + stream := rng.GetStream() + e2eKeyBytes, err = csprng.GenerateInGroup(e2e.GetPBytes(), 256, stream) + stream.Close() + if err != nil { + jww.FATAL.Panicf(err.Error()) + } + }() // RSA Keygen (4096 bit defaults) - transmissionRsaKey, err := rsa.GenerateKey(rng, rsa.DefaultRSABitLen) - if err != nil { - jww.FATAL.Panicf(err.Error()) - } - receptionRsaKey, err := rsa.GenerateKey(rng, rsa.DefaultRSABitLen) - if err != nil { - jww.FATAL.Panicf(err.Error()) - } + go func() { + defer wg.Done() + var err error + stream := rng.GetStream() + transmissionRsaKey, err = rsa.GenerateKey(stream, rsa.DefaultRSABitLen) + stream.Close() + if err != nil { + jww.FATAL.Panicf(err.Error()) + } + }() + + go func() { + defer wg.Done() + var err error + stream := rng.GetStream() + receptionRsaKey, err = rsa.GenerateKey(stream, rsa.DefaultRSABitLen) + stream.Close() + if err != nil { + jww.FATAL.Panicf(err.Error()) + } + }() // Salt, UID, etc gen - transmissionSalt := make([]byte, SaltSize) - n, err := csprng.NewSystemRNG().Read(transmissionSalt) - if err != nil { - jww.FATAL.Panicf(err.Error()) - } - if n != SaltSize { - jww.FATAL.Panicf("transmissionSalt size too small: %d", n) - } + go func(){ + defer wg.Done() + transmissionSalt = make([]byte, SaltSize) + stream := rng.GetStream() + n, err := stream.Read(transmissionSalt) + stream.Close() + if err != nil { + jww.FATAL.Panicf(err.Error()) + } + if n != SaltSize { + jww.FATAL.Panicf("transmissionSalt size too small: %d", n) + } + }() + + + go func(){ + defer wg.Done() + receptionSalt = make([]byte, SaltSize) + stream := rng.GetStream() + n, err := stream.Read(receptionSalt) + stream.Close() + if err != nil { + jww.FATAL.Panicf(err.Error()) + } + if n != SaltSize { + jww.FATAL.Panicf("transmissionSalt size too small: %d", n) + } + }() + + wg.Wait() + transmissionID, err := xx.NewID(transmissionRsaKey.GetPublic(), transmissionSalt, id.User) if err != nil { jww.FATAL.Panicf(err.Error()) } - // Salt, UID, etc gen - receptionSalt := make([]byte, SaltSize) - n, err = csprng.NewSystemRNG().Read(receptionSalt) - if err != nil { - jww.FATAL.Panicf(err.Error()) - } - if n != SaltSize { - jww.FATAL.Panicf("receptionSalt size too small: %d", n) - } receptionID, err := xx.NewID(receptionRsaKey.GetPublic(), receptionSalt, id.User) if err != nil { jww.FATAL.Panicf(err.Error())