feat(destination): implement hash calculation for PLAIN destination and update identity handling in destination creation
This commit is contained in:
@@ -107,9 +107,9 @@ type Destination struct {
|
||||
func New(id *identity.Identity, direction byte, destType byte, appName string, transport Transport, aspects ...string) (*Destination, error) {
|
||||
debug.Log(debug.DEBUG_INFO, "Creating new destination", "app", appName, "type", destType, "direction", direction)
|
||||
|
||||
if id == nil {
|
||||
debug.Log(debug.DEBUG_ERROR, "Cannot create destination: identity is nil")
|
||||
return nil, errors.New("identity cannot be nil")
|
||||
if id == nil && destType != PLAIN {
|
||||
debug.Log(debug.DEBUG_ERROR, "Cannot create destination: identity is nil for non-PLAIN destination")
|
||||
return nil, errors.New("identity cannot be nil for non-PLAIN destination")
|
||||
}
|
||||
|
||||
d := &Destination{
|
||||
@@ -144,9 +144,9 @@ func New(id *identity.Identity, direction byte, destType byte, appName string, t
|
||||
func FromHash(hash []byte, id *identity.Identity, destType byte, transport Transport) (*Destination, error) {
|
||||
debug.Log(debug.DEBUG_INFO, "Creating destination from hash", "hash", fmt.Sprintf("%x", hash))
|
||||
|
||||
if id == nil {
|
||||
debug.Log(debug.DEBUG_ERROR, "Cannot create destination: identity is nil")
|
||||
return nil, errors.New("identity cannot be nil")
|
||||
if id == nil && destType != PLAIN {
|
||||
debug.Log(debug.DEBUG_ERROR, "Cannot create destination: identity is nil for non-PLAIN destination")
|
||||
return nil, errors.New("identity cannot be nil for non-PLAIN destination")
|
||||
}
|
||||
|
||||
d := &Destination{
|
||||
@@ -169,19 +169,25 @@ func FromHash(hash []byte, id *identity.Identity, destType byte, transport Trans
|
||||
func (d *Destination) calculateHash() []byte {
|
||||
debug.Log(debug.DEBUG_TRACE, "Calculating hash for destination", "name", d.ExpandName())
|
||||
|
||||
// destination_hash = SHA256(name_hash_10bytes + identity_hash_16bytes)[:16]
|
||||
// Identity hash is the truncated hash of the public key (16 bytes)
|
||||
identityHash := identity.TruncatedHash(d.identity.GetPublicKey())
|
||||
|
||||
// Name hash is the FULL 32-byte SHA256, then we take first 10 bytes for concatenation
|
||||
nameHashFull := sha256.Sum256([]byte(d.ExpandName()))
|
||||
nameHash10 := nameHashFull[:10] // Only use 10 bytes
|
||||
|
||||
debug.Log(debug.DEBUG_ALL, "Identity hash", "hash", fmt.Sprintf("%x", identityHash))
|
||||
debug.Log(debug.DEBUG_ALL, "Name hash (10 bytes)", "hash", fmt.Sprintf("%x", nameHash10))
|
||||
var combined []byte
|
||||
if d.identity != nil {
|
||||
// destination_hash = SHA256(name_hash_10bytes + identity_hash_16bytes)[:16]
|
||||
// Identity hash is the truncated hash of the public key (16 bytes)
|
||||
identityHash := identity.TruncatedHash(d.identity.GetPublicKey())
|
||||
debug.Log(debug.DEBUG_ALL, "Identity hash", "hash", fmt.Sprintf("%x", identityHash))
|
||||
debug.Log(debug.DEBUG_ALL, "Name hash (10 bytes)", "hash", fmt.Sprintf("%x", nameHash10))
|
||||
|
||||
// Concatenate name_hash (10 bytes) + identity_hash (16 bytes) = 26 bytes
|
||||
combined := append(nameHash10, identityHash...)
|
||||
// Concatenate name_hash (10 bytes) + identity_hash (16 bytes) = 26 bytes
|
||||
combined = append(nameHash10, identityHash...)
|
||||
} else {
|
||||
// PLAIN destination has no identity hash
|
||||
combined = nameHash10
|
||||
debug.Log(debug.DEBUG_ALL, "Name hash (10 bytes)", "hash", fmt.Sprintf("%x", nameHash10))
|
||||
}
|
||||
|
||||
// Then hash again and truncate to 16 bytes
|
||||
finalHashFull := sha256.Sum256(combined)
|
||||
|
||||
@@ -2,6 +2,7 @@ package destination
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/sha256"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
@@ -150,3 +151,28 @@ func TestPlainDestination(t *testing.T) {
|
||||
t.Error("Plain destination should not decrypt")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPlainDestinationHash(t *testing.T) {
|
||||
// A PLAIN destination with no identity should have a hash based only on its name
|
||||
transport := &mockTransport{}
|
||||
dest, err := New(nil, IN|OUT, PLAIN, "testapp", transport, "testaspect")
|
||||
if err != nil {
|
||||
t.Fatalf("New failed: %v", err)
|
||||
}
|
||||
|
||||
hash := dest.GetHash()
|
||||
if len(hash) != 16 {
|
||||
t.Fatalf("Expected hash length 16, got %d", len(hash))
|
||||
}
|
||||
|
||||
// Calculate manually: SHA256(SHA256("testapp.testaspect")[:10])[:16]
|
||||
name := "testapp.testaspect"
|
||||
nameHashFull := sha256.Sum256([]byte(name))
|
||||
nameHash10 := nameHashFull[:10]
|
||||
finalHashFull := sha256.Sum256(nameHash10)
|
||||
expectedHash := finalHashFull[:16]
|
||||
|
||||
if !bytes.Equal(hash, expectedHash) {
|
||||
t.Errorf("Expected hash %x, got %x", expectedHash, hash)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user