From 1cc185cb35be3a6e6656c4621a2c6a58c4d3af5b Mon Sep 17 00:00:00 2001 From: Virgil Date: Tue, 31 Mar 2026 05:24:39 +0000 Subject: [PATCH] Align node and sigil APIs with AX principles --- node/node.go | 27 ++++++--------------------- node/node_test.go | 17 ----------------- sigil/crypto_sigil.go | 30 ++++++------------------------ sigil/crypto_sigil_test.go | 38 +++++++++++++++++++------------------- 4 files changed, 31 insertions(+), 81 deletions(-) diff --git a/node/node.go b/node/node.go index 45de545..00237b1 100644 --- a/node/node.go +++ b/node/node.go @@ -122,11 +122,6 @@ func (node *Node) LoadTar(data []byte) error { return nil } -// Example: _ = nodeTree.WalkNode("config", func(_ string, _ fs.DirEntry, _ error) error { return nil }) -func (node *Node) WalkNode(root string, fn fs.WalkDirFunc) error { - return node.Walk(root, fn) -} - // Example: options := node.WalkOptions{MaxDepth: 1, SkipErrors: true} type WalkOptions struct { MaxDepth int @@ -135,21 +130,16 @@ type WalkOptions struct { } // Example: _ = nodeTree.Walk(".", func(_ string, _ fs.DirEntry, _ error) error { return nil }, node.WalkOptions{MaxDepth: 1, SkipErrors: true}) -func (node *Node) Walk(root string, fn fs.WalkDirFunc, options ...WalkOptions) error { - walkOptions := WalkOptions{} - if len(options) > 0 { - walkOptions = options[0] - } - - if walkOptions.SkipErrors { +func (node *Node) Walk(root string, fn fs.WalkDirFunc, options WalkOptions) error { + if options.SkipErrors { if _, err := node.Stat(root); err != nil { return nil } } return fs.WalkDir(node, root, func(entryPath string, entry fs.DirEntry, err error) error { - if walkOptions.Filter != nil && err == nil { - if !walkOptions.Filter(entryPath, entry) { + if options.Filter != nil && err == nil { + if !options.Filter(entryPath, entry) { if entry != nil && entry.IsDir() { return fs.SkipDir } @@ -159,11 +149,11 @@ func (node *Node) Walk(root string, fn fs.WalkDirFunc, options ...WalkOptions) e result := fn(entryPath, entry, err) - if result == nil && walkOptions.MaxDepth > 0 && entry != nil && entry.IsDir() && entryPath != root { + if result == nil && options.MaxDepth > 0 && entry != nil && entry.IsDir() && entryPath != root { rel := core.TrimPrefix(entryPath, root) rel = core.TrimPrefix(rel, "/") depth := len(core.Split(rel, "/")) - if depth >= walkOptions.MaxDepth { + if depth >= options.MaxDepth { return fs.SkipDir } } @@ -172,11 +162,6 @@ func (node *Node) Walk(root string, fn fs.WalkDirFunc, options ...WalkOptions) e }) } -// Example: _ = nodeTree.WalkWithOptions(".", func(_ string, _ fs.DirEntry, _ error) error { return nil }, node.WalkOptions{MaxDepth: 1, SkipErrors: true}) -func (node *Node) WalkWithOptions(root string, fn fs.WalkDirFunc, options WalkOptions) error { - return node.Walk(root, fn, options) -} - // Example: content, _ := nodeTree.ReadFile("config/app.yaml") func (node *Node) ReadFile(name string) ([]byte, error) { name = core.TrimPrefix(name, "/") diff --git a/node/node_test.go b/node/node_test.go index 8880c4e..61f24b1 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -357,23 +357,6 @@ func TestNode_Walk_Good(t *testing.T) { }) } -func TestNode_WalkNode_Good(t *testing.T) { - n := New() - n.AddData("alpha.txt", []byte("alpha")) - n.AddData("nested/beta.txt", []byte("beta")) - - var paths []string - err := n.WalkNode(".", func(p string, d fs.DirEntry, err error) error { - require.NoError(t, err) - paths = append(paths, p) - return nil - }) - require.NoError(t, err) - - sort.Strings(paths) - assert.Equal(t, []string{".", "alpha.txt", "nested", "nested/beta.txt"}, paths) -} - // --------------------------------------------------------------------------- // CopyFile // --------------------------------------------------------------------------- diff --git a/sigil/crypto_sigil.go b/sigil/crypto_sigil.go index 798c24f..306f702 100644 --- a/sigil/crypto_sigil.go +++ b/sigil/crypto_sigil.go @@ -1,4 +1,4 @@ -// Example: cipherSigil, _ := sigil.NewChaChaPolySigil([]byte("0123456789abcdef0123456789abcdef")) +// Example: cipherSigil, _ := sigil.NewChaChaPolySigil([]byte("0123456789abcdef0123456789abcdef"), nil) // Example: ciphertext, _ := cipherSigil.In([]byte("payload")) // Example: plaintext, _ := cipherSigil.Out(ciphertext) package sigil @@ -171,7 +171,7 @@ func (obfuscator *ShuffleMaskObfuscator) deriveMask(entropy []byte, length int) } // Example: cipherSigil, _ := sigil.NewChaChaPolySigil( -// Example: key, +// Example: []byte("0123456789abcdef0123456789abcdef"), // Example: &sigil.ShuffleMaskObfuscator{}, // Example: ) type ChaChaPolySigil struct { @@ -180,10 +180,10 @@ type ChaChaPolySigil struct { randomReader goio.Reader } -// Example: cipherSigil, _ := sigil.NewChaChaPolySigil([]byte("0123456789abcdef0123456789abcdef")) +// Example: cipherSigil, _ := sigil.NewChaChaPolySigil([]byte("0123456789abcdef0123456789abcdef"), nil) // Example: ciphertext, _ := cipherSigil.In([]byte("payload")) // Example: plaintext, _ := cipherSigil.Out(ciphertext) -func NewChaChaPolySigil(key []byte, obfuscators ...PreObfuscator) (*ChaChaPolySigil, error) { +func NewChaChaPolySigil(key []byte, obfuscator PreObfuscator) (*ChaChaPolySigil, error) { if len(key) != 32 { return nil, InvalidKeyError } @@ -191,9 +191,8 @@ func NewChaChaPolySigil(key []byte, obfuscators ...PreObfuscator) (*ChaChaPolySi keyCopy := make([]byte, 32) copy(keyCopy, key) - obfuscator := PreObfuscator(&XORObfuscator{}) - if len(obfuscators) > 0 && obfuscators[0] != nil { - obfuscator = obfuscators[0] + if obfuscator == nil { + obfuscator = &XORObfuscator{} } return &ChaChaPolySigil{ @@ -203,23 +202,6 @@ func NewChaChaPolySigil(key []byte, obfuscators ...PreObfuscator) (*ChaChaPolySi }, nil } -// Example: cipherSigil, _ := sigil.NewChaChaPolySigil( -// Example: []byte("0123456789abcdef0123456789abcdef"), -// Example: &sigil.ShuffleMaskObfuscator{}, -// Example: ) -// Example: ciphertext, _ := cipherSigil.In([]byte("payload")) -// Example: plaintext, _ := cipherSigil.Out(ciphertext) -func NewChaChaPolySigilWithObfuscator(key []byte, obfuscator PreObfuscator) (*ChaChaPolySigil, error) { - cipherSigil, err := NewChaChaPolySigil(key, obfuscator) - if err != nil { - return nil, err - } - if obfuscator != nil { - cipherSigil.Obfuscator = obfuscator - } - return cipherSigil, nil -} - func (sigil *ChaChaPolySigil) In(data []byte) ([]byte, error) { if sigil.Key == nil { return nil, NoKeyConfiguredError diff --git a/sigil/crypto_sigil_test.go b/sigil/crypto_sigil_test.go index 7f1425c..367043f 100644 --- a/sigil/crypto_sigil_test.go +++ b/sigil/crypto_sigil_test.go @@ -150,7 +150,7 @@ func TestCryptoSigil_NewChaChaPolySigil_Good(t *testing.T) { key := make([]byte, 32) _, _ = rand.Read(key) - s, err := NewChaChaPolySigil(key) + s, err := NewChaChaPolySigil(key, nil) require.NoError(t, err) assert.NotNil(t, s) assert.Equal(t, key, s.Key) @@ -163,7 +163,7 @@ func TestCryptoSigil_NewChaChaPolySigil_KeyIsCopied_Good(t *testing.T) { original := make([]byte, 32) copy(original, key) - s, err := NewChaChaPolySigil(key) + s, err := NewChaChaPolySigil(key, nil) require.NoError(t, err) // Mutating the original key should not affect the sigil. @@ -172,17 +172,17 @@ func TestCryptoSigil_NewChaChaPolySigil_KeyIsCopied_Good(t *testing.T) { } func TestCryptoSigil_NewChaChaPolySigil_ShortKey_Bad(t *testing.T) { - _, err := NewChaChaPolySigil([]byte("too short")) + _, err := NewChaChaPolySigil([]byte("too short"), nil) assert.ErrorIs(t, err, InvalidKeyError) } func TestCryptoSigil_NewChaChaPolySigil_LongKey_Bad(t *testing.T) { - _, err := NewChaChaPolySigil(make([]byte, 64)) + _, err := NewChaChaPolySigil(make([]byte, 64), nil) assert.ErrorIs(t, err, InvalidKeyError) } func TestCryptoSigil_NewChaChaPolySigil_EmptyKey_Bad(t *testing.T) { - _, err := NewChaChaPolySigil(nil) + _, err := NewChaChaPolySigil(nil, nil) assert.ErrorIs(t, err, InvalidKeyError) } @@ -219,7 +219,7 @@ func TestCryptoSigil_ChaChaPolySigil_RoundTrip_Good(t *testing.T) { key := make([]byte, 32) _, _ = rand.Read(key) - s, err := NewChaChaPolySigil(key) + s, err := NewChaChaPolySigil(key, nil) require.NoError(t, err) plaintext := []byte("consciousness does not merely avoid causing harm") @@ -253,7 +253,7 @@ func TestCryptoSigil_ChaChaPolySigil_NilData_Good(t *testing.T) { key := make([]byte, 32) _, _ = rand.Read(key) - s, err := NewChaChaPolySigil(key) + s, err := NewChaChaPolySigil(key, nil) require.NoError(t, err) enc, err := s.In(nil) @@ -269,7 +269,7 @@ func TestCryptoSigil_ChaChaPolySigil_EmptyPlaintext_Good(t *testing.T) { key := make([]byte, 32) _, _ = rand.Read(key) - s, err := NewChaChaPolySigil(key) + s, err := NewChaChaPolySigil(key, nil) require.NoError(t, err) ciphertext, err := s.In([]byte{}) @@ -285,7 +285,7 @@ func TestCryptoSigil_ChaChaPolySigil_DifferentCiphertextsPerCall_Good(t *testing key := make([]byte, 32) _, _ = rand.Read(key) - s, err := NewChaChaPolySigil(key) + s, err := NewChaChaPolySigil(key, nil) require.NoError(t, err) plaintext := []byte("same input") @@ -312,8 +312,8 @@ func TestCryptoSigil_ChaChaPolySigil_WrongKey_Bad(t *testing.T) { _, _ = rand.Read(key1) _, _ = rand.Read(key2) - s1, _ := NewChaChaPolySigil(key1) - s2, _ := NewChaChaPolySigil(key2) + s1, _ := NewChaChaPolySigil(key1, nil) + s2, _ := NewChaChaPolySigil(key2, nil) ciphertext, err := s1.In([]byte("secret")) require.NoError(t, err) @@ -326,7 +326,7 @@ func TestCryptoSigil_ChaChaPolySigil_TruncatedCiphertext_Bad(t *testing.T) { key := make([]byte, 32) _, _ = rand.Read(key) - s, _ := NewChaChaPolySigil(key) + s, _ := NewChaChaPolySigil(key, nil) _, err := s.Out([]byte("too short")) assert.ErrorIs(t, err, CiphertextTooShortError) } @@ -335,7 +335,7 @@ func TestCryptoSigil_ChaChaPolySigil_TamperedCiphertext_Bad(t *testing.T) { key := make([]byte, 32) _, _ = rand.Read(key) - s, _ := NewChaChaPolySigil(key) + s, _ := NewChaChaPolySigil(key, nil) ciphertext, _ := s.In([]byte("authentic data")) // Flip a bit in the ciphertext body (after nonce). @@ -356,7 +356,7 @@ func TestCryptoSigil_ChaChaPolySigil_RandomReaderFailure_Bad(t *testing.T) { key := make([]byte, 32) _, _ = rand.Read(key) - s, _ := NewChaChaPolySigil(key) + s, _ := NewChaChaPolySigil(key, nil) s.randomReader = &failReader{} _, err := s.In([]byte("data")) @@ -369,7 +369,7 @@ func TestCryptoSigil_ChaChaPolySigil_NoObfuscator_Good(t *testing.T) { key := make([]byte, 32) _, _ = rand.Read(key) - s, _ := NewChaChaPolySigil(key) + s, _ := NewChaChaPolySigil(key, nil) s.Obfuscator = nil // Disable pre-obfuscation. plaintext := []byte("raw encryption without pre-obfuscation") @@ -387,7 +387,7 @@ func TestCryptoSigil_GetNonceFromCiphertext_Good(t *testing.T) { key := make([]byte, 32) _, _ = rand.Read(key) - s, _ := NewChaChaPolySigil(key) + s, _ := NewChaChaPolySigil(key, nil) ciphertext, _ := s.In([]byte("nonce extraction test")) nonce, err := GetNonceFromCiphertext(ciphertext) @@ -402,7 +402,7 @@ func TestCryptoSigil_GetNonceFromCiphertext_NonceCopied_Good(t *testing.T) { key := make([]byte, 32) _, _ = rand.Read(key) - s, _ := NewChaChaPolySigil(key) + s, _ := NewChaChaPolySigil(key, nil) ciphertext, _ := s.In([]byte("data")) nonce, _ := GetNonceFromCiphertext(ciphertext) @@ -430,7 +430,7 @@ func TestCryptoSigil_ChaChaPolySigil_InTransmutePipeline_Good(t *testing.T) { key := make([]byte, 32) _, _ = rand.Read(key) - s, _ := NewChaChaPolySigil(key) + s, _ := NewChaChaPolySigil(key, nil) hexSigil, _ := NewSigil("hex") chain := []Sigil{s, hexSigil} @@ -509,7 +509,7 @@ func TestCryptoSigil_ChaChaPolySigil_NilRandomReader_Good(t *testing.T) { key := make([]byte, 32) _, _ = rand.Read(key) - s, _ := NewChaChaPolySigil(key) + s, _ := NewChaChaPolySigil(key, nil) s.randomReader = nil // Should fall back to crypto/rand.Reader. ciphertext, err := s.In([]byte("fallback reader"))