Skip to content

Commit

Permalink
feat: verifySignature function
Browse files Browse the repository at this point in the history
  • Loading branch information
Villaquiranm committed Sep 9, 2024
1 parent 68b8f54 commit 76ec144
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 0 deletions.
42 changes: 42 additions & 0 deletions gnovm/stdlibs/generated.go
Original file line number Diff line number Diff line change
Expand Up @@ -721,6 +721,48 @@ var nativeFuncs = [...]NativeFunc{
))
},
},
{
"std",
"verifySignature",
[]gno.FieldTypeExpr{
{Name: gno.N("p0"), Type: gno.X("string")},
{Name: gno.N("p1"), Type: gno.X("string")},
{Name: gno.N("p2"), Type: gno.X("string")},
},
[]gno.FieldTypeExpr{
{Name: gno.N("r0"), Type: gno.X("bool")},
{Name: gno.N("r1"), Type: gno.X("string")},
},
false,
func(m *gno.Machine) {
b := m.LastBlock()
var (
p0 string
rp0 = reflect.ValueOf(&p0).Elem()
p1 string
rp1 = reflect.ValueOf(&p1).Elem()
p2 string
rp2 = reflect.ValueOf(&p2).Elem()
)

gno.Gno2GoValue(b.GetPointerTo(nil, gno.NewValuePathBlock(1, 0, "")).TV, rp0)
gno.Gno2GoValue(b.GetPointerTo(nil, gno.NewValuePathBlock(1, 1, "")).TV, rp1)
gno.Gno2GoValue(b.GetPointerTo(nil, gno.NewValuePathBlock(1, 2, "")).TV, rp2)

r0, r1 := libs_std.X_verifySignature(p0, p1, p2)

m.PushValue(gno.Go2GnoValue(
m.Alloc,
m.Store,
reflect.ValueOf(&r0).Elem(),
))
m.PushValue(gno.Go2GnoValue(
m.Alloc,
m.Store,
reflect.ValueOf(&r1).Elem(),
))
},
},
{
"strconv",
"Itoa",
Expand Down
5 changes: 5 additions & 0 deletions gnovm/stdlibs/std/native.gno
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ func DecodeBech32(addr Address) (prefix string, bz [20]byte, ok bool) {
return decodeBech32(string(addr))
}

func VerifySignature(pubKeySigner string, signature string, msg string) (bool, string) {
return verifySignature(pubKeySigner, msg, signature)
}

// Variations which don't use named types.
func origSend() (denoms []string, amounts []int64)
func origCaller() string
Expand All @@ -65,3 +69,4 @@ func getRealm(height int) (address string, pkgPath string)
func derivePkgAddr(pkgPath string) string
func encodeBech32(prefix string, bz [20]byte) string
func decodeBech32(addr string) (prefix string, bz [20]byte, ok bool)
func verifySignature(pubKeySigner string, msg string, signature string) (bool, string)
18 changes: 18 additions & 0 deletions gnovm/stdlibs/std/native.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package std

import (
"encoding/hex"

gno "github.com/gnolang/gno/gnovm/pkg/gnolang"
"github.com/gnolang/gno/tm2/pkg/bech32"
"github.com/gnolang/gno/tm2/pkg/crypto"
Expand Down Expand Up @@ -150,6 +152,22 @@ func X_encodeBech32(prefix string, bytes [20]byte) string {
return b32
}

func X_verifySignature(pubKeySigner string, msg string, signature string) (bool, string) {
key, err := crypto.PubKeyFromBech32(pubKeySigner)
if err != nil {
panic(err) // should not happen
}

decodedData, err := hex.DecodeString(signature)
if err != nil {
panic(err) // should not happen
}

validSignature := key.VerifyBytes([]byte(msg), decodedData)

return validSignature, key.Address().String()
}

func X_decodeBech32(addr string) (prefix string, bytes [20]byte, ok bool) {
prefix, bz, err := bech32.Decode(addr)
if err != nil || len(bz) != 20 {
Expand Down
33 changes: 33 additions & 0 deletions gnovm/stdlibs/std/native_test.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
package std

import (
"encoding/hex"
"testing"

"github.com/stretchr/testify/assert"

"github.com/gnolang/gno/gnovm/pkg/gnoenv"
gno "github.com/gnolang/gno/gnovm/pkg/gnolang"
"github.com/gnolang/gno/tm2/pkg/crypto"
"github.com/gnolang/gno/tm2/pkg/crypto/keys"
)

const DefaultAccount_Seed = "source bonus chronic canvas draft south burst lottery vacant surface solve popular case indicate oppose farm nothing bullet exhibit title speed wink action roast"

func TestPrevRealmIsOrigin(t *testing.T) {
var (
user = gno.DerivePkgAddr("user1.gno").Bech32()
Expand Down Expand Up @@ -192,3 +197,31 @@ func TestPrevRealmIsOrigin(t *testing.T) {
})
}
}

func TestVerify(t *testing.T) {
kb, _ := keys.NewKeyBaseFromDir(gnoenv.HomeDir())
pass := "hardPass"
info, err := kb.CreateAccount("user", DefaultAccount_Seed, pass, pass, 0, 0)
assert.NoError(t, err)

publicKey := info.GetPubKey().String() // gpub1pgfj7ard9eg82cjtv4u4xetrwqer2dntxyfzxz3pqfzjcj8wph4wl0x7tqu3k7geuqsz2d45eddys0hgf0xd7dr2dupnqukpghs
goodMessage := "Verification Ok"
maliciousMessage := "Malicious Message"
signature, _, err := kb.Sign("user", pass, []byte(goodMessage))
assert.NoError(t, err)
signatureHex := hex.EncodeToString(signature)
signatureValid, signer := X_verifySignature(publicKey, goodMessage, signatureHex)

if !signatureValid {
t.Error("verify failed")
}

if signer != info.GetAddress().String() {
t.Error("signer is not equal to address")
}

signatureValid, _ = X_verifySignature(publicKey, maliciousMessage, signatureHex)
if signatureValid {
t.Error("verify worked on malicious message")
}
}

0 comments on commit 76ec144

Please sign in to comment.