Skip to content

Commit

Permalink
feat: add verifySignature native function
Browse files Browse the repository at this point in the history
  • Loading branch information
Villaquiranm committed Sep 4, 2024
1 parent aae5d49 commit 5d3987a
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 0 deletions.
5 changes: 5 additions & 0 deletions examples/gno.land/r/gnoland/ghverify/contract.gno
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ func RequestVerification(githubHandle string) {
); err != nil {
panic(err)
}
std.Emit(
"verification_requested",
"from", gnoAddress,
"handle", githubHandle,
)
}

// GnorkleEntrypoint is the entrypoint to the gnorkle oracle handler.
Expand Down
36 changes: 36 additions & 0 deletions gnovm/stdlibs/generated.go
Original file line number Diff line number Diff line change
Expand Up @@ -721,6 +721,42 @@ 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")},
},
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 := libs_std.X_verifySignature(p0, p1, p2)

m.PushValue(gno.Go2GnoValue(
m.Alloc,
m.Store,
reflect.ValueOf(&r0).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,msg string, signature string) bool {
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
8 changes: 8 additions & 0 deletions gnovm/stdlibs/std/native.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,14 @@ func X_encodeBech32(prefix string, bytes [20]byte) string {
return b32
}

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

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
25 changes: 25 additions & 0 deletions gnovm/stdlibs/std/native_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@ import (

"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 +196,24 @@ 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)

if !X_verifySignature(publicKey, goodMessage, string(signature)) {
t.Error("verify failed")
}

if X_verifySignature(publicKey, maliciousMessage, string(signature)) {
t.Error("verify worked on malicious message")
}
}

0 comments on commit 5d3987a

Please sign in to comment.