update structure
This commit is contained in:
parent
3a77463614
commit
9c23c060b5
|
@ -7,8 +7,8 @@ import (
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"git.xdrm.io/schastsp/context"
|
"git.xdrm.io/schastsp/context"
|
||||||
"git.xdrm.io/schastsp/client"
|
"git.xdrm.io/schastsp/internal/client"
|
||||||
"git.xdrm.io/schastsp/server"
|
"git.xdrm.io/schastsp/internal/server"
|
||||||
)
|
)
|
||||||
|
|
||||||
/* Store target config paths */
|
/* Store target config paths */
|
||||||
|
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"git.xdrm.io/schastsp/client/keyset"
|
"git.xdrm.io/schastsp/client/keyset"
|
||||||
"git.xdrm.io/schastsp/context"
|
"git.xdrm.io/schastsp/context"
|
||||||
"git.xdrm.io/schastsp/pkg/scha"
|
"git.xdrm.io/schastsp/util/scha"
|
||||||
"io"
|
"io"
|
||||||
)
|
)
|
||||||
|
|
|
@ -4,9 +4,9 @@ import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"git.xdrm.io/schastsp/client/keyset"
|
"git.xdrm.io/schastsp/client/keyset"
|
||||||
"git.xdrm.io/schastsp/pkg/scha"
|
"git.xdrm.io/schastsp/util/scha"
|
||||||
"git.xdrm.io/schastsp/pkg/timeid"
|
"git.xdrm.io/schastsp/util/timeid"
|
||||||
"git.xdrm.io/schastsp/pkg/xor"
|
"git.xdrm.io/schastsp/util/xor"
|
||||||
)
|
)
|
||||||
|
|
||||||
/* (1) Updates 'key' and 'sync' with files
|
/* (1) Updates 'key' and 'sync' with files
|
|
@ -1,7 +1,7 @@
|
||||||
package client;
|
package client;
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.xdrm.io/schastsp/client/keyset"
|
"git.xdrm.io/schastsp/internal/client/keyset"
|
||||||
"fmt"
|
"fmt"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"errors"
|
"errors"
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
"git.xdrm.io/schastsp/context"
|
"git.xdrm.io/schastsp/context"
|
||||||
"git.xdrm.io/schastsp/pkg/scha"
|
"git.xdrm.io/schastsp/util/scha"
|
||||||
"io"
|
"io"
|
||||||
)
|
)
|
||||||
|
|
|
@ -2,7 +2,7 @@ package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"git.xdrm.io/schastsp/pkg/scha"
|
"git.xdrm.io/schastsp/util/scha"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
|
@ -4,9 +4,9 @@ import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"git.xdrm.io/schastsp/pkg/scha"
|
"git.xdrm.io/schastsp/util/scha"
|
||||||
"git.xdrm.io/schastsp/pkg/timeid"
|
"git.xdrm.io/schastsp/util/timeid"
|
||||||
"git.xdrm.io/schastsp/pkg/xor"
|
"git.xdrm.io/schastsp/util/xor"
|
||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,101 @@
|
||||||
|
package scha
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"crypto/sha512"
|
||||||
|
"git.xdrm.io/schastsp/pkg/xor"
|
||||||
|
)
|
||||||
|
|
||||||
|
/* (0) Static
|
||||||
|
---------------------------------------------------------*/
|
||||||
|
/* (1) Constants */
|
||||||
|
const HSIZE uint16 = sha512.Size;
|
||||||
|
const HBITSIZE uint32 = uint32(HSIZE) * 8;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* (1) Basic hash function
|
||||||
|
*
|
||||||
|
* @input<[]byte> Byte array input
|
||||||
|
*
|
||||||
|
* @return digest<[]byte]> Byte array digest
|
||||||
|
*
|
||||||
|
---------------------------------------------------------*/
|
||||||
|
func hash(input []byte) []byte{
|
||||||
|
|
||||||
|
/* (1) Create sha512 hasher */
|
||||||
|
hasher := sha512.New();
|
||||||
|
|
||||||
|
/* (2) Defer memory cleanup */
|
||||||
|
defer hasher.Reset();
|
||||||
|
|
||||||
|
/* (3) Set input to be hashed */
|
||||||
|
hasher.Write(input);
|
||||||
|
|
||||||
|
/* (4) Extract digest */
|
||||||
|
return hasher.Sum(nil);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* (2) Public hashing interface
|
||||||
|
*
|
||||||
|
* @input<[]byte> Byte array input
|
||||||
|
* @depth<uint> Number of time to hash recursively (must be > 1)
|
||||||
|
* @salt<[]byte> [OPT] Optional salt
|
||||||
|
* @pepper<[]byte> [OPT] Optional pepper
|
||||||
|
*
|
||||||
|
* @return digest<[]byte]> Byte array digest
|
||||||
|
* @return err<error> If consistence 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");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (2) Avoir empty input */
|
||||||
|
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] }
|
||||||
|
|
||||||
|
/* (2) Optional pepper */
|
||||||
|
pepper := make([]byte, 0)
|
||||||
|
if len(options) > 0 { pepper = options[0] }
|
||||||
|
|
||||||
|
|
||||||
|
/* (3) Process cyclic hash
|
||||||
|
---------------------------------------------------------*/
|
||||||
|
/* (1) Initialise digest */
|
||||||
|
digest := make([]byte, 0, HSIZE)
|
||||||
|
|
||||||
|
/* (2) Process first hash + 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) )
|
||||||
|
} else {
|
||||||
|
digest = hash(digest)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return digest, nil
|
||||||
|
}
|
|
@ -0,0 +1,156 @@
|
||||||
|
package scha
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestSimpleHash(t *testing.T){
|
||||||
|
|
||||||
|
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));
|
||||||
|
|
||||||
|
/* (2) Fail on errors */
|
||||||
|
if err != nil {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (3) Check each byte */
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func TestDepth1Plus1Equals2(t *testing.T){
|
||||||
|
|
||||||
|
input := []byte("someOtherPlainText");
|
||||||
|
|
||||||
|
/* (1) Calculate H1 */
|
||||||
|
h1, err := Hash(input, 1)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Expected no error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (2) Calculate H1(H1) */
|
||||||
|
h11, err := Hash(h1, 1);
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Expected no error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (3) Calculate H2 */
|
||||||
|
h2, err := Hash(input, 1+1);
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func TestDepth52Plus64Equals116(t *testing.T){
|
||||||
|
|
||||||
|
input := []byte("someOtherPlainText");
|
||||||
|
|
||||||
|
/* (1) Calculate H52 */
|
||||||
|
h52, err := Hash(input, 52)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Expected no error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (2) Calculate H52(H64) */
|
||||||
|
h5264, err := Hash(h52, 64);
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Expected no error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (3) Calculate H116 */
|
||||||
|
h116, err := Hash(input, 52+64);
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func TestDepthError(t *testing.T){
|
||||||
|
|
||||||
|
input := []byte("somePlainText");
|
||||||
|
_, err := Hash(input, 0);
|
||||||
|
|
||||||
|
/* (2) Fail on errors */
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("Expected an error for depth of 0");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func TestEmptyInputError(t *testing.T){
|
||||||
|
|
||||||
|
_, err := Hash(nil, 1);
|
||||||
|
|
||||||
|
/* (2) Fail on errors */
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("Expected an error for empty input");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
package timeid
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
/* (1) Generates the current time id
|
||||||
|
*
|
||||||
|
* @wsize<float64> Window Size in seconds
|
||||||
|
*
|
||||||
|
* @return id<uint32> Current time id
|
||||||
|
* @return parity<uint32> Current time parity
|
||||||
|
*
|
||||||
|
---------------------------------------------------------*/
|
||||||
|
func Generate(wsize float64) (uint32, uint32){
|
||||||
|
|
||||||
|
/* (1) If wsize is 0 (div by zero possible error) */
|
||||||
|
if wsize == 0 { return 0, 0 }
|
||||||
|
|
||||||
|
/* (2) Get current timestamp */
|
||||||
|
timestamp := float64( time.Now().Unix() );
|
||||||
|
|
||||||
|
/* (3) Calculate the time id */
|
||||||
|
var id = uint32( timestamp / wsize );
|
||||||
|
|
||||||
|
/* (4) Calculate parity */
|
||||||
|
var parity = id % 2;
|
||||||
|
|
||||||
|
return id, parity;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* (2) Try to guess a previous time id from its parity
|
||||||
|
*
|
||||||
|
* @wsize<float64> Window Size in seconds
|
||||||
|
* @parity<uint32> Received parity
|
||||||
|
*
|
||||||
|
* @return id<uint32> The guessed time id
|
||||||
|
*
|
||||||
|
---------------------------------------------------------*/
|
||||||
|
func Guess(wsize float64, parity uint32) uint32{
|
||||||
|
|
||||||
|
/* (1) Get current time id */
|
||||||
|
var idNow, parityNow = Generate(wsize);
|
||||||
|
|
||||||
|
/* (2) Update ID with tidNow parity difference */
|
||||||
|
return idNow - uint32(math.Abs( float64(parityNow) - float64(parity) ));
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package timeid
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func TestGuessing(t *testing.T){
|
||||||
|
|
||||||
|
var windowSize float64 = .5;
|
||||||
|
|
||||||
|
id, parity := Generate(windowSize);
|
||||||
|
|
||||||
|
time.Sleep( time.Duration(windowSize) * time.Second);
|
||||||
|
|
||||||
|
var guessedId = Guess(windowSize, parity);
|
||||||
|
|
||||||
|
if id != guessedId {
|
||||||
|
t.Errorf("Wrong guessed id, expected '%d' ; got '%d'", id, guessedId);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
package xor
|
||||||
|
|
||||||
|
import "math"
|
||||||
|
|
||||||
|
/* (1) bitwise XOR between bytes
|
||||||
|
*
|
||||||
|
* @_left<byte> Left operand
|
||||||
|
* @_right<byte> Right operand
|
||||||
|
*
|
||||||
|
* @return out<byte> Bitwise XOR result between _left and _right
|
||||||
|
*
|
||||||
|
---------------------------------------------------------*/
|
||||||
|
func Byte(_left byte, _right byte) byte {
|
||||||
|
|
||||||
|
return _left ^ _right;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* (2) bitwise XOR between Byte arrays
|
||||||
|
*
|
||||||
|
* @_left<byte[]> Left operand
|
||||||
|
* @_right<byte[]> Right operand
|
||||||
|
*
|
||||||
|
* @return out<byte[]> Bitwise XOR result between _left and _right
|
||||||
|
*
|
||||||
|
* @@ NOTE @@
|
||||||
|
* If an argument is smaller, it will be right-padded with null bytes (0x00)
|
||||||
|
*
|
||||||
|
---------------------------------------------------------*/
|
||||||
|
func ByteArray(_left []byte, _right []byte) []byte {
|
||||||
|
|
||||||
|
/* (1) Process
|
||||||
|
---------------------------------------------------------*/
|
||||||
|
/* (1) Extract lengths */
|
||||||
|
ll := len(_left)
|
||||||
|
lr := len(_right)
|
||||||
|
|
||||||
|
/* (2) Get max length */
|
||||||
|
l := int(math.Max(float64(ll), float64(lr)))
|
||||||
|
|
||||||
|
/* (3) Initialise 'out' */
|
||||||
|
out := make([]byte, l, l)
|
||||||
|
|
||||||
|
/* (2) Process bitwise XOR */
|
||||||
|
for i := 0 ; i < l ; i++ {
|
||||||
|
|
||||||
|
// 1. Out of range for _left
|
||||||
|
if i >= ll {
|
||||||
|
|
||||||
|
out[i] = _right[i];
|
||||||
|
|
||||||
|
} else if i >= lr {
|
||||||
|
|
||||||
|
out[i] = _left[i];
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
out[i] = Byte(_left[i], _right[i])
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return out
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue