diff --git a/.docker/wallets/wallet1.json b/.docker/wallets/wallet1.json index 0e7102d1c..de29bf7c7 100644 --- a/.docker/wallets/wallet1.json +++ b/.docker/wallets/wallet1.json @@ -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", diff --git a/.docker/wallets/wallet1_solo.json b/.docker/wallets/wallet1_solo.json index cc6da19a8..97f745b1b 100644 --- a/.docker/wallets/wallet1_solo.json +++ b/.docker/wallets/wallet1_solo.json @@ -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", diff --git a/.docker/wallets/wallet2.json b/.docker/wallets/wallet2.json index 954833570..92e2114af 100644 --- a/.docker/wallets/wallet2.json +++ b/.docker/wallets/wallet2.json @@ -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", diff --git a/.docker/wallets/wallet3.json b/.docker/wallets/wallet3.json index 09a5aa8b7..f48127972 100644 --- a/.docker/wallets/wallet3.json +++ b/.docker/wallets/wallet3.json @@ -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", diff --git a/.docker/wallets/wallet4.json b/.docker/wallets/wallet4.json index 0a6c5fd06..1cbad5ad9 100644 --- a/.docker/wallets/wallet4.json +++ b/.docker/wallets/wallet4.json @@ -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", diff --git a/go.mod b/go.mod index b6c004c6d..9d982537e 100644 --- a/go.mod +++ b/go.mod @@ -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 diff --git a/go.sum b/go.sum index 57963dec3..a3d1764be 100644 --- a/go.sum +++ b/go.sum @@ -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= diff --git a/pkg/compiler/syscall.go b/pkg/compiler/syscall.go index 9b725a1c4..e47a9ca75 100644 --- a/pkg/compiler/syscall.go +++ b/pkg/compiler/syscall.go @@ -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", diff --git a/pkg/compiler/verify_test.go b/pkg/compiler/verify_test.go index 9ea772f13..329f3e016 100644 --- a/pkg/compiler/verify_test.go +++ b/pkg/compiler/verify_test.go @@ -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) } ` } diff --git a/pkg/consensus/payload_test.go b/pkg/consensus/payload_test.go index 1cbe97a3b..8f738b544 100644 --- a/pkg/consensus/payload_test.go +++ b/pkg/consensus/payload_test.go @@ -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) diff --git a/pkg/consensus/testdata/wallet1.json b/pkg/consensus/testdata/wallet1.json index 0e7102d1c..de29bf7c7 100644 --- a/pkg/consensus/testdata/wallet1.json +++ b/pkg/consensus/testdata/wallet1.json @@ -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", diff --git a/pkg/consensus/testdata/wallet2.json b/pkg/consensus/testdata/wallet2.json index 954833570..92e2114af 100644 --- a/pkg/consensus/testdata/wallet2.json +++ b/pkg/consensus/testdata/wallet2.json @@ -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", diff --git a/pkg/consensus/testdata/wallet3.json b/pkg/consensus/testdata/wallet3.json index 09a5aa8b7..f48127972 100644 --- a/pkg/consensus/testdata/wallet3.json +++ b/pkg/consensus/testdata/wallet3.json @@ -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", diff --git a/pkg/consensus/testdata/wallet4.json b/pkg/consensus/testdata/wallet4.json index 0a6c5fd06..1cbad5ad9 100644 --- a/pkg/consensus/testdata/wallet4.json +++ b/pkg/consensus/testdata/wallet4.json @@ -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", diff --git a/pkg/core/interop/crypto/ecdsa.go b/pkg/core/interop/crypto/ecdsa.go index d744eef20..67676292c 100644 --- a/pkg/core/interop/crypto/ecdsa.go +++ b/pkg/core/interop/crypto/ecdsa.go @@ -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 } diff --git a/pkg/core/interop/crypto/ecdsa_test.go b/pkg/core/interop/crypto/ecdsa_test.go index a628966a9..4261d0014 100644 --- a/pkg/core/interop/crypto/ecdsa_test.go +++ b/pkg/core/interop/crypto/ecdsa_test.go @@ -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 diff --git a/pkg/core/interop/crypto/interop.go b/pkg/core/interop/crypto/interop.go index bf651058a..77dc58479 100644 --- a/pkg/core/interop/crypto/interop.go +++ b/pkg/core/interop/crypto/interop.go @@ -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: diff --git a/pkg/core/interop/runtime/witness.go b/pkg/core/interop/runtime/witness.go index c152a8eff..b5783db17 100644 --- a/pkg/core/interop/runtime/witness.go +++ b/pkg/core/interop/runtime/witness.go @@ -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") } diff --git a/pkg/core/interop_neo_test.go b/pkg/core/interop_neo_test.go index ba88104da..9d26b88b0 100644 --- a/pkg/core/interop_neo_test.go +++ b/pkg/core/interop_neo_test.go @@ -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 { diff --git a/pkg/core/interop_system.go b/pkg/core/interop_system.go index 0b2905aad..003c6acda 100644 --- a/pkg/core/interop_system.go +++ b/pkg/core/interop_system.go @@ -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 } diff --git a/pkg/core/interops.go b/pkg/core/interops.go index 35bb5e5ae..e9a6da597 100644 --- a/pkg/core/interops.go +++ b/pkg/core/interops.go @@ -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}, diff --git a/pkg/core/native/native_neo.go b/pkg/core/native/native_neo.go index 747025315..ca88bfe97 100644 --- a/pkg/core/native/native_neo.go +++ b/pkg/core/native/native_neo.go @@ -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 } diff --git a/pkg/core/util_test.go b/pkg/core/util_test.go index de438e42c..4a42db8a7 100644 --- a/pkg/core/util_test.go +++ b/pkg/core/util_test.go @@ -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) diff --git a/pkg/crypto/keys/private_key.go b/pkg/crypto/keys/private_key.go index 0c2dc7d5b..02f23256b 100644 --- a/pkg/crypto/keys/private_key.go +++ b/pkg/crypto/keys/private_key.go @@ -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 } diff --git a/pkg/crypto/keys/publickey.go b/pkg/crypto/keys/publickey.go index a6d905826..003a41d62 100644 --- a/pkg/crypto/keys/publickey.go +++ b/pkg/crypto/keys/publickey.go @@ -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). diff --git a/pkg/crypto/keys/publickey_test.go b/pkg/crypto/keys/publickey_test.go index 848808919..c4b03c5d1 100644 --- a/pkg/crypto/keys/publickey_test.go +++ b/pkg/crypto/keys/publickey_test.go @@ -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) } diff --git a/pkg/crypto/keys/sign_verify_test.go b/pkg/crypto/keys/sign_verify_test.go index 5241a2cc6..b78df4fac 100644 --- a/pkg/crypto/keys/sign_verify_test.go +++ b/pkg/crypto/keys/sign_verify_test.go @@ -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())) + }) } diff --git a/pkg/internal/keytestcases/testcases.go b/pkg/internal/keytestcases/testcases.go index cdc92b159..62f8dc85d 100644 --- a/pkg/internal/keytestcases/testcases.go +++ b/pkg/internal/keytestcases/testcases.go @@ -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, }, } diff --git a/pkg/interop/crypto/crypto.go b/pkg/interop/crypto/crypto.go index fa2d394f6..6e894465b 100644 --- a/pkg/interop/crypto/crypto.go +++ b/pkg/interop/crypto/crypto.go @@ -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 } diff --git a/pkg/rpc/server/server_test.go b/pkg/rpc/server/server_test.go index 04ab458b3..1f7feca7d 100644 --- a/pkg/rpc/server/server_test.go +++ b/pkg/rpc/server/server_test.go @@ -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 diff --git a/pkg/rpc/server/testdata/testblocks.acc b/pkg/rpc/server/testdata/testblocks.acc index c00d33f9e..98d85b7a0 100644 Binary files a/pkg/rpc/server/testdata/testblocks.acc and b/pkg/rpc/server/testdata/testblocks.acc differ diff --git a/pkg/smartcontract/contract.go b/pkg/smartcontract/contract.go index 6f55f08c7..0b12dc3ba 100644 --- a/pkg/smartcontract/contract.go +++ b/pkg/smartcontract/contract.go @@ -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 } diff --git a/pkg/smartcontract/contract_test.go b/pkg/smartcontract/contract_test.go index 4ea1dae87..889def6be 100644 --- a/pkg/smartcontract/contract_test.go +++ b/pkg/smartcontract/contract_test.go @@ -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()) } diff --git a/pkg/vm/contract_checks.go b/pkg/vm/contract_checks.go index 1c8bfc4ea..cd2f83b52 100644 --- a/pkg/vm/contract_checks.go +++ b/pkg/vm/contract_checks.go @@ -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) { diff --git a/pkg/vm/vm.go b/pkg/vm/vm.go index 630bbfc19..7ce280883 100644 --- a/pkg/vm/vm.go +++ b/pkg/vm/vm.go @@ -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()) } diff --git a/pkg/vm/vm_test.go b/pkg/vm/vm_test.go index e076a0f71..fe324aa7c 100644 --- a/pkg/vm/vm_test.go +++ b/pkg/vm/vm_test.go @@ -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) { diff --git a/pkg/wallet/account_test.go b/pkg/wallet/account_test.go index 836718b8d..84225b413 100644 --- a/pkg/wallet/account_test.go +++ b/pkg/wallet/account_test.go @@ -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) }) } diff --git a/pkg/wallet/testdata/wallet1.json b/pkg/wallet/testdata/wallet1.json index 0e7102d1c..de29bf7c7 100644 --- a/pkg/wallet/testdata/wallet1.json +++ b/pkg/wallet/testdata/wallet1.json @@ -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", diff --git a/pkg/wallet/testdata/wallet2.json b/pkg/wallet/testdata/wallet2.json index 9fbfa2656..df0fff3ec 100644 --- a/pkg/wallet/testdata/wallet2.json +++ b/pkg/wallet/testdata/wallet2.json @@ -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", diff --git a/pkg/wallet/wallet_test.go b/pkg/wallet/wallet_test.go index e811eea04..302795845 100644 --- a/pkg/wallet/wallet_test.go +++ b/pkg/wallet/wallet_test.go @@ -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) }