Merge pull request #1175 from nspcc-dev/neo3/crypto/ecdsa

crypto: add Secp256k1 support
This commit is contained in:
Roman Khimov 2020-07-15 13:34:42 +03:00 committed by GitHub
commit 75dc62fa81
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
40 changed files with 366 additions and 215 deletions

View file

@ -2,11 +2,11 @@
"version": "3.0",
"accounts": [
{
"address": "NQRLhCpAru9BjGsMwk67vdMwmzKMRgsnnN",
"key": "6PYSxdYbqJQKJcE7L8SUummK4X95aK14KA9obhw3fw6SX3rMRofPzpnr8L",
"address": "NbTiM6h8r99kpRtb428XcsUk1TzKed2gTc",
"key": "6PYN7LvaWqBNw7Xb7a52LSbPnP91kyuzYi3HncGvQwQoYAY2W8DncTgpux",
"label": "",
"contract": {
"script": "DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcILQQqQatQ=",
"script": "DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcILQZVEDXg=",
"parameters": [
{
"name": "parameter0",
@ -19,11 +19,11 @@
"isDefault": false
},
{
"address": "Nbb1qkwcwNSBs9pAnrVVrnFbWnbWBk91U2",
"key": "6PYSxdYbqJQKJcE7L8SUummK4X95aK14KA9obhw3fw6SX3rMRofPzpnr8L",
"address": "NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY",
"key": "6PYN7LvaWqBNw7Xb7a52LSbPnP91kyuzYi3HncGvQwQoYAY2W8DncTgpux",
"label": "",
"contract": {
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBMHOzuw==",
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBE43vrw==",
"parameters": [
{
"name": "parameter0",

View file

@ -2,11 +2,11 @@
"version": "3.0",
"accounts": [
{
"address": "NQRLhCpAru9BjGsMwk67vdMwmzKMRgsnnN",
"key": "6PYSxdYbqJQKJcE7L8SUummK4X95aK14KA9obhw3fw6SX3rMRofPzpnr8L",
"address": "NbTiM6h8r99kpRtb428XcsUk1TzKed2gTc",
"key": "6PYN7LvaWqBNw7Xb7a52LSbPnP91kyuzYi3HncGvQwQoYAY2W8DncTgpux",
"label": "",
"contract": {
"script": "DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcILQQqQatQ=",
"script": "DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcILQZVEDXg=",
"parameters": [
{
"name": "parameter0",
@ -19,11 +19,11 @@
"isDefault": false
},
{
"address": "Nbb1qkwcwNSBs9pAnrVVrnFbWnbWBk91U2",
"key": "6PYSxdYbqJQKJcE7L8SUummK4X95aK14KA9obhw3fw6SX3rMRofPzpnr8L",
"address": "NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY",
"key": "6PYN7LvaWqBNw7Xb7a52LSbPnP91kyuzYi3HncGvQwQoYAY2W8DncTgpux",
"label": "",
"contract": {
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBMHOzuw==",
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBE43vrw==",
"parameters": [
{
"name": "parameter0",
@ -44,11 +44,11 @@
"isDefault": false
},
{
"address": "NYqxsNMHxDg3T19APYP27mBZFfauC4zngR",
"key": "6PYSxdYbqJQKJcE7L8SUummK4X95aK14KA9obhw3fw6SX3rMRofPzpnr8L",
"address": "NVNvVRW5Q5naSx2k2iZm7xRgtRNGuZppAK",
"key": "6PYN7LvaWqBNw7Xb7a52LSbPnP91kyuzYi3HncGvQwQoYAY2W8DncTgpux",
"label": "",
"contract": {
"script": "EQwhArNiK/QBe9/jF8WK7V9MdT8ga324lgRvp9d0u8S/f43CEQtBMHOzuw==",
"script": "EQwhArNiK/QBe9/jF8WK7V9MdT8ga324lgRvp9d0u8S/f43CEQtBE43vrw==",
"parameters": [
{
"name": "parameter0",

View file

@ -2,11 +2,11 @@
"version": "3.0",
"accounts": [
{
"address": "NNsXzAGGVY3H3viPHzaoD6BcVtqNCdMAHZ",
"key": "6PYVQUTQLzdhtdnNLSBkse2DGG5gpPFuNGjaBZxYuJ4XsQrtVNy1E9k7R9",
"address": "NWvKSwutC8D6VKmmPxAEgFKx2NLvFhn8q5",
"key": "6PYKEHagXJ3mDLdga1FoyTGRtPdJgPz6Gb8sjEFwZvRu7ncD9PVZfHtMzL",
"label": "",
"contract": {
"script": "DCECEDp/fdAWVYWX95YNJ8UWpDlP2Wi55lFV60sBPkBAQG4LQQqQatQ=",
"script": "DCECEDp/fdAWVYWX95YNJ8UWpDlP2Wi55lFV60sBPkBAQG4LQZVEDXg=",
"parameters": [
{
"name": "parameter0",
@ -19,11 +19,11 @@
"isDefault": false
},
{
"address": "Nbb1qkwcwNSBs9pAnrVVrnFbWnbWBk91U2",
"key": "6PYVQUTQLzdhtdnNLSBkse2DGG5gpPFuNGjaBZxYuJ4XsQrtVNy1E9k7R9",
"address": "NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY",
"key": "6PYKEHagXJ3mDLdga1FoyTGRtPdJgPz6Gb8sjEFwZvRu7ncD9PVZfHtMzL",
"label": "",
"contract": {
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBMHOzuw==",
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBE43vrw==",
"parameters": [
{
"name": "parameter0",

View file

@ -2,11 +2,11 @@
"version": "3.0",
"accounts": [
{
"address": "Nfzhk6dtjLZE93iGkqYv5pwrTW5QRQk5bV",
"key": "6PYU172i51nsGS1P72gYq4czWdbUvMBQvrJnrJ1VEMZhmXPN6iX4jkmixC",
"address": "NNB3RsnTABEwoKEudNG92njds91WtiCuxd",
"key": "6PYLjn1Zw3RQmP3CkDxoZvYtMpu7ZUdjHnvu7wPuohUcXWCMh9vY661R8A",
"label": "",
"contract": {
"script": "DCED2QwH32PmkM53kS4Qq1GsyUS2aGAje2CMT4+DCece5pkLQQqQatQ=",
"script": "DCED2QwH32PmkM53kS4Qq1GsyUS2aGAje2CMT4+DCece5pkLQZVEDXg=",
"parameters": [
{
"name": "parameter0",
@ -19,11 +19,11 @@
"isDefault": false
},
{
"address": "Nbb1qkwcwNSBs9pAnrVVrnFbWnbWBk91U2",
"key": "6PYU172i51nsGS1P72gYq4czWdbUvMBQvrJnrJ1VEMZhmXPN6iX4jkmixC",
"address": "NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY",
"key": "6PYLjn1Zw3RQmP3CkDxoZvYtMpu7ZUdjHnvu7wPuohUcXWCMh9vY661R8A",
"label": "",
"contract": {
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBMHOzuw==",
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBE43vrw==",
"parameters": [
{
"name": "parameter0",

View file

@ -2,11 +2,11 @@
"version": "3.0",
"accounts": [
{
"address": "NU5BGveyZSQ7TUAxRnKVDXgE9oExpzV5vY",
"key": "6PYW1FxFURLUrFCzLRwoChXHGn77Fy8qDB5j1sUjpbi6mk4J1KgTR8vvAk",
"address": "Nfzo95iBXfeAGx5rdjPedZRAqHKh9hwMdR",
"key": "6PYLbYYg9jUgzJQpKhpvNExa2UEgtp4356XPg56pHuCpE7gQmj84ESNjYW",
"label": "",
"contract": {
"script": "DCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWILQQqQatQ=",
"script": "DCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWILQZVEDXg=",
"parameters": [
{
"name": "parameter0",
@ -19,11 +19,11 @@
"isDefault": false
},
{
"address": "Nbb1qkwcwNSBs9pAnrVVrnFbWnbWBk91U2",
"key": "6PYW1FxFURLUrFCzLRwoChXHGn77Fy8qDB5j1sUjpbi6mk4J1KgTR8vvAk",
"address": "NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY",
"key": "6PYLbYYg9jUgzJQpKhpvNExa2UEgtp4356XPg56pHuCpE7gQmj84ESNjYW",
"label": "",
"contract": {
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBMHOzuw==",
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBE43vrw==",
"parameters": [
{
"name": "parameter0",

1
go.mod
View file

@ -3,6 +3,7 @@ module github.com/nspcc-dev/neo-go
require (
github.com/Workiva/go-datastructures v1.0.50
github.com/alicebob/miniredis v2.5.0+incompatible
github.com/btcsuite/btcd v0.20.1-beta
github.com/dgraph-io/badger/v2 v2.0.3
github.com/frankban/quicktest v1.10.0 // indirect
github.com/go-redis/redis v6.10.2+incompatible

28
go.sum
View file

@ -13,6 +13,8 @@ github.com/abiosoft/ishell v2.0.0+incompatible h1:zpwIuEHc37EzrsIYah3cpevrIc8Oma
github.com/abiosoft/ishell v2.0.0+incompatible/go.mod h1:HQR9AqF2R3P4XXpMpI0NAzgHf/aS6+zVXRj14cVk9qg=
github.com/abiosoft/readline v0.0.0-20180607040430-155bce2042db h1:CjPUSXOiYptLbTdr1RceuZgSFDQ7U15ITERUGrUORx8=
github.com/abiosoft/readline v0.0.0-20180607040430-155bce2042db/go.mod h1:rB3B4rKii8V21ydCbIzH5hZiCQE7f5E9SzUb/ZZx530=
github.com/aead/siphash v1.0.1 h1:FwHfE/T45KPKYuuSAKyyvE+oPWcaQ+CUmFW0bPlM+kg=
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
@ -28,6 +30,22 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw=
github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f h1:bAs4lUbRJpnnkd9VhRV3jjAVU7DJVjMaK+IsvSeZvFo=
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d h1:yJzD/yFppdVCf6ApMkVy8cUxV0XrxdP9rVf6D87/Mng=
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd h1:R/opQEbFEy9JGkIguV40SvRY1uliPX8ifOvi6ICsFCw=
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg=
github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd h1:qdGvebPBDuYDPGi1WCPjy1tGyMpmDK8IEapSsszn7HE=
github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY=
github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723 h1:ZA/jbKoGcVAnER6pCHPEkGdZOV7U1oLUedErBHCUMs0=
github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792 h1:R8vQdOQdZ9Y3SkEwmHoWBmX1DNXhXZqlTpq6s4tyJGc=
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY=
github.com/btcsuite/winsvc v1.0.0 h1:J9B4L7e3oqhXOcm+2IuNApwzQec85lE+QaikUcCs+dk=
github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.0 h1:yTUvW7Vhb89inJ+8irsUqiWjh8iT6sQPZiQzI6ReGkA=
@ -41,6 +59,7 @@ github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@ -95,9 +114,15 @@ github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89 h1:12K8AlpT0/6QUXSfV0yi4Q0jkbq8NDtIKFtF61AoqV0=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jrick/logrotate v1.0.0 h1:lQ1bL/n9mBNeIXoTUoYRlK4dHuNJVofX9oWqBtPnSzI=
github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23 h1:FOOIBWrEkLgmlgGfMuZT83xIwfPDxEI2OHu6xUmJMFE=
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
@ -150,10 +175,12 @@ github.com/nspcc-dev/rfc6979 v0.2.0 h1:3e1WNxrN60/6N0DW7+UYisLeZJyfqZTNOjeV/toYv
github.com/nspcc-dev/rfc6979 v0.2.0/go.mod h1:exhIh1PdpDC5vQmyEsGvc4YDM/lyQp/452QxGq/UEso=
github.com/onsi/ginkgo v1.6.0 h1:Ix8l273rp3QzYgXSR+c8d1fTG7UPgYkOSELPhiY/YGw=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.10.3 h1:OoxbjfXVZyod1fmWYhI7SEyaD8B00ynP3T+D5GiyHOY=
github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v1.4.2 h1:3mYCb7aPxS/RU7TI1y4rkEn1oKmPRjNJLNEXgw7MH2I=
github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.1 h1:K0jcRCwNQM3vFGh1ppMtDh/+7ApJrjldlX8fA0jDTLQ=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
@ -220,6 +247,7 @@ go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=

View file

@ -6,7 +6,10 @@ var syscalls = map[string]map[string]string{
"Deserialize": "System.Binary.Deserialize",
},
"crypto": {
"ECDsaVerify": "Neo.Crypto.ECDsaVerify",
"ECDsaSecp256r1Verify": "Neo.Crypto.VerifyWithECDsaSecp256r1",
"ECDsaSecp256k1Verify": "Neo.Crypto.VerifyWithECDsaSecp256k1",
"ECDSASecp256r1CheckMultisig": "Neo.Crypto.CheckMultisigWithECDsaSecp256r1",
"ECDSASecp256k1CheckMultisig": "Neo.Crypto.CheckMultisigWithECDsaSecp256k1",
},
"enumerator": {
"Concat": "System.Enumerator.Concat",

View file

@ -19,7 +19,7 @@ func TestVerifyGood(t *testing.T) {
src := getVerifyProg(pub, sig, msg)
v, p := vmAndCompileInterop(t, src)
p.interops[emit.InteropNameToID([]byte("Neo.Crypto.ECDsaVerify"))] = func(v *vm.VM) error {
p.interops[emit.InteropNameToID([]byte("Neo.Crypto.VerifyWithECDsaSecp256r1"))] = func(v *vm.VM) error {
assert.Equal(t, msg, v.Estack().Pop().Bytes())
assert.Equal(t, pub, v.Estack().Pop().Bytes())
assert.Equal(t, sig, v.Estack().Pop().Bytes())
@ -54,7 +54,7 @@ func getVerifyProg(pub, sig, msg []byte) string {
pub := ` + pubS + `
sig := ` + sigS + `
msg := ` + msgS + `
return crypto.ECDsaVerify(msg, pub, sig)
return crypto.ECDsaSecp256r1Verify(msg, pub, sig)
}
`
}

View file

@ -1,7 +1,6 @@
package consensus
import (
"encoding/hex"
"math/rand"
"testing"
@ -75,6 +74,7 @@ func TestConsensusPayload_Setters(t *testing.T) {
require.Equal(t, pl, p.GetRecoveryMessage())
}
/*// TODO: update binary (see https://github.com/nspcc-dev/neo-go/issues/1178)
func TestConsensusPayload_Verify(t *testing.T) {
// signed payload from testnet
dataHex := "00000000a70b769e4af60878f6daa72be41770c62592c694bf9ead6b16b30ad90f28c4098cc704000400423000d5b4baae11191ac370a4d7860df01824fcea7f934d6461db6d4b7966ca3c135c8c262b7f23bbac13e73885223604141e062234d999068d9a74b77caeeb5271cf01420c4055ae8c7694c296e92da393f944b0dc1cd70d12de3ee944e9afc872d1db427fe87fcbe913709a8ec73e2f5acdfc0b7f0a96e9d63bad0a20e3226c882237f5c771290c2102a7834be9b32e2981d157cb5bbd3acb42cfd11ea5c3b10224d7a44e98c5910f1b0b410a906ad4"
@ -89,7 +89,7 @@ func TestConsensusPayload_Verify(t *testing.T) {
require.NoError(t, p.decodeData())
require.True(t, p.Verify(h))
}
*/
func TestConsensusPayload_Serializable(t *testing.T) {
for _, mt := range messageTypes {
p := randomPayload(t, mt)

View file

@ -2,11 +2,11 @@
"version": "3.0",
"accounts": [
{
"address": "NQRLhCpAru9BjGsMwk67vdMwmzKMRgsnnN",
"key": "6PYSxdYbqJQKJcE7L8SUummK4X95aK14KA9obhw3fw6SX3rMRofPzpnr8L",
"address": "NbTiM6h8r99kpRtb428XcsUk1TzKed2gTc",
"key": "6PYN7LvaWqBNw7Xb7a52LSbPnP91kyuzYi3HncGvQwQoYAY2W8DncTgpux",
"label": "",
"contract": {
"script": "DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcILQQqQatQ=",
"script": "DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcILQZVEDXg=",
"parameters": [
{
"name": "parameter0",
@ -19,11 +19,11 @@
"isDefault": false
},
{
"address": "Nbb1qkwcwNSBs9pAnrVVrnFbWnbWBk91U2",
"key": "6PYSxdYbqJQKJcE7L8SUummK4X95aK14KA9obhw3fw6SX3rMRofPzpnr8L",
"address": "NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY",
"key": "6PYN7LvaWqBNw7Xb7a52LSbPnP91kyuzYi3HncGvQwQoYAY2W8DncTgpux",
"label": "",
"contract": {
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBMHOzuw==",
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBE43vrw==",
"parameters": [
{
"name": "parameter0",

View file

@ -2,11 +2,11 @@
"version": "3.0",
"accounts": [
{
"address": "NNsXzAGGVY3H3viPHzaoD6BcVtqNCdMAHZ",
"key": "6PYVQUTQLzdhtdnNLSBkse2DGG5gpPFuNGjaBZxYuJ4XsQrtVNy1E9k7R9",
"address": "NWvKSwutC8D6VKmmPxAEgFKx2NLvFhn8q5",
"key": "6PYKEHagXJ3mDLdga1FoyTGRtPdJgPz6Gb8sjEFwZvRu7ncD9PVZfHtMzL",
"label": "",
"contract": {
"script": "DCECEDp/fdAWVYWX95YNJ8UWpDlP2Wi55lFV60sBPkBAQG4LQQqQatQ=",
"script": "DCECEDp/fdAWVYWX95YNJ8UWpDlP2Wi55lFV60sBPkBAQG4LQZVEDXg=",
"parameters": [
{
"name": "parameter0",
@ -19,11 +19,11 @@
"isDefault": false
},
{
"address": "Nbb1qkwcwNSBs9pAnrVVrnFbWnbWBk91U2",
"key": "6PYVQUTQLzdhtdnNLSBkse2DGG5gpPFuNGjaBZxYuJ4XsQrtVNy1E9k7R9",
"address": "NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY",
"key": "6PYKEHagXJ3mDLdga1FoyTGRtPdJgPz6Gb8sjEFwZvRu7ncD9PVZfHtMzL",
"label": "",
"contract": {
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBMHOzuw==",
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBE43vrw==",
"parameters": [
{
"name": "parameter0",

View file

@ -2,11 +2,11 @@
"version": "3.0",
"accounts": [
{
"address": "Nfzhk6dtjLZE93iGkqYv5pwrTW5QRQk5bV",
"key": "6PYU172i51nsGS1P72gYq4czWdbUvMBQvrJnrJ1VEMZhmXPN6iX4jkmixC",
"address": "NNB3RsnTABEwoKEudNG92njds91WtiCuxd",
"key": "6PYLjn1Zw3RQmP3CkDxoZvYtMpu7ZUdjHnvu7wPuohUcXWCMh9vY661R8A",
"label": "",
"contract": {
"script": "DCED2QwH32PmkM53kS4Qq1GsyUS2aGAje2CMT4+DCece5pkLQQqQatQ=",
"script": "DCED2QwH32PmkM53kS4Qq1GsyUS2aGAje2CMT4+DCece5pkLQZVEDXg=",
"parameters": [
{
"name": "parameter0",
@ -19,11 +19,11 @@
"isDefault": false
},
{
"address": "Nbb1qkwcwNSBs9pAnrVVrnFbWnbWBk91U2",
"key": "6PYU172i51nsGS1P72gYq4czWdbUvMBQvrJnrJ1VEMZhmXPN6iX4jkmixC",
"address": "NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY",
"key": "6PYLjn1Zw3RQmP3CkDxoZvYtMpu7ZUdjHnvu7wPuohUcXWCMh9vY661R8A",
"label": "",
"contract": {
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBMHOzuw==",
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBE43vrw==",
"parameters": [
{
"name": "parameter0",

View file

@ -2,11 +2,11 @@
"version": "3.0",
"accounts": [
{
"address": "NU5BGveyZSQ7TUAxRnKVDXgE9oExpzV5vY",
"key": "6PYW1FxFURLUrFCzLRwoChXHGn77Fy8qDB5j1sUjpbi6mk4J1KgTR8vvAk",
"address": "Nfzo95iBXfeAGx5rdjPedZRAqHKh9hwMdR",
"key": "6PYLbYYg9jUgzJQpKhpvNExa2UEgtp4356XPg56pHuCpE7gQmj84ESNjYW",
"label": "",
"contract": {
"script": "DCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWILQQqQatQ=",
"script": "DCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWILQZVEDXg=",
"parameters": [
{
"name": "parameter0",
@ -19,11 +19,11 @@
"isDefault": false
},
{
"address": "Nbb1qkwcwNSBs9pAnrVVrnFbWnbWBk91U2",
"key": "6PYW1FxFURLUrFCzLRwoChXHGn77Fy8qDB5j1sUjpbi6mk4J1KgTR8vvAk",
"address": "NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY",
"key": "6PYLbYYg9jUgzJQpKhpvNExa2UEgtp4356XPg56pHuCpE7gQmj84ESNjYW",
"label": "",
"contract": {
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBMHOzuw==",
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBE43vrw==",
"parameters": [
{
"name": "parameter0",

View file

@ -1,9 +1,11 @@
package crypto
import (
"crypto/elliptic"
"errors"
"fmt"
"github.com/btcsuite/btcd/btcec"
"github.com/nspcc-dev/neo-go/pkg/core/interop"
"github.com/nspcc-dev/neo-go/pkg/crypto"
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
@ -15,13 +17,24 @@ import (
// ECDSAVerifyPrice is a gas price of a single verification.
const ECDSAVerifyPrice = 1000000
// ECDSAVerify checks ECDSA signature.
func ECDSAVerify(ic *interop.Context, v *vm.VM) error {
// ECDSASecp256r1Verify checks ECDSA signature using Secp256r1 elliptic curve.
func ECDSASecp256r1Verify(ic *interop.Context, v *vm.VM) error {
return ecdsaVerify(ic, v, elliptic.P256())
}
// ECDSASecp256k1Verify checks ECDSA signature using Secp256k1 elliptic curve
func ECDSASecp256k1Verify(ic *interop.Context, v *vm.VM) error {
return ecdsaVerify(ic, v, btcec.S256())
}
// ecdsaVerify is internal representation of ECDSASecp256k1Verify and
// ECDSASecp256r1Verify.
func ecdsaVerify(ic *interop.Context, v *vm.VM, curve elliptic.Curve) error {
msg := getMessage(ic, v.Estack().Pop().Item())
hashToCheck := hash.Sha256(msg).BytesBE()
keyb := v.Estack().Pop().Bytes()
signature := v.Estack().Pop().Bytes()
pkey, err := keys.NewPublicKeyFromBytes(keyb)
pkey, err := keys.NewPublicKeyFromBytes(keyb, curve)
if err != nil {
return err
}
@ -30,8 +43,21 @@ func ECDSAVerify(ic *interop.Context, v *vm.VM) error {
return nil
}
// ECDSACheckMultisig checks multiple ECDSA signatures at once.
func ECDSACheckMultisig(ic *interop.Context, v *vm.VM) error {
// ECDSASecp256r1CheckMultisig checks multiple ECDSA signatures at once using
// Secp256r1 elliptic curve.
func ECDSASecp256r1CheckMultisig(ic *interop.Context, v *vm.VM) error {
return ecdsaCheckMultisig(ic, v, elliptic.P256())
}
// ECDSASecp256k1CheckMultisig checks multiple ECDSA signatures at once using
// Secp256k1 elliptic curve.
func ECDSASecp256k1CheckMultisig(ic *interop.Context, v *vm.VM) error {
return ecdsaCheckMultisig(ic, v, btcec.S256())
}
// ecdsaCheckMultisig is internal representation of ECDSASecp256r1CheckMultisig and
// ECDSASecp256k1CheckMultisig
func ecdsaCheckMultisig(ic *interop.Context, v *vm.VM, curve elliptic.Curve) error {
msg := getMessage(ic, v.Estack().Pop().Item())
hashToCheck := hash.Sha256(msg).BytesBE()
pkeys, err := v.Estack().PopSigElements()
@ -50,7 +76,7 @@ func ECDSACheckMultisig(ic *interop.Context, v *vm.VM) error {
if len(pkeys) < len(sigs) {
return errors.New("more signatures than there are keys")
}
sigok := vm.CheckMultisigPar(v, hashToCheck, pkeys, sigs)
sigok := vm.CheckMultisigPar(v, curve, hashToCheck, pkeys, sigs)
v.Estack().PushVal(sigok)
return nil
}

View file

@ -57,7 +57,7 @@ func subSlice(arr []stackitem.Item, indices []int) []stackitem.Item {
func initCHECKMULTISIGVM(t *testing.T, n int, ik, is []int) *vm.VM {
buf := make([]byte, 5)
buf[0] = byte(opcode.SYSCALL)
binary.LittleEndian.PutUint32(buf[1:], ecdsaCheckMultisigID)
binary.LittleEndian.PutUint32(buf[1:], ecdsaSecp256r1CheckMultisigID)
v := vm.New()
v.GasLimit = -1

View file

@ -7,25 +7,25 @@ import (
)
var (
ecdsaVerifyID = emit.InteropNameToID([]byte("Neo.Crypto.ECDsaVerify"))
ecdsaCheckMultisigID = emit.InteropNameToID([]byte("Neo.Crypto.ECDsaCheckMultiSig"))
sha256ID = emit.InteropNameToID([]byte("Neo.Crypto.SHA256"))
ecdsaSecp256r1VerifyID = emit.InteropNameToID([]byte("Neo.Crypto.VerifyWithECDsaSecp256r1"))
ecdsaSecp256r1CheckMultisigID = emit.InteropNameToID([]byte("Neo.Crypto.CheckMultisigWithECDsaSecp256r1"))
sha256ID = emit.InteropNameToID([]byte("Neo.Crypto.SHA256"))
)
// GetInterop returns interop getter for crypto-related stuff.
func GetInterop(ic *interop.Context) func(uint32) *vm.InteropFuncPrice {
return func(id uint32) *vm.InteropFuncPrice {
switch id {
case ecdsaVerifyID:
case ecdsaSecp256r1VerifyID:
return &vm.InteropFuncPrice{
Func: func(v *vm.VM) error {
return ECDSAVerify(ic, v)
return ECDSASecp256r1Verify(ic, v)
},
}
case ecdsaCheckMultisigID:
case ecdsaSecp256r1CheckMultisigID:
return &vm.InteropFuncPrice{
Func: func(v *vm.VM) error {
return ECDSACheckMultisig(ic, v)
return ECDSASecp256r1CheckMultisig(ic, v)
},
}
case sha256ID:

View file

@ -1,6 +1,8 @@
package runtime
import (
"crypto/elliptic"
"github.com/nspcc-dev/neo-go/pkg/core/dao"
"github.com/nspcc-dev/neo-go/pkg/core/interop"
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
@ -90,7 +92,7 @@ func CheckWitness(ic *interop.Context, v *vm.VM) error {
hash, err := util.Uint160DecodeBytesBE(hashOrKey)
if err != nil {
var key *keys.PublicKey
key, err = keys.NewPublicKeyFromBytes(hashOrKey)
key, err = keys.NewPublicKeyFromBytes(hashOrKey, elliptic.P256())
if err != nil {
return errors.New("parameter given is neither a key nor a hash")
}

View file

@ -159,7 +159,7 @@ func TestECDSAVerify(t *testing.T) {
err = fmt.Errorf("panic: %v", r)
}
}()
err = crypto.ECDSAVerify(ic, v)
err = crypto.ECDSASecp256r1Verify(ic, v)
}()
if isErr {

View file

@ -1,6 +1,7 @@
package core
import (
"crypto/elliptic"
"errors"
"fmt"
"math"
@ -492,7 +493,7 @@ func contractIsStandard(ic *interop.Context, v *vm.VM) error {
// contractCreateStandardAccount calculates contract scripthash for a given public key.
func contractCreateStandardAccount(ic *interop.Context, v *vm.VM) error {
h := v.Estack().Pop().Bytes()
p, err := keys.NewPublicKeyFromBytes(h)
p, err := keys.NewPublicKeyFromBytes(h, elliptic.P256())
if err != nil {
return err
}

View file

@ -138,8 +138,10 @@ var systemInterops = []interop.Function{
}
var neoInterops = []interop.Function{
{Name: "Neo.Crypto.ECDsaVerify", Func: crypto.ECDSAVerify, Price: crypto.ECDSAVerifyPrice},
{Name: "Neo.Crypto.ECDsaCheckMultiSig", Func: crypto.ECDSACheckMultisig, Price: 0},
{Name: "Neo.Crypto.VerifyWithECDsaSecp256r1", Func: crypto.ECDSASecp256r1Verify, Price: crypto.ECDSAVerifyPrice},
{Name: "Neo.Crypto.VerifyWithECDsaSecp256k1", Func: crypto.ECDSASecp256k1Verify, Price: crypto.ECDSAVerifyPrice},
{Name: "Neo.Crypto.CheckMultisigWithECDsaSecp256r1", Func: crypto.ECDSASecp256r1CheckMultisig, Price: 0},
{Name: "Neo.Crypto.CheckMultisigWithECDsaSecp256k1", Func: crypto.ECDSASecp256k1CheckMultisig, Price: 0},
{Name: "Neo.Crypto.SHA256", Func: crypto.Sha256, Price: 1000000},
{Name: "Neo.Native.Deploy", Func: native.Deploy, Price: 0,
AllowedTriggers: trigger.Application, RequiredFlags: smartcontract.AllowModifyStates},

View file

@ -1,6 +1,7 @@
package native
import (
"crypto/elliptic"
"math/big"
"sort"
"strings"
@ -361,7 +362,7 @@ func (n *NEO) GetRegisteredValidators(d dao.DAO) ([]state.Validator, error) {
}
arr := make([]state.Validator, len(kvs))
for i := range kvs {
arr[i].Key, err = keys.NewPublicKeyFromBytes([]byte(kvs[i].Key))
arr[i].Key, err = keys.NewPublicKeyFromBytes([]byte(kvs[i].Key), elliptic.P256())
if err != nil {
return nil, err
}

View file

@ -21,14 +21,14 @@ func TestGenesisBlockMainNet(t *testing.T) {
// have been changed. Consequently, hash of the genesis block has been changed.
// Update expected genesis block hash for better times.
// Old hash is "d42561e3d30e15be6400b6df2f328e02d2bf6354c41dce433bc57687c82144bf"
expect := "dba446947a90b2862ef050703b44828ad8b02d11978f8ef59bd3e1c97aabf6e5"
expect := "94e61af2441145cc251752707a58107850328a48bb095fd175ca2f8513ab5676"
assert.Equal(t, expect, block.Hash().StringLE())
}
func TestGetConsensusAddressMainNet(t *testing.T) {
var (
consensusAddr = "NWNnqYniJyFh1qx5KyBeTV4uq5ewvNrAuD"
consensusScript = "72c3d9b3bbf776698694cd2c73fa597a10c31294"
consensusAddr = "NiVihDFvZacZhujTWkBhRz32UDuNRp416f"
consensusScript = "f7b4d00143932f3b6243cfc06cb4a68f22c739e2"
)
cfg, err := config.Load("../../config", netmode.MainNet)

View file

@ -14,21 +14,31 @@ import (
"github.com/nspcc-dev/rfc6979"
)
// PrivateKey represents a NEO private key.
// PrivateKey represents a NEO private key and provides a high level API around
// ecdsa.PrivateKey.
type PrivateKey struct {
b []byte
ecdsa.PrivateKey
}
// NewPrivateKey creates a new random private key.
// NewPrivateKey creates a new random Secp256k1 private key.
func NewPrivateKey() (*PrivateKey, error) {
priv, _, _, err := elliptic.GenerateKey(elliptic.P256(), rand.Reader)
priv, x, y, err := elliptic.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
return nil, err
}
return &PrivateKey{b: priv}, nil
return &PrivateKey{
ecdsa.PrivateKey{
PublicKey: ecdsa.PublicKey{
Curve: elliptic.P256(),
X: x,
Y: y,
},
D: new(big.Int).SetBytes(priv),
},
}, nil
}
// NewPrivateKeyFromHex returns a PrivateKey created from the
// NewPrivateKeyFromHex returns a Secp256k1 PrivateKey created from the
// given hex string.
func NewPrivateKeyFromHex(str string) (*PrivateKey, error) {
b, err := hex.DecodeString(str)
@ -38,17 +48,35 @@ func NewPrivateKeyFromHex(str string) (*PrivateKey, error) {
return NewPrivateKeyFromBytes(b)
}
// NewPrivateKeyFromBytes returns a NEO PrivateKey from the given byte slice.
// NewPrivateKeyFromBytes returns a NEO Secp256r1 PrivateKey from the given
// byte slice.
func NewPrivateKeyFromBytes(b []byte) (*PrivateKey, error) {
if len(b) != 32 {
return nil, fmt.Errorf(
"invalid byte length: expected %d bytes got %d", 32, len(b),
)
}
return &PrivateKey{b}, nil
var (
c = elliptic.P256()
d = new(big.Int).SetBytes(b)
)
x, y := c.ScalarBaseMult(d.Bytes())
return &PrivateKey{
ecdsa.PrivateKey{
PublicKey: ecdsa.PublicKey{
Curve: c,
X: x,
Y: y,
},
D: d,
},
}, nil
}
// NewPrivateKeyFromASN1 returns a NEO PrivateKey from the ASN.1 serialized key.
// NewPrivateKeyFromASN1 returns a NEO Secp256k1 PrivateKey from the ASN.1
// serialized key.
func NewPrivateKeyFromASN1(b []byte) (*PrivateKey, error) {
privkey, err := x509.ParseECPrivateKey(b)
if err != nil {
@ -59,14 +87,8 @@ func NewPrivateKeyFromASN1(b []byte) (*PrivateKey, error) {
// PublicKey derives the public key from the private key.
func (p *PrivateKey) PublicKey() *PublicKey {
var (
c = elliptic.P256()
q = new(big.Int).SetBytes(p.b)
)
x, y := c.ScalarBaseMult(q.Bytes())
return &PublicKey{X: x, Y: y}
result := PublicKey(p.PrivateKey.PublicKey)
return &result
}
// NewPrivateKeyFromWIF returns a NEO PrivateKey from the given
@ -83,7 +105,7 @@ func NewPrivateKeyFromWIF(wif string) (*PrivateKey, error) {
// Good documentation about this process can be found here:
// https://en.bitcoin.it/wiki/Wallet_import_format
func (p *PrivateKey) WIF() string {
w, err := WIFEncode(p.b, WIFVersion, true)
w, err := WIFEncode(p.Bytes(), WIFVersion, true)
// The only way WIFEncode() can fail is if we're to give it a key of
// wrong size, but we have a proper key here, aren't we?
if err != nil {
@ -109,7 +131,7 @@ func (p *PrivateKey) GetScriptHash() util.Uint160 {
// Sign signs arbitrary length data using the private key.
func (p *PrivateKey) Sign(data []byte) []byte {
var (
privateKey = p.ecdsa()
privateKey = &p.PrivateKey
digest = sha256.Sum256(data)
)
@ -125,21 +147,16 @@ func (p *PrivateKey) Sign(data []byte) []byte {
return signature
}
// ecsda converts the key to a usable ecsda.PrivateKey for signing data.
func (p *PrivateKey) ecdsa() *ecdsa.PrivateKey {
priv := new(ecdsa.PrivateKey)
priv.PublicKey.Curve = elliptic.P256()
priv.D = new(big.Int).SetBytes(p.b)
priv.PublicKey.X, priv.PublicKey.Y = priv.PublicKey.Curve.ScalarBaseMult(p.b)
return priv
}
// String implements the stringer interface.
func (p *PrivateKey) String() string {
return hex.EncodeToString(p.b)
return hex.EncodeToString(p.Bytes())
}
// Bytes returns the underlying bytes of the PrivateKey.
func (p *PrivateKey) Bytes() []byte {
return p.b
bytes := p.D.Bytes()
result := make([]byte, 32)
copy(result[32-len(bytes):], bytes)
return result
}

View file

@ -9,6 +9,7 @@ import (
"fmt"
"math/big"
"github.com/btcsuite/btcd/btcec"
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
"github.com/nspcc-dev/neo-go/pkg/io"
@ -76,11 +77,8 @@ func (keys PublicKeys) Unique() PublicKeys {
}
// PublicKey represents a public key and provides a high level
// API around the X/Y point.
type PublicKey struct {
X *big.Int
Y *big.Int
}
// API around ecdsa.PublicKey.
type PublicKey ecdsa.PublicKey
// Equal returns true in case public keys are equal.
func (p *PublicKey) Equal(key *PublicKey) bool {
@ -103,12 +101,13 @@ func NewPublicKeyFromString(s string) (*PublicKey, error) {
if err != nil {
return nil, err
}
return NewPublicKeyFromBytes(b)
return NewPublicKeyFromBytes(b, elliptic.P256())
}
// NewPublicKeyFromBytes returns public key created from b.
func NewPublicKeyFromBytes(b []byte) (*PublicKey, error) {
// NewPublicKeyFromBytes returns public key created from b using given EC.
func NewPublicKeyFromBytes(b []byte, curve elliptic.Curve) (*PublicKey, error) {
pubKey := new(PublicKey)
pubKey.Curve = curve
if err := pubKey.DecodeBytes(b); err != nil {
return nil, err
}
@ -173,23 +172,30 @@ func NewPublicKeyFromASN1(data []byte) (*PublicKey, error) {
if !ok {
return nil, errors.New("given bytes aren't ECDSA public key")
}
key := PublicKey{
X: pk.X,
Y: pk.Y,
}
return &key, nil
result := PublicKey(*pk)
return &result, nil
}
// decodeCompressedY performs decompression of Y coordinate for given X and Y's least significant bit.
func decodeCompressedY(x *big.Int, ylsb uint) (*big.Int, error) {
c := elliptic.P256()
cp := c.Params()
three := big.NewInt(3)
/* y**2 = x**3 + a*x + b % p */
xCubed := new(big.Int).Exp(x, three, cp.P)
threeX := new(big.Int).Mul(x, three)
threeX.Mod(threeX, cp.P)
ySquared := new(big.Int).Sub(xCubed, threeX)
// We use here a short-form Weierstrass curve (https://www.hyperelliptic.org/EFD/g1p/auto-shortw.html)
// y² = x³ + ax + b. Two types of elliptic curves are supported:
// 1. Secp256k1 (Koblitz curve): y² = x³ + b,
// 2. Secp256r1 (Random curve): y² = x³ - 3x + b.
// To decode compressed curve point we perform the following operation: y = sqrt(x³ + ax + b mod p)
// where `p` denotes the order of the underlying curve field
func decodeCompressedY(x *big.Int, ylsb uint, curve elliptic.Curve) (*big.Int, error) {
var a *big.Int
switch curve.(type) {
case *btcec.KoblitzCurve:
a = big.NewInt(0)
default:
a = big.NewInt(3)
}
cp := curve.Params()
xCubed := new(big.Int).Exp(x, big.NewInt(3), cp.P)
aX := new(big.Int).Mul(x, a)
aX.Mod(aX, cp.P)
ySquared := new(big.Int).Sub(xCubed, aX)
ySquared.Add(ySquared, cp.B)
ySquared.Mod(ySquared, cp.P)
y := new(big.Int).ModSqrt(ySquared, cp.P)
@ -210,7 +216,8 @@ func (p *PublicKey) DecodeBytes(data []byte) error {
return b.Err
}
// DecodeBinary decodes a PublicKey from the given BinReader.
// DecodeBinary decodes a PublicKey from the given BinReader using information
// about the EC curve to decompress Y point. Secp256r1 is a default value for EC curve.
func (p *PublicKey) DecodeBinary(r *io.BinReader) {
var prefix uint8
var x, y *big.Int
@ -221,8 +228,11 @@ func (p *PublicKey) DecodeBinary(r *io.BinReader) {
return
}
p256 := elliptic.P256()
p256Params := p256.Params()
if p.Curve == nil {
p.Curve = elliptic.P256()
}
curve := p.Curve
curveParams := p.Params()
// Infinity
switch prefix {
case 0x00:
@ -237,7 +247,7 @@ func (p *PublicKey) DecodeBinary(r *io.BinReader) {
}
x = new(big.Int).SetBytes(xbytes)
ylsb := uint(prefix & 0x1)
y, err = decodeCompressedY(x, ylsb)
y, err = decodeCompressedY(x, ylsb, curve)
if err != nil {
r.Err = err
return
@ -252,7 +262,7 @@ func (p *PublicKey) DecodeBinary(r *io.BinReader) {
}
x = new(big.Int).SetBytes(xbytes)
y = new(big.Int).SetBytes(ybytes)
if !p256.IsOnCurve(x, y) {
if !curve.IsOnCurve(x, y) {
r.Err = errors.New("encoded point is not on the P256 curve")
return
}
@ -260,7 +270,7 @@ func (p *PublicKey) DecodeBinary(r *io.BinReader) {
r.Err = errors.Errorf("invalid prefix %d", prefix)
return
}
if x.Cmp(p256Params.P) >= 0 || y.Cmp(p256Params.P) >= 0 {
if x.Cmp(curveParams.P) >= 0 || y.Cmp(curveParams.P) >= 0 {
r.Err = errors.New("enccoded point is not correct (X or Y is bigger than P")
return
}
@ -285,7 +295,7 @@ func (p *PublicKey) GetVerificationScript() []byte {
}
emit.Bytes(buf.BinWriter, b)
emit.Opcode(buf.BinWriter, opcode.PUSHNULL)
emit.Syscall(buf.BinWriter, "Neo.Crypto.ECDsaVerify")
emit.Syscall(buf.BinWriter, "Neo.Crypto.VerifyWithECDsaSecp256r1")
return buf.Bytes()
}
@ -303,17 +313,13 @@ func (p *PublicKey) Address() string {
// Verify returns true if the signature is valid and corresponds
// to the hash and public key.
func (p *PublicKey) Verify(signature []byte, hash []byte) bool {
publicKey := &ecdsa.PublicKey{}
publicKey.Curve = elliptic.P256()
publicKey.X = p.X
publicKey.Y = p.Y
if p.X == nil || p.Y == nil {
return false
}
rBytes := new(big.Int).SetBytes(signature[0:32])
sBytes := new(big.Int).SetBytes(signature[32:64])
return ecdsa.Verify(publicKey, hash, rBytes, sBytes)
pk := ecdsa.PublicKey(*p)
return ecdsa.Verify(&pk, hash, rBytes, sBytes)
}
// IsInfinity checks if the key is infinite (null, basically).

View file

@ -1,6 +1,7 @@
package keys
import (
"crypto/elliptic"
"encoding/hex"
"encoding/json"
"math/rand"
@ -59,7 +60,7 @@ func TestNewPublicKeyFromBytes(t *testing.T) {
require.NoError(t, err)
b := priv.PublicKey().Bytes()
pub, err := NewPublicKeyFromBytes(b)
pub, err := NewPublicKeyFromBytes(b, elliptic.P256())
require.NoError(t, err)
require.Equal(t, priv.PublicKey(), pub)
}
@ -106,7 +107,7 @@ func TestPubkeyToAddress(t *testing.T) {
pubKey, err := NewPublicKeyFromString("031ee4e73a17d8f76dc02532e2620bcb12425b33c0c9f9694cc2caa8226b68cad4")
require.NoError(t, err)
actual := pubKey.Address()
expected := "NNqoUeNb2tfhEExY7mrPbxf4EZZRKX5nHF"
expected := "NcKJdJTEDeCSV9BJAKWWxkBMcHTeVnSzJo"
require.Equal(t, expected, actual)
}

View file

@ -1,38 +1,81 @@
package keys
import (
"crypto/ecdsa"
"testing"
"github.com/btcsuite/btcd/btcec"
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestPubKeyVerify(t *testing.T) {
var data = []byte("sample")
hashedData := hash.Sha256(data)
privKey, err := NewPrivateKey()
assert.Nil(t, err)
signedData := privKey.Sign(data)
pubKey := privKey.PublicKey()
result := pubKey.Verify(signedData, hashedData.BytesBE())
expected := true
assert.Equal(t, expected, result)
t.Run("Secp256r1", func(t *testing.T) {
privKey, err := NewPrivateKey()
assert.Nil(t, err)
signedData := privKey.Sign(data)
pubKey := privKey.PublicKey()
result := pubKey.Verify(signedData, hashedData.BytesBE())
expected := true
assert.Equal(t, expected, result)
pubKey = &PublicKey{}
assert.False(t, pubKey.Verify(signedData, hashedData.BytesBE()))
pubKey = &PublicKey{}
assert.False(t, pubKey.Verify(signedData, hashedData.BytesBE()))
})
t.Run("Secp256k1", func(t *testing.T) {
privateKey, err := btcec.NewPrivateKey(btcec.S256())
assert.Nil(t, err)
signature, err := privateKey.Sign(hashedData.BytesBE())
require.NoError(t, err)
signedData := append(signature.R.Bytes(), signature.S.Bytes()...)
pubKey := PublicKey(ecdsa.PublicKey{
Curve: btcec.S256(),
X: privateKey.X,
Y: privateKey.Y,
})
require.True(t, pubKey.Verify(signedData, hashedData.BytesBE()))
pubKey = PublicKey{}
assert.False(t, pubKey.Verify(signedData, hashedData.BytesBE()))
})
}
func TestWrongPubKey(t *testing.T) {
privKey, _ := NewPrivateKey()
sample := []byte("sample")
hashedData := hash.Sha256(sample)
signedData := privKey.Sign(sample)
secondPrivKey, _ := NewPrivateKey()
wrongPubKey := secondPrivKey.PublicKey()
t.Run("Secp256r1", func(t *testing.T) {
privKey, _ := NewPrivateKey()
signedData := privKey.Sign(sample)
actual := wrongPubKey.Verify(signedData, hashedData.BytesBE())
expcted := false
assert.Equal(t, expcted, actual)
secondPrivKey, _ := NewPrivateKey()
wrongPubKey := secondPrivKey.PublicKey()
actual := wrongPubKey.Verify(signedData, hashedData.BytesBE())
expcted := false
assert.Equal(t, expcted, actual)
})
t.Run("Secp256k1", func(t *testing.T) {
privateKey, err := btcec.NewPrivateKey(btcec.S256())
assert.Nil(t, err)
signature, err := privateKey.Sign(hashedData.BytesBE())
assert.Nil(t, err)
signedData := append(signature.R.Bytes(), signature.S.Bytes()...)
secondPrivKey, err := btcec.NewPrivateKey(btcec.S256())
assert.Nil(t, err)
wrongPubKey := PublicKey(ecdsa.PublicKey{
Curve: btcec.S256(),
X: secondPrivKey.X,
Y: secondPrivKey.Y,
})
assert.False(t, wrongPubKey.Verify(signedData, hashedData.BytesBE()))
})
}

View file

@ -14,28 +14,28 @@ type Ktype struct {
// Arr contains a set of known keys in Ktype format.
var Arr = []Ktype{
{
Address: "NMPAXGtMfZ8s8rcfP9JhrYrNeZHG4xSVmd",
Address: "NNWAo5vdVJz1oyCuNiaTBA3amBHnWCF4Yk",
PrivateKey: "7d128a6d096f0c14c3a25a2b0c41cf79661bfcb4a8cc95aaaea28bde4d732344",
PublicKey: "02028a99826edc0c97d18e22b6932373d908d323aa7f92656a77ec26e8861699ef",
Wif: "L1QqQJnpBwbsPGAuutuzPTac8piqvbR1HRjrY5qHup48TBCBFe4g",
Passphrase: "city of zion",
EncryptedWif: "6PYWdzMKGbfxHbfb2JqZJ5Yr1y6jjjuSPLjvgS4byvDkgz2NdiBgeJwBFc",
EncryptedWif: "6PYSeMMbJtfMRD81eHzriwrRKquu2dgLNurYcAbmJa7YqAiThgA2vGQu5o",
},
{
Address: "NRC6oteucWYXq7aASD6YWe5rNeXAw1ehye",
Address: "NiwvMyWYeNghLG8tDyKkWwuZV3wS8CPrrV",
PrivateKey: "9ab7e154840daca3a2efadaf0df93cd3a5b51768c632f5433f86909d9b994a69",
PublicKey: "031d8e1630ce640966967bc6d95223d21f44304133003140c3b52004dc981349c9",
Wif: "L2QTooFoDFyRFTxmtiVHt5CfsXfVnexdbENGDkkrrgTTryiLsPMG",
Passphrase: "我的密码",
EncryptedWif: "6PYLxXgqE8MaQJr3NR96rfFBxzdNLytb3CfxeDXyijSEG2M1vF9d4CoRAg",
EncryptedWif: "6PYKWKaq5NMyjt8cjvnJnvmV13inhFuePpWZMkddFAMCgjC3ETt7kX16V9",
},
{
Address: "NTFAwXLGoiWwSMP5vJyZp8K4cBFwrzUs8m",
Address: "NTWHAzB82LRGWNuuqjVyyzpGvF3WxbbPoG",
PrivateKey: "3edee7036b8fd9cef91de47386b191dd76db2888a553e7736bb02808932a915b",
PublicKey: "02232ce8d2e2063dce0451131851d47421bfc4fc1da4db116fca5302c0756462fa",
Wif: "KyKvWLZsNwBJx5j9nurHYRwhYfdQUu9tTEDsLCUHDbYBL8cHxMiG",
Passphrase: "MyL33tP@33w0rd",
EncryptedWif: "6PYRoabFnWARA3ZWwfJ4efQ4uuuB9WdVrA1LFbMkZLtXZ2DJg3bzjiK59s",
EncryptedWif: "6PYSzKoJBQMj9uHUv1Sc2ZhMrydqDF8ZCTeE9FuPiNdEx7Lo9NoEuaXeyk",
},
{
Address: "xdf4UGKevVrMR1j3UkPsuoYKSC4ocoAkKx",
@ -43,7 +43,7 @@ var Arr = []Ktype{
PublicKey: "zz232ce8d2e2063dce0451131851d47421bfc4fc1da4db116fca5302c0756462fa",
Wif: "zzKvWLZsNwBJx5j9nurHYRwhYfdQUu9tTEDsLCUHDbYBL8cHxMiG",
Passphrase: "zzL33tP@33w0rd",
EncryptedWif: "6PYRoabFnWARA3ZWwfJ4efQ4uuuB9WdVrA1LFbMkZLtXZ2DJg3bzjiK59s",
EncryptedWif: "6PYSzKoJBQMj9uHUv1Sc2ZhMrydqDF8ZCTeE9FuPiNdEx7Lo9NoEuaXeyk",
Invalid: true,
},
}

View file

@ -8,8 +8,26 @@ func SHA256(b []byte) []byte {
return nil
}
// ECDsaVerify checks that sig is correct msg's signature for a given pub
// (serialized public key). It uses `Neo.Crypto.ECDsaVerify` syscall.
func ECDsaVerify(msg []byte, pub []byte, sig []byte) bool {
// ECDsaSecp256r1Verify checks that sig is correct msg's signature for a given pub
// (serialized public key). It uses `Neo.Crypto.VerifyWithECDsaSecp256r1` syscall.
func ECDsaSecp256r1Verify(msg []byte, pub []byte, sig []byte) bool {
return false
}
// ECDsaSecp256k1Verify checks that sig is correct msg's signature for a given pub
// (serialized public key). It uses `Neo.Crypto.VerifyWithECDsaSecp256k1` syscall.
func ECDsaSecp256k1Verify(msg []byte, pub []byte, sig []byte) bool {
return false
}
// ECDSASecp256r1CheckMultisig checks multiple ECDSA signatures at once. It uses
// `Neo.Crypto.CheckMultisigWithECDsaSecp256r1` syscall.
func ECDSASecp256r1CheckMultisig(msg []byte, pubs [][]byte, sigs [][]byte) bool {
return false
}
// ECDSASecp256k1CheckMultisig checks multiple ECDSA signatures at once. It uses
// `Neo.Crypto.CheckMultisigWithECDsaSecp256k1` syscall.
func ECDSASecp256k1CheckMultisig(msg []byte, pubs [][]byte, sigs [][]byte) bool {
return false
}

View file

@ -52,7 +52,7 @@ type rpcTestCase struct {
}
const testContractHash = "10e262ef80c76bdecca287a2c047841fc02c3129"
const deploymentTxHash = "4843700d16be3e6507a25909d3b2aa1472dcd0526be2520f2bfdd53d768bfebf"
const deploymentTxHash = "49f555734b90eb7d4f87041b5146a9b6bc7cf70060bb665212773719091b3a81"
var rpcTestCases = map[string][]rpcTestCase{
"getapplicationlog": {
@ -720,7 +720,7 @@ var rpcTestCases = map[string][]rpcTestCase{
"sendrawtransaction": {
{
name: "positive",
params: `["000a000000316e851039019d39dfc2c37d6c3fee19fd58098780969800000000009269130000000000b00400000001316e851039019d39dfc2c37d6c3fee19fd580987015d0300e87648170000000c1420728274afafc36f43a071d328cfa3e629d9cbb00c14316e851039019d39dfc2c37d6c3fee19fd58098713c00c087472616e736665720c14897720d8cd76f4f00abfa37c0edd889c208fde9b41627d5b523801420c4037c8c002c3352329c5f2995567a355d57372447c156ea544844d5f8027babf4cd86142d986681992805e3f62f2625b551f18cf05897e6ea7c135f22537bb740e290c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b410a906ad4"]`,
params: `["000a000000aa8acf859d4fe402b34e673f2156821796a488eb80969800000000009269130000000000b00400000001aa8acf859d4fe402b34e673f2156821796a488eb015d0300e87648170000000c1478ba4c24009fe510e136c9995a2e05215e1be4dc0c14aa8acf859d4fe402b34e673f2156821796a488eb13c00c087472616e736665720c14897720d8cd76f4f00abfa37c0edd889c208fde9b41627d5b523801420c4040719393aa590d962cb5a48e16360ac75a6c358c9699e9f1a853afede4d601b6783e28f5ec74542aaf59519e76830ba9d267656db324461fdb08d1d51521e103290c2102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc20b4195440d78"]`,
result: func(e *executor) interface{} {
v := true
return &v

Binary file not shown.

View file

@ -30,7 +30,7 @@ func CreateMultiSigRedeemScript(m int, publicKeys keys.PublicKeys) ([]byte, erro
}
emit.Int(buf.BinWriter, int64(len(publicKeys)))
emit.Opcode(buf.BinWriter, opcode.PUSHNULL)
emit.Syscall(buf.BinWriter, "Neo.Crypto.ECDsaCheckMultiSig")
emit.Syscall(buf.BinWriter, "Neo.Crypto.CheckMultisigWithECDsaSecp256r1")
return buf.Bytes(), nil
}

View file

@ -34,5 +34,5 @@ func TestCreateMultiSigRedeemScript(t *testing.T) {
assert.Equal(t, opcode.PUSH3, opcode.Opcode(br.ReadB()))
assert.Equal(t, opcode.PUSHNULL, opcode.Opcode(br.ReadB()))
assert.Equal(t, opcode.SYSCALL, opcode.Opcode(br.ReadB()))
assert.Equal(t, emit.InteropNameToID([]byte("Neo.Crypto.ECDsaCheckMultiSig")), br.ReadU32LE())
assert.Equal(t, emit.InteropNameToID([]byte("Neo.Crypto.CheckMultisigWithECDsaSecp256r1")), br.ReadU32LE())
}

View file

@ -10,8 +10,8 @@ import (
)
var (
verifyInteropID = emit.InteropNameToID([]byte("Neo.Crypto.ECDsaVerify"))
multisigInteropID = emit.InteropNameToID([]byte("Neo.Crypto.ECDsaCheckMultiSig"))
verifyInteropID = emit.InteropNameToID([]byte("Neo.Crypto.VerifyWithECDsaSecp256r1"))
multisigInteropID = emit.InteropNameToID([]byte("Neo.Crypto.CheckMultisigWithECDsaSecp256r1"))
)
func getNumOfThingsFromInstr(instr opcode.Opcode, param []byte) (int, bool) {

View file

@ -1,6 +1,7 @@
package vm
import (
"crypto/elliptic"
"encoding/binary"
"encoding/json"
"fmt"
@ -1457,9 +1458,9 @@ func (v *VM) calcJumpOffset(ctx *Context, parameter []byte) (int, int, error) {
}
// CheckMultisigPar checks if sigs contains sufficient valid signatures.
func CheckMultisigPar(v *VM, h []byte, pkeys [][]byte, sigs [][]byte) bool {
func CheckMultisigPar(v *VM, curve elliptic.Curve, h []byte, pkeys [][]byte, sigs [][]byte) bool {
if len(sigs) == 1 {
return checkMultisig1(v, h, pkeys, sigs[0])
return checkMultisig1(v, curve, h, pkeys, sigs[0])
}
k1, k2 := 0, len(pkeys)-1
@ -1496,8 +1497,8 @@ func CheckMultisigPar(v *VM, h []byte, pkeys [][]byte, sigs [][]byte) bool {
go worker(tasks, results)
}
tasks <- task{pub: v.bytesToPublicKey(pkeys[k1]), signum: s1}
tasks <- task{pub: v.bytesToPublicKey(pkeys[k2]), signum: s2}
tasks <- task{pub: v.bytesToPublicKey(pkeys[k1], curve), signum: s1}
tasks <- task{pub: v.bytesToPublicKey(pkeys[k2], curve), signum: s2}
sigok := true
taskCount := 2
@ -1541,7 +1542,7 @@ loop:
nextKey = k2
}
taskCount++
tasks <- task{pub: v.bytesToPublicKey(pkeys[nextKey]), signum: nextSig}
tasks <- task{pub: v.bytesToPublicKey(pkeys[nextKey], curve), signum: nextSig}
}
close(tasks)
@ -1549,9 +1550,9 @@ loop:
return sigok
}
func checkMultisig1(v *VM, h []byte, pkeys [][]byte, sig []byte) bool {
func checkMultisig1(v *VM, curve elliptic.Curve, h []byte, pkeys [][]byte, sig []byte) bool {
for i := range pkeys {
pkey := v.bytesToPublicKey(pkeys[i])
pkey := v.bytesToPublicKey(pkeys[i], curve)
if pkey.Verify(sig, h) {
return true
}
@ -1606,14 +1607,14 @@ func (v *VM) checkInvocationStackSize() {
// bytesToPublicKey is a helper deserializing keys using cache and panicing on
// error.
func (v *VM) bytesToPublicKey(b []byte) *keys.PublicKey {
func (v *VM) bytesToPublicKey(b []byte, curve elliptic.Curve) *keys.PublicKey {
var pkey *keys.PublicKey
s := string(b)
if v.keys[s] != nil {
pkey = v.keys[s]
} else {
var err error
pkey, err = keys.NewPublicKeyFromBytes(b)
pkey, err = keys.NewPublicKeyFromBytes(b, curve)
if err != nil {
panic(err.Error())
}

View file

@ -2,6 +2,7 @@ package vm
import (
"bytes"
"crypto/elliptic"
"encoding/binary"
"encoding/hex"
"fmt"
@ -116,9 +117,9 @@ func TestBytesToPublicKey(t *testing.T) {
assert.Equal(t, 0, len(cache))
keyHex := "03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c"
keyBytes, _ := hex.DecodeString(keyHex)
key := v.bytesToPublicKey(keyBytes)
key := v.bytesToPublicKey(keyBytes, elliptic.P256())
assert.NotNil(t, key)
key2 := v.bytesToPublicKey(keyBytes)
key2 := v.bytesToPublicKey(keyBytes, elliptic.P256())
assert.Equal(t, key, key2)
cache = v.GetPublicKeys()
@ -126,7 +127,7 @@ func TestBytesToPublicKey(t *testing.T) {
assert.NotNil(t, cache[string(keyBytes)])
keyBytes[0] = 0xff
require.Panics(t, func() { v.bytesToPublicKey(keyBytes) })
require.Panics(t, func() { v.bytesToPublicKey(keyBytes, elliptic.P256()) })
}
func TestPushBytes1to75(t *testing.T) {

View file

@ -113,13 +113,13 @@ func TestAccount_ConvertMultisig(t *testing.T) {
t.Run("1/1 multisig", func(t *testing.T) {
pubs := convertPubs(t, hexs[:1])
require.NoError(t, a.ConvertMultisig(1, pubs))
require.Equal(t, "NYqxsNMHxDg3T19APYP27mBZFfauC4zngR", a.Address)
require.Equal(t, "NVNvVRW5Q5naSx2k2iZm7xRgtRNGuZppAK", a.Address)
})
t.Run("3/4 multisig", func(t *testing.T) {
pubs := convertPubs(t, hexs)
require.NoError(t, a.ConvertMultisig(3, pubs))
require.Equal(t, "Nbb1qkwcwNSBs9pAnrVVrnFbWnbWBk91U2", a.Address)
require.Equal(t, "NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY", a.Address)
})
}

View file

@ -2,11 +2,11 @@
"version": "3.0",
"accounts": [
{
"address": "NQRLhCpAru9BjGsMwk67vdMwmzKMRgsnnN",
"key": "6PYSxdYbqJQKJcE7L8SUummK4X95aK14KA9obhw3fw6SX3rMRofPzpnr8L",
"address": "NbTiM6h8r99kpRtb428XcsUk1TzKed2gTc",
"key": "6PYN7LvaWqBNw7Xb7a52LSbPnP91kyuzYi3HncGvQwQoYAY2W8DncTgpux",
"label": "",
"contract": {
"script": "DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcILQQqQatQ=",
"script": "DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcILQZVEDXg=",
"parameters": [
{
"name": "parameter0",
@ -19,11 +19,11 @@
"isDefault": false
},
{
"address": "Nbb1qkwcwNSBs9pAnrVVrnFbWnbWBk91U2",
"key": "6PYSxdYbqJQKJcE7L8SUummK4X95aK14KA9obhw3fw6SX3rMRofPzpnr8L",
"address": "NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY",
"key": "6PYN7LvaWqBNw7Xb7a52LSbPnP91kyuzYi3HncGvQwQoYAY2W8DncTgpux",
"label": "",
"contract": {
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBMHOzuw==",
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBE43vrw==",
"parameters": [
{
"name": "parameter0",

View file

@ -2,11 +2,11 @@
"version": "3.0",
"accounts": [
{
"address": "NQRLhCpAru9BjGsMwk67vdMwmzKMRgsnnN",
"key": "6PYSxdYbqJQKJcE7L8SUummK4X95aK14KA9obhw3fw6SX3rMRofPzpnr8L",
"address": "NbTiM6h8r99kpRtb428XcsUk1TzKed2gTc",
"key": "6PYN7LvaWqBNw7Xb7a52LSbPnP91kyuzYi3HncGvQwQoYAY2W8DncTgpux",
"label": "",
"contract": {
"script": "DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcILQQqQatQ=",
"script": "DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcILQZVEDXg=",
"parameters": [
{
"name": "parameter0",
@ -19,11 +19,11 @@
"isDefault": false
},
{
"address": "Nbb1qkwcwNSBs9pAnrVVrnFbWnbWBk91U2",
"key": "6PYSxdYbqJQKJcE7L8SUummK4X95aK14KA9obhw3fw6SX3rMRofPzpnr8L",
"address": "NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY",
"key": "6PYN7LvaWqBNw7Xb7a52LSbPnP91kyuzYi3HncGvQwQoYAY2W8DncTgpux",
"label": "",
"contract": {
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBMHOzuw==",
"script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBE43vrw==",
"parameters": [
{
"name": "parameter0",
@ -44,11 +44,11 @@
"isDefault": false
},
{
"address": "NNsXzAGGVY3H3viPHzaoD6BcVtqNCdMAHZ",
"key": "6PYVQUTQLzdhtdnNLSBkse2DGG5gpPFuNGjaBZxYuJ4XsQrtVNy1E9k7R9",
"address": "NWvKSwutC8D6VKmmPxAEgFKx2NLvFhn8q5",
"key": "6PYKEHagXJ3mDLdga1FoyTGRtPdJgPz6Gb8sjEFwZvRu7ncD9PVZfHtMzL",
"label": "",
"contract": {
"script": "DCECEDp/fdAWVYWX95YNJ8UWpDlP2Wi55lFV60sBPkBAQG4LQQqQatQ=",
"script": "DCECEDp/fdAWVYWX95YNJ8UWpDlP2Wi55lFV60sBPkBAQG4LQZVEDXg=",
"parameters": [
{
"name": "parameter0",

View file

@ -181,14 +181,14 @@ func TestWalletGetChangeAddress(t *testing.T) {
require.NoError(t, err)
sh := w1.GetChangeAddress()
// No default address, the first one is used.
expected, err := address.StringToUint160("NQRLhCpAru9BjGsMwk67vdMwmzKMRgsnnN")
expected, err := address.StringToUint160("NbTiM6h8r99kpRtb428XcsUk1TzKed2gTc")
require.NoError(t, err)
require.Equal(t, expected, sh)
w2, err := NewWalletFromFile("testdata/wallet2.json")
require.NoError(t, err)
sh = w2.GetChangeAddress()
// Default address.
expected, err = address.StringToUint160("NNsXzAGGVY3H3viPHzaoD6BcVtqNCdMAHZ")
expected, err = address.StringToUint160("NWvKSwutC8D6VKmmPxAEgFKx2NLvFhn8q5")
require.NoError(t, err)
require.Equal(t, expected, sh)
}