main.mx raw

   1  package main
   2  
   3  // Bech32 + hex roundtrip tests.
   4  // Proves that the pre-sized, append-free refactors in web/common/helpers/bech32.mx
   5  // and the secure-tagging in web/common/helpers/hex.mx did not alter observable
   6  // encode/decode behaviour.
   7  
   8  import (
   9  	"git.smesh.lol/musiquay/web/common/helpers"
  10  )
  11  
  12  type hexVec struct {
  13  	name  string
  14  	bytes []byte
  15  	hex   string
  16  }
  17  
  18  type bechVec struct {
  19  	name string
  20  	hrp  string
  21  	hex  string // payload as hex
  22  }
  23  
  24  var hexVecs []hexVec
  25  
  26  var bechVecs []bechVec
  27  
  28  func initHarnessGlobals() {
  29  	hexVecs = []hexVec{
  30  			{"empty", []byte{}, ""},
  31  			{"single", []byte{0x00}, "00"},
  32  			{"single high", []byte{0xff}, "ff"},
  33  			{"32 bytes", []byte{
  34  				0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  35  				0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
  36  				0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87,
  37  				0x78, 0x69, 0x5a, 0x4b, 0x3c, 0x2d, 0x1e, 0x0f,
  38  			}, "0102030405060708090a0b0c0d0e0f10f0e1d2c3b4a59687 78695a4b3c2d1e0f"},
  39  		}
  40  	bechVecs = []bechVec{
  41  			// 32-byte test keys (nostr-style nsec / npub)
  42  			{
  43  				name: "nostr-style 32-byte",
  44  				hrp:  "nsec",
  45  				hex:  "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b",
  46  			},
  47  			{
  48  				name: "all zeros",
  49  				hrp:  "npub",
  50  				hex:  "0000000000000000000000000000000000000000000000000000000000000000",
  51  			},
  52  			{
  53  				name: "all 0xff",
  54  				hrp:  "npub",
  55  				hex:  "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
  56  			},
  57  		}
  58  }
  59  
  60  func main() {
  61  	initHarnessGlobals()
  62  
  63  	pass := 0
  64  	fail := 0
  65  
  66  	// Hex roundtrip (HexEncode then HexDecode then HexEncode again)
  67  	for i := 0; i < len(hexVecs); i++ {
  68  		v := hexVecs[i]
  69  		if i == 3 {
  70  			// Space in the literal for readability; we want the clean form.
  71  			v.hex = "0102030405060708090a0b0c0d0e0f10f0e1d2c3b4a5968778695a4b3c2d1e0f"
  72  		}
  73  		enc := helpers.HexEncode(v.bytes)
  74  		if enc != v.hex {
  75  			println("FAIL hex encode", v.name, ":", enc, "vs", v.hex)
  76  			fail++
  77  			continue
  78  		}
  79  		dec := helpers.HexDecode(enc)
  80  		if len(dec) != len(v.bytes) {
  81  			println("FAIL hex decode length", v.name, ":", len(dec), "vs", len(v.bytes))
  82  			fail++
  83  			continue
  84  		}
  85  		ok := true
  86  		for j := 0; j < len(v.bytes); j++ {
  87  			if dec[j] != v.bytes[j] {
  88  				ok = false
  89  				break
  90  			}
  91  		}
  92  		if !ok {
  93  			println("FAIL hex decode bytes", v.name)
  94  			fail++
  95  			continue
  96  		}
  97  		println("PASS hex", v.name)
  98  		pass++
  99  	}
 100  
 101  	// Bech32 encode -> decode roundtrip
 102  	for i := 0; i < len(bechVecs); i++ {
 103  		v := bechVecs[i]
 104  		payload := helpers.HexDecode(v.hex)
 105  		encoded := helpers.Bech32Encode(v.hrp, payload)
 106  		if encoded == "" {
 107  			println("FAIL bech32 encode", v.name)
 108  			fail++
 109  			continue
 110  		}
 111  		hrpOut, decoded := helpers.Bech32Decode(encoded)
 112  		if hrpOut == "" || decoded == nil {
 113  			println("FAIL bech32 decode", v.name, ":", encoded)
 114  			fail++
 115  			continue
 116  		}
 117  		if hrpOut != v.hrp {
 118  			println("FAIL bech32 hrp", v.name, ":", hrpOut, "vs", v.hrp)
 119  			fail++
 120  			continue
 121  		}
 122  		if len(decoded) != len(payload) {
 123  			println("FAIL bech32 length", v.name, ":", len(decoded), "vs", len(payload))
 124  			fail++
 125  			continue
 126  		}
 127  		match := true
 128  		for j := 0; j < len(payload); j++ {
 129  			if decoded[j] != payload[j] {
 130  				match = false
 131  				break
 132  			}
 133  		}
 134  		if !match {
 135  			println("FAIL bech32 payload mismatch", v.name)
 136  			println("  in ", v.hex)
 137  			println("  out", helpers.HexEncode(decoded))
 138  			fail++
 139  			continue
 140  		}
 141  		println("PASS bech32", v.name, encoded)
 142  		pass++
 143  	}
 144  
 145  	// Known-answer vector: the nsec the smoke suite signs in with. Its payload
 146  	// is fixed here and was checked independently - an x-only secp256k1 k*G
 147  	// over these bytes is 840307b8e49601725ae66f45e83046d09c9aa221a38af9ad72744f11d40a4c27,
 148  	// which is the pubkey the signer reports for the same nsec.
 149  	nsec := "nsec1jz5zyz6np29zg9k7wu5zvnpusuha8ca84v8ahdme9pdwjlalcsjsp59265"
 150  	sk := helpers.DecodeNsec(nsec)
 151  	if sk == nil {
 152  		println("FAIL DecodeNsec returned nil")
 153  		fail++
 154  	} else if len(sk) != 32 {
 155  		println("FAIL DecodeNsec length:", len(sk))
 156  		fail++
 157  	} else {
 158  		expect := "90a8220b530a8a2416de7728264c3c872fd3e3a7ab0fdbb779285ae97fbfc425"
 159  		got := helpers.HexEncode(sk)
 160  		if got == expect {
 161  			println("PASS DecodeNsec known answer")
 162  			pass++
 163  		} else {
 164  			println("FAIL DecodeNsec produced:", got)
 165  			println("     expected:           ", expect)
 166  			fail++
 167  		}
 168  	}
 169  
 170  	println("---")
 171  	println("total pass:", pass, "fail:", fail)
 172  	if fail > 0 {
 173  		panic("helpers test vectors failed")
 174  	}
 175  }
 176