gofmt, govet, ..
This commit is contained in:
parent
f567b75f4e
commit
f58c8ff3a9
|
@ -27,7 +27,9 @@ func (c *T) updateConfig() {
|
|||
err = c.fkey.Fetch(c.key)
|
||||
|
||||
/* (3) On error -> set key to NIL */
|
||||
if err != nil { c.key = nil }
|
||||
if err != nil {
|
||||
c.key = nil
|
||||
}
|
||||
|
||||
/* (4) Create default sync */
|
||||
c.sync, err = keyset.Create(c.ctx)
|
||||
|
@ -36,7 +38,9 @@ func (c *T) updateConfig() {
|
|||
err = c.fsync.Fetch(c.sync)
|
||||
|
||||
/* (6) On error -> set sync to NIL */
|
||||
if err != nil { c.sync = nil }
|
||||
if err != nil {
|
||||
c.sync = nil
|
||||
}
|
||||
|
||||
/* (7) Exit if all keysets have been fetched */
|
||||
if c.key != nil && c.sync != nil {
|
||||
|
@ -45,7 +49,6 @@ func (c *T) updateConfig() {
|
|||
|
||||
}
|
||||
|
||||
|
||||
/* (2) If cannot fetch -> create new keysets
|
||||
---------------------------------------------------------*/
|
||||
if c.key == nil {
|
||||
|
@ -56,16 +59,19 @@ func (c *T) updateConfig() {
|
|||
c.sync, _ = keyset.Create(c.ctx)
|
||||
}
|
||||
|
||||
|
||||
/* (3) Store current value
|
||||
---------------------------------------------------------*/
|
||||
/* (1) Store key */
|
||||
err = c.fkey.Store(c.key)
|
||||
if err != nil { panic("Cannot store key") }
|
||||
if err != nil {
|
||||
panic("Cannot store key")
|
||||
}
|
||||
|
||||
/* (2) Store sync */
|
||||
err = c.fsync.Store(c.sync)
|
||||
if err != nil { panic("Cannot store sync") }
|
||||
if err != nil {
|
||||
panic("Cannot store sync")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -81,7 +87,9 @@ func (c *T) migrateKey() {
|
|||
|
||||
/* (2) Regenerate sync */
|
||||
c.sync, err = keyset.Create(c.ctx)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
/* (3) Store keysets to files */
|
||||
c.updateConfig()
|
||||
|
@ -95,7 +103,9 @@ func (c *T) generateKeyWithConstraints() {
|
|||
|
||||
/* Get current hash */
|
||||
keyHash, err := c.key.CurrentHash()
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
/* Search key one is respects contraints */
|
||||
for true {
|
||||
|
@ -111,19 +121,21 @@ func (c *T) generateKeyWithConstraints() {
|
|||
|
||||
/* (3) Hash time id */
|
||||
hashedTimeID, err := scha.Hash(timeIDBytes, 1)
|
||||
if err != nil { continue }
|
||||
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
/* (2) Generate a new sync
|
||||
---------------------------------------------------------*/
|
||||
newKey, _ := keyset.Create(c.ctx)
|
||||
|
||||
|
||||
/* (3) Check constraints
|
||||
---------------------------------------------------------*/
|
||||
/* (1) Get next hash */
|
||||
syncHash, err := newKey.CurrentHash()
|
||||
if err != nil { continue }
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
/* (2) Get x1 */
|
||||
x1 := make([]byte, scha.HSIZE)
|
||||
|
@ -145,18 +157,26 @@ func (c *T) generateKeyWithConstraints() {
|
|||
/* (2) Get time mod difference (first byte) */
|
||||
timeConstraintValue := x[0]%2 == byte(timeMod)
|
||||
|
||||
if DEBUG { fmt.Printf(" %.2x ^ %.2x = %.2x[%d] %% 2 = %d == %d ? %t\n", x1[0], x2[0], x[0], x[0], x[0]%2, timeMod, timeConstraintValue) }
|
||||
if DEBUG {
|
||||
fmt.Printf(" %.2x ^ %.2x = %.2x[%d] %% 2 = %d == %d ? %t\n", x1[0], x2[0], x[0], x[0], x[0]%2, timeMod, timeConstraintValue)
|
||||
}
|
||||
|
||||
/* (4) Retry if invalid time constraint */
|
||||
if !timeConstraintValue { continue }
|
||||
if !timeConstraintValue {
|
||||
continue
|
||||
}
|
||||
|
||||
/* (5) Get migration mod difference (second byte) */
|
||||
migrationConstraintValue := x[1]%3 == byte(c.key.MigrationCode())
|
||||
|
||||
if DEBUG { fmt.Printf(" %.2x ^ %.2x = %.2x[%d] %% 3 = %d == %d ? %t\n", x1[1], x2[1], x[1], x[1], x[1]%3, c.key.MigrationCode(), migrationConstraintValue) }
|
||||
if DEBUG {
|
||||
fmt.Printf(" %.2x ^ %.2x = %.2x[%d] %% 3 = %d == %d ? %t\n", x1[1], x2[1], x[1], x[1], x[1]%3, c.key.MigrationCode(), migrationConstraintValue)
|
||||
}
|
||||
|
||||
/* (6) Retry if invalid time constraint */
|
||||
if !migrationConstraintValue { continue }
|
||||
if !migrationConstraintValue {
|
||||
continue
|
||||
}
|
||||
|
||||
/* (7) Store new sync */
|
||||
c.sync = newKey
|
||||
|
@ -215,7 +235,9 @@ func (c *T) generateRequest(x1 []byte, x2 []byte) error {
|
|||
---------------------------------------------------------*/
|
||||
/* (1) Store current hash */
|
||||
h0, err := c.key.CurrentHash()
|
||||
if err != nil { return err }
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
/* (2) Copy into next hash (same value) */
|
||||
h1 := make([]byte, scha.HSIZE)
|
||||
|
@ -226,7 +248,9 @@ func (c *T) generateRequest(x1 []byte, x2 []byte) error {
|
|||
// 2. Else -> use 'sync'
|
||||
if c.key.MigrationCode() > 0 {
|
||||
h1, err = c.sync.CurrentHash()
|
||||
if err != nil { return err }
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
/* (5) Manage time id
|
||||
|
@ -302,14 +326,18 @@ func (c *T) rescue(y1 []byte, y2 []byte) error {
|
|||
|
||||
/* (3) Hash timeId */
|
||||
hashedTimeID, err := scha.Hash(timeIDBytes, 1)
|
||||
if err != nil { return err }
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
/* (4) Get the received hash */
|
||||
receivedHash := xor.ByteArray(y1, hashedTimeID)
|
||||
|
||||
/* (5) Try to rescue the key */
|
||||
err = c.key.Rescue(receivedHash)
|
||||
if err != nil { return err }
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
/* (6) Store updated key */
|
||||
c.updateConfig()
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
package client;
|
||||
package client
|
||||
|
||||
import (
|
||||
"git.xdrm.io/logauth/schastsp/internal/keyset"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"errors"
|
||||
"fmt"
|
||||
"git.xdrm.io/logauth/schastsp/internal/keyset"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
|
||||
type config struct {
|
||||
path string // absolute configuration file path
|
||||
}
|
||||
|
@ -21,47 +20,54 @@ type config struct {
|
|||
---------------------------------------------------------*/
|
||||
func Config(dir string, name string) (*config, error) {
|
||||
|
||||
inst := new(config);
|
||||
inst := new(config)
|
||||
|
||||
/* (1) Build full path */
|
||||
absoluteDir, err := filepath.Abs(dir);
|
||||
if err != nil { return nil, err; }
|
||||
|
||||
basename := filepath.Base(name);
|
||||
fullpath := fmt.Sprintf("%s/%s", absoluteDir, basename);
|
||||
absoluteDir, err := filepath.Abs(dir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
basename := filepath.Base(name)
|
||||
fullpath := fmt.Sprintf("%s/%s", absoluteDir, basename)
|
||||
|
||||
/* (2) Check directory */
|
||||
if info, err := os.Stat(absoluteDir); err != nil {
|
||||
|
||||
// Unknown error
|
||||
if !os.IsNotExist(err) { return nil, err }
|
||||
if !os.IsNotExist(err) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// not exists -> try to create dir
|
||||
err2 := os.MkdirAll(absoluteDir, 0755);
|
||||
if err2 != nil { return nil, err2 }
|
||||
err2 := os.MkdirAll(absoluteDir, 0755)
|
||||
if err2 != nil {
|
||||
return nil, err2
|
||||
}
|
||||
|
||||
// fail if not a directory
|
||||
// fail if not a directory
|
||||
} else if !info.Mode().IsDir() {
|
||||
return nil, errors.New("Configuration dir is not a directory");
|
||||
return nil, errors.New("Configuration dir is not a directory")
|
||||
}
|
||||
|
||||
|
||||
/* (3) Check file */
|
||||
info, err := os.Stat(fullpath);
|
||||
info, err := os.Stat(fullpath)
|
||||
if err != nil {
|
||||
|
||||
// Unknown error
|
||||
if !os.IsNotExist(err) { return nil, err }
|
||||
if !os.IsNotExist(err) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// File does not exist -> try to create file
|
||||
_, err2 := os.Create(fullpath);
|
||||
if err2 != nil { return nil, err2 }
|
||||
_, err2 := os.Create(fullpath)
|
||||
if err2 != nil {
|
||||
return nil, err2
|
||||
}
|
||||
|
||||
|
||||
// fail if exists but not regular file
|
||||
// fail if exists but not regular file
|
||||
} else if !info.Mode().IsRegular() {
|
||||
return nil, errors.New("Configuration file is not a regular file");
|
||||
return nil, errors.New("Configuration file is not a regular file")
|
||||
}
|
||||
|
||||
inst.path = fullpath
|
||||
|
@ -70,7 +76,6 @@ func Config(dir string, name string) (*config, error) {
|
|||
|
||||
}
|
||||
|
||||
|
||||
/* (2) Fetches a keyset from a file
|
||||
*
|
||||
* @ks<*keyset.T> Set to fetch into
|
||||
|
@ -83,20 +88,23 @@ func (c config) Fetch(ks *keyset.T) (err error) {
|
|||
|
||||
/* (1) Open file */
|
||||
file, err := os.Open(c.path)
|
||||
if err != nil { return err }
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
/* (2) Defer close */
|
||||
defer file.Close()
|
||||
|
||||
/* (3) Fetch from file */
|
||||
err = ks.Fetch(file);
|
||||
if err != nil { return err }
|
||||
err = ks.Fetch(file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* (3) Stores a keyset into file
|
||||
*
|
||||
* @ks<*keyset.T> Set to store
|
||||
|
@ -108,16 +116,20 @@ func (c config) Fetch(ks *keyset.T) (err error) {
|
|||
func (c config) Store(ks *keyset.T) error {
|
||||
|
||||
/* (1) Open file */
|
||||
file, err := os.OpenFile(c.path, os.O_RDWR|os.O_CREATE, 0755);
|
||||
if err != nil { return err }
|
||||
file, err := os.OpenFile(c.path, os.O_RDWR|os.O_CREATE, 0755)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
/* (2) Defer close */
|
||||
defer file.Close()
|
||||
|
||||
/* (3) Store into file */
|
||||
err = ks.Store(file)
|
||||
if err != nil { return err }
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"git.xdrm.io/logauth/schastsp/internal/scha"
|
||||
"time"
|
||||
"os"
|
||||
"flag"
|
||||
"fmt"
|
||||
"git.xdrm.io/logauth/schastsp/context"
|
||||
"git.xdrm.io/logauth/schastsp/internal/scha"
|
||||
"git.xdrm.io/logauth/schastsp/server"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main(){
|
||||
func main() {
|
||||
|
||||
executionStart := time.Now().UnixNano()
|
||||
|
||||
|
@ -37,69 +37,81 @@ func main(){
|
|||
/* (7) Parse flags */
|
||||
flag.Parse()
|
||||
|
||||
|
||||
/* (2) Create context + client
|
||||
---------------------------------------------------------*/
|
||||
/* (1) Create context */
|
||||
ctx, err := context.Create( float64(*winSize) / 1e3, uint16(*minDepth), uint16(*thrDepth), uint16(*maxDepth) );
|
||||
if err != nil { os.Stderr.WriteString( fmt.Sprintf("[SERVER_ERROR:context] %s\n", err) ); return }
|
||||
ctx, err := context.Create(float64(*winSize)/1e3, uint16(*minDepth), uint16(*thrDepth), uint16(*maxDepth))
|
||||
if err != nil {
|
||||
os.Stderr.WriteString(fmt.Sprintf("[SERVER_ERROR:context] %s\n", err))
|
||||
return
|
||||
}
|
||||
|
||||
/* (2) Create server */
|
||||
ser, err := server.New(ctx, *serverConfigPath)
|
||||
if err != nil { os.Stderr.WriteString( fmt.Sprintf("[SERVER_ERROR:server] %s\n", err) ); return }
|
||||
|
||||
|
||||
if err != nil {
|
||||
os.Stderr.WriteString(fmt.Sprintf("[SERVER_ERROR:server] %s\n", err))
|
||||
return
|
||||
}
|
||||
|
||||
/* (3) Dispatch execution
|
||||
---------------------------------------------------------*/
|
||||
/* (1) If synchronisation request */
|
||||
if *syncRequest {
|
||||
synchronisationCommit(ser);
|
||||
synchronisationCommit(ser)
|
||||
|
||||
/* (2) If request handling */
|
||||
/* (2) If request handling */
|
||||
} else {
|
||||
|
||||
err = ser.HandleRequest(os.Stdin, os.Stdout)
|
||||
if err != nil { os.Stderr.WriteString( fmt.Sprintf("[SERVER_ERROR:request] %s\n", err) ) }
|
||||
if err != nil {
|
||||
os.Stderr.WriteString(fmt.Sprintf("[SERVER_ERROR:request] %s\n", err))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
executionStop := time.Now().UnixNano()
|
||||
nsElapsed := float64(executionStop - executionStart)
|
||||
usElapsed := float64(nsElapsed / 1e3)
|
||||
msElapsed := float64(usElapsed / 1e3)
|
||||
sElapsed := float64(msElapsed / 1e3)
|
||||
nsElapsed := float64(executionStop - executionStart)
|
||||
usElapsed := float64(nsElapsed / 1e3)
|
||||
msElapsed := float64(usElapsed / 1e3)
|
||||
sElapsed := float64(msElapsed / 1e3)
|
||||
|
||||
if sElapsed >= 1 { os.Stderr.WriteString( fmt.Sprintf("executed in %.3f s\n", sElapsed) )
|
||||
} else if msElapsed >= 1 { os.Stderr.WriteString( fmt.Sprintf("executed in %.3f ms\n", msElapsed) )
|
||||
} else if usElapsed >= 1 { os.Stderr.WriteString( fmt.Sprintf("executed in %.3f us\n", usElapsed) )
|
||||
} else if nsElapsed >= 1 { os.Stderr.WriteString( fmt.Sprintf("executed in %.3f ns\n", nsElapsed) ) }
|
||||
if sElapsed >= 1 {
|
||||
os.Stderr.WriteString(fmt.Sprintf("executed in %.3f s\n", sElapsed))
|
||||
} else if msElapsed >= 1 {
|
||||
os.Stderr.WriteString(fmt.Sprintf("executed in %.3f ms\n", msElapsed))
|
||||
} else if usElapsed >= 1 {
|
||||
os.Stderr.WriteString(fmt.Sprintf("executed in %.3f us\n", usElapsed))
|
||||
} else if nsElapsed >= 1 {
|
||||
os.Stderr.WriteString(fmt.Sprintf("executed in %.3f ns\n", nsElapsed))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
func synchronisationCommit(ser *server.T){
|
||||
func synchronisationCommit(ser *server.T) {
|
||||
|
||||
/* (1) Try to read key from standard input */
|
||||
syncKey := make([]byte, scha.HSIZE)
|
||||
read, err := os.Stdin.Read(syncKey)
|
||||
if err != nil { os.Stderr.WriteString( fmt.Sprintf("[SERVER_ERROR:syncKey] %s\n", err) ); return }
|
||||
if uint16(read) != scha.HSIZE { os.Stderr.WriteString( fmt.Sprintf("[SERVER_ERROR:syncKey] Cannot read proper key size\n") ); return }
|
||||
if err != nil {
|
||||
os.Stderr.WriteString(fmt.Sprintf("[SERVER_ERROR:syncKey] %s\n", err))
|
||||
return
|
||||
}
|
||||
if uint16(read) != scha.HSIZE {
|
||||
os.Stderr.WriteString(fmt.Sprintf("[SERVER_ERROR:syncKey] Cannot read proper key size\n"))
|
||||
return
|
||||
}
|
||||
|
||||
/* (2) Store synchronisation key */
|
||||
err = ser.SynchronisationKey(syncKey)
|
||||
if err != nil { os.Stderr.WriteString( fmt.Sprintf("[SERVER_ERROR:syncKey] %s\n", err) ); return }
|
||||
if err != nil {
|
||||
os.Stderr.WriteString(fmt.Sprintf("[SERVER_ERROR:syncKey] %s\n", err))
|
||||
return
|
||||
}
|
||||
|
||||
/* (3) Debug */
|
||||
os.Stdout.WriteString("Synchronisation key successfully written\n")
|
||||
|
||||
return;
|
||||
return
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,41 +1,41 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"time"
|
||||
"bytes"
|
||||
"os"
|
||||
"flag"
|
||||
"fmt"
|
||||
"git.xdrm.io/logauth/schastsp/context"
|
||||
"git.xdrm.io/logauth/schastsp/client"
|
||||
"git.xdrm.io/logauth/schastsp/context"
|
||||
"git.xdrm.io/logauth/schastsp/server"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
/* Store target config paths */
|
||||
var clientConfigPath = "/tmp/cyclichash/client/";
|
||||
var serverConfigPath = "/tmp/cyclichash/server/lastkey";
|
||||
var clientConfigPath = "/tmp/cyclichash/client/"
|
||||
var serverConfigPath = "/tmp/cyclichash/server/lastkey"
|
||||
|
||||
|
||||
func main(){
|
||||
func main() {
|
||||
|
||||
executionStart := time.Now().UnixNano()
|
||||
|
||||
|
||||
/* (1) Create context
|
||||
---------------------------------------------------------*/
|
||||
/* (1) Create it */
|
||||
ctx, err := context.Create(2, 0x0f0, 0x0a, 0xfff);
|
||||
if err != nil { fmt.Printf("[ERROR:context] %s\n", err); return }
|
||||
|
||||
ctx, err := context.Create(2, 0x0f0, 0x0a, 0xfff)
|
||||
if err != nil {
|
||||
fmt.Printf("[ERROR:context] %s\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
/* (2) Manage flags (cli arguments)
|
||||
---------------------------------------------------------*/
|
||||
/* (1) Define 'sync' mode */
|
||||
var sync bool;
|
||||
var sync bool
|
||||
flag.BoolVar(&sync, "sync", false, "If set, a new synchronisation key will be outputed\nNote: it will break existing systems")
|
||||
|
||||
/* (2) Define connection 'latency' */
|
||||
var latency int64;
|
||||
var latency int64
|
||||
flag.Int64Var(&latency, "t", 0, "Connection latency in ms")
|
||||
|
||||
/* (3) Parse cli arguments */
|
||||
|
@ -48,86 +48,106 @@ func main(){
|
|||
testCommunication(ctx, latency)
|
||||
}
|
||||
|
||||
|
||||
|
||||
executionStop := time.Now().UnixNano()
|
||||
nsElapsed := float64(executionStop - executionStart)
|
||||
usElapsed := float64(nsElapsed / 1e3)
|
||||
msElapsed := float64(usElapsed / 1e3)
|
||||
sElapsed := float64(msElapsed / 1e3)
|
||||
|
||||
if sElapsed >= 1 { fmt.Printf("executed in %.3f s\n", sElapsed)
|
||||
} else if msElapsed >= 1 { fmt.Printf("executed in %.3f ms\n", msElapsed)
|
||||
} else if usElapsed >= 1 { fmt.Printf("executed in %.3f us\n", usElapsed)
|
||||
} else if nsElapsed >= 1 { fmt.Printf("executed in %.3f ns\n", nsElapsed) }
|
||||
nsElapsed := float64(executionStop - executionStart)
|
||||
usElapsed := float64(nsElapsed / 1e3)
|
||||
msElapsed := float64(usElapsed / 1e3)
|
||||
sElapsed := float64(msElapsed / 1e3)
|
||||
|
||||
if sElapsed >= 1 {
|
||||
fmt.Printf("executed in %.3f s\n", sElapsed)
|
||||
} else if msElapsed >= 1 {
|
||||
fmt.Printf("executed in %.3f ms\n", msElapsed)
|
||||
} else if usElapsed >= 1 {
|
||||
fmt.Printf("executed in %.3f us\n", usElapsed)
|
||||
} else if nsElapsed >= 1 {
|
||||
fmt.Printf("executed in %.3f ns\n", nsElapsed)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
func synchronise(ctx *context.T){
|
||||
func synchronise(ctx *context.T) {
|
||||
|
||||
/* (1) Create client */
|
||||
client, err := client.New(ctx, clientConfigPath);
|
||||
if err != nil { fmt.Printf("[ERROR:client] %s\n", err); return }
|
||||
client, err := client.New(ctx, clientConfigPath)
|
||||
if err != nil {
|
||||
fmt.Printf("[ERROR:client] %s\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
/* (2) Get synchronisation key */
|
||||
syncKey, err := client.SynchronisationKey()
|
||||
if err != nil { fmt.Printf("[ERROR:syncKey] %s\n", err); return }
|
||||
if err != nil {
|
||||
fmt.Printf("[ERROR:syncKey] %s\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
/* (3) Store synchronisation key */
|
||||
conf, err := os.OpenFile(serverConfigPath, os.O_RDWR|os.O_CREATE, 0775)
|
||||
if err != nil { fmt.Printf("[ERROR:syncKey:storage] %s\n", err); return }
|
||||
if err != nil {
|
||||
fmt.Printf("[ERROR:syncKey:storage] %s\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
defer conf.Close()
|
||||
|
||||
conf.Write(syncKey)
|
||||
|
||||
fmt.Printf("Synchronisation Key stored\n");
|
||||
fmt.Printf("Synchronisation Key stored\n")
|
||||
|
||||
return;
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
|
||||
func testCommunication(ctx *context.T, latency int64){
|
||||
func testCommunication(ctx *context.T, latency int64) {
|
||||
|
||||
/* (1) Setup
|
||||
---------------------------------------------------------*/
|
||||
/* (1) Create client */
|
||||
client, err := client.New(ctx, clientConfigPath);
|
||||
if err != nil { fmt.Printf("[ERROR:client] %s\n", err); return }
|
||||
client, err := client.New(ctx, clientConfigPath)
|
||||
if err != nil {
|
||||
fmt.Printf("[ERROR:client] %s\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
/* (2) Create server */
|
||||
server, err := server.New(ctx, serverConfigPath)
|
||||
if err != nil { fmt.Printf("[ERROR:server] %s\n", err); return }
|
||||
if err != nil {
|
||||
fmt.Printf("[ERROR:server] %s\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
/* (3) Create emulation buffers */
|
||||
requestSocket, responseSocket := new(bytes.Buffer), new(bytes.Buffer)
|
||||
|
||||
|
||||
|
||||
/* (2) REAL STUFF HAPPENS HERE
|
||||
---------------------------------------------------------*/
|
||||
/* (1) Request | client send */
|
||||
err = client.Send(requestSocket)
|
||||
if err != nil { fmt.Printf("[ERROR:request:send] %s\n", err); return }
|
||||
if err != nil {
|
||||
fmt.Printf("[ERROR:request:send] %s\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
/* (2) Emulate latency */
|
||||
time.Sleep( time.Duration(latency) * time.Second / 1e3)
|
||||
time.Sleep(time.Duration(latency) * time.Second / 1e3)
|
||||
|
||||
/* (3) Request | server receive */
|
||||
/* Response | server send */
|
||||
err = server.HandleRequest(requestSocket, responseSocket)
|
||||
if err != nil { fmt.Printf("[ERROR:request:receive] %s\n", err); return }
|
||||
if err != nil {
|
||||
fmt.Printf("[ERROR:request:receive] %s\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
/* (4) Response | client receive */
|
||||
err = client.Receive(responseSocket)
|
||||
if err != nil { fmt.Printf("[ERROR:response:receive] %s\n", err); return }
|
||||
if err != nil {
|
||||
fmt.Printf("[ERROR:response:receive] %s\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
return;
|
||||
return
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,13 +11,12 @@ const DefaultMin = 0x00f0
|
|||
const DefaultMax = 0x0fff
|
||||
const DefaultThr = 0x000a
|
||||
|
||||
|
||||
/* (2) Struct attributes */
|
||||
type T struct {
|
||||
win float64; // 'timeid' window size
|
||||
min uint16; // minimum scha depth
|
||||
max uint16; // maximum scha depth
|
||||
thr uint16; // scha depth threshold
|
||||
win float64 // 'timeid' window size
|
||||
min uint16 // minimum scha depth
|
||||
max uint16 // maximum scha depth
|
||||
thr uint16 // scha depth threshold
|
||||
}
|
||||
|
||||
/* (3) Constructor
|
||||
|
@ -30,13 +29,15 @@ type T struct {
|
|||
* @return outName<outType> outDesc
|
||||
*
|
||||
---------------------------------------------------------*/
|
||||
func Create(win float64, optional... uint16) (*T, error) {
|
||||
func Create(win float64, optional ...uint16) (*T, error) {
|
||||
|
||||
var inst = new(T);
|
||||
var inst = new(T)
|
||||
|
||||
/* (1) Window size error */
|
||||
if win < 0 { return nil, errors.New("Window size must be positive and is negative") }
|
||||
inst.win = win;
|
||||
if win < 0 {
|
||||
return nil, errors.New("Window size must be positive and is negative")
|
||||
}
|
||||
inst.win = win
|
||||
|
||||
/* (2) Default values */
|
||||
inst.min = DefaultMin
|
||||
|
@ -49,13 +50,13 @@ func Create(win float64, optional... uint16) (*T, error) {
|
|||
if optional[0] < 0x0f {
|
||||
return nil, errors.New("Minimum depth must be greater than 0x0f (decimal 15) for consistency issues")
|
||||
}
|
||||
inst.min = optional[0];
|
||||
inst.min = optional[0]
|
||||
|
||||
}
|
||||
|
||||
/* (4) Optional 'thr' */
|
||||
if len(optional) > 1 {
|
||||
inst.thr = optional[1];
|
||||
inst.thr = optional[1]
|
||||
}
|
||||
|
||||
/* (5) Optional 'max' */
|
||||
|
@ -64,7 +65,7 @@ func Create(win float64, optional... uint16) (*T, error) {
|
|||
if optional[2] <= inst.min+inst.thr {
|
||||
return nil, errors.New("Minimum depth must be greater than 0x0f (decimal 15) for consistency issues")
|
||||
}
|
||||
inst.max = optional[2];
|
||||
inst.max = optional[2]
|
||||
|
||||
}
|
||||
|
||||
|
@ -72,7 +73,7 @@ func Create(win float64, optional... uint16) (*T, error) {
|
|||
}
|
||||
|
||||
/* (4) Getters */
|
||||
func (c T) Window() float64 { return c.win }
|
||||
func (c T) MinDepth() uint16 { return c.min }
|
||||
func (c T) MaxDepth() uint16 { return c.max }
|
||||
func (c T) DepthThreshold() uint16 { return c.thr }
|
||||
func (c T) Window() float64 { return c.win }
|
||||
func (c T) MinDepth() uint16 { return c.min }
|
||||
func (c T) MaxDepth() uint16 { return c.max }
|
||||
func (c T) DepthThreshold() uint16 { return c.thr }
|
||||
|
|
|
@ -4,14 +4,13 @@ import (
|
|||
"testing"
|
||||
)
|
||||
|
||||
|
||||
func TestDefaultArguments(t *testing.T) {
|
||||
|
||||
ctx, err := Create(2.2);
|
||||
ctx, err := Create(2.2)
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("[Unexpected error]: %s", err);
|
||||
return;
|
||||
t.Errorf("[Unexpected error]: %s", err)
|
||||
return
|
||||
}
|
||||
// check all optional arguments
|
||||
if ctx.Window() != 2.2 {
|
||||
|
@ -38,34 +37,34 @@ func TestDefaultArguments(t *testing.T) {
|
|||
|
||||
func TestOptionalMinConstraint(t *testing.T) {
|
||||
|
||||
ctx, err := Create(2.2, 0x0f);
|
||||
ctx, err := Create(2.2, 0x0f)
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("[Unexpected error]: %s", err);
|
||||
return;
|
||||
t.Errorf("[Unexpected error]: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx, err = Create(2.2, 0x0f-1);
|
||||
ctx, err = Create(2.2, 0x0f-1)
|
||||
if err == nil {
|
||||
t.Errorf("Expected an error with 'min' < %d ; got min=%d", 0x0f, ctx.MinDepth());
|
||||
return;
|
||||
t.Errorf("Expected an error with 'min' < %d ; got min=%d", 0x0f, ctx.MinDepth())
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestOptionalMaxConstraint(t *testing.T) {
|
||||
|
||||
ctx, err := Create(2.2, 0xf1, 0x02, 0xf1+0x02+1);
|
||||
ctx, err := Create(2.2, 0xf1, 0x02, 0xf1+0x02+1)
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("[Unexpected error]: %s", err);
|
||||
return;
|
||||
t.Errorf("[Unexpected error]: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx, err = Create(2.2, 0xf1, 0x02, 0xf1+0x02);
|
||||
ctx, err = Create(2.2, 0xf1, 0x02, 0xf1+0x02)
|
||||
if err == nil {
|
||||
t.Errorf("Expected an error with 'max' > 'min'+'thr' ; got max=%d, min=%d, thr=%d", ctx.MinDepth(), ctx.MaxDepth(), ctx.DepthThreshold());
|
||||
return;
|
||||
t.Errorf("Expected an error with 'max' > 'min'+'thr' ; got max=%d, min=%d, thr=%d", ctx.MinDepth(), ctx.MaxDepth(), ctx.DepthThreshold())
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
|
||||
/* (2) Generates a pseudo-random KeySet
|
||||
*
|
||||
---------------------------------------------------------*/
|
||||
|
@ -27,7 +26,7 @@ func (s *T) generate() {
|
|||
/* (2) Manage other attributes
|
||||
---------------------------------------------------------*/
|
||||
/* (1) Random depth pick init */
|
||||
var randMin, randMax = s.ctx.MinDepth() + (s.ctx.MaxDepth()-s.ctx.MinDepth()) / 2, s.ctx.MaxDepth()
|
||||
var randMin, randMax = s.ctx.MinDepth() + (s.ctx.MaxDepth()-s.ctx.MinDepth())/2, s.ctx.MaxDepth()
|
||||
|
||||
/* (2) Select "random" depth */
|
||||
s.depth = randMin + uint16(rand.Intn(int(randMax+1-randMin)))
|
||||
|
@ -35,4 +34,4 @@ func (s *T) generate() {
|
|||
/* (3) Reset comsumption level */
|
||||
s.mcode = 0
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,19 +1,16 @@
|
|||
package scha
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"crypto/sha512"
|
||||
"errors"
|
||||
"git.xdrm.io/logauth/schastsp/internal/xor"
|
||||
)
|
||||
|
||||
/* (0) Static
|
||||
---------------------------------------------------------*/
|
||||
/* (1) Constants */
|
||||
const HSIZE uint16 = sha512.Size;
|
||||
const HBITSIZE uint32 = uint32(HSIZE) * 8;
|
||||
|
||||
|
||||
|
||||
const HSIZE uint16 = sha512.Size
|
||||
const HBITSIZE uint32 = uint32(HSIZE) * 8
|
||||
|
||||
/* (1) Basic hash function
|
||||
*
|
||||
|
@ -22,23 +19,22 @@ const HBITSIZE uint32 = uint32(HSIZE) * 8;
|
|||
* @return digest<[]byte]> Byte array digest
|
||||
*
|
||||
---------------------------------------------------------*/
|
||||
func hash(input []byte) []byte{
|
||||
func hash(input []byte) []byte {
|
||||
|
||||
/* (1) Create sha512 hasher */
|
||||
hasher := sha512.New();
|
||||
hasher := sha512.New()
|
||||
|
||||
/* (2) Defer memory cleanup */
|
||||
defer hasher.Reset();
|
||||
defer hasher.Reset()
|
||||
|
||||
/* (3) Set input to be hashed */
|
||||
hasher.Write(input);
|
||||
hasher.Write(input)
|
||||
|
||||
/* (4) Extract digest */
|
||||
return hasher.Sum(nil);
|
||||
return hasher.Sum(nil)
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* (2) Public hashing interface
|
||||
*
|
||||
* @input<[]byte> Byte array input
|
||||
|
@ -50,32 +46,33 @@ func hash(input []byte) []byte{
|
|||
* @return err<error> If consistence error
|
||||
*
|
||||
---------------------------------------------------------*/
|
||||
func Hash(input []byte, depth uint16, options... []byte) ([]byte, error) {
|
||||
|
||||
func Hash(input []byte, depth uint16, options ...[]byte) ([]byte, error) {
|
||||
|
||||
/* (1) Manage errors errors
|
||||
---------------------------------------------------------*/
|
||||
/* (1) Avoid no depth (no hash at all) */
|
||||
if( depth < 1 ){
|
||||
return nil, errors.New("Cannot use a 'depth' of zero. This is inconsistent and means that no hash will be processed");
|
||||
if depth < 1 {
|
||||
return nil, errors.New("Cannot use a 'depth' of zero. This is inconsistent and means that no hash will be processed")
|
||||
}
|
||||
|
||||
/* (2) Avoir empty input */
|
||||
if( len(input) < 1 ){
|
||||
return nil, errors.New("Cannot use an empty 'input'. This is inconsistent");
|
||||
if len(input) < 1 {
|
||||
return nil, errors.New("Cannot use an empty 'input'. This is inconsistent")
|
||||
}
|
||||
|
||||
|
||||
/* (2) Extract optional arguments
|
||||
---------------------------------------------------------*/
|
||||
/* (1) Optional salt */
|
||||
salt := make([]byte, 0)
|
||||
if len(options) > 0 { salt = options[0] }
|
||||
if len(options) > 0 {
|
||||
salt = options[0]
|
||||
}
|
||||
|
||||
/* (2) Optional pepper */
|
||||
pepper := make([]byte, 0)
|
||||
if len(options) > 0 { pepper = options[0] }
|
||||
|
||||
if len(options) > 0 {
|
||||
pepper = options[0]
|
||||
}
|
||||
|
||||
/* (3) Process cyclic hash
|
||||
---------------------------------------------------------*/
|
||||
|
@ -83,14 +80,14 @@ func Hash(input []byte, depth uint16, options... []byte) ([]byte, error) {
|
|||
digest := make([]byte, 0, HSIZE)
|
||||
|
||||
/* (2) Process first hash + salt */
|
||||
digest = hash( xor.ByteArray(input, salt) )
|
||||
digest = hash(xor.ByteArray(input, salt))
|
||||
|
||||
/* (3) Iterate @depth times */
|
||||
for depth--; depth > 0; depth-- {
|
||||
|
||||
// Add Pepper only for last time
|
||||
if( depth == 1 ){
|
||||
digest = hash( xor.ByteArray(digest, pepper) )
|
||||
if depth == 1 {
|
||||
digest = hash(xor.ByteArray(digest, pepper))
|
||||
} else {
|
||||
digest = hash(digest)
|
||||
}
|
||||
|
@ -98,4 +95,4 @@ func Hash(input []byte, depth uint16, options... []byte) ([]byte, error) {
|
|||
}
|
||||
|
||||
return digest, nil
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,155 +2,147 @@ package scha
|
|||
|
||||
import "testing"
|
||||
|
||||
func TestSimpleHash(t *testing.T){
|
||||
func TestSimpleHash(t *testing.T) {
|
||||
|
||||
input := []byte("somePlainText");
|
||||
input := []byte("somePlainText")
|
||||
expected := []byte{
|
||||
0x4c, 0xcb, 0x0e, 0xf6, 0x81, 0x99, 0x2e, 0xd6, 0xb8, 0x17, 0x52, 0x1d, 0x09,
|
||||
0x6e, 0x99, 0x19, 0xe7, 0xda, 0x50, 0xc8, 0xbf, 0x64, 0xae, 0xc1, 0x4f, 0xaa,
|
||||
0x47, 0x06, 0xf3, 0x49, 0x30, 0x8a, 0x90, 0x8e, 0xd2, 0xff, 0xc2, 0x6d, 0xee,
|
||||
0xaa, 0xd6, 0x45, 0xd8, 0xb3, 0x17, 0xe3, 0xb9, 0x45, 0x29, 0x26, 0xe2, 0x8e,
|
||||
0x99, 0x50, 0x94, 0x49, 0x90, 0x02, 0xa5, 0x61, 0x4a, 0x3f, 0x5e, 0xfa};
|
||||
got, err := Hash(input, 1);
|
||||
digestLength := uint(len(got));
|
||||
0x99, 0x50, 0x94, 0x49, 0x90, 0x02, 0xa5, 0x61, 0x4a, 0x3f, 0x5e, 0xfa}
|
||||
got, err := Hash(input, 1)
|
||||
digestLength := uint(len(got))
|
||||
|
||||
/* (2) Fail on errors */
|
||||
if err != nil {
|
||||
t.Errorf("Expected no errors, got: %s", err);
|
||||
t.Errorf("Expected no errors, got: %s", err)
|
||||
}
|
||||
|
||||
/* (2) Fail on wrong size */
|
||||
if uint16(digestLength) != HSIZE {
|
||||
t.Errorf("Expected hash digest of %d bytes ; %d bytes received", HSIZE, digestLength);
|
||||
if uint16(digestLength) != HSIZE {
|
||||
t.Errorf("Expected hash digest of %d bytes ; %d bytes received", HSIZE, digestLength)
|
||||
}
|
||||
|
||||
/* (3) Check each byte */
|
||||
for k, v := range got{
|
||||
for k, v := range got {
|
||||
|
||||
if v != expected[k] {
|
||||
t.Errorf("Expected sha[%d] of '%x' to be '%x' ; received '%x'", HSIZE, input, expected, got);
|
||||
return;
|
||||
t.Errorf("Expected sha[%d] of '%x' to be '%x' ; received '%x'", HSIZE, input, expected, got)
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestDepth1Plus1Equals2(t *testing.T) {
|
||||
|
||||
|
||||
func TestDepth1Plus1Equals2(t *testing.T){
|
||||
|
||||
input := []byte("someOtherPlainText");
|
||||
input := []byte("someOtherPlainText")
|
||||
|
||||
/* (1) Calculate H1 */
|
||||
h1, err := Hash(input, 1)
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("Expected no error");
|
||||
return;
|
||||
t.Errorf("Expected no error")
|
||||
return
|
||||
}
|
||||
|
||||
/* (2) Calculate H1(H1) */
|
||||
h11, err := Hash(h1, 1);
|
||||
h11, err := Hash(h1, 1)
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("Expected no error");
|
||||
return;
|
||||
t.Errorf("Expected no error")
|
||||
return
|
||||
}
|
||||
|
||||
/* (3) Calculate H2 */
|
||||
h2, err := Hash(input, 1+1);
|
||||
h2, err := Hash(input, 1+1)
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("Expected no error");
|
||||
return;
|
||||
t.Errorf("Expected no error")
|
||||
return
|
||||
}
|
||||
|
||||
/* (4) Manage different length */
|
||||
if len(h11) != len(h2) || len(h11) != int(HSIZE) {
|
||||
t.Errorf("Expected digest lengths to be %d, got %d and %d", HSIZE, len(h11), len(h2));
|
||||
return;
|
||||
t.Errorf("Expected digest lengths to be %d, got %d and %d", HSIZE, len(h11), len(h2))
|
||||
return
|
||||
}
|
||||
|
||||
/* (5) Compare the 2 strings */
|
||||
for k, v := range h11 {
|
||||
if v != h2[k] {
|
||||
t.Errorf("Expected h2() to be equal to h1(h1())\n got '%x'\n expected '%x'", h2, h11)
|
||||
return;
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestDepth52Plus64Equals116(t *testing.T) {
|
||||
|
||||
|
||||
func TestDepth52Plus64Equals116(t *testing.T){
|
||||
|
||||
input := []byte("someOtherPlainText");
|
||||
input := []byte("someOtherPlainText")
|
||||
|
||||
/* (1) Calculate H52 */
|
||||
h52, err := Hash(input, 52)
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("Expected no error");
|
||||
return;
|
||||
t.Errorf("Expected no error")
|
||||
return
|
||||
}
|
||||
|
||||
/* (2) Calculate H52(H64) */
|
||||
h5264, err := Hash(h52, 64);
|
||||
h5264, err := Hash(h52, 64)
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("Expected no error");
|
||||
return;
|
||||
t.Errorf("Expected no error")
|
||||
return
|
||||
}
|
||||
|
||||
/* (3) Calculate H116 */
|
||||
h116, err := Hash(input, 52+64);
|
||||
h116, err := Hash(input, 52+64)
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("Expected no error");
|
||||
return;
|
||||
t.Errorf("Expected no error")
|
||||
return
|
||||
}
|
||||
|
||||
/* (4) Manage different length */
|
||||
if len(h5264) != len(h116) || len(h5264) != int(HSIZE) {
|
||||
t.Errorf("Expected digest lengths to be %d, got %d and %d", HSIZE, len(h5264), len(h116));
|
||||
return;
|
||||
t.Errorf("Expected digest lengths to be %d, got %d and %d", HSIZE, len(h5264), len(h116))
|
||||
return
|
||||
}
|
||||
|
||||
/* (5) Compare the 2 strings */
|
||||
for k, v := range h5264 {
|
||||
if v != h116[k] {
|
||||
t.Errorf("Expected h116() to be equal to h52(h64())\n got '%x'\n expected '%x'", h116, h5264)
|
||||
return;
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestDepthError(t *testing.T) {
|
||||
|
||||
|
||||
func TestDepthError(t *testing.T){
|
||||
|
||||
input := []byte("somePlainText");
|
||||
_, err := Hash(input, 0);
|
||||
input := []byte("somePlainText")
|
||||
_, err := Hash(input, 0)
|
||||
|
||||
/* (2) Fail on errors */
|
||||
if err == nil {
|
||||
t.Errorf("Expected an error for depth of 0");
|
||||
t.Errorf("Expected an error for depth of 0")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestEmptyInputError(t *testing.T) {
|
||||
|
||||
|
||||
func TestEmptyInputError(t *testing.T){
|
||||
|
||||
_, err := Hash(nil, 1);
|
||||
_, err := Hash(nil, 1)
|
||||
|
||||
/* (2) Fail on errors */
|
||||
if err == nil {
|
||||
t.Errorf("Expected an error for empty input");
|
||||
t.Errorf("Expected an error for empty input")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
|
||||
/* (1) Generates the current time id
|
||||
*
|
||||
* @wsize<float64> Window Size in seconds
|
||||
|
@ -14,24 +13,25 @@ import (
|
|||
* @return parity<uint32> Current time parity
|
||||
*
|
||||
---------------------------------------------------------*/
|
||||
func Generate(wsize float64) (uint32, uint32){
|
||||
func Generate(wsize float64) (uint32, uint32) {
|
||||
|
||||
/* (1) If wsize is 0 (div by zero possible error) */
|
||||
if wsize == 0 { return 0, 0 }
|
||||
if wsize == 0 {
|
||||
return 0, 0
|
||||
}
|
||||
|
||||
/* (2) Get current timestamp */
|
||||
timestamp := float64( time.Now().Unix() );
|
||||
timestamp := float64(time.Now().Unix())
|
||||
|
||||
/* (3) Calculate the time id */
|
||||
var id = uint32( timestamp / wsize );
|
||||
var id = uint32(timestamp / wsize)
|
||||
|
||||
/* (4) Calculate parity */
|
||||
var parity = id % 2;
|
||||
var parity = id % 2
|
||||
|
||||
return id, parity;
|
||||
return id, parity
|
||||
}
|
||||
|
||||
|
||||
/* (2) Try to guess a previous time id from its parity
|
||||
*
|
||||
* @wsize<float64> Window Size in seconds
|
||||
|
@ -40,12 +40,12 @@ func Generate(wsize float64) (uint32, uint32){
|
|||
* @return id<uint32> The guessed time id
|
||||
*
|
||||
---------------------------------------------------------*/
|
||||
func Guess(wsize float64, parity uint32) uint32{
|
||||
func Guess(wsize float64, parity uint32) uint32 {
|
||||
|
||||
/* (1) Get current time id */
|
||||
var idNow, parityNow = Generate(wsize);
|
||||
var idNow, parityNow = Generate(wsize)
|
||||
|
||||
/* (2) Update ID with tidNow parity difference */
|
||||
return idNow - uint32(math.Abs( float64(parityNow) - float64(parity) ));
|
||||
return idNow - uint32(math.Abs(float64(parityNow)-float64(parity)))
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,23 +1,22 @@
|
|||
package timeid
|
||||
|
||||
import (
|
||||
"time"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestGuessing(t *testing.T) {
|
||||
|
||||
func TestGuessing(t *testing.T){
|
||||
var windowSize float64 = .5
|
||||
|
||||
var windowSize float64 = .5;
|
||||
id, parity := Generate(windowSize)
|
||||
|
||||
id, parity := Generate(windowSize);
|
||||
time.Sleep(time.Duration(windowSize) * time.Second)
|
||||
|
||||
time.Sleep( time.Duration(windowSize) * time.Second);
|
||||
|
||||
var guessedId = Guess(windowSize, parity);
|
||||
var guessedId = Guess(windowSize, parity)
|
||||
|
||||
if id != guessedId {
|
||||
t.Errorf("Wrong guessed id, expected '%d' ; got '%d'", id, guessedId);
|
||||
t.Errorf("Wrong guessed id, expected '%d' ; got '%d'", id, guessedId)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,11 +12,10 @@ import "math"
|
|||
---------------------------------------------------------*/
|
||||
func Byte(_left byte, _right byte) byte {
|
||||
|
||||
return _left ^ _right;
|
||||
return _left ^ _right
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* (2) bitwise XOR between Byte arrays
|
||||
*
|
||||
* @_left<byte[]> Left operand
|
||||
|
@ -43,16 +42,16 @@ func ByteArray(_left []byte, _right []byte) []byte {
|
|||
out := make([]byte, l, l)
|
||||
|
||||
/* (2) Process bitwise XOR */
|
||||
for i := 0 ; i < l ; i++ {
|
||||
for i := 0; i < l; i++ {
|
||||
|
||||
// 1. Out of range for _left
|
||||
if i >= ll {
|
||||
|
||||
out[i] = _right[i];
|
||||
out[i] = _right[i]
|
||||
|
||||
} else if i >= lr {
|
||||
|
||||
out[i] = _left[i];
|
||||
out[i] = _left[i]
|
||||
|
||||
} else {
|
||||
|
||||
|
|
116
server/server.go
116
server/server.go
|
@ -1,13 +1,13 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"git.xdrm.io/logauth/schastsp/context"
|
||||
"git.xdrm.io/logauth/schastsp/internal/scha"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"errors"
|
||||
"git.xdrm.io/logauth/schastsp/context"
|
||||
)
|
||||
|
||||
const DEBUG = false
|
||||
|
@ -15,12 +15,11 @@ const DEBUG = false
|
|||
/* (1) Structure
|
||||
---------------------------------------------------------*/
|
||||
type T struct {
|
||||
ctx *context.T // shared context
|
||||
hash []byte // current key
|
||||
conf string // configuration file path
|
||||
ctx *context.T // shared context
|
||||
hash []byte // current key
|
||||
conf string // configuration file path
|
||||
}
|
||||
|
||||
|
||||
/* (2) Constructor
|
||||
*
|
||||
* @ctx<context.T> Shared context
|
||||
|
@ -32,43 +31,49 @@ func New(ctx *context.T, savePath string) (*T, error) {
|
|||
inst := new(T)
|
||||
|
||||
/* (1) Store context */
|
||||
if ctx == nil { return nil, errors.New("Context must not be nil"); }
|
||||
inst.ctx = ctx;
|
||||
if ctx == nil {
|
||||
return nil, errors.New("Context must not be nil")
|
||||
}
|
||||
inst.ctx = ctx
|
||||
|
||||
/* (2) Get absolute file path */
|
||||
absolutePath, err := filepath.Abs(savePath);
|
||||
if err != nil { return nil, err; }
|
||||
absolutePath, err := filepath.Abs(savePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
/* (3) Check file */
|
||||
info, err := os.Stat(absolutePath);
|
||||
info, err := os.Stat(absolutePath)
|
||||
if err != nil {
|
||||
|
||||
// Unknown error
|
||||
if !os.IsNotExist(err) { return nil, err }
|
||||
if !os.IsNotExist(err) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// File does not exist -> try to create file
|
||||
_, err2 := os.Create(absolutePath);
|
||||
if err2 != nil { return nil, err2 }
|
||||
_, err2 := os.Create(absolutePath)
|
||||
if err2 != nil {
|
||||
return nil, err2
|
||||
}
|
||||
|
||||
// fail if exists but not regular file
|
||||
// fail if exists but not regular file
|
||||
} else if !info.Mode().IsRegular() {
|
||||
return nil, errors.New("Configuration file is not a regular file");
|
||||
return nil, errors.New("Configuration file is not a regular file")
|
||||
}
|
||||
|
||||
/* (4) Store file path */
|
||||
inst.conf = absolutePath;
|
||||
inst.conf = absolutePath
|
||||
|
||||
/* (5) Try to fetch hash from conf */
|
||||
inst.hash = make([]byte, scha.HSIZE)
|
||||
err = inst.fetch();
|
||||
err = inst.fetch()
|
||||
// if err != nil { return nil, err }
|
||||
|
||||
return inst, nil;
|
||||
return inst, nil
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* (3) Handle request and send response
|
||||
*
|
||||
* @req<io.Reader> Request reader
|
||||
|
@ -82,33 +87,44 @@ func (s *T) HandleRequest(req io.Reader, res io.Writer) error {
|
|||
/* (1) Manage request
|
||||
---------------------------------------------------------*/
|
||||
/* (1) Read x1 */
|
||||
x1 := make([]byte, scha.HSIZE);
|
||||
read, err := req.Read(x1);
|
||||
if err != nil { return fmt.Errorf("Reading x1 : %s", err) }
|
||||
if uint16(read) != scha.HSIZE { return fmt.Errorf("Cannot read x1 : %d / %d bytes available", read, scha.HSIZE) }
|
||||
x1 := make([]byte, scha.HSIZE)
|
||||
read, err := req.Read(x1)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Reading x1 : %s", err)
|
||||
}
|
||||
if uint16(read) != scha.HSIZE {
|
||||
return fmt.Errorf("Cannot read x1 : %d / %d bytes available", read, scha.HSIZE)
|
||||
}
|
||||
|
||||
/* (2) Read x2 */
|
||||
x2 := make([]byte, scha.HSIZE);
|
||||
read, err = req.Read(x2);
|
||||
if err != nil { return fmt.Errorf("Reading x2 : %s", err) }
|
||||
if uint16(read) != scha.HSIZE { return fmt.Errorf("Cannot read x2 : %d / %d bytes available", read, scha.HSIZE) }
|
||||
x2 := make([]byte, scha.HSIZE)
|
||||
read, err = req.Read(x2)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Reading x2 : %s", err)
|
||||
}
|
||||
if uint16(read) != scha.HSIZE {
|
||||
return fmt.Errorf("Cannot read x2 : %d / %d bytes available", read, scha.HSIZE)
|
||||
}
|
||||
|
||||
/* (3) Manage request */
|
||||
errCode, err := s.manageRequest(x1, x2)
|
||||
if err != nil { return err }
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
/* (4) Valid authentication */
|
||||
if errCode == 0 {
|
||||
|
||||
response := []byte{0x00}
|
||||
written, err := res.Write(response)
|
||||
if written != 1 || err != nil { return err }
|
||||
if written != 1 || err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil;
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* (2) If not authenticated -> build resynchronisation response
|
||||
---------------------------------------------------------*/
|
||||
/* (1) Init y1 + y2 */
|
||||
|
@ -117,29 +133,41 @@ func (s *T) HandleRequest(req io.Reader, res io.Writer) error {
|
|||
|
||||
/* (2) Generate response */
|
||||
err = s.generateResynchronisationResponse(y1, y2)
|
||||
if err != nil { return err }
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
/* (3) Write error code */
|
||||
responseCode := []byte{errCode}
|
||||
written, err := res.Write(responseCode);
|
||||
if err != nil { return err }
|
||||
if written != len(responseCode) { return errors.New("Cannot write response code") }
|
||||
written, err := res.Write(responseCode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if written != len(responseCode) {
|
||||
return errors.New("Cannot write response code")
|
||||
}
|
||||
|
||||
/* (4) Write y1 into response */
|
||||
written, err = res.Write(y1)
|
||||
if err != nil { return err }
|
||||
if written != len(y1) { return errors.New("Cannot write y1") }
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if written != len(y1) {
|
||||
return errors.New("Cannot write y1")
|
||||
}
|
||||
|
||||
/* (5) Write y2 into response */
|
||||
written, err = res.Write(y2)
|
||||
if err != nil { return err }
|
||||
if written != len(y1) { return errors.New("Cannot write y2") }
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if written != len(y1) {
|
||||
return errors.New("Cannot write y2")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* (4) Apply a synchronisation key
|
||||
*
|
||||
* @syncKey<[]byte> Synchronisation key from client
|
||||
|
@ -162,4 +190,4 @@ func (s *T) SynchronisationKey(syncKey []byte) error {
|
|||
|
||||
return nil
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,14 +19,18 @@ func (s T) store() error {
|
|||
|
||||
/* (1) Try to open file for writing */
|
||||
file, err := os.OpenFile(s.conf, os.O_RDWR|os.O_CREATE, 0755)
|
||||
if err != nil { return err }
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
/* (2) Defer close */
|
||||
defer file.Close()
|
||||
|
||||
/* (3) Write hash into file */
|
||||
err = binary.Write(file, binary.BigEndian, s.hash)
|
||||
if err != nil { return err }
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
|
@ -41,7 +45,9 @@ func (s *T) fetch() error {
|
|||
|
||||
/* (1) Try to open file for reading */
|
||||
file, err := os.Open(s.conf)
|
||||
if err != nil { return err }
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
/* (2) Defer close */
|
||||
defer file.Close()
|
||||
|
@ -49,7 +55,9 @@ func (s *T) fetch() error {
|
|||
/* (3) Try to fetch hash from file */
|
||||
fetchedHash := make([]byte, scha.HSIZE)
|
||||
err = binary.Read(file, binary.BigEndian, fetchedHash)
|
||||
if err != nil { return err }
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
/* (4) Fail if wrong size */
|
||||
if uint16(len(fetchedHash)) != scha.HSIZE {
|
||||
|
@ -77,7 +85,9 @@ func (s *T) fetch() error {
|
|||
---------------------------------------------------------*/
|
||||
func (s *T) manageRequest(x1 []byte, x2 []byte) (byte, error) {
|
||||
|
||||
if DEBUG { fmt.Printf(" stored hash is H = %x\n", s.hash) }
|
||||
if DEBUG {
|
||||
fmt.Printf(" stored hash is H = %x\n", s.hash)
|
||||
}
|
||||
|
||||
/* (1) Extract meta data
|
||||
---------------------------------------------------------*/
|
||||
|
@ -86,19 +96,22 @@ func (s *T) manageRequest(x1 []byte, x2 []byte) (byte, error) {
|
|||
|
||||
/* (2) Extract migration code */
|
||||
mcode := uint8(x[1]) % 3
|
||||
if DEBUG { fmt.Printf(" extracted code is o = %d\n", mcode) }
|
||||
if DEBUG {
|
||||
fmt.Printf(" extracted code is o = %d\n", mcode)
|
||||
}
|
||||
|
||||
/* (3) Fail if no migration but different hashes */
|
||||
if mcode == 0 && string(x1[2:]) != string(x2[2:]) {
|
||||
return 1, nil
|
||||
}
|
||||
|
||||
|
||||
/* (2) TimeID management
|
||||
---------------------------------------------------------*/
|
||||
/* (1) Extract time mod */
|
||||
timeMod := uint32(x[0]) % 2
|
||||
if DEBUG { fmt.Printf(" extracted time mod m = %d\n", timeMod) }
|
||||
if DEBUG {
|
||||
fmt.Printf(" extracted time mod m = %d\n", timeMod)
|
||||
}
|
||||
|
||||
/* (2) Try to guess time id */
|
||||
timeID := timeid.Guess(s.ctx.Window(), timeMod)
|
||||
|
@ -107,35 +120,43 @@ func (s *T) manageRequest(x1 []byte, x2 []byte) (byte, error) {
|
|||
|
||||
/* (3) Hash guessed time id */
|
||||
hashedTimeID, err := scha.Hash(timeIDBytes, 1)
|
||||
if err != nil { return 2, err }
|
||||
|
||||
if err != nil {
|
||||
return 2, err
|
||||
}
|
||||
|
||||
/* (3) Extract hashes
|
||||
---------------------------------------------------------*/
|
||||
/* (1) Extract hash from x0 */
|
||||
h0 := xor.ByteArray(x1, hashedTimeID)
|
||||
if DEBUG { fmt.Printf(" supposing hash is h0 = %x\n", h0) }
|
||||
if DEBUG {
|
||||
fmt.Printf(" supposing hash is h0 = %x\n", h0)
|
||||
}
|
||||
|
||||
/* (2) Extract next hash from x1 */
|
||||
h1 := xor.ByteArray(x2, hashedTimeID)
|
||||
if DEBUG { fmt.Printf(" supposing next is h1 = %x\n", h1) }
|
||||
if DEBUG {
|
||||
fmt.Printf(" supposing next is h1 = %x\n", h1)
|
||||
}
|
||||
|
||||
/* (3) Only remove timeMod if migration code = 0 */
|
||||
if mcode == 0 {
|
||||
h1[0] = xor.Byte(h1[0], byte(timeMod))
|
||||
}
|
||||
|
||||
|
||||
/* (4) Hash h0 to compare with stored hash 's.hash'
|
||||
---------------------------------------------------------*/
|
||||
/* (1) Hash 1 time to check if matches */
|
||||
hashedH0, err := scha.Hash(h0, 1)
|
||||
if err != nil { return 2, err }
|
||||
if err != nil {
|
||||
return 2, err
|
||||
}
|
||||
|
||||
/* (2) If migration code = 2 (Rescue mode) -> hash MIN times */
|
||||
if mcode == 2 {
|
||||
hashedH0, err = scha.Hash(h0, s.ctx.MinDepth())
|
||||
if err != nil { return 2, err }
|
||||
if err != nil {
|
||||
return 2, err
|
||||
}
|
||||
|
||||
if DEBUG {
|
||||
fmt.Printf(" hashed is h(min) = %x\n", hashedH0)
|
||||
|
@ -149,7 +170,6 @@ func (s *T) manageRequest(x1 []byte, x2 []byte) (byte, error) {
|
|||
return 1, nil
|
||||
}
|
||||
|
||||
|
||||
/* (5) Store next hash
|
||||
---------------------------------------------------------*/
|
||||
copy(s.hash, h1)
|
||||
|
@ -177,7 +197,9 @@ func (s *T) generateResynchronisationResponse(y1 []byte, y2 []byte) error {
|
|||
binary.BigEndian.PutUint32(timeIDBytes, timeID)
|
||||
|
||||
hashedTimeID, err := scha.Hash(timeIDBytes, 1)
|
||||
if err != nil { return err }
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
/* (4) Process y1 = H ^ h(timeId) */
|
||||
copy(y1, xor.ByteArray(s.hash, hashedTimeID))
|
||||
|
|
Loading…
Reference in New Issue