From 4b82b94f7abfcd7d9e44b84c437b5eec335434a9 Mon Sep 17 00:00:00 2001 From: cyyber Date: Mon, 22 Aug 2022 02:11:01 +0530 Subject: [PATCH] gopherjs support to generate js library for dilithium --- go.mod | 4 +- go.sum | 6 +- qrllib-js/dilithiumjs/dilithium.go | 119 +++++++++++++++++++++++++++ qrllib-js/main.go | 37 +++++++++ qrllib-js/xmssjs/xmss.go | 124 +++++++++++++++++++++++++++++ 5 files changed, 287 insertions(+), 3 deletions(-) create mode 100644 qrllib-js/dilithiumjs/dilithium.go create mode 100644 qrllib-js/main.go create mode 100644 qrllib-js/xmssjs/xmss.go diff --git a/go.mod b/go.mod index 36db964..d83458d 100644 --- a/go.mod +++ b/go.mod @@ -4,4 +4,6 @@ go 1.18 require golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d -require golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 // indirect +require golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect + +require github.com/gopherjs/gopherjs v1.18.0-beta1.0.20220817214357-b972ef3adc13 diff --git a/go.sum b/go.sum index bc36c73..7203a1e 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,6 @@ +github.com/gopherjs/gopherjs v1.18.0-beta1.0.20220817214357-b972ef3adc13 h1:SFRhRWRwuyWGcFUUWjmOtz6Fplqx6xhgb4pGQc9VJtc= +github.com/gopherjs/gopherjs v1.18.0-beta1.0.20220817214357-b972ef3adc13/go.mod h1:6UY8PXRnu51MqjYCCY4toG0S5GeH5uVJ3qDxIsa+kqo= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d h1:sK3txAijHtOK88l68nt020reeT1ZdKLIYetKl95FzVY= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad h1:ntjMns5wyP/fN65tdBD4g8J5w8n015+iIIs9rtjXkY0= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/qrllib-js/dilithiumjs/dilithium.go b/qrllib-js/dilithiumjs/dilithium.go new file mode 100644 index 0000000..324a4e6 --- /dev/null +++ b/qrllib-js/dilithiumjs/dilithium.go @@ -0,0 +1,119 @@ +package dilithiumjs + +import ( + "encoding/hex" + "github.com/gopherjs/gopherjs/js" + "github.com/theQRL/go-qrllib/common" + "github.com/theQRL/go-qrllib/dilithium" +) + +type DilithiumJS struct { + *js.Object + d *dilithium.Dilithium + pk string `js:"pk"` + sk string `js:"sk"` + seed string `js:"seed"` +} + +func newDilithiumJS(d *dilithium.Dilithium) *js.Object { + binPK := d.GetPK() + binSK := d.GetSK() + binSeed := d.GetSeed() + + djs := DilithiumJS{Object: js.Global.Get("Object").New()} + djs.d = d + djs.pk = hex.EncodeToString(binPK[:]) + djs.sk = hex.EncodeToString(binSK[:]) + djs.seed = hex.EncodeToString(binSeed[:]) + + djs.Object.Set("GetPK", djs.GetPK) + djs.Object.Set("GetSK", djs.GetSK) + djs.Object.Set("GetSeed", djs.GetSeed) + djs.Object.Set("GetMnemonic", djs.d.GetMnemonic) + djs.Object.Set("GetAddress", djs.GetAddress) + djs.Object.Set("Sign", djs.Sign) + + return djs.Object +} + +func NewDilithiumJS() *js.Object { + d := dilithium.New() + return newDilithiumJS(d) +} + +func NewDilithiumJSFromSeed(seed string) *js.Object { + binSeed, err := hex.DecodeString(seed) + if err != nil { + return nil + } + var sizedBinSeed [common.SeedSize]uint8 + copy(sizedBinSeed[:], binSeed) + d := dilithium.NewDilithiumFromSeed(sizedBinSeed) + + return newDilithiumJS(d) +} + +func (d *DilithiumJS) GetPK() string { + return d.pk +} + +func (d *DilithiumJS) GetSK() string { + return d.sk +} + +func (d *DilithiumJS) GetSeed() string { + return d.seed +} + +func (d *DilithiumJS) GetAddress() string { + binAddr := d.d.GetAddress() + return hex.EncodeToString(binAddr[:]) +} + +func (d *DilithiumJS) Sign(message string) string { + binSignature := d.d.Sign([]uint8(message)) + return hex.EncodeToString(binSignature[:]) +} + +func DilithiumVerify(message string, signature string, pk string) bool { + binMessage := []uint8(message) + binSignature, err := hex.DecodeString(signature) + if err != nil { + return false + } + binPK, err := hex.DecodeString(pk) + if err != nil { + return false + } + + var sizedBinPK [dilithium.PKSizePacked]uint8 + copy(sizedBinPK[:], binPK) + + return dilithium.Verify(binMessage, binSignature, &sizedBinPK) +} + +func GetDilithiumAddressFromPK(pk string) string { + binPK, err := hex.DecodeString(pk) + if err != nil { + return "" + } + + var sizedBinPK [dilithium.PKSizePacked]uint8 + copy(sizedBinPK[:], binPK) + + binAddress := dilithium.GetDilithiumAddressFromPK(sizedBinPK) + + return hex.EncodeToString(binAddress[:]) +} + +func IsValidDilithiumAddress(address string) bool { + binAddr, err := hex.DecodeString(address) + if err != nil { + return false + } + + var sizedBinAddr [common.AddressSize]uint8 + copy(sizedBinAddr[:], binAddr) + + return dilithium.IsValidDilithiumAddress(sizedBinAddr) +} diff --git a/qrllib-js/main.go b/qrllib-js/main.go new file mode 100644 index 0000000..b377fcb --- /dev/null +++ b/qrllib-js/main.go @@ -0,0 +1,37 @@ +package main + +//go:generate gopherjs build --minify + +import ( + "github.com/gopherjs/gopherjs/js" + "github.com/theQRL/go-qrllib/qrllib-js/dilithiumjs" +) + +func main() { + js.Global.Set("dilithium", map[string]interface{}{ + "New": dilithiumjs.NewDilithiumJS, + "NewFromSeed": dilithiumjs.NewDilithiumJSFromSeed, + "Verify": dilithiumjs.DilithiumVerify, + "GetAddressFromPK": dilithiumjs.GetDilithiumAddressFromPK, + "IsValidAddress": dilithiumjs.IsValidDilithiumAddress, + }) + + //js.Global.Set("xmss", map[string]interface{}{ + //"NewFromHeight": xmssjs.NewXMSSJSFromHeight, + //"NewFromSeed": xmssjs.NewXMSSJSFromSeed, + //"Verify": xmssjs.XMSSVerify, + //"GetAddressFromPK": xmssjs.GetXMSSAddressFromPK, + //"IsValidAddress": xmssjs.IsValidXMSSAddress, + + //"hashFunction": map[string]interface{}{ + // "SHA2_256": xmss.SHA2_256, + // "SHAKE_128": xmss.SHAKE_128, + // "SHAKE_256": xmss.SHAKE_256, + //}, + // + //"addressFormatType": map[string]interface{}{ + // "SHA256_2X": common.SHA256_2X, + //}, + //}) + +} diff --git a/qrllib-js/xmssjs/xmss.go b/qrllib-js/xmssjs/xmss.go new file mode 100644 index 0000000..ba31160 --- /dev/null +++ b/qrllib-js/xmssjs/xmss.go @@ -0,0 +1,124 @@ +package xmssjs + +import ( + "encoding/hex" + "fmt" + "github.com/gopherjs/gopherjs/js" + "github.com/theQRL/go-qrllib/common" + "github.com/theQRL/go-qrllib/xmss" +) + +type XMSSJS struct { + *js.Object + x *xmss.XMSS + pk string `js:"pk"` + sk string `js:"sk"` + seed string `js:"seed"` +} + +func newXMSSJS(x *xmss.XMSS) *js.Object { + binPK := x.GetPK() + binSK := x.GetSK() + binSeed := x.GetSeed() + + xmssjs := XMSSJS{Object: js.Global.Get("Object").New()} + xmssjs.x = x + xmssjs.pk = hex.EncodeToString(binPK[:]) + xmssjs.sk = hex.EncodeToString(binSK[:]) + xmssjs.seed = hex.EncodeToString(binSeed[:]) + + xmssjs.Object.Set("GetPK", xmssjs.GetPK) + xmssjs.Object.Set("GetSK", xmssjs.GetSK) + xmssjs.Object.Set("GetSeed", xmssjs.GetSeed) + xmssjs.Object.Set("GetMnemonic", xmssjs.x.GetMnemonic) + xmssjs.Object.Set("GetAddress", xmssjs.GetAddress) + xmssjs.Object.Set("Sign", xmssjs.Sign) + + return xmssjs.Object +} + +func NewXMSSJSFromHeight(height uint8, hashFunction xmss.HashFunction) *js.Object { + x := xmss.NewXMSSFromHeight(height, hashFunction) + return newXMSSJS(x) +} + +func NewXMSSJSFromSeed(seed string, height uint8, hashFunction xmss.HashFunction, addrFormatType common.AddrFormatType) *js.Object { + binSeed, err := hex.DecodeString(seed) + if err != nil { + + } + var sizedBinSeed [common.SeedSize]uint8 + copy(sizedBinSeed[:], binSeed) + + x := xmss.NewXMSSFromSeed(sizedBinSeed, height, hashFunction, addrFormatType) + + return newXMSSJS(x) +} + +func (x *XMSSJS) GetPK() string { + return x.pk +} + +func (x *XMSSJS) GetSK() string { + return x.sk +} + +func (x *XMSSJS) GetSeed() string { + return x.seed +} + +func (x *XMSSJS) GetAddress() string { + binAddr := x.x.GetAddress() + return hex.EncodeToString(binAddr[:]) +} + +func (x *XMSSJS) Sign(message string) string { + binSignature, err := x.x.Sign([]uint8(message)) + if err != nil { + panic(fmt.Errorf("signing failed %v", err.Error())) + } + return hex.EncodeToString(binSignature[:]) +} + +func XMSSVerify(message string, signature string, pk string) bool { + binMessage := []uint8(message) + binSignature, err := hex.DecodeString(signature) + if err != nil { + return false + } + binPK, err := hex.DecodeString(pk) + if err != nil { + return false + } + + var sizedBinPK [xmss.ExtendedPKSize]uint8 + copy(sizedBinPK[:], binPK) + + return xmss.Verify(binMessage, binSignature, sizedBinPK) +} + +func GetXMSSAddressFromPK(pk string) string { + binPK, err := hex.DecodeString(pk) + if err != nil { + return "" + } + + var sizedBinPK [xmss.ExtendedPKSize]uint8 + copy(sizedBinPK[:], binPK) + + binAddress := xmss.GetXMSSAddressFromPK(sizedBinPK) + + return hex.EncodeToString(binAddress[:]) +} + +func IsValidXMSSAddress(address string) bool { + binAddr, err := hex.DecodeString(address) + if err != nil { + return false + } + + var sizedBinAddr [common.AddressSize]uint8 + copy(sizedBinAddr[:], binAddr) + + return xmss.IsValidXMSSAddress(sizedBinAddr) +}