diff --git a/cmd/keyaddr/handlers.go b/cmd/keyaddr/handlers.go index 05b4689..19362fe 100644 --- a/cmd/keyaddr/handlers.go +++ b/cmd/keyaddr/handlers.go @@ -9,14 +9,16 @@ package main // https://www.apache.org/licenses/LICENSE-2.0.txt // - -- --- ---- ----- - import ( + "encoding/hex" "fmt" "math" "regexp" "syscall/js" + "github.com/ndau/ndaumath/pkg/address" "github.com/ndau/ndaumath/pkg/keyaddr" + "github.com/ndau/ndaumath/pkg/signature" ) // exit will quit the go program, causing the application to no longer respond to function calls. @@ -72,6 +74,136 @@ func newKey(this js.Value, args []js.Value) interface{} { return nil } +// JS Usage: newEdKey(cb) --> no args +func newEdKey(this js.Value, args []js.Value) interface{} { + go func(args []js.Value) { + logDebug("newEdKey") + + // clean args + callback, _, err := handleArgs(args, 0, "newEdKey") + if err != nil { + return + } + + // do work + public, private, err := signature.Generate(signature.Ed25519, nil) + if err != nil { + jsLogReject(callback, "error creating new ed key: %s", err) + return + } + + pubkeyText, err := public.MarshalText() + if err != nil { + jsLogReject(callback, "error marshalling new public ed key: %s", err) + return + } + + privkeyText, err := private.MarshalText() + if err != nil { + jsLogReject(callback, "error marshalling new private ed key: %s", err) + return + } + + // Make an map[string]interface{} so syscall will turn it into a js object. + obj := make(map[string]interface{}) + obj["pubkey"] = string(pubkeyText) + obj["privkey"] = string(privkeyText) + + // return result + callback.Invoke(nil, js.ValueOf(obj)) + return + }(args) + return nil +} + +// JS Usage: newEdKey(seed, cb) +func newEdKeyFromSeed(this js.Value, args []js.Value) interface{} { + go func(args []js.Value) { + logDebug("newEdKeyFromSeed") + + // clean args + callback, remainder, err := handleArgs(args, 1, "newEdKeyFromSeed") + if err != nil { + return + } + + seedString := remainder[0].String() + seed, err := hex.DecodeString(seedString) + if err != nil { + jsLogReject(callback, "error decoding data from hex: %s", err) + return + } + + // do work + public, private, err := signature.GenerateFromSeed(signature.Ed25519, seed) + if err != nil { + jsLogReject(callback, "error creating new ed key: %s", err) + return + } + + pubkeyText, err := public.MarshalText() + if err != nil { + jsLogReject(callback, "error marshalling new public ed key: %s", err) + return + } + + privkeyText, err := private.MarshalText() + if err != nil { + jsLogReject(callback, "error marshalling new private ed key: %s", err) + return + } + + // Make an map[string]interface{} so syscall will turn it into a js object. + obj := make(map[string]interface{}) + obj["pubkey"] = string(pubkeyText) + obj["privkey"] = string(privkeyText) + + // return result + callback.Invoke(nil, js.ValueOf(obj)) + return + }(args) + return nil +} + +// JS Usage: addrFromPublicKey(pubKey, cb) +func addrFromPublicKey(this js.Value, args []js.Value) interface{} { + go func(args []js.Value) { + logDebug("addrFromPublicKey") + + // clean args + callback, remainder, err := handleArgs(args, 1, "addrFromPublicKey") + if err != nil { + return + } + + pubKeyString := remainder[0].String() + + // do work + key, err := signature.ParseKey(pubKeyString) + if err != nil { + jsLogReject(callback, "error parsing public key: %s", err) + return + } + + _, ok := key.(*signature.PublicKey) + if !ok { + jsLogReject(callback, "addresses can only be generated from public keys") + return + } + + addr, err := address.Generate(address.KindExchange, key.KeyBytes()) + if err != nil { + jsLogReject(callback, "error generating address from key: %s", err) + return + } + + // return result + callback.Invoke(nil, addr.String()) + return + }(args) + return nil +} + // JS Usage: wordsToBytes(language, words, cb) // language defaults to en if not specified. func wordsToBytes(this js.Value, args []js.Value) interface{} { @@ -370,7 +502,71 @@ func sign(this js.Value, args []js.Value) interface{} { msg := remainder[1].String() // do work - sig, err := k.Sign(msg) + sig, err := k.SignSecP(msg) + if err != nil { + logError(fmt.Sprintf("error creating signature: key length: %s, msg: %s, err: %s", len(k.Key), msg, err.Error())) + jsLogReject(callback, "error creating signature: %s", err) + return + } + + // return result + callback.Invoke(nil, sig.Signature) + return + }(args) + return nil +} + +// JS Usage: signEdB64(privateKey, base64Message, cb) +func signEdB64(this js.Value, args []js.Value) interface{} { + js.Global().Get("console").Call("log", "sign starting") + go func(args []js.Value) { + logDebug("signEdB64") + // clean args + callback, remainder, err := handleArgs(args, 2, "signEdB64") + if err != nil { + return + } + + k := keyaddr.Key{ + Key: remainder[0].String(), + } + + msg := remainder[1].String() + + // do work + sig, err := k.SignEdB64(msg) + if err != nil { + logError(fmt.Sprintf("error creating signature: key length: %s, msg: %s, err: %s", len(k.Key), msg, err.Error())) + jsLogReject(callback, "error creating signature: %s", err) + return + } + + // return result + callback.Invoke(nil, sig.Signature) + return + }(args) + return nil +} + +// JS Usage: signEdText(privateKey, textMessage, cb) +func signEdText(this js.Value, args []js.Value) interface{} { + js.Global().Get("console").Call("log", "sign starting") + go func(args []js.Value) { + logDebug("signEdText") + // clean args + callback, remainder, err := handleArgs(args, 2, "signEdText") + if err != nil { + return + } + + k := keyaddr.Key{ + Key: remainder[0].String(), + } + + msg := remainder[1].String() + + // do work + sig, err := k.SignEdText(msg) if err != nil { logError(fmt.Sprintf("error creating signature: key length: %s, msg: %s, err: %s", len(k.Key), msg, err.Error())) jsLogReject(callback, "error creating signature: %s", err) diff --git a/cmd/keyaddr/main.go b/cmd/keyaddr/main.go index dde66df..8c218f4 100644 --- a/cmd/keyaddr/main.go +++ b/cmd/keyaddr/main.go @@ -9,7 +9,6 @@ package main // https://www.apache.org/licenses/LICENSE-2.0.txt // - -- --- ---- ----- - /* Notes: @@ -35,25 +34,28 @@ import ( var waitChannel chan struct{} func main() { - js.Global().Get("console").Call("log", "WASM Keyaddr starting") - waitChannel = make(chan struct{}) // put go functions in a javascript object obj := map[string]interface{}{ - "newKey": js.FuncOf(newKey), - "wordsToBytes": js.FuncOf(wordsToBytes), - "deriveFrom": js.FuncOf(deriveFrom), - "ndauAddress": js.FuncOf(ndauAddress), - "toPublic": js.FuncOf(toPublic), - "child": js.FuncOf(child), - "sign": js.FuncOf(sign), - "hardenedChild": js.FuncOf(hardenedChild), - "wordsFromPrefix": js.FuncOf(wordsFromPrefix), - "isPrivate": js.FuncOf(isPrivate), - "wordsFromBytes": js.FuncOf(wordsFromBytes), - "fromString": js.FuncOf(fromString), - "exit": js.FuncOf(exit), + "newKey": js.FuncOf(newKey), + "wordsToBytes": js.FuncOf(wordsToBytes), + "deriveFrom": js.FuncOf(deriveFrom), + "ndauAddress": js.FuncOf(ndauAddress), + "toPublic": js.FuncOf(toPublic), + "child": js.FuncOf(child), + "sign": js.FuncOf(sign), + "signEdB64": js.FuncOf(signEdB64), + "signEdText": js.FuncOf(signEdText), + "hardenedChild": js.FuncOf(hardenedChild), + "wordsFromPrefix": js.FuncOf(wordsFromPrefix), + "isPrivate": js.FuncOf(isPrivate), + "wordsFromBytes": js.FuncOf(wordsFromBytes), + "fromString": js.FuncOf(fromString), + "newEdKey": js.FuncOf(newEdKey), + "newEdKeyFromSeed": js.FuncOf(newEdKeyFromSeed), + "addrFromPublicKey": js.FuncOf(addrFromPublicKey), + "exit": js.FuncOf(exit), } // Register all functions globally under KeyaddrNS. Either `window` in browsers, or diff --git a/cmd/keyaddr/tests.js b/cmd/keyaddr/tests.js index d5f9987..409fa9e 100644 --- a/cmd/keyaddr/tests.js +++ b/cmd/keyaddr/tests.js @@ -266,7 +266,7 @@ describe('simple memory test', () => { const key = await Keyaddr.newKey(bytes) const oldLogLevel = global.KeyaddrLogLevel // save previous log level global.KeyaddrLogLevel = global.KeyaddrLogLevelError // turn off excessive logs - for (let i = 1; i < 1000; i++) { + for (let i = 1; i < 500; i++) { const newKey = await Keyaddr.deriveFrom(key, '/', `/44'/20036'/100/${i}`) const addy = await Keyaddr.ndauAddress(newKey) } diff --git a/cmd/keyaddr/yarn.lock b/cmd/keyaddr/yarn.lock index 58f7474..f6be1b8 100644 --- a/cmd/keyaddr/yarn.lock +++ b/cmd/keyaddr/yarn.lock @@ -683,11 +683,6 @@ ansi-colors@3.2.3: resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.3.tgz#57d35b8686e851e2cc04c403f1c00203976a1813" integrity sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw== -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= - ansi-regex@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" @@ -698,7 +693,7 @@ ansi-regex@^4.1.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== -ansi-styles@^3.2.1: +ansi-styles@^3.2.0, ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== @@ -799,19 +794,14 @@ check-error@^1.0.2: resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII= -cliui@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49" - integrity sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ== +cliui@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" + integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== dependencies: - string-width "^2.1.1" - strip-ansi "^4.0.0" - wrap-ansi "^2.0.0" - -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= + string-width "^3.1.0" + strip-ansi "^5.2.0" + wrap-ansi "^5.1.0" color-convert@^1.9.0: version "1.9.3" @@ -860,17 +850,6 @@ core-js@^3.2.1: resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.2.1.tgz#cd41f38534da6cc59f7db050fe67307de9868b09" integrity sha512-Qa5XSVefSVPRxy2XfUC13WbvqkxhkwB3ve+pgCQveNgYzbM/UxZeu1dcOX/xr4UmfUd+muuvsaxilQzCyUurMw== -cross-spawn@^6.0.0: - version "6.0.5" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" - integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== - dependencies: - nice-try "^1.0.4" - path-key "^2.0.1" - semver "^5.5.0" - shebang-command "^1.2.0" - which "^1.2.9" - debug@3.2.6: version "3.2.6" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" @@ -919,13 +898,6 @@ emoji-regex@^7.0.1: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== -end-of-stream@^1.1.0: - version "1.4.4" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" - integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== - dependencies: - once "^1.4.0" - es-abstract@^1.5.1: version "1.14.2" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.14.2.tgz#7ce108fad83068c8783c3cdf62e504e084d8c497" @@ -966,19 +938,6 @@ esutils@^2.0.2: resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== -execa@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" - integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== - dependencies: - cross-spawn "^6.0.0" - get-stream "^4.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - find-cache-dir@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" @@ -1012,11 +971,6 @@ function-bind@^1.1.1: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== -get-caller-file@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" - integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== - get-caller-file@^2.0.1: version "2.0.5" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" @@ -1027,13 +981,6 @@ get-func-name@^2.0.0: resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE= -get-stream@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" - integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== - dependencies: - pump "^3.0.0" - glob@7.1.3: version "7.1.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" @@ -1105,11 +1052,6 @@ invariant@^2.2.2: dependencies: loose-envify "^1.0.0" -invert-kv@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" - integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== - is-buffer@~2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.3.tgz#4ecf3fcf749cbd1e472689e109ac66261a25e725" @@ -1125,13 +1067,6 @@ is-date-object@^1.0.1: resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" integrity sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY= -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= - dependencies: - number-is-nan "^1.0.0" - is-fullwidth-code-point@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" @@ -1144,11 +1079,6 @@ is-regex@^1.0.4: dependencies: has "^1.0.1" -is-stream@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= - is-symbol@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38" @@ -1196,13 +1126,6 @@ json5@^2.1.0: dependencies: minimist "^1.2.0" -lcid@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" - integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA== - dependencies: - invert-kv "^2.0.0" - locate-path@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" @@ -1211,11 +1134,16 @@ locate-path@^3.0.0: p-locate "^3.0.0" path-exists "^3.0.0" -lodash@^4.17.11, lodash@^4.17.13: +lodash@^4.17.13: version "4.17.15" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== +lodash@^4.17.15: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + log-symbols@2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" @@ -1238,27 +1166,6 @@ make-dir@^2.0.0: pify "^4.0.1" semver "^5.6.0" -map-age-cleaner@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" - integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== - dependencies: - p-defer "^1.0.0" - -mem@^4.0.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178" - integrity sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w== - dependencies: - map-age-cleaner "^0.1.1" - mimic-fn "^2.0.0" - p-is-promise "^2.0.0" - -mimic-fn@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== - minimatch@3.0.4, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" @@ -1276,17 +1183,29 @@ minimist@^1.2.0: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= -mkdirp@0.5.1, mkdirp@^0.5.1: +minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + +mkdirp@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.4.tgz#fd01504a6797ec5c9be81ff43d204961ed64a512" + integrity sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw== + dependencies: + minimist "^1.2.5" + +mkdirp@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= dependencies: minimist "0.0.8" -mocha@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-6.2.0.tgz#f896b642843445d1bb8bca60eabd9206b8916e56" - integrity sha512-qwfFgY+7EKAAUAdv7VYMZQknI7YJSGesxHyhn6qD52DV8UcSZs5XwCifcZGMVIE4a5fbmhvbotxC0DLQ0oKohQ== +mocha@^6.2.3: + version "6.2.3" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-6.2.3.tgz#e648432181d8b99393410212664450a4c1e31912" + integrity sha512-0R/3FvjIGH3eEuG17ccFPk117XL2rWxatr81a57D+r/x2uTYZRbdZ4oVidEUMh2W2TJDa7MdAb12Lm2/qrKajg== dependencies: ansi-colors "3.2.3" browser-stdout "1.3.1" @@ -1300,7 +1219,7 @@ mocha@^6.2.0: js-yaml "3.13.1" log-symbols "2.2.0" minimatch "3.0.4" - mkdirp "0.5.1" + mkdirp "0.5.4" ms "2.1.1" node-environment-flags "1.0.5" object.assign "4.1.0" @@ -1308,9 +1227,9 @@ mocha@^6.2.0: supports-color "6.0.0" which "1.3.1" wide-align "1.1.3" - yargs "13.2.2" - yargs-parser "13.0.0" - yargs-unparser "1.5.0" + yargs "13.3.2" + yargs-parser "13.1.2" + yargs-unparser "1.6.0" ms@2.1.1: version "2.1.1" @@ -1322,11 +1241,6 @@ ms@^2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -nice-try@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" - integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== - node-environment-flags@1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/node-environment-flags/-/node-environment-flags-1.0.5.tgz#fa930275f5bf5dae188d6192b24b4c8bbac3d76a" @@ -1355,18 +1269,6 @@ node-releases@^1.1.29: dependencies: semver "^5.3.0" -npm-run-path@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" - integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= - dependencies: - path-key "^2.0.0" - -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= - object-inspect@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.6.0.tgz#c70b6cbf72f274aab4c34c0c82f5167bf82cf15b" @@ -1395,37 +1297,13 @@ object.getownpropertydescriptors@^2.0.3: define-properties "^1.1.2" es-abstract "^1.5.1" -once@^1.3.0, once@^1.3.1, once@^1.4.0: +once@^1.3.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= dependencies: wrappy "1" -os-locale@^3.0.0, os-locale@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" - integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q== - dependencies: - execa "^1.0.0" - lcid "^2.0.0" - mem "^4.0.0" - -p-defer@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" - integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= - -p-finally@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= - -p-is-promise@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" - integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== - p-limit@^2.0.0: version "2.2.1" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.1.tgz#aa07a788cc3151c939b5131f63570f0dd2009537" @@ -1460,11 +1338,6 @@ path-is-absolute@^1.0.0: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= -path-key@^2.0.0, path-key@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= - path-parse@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" @@ -1499,14 +1372,6 @@ private@^0.1.6: resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== -pump@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" - integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - regenerate-unicode-properties@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz#ef51e0f0ea4ad424b77bf7cb41f3e015c70a3f0e" @@ -1560,11 +1425,6 @@ require-directory@^2.1.1: resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= -require-main-filename@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" - integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= - require-main-filename@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" @@ -1597,23 +1457,6 @@ set-blocking@^2.0.0: resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= -shebang-command@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= - dependencies: - shebang-regex "^1.0.0" - -shebang-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= - -signal-exit@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" - integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= - source-map-support@^0.5.9: version "0.5.13" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" @@ -1637,16 +1480,7 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= -string-width@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" - -"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.1: +"string-width@^1.0.2 || 2": version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== @@ -1654,7 +1488,7 @@ string-width@^1.0.1: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" -string-width@^3.0.0: +string-width@^3.0.0, string-width@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== @@ -1679,13 +1513,6 @@ string.prototype.trimright@^2.0.0: define-properties "^1.1.3" function-bind "^1.1.1" -strip-ansi@^3.0.0, strip-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= - dependencies: - ansi-regex "^2.0.0" - strip-ansi@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" @@ -1693,18 +1520,13 @@ strip-ansi@^4.0.0: dependencies: ansi-regex "^3.0.0" -strip-ansi@^5.1.0: +strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== dependencies: ansi-regex "^4.1.0" -strip-eof@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" - integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= - strip-json-comments@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" @@ -1769,7 +1591,7 @@ which-module@^2.0.0: resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= -which@1.3.1, which@^1.2.9: +which@1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== @@ -1783,88 +1605,54 @@ wide-align@1.1.3: dependencies: string-width "^1.0.2 || 2" -wrap-ansi@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" - integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= +wrap-ansi@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" + integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" + ansi-styles "^3.2.0" + string-width "^3.0.0" + strip-ansi "^5.0.0" wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= -"y18n@^3.2.1 || ^4.0.0", y18n@^4.0.0: +y18n@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== -yargs-parser@13.0.0: - version "13.0.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.0.0.tgz#3fc44f3e76a8bdb1cc3602e860108602e5ccde8b" - integrity sha512-w2LXjoL8oRdRQN+hOyppuXs+V/fVAYtpcrRxZuF7Kt/Oc+Jr2uAcVntaUTNT6w5ihoWfFDpNY8CPx1QskxZ/pw== - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" - -yargs-parser@^11.1.1: - version "11.1.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-11.1.1.tgz#879a0865973bca9f6bab5cbdf3b1c67ec7d3bcf4" - integrity sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ== +yargs-parser@13.1.2, yargs-parser@^13.1.2: + version "13.1.2" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" + integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== dependencies: camelcase "^5.0.0" decamelize "^1.2.0" -yargs-parser@^13.0.0: - version "13.1.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.1.tgz#d26058532aa06d365fe091f6a1fc06b2f7e5eca0" - integrity sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ== - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" - -yargs-unparser@1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-1.5.0.tgz#f2bb2a7e83cbc87bb95c8e572828a06c9add6e0d" - integrity sha512-HK25qidFTCVuj/D1VfNiEndpLIeJN78aqgR23nL3y4N0U/91cOAzqfHlF8n2BvoNDcZmJKin3ddNSvOxSr8flw== +yargs-unparser@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-1.6.0.tgz#ef25c2c769ff6bd09e4b0f9d7c605fb27846ea9f" + integrity sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw== dependencies: flat "^4.1.0" - lodash "^4.17.11" - yargs "^12.0.5" + lodash "^4.17.15" + yargs "^13.3.0" -yargs@13.2.2: - version "13.2.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.2.2.tgz#0c101f580ae95cea7f39d927e7770e3fdc97f993" - integrity sha512-WyEoxgyTD3w5XRpAQNYUB9ycVH/PQrToaTXdYXRdOXvEy1l19br+VJsc0vcO8PTGg5ro/l/GY7F/JMEBmI0BxA== +yargs@13.3.2, yargs@^13.3.0: + version "13.3.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" + integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw== dependencies: - cliui "^4.0.0" + cliui "^5.0.0" find-up "^3.0.0" get-caller-file "^2.0.1" - os-locale "^3.1.0" require-directory "^2.1.1" require-main-filename "^2.0.0" set-blocking "^2.0.0" string-width "^3.0.0" which-module "^2.0.0" y18n "^4.0.0" - yargs-parser "^13.0.0" - -yargs@^12.0.5: - version "12.0.5" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13" - integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw== - dependencies: - cliui "^4.0.0" - decamelize "^1.2.0" - find-up "^3.0.0" - get-caller-file "^1.0.1" - os-locale "^3.0.0" - require-directory "^2.1.1" - require-main-filename "^1.0.1" - set-blocking "^2.0.0" - string-width "^2.0.0" - which-module "^2.0.0" - y18n "^3.2.1 || ^4.0.0" - yargs-parser "^11.1.1" + yargs-parser "^13.1.2" diff --git a/pkg/keyaddr/key.go b/pkg/keyaddr/key.go index c06d072..4d84434 100644 --- a/pkg/keyaddr/key.go +++ b/pkg/keyaddr/key.go @@ -10,7 +10,6 @@ package keyaddr // https://www.apache.org/licenses/LICENSE-2.0.txt // - -- --- ---- ----- - // It is built using the gomobile tool, so the API is constrained to particular types of parameters: // // * string @@ -163,11 +162,11 @@ func (k *Key) HardenedChild(n int32) (*Key, error) { return KeyFromExtended(nk) } -// Sign uses the given key to sign a message; the message must be the +// SignSecP uses the given SecP key to sign a message; the message must be the // standard base64 encoding of the bytes of the message. // It returns a signature object. // The key must be a private key. -func (k *Key) Sign(msgstr string) (*Signature, error) { +func (k *Key) SignSecP(msgstr string) (*Signature, error) { msg, err := base64.StdEncoding.DecodeString(msgstr) if err != nil { return nil, errors.Wrap(err, "error decoding string") @@ -184,6 +183,37 @@ func (k *Key) Sign(msgstr string) (*Signature, error) { return SignatureFrom(sig) } +// SignEdB64 uses the given ED key to sign a message; the message must be the +// standard base64 encoding of the bytes of the message. +// It returns a signature object. +// The key must be a private key. +func (k *Key) SignEdB64(msgstr string) (*Signature, error) { + msg, err := base64.StdEncoding.DecodeString(msgstr) + if err != nil { + return nil, errors.Wrap(err, "error decoding b64 bstring") + } + pk, err := k.UnivToPrivateKey() + if err != nil { + return nil, errors.Wrap(err, "error getting private key") + } + sig := pk.Sign(msg) + return SignatureFrom(sig) +} + +// SignEdText uses the given ED key to sign a message; the message must be the +// text encoding of the bytes of the message. +// It returns a signature object. +// The key must be a private key. +func (k *Key) SignEdText(msgstr string) (*Signature, error) { + msg := []byte(msgstr) + pk, err := k.UnivToPrivateKey() + if err != nil { + return nil, errors.Wrap(err, "error getting private key") + } + sig := pk.Sign(msg) + return SignatureFrom(sig) +} + // NdauAddress returns the ndau address associated with the given key. // Key can be either public or private; if it is private it will be // converted to a public key first. diff --git a/pkg/keyaddr/key_conv.go b/pkg/keyaddr/key_conv.go index c281705..6407d93 100644 --- a/pkg/keyaddr/key_conv.go +++ b/pkg/keyaddr/key_conv.go @@ -9,7 +9,6 @@ package keyaddr // https://www.apache.org/licenses/LICENSE-2.0.txt // - -- --- ---- ----- - import ( "github.com/ndau/ndaumath/pkg/key" "github.com/ndau/ndaumath/pkg/signature" @@ -96,3 +95,14 @@ func (k *Key) ToPrivateKey() (signature.PrivateKey, error) { err = out.UnmarshalText(text) return out, err } + +// UnivToPrivateKey constructs a `signature.PrivateKey` from a `*Key` +func (k *Key) UnivToPrivateKey() (signature.PrivateKey, error) { + out := signature.PrivateKey{} + key, err := signature.ParseKey(k.Key) + if err != nil { + return out, errors.Wrap(err, "parsing key") + } + pkey := key.(*signature.PrivateKey) + return *pkey, nil +} diff --git a/pkg/signature/algorithm.go b/pkg/signature/algorithm.go index aae8e4a..76f5a04 100644 --- a/pkg/signature/algorithm.go +++ b/pkg/signature/algorithm.go @@ -9,7 +9,6 @@ package signature // https://www.apache.org/licenses/LICENSE-2.0.txt // - -- --- ---- ----- - import ( "io" "reflect" @@ -36,6 +35,9 @@ type Algorithm interface { // Generate creates a new keypair Generate(rand io.Reader) (public, private []byte, err error) + // Generate creates a new keypair + GenerateFromSeed(seed []byte) (public, private []byte, err error) + // Sign signs the message with privateKey and returns a signature Sign(private, message []byte) []byte // Verify verifies a message's signature @@ -116,3 +118,13 @@ func Generate(al Algorithm, rdr io.Reader) (public PublicKey, private PrivateKey } return } + +// Generate a high-level keypair from a given seed +func GenerateFromSeed(al Algorithm, seed []byte) (public PublicKey, private PrivateKey, err error) { + pubBytes, privBytes, err := al.GenerateFromSeed(seed) + if err == nil { + public = PublicKey{keyBase{algorithm: al, key: pubBytes, extra: []byte{}}} + private = PrivateKey{keyBase{algorithm: al, key: privBytes, extra: []byte{}}} + } + return +} diff --git a/pkg/signature/algorithms/ed25519/ed25519.go b/pkg/signature/algorithms/ed25519/ed25519.go index 0667bac..62e0c9b 100644 --- a/pkg/signature/algorithms/ed25519/ed25519.go +++ b/pkg/signature/algorithms/ed25519/ed25519.go @@ -9,8 +9,8 @@ package ed25519 // https://www.apache.org/licenses/LICENSE-2.0.txt // - -- --- ---- ----- - import ( + "errors" "io" impl "golang.org/x/crypto/ed25519" @@ -43,6 +43,17 @@ func (e ed25519) Generate(rand io.Reader) (public, private []byte, err error) { return impl.GenerateKey(rand) } +// GenerateFromSeed implements Algorithm +func (e ed25519) GenerateFromSeed(seed []byte) (public, private []byte, err error) { + if len(seed) != 32 { + return nil, nil, errors.New("seed must be length 32") + } + privKey := impl.NewKeyFromSeed(seed) + pubKey := (privKey.Public()).(impl.PublicKey) + + return pubKey, privKey, nil +} + // Sign implements Algorithm func (e ed25519) Sign(private, message []byte) []byte { return impl.Sign(impl.PrivateKey(private), message) diff --git a/pkg/signature/algorithms/null/null.go b/pkg/signature/algorithms/null/null.go index dbbfc08..c6a5950 100644 --- a/pkg/signature/algorithms/null/null.go +++ b/pkg/signature/algorithms/null/null.go @@ -9,7 +9,6 @@ package null // https://www.apache.org/licenses/LICENSE-2.0.txt // - -- --- ---- ----- - import ( "errors" "io" @@ -44,6 +43,11 @@ func (null) Generate(rand io.Reader) (public, private []byte, err error) { return []byte{}, []byte{}, errors.New("generating null keys is not permitted") } +// GenerateFromSeed implements Algorithm +func (null) GenerateFromSeed(seed []byte) (public, private []byte, err error) { + return []byte{}, []byte{}, errors.New("generating null keys is not permitted") +} + // Sign implements Algorithm func (n null) Sign(private, message []byte) []byte { return []byte{} diff --git a/pkg/signature/algorithms/secp256k1/secp256k1.go b/pkg/signature/algorithms/secp256k1/secp256k1.go index 93422c2..8179f46 100644 --- a/pkg/signature/algorithms/secp256k1/secp256k1.go +++ b/pkg/signature/algorithms/secp256k1/secp256k1.go @@ -9,9 +9,9 @@ package secp256k1 // https://www.apache.org/licenses/LICENSE-2.0.txt // - -- --- ---- ----- - import ( "crypto/sha256" + "errors" "io" "github.com/btcsuite/btcd/btcec" @@ -66,6 +66,19 @@ func (secp256k1) Generate(rand io.Reader) (public, private []byte, err error) { return } +// GenerateFromSeed creates a new keypair from a given seed +func (secp256k1) GenerateFromSeed(seed []byte) (public, private []byte, err error) { + if len(seed) != 32 { + return nil, nil, errors.New("seed must be length 32") + } + + prv, _, err := bip32.NewMaster(seed) + private = prv[:] + public = bip32.PrivateToPublic(private) + + return +} + // btcec documentation claims that we're not supposed to sign full messages, // but instead pre-hash the message and sign the hash. That sounds weird // to me, but who am I to disobey the documentation?