//go:build phoboscref /* SPDX-License-Identifier: MIT * * Phobos */ package cref_test import ( "bytes" "crypto/sha256" "encoding/hex" "fmt" "math/rand" "net/netip" "os" "testing" "golang.zx2c4.com/wireguard/windows/phobos/cref" ) const goldenHeader = `/* SPDX-License-Identifier: MIT * * Phobos */ package phobos type maskVector struct { key string length int digest string } type streamVector struct { key string length int split int digest string } type decodeVector struct { key string obfuscateBytes int encoded string decoded string } type bindingSuccessVector struct { txid string addr string out string } ` func digest(data []byte) string { sum := sha256.Sum256(data) return hex.EncodeToString(sum[:]) } func TestGenerateGoldenVectors(t *testing.T) { path := os.Getenv("PHOBOS_GOLDEN_OUT") if path == "" { t.Skip("set PHOBOS_GOLDEN_OUT to regenerate golden vectors") } keys := []string{"k", "phobos", "Ic0OGtSf1BdMmMDzs7GmYRuPS/HGmNXsSU9EOWEeuQI="} var out bytes.Buffer out.WriteString(goldenHeader) out.WriteString("var maskVectors = []maskVector{\n") for _, key := range keys { for _, length := range []int{1, 16, 64, 148, 1499, 1500, 1501, 4096, 9000} { mask := cref.XOR(make([]byte, length), []byte(key)) fmt.Fprintf(&out, "\t{%q, %d, %q},\n", key, length, digest(mask)) } } out.WriteString("}\n\n") out.WriteString("var streamVectors = []streamVector{\n") for _, key := range keys { for _, length := range []int{64, 65, 300, 20000} { for _, split := range []int{0, 1, length / 2} { stream := cref.Stream(make([]byte, length), []byte(key), split) fmt.Fprintf(&out, "\t{%q, %d, %d, %q},\n", key, length, split, digest(stream)) } } } out.WriteString("}\n\n") rng := rand.New(rand.NewSource(42)) out.WriteString("var decodeVectors = []decodeVector{\n") for _, key := range keys { for _, obfuscateBytes := range []int{0, 16} { for _, length := range []int{32, 92, 148} { payload := make([]byte, length) rng.Read(payload) payload[0] = byte(1 + rng.Intn(4)) payload[1], payload[2], payload[3] = 0, 0, 0 encoded := cref.Encode(payload, []byte(key), 4, obfuscateBytes, 65535) fmt.Fprintf(&out, "\t{%q, %d,\n\t\t%q,\n\t\t%q},\n", key, obfuscateBytes, hex.EncodeToString(encoded), hex.EncodeToString(payload)) } } } out.WriteString("}\n\n") out.WriteString("var bindingSuccessVectors = []bindingSuccessVector{\n") for _, addr := range []string{"127.0.0.1:51820", "10.0.0.7:1", "203.0.113.42:65535"} { txid := make([]byte, 12) rng.Read(txid) frame := cref.StunBindingSuccess(txid, netip.MustParseAddrPort(addr)) fmt.Fprintf(&out, "\t{%q, %q,\n\t\t%q},\n", hex.EncodeToString(txid), addr, hex.EncodeToString(frame)) } out.WriteString("}\n") if err := os.WriteFile(path, out.Bytes(), 0o644); err != nil { t.Fatal(err) } }