From 18a4efddd35b2ccc9e861334d05a86b4412a26ee Mon Sep 17 00:00:00 2001
From: Benjamin Wenger <ben@elixxir.ioo>
Date: Thu, 30 Dec 2021 15:48:17 -0800
Subject: [PATCH] implemented the mechanisim for a variable keying threshold.

---
 README.md                   |  1 +
 cmd/root.go                 |  6 ++++++
 interfaces/params/E2E.go    | 43 +++++++++++++++++++------------------
 storage/e2e/session.go      |  5 +++--
 storage/e2e/session_test.go |  6 ------
 5 files changed, 32 insertions(+), 29 deletions(-)

diff --git a/README.md b/README.md
index b7b0c4585..e494e57d8 100644
--- a/README.md
+++ b/README.md
@@ -166,6 +166,7 @@ Flags:
       --e2eMaxKeys uint           Max keys used before blocking until a rekey completes (default 800)
       --e2eMinKeys uint           Minimum number of keys used before requesting rekey (default 500)
       --e2eNumReKeys uint         Number of rekeys reserved for rekey operations (default 16)
+      --e2eRekeyThreshold float64 Number between 0 an 1. Percent of keys used before a rekey is started
       --forceHistoricalRounds     Force all rounds to be sent to historical round retrieval
       --forceMessagePickupRetry   Enable a mechanism which forces a 50% chance of no message pickup, instead triggering the message pickup retry mechanism
   -h, --help                      help for client
diff --git a/cmd/root.go b/cmd/root.go
index d94817ec6..28dd11f80 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -573,6 +573,7 @@ func createClient() *api.Client {
 	netParams.E2EParams.MaxKeys = uint16(viper.GetUint("e2eMaxKeys"))
 	netParams.E2EParams.NumRekeys = uint16(
 		viper.GetUint("e2eNumReKeys"))
+	netParams.E2EParams.RekeyThreshold = viper.GetFloat64("e2eRekeyThreshold")
 	netParams.ForceHistoricalRounds = viper.GetBool("forceHistoricalRounds")
 	netParams.FastPolling = !viper.GetBool("slowPolling")
 	netParams.ForceMessagePickupRetry = viper.GetBool("forceMessagePickupRetry")
@@ -596,6 +597,7 @@ func initClient() *api.Client {
 	netParams.E2EParams.MaxKeys = uint16(viper.GetUint("e2eMaxKeys"))
 	netParams.E2EParams.NumRekeys = uint16(
 		viper.GetUint("e2eNumReKeys"))
+	netParams.E2EParams.RekeyThreshold = viper.GetFloat64("e2eRekeyThreshold")
 	netParams.ForceHistoricalRounds = viper.GetBool("forceHistoricalRounds")
 	netParams.FastPolling = viper.GetBool(" slowPolling")
 	netParams.ForceMessagePickupRetry = viper.GetBool("forceMessagePickupRetry")
@@ -1069,6 +1071,10 @@ func init() {
 		"", uint(defaultE2EParams.NumRekeys),
 		"Number of rekeys reserved for rekey operations")
 	viper.BindPFlag("e2eNumReKeys", rootCmd.Flags().Lookup("e2eNumReKeys"))
+	rootCmd.Flags().Float64P("e2eRekeyThreshold",
+		"", defaultE2EParams.RekeyThreshold,
+		"Number between 0 an 1. Percent of keys used before a rekey is started")
+	viper.BindPFlag("e2eRekeyThreshold", rootCmd.Flags().Lookup("e2eRekeyThreshold"))
 
 	rootCmd.Flags().String("profile-cpu", "",
 		"Enable cpu profiling to this file")
diff --git a/interfaces/params/E2E.go b/interfaces/params/E2E.go
index 9d473c429..66f5b8f98 100644
--- a/interfaces/params/E2E.go
+++ b/interfaces/params/E2E.go
@@ -10,7 +10,6 @@ package params
 import (
 	"encoding/json"
 	"fmt"
-	"gitlab.com/elixxir/crypto/e2e"
 )
 
 type E2E struct {
@@ -64,35 +63,37 @@ func (st SendType) String() string {
 
 // Network E2E Params
 
+
+
+type E2ESessionParams struct {
+	// using the DH as a seed, both sides generate a number
+	// of keys to use before they must rekey because
+	// there are no keys to use.
+	MinKeys   		uint16
+	MaxKeys   		uint16
+	// the percent of keys before a rekey is attempted. must be <0
+	RekeyThreshold 	float64
+	// extra keys generated and reserved for rekey attempts. This
+	// many keys are not allowed to be used for sending messages
+	// in order to ensure there are extras for rekeying.
+	NumRekeys 		uint16
+}
+
 // DEFAULT KEY GENERATION PARAMETERS
 // Hardcoded limits for keys
-// With 16 receiving states we can hold
-// 16*64=1024 dirty bits for receiving keys
-// With that limit, and setting maxKeys to 800,
-// we need a Threshold of 224, and a scalar
-// smaller than 1.28 to ensure we never generate
-// more than 1024 keys
-// With 1 receiving states for ReKeys we can hold
-// 64 Rekeys
+// sets the number of keys very high, but with a low rekey threshold. In this case, if the other party is online, you will read
 const (
-	minKeys   uint16  = 500
-	maxKeys   uint16  = 800
-	ttlScalar float64 = 1.2 // generate 20% extra keys
-	threshold uint16  = 224
-	numReKeys uint16  = 16
+	minKeys   		uint16  = 1000
+	maxKeys   		uint16  = 2000
+	rekeyThrshold 	float64	= 0.05
+	numReKeys 		uint16  = 16
 )
 
-type E2ESessionParams struct {
-	MinKeys   uint16
-	MaxKeys   uint16
-	NumRekeys uint16
-	e2e.TTLParams
-}
-
 func GetDefaultE2ESessionParams() E2ESessionParams {
 	return E2ESessionParams{
 		MinKeys:   minKeys,
 		MaxKeys:   maxKeys,
+		RekeyThreshold: rekeyThrshold,
 		NumRekeys: numReKeys,
 	}
 }
diff --git a/storage/e2e/session.go b/storage/e2e/session.go
index 5f05d882b..8fbcae123 100644
--- a/storage/e2e/session.go
+++ b/storage/e2e/session.go
@@ -22,6 +22,7 @@ import (
 	"gitlab.com/xx_network/crypto/randomness"
 	"gitlab.com/xx_network/primitives/id"
 	"gitlab.com/xx_network/primitives/netTime"
+	"math"
 	"math/big"
 	"sync"
 	"testing"
@@ -637,8 +638,8 @@ func (s *Session) generate(kv *versioned.KV) *versioned.KV {
 		int64(p.MaxKeys-p.MinKeys)),
 		s.baseKey.Bytes(), h).Int64() + int64(p.MinKeys))
 
-	// start rekeying when 75% of keys have been used
-	s.rekeyThreshold = (numKeys * 3) / 4
+	// start rekeying when enough keys have been used
+	s.rekeyThreshold = uint32(math.Ceil(s.e2eParams.RekeyThreshold*float64(numKeys)))
 
 	// the total number of keys should be the number of rekeys plus the
 	// number of keys to use
diff --git a/storage/e2e/session_test.go b/storage/e2e/session_test.go
index 58b2ed87b..2719df3c7 100644
--- a/storage/e2e/session_test.go
+++ b/storage/e2e/session_test.go
@@ -263,12 +263,6 @@ func cmpSerializedFields(a *Session, b *Session) error {
 	if a.e2eParams.NumRekeys != b.e2eParams.NumRekeys {
 		return errors.New("NumRekeys differed")
 	}
-	if a.e2eParams.MinNumKeys != b.e2eParams.MinNumKeys {
-		return errors.New("minNumKeys differed")
-	}
-	if a.e2eParams.TTLScalar != b.e2eParams.TTLScalar {
-		return errors.New("ttlScalar differed")
-	}
 	if a.baseKey.Cmp(b.baseKey) != 0 {
 		return errors.New("baseKey differed")
 	}
-- 
GitLab