Skip to content

Commit

Permalink
Merge pull request #119 from filecoin-project/feat/delegated
Browse files Browse the repository at this point in the history
feat: support delegated address
  • Loading branch information
hunjixin authored Feb 17, 2023
2 parents 6727d22 + a82626f commit 2d97ede
Show file tree
Hide file tree
Showing 9 changed files with 166 additions and 12 deletions.
1 change: 0 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ show-env:
@echo '-------------------------------------------------'

lint:
gofmt -s -w ./
golangci-lint run

clean:
Expand Down
3 changes: 1 addition & 2 deletions cli/wallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"os"
"strings"

Expand Down Expand Up @@ -233,7 +232,7 @@ var walletImport = &cli.Command{
inpdata = indata

} else {
fdata, err := ioutil.ReadFile(cctx.Args().First())
fdata, err := os.ReadFile(cctx.Args().First())
if err != nil {
if strings.Contains(err.Error(), "no such file or directory") {
return errors.New("input whether it is a file, if not, exec `./venus-wallet import` and then `enter` ")
Expand Down
122 changes: 122 additions & 0 deletions crypto/delegated.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
package crypto

import (
"fmt"

"golang.org/x/crypto/sha3"

"github.com/filecoin-project/go-address"
gocrypto "github.com/filecoin-project/go-crypto"
"github.com/filecoin-project/go-state-types/builtin"
"github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/venus/venus-shared/types"
)

type delegatedPrivateKey struct {
key []byte
}

func newDelegatedKeyFromData(data []byte) PrivateKey {
return &delegatedPrivateKey{
key: data,
}
}

func genDelegatedPrivateKey() (PrivateKey, error) {
prv, err := gocrypto.GenerateKey()
if err != nil {
return nil, err
}
p := &delegatedPrivateKey{
key: prv,
}
return p, nil
}

func (p *delegatedPrivateKey) Public() []byte {
return gocrypto.PublicKey(p.key)
}

func (p *delegatedPrivateKey) Sign(msg []byte) (*crypto.Signature, error) {
hasher := sha3.NewLegacyKeccak256()
hasher.Write(msg)
hashSum := hasher.Sum(nil)
sig, err := gocrypto.Sign(p.key, hashSum)
if err != nil {
return nil, err
}

return &crypto.Signature{
Type: p.Type(),
Data: sig,
}, nil
}

func (p *delegatedPrivateKey) Bytes() []byte {
return p.key
}

func (p *delegatedPrivateKey) Address() (address.Address, error) {
pubKey := p.Public()
// Transitory Delegated signature verification as per FIP-0055
ethAddr, err := types.EthAddressFromPubKey(pubKey)
if err != nil {
return address.Undef, fmt.Errorf("failed to calculate Eth address from public key: %w", err)
}
ea, err := types.CastEthAddress(ethAddr)
if err != nil {
return address.Undef, fmt.Errorf("failed to create ethereum address from bytes: %w", err)
}

return ea.ToFilecoinAddress()
}

func (p *delegatedPrivateKey) Type() types.SigType {
return types.SigTypeDelegated
}

func (p *delegatedPrivateKey) KeyType() types.KeyType {
return types.KTDelegated
}

func (p *delegatedPrivateKey) ToKeyInfo() *types.KeyInfo {
return &types.KeyInfo{
PrivateKey: p.Bytes(),
Type: types.KTSecp256k1,
}
}

func delegatedVerify(sig []byte, a address.Address, msg []byte) error {
hasher := sha3.NewLegacyKeccak256()
hasher.Write(msg)
hash := hasher.Sum(nil)

pubk, err := gocrypto.EcRecover(hash, sig)
if err != nil {
return err
}

// if we get an uncompressed public key (that's what we get from the library,
// but putting this check here for defensiveness), strip the prefix
if pubk[0] == 0x04 {
pubk = pubk[1:]
}

hasher.Reset()
hasher.Write(pubk)
addrHash := hasher.Sum(nil)

// The address hash will not start with [12]byte{0xff}, so we don't have to use
// EthAddr.ToFilecoinAddress() to handle the case with an id address
// Also, importing ethtypes here will cause circulating import
maybeaddr, err := address.NewDelegatedAddress(builtin.EthereumAddressManagerActorID, addrHash[12:])
if err != nil {
return err
}

if maybeaddr != a {
return fmt.Errorf("signature did not match")
}

return nil
}
10 changes: 10 additions & 0 deletions crypto/key.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ func Verify(sig *crypto.Signature, addr address.Address, msg []byte) error {
return secpVerify(sig.Data, addr, msg)
case types.SigTypeBLS:
return blsVerify(sig.Data, addr, msg)
case types.SigTypeDelegated:
return delegatedVerify(sig.Data, addr, msg)
default:
return fmt.Errorf("cannot verify signature of unsupported type: %v", sig.Type)
}
Expand All @@ -49,6 +51,8 @@ func GeneratePrivateKey(st types.SigType) (PrivateKey, error) {
return genSecpPrivateKey()
case types.SigTypeBLS:
return genBlsPrivate()
case types.SigTypeDelegated:
return genDelegatedPrivateKey()
default:
return nil, fmt.Errorf("invalid signature type: %d", st)
}
Expand All @@ -60,6 +64,8 @@ func NewKeyFromKeyInfo(ki *types.KeyInfo) (PrivateKey, error) {
return newBlsKeyFromData(ki.PrivateKey)
case types.KTSecp256k1:
return newSecpKeyFromData(ki.PrivateKey), nil
case types.KTDelegated:
return newDelegatedKeyFromData(ki.PrivateKey), nil
default:
return nil, fmt.Errorf("invalid key type: %s", ki.Type)
}
Expand All @@ -71,6 +77,8 @@ func NewKeyFromData2(kt types.KeyType, prv []byte) (PrivateKey, error) {
return newBlsKeyFromData(prv)
case types.KTSecp256k1:
return newSecpKeyFromData(prv), nil
case types.KTDelegated:
return newDelegatedKeyFromData(prv), nil
default:
return nil, fmt.Errorf("invalid key type: %s", kt)
}
Expand All @@ -82,6 +90,8 @@ func NewKeyFromData(st types.SigType, prv []byte) (PrivateKey, error) {
return newSecpKeyFromData(prv), nil
case types.SigTypeBLS:
return newBlsKeyFromData(prv)
case types.SigTypeDelegated:
return newDelegatedKeyFromData(prv), nil
default:
return nil, fmt.Errorf("invalid signature type: %d", st)
}
Expand Down
28 changes: 28 additions & 0 deletions crypto/key_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,31 @@ func TestBLSPrivateKey(t *testing.T) {
}
assert.Equal(t, fmt.Sprintf("%x", signature.Data), "828e485cf906ae5deda33ec3e16b2a5ac761ab5a6109f481134a4dd40d7b5c3b03d187f614c7dd85d142ff50b902bdf50923f58b5bb741b4a522bf17f8efe5cf3f8f51715cd31a765eb5e5d76889102752d2cc2efa4287829cacb4de2be07cf7")
}

func TestDelegatedPrivateKey(t *testing.T) {
k := "33ff38fa8c1c53c3ef1b2f811cee9ce4f7ec2ce90b16ceeb9675dc6aa3d04821"
key, err := hex.DecodeString(k)
if err != nil {
t.Fatal(err)
}
prv, err := NewKeyFromData2(types.KTDelegated, key)
if err != nil {
t.Fatalf("load private key from bytes err:%s", err)
}

pub := prv.Public()
assert.Equal(t, fmt.Sprintf("%x", pub), "04f047588679644c440d8f7878fe29730e0cdc8c21b32ab8be5c8c01e1bf5d25e09609fff9c037fcd5cd6ac090e44a438c3d13a31a39a96a4b412831e4a3c83b0e")

addr, err := prv.Address()
if err != nil {
t.Fatalf("private key parse address error:%s", err)
}
assert.Equal(t, addr.String(), "t410fnz6o7a4owcgw33z2zvsxtuf64aoxlmcn4dh5hzy")

signData := []byte("hello filecoin")
signature, err := prv.Sign(signData)
if err != nil {
t.Fatalf("private key sign data err:%s", err)
}
assert.Equal(t, fmt.Sprintf("%x", signature.Data), "e8f6ad5958dde03013e45fc77f71238cd0013af0d05ec5569007f70ffa7d2453007e7a581dcdf6d9f8e89846de210b74b188d8e1d2629f2d351e9e92f08be29600")
}
5 changes: 2 additions & 3 deletions example/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"
"crypto/sha256"
"fmt"
"io/ioutil"
"log"
"os"
"os/exec"
Expand Down Expand Up @@ -79,12 +78,12 @@ func main() {
if err != nil {
log.Fatal(err)
}
tb, err := ioutil.ReadFile(path.Join(dir, "example", "remote-token.tmp"))
tb, err := os.ReadFile(path.Join(dir, "example", "remote-token.tmp"))
if err != nil {
log.Fatal(err)
}
token := strings.TrimSpace(string(tb))
pb, err := ioutil.ReadFile(path.Join(dir, "example", "pid.tmp"))
pb, err := os.ReadFile(path.Join(dir, "example", "pid.tmp"))
if err != nil {
log.Fatal(err)
}
Expand Down
3 changes: 1 addition & 2 deletions filemgr/fs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
package filemgr

import (
"io/ioutil"
"os"
"testing"

Expand All @@ -12,7 +11,7 @@ import (

func TestNewFS(t *testing.T) {
// stm: @VENUSWALLET_FILEMGR_FS_NEW_001
fsPath, err := ioutil.TempDir("", "venus-repo-")
fsPath, err := os.MkdirTemp("", "venus-repo-")
defer os.RemoveAll(fsPath)
if err != nil {
t.Fatal(err)
Expand Down
3 changes: 1 addition & 2 deletions filemgr/jwt.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"crypto/rand"
"encoding/hex"
"io"
"io/ioutil"

"github.com/filecoin-project/venus-wallet/config"
"github.com/filecoin-project/venus/venus-shared/api/permission"
Expand All @@ -22,7 +21,7 @@ type jwtSecret struct {

// Random generation of secret keys
func randSecret() (*jwtSecret, error) {
sk, err := ioutil.ReadAll(io.LimitReader(rand.Reader, 32))
sk, err := io.ReadAll(io.LimitReader(rand.Reader, 32))
if err != nil {
return nil, err
}
Expand Down
3 changes: 1 addition & 2 deletions integration_test/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package integration
import (
"context"
"fmt"
"io/ioutil"
"os"
"strings"
"syscall"
Expand Down Expand Up @@ -104,7 +103,7 @@ func (inst *WalletInst) StopAndWait() error {
}

func NewWalletInst() (*WalletInst, error) {
dir, err := ioutil.TempDir("", "venus_wallet_")
dir, err := os.MkdirTemp("", "venus_wallet_")
if err != nil {
return nil, err
}
Expand Down

0 comments on commit 2d97ede

Please sign in to comment.