Skip to content

Commit

Permalink
add signature verification for secp and bls
Browse files Browse the repository at this point in the history
Signed-off-by: Ignacio Hagopian <jsign.uy@gmail.com>
  • Loading branch information
jsign committed Sep 7, 2021
1 parent 09ca970 commit b4937ff
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 18 deletions.
14 changes: 14 additions & 0 deletions bls/bls.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,17 @@ func Sign(pk []byte, msg []byte) ([]byte, error) {
}
return s, nil
}

// Verify verifies that a message is correctly signed by a public key.
func Verify(pubkey, msg, sig []byte) bool {
point := curve12381.NewGroupG1().Point()
if err := point.UnmarshalBinary(pubkey); err != nil {
return false
}
signer := bls.NewSchemeOnG2(curve12381.NewBLS12381Suite())
if err := signer.Verify(point, msg, sig); err != nil {
return false
}

return true
}
23 changes: 23 additions & 0 deletions secp256k1/secp256k1.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package secp256k1

import (
"bytes"
"fmt"

"github.com/dchest/blake2b"
Expand Down Expand Up @@ -28,6 +29,28 @@ func Sign(pk []byte, msg []byte) ([]byte, error) {
return sig, nil
}

// Verify verifies that a message is correctly signed by a public key.
func Verify(pubkey, msg, sig []byte) bool {
// We need to do the inverse operation of signatures.b
recoveryID := sig[64] + 27
copy(sig[1:], sig)
sig[0] = recoveryID

msgHash := blake2b.Sum256(msg)
vpubkey, _, err := ecdsa.RecoverCompact(sig, msgHash[:])
if err != nil {
return false
}
verifAddr, err := address.NewSecp256k1Address(vpubkey.SerializeUncompressed())
if err != nil {
return false
}
if !bytes.Equal(verifAddr.Payload(), pubkey) {
return false
}
return true
}

func GetPubKey(pk []byte) (address.Address, error) {
priv := secp256k1.PrivKeyFromBytes(pk)
pubkey := priv.PubKey()
Expand Down
15 changes: 15 additions & 0 deletions wallet/wallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,21 @@ func WalletSign(exportedPK string, msg []byte) (*crypto.Signature, error) {
}
}

func WalletVerify(publicKey address.Address, msg []byte, sig []byte) (bool, error) {
var signature crypto.Signature
if err := signature.UnmarshalBinary(sig); err != nil {
return false, fmt.Errorf("unmarshaling signature: %s", err)
}
switch publicKey.Protocol() {
case address.SECP256K1:
return secp256k1.Verify(publicKey.Payload(), msg, signature.Data), nil
case address.BLS:
return bls.Verify(publicKey.Payload(), msg, signature.Data), nil
default:
return false, fmt.Errorf("address type not supported")
}
}

func PublicKey(lotusExportedPK string) (address.Address, error) {
ki, err := decodeLotusExportedPK(lotusExportedPK)
if err != nil {
Expand Down
94 changes: 76 additions & 18 deletions wallet/wallet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,62 @@ import (
"encoding/hex"
"testing"

"github.com/filecoin-project/go-address"
"github.com/stretchr/testify/require"
)

var msg = []byte("DUKE") // 44554b45 in hex.

func TestSecp256k1(t *testing.T) {
t.Parallel()

publicAddr := "f1fib3pv7jua2ockdugtz7viz3cyy6lkhh7rfx3sa"

// lotus wallet export f1fib3pv7jua2ockdugtz7viz3cyy6lkhh7rfx3sa
pk64 := "7b2254797065223a22736563703235366b31222c22507269766174654b6579223a226b35507976337148327349586343595a58594f5775453149326e32554539436861556b6c4e36695a5763453d227d"
privateKeyHex := "7b2254797065223a22736563703235366b31222c22507269766174654b6579223a226b35507976337148327349586343595a58594f5775453149326e32554539436861556b6c4e36695a5763453d227d"

// lotus wallet sign f1fib3pv7jua2ockdugtz7viz3cyy6lkhh7rfx3sa 44554b45
hexSignature := "0103bff286f1371c1a4ce8e33c29d6a20eeb53f17970190d12c5a1c0fc4be9a56e766250d5a82dda2179fa90ae297696d1dfaa9eea8f2f833da0cf87b927294eb700"

t.Run("sign", func(t *testing.T) {
t.Parallel()

lotusFormatSig := testSign(t, pk64)
sig, err := WalletSign(privateKeyHex, msg)
require.NoError(t, err)
sigm, err := sig.MarshalBinary()
require.NoError(t, err)
genHexSignature := hex.EncodeToString(sigm)

require.Equal(t, hexSignature, genHexSignature)
})

t.Run("verify", func(t *testing.T) {
t.Parallel()

// Check that signature verification succeeds with correct: signature, message, and public key.
sig, err := hex.DecodeString(hexSignature)
require.NoError(t, err)
addr, err := address.NewFromString(publicAddr)
require.NoError(t, err)
okSig, err := WalletVerify(addr, msg, sig)
require.NoError(t, err)
require.True(t, okSig)

// Check that signature verification fails with incorrect message.
okSig, err = WalletVerify(addr, []byte("DUKEZ"), sig)
require.NoError(t, err)
require.False(t, okSig)

// lotus wallet sign f1fib3pv7jua2ockdugtz7viz3cyy6lkhh7rfx3sa 44554b45
require.Equal(t, "0103bff286f1371c1a4ce8e33c29d6a20eeb53f17970190d12c5a1c0fc4be9a56e766250d5a82dda2179fa90ae297696d1dfaa9eea8f2f833da0cf87b927294eb700", lotusFormatSig)
// Check that signature verification fails with incorrect public key.
wrongAddr, err := address.NewFromString("f1fib3pv7jua2ockdugtz7viz3cyy6lkhh7rfx3sb")
require.NoError(t, err)
okSig, err = WalletVerify(wrongAddr, msg, sig)
require.NoError(t, err)
require.False(t, okSig)
})

t.Run("gen-pubkey", func(t *testing.T) {
addr, err := PublicKey(pk64)
addr, err := PublicKey(privateKeyHex)
require.NoError(t, err)
require.Equal(t, "f1fib3pv7jua2ockdugtz7viz3cyy6lkhh7rfx3sa", addr.String())
})
Expand All @@ -32,27 +68,49 @@ func TestSecp256k1(t *testing.T) {
func TestBLSSign(t *testing.T) {
t.Parallel()

publicAddr := "f3rpskqryflc2sqzzzu7j2q6fecrkdkv4p2avpf4kyk5u754he7g6cr2rbpmif7pam5oxbme2oyzot4ry3d74q"

// lotus wallet export f3rpskqryflc2sqzzzu7j2q6fecrkdkv4p2avpf4kyk5u754he7g6cr2rbpmif7pam5oxbme2oyzot4ry3d74q
pk64 := "7b2254797065223a22626c73222c22507269766174654b6579223a226862702f794666527439514c43716b6d566171415752436f50556777314b776971716e73684e49704e57513d227d"
privateKeyHex := "7b2254797065223a22626c73222c22507269766174654b6579223a226862702f794666527439514c43716b6d566171415752436f50556777314b776971716e73684e49704e57513d227d"

// lotus wallet sign f3rpskqryflc2sqzzzu7j2q6fecrkdkv4p2avpf4kyk5u754he7g6cr2rbpmif7pam5oxbme2oyzot4ry3d74q 44554b45
hexSignature := "0280cef41af956cf6855725a5af0d8d956ea41f6da2688cc1f436a7ea5ebd15d96ba384746b819c0836c53a54d6d30b0a70b528204e9da92f833031e7a4776f57bad83e033ea0235bad0f8a5337a4eb66870fc0429175ed63f91203ec1b65c6e31"

t.Run("sign", func(t *testing.T) {
t.Parallel()

lotusFormatSig := testSign(t, pk64)
sig, err := WalletSign(privateKeyHex, msg)
require.NoError(t, err)
sigm, err := sig.MarshalBinary()
require.NoError(t, err)
genHexSignature := hex.EncodeToString(sigm)

// lotus wallet sign f3rpskqryflc2sqzzzu7j2q6fecrkdkv4p2avpf4kyk5u754he7g6cr2rbpmif7pam5oxbme2oyzot4ry3d74q 44554b45
require.Equal(t, "0280cef41af956cf6855725a5af0d8d956ea41f6da2688cc1f436a7ea5ebd15d96ba384746b819c0836c53a54d6d30b0a70b528204e9da92f833031e7a4776f57bad83e033ea0235bad0f8a5337a4eb66870fc0429175ed63f91203ec1b65c6e31", lotusFormatSig)
require.Equal(t, hexSignature, genHexSignature)
})
}

func testSign(t *testing.T, lotusExportedPK string) string {
t.Helper()
msg := []byte("DUKE")
t.Run("verify", func(t *testing.T) {
t.Parallel()

// Check that signature verification succeeds with correct: signature, message, and public key.
sig, err := hex.DecodeString(hexSignature)
require.NoError(t, err)
addr, err := address.NewFromString(publicAddr)
require.NoError(t, err)
okSig, err := WalletVerify(addr, msg, sig)
require.NoError(t, err)
require.True(t, okSig)

// Check that signature verification fails with incorrect message.
okSig, err = WalletVerify(addr, []byte("DUKEZ"), sig)
require.NoError(t, err)
require.False(t, okSig)

sig, err := WalletSign(lotusExportedPK, msg)
require.NoError(t, err)
// Check that signature verification fails with incorrect public key.
wrongAddr, err := address.NewFromString("f3wmv7nhiqosmlr6mis2mr4xzupdhe3rtvw5ntis4x6yru7jhm35pfla2pkwgwfa3t62kdmoylssczmf74yika")
require.NoError(t, err)
okSig, err = WalletVerify(wrongAddr, msg, sig)
require.NoError(t, err)
require.False(t, okSig)

sigm, err := sig.MarshalBinary()
require.NoError(t, err)
return hex.EncodeToString(sigm)
})
}

0 comments on commit b4937ff

Please sign in to comment.