parent
0e8bf83dda
commit
16f952270c
3 changed files with 47 additions and 0 deletions
|
@ -2,6 +2,7 @@ package native
|
|||
|
||||
import (
|
||||
"crypto/elliptic"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
|
@ -14,6 +15,7 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
"github.com/twmb/murmur3"
|
||||
)
|
||||
|
||||
// Crypto represents CryptoLib contract.
|
||||
|
@ -46,6 +48,12 @@ func newCrypto() *Crypto {
|
|||
md = newMethodAndPrice(c.ripemd160, 1<<15, callflag.NoneFlag)
|
||||
c.AddMethod(md, desc)
|
||||
|
||||
desc = newDescriptor("murmur32", smartcontract.ByteArrayType,
|
||||
manifest.NewParameter("data", smartcontract.ByteArrayType),
|
||||
manifest.NewParameter("seed", smartcontract.IntegerType))
|
||||
md = newMethodAndPrice(c.murmur32, 1<<13, callflag.NoneFlag)
|
||||
c.AddMethod(md, desc)
|
||||
|
||||
desc = newDescriptor("verifyWithECDsa", smartcontract.BoolType,
|
||||
manifest.NewParameter("message", smartcontract.ByteArrayType),
|
||||
manifest.NewParameter("pubkey", smartcontract.ByteArrayType),
|
||||
|
@ -72,6 +80,18 @@ func (c *Crypto) ripemd160(_ *interop.Context, args []stackitem.Item) stackitem.
|
|||
return stackitem.NewByteArray(hash.RipeMD160(bs).BytesBE())
|
||||
}
|
||||
|
||||
func (c *Crypto) murmur32(_ *interop.Context, args []stackitem.Item) stackitem.Item {
|
||||
bs, err := args[0].TryBytes()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
seed := toUint32(args[1])
|
||||
h := murmur3.SeedSum32(seed, bs)
|
||||
result := make([]byte, 4)
|
||||
binary.LittleEndian.PutUint32(result, h)
|
||||
return stackitem.NewByteArray(result)
|
||||
}
|
||||
|
||||
func (c *Crypto) verifyWithECDsa(_ *interop.Context, args []stackitem.Item) stackitem.Item {
|
||||
msg, err := args[0].TryBytes()
|
||||
if err != nil {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package native
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"math"
|
||||
"math/big"
|
||||
|
@ -43,6 +44,26 @@ func TestRIPEMD160(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestMurmur32(t *testing.T) {
|
||||
c := newCrypto()
|
||||
ic := &interop.Context{VM: vm.New()}
|
||||
|
||||
t.Run("bad arg type", func(t *testing.T) {
|
||||
require.Panics(t, func() {
|
||||
c.murmur32(ic, []stackitem.Item{stackitem.NewInterop(nil), stackitem.Make(5)})
|
||||
})
|
||||
})
|
||||
t.Run("good", func(t *testing.T) {
|
||||
// Example from the C# node:
|
||||
// https://github.com/neo-project/neo/blob/2a64c1cc809d1ff4b3a573c7c22bffbbf69a738b/tests/neo.UnitTests/Cryptography/UT_Murmur32.cs#L18
|
||||
data := []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1}
|
||||
seed := 10
|
||||
expected := make([]byte, 4)
|
||||
binary.LittleEndian.PutUint32(expected, 378574820)
|
||||
require.Equal(t, expected, c.murmur32(ic, []stackitem.Item{stackitem.NewByteArray(data), stackitem.Make(seed)}).Value().([]byte))
|
||||
})
|
||||
}
|
||||
|
||||
func TestCryptoLibVerifyWithECDsa(t *testing.T) {
|
||||
t.Run("R1", func(t *testing.T) {
|
||||
testECDSAVerify(t, Secp256r1)
|
||||
|
|
|
@ -32,6 +32,12 @@ func Ripemd160(b []byte) interop.Hash160 {
|
|||
return neogointernal.CallWithToken(Hash, "ripemd160", int(contract.NoneFlag), b).(interop.Hash160)
|
||||
}
|
||||
|
||||
// Murmur32 calls `murmur32` method of native CryptoLib contract and computes Murmur32 hash of b
|
||||
// using the given seed.
|
||||
func Murmur32(b []byte, seed int) []byte {
|
||||
return neogointernal.CallWithToken(Hash, "murmur32", int(contract.NoneFlag), b, seed).([]byte)
|
||||
}
|
||||
|
||||
// VerifyWithECDsa calls `verifyWithECDsa` method of native CryptoLib contract and checks that sig is
|
||||
// correct msg's signature for a given pub (serialized public key on a given curve).
|
||||
func VerifyWithECDsa(msg []byte, pub interop.PublicKey, sig interop.Signature, curve NamedCurve) bool {
|
||||
|
|
Loading…
Reference in a new issue