crypto: add StringCompressed() for PublicKey

Add StringCompressed to get a string representation of the key in
compressed form.

Close #3263

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
This commit is contained in:
Ekaterina Pavlova 2024-04-09 12:13:43 +03:00
parent 8913542f93
commit ae3515e819
19 changed files with 64 additions and 74 deletions

View file

@ -1,7 +1,6 @@
package cmdargs
import (
"encoding/hex"
"strings"
"testing"
@ -45,7 +44,7 @@ func TestParseCosigner(t *testing.T) {
Scopes: transaction.CalledByEntry | transaction.CustomContracts,
AllowedContracts: []util.Uint160{c1, c2},
},
acc.StringLE() + ":CustomGroups:" + hex.EncodeToString(priv.PublicKey().Bytes()): {
acc.StringLE() + ":CustomGroups:" + priv.PublicKey().StringCompressed(): {
Account: acc,
Scopes: transaction.CustomGroups,
AllowedGroups: keys.PublicKeys{priv.PublicKey()},

View file

@ -3,7 +3,6 @@ package query
import (
"bytes"
"encoding/base64"
"encoding/hex"
"fmt"
"sort"
"strconv"
@ -204,7 +203,7 @@ func queryCandidates(ctx *cli.Context) error {
var res []byte
res = fmt.Appendf(res, "Key\tVotes\tCommittee\tConsensus\n")
for _, val := range vals {
res = fmt.Appendf(res, "%s\t%d\t%t\t%t\n", hex.EncodeToString(val.PublicKey.Bytes()), val.Votes, comm.Contains(&val.PublicKey), val.Active)
res = fmt.Appendf(res, "%s\t%d\t%t\t%t\n", val.PublicKey.StringCompressed(), val.Votes, comm.Contains(&val.PublicKey), val.Active)
}
tw := tabwriter.NewWriter(ctx.App.Writer, 0, 2, 2, ' ', 0)
_, err = tw.Write(res)
@ -235,7 +234,7 @@ func queryCommittee(ctx *cli.Context) error {
}
for _, k := range comm {
fmt.Fprintln(ctx.App.Writer, hex.EncodeToString(k.Bytes()))
fmt.Fprintln(ctx.App.Writer, k.StringCompressed())
}
return nil
}
@ -306,7 +305,7 @@ func queryVoter(ctx *cli.Context) error {
}
voted := "null"
if st.VoteTo != nil {
voted = fmt.Sprintf("%s (%s)", hex.EncodeToString(st.VoteTo.Bytes()), address.Uint160ToString(st.VoteTo.GetScriptHash()))
voted = fmt.Sprintf("%s (%s)", st.VoteTo.StringCompressed(), address.Uint160ToString(st.VoteTo.GetScriptHash()))
}
fmt.Fprintf(ctx.App.Writer, "\tVoted: %s\n", voted)
fmt.Fprintf(ctx.App.Writer, "\tAmount : %s\n", fixedn.ToString(&st.Balance, int(dec)))

View file

@ -1,7 +1,6 @@
package smartcontract
import (
"encoding/hex"
"errors"
"fmt"
@ -28,10 +27,9 @@ func (p permission) MarshalYAML() (any, error) {
&yaml.Node{Kind: yaml.ScalarNode, Value: permHashKey},
&yaml.Node{Kind: yaml.ScalarNode, Value: p.Contract.Value.(util.Uint160).StringLE()})
case manifest.PermissionGroup:
bs := p.Contract.Value.(*keys.PublicKey).Bytes()
m.Content = append(m.Content,
&yaml.Node{Kind: yaml.ScalarNode, Value: permGroupKey},
&yaml.Node{Kind: yaml.ScalarNode, Value: hex.EncodeToString(bs)})
&yaml.Node{Kind: yaml.ScalarNode, Value: p.Contract.Value.(*keys.PublicKey).StringCompressed()})
default:
return nil, fmt.Errorf("invalid permission type: %d", p.Contract.Type)
}

View file

@ -1,7 +1,6 @@
package smartcontract
import (
"encoding/hex"
"flag"
"os"
"testing"
@ -109,7 +108,7 @@ func TestPermissionMarshal(t *testing.T) {
p.Methods.Add("abc")
p.Methods.Add("lamao")
testPermissionMarshal(t, p,
"group: "+hex.EncodeToString(priv.PublicKey().Bytes())+"\n"+
"group: "+priv.PublicKey().StringCompressed()+"\n"+
"methods:\n - abc\n - lamao\n")
})
}
@ -118,7 +117,7 @@ func TestPermissionUnmarshalInvalid(t *testing.T) {
priv, err := keys.NewPrivateKey()
require.NoError(t, err)
pub := hex.EncodeToString(priv.PublicKey().Bytes())
pub := priv.PublicKey().StringCompressed()
u160 := random.Uint160().StringLE()
testCases := []string{
"hash: []\nmethods: '*'\n", // invalid hash type

View file

@ -1,7 +1,6 @@
package wallet_test
import (
"encoding/hex"
"math/big"
"strconv"
"testing"
@ -18,7 +17,7 @@ func TestRegisterCandidate(t *testing.T) {
validatorAddress := testcli.ValidatorPriv.Address()
validatorPublic := testcli.ValidatorPriv.PublicKey()
validatorHex := hex.EncodeToString(validatorPublic.Bytes())
validatorHex := validatorPublic.StringCompressed()
e.In.WriteString("one\r")
e.Run(t, "neo-go", "wallet", "nep17", "multitransfer",

View file

@ -1,7 +1,6 @@
package wallet_test
import (
"encoding/hex"
"encoding/json"
"fmt"
"math/big"
@ -45,9 +44,9 @@ func TestSignMultisigTx(t *testing.T) {
"--wallet", w,
"--wif", wif,
"--min", "2",
hex.EncodeToString(pubs[0].Bytes()),
hex.EncodeToString(pubs[1].Bytes()),
hex.EncodeToString(pubs[2].Bytes()))
pubs[0].StringCompressed(),
pubs[1].StringCompressed(),
pubs[2].StringCompressed())
}
addAccount(wallet1Path, privs[0].WIF())
addAccount(wallet2Path, privs[1].WIF())

View file

@ -1,7 +1,6 @@
package wallet_test
import (
"encoding/hex"
"encoding/json"
"math/big"
"os"
@ -437,16 +436,16 @@ func TestWalletInit(t *testing.T) {
"--wallet", walletPath,
"--min", "2"}
t.Run("invalid pub encoding", func(t *testing.T) {
e.RunWithError(t, append(cmd, hex.EncodeToString(pubs[1].Bytes()),
hex.EncodeToString(pubs[1].Bytes()),
hex.EncodeToString(pubs[2].Bytes()),
e.RunWithError(t, append(cmd, pubs[1].StringCompressed(),
pubs[1].StringCompressed(),
pubs[2].StringCompressed(),
"not-a-pub")...)
})
t.Run("missing WIF", func(t *testing.T) {
e.RunWithError(t, append(cmd, hex.EncodeToString(pubs[0].Bytes()),
hex.EncodeToString(pubs[1].Bytes()),
hex.EncodeToString(pubs[2].Bytes()),
hex.EncodeToString(pubs[3].Bytes()))...)
e.RunWithError(t, append(cmd, pubs[0].StringCompressed(),
pubs[1].StringCompressed(),
pubs[2].StringCompressed(),
pubs[3].StringCompressed())...)
})
cmd = append(cmd, "--wif", privs[0].WIF())
t.Run("InvalidPublicKeys", func(t *testing.T) {
@ -455,18 +454,18 @@ func TestWalletInit(t *testing.T) {
e.In.WriteString("multipass\r")
defer e.In.Reset()
e.RunWithError(t, append(cmd, hex.EncodeToString(pubs[1].Bytes()),
hex.EncodeToString(pubs[1].Bytes()),
hex.EncodeToString(pubs[2].Bytes()),
hex.EncodeToString(pubs[3].Bytes()))...)
e.RunWithError(t, append(cmd, pubs[1].StringCompressed(),
pubs[1].StringCompressed(),
pubs[2].StringCompressed(),
pubs[3].StringCompressed())...)
})
e.In.WriteString("multiacc\r")
e.In.WriteString("multipass\r")
e.In.WriteString("multipass\r")
e.Run(t, append(cmd, hex.EncodeToString(pubs[0].Bytes()),
hex.EncodeToString(pubs[1].Bytes()),
hex.EncodeToString(pubs[2].Bytes()),
hex.EncodeToString(pubs[3].Bytes()))...)
e.Run(t, append(cmd, pubs[0].StringCompressed(),
pubs[1].StringCompressed(),
pubs[2].StringCompressed(),
pubs[3].StringCompressed())...)
script, err := smartcontract.CreateMultiSigRedeemScript(2, pubs)
require.NoError(t, err)
@ -482,10 +481,10 @@ func TestWalletInit(t *testing.T) {
e.In.WriteString("multiacc\r")
e.In.WriteString("multipass\r")
e.In.WriteString("multipass\r")
e.RunWithError(t, append(cmd, hex.EncodeToString(pubs[0].Bytes()),
hex.EncodeToString(pubs[1].Bytes()),
hex.EncodeToString(pubs[2].Bytes()),
hex.EncodeToString(pubs[3].Bytes()))...)
e.RunWithError(t, append(cmd, pubs[0].StringCompressed(),
pubs[1].StringCompressed(),
pubs[2].StringCompressed(),
pubs[3].StringCompressed())...)
})
privs, pubs = testcli.GenerateKeys(t, 3)
@ -508,9 +507,9 @@ func TestWalletInit(t *testing.T) {
e.Run(t, "neo-go", "wallet", "import-multisig",
"--wallet", walletPath,
"--min", "2",
hex.EncodeToString(pubs[0].Bytes()), // Public key of the already imported account
hex.EncodeToString(pubs[1].Bytes()),
hex.EncodeToString(pubs[2].Bytes()))
pubs[0].StringCompressed(), // Public key of the already imported account
pubs[1].StringCompressed(),
pubs[2].StringCompressed())
w, err := wallet.NewWalletFromFile(walletPath)
require.NoError(t, err)
@ -530,9 +529,9 @@ func TestWalletInit(t *testing.T) {
e.RunWithError(t, "neo-go", "wallet", "import-multisig",
"--wallet", walletPath,
"--min", "2",
hex.EncodeToString(pubsNew[0].Bytes()),
hex.EncodeToString(pubsNew[1].Bytes()),
hex.EncodeToString(pubsNew[2].Bytes()))
pubsNew[0].StringCompressed(),
pubsNew[1].StringCompressed(),
pubsNew[2].StringCompressed())
w, err := wallet.NewWalletFromFile(walletPath)
require.NoError(t, err)

View file

@ -196,7 +196,7 @@ func Init(t *testing.T, rootpath string, e *neotest.Executor) {
require.NoError(t, ntr.Accounts[0].Decrypt("one", ntr.Scrypt))
designateSuperInvoker.Invoke(t, stackitem.Null{}, "designateAsRole",
int64(noderoles.P2PNotary), []any{ntr.Accounts[0].PublicKey().Bytes()})
t.Logf("Designated Notary node: %s", hex.EncodeToString(ntr.Accounts[0].PublicKey().Bytes()))
t.Logf("Designated Notary node: %s", ntr.Accounts[0].PublicKey().StringCompressed())
// Block #10: push verification contract with arguments into the chain.
verifyPath = filepath.Join(testDataPrefix, "verify_args", "verification_with_args_contract.go")

View file

@ -2,7 +2,6 @@ package config
import (
"encoding/base64"
"encoding/hex"
"fmt"
"path/filepath"
"testing"
@ -320,7 +319,7 @@ func TestGenesisExtensionsMarshalYAML(t *testing.T) {
t.Run("unmarshal config", func(t *testing.T) {
t.Run("good", func(t *testing.T) {
pubStr := hex.EncodeToString(pub.Bytes())
pubStr := pub.StringCompressed()
script := []byte{1, 2, 3, 4}
cfgYml := fmt.Sprintf(`ProtocolConfiguration:
Genesis:
@ -354,7 +353,7 @@ func TestGenesisExtensionsMarshalYAML(t *testing.T) {
})
t.Run("unknown role", func(t *testing.T) {
pubStr := hex.EncodeToString(pub.Bytes())
pubStr := pub.StringCompressed()
cfgYml := fmt.Sprintf(`ProtocolConfiguration:
Genesis:
Roles:
@ -367,7 +366,7 @@ func TestGenesisExtensionsMarshalYAML(t *testing.T) {
})
t.Run("last role", func(t *testing.T) {
pubStr := hex.EncodeToString(pub.Bytes())
pubStr := pub.StringCompressed()
cfgYml := fmt.Sprintf(`ProtocolConfiguration:
Genesis:
Roles:

View file

@ -364,7 +364,7 @@ func (p *PublicKey) String() string {
// MarshalJSON implements the json.Marshaler interface.
func (p PublicKey) MarshalJSON() ([]byte, error) {
return json.Marshal(hex.EncodeToString(p.Bytes()))
return json.Marshal(p.StringCompressed())
}
// UnmarshalJSON implements the json.Unmarshaler interface.
@ -389,7 +389,7 @@ func (p *PublicKey) UnmarshalJSON(data []byte) error {
// MarshalYAML implements the YAML marshaler interface.
func (p *PublicKey) MarshalYAML() (any, error) {
return hex.EncodeToString(p.Bytes()), nil
return p.StringCompressed(), nil
}
// UnmarshalYAML implements the YAML unmarshaler interface.
@ -406,3 +406,9 @@ func (p *PublicKey) UnmarshalYAML(unmarshal func(any) error) error {
}
return p.DecodeBytes(b)
}
// StringCompressed returns the hex string representation of the public key
// in its compressed form.
func (p *PublicKey) StringCompressed() string {
return hex.EncodeToString(p.Bytes())
}

View file

@ -77,7 +77,7 @@ func TestDecodeFromString(t *testing.T) {
str := "03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c"
pubKey, err := NewPublicKeyFromString(str)
require.NoError(t, err)
require.Equal(t, str, hex.EncodeToString(pubKey.Bytes()))
require.Equal(t, str, pubKey.StringCompressed())
_, err = NewPublicKeyFromString(str[2:])
require.Error(t, err)

View file

@ -95,12 +95,12 @@ func init() {
// Config entry must contain validators first in a specific order.
standByCommittee = make([]string, len(pubs))
standByCommittee[0] = hex.EncodeToString(pubs[2].Bytes())
standByCommittee[1] = hex.EncodeToString(pubs[0].Bytes())
standByCommittee[2] = hex.EncodeToString(pubs[3].Bytes())
standByCommittee[3] = hex.EncodeToString(pubs[1].Bytes())
standByCommittee[4] = hex.EncodeToString(pubs[4].Bytes())
standByCommittee[5] = hex.EncodeToString(pubs[5].Bytes())
standByCommittee[0] = pubs[2].StringCompressed()
standByCommittee[1] = pubs[0].StringCompressed()
standByCommittee[2] = pubs[3].StringCompressed()
standByCommittee[3] = pubs[1].StringCompressed()
standByCommittee[4] = pubs[4].StringCompressed()
standByCommittee[5] = pubs[5].StringCompressed()
multiValidatorAcc = make([]*wallet.Account, 4)
sort.Sort(pubs[:4])

View file

@ -1,7 +1,6 @@
package oracle
import (
"encoding/hex"
"errors"
"fmt"
gio "io"
@ -45,7 +44,7 @@ func (o *Oracle) AddResponse(pub *keys.PublicKey, reqID uint64, txSig []byte) {
ok = pub.VerifyHashable(txSig, uint32(o.Network), incTx.backupTx)
if !ok {
o.Log.Debug("invalid response signature",
zap.String("pub", hex.EncodeToString(pub.Bytes())))
zap.String("pub", pub.StringCompressed()))
incTx.Unlock()
return
}

View file

@ -1,7 +1,6 @@
package context
import (
"encoding/hex"
"encoding/json"
"testing"
@ -185,7 +184,7 @@ func TestParameterContext_MarshalJSON(t *testing.T) {
Value: sign,
}},
Signatures: map[string][]byte{
hex.EncodeToString(priv.PublicKey().Bytes()): sign,
priv.PublicKey().StringCompressed(): sign,
},
},
},

View file

@ -1,8 +1,6 @@
package context
import (
"encoding/hex"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
)
@ -16,11 +14,11 @@ type Item struct {
// GetSignature returns a signature for the pub if present.
func (it *Item) GetSignature(pub *keys.PublicKey) []byte {
return it.Signatures[hex.EncodeToString(pub.Bytes())]
return it.Signatures[pub.StringCompressed()]
}
// AddSignature adds a signature for the pub.
func (it *Item) AddSignature(pub *keys.PublicKey, sig []byte) {
pubHex := hex.EncodeToString(pub.Bytes())
pubHex := pub.StringCompressed()
it.Signatures[pubHex] = sig
}

View file

@ -1,7 +1,6 @@
package context
import (
"encoding/hex"
"testing"
"github.com/nspcc-dev/neo-go/internal/random"
@ -46,8 +45,8 @@ func TestContextItem_MarshalJSON(t *testing.T) {
Value: random.Bytes(keys.SignatureLen),
}},
Signatures: map[string][]byte{
hex.EncodeToString(priv1.PublicKey().Bytes()): random.Bytes(keys.SignatureLen),
hex.EncodeToString(priv2.PublicKey().Bytes()): random.Bytes(keys.SignatureLen),
priv1.PublicKey().StringCompressed(): random.Bytes(keys.SignatureLen),
priv2.PublicKey().StringCompressed(): random.Bytes(keys.SignatureLen),
},
}

View file

@ -79,7 +79,7 @@ func (g Groups) Contains(k *keys.PublicKey) bool {
// MarshalJSON implements the json.Marshaler interface.
func (g *Group) MarshalJSON() ([]byte, error) {
aux := &groupAux{
PublicKey: hex.EncodeToString(g.PublicKey.Bytes()),
PublicKey: g.PublicKey.StringCompressed(),
Signature: g.Signature,
}
return json.Marshal(aux)

View file

@ -2,7 +2,6 @@ package manifest
import (
"crypto/elliptic"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
@ -204,7 +203,7 @@ func (d *PermissionDesc) MarshalJSON() ([]byte, error) {
case PermissionHash:
return json.Marshal("0x" + d.Hash().StringLE())
case PermissionGroup:
return json.Marshal(hex.EncodeToString(d.Group().Bytes()))
return json.Marshal(d.Group().StringCompressed())
default:
return []byte(`"*"`), nil
}

View file

@ -1,7 +1,6 @@
package wallet
import (
"encoding/hex"
"encoding/json"
"testing"
@ -237,7 +236,7 @@ func compareFields(t *testing.T, tk keytestcases.Ktype, acc *Account) {
require.Equalf(t, want, have, "expected address %s got %s", want, have)
want, have = tk.Wif, acc.privateKey.WIF()
require.Equalf(t, want, have, "expected wif %s got %s", want, have)
want, have = tk.PublicKey, hex.EncodeToString(acc.PublicKey().Bytes())
want, have = tk.PublicKey, acc.PublicKey().StringCompressed()
require.Equalf(t, want, have, "expected pub key %s got %s", want, have)
want, have = tk.PrivateKey, acc.privateKey.String()
require.Equalf(t, want, have, "expected priv key %s got %s", want, have)