2020-03-18 09:41:09 +00:00
|
|
|
package crypto
|
|
|
|
|
|
|
|
import (
|
2020-07-13 09:59:41 +00:00
|
|
|
"crypto/elliptic"
|
2020-03-18 11:04:52 +00:00
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
|
2021-02-05 08:25:22 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/core/fee"
|
2020-03-18 09:41:09 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/vm"
|
|
|
|
)
|
|
|
|
|
2020-07-13 10:39:36 +00:00
|
|
|
// ECDSASecp256r1CheckMultisig checks multiple ECDSA signatures at once using
|
|
|
|
// Secp256r1 elliptic curve.
|
2020-08-07 11:37:49 +00:00
|
|
|
func ECDSASecp256r1CheckMultisig(ic *interop.Context) error {
|
2021-03-09 15:11:21 +00:00
|
|
|
hashToCheck := ic.Container.GetSignedHash()
|
2020-08-07 11:37:49 +00:00
|
|
|
pkeys, err := ic.VM.Estack().PopSigElements()
|
2020-03-18 11:04:52 +00:00
|
|
|
if err != nil {
|
2020-08-06 16:09:57 +00:00
|
|
|
return fmt.Errorf("wrong parameters: %w", err)
|
2020-03-18 11:04:52 +00:00
|
|
|
}
|
2021-02-05 08:25:22 +00:00
|
|
|
if !ic.VM.AddGas(ic.BaseExecFee() * fee.ECDSAVerifyPrice * int64(len(pkeys))) {
|
2020-06-19 09:21:37 +00:00
|
|
|
return errors.New("gas limit exceeded")
|
|
|
|
}
|
2020-08-07 11:37:49 +00:00
|
|
|
sigs, err := ic.VM.Estack().PopSigElements()
|
2020-03-18 11:04:52 +00:00
|
|
|
if err != nil {
|
2020-08-06 16:09:57 +00:00
|
|
|
return fmt.Errorf("wrong parameters: %w", err)
|
2020-03-18 11:04:52 +00:00
|
|
|
}
|
|
|
|
// It's ok to have more keys than there are signatures (it would
|
|
|
|
// just mean that some keys didn't sign), but not the other way around.
|
|
|
|
if len(pkeys) < len(sigs) {
|
|
|
|
return errors.New("more signatures than there are keys")
|
|
|
|
}
|
2021-03-09 14:38:41 +00:00
|
|
|
sigok := vm.CheckMultisigPar(ic.VM, elliptic.P256(), hashToCheck.BytesBE(), pkeys, sigs)
|
2020-08-07 11:37:49 +00:00
|
|
|
ic.VM.Estack().PushVal(sigok)
|
2020-03-18 11:04:52 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2021-03-04 17:56:54 +00:00
|
|
|
// ECDSASecp256r1CheckSig checks ECDSA signature using Secp256r1 elliptic curve.
|
|
|
|
func ECDSASecp256r1CheckSig(ic *interop.Context) error {
|
|
|
|
hashToCheck := ic.Container.GetSignedHash()
|
|
|
|
keyb := ic.VM.Estack().Pop().Bytes()
|
|
|
|
signature := ic.VM.Estack().Pop().Bytes()
|
|
|
|
pkey, err := keys.NewPublicKeyFromBytes(keyb, elliptic.P256())
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
res := pkey.Verify(signature, hashToCheck.BytesBE())
|
|
|
|
ic.VM.Estack().PushVal(res)
|
|
|
|
return nil
|
|
|
|
}
|