Skip to content

Commit

Permalink
Merge pull request #4 from halseth/matt-demo
Browse files Browse the repository at this point in the history
Matt demo
  • Loading branch information
halseth authored Dec 12, 2023
2 parents 2ea47bc + 316b305 commit f13eba6
Show file tree
Hide file tree
Showing 26 changed files with 1,851 additions and 66 deletions.
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,13 @@

# Binaries
/cmd/tapsim/tapsim
/cmd/keys/keys
/cmd/tweak/tweak
/cmd/merkle/merkle
/keys
/merkle
/tweak
/tapsim
cmd/scriptnum/scriptnum
examples/matt/coinpool/v2/cmd/cmd
scriptnum
50 changes: 50 additions & 0 deletions cmd/keys/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package main

import (
"fmt"

"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcec/v2/schnorr"
flags "github.com/jessevdk/go-flags"
)

const usage = "Returns n keys on the format 'privkey,pubkey'"

type config struct {
Num int `short:"n" long:"num" description:"number of keys to generate"`
}

var cfg = config{}

func main() {
parser := flags.NewParser(&cfg, flags.Default)
parser.Usage = usage
if _, err := parser.Parse(); err != nil {
fmt.Println(err)
return
}

err := run()
if err != nil {
fmt.Println(err)
return
}
}

func run() error {
if cfg.Num < 1 {
return fmt.Errorf("number of keys mus be positive")
}

for i := 0; i < cfg.Num; i++ {
privKey, err := btcec.NewPrivateKey()
if err != nil {
return err
}
privKeyBytes := privKey.Serialize()
pubKey := privKey.PubKey()
pubKeyBytes := schnorr.SerializePubKey(pubKey)
fmt.Printf("%x,%x\n", privKeyBytes, pubKeyBytes)
}
return nil
}
92 changes: 92 additions & 0 deletions cmd/merkle/build/merkle.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package build

import (
"bytes"
"crypto/sha256"
"encoding/hex"
"fmt"
"strings"
)

func Merkle(leaves []string) ([]string, error) {

var level [][32]byte
for _, l := range leaves {
if l == "" {
continue
}

var bs []byte

// Grouped leaves
if strings.HasPrefix(l, "(") &&
strings.HasSuffix(l, ")") {

l = strings.TrimPrefix(l, "(")
l = strings.TrimSuffix(l, ")")

els := strings.Split(l, ",")

group := bytes.Buffer{}
for _, el := range els {
h, err := hex.DecodeString(el)
if err != nil {
return nil, fmt.Errorf("unable to parse '%s': %w", l, err)
}

hash := sha256.Sum256(h)
group.Write(hash[:])
}

bs = group.Bytes()
} else if l == "<>" {
bs = []byte{}
} else {
var err error
bs, err = hex.DecodeString(l)
if err != nil {
return nil, fmt.Errorf("unable to parse '%s': %w", l, err)
}

}

hash := sha256.Sum256(bs)
level = append(level, hash)
}

var tree []string
addLevel := func(level [][32]byte) {
s := ""
for i, l := range level {
s += fmt.Sprintf("%x", l)
if i < len(level)-1 {
s += " "
}
}

tree = append(tree, s)

}

addLevel(level)
for len(level) > 1 {
if len(level)%2 != 0 {
return nil, fmt.Errorf("invalid number of leaves")
}

var nextLevel [][32]byte
for i := 1; i < len(level); i += 2 {
item := make([]byte, 64)
copy(item[:32], level[i-1][:])
copy(item[32:], level[i][:])
hash := sha256.Sum256(item)

nextLevel = append(nextLevel, hash)
}

level = nextLevel
addLevel(level)
}

return tree, nil
}
43 changes: 43 additions & 0 deletions cmd/merkle/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package main

import (
"fmt"
"strings"

"github.com/halseth/tapsim/cmd/merkle/build"
flags "github.com/jessevdk/go-flags"
)

type config struct {
Leaves string `short:"l" long:"leaves" description:"space separated string of hex values to commit to (must be power of 2). To group more values in single leaf, use (val1,val2)"`
}

var cfg = config{}

func main() {
if _, err := flags.Parse(&cfg); err != nil {
fmt.Println(err)
return
}

err := run()
if err != nil {
fmt.Println(err)
return
}
}

func run() error {
leaves := strings.Split(cfg.Leaves, " ")

tree, err := build.Merkle(leaves)
if err != nil {
return err
}

for i := len(tree) - 1; i >= 0; i-- {
fmt.Printf("%s\n", tree[i])
}

return nil
}
49 changes: 49 additions & 0 deletions cmd/scriptnum/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package main

import (
"encoding/hex"
"fmt"
"os"
"strconv"
"strings"

"github.com/halseth/mattlab/commitment"
)

func main() {
val := os.Args[1]
var (
num uint64
err error
)

if val == "from" {
scriptNumHex := os.Args[2]
v, err := hex.DecodeString(scriptNumHex)
if err != nil {
panic(err)
}

scriptNum, err := commitment.MakeScriptNum(v, true, len(v))
if err != nil {
panic(err)
}

fmt.Printf("%d\n", scriptNum)
return
}

base := 10
if strings.HasPrefix(val, "0x") {
base = 16
val = strings.TrimPrefix(val, "0x")
}
num, err = strconv.ParseUint(val, base, 64)
if err != nil {
panic(err)
}
s := commitment.ScriptNum(num)

fmt.Printf("%x\n", s.Bytes())

}
38 changes: 35 additions & 3 deletions cmd/tapsim/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

"github.com/btcsuite/btcd/btcec/v2/schnorr"
"github.com/halseth/tapsim/file"
"github.com/halseth/tapsim/output"
"github.com/halseth/tapsim/script"
"github.com/urfave/cli/v2"
)
Expand Down Expand Up @@ -65,6 +66,12 @@ func main() {
Aliases: []string{"ni"},
Usage: "disable interactive mode",
},
&cli.BoolFlag{
Name: "no-step",
Aliases: []string{"ns"},
Usage: "don't show step by step, just validate",
},

&cli.StringFlag{
Name: "privkeys",
Usage: "specify private keys as \"key1:<hex>,key2:<hex>\" to sign the transaction. Set <hex> empty to generate a random key with the given ID.",
Expand All @@ -87,6 +94,18 @@ func main() {
Name: "tagfile",
Usage: "optional json file map from hex values to human-readable tags",
},
&cli.IntFlag{
Name: "colwidth",
Usage: "output column width (default: 40)",
},
&cli.IntFlag{
Name: "rows",
Usage: "max rows to print in execution table (default: 25)",
},
&cli.IntFlag{
Name: "skip",
Usage: "skip aheead",
},
},
},
}
Expand Down Expand Up @@ -115,6 +134,18 @@ func parse(cCtx *cli.Context) error {
}

func execute(cCtx *cli.Context) error {

colWidth := cCtx.Int("colwidth")
if colWidth > 0 {
output.ColumnWidth = colWidth
}
maxRows := cCtx.Int("rows")
if maxRows > 0 {
output.MaxRows = maxRows
}

skipAhead := cCtx.Int("skip")

var scriptStr []string
scriptFile := cCtx.String("script")
scriptFiles := cCtx.String("scripts")
Expand Down Expand Up @@ -178,6 +209,7 @@ func execute(cCtx *cli.Context) error {
}

nonInteractive := cCtx.Bool("non-interactive")
noStep := cCtx.Bool("no-step")
privKeys := strings.Split(cCtx.String("privkeys"), ",")
keyMap := make(map[string][]byte)
for _, privKeyStr := range privKeys {
Expand Down Expand Up @@ -273,13 +305,13 @@ func execute(cCtx *cli.Context) error {

executeErr := script.Execute(
keyMap, inputKeyBytes, txOutKeys, parsedScripts, scriptIndex,
parsedWitness, !nonInteractive, tags,
parsedWitness, !nonInteractive, noStep, tags, skipAhead,
)
if executeErr != nil {
fmt.Printf("script exection failed: %s\r\n", executeErr)
return nil
return executeErr
}

fmt.Printf("script verified\r\n")
fmt.Printf("script execution verified\r\n")
return nil
}
Loading

0 comments on commit f13eba6

Please sign in to comment.