@@ -1042,6 +1042,103 @@ func TestECOpsNonTaproot(t *testing.T) {
10421042 }
10431043}
10441044
1045+ // TestECOpsWithoutFlag tests that EC opcodes fail when taproot is enabled but
1046+ // the ScriptVerifyECOps flag is not set.
1047+ func TestECOpsWithoutFlag (t * testing.T ) {
1048+ t .Parallel ()
1049+
1050+ privKey , _ := generateTestPrivateKey (
1051+ t .Name (), 1 ,
1052+ )
1053+ pubKey := privKey .PubKey ()
1054+ point33 := pubKey .SerializeCompressed ()
1055+
1056+ opcodes := []struct {
1057+ name string
1058+ template string
1059+ params map [string ]interface {}
1060+ }{
1061+ {
1062+ name : "OP_EC_POINT_ADD without EC flag" ,
1063+ template : `
1064+ {{ hex .Point1 }} {{ hex .Point2 }} OP_EC_POINT_ADD` ,
1065+ params : map [string ]interface {}{
1066+ "Point1" : point33 ,
1067+ "Point2" : point33 ,
1068+ },
1069+ },
1070+ {
1071+ name : "OP_EC_POINT_MUL without EC flag" ,
1072+ template : `
1073+ {{ hex .Scalar }} {{ hex .Point }} OP_EC_POINT_MUL` ,
1074+ params : map [string ]interface {}{
1075+ "Scalar" : append (
1076+ bytes .Repeat ([]byte {0x00 }, 31 ), 0x01 ,
1077+ ),
1078+ "Point" : point33 ,
1079+ },
1080+ },
1081+ {
1082+ name : "OP_EC_POINT_NEGATE without EC flag" ,
1083+ template : "{{ hex .Point }} OP_EC_POINT_NEGATE" ,
1084+ params : map [string ]interface {}{
1085+ "Point" : point33 ,
1086+ },
1087+ },
1088+ {
1089+ name : "OP_EC_POINT_X_COORD without EC flag" ,
1090+ template : "{{ hex .Point }} OP_EC_POINT_X_COORD" ,
1091+ params : map [string ]interface {}{
1092+ "Point" : point33 ,
1093+ },
1094+ },
1095+ }
1096+
1097+ for _ , test := range opcodes {
1098+ t .Run (test .name , func (t * testing.T ) {
1099+ // Construct the script, create spend info, then
1100+ // construct a valid tapscript spend from that.
1101+ testScript := createTestScriptFromTemplate (
1102+ t , test .template , test .params ,
1103+ )
1104+ spendInfo , err := createTaprootSpendInfo (
1105+ testScript , test .name ,
1106+ )
1107+ require .NoError (
1108+ t , err , "failed to create taproot spend info" ,
1109+ )
1110+ spendTx := createTaprootSpendingTx (
1111+ testScript , spendInfo .ctrlBlockBytes ,
1112+ )
1113+
1114+ // Create the engine with the requisite prev output
1115+ // fetcher. We don't apply the EC OP script flag, so
1116+ // all executions should fail.
1117+ prevOutFetcher := NewCannedPrevOutputFetcher (
1118+ spendInfo .p2trScript , 100000 ,
1119+ )
1120+ flags := StandardVerifyFlags | ScriptVerifyTaproot
1121+ vm , err := NewEngine (
1122+ spendInfo .p2trScript , spendTx , 0 , flags , nil ,
1123+ nil , 100000 , prevOutFetcher ,
1124+ )
1125+ require .NoError (t , err , "failed to create engine" )
1126+
1127+ err = vm .Execute ()
1128+
1129+ // Execution should fail as this op code is disabled.
1130+ require .Error (
1131+ t , err , "expected script to fail " +
1132+ "without EC ops flag but it succeeded" ,
1133+ )
1134+ require .True (
1135+ t , IsErrorCode (err , ErrDisabledOpcode ),
1136+ "expected ErrDisabledOpcode, got %v" , err ,
1137+ )
1138+ })
1139+ }
1140+ }
1141+
10451142// TestECOpsErrors tests error/edge cases for the EC opcodes.
10461143func TestECOpsErrors (t * testing.T ) {
10471144 t .Parallel ()
0 commit comments