Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: dashhive/dashmsg
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v0.9.1
Choose a base ref
...
head repository: dashhive/dashmsg
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: main
Choose a head ref
  • 8 commits
  • 16 files changed
  • 2 contributors

Commits on Mar 14, 2022

  1. chore: tooling should ignore ./vendor/

    AJ ONeal committed Mar 14, 2022
    Copy the full SHA
    f5378b2 View commit details
  2. feat: make work with arbitrary coin types

    AJ ONeal committed Mar 14, 2022
    Copy the full SHA
    d40394c View commit details
  3. Copy the full SHA
    1587b82 View commit details
  4. fix: switch to Dash pubkeyhash algo

    AJ ONeal committed Mar 14, 2022
    Copy the full SHA
    720fc94 View commit details
  5. build: go mod tidy; go mod vendor

    AJ ONeal committed Mar 14, 2022
    Copy the full SHA
    38cdd49 View commit details
  6. Copy the full SHA
    54c3ee7 View commit details

Commits on Mar 16, 2022

  1. fix: use correct magic byte prefix for public key

    AJ ONeal committed Mar 16, 2022
    Copy the full SHA
    4532b06 View commit details

Commits on Oct 24, 2024

  1. fix(example): show correct address

    coolaj86 committed Oct 24, 2024
    Copy the full SHA
    9821f94 View commit details
2 changes: 1 addition & 1 deletion .goreleaser.yml
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@ builds:
- id: dashmsg-default
main: ./cmd/dashmsg/
env:
- CGO_ENABLED=0
- CGO_ENABLED=1
goos:
- darwin
- linux
1 change: 1 addition & 0 deletions .ignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
vendor
29 changes: 22 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -3,14 +3,14 @@
Sign and Verify messages with Dash Private Keys

```bash
dashmsg sign \
dashmsg sign --cointype 0x4c \
'XK5DHnAiSj6HQNsNcDkawd9qdp8UFMdYftdVZFuRreTMJtbJhk8i' \
'dte2022-akerdemelidis|estoever|mmason'
```

```bash
dashmsg verify \
'Xn4A2vv5fb7LvmiiXPPMexYbSbiQ29rzDu' \
'XyBmeuLa8y3D3XmzPvCTj5PVh7WvMPkLn1' \
'dte2022-akerdemelidis|estoever|mmason' \
'H2Opy9NX72iPZRcDVEHrFn2qmVwWMgc+DKILdVxl1yfmcL2qcpu9esw9wcD7RH0/dJHnIISe5j39EYahorWQM7I='
```
@@ -28,18 +28,18 @@ dashmsg help
```

```txt
dashmsg v0.9.0 (gxxxxxx) 2022-03-12T01:33:52-0700
dashmsg v0.9.1 (xxxxxxx) 2022-03-13T11:45:52-0700
Usage
dashmsg <command> [flags] args...
dashmsg <command> [flags] args...
See usage: dashmsg help <command>
Commands:
version
gen [name.wif]
sign <key> <msg>
inspect <key | address | signature>
gen [--cointype '0xcc'] [name.wif]
sign [--cointype '0x4c'] <key> <msg>
inspect [--cointype '0x4c'] <key | address | signature>
decode (alias of inspect)
verify <payment address> <msg> <signature>
@@ -67,6 +67,21 @@ pushd ./dashmsg/
go build -mod=vendor -o dashmsg ./cmd/dashmsg/
```

### GoReleaser

Because one of the dependencies requires `CGO_ENABLED=1` and uses low-level syscalls (I have no idea why - probably completely unnecessary), it must be built on and released from the respective OSes.

```bash
goreleaser -f .goreleaser.yml --rm-dist --single-target --skip-validate
```

```txt
--single-target - build only for the current OS
--skip-validate - uploads the image even though it can update the checksums
```

**Note**: MacOS actually can build both the amd64 and arm64 versions on an M1.

## Go Library

Documentation at <https://pkg.go.dev/github.com/dashhive/dashmsg>.
80 changes: 45 additions & 35 deletions cmd/dashmsg/main.go
Original file line number Diff line number Diff line change
@@ -26,15 +26,15 @@ func usage() {
fmt.Println(ver())
fmt.Println()
fmt.Println("Usage")
fmt.Printf(" %s <command> [flags] args...\n", name)
fmt.Printf(" %s <command> [flags] args...\n", name)
fmt.Println("")
fmt.Printf("See usage: %s help <command>\n", name)
fmt.Println("")
fmt.Println("Commands:")
fmt.Println(" version")
fmt.Println(" gen [name.wif]")
fmt.Println(" sign <key> <msg>")
fmt.Println(" inspect <key | address | signature>")
fmt.Println(" gen [--cointype '0xcc'] [name.wif]")
fmt.Println(" sign [--cointype '0x4c'] <key> <msg>")
fmt.Println(" inspect [--cointype '0x4c'] <key | address | signature>")
fmt.Println(" decode (alias of inspect)")
fmt.Println(" verify <payment address> <msg> <signature>")
fmt.Println("")
@@ -99,26 +99,42 @@ func main() {
}

func gen(args []string) {
wif := dashmsg.GenerateWIF()
var cointype string

if len(args) == 1 {
flags := flag.NewFlagSet("gen", flag.ExitOnError)
flags.StringVar(&cointype, "cointype", "", "the magic version (hex) string of the private key")
flags.Parse(args)

cointype = strings.TrimPrefix(cointype, "0x")

wif := dashmsg.GenerateWIF(cointype)

if len(flags.Args()) == 1 {
b := []byte(wif)
b = append(b, '\n')
ioutil.WriteFile(args[0], b, 0644)
fmt.Printf("wrote Private Key (as WIF) to %q\n", args[0])
ioutil.WriteFile(flags.Args()[0], b, 0644)
fmt.Printf("wrote Private Key (as WIF) to %q\n", flags.Args()[0])
return
}

fmt.Println(wif)
}

func inspect(args []string) {
if len(args) != 1 {
var cointype string

flags := flag.NewFlagSet("inspect", flag.ExitOnError)
flags.StringVar(&cointype, "cointype", "", "the magic version (hex) string of the private key")
flags.Parse(args)

cointype = strings.TrimPrefix(cointype, "0x")

if len(flags.Args()) != 1 {
fmt.Fprintf(os.Stderr, "usage: %s inspect <addr-or-key>\n", os.Args[0])
os.Exit(1)
return
}
input := args[0]
input := flags.Args()[0]

var usererr error
inputlen := len(input)
@@ -144,16 +160,19 @@ func inspect(args []string) {
break
}

priv, err := dashmsg.WIFToPrivateKey(wif)
privCointype, priv, err := dashmsg.WIFToPrivateKey(wif)
if nil != err {
usererr = err
break
}
if 0 == len(cointype) {
cointype = privCointype
}

pubBytes := dashmsg.MarshalPublicKey(priv.PublicKey)
pkh := dashmsg.PublicKeyToAddress(priv.PublicKey)
pkh := dashmsg.PublicKeyToAddress(cointype, priv.PublicKey)

fmt.Printf("PrivateKey (hex): %s (coin type)\n", hexstr[:2])
fmt.Printf("PrivateKey (hex): %s (coin type)\n", privCointype)
fmt.Printf(" : %s\n", hexstr[2:66])
fmt.Printf(" : %s (compressed)\n", hexstr[66:])
fmt.Println()
@@ -184,9 +203,14 @@ func inspect(args []string) {
}

func sign(args []string) {
var cointype string

flags := flag.NewFlagSet("sign", flag.ExitOnError)
flags.StringVar(&cointype, "cointype", "", "the magic version (hex) string of the private key")
flags.Parse(args)

cointype = strings.TrimPrefix(cointype, "0x")

if len(flags.Args()) <= 1 {
fmt.Fprintf(os.Stderr, "usage: %s sign <addr-or-key> <msg>\n", os.Args[0])
os.Exit(1)
@@ -195,7 +219,7 @@ func sign(args []string) {
wifname := flags.Args()[0]
payload := flags.Args()[1]

priv, err := readWif(wifname)
_, priv, err := readWif(wifname)
if nil != err {
fmt.Fprintf(os.Stderr, "error: could not decode private key: %v\n", err)
os.Exit(1)
@@ -233,31 +257,17 @@ func verify(args []string) {
addr := string(addrBytes)

msg := readFileOrString(msgname)
magichash := dashmsg.MagicHash(msg)

sigBytes := readFileOrString(signame)
sig := string(sigBytes)

sigBytes, err := base64.StdEncoding.DecodeString(sig)
if nil != err {
fmt.Fprintf(os.Stderr, "error: could not decode signature: %v\n", err)
os.Exit(1)
return
}

pub, err := dashmsg.SigToPub(magichash, sigBytes)
if nil != err {
fmt.Fprintf(os.Stderr, "error: could not verify message: %v\n", err)
if err := dashmsg.MagicVerify(addr, msg, sig); nil != err {
fmt.Fprintf(os.Stderr, "error: %v", err)
os.Exit(1)
return
}

if dashmsg.PublicKeyToAddress(*pub) == addr {
fmt.Println("Verified: true")
return
}

fmt.Println("Invalid Signature")
fmt.Println("Verified: true")
}

func readFileOrString(str string) []byte {
@@ -270,18 +280,18 @@ func readFileOrString(str string) []byte {
return b
}

func readWif(wifname string) (*ecdsa.PrivateKey, error) {
func readWif(wifname string) (string, *ecdsa.PrivateKey, error) {
// Read as file
wif := readFileOrString(wifname)

priv, err := dashmsg.WIFToPrivateKey(string(wif))
cointype, priv, err := dashmsg.WIFToPrivateKey(string(wif))
if nil != err {
// Neither a valid file nor string. Blast!
return nil, fmt.Errorf(
return "", nil, fmt.Errorf(
"could not read private key as file (or parse as string) %q:\n%s",
wifname, err,
)
}

return priv, nil
return cointype, priv, nil
}
Loading