summaryrefslogtreecommitdiff
path: root/fb/b37cc9df9a64381af11056189f6c374f9babd9
blob: 06c946b5a6107f4ce1b36f3c4b4725bc46869d1a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
Return-Path: <jlrubin@mit.edu>
Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136])
 by lists.linuxfoundation.org (Postfix) with ESMTP id EFC9AC0174
 for <bitcoin-dev@lists.linuxfoundation.org>;
 Mon,  3 Feb 2020 08:21:09 +0000 (UTC)
Received: from localhost (localhost [127.0.0.1])
 by silver.osuosl.org (Postfix) with ESMTP id D057820016
 for <bitcoin-dev@lists.linuxfoundation.org>;
 Mon,  3 Feb 2020 08:21:09 +0000 (UTC)
X-Virus-Scanned: amavisd-new at osuosl.org
Received: from silver.osuosl.org ([127.0.0.1])
 by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)
 with ESMTP id Ujsk1X4iSfZA
 for <bitcoin-dev@lists.linuxfoundation.org>;
 Mon,  3 Feb 2020 08:21:06 +0000 (UTC)
X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6
Received: from outgoing.mit.edu (outgoing-auth-1.mit.edu [18.9.28.11])
 by silver.osuosl.org (Postfix) with ESMTPS id 607E01FEE0
 for <bitcoin-dev@lists.linuxfoundation.org>;
 Mon,  3 Feb 2020 08:21:06 +0000 (UTC)
Received: from mail-io1-f54.google.com (mail-io1-f54.google.com
 [209.85.166.54]) (authenticated bits=0)
 (User authenticated as jlrubin@ATHENA.MIT.EDU)
 by outgoing.mit.edu (8.14.7/8.12.4) with ESMTP id 0138L4bc015902
 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=NOT)
 for <bitcoin-dev@lists.linuxfoundation.org>; Mon, 3 Feb 2020 03:21:04 -0500
Received: by mail-io1-f54.google.com with SMTP id n21so15702703ioo.10
 for <bitcoin-dev@lists.linuxfoundation.org>;
 Mon, 03 Feb 2020 00:21:04 -0800 (PST)
X-Gm-Message-State: APjAAAWW1O42wGbNMEyxry0ZbsBEG7CN7eS48tAKmHtSdQDVgugNRO1k
 8sn8r5/BA+wld2gUVnwW77sv9dnr16X2dsOujFc=
X-Google-Smtp-Source: APXvYqzFOO+MaOsslK37odoks5zUoWtQlNYeI6HVvkPHR1IMBvxkF+8FsP5yWQrvcDWVDNl5G1VZML8rlp4Qjy+Z76k=
X-Received: by 2002:a5e:a809:: with SMTP id c9mr18512424ioa.105.1580718064029; 
 Mon, 03 Feb 2020 00:21:04 -0800 (PST)
MIME-Version: 1.0
References: <20200201203941.GE28549@mcelrath.org>
In-Reply-To: <20200201203941.GE28549@mcelrath.org>
From: Jeremy <jlrubin@mit.edu>
Date: Mon, 3 Feb 2020 00:20:52 -0800
X-Gmail-Original-Message-ID: <CAD5xwhjLPQDOg4vA1a-NbFn4kDm+a6ZYCmvQKkfDjaPzRH+jMA@mail.gmail.com>
Message-ID: <CAD5xwhjLPQDOg4vA1a-NbFn4kDm+a6ZYCmvQKkfDjaPzRH+jMA@mail.gmail.com>
To: Bob McElrath <bob@mcelrath.org>,
 Bitcoin Protocol Discussion <bitcoin-dev@lists.linuxfoundation.org>
Content-Type: multipart/alternative; boundary="000000000000b2563f059da79a3b"
X-Mailman-Approved-At: Mon, 03 Feb 2020 08:31:49 +0000
Subject: Re: [bitcoin-dev] CTV through SIGHASH flags
X-BeenThere: bitcoin-dev@lists.linuxfoundation.org
X-Mailman-Version: 2.1.15
Precedence: list
List-Id: Bitcoin Protocol Discussion <bitcoin-dev.lists.linuxfoundation.org>
List-Unsubscribe: <https://lists.linuxfoundation.org/mailman/options/bitcoin-dev>, 
 <mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=unsubscribe>
List-Archive: <http://lists.linuxfoundation.org/pipermail/bitcoin-dev/>
List-Post: <mailto:bitcoin-dev@lists.linuxfoundation.org>
List-Help: <mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=help>
List-Subscribe: <https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev>, 
 <mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=subscribe>
X-List-Received-Date: Mon, 03 Feb 2020 08:21:10 -0000

--000000000000b2563f059da79a3b
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

I think these ideas shows healthy review of how OP_CTV is specified against
alternatives, but I think most of the ideas presented are ill advised.

--
@JeremyRubin <https://twitter.com/JeremyRubin>
<https://twitter.com/JeremyRubin>


On Sat, Feb 1, 2020 at 2:15 PM Bob McElrath via bitcoin-dev <
bitcoin-dev@lists.linuxfoundation.org> wrote:

> We propose that OP_CHECKTEMPLATEVERIFY should behave more like CHECKSIG,
> including a flags byte that specify what is hashed. This unifies the ways=
 a
> SigHash is computed, differing only in the final checksig which is omitte=
d
> in
> favor of chacking the hash directly. Having two paths to create a
> signature hash
> introduces extra complexity, especially as concerns potential future
> SIGHASH
> flag upgrades.

<snip>

> I believe the above may be possible *without* a new opcode and simply wit=
h
> a
> sighash flag. That is, consider a flag SIGHASH_NOSIG which behaves as
> follows:
> The stack is expected to contain <hash> <flags>, where the hash to be
> checked is
> <hash> and is in the place where you'd normally put a pubkey. The byte
> <flags>
> is the second thing on the stack. This is intended to be an empty
> "signature"
> with the flags byte appended (which must contain SIGHASH_NOSIG to succeed=
).
>


I've previously brought this up in IRC
http://gnusha.org/bitcoin-wizards/2019-11-28.log


AFAIK, using an actual CheckSig SIGHASH Flag as is is a bad idea because
then you need to include an encoding valid signature and pubkey that map
onto the hash to check. This is not just extra 11 extra bytes of data (33
bytes PubKey + 9 bytes Signature + 2 push -32 bytes - 1 byte push), it's
also a very awkward API. I don't think you can soft-fork around these
encoding rules. But you're right that it's possible to add this as a
SIGHASH flag. I don't think doing CTV as a sighash flag is worth
considering further.

I get your point that CTV is kind of a signature hash, and that we might
want to not have a separate path. This ignores, however, that the current
SIGHASH code-path is kind of garbage and literally no one likes it and it
has been the source of nasty issues previously. Thus I posit that a
separate path creates less complexity, as we don't need to worry about
accidentally introducing a weird interaction with other sighash flags.




> CTV omits inputs as part of its semantics, so CTV-type functionality usin=
g
> CHECKSIG is also achievable if some form of NOINPUT flag is also deployed=
.
> With
> NOINPUT alone, a standard CHECKSIG can be used to implement a covenant --
> though
> it uses an unnecessarily large number of bytes just to check a 32-byte
> hash.
> Therefore, any pitfalls CTV intends to evade can be evaded by using a
> CHECKSIG,
> if NOINPUT is deployed in some form, adding new flexibility.  Beyond what=
's
> possible with NOINPUT/ANYPREVOUT, CTV additionally commits to:
>
> =C2=BB=C2=B7=C2=B7=C2=B7=C2=B7=C2=B7=C2=B7=C2=B71. Number of inputs
> =C2=BB=C2=B7=C2=B7=C2=B7=C2=B7=C2=B7=C2=B7=C2=B72. Number of outputs
> =C2=BB=C2=B7=C2=B7=C2=B7=C2=B7=C2=B7=C2=B7=C2=B73. Index of input
>

NOINPUT as specified here
https://github.com/ajtowns/bips/blob/bip-anyprevout/bip-anyprevout.mediawik=
i
(is this the latest?) isn't a great surrogate for CTV because CTV commits
to the input index which prevents half-spend. This also encumbers, as
proposed, an additional chaperone signature to fix it to a specific output.

This adds a lot of complexity and space to using CTV. Maybe NOINPUT could
make changes to special-case CTV, but then we're back to CTV again.



>
> The justification given for committing to the number of inputs and output=
s
> is
> that "it makes CTV hashes easier to compute with script", however doing s=
o
> would
> require OP_CAT. It's noted that both of these are actually redundant
> commitments. Since the constexpr requirement was removed, if OP_CAT were
> enabled, this commitment to the input index could be evaded by computing
> the CTV
> hash within the script, modifying the input index using data taken from t=
he
> witness. Therefore committing to the input index is a
> sender-specified-policy
> choice, and not an anti-footgun measure for the redeemer. As such, it's
> appropriate to consider committing to the input index using a flag instea=
d.
>
> This is incorrect almost entirely.

1. There is a semantic difference between the *commitment* being strictly
redundant, which has more to do with malleation, and being redundant from a
feature perspective. I could maybe do a better job here of expanding what
"easier" means here -- there are actually some scripts which are quite
difficult to write/impossible without this. I've described this a couple
places outside of the BIP, but essentially it allows you to pin the number
of inputs/outputs separately from the hashes themselves. So if you're
trying to build the template in script, you might want to allow the
Sequences to be set to any value, and pass them via a hash. But then from a
hash you can't check the validity of the length. An external length
commitment lets you do this, but without it you would have to pass in the
sequences directly.
2. The constexpr requirement was implemented in a soft-fork re-moveable
manner specifically so that if we wanted OP_CAT, we could add it without
also introducing constructing CTVs on the stack. Similarly, it would be
possible to specify with OP_CAT as a soft-fork removeable rule that if
OP_CAT executes before an OP_CTV, the script is invalid. The constexpr rule
was removed on the sentiment that if we introduce OP_CAT, we almost surely
intend to introduce it for OP_CTV (or related) use cases.
3. Committing to the input-index is not a *sender* policy choice. It's a
receiver policy choice. I tell a Payer my invoice/address, and they emit a
transaction matching it. From an address containing a CTV, I as the
receiver set the input_index. I don't see how this is related to the
anti-footgun-ness
4. You write as if OP_CTV + OP_CAT allows the input index to stripped
*unconditionally*. That's wrong. It's an opt in if you write a script
taking it as a parameter. You can't evade it in general use.
5. The "anti-footgun" measure is that it precludes reused-keys being spent
in the same transaction. Were you to opt out of the mechanism (via OP_CAT
input_index), then you opt out of the reuse protection. (This only matters
if there is more than one input to begin with).
6. Committing to it via a flag is strictly less flexible, because I can do
a lot more with OP_CAT than with a flag. For instance, I can do
<input_index> <min> <max> OP_WITHIN OP_VERIFY to ensure that it falls
within a certain range of inputs.
7. A flag is also an extra byte somewhere or uses a sighash bit.
8. Enabling a flag right away enables a big footgun right off the bat. I
think it's bad for use safety.
9. Rather than add flags, if you wanted to add this, I would suggest
reserving max input_index to specify a don't care value. Then you always
check a given CTV against the don't care value and the specified value.
Hashing the don't care value can be done in the PreComputedTxData. But I
don't think it's worth special casing or making available today because of
8.



> There are probably reasons this might not work as a flag that I haven't
> discovered yet. Alternatively CTV might be considered to be an alternativ=
e
> type
> of CHECKSIG operator and might be renamed to CHECKSIGHASH, appending flag
> bytes
> to the hash to be checked.
>

Sure -- happy to go down the renaming path again. Keep in mind that CTV
currently only applies rules when the argument is 32-bytes. Future
soft-forkers are welcome to define a rule for a 33byte 1st argument that
treats it as a pubkey and has CHECKSIG semantics, and looks for another
argument.



>
> The flags discussed above, NOINPUT, NOSIG, INPUTINDEX are all really
> sender-policy choices, while SIGHASH flags are redeemer-choice as they
> usually
> occur in the witness. There's really no way currently for an output to
> specify
> that the redeemer must use a particular set of flags. One way to achieve
> this is
> to put the CHECKSIG(HASH) including its flags into the redeemScript --
> which is
> functionally what CTV does (or a CHECKSIG in a redeemScript using NOINPUT=
).
> This is committed to in outputs and therefore specifies sender policies,
> however
> the redeemScript is specified by the receiver.  Perhaps an anti-footgun
> measure
> would be to require that certain SIGHASH flags like these MUST be
> committed to
> in the output, by the sender.
>
>
I think this "sender/redeemer" framework is a bit bunk. Ultimately all
redeemers are senders, and you aren't forcing a choice on someone. You
could be on to something though, but I think in general Bitcoin has gone
the way of opaque addresses so that people can't encumber arbitrary
policies on your coins. Maybe it swings the other way...



> CSV (CHECKSEQUENCEVERIFY) is an example that redemption policies are
> committed
> to in the output by the sender via the sequence_no field, and then checke=
d
> with
> an opcode OP_CSV to enable relative timelocks. It's probably possible to
> add new
> flags to the sequence_no field, and check the new semantics with CSV
> instead of
> an entiely new opcode.
>


The sender commits to them, but legally, if you add a contract that I
didn't agree to as receipt (e.g., in segwit address -- which the script is
hashed) I won't even know I got paid. So the way Bitcoin works today, these
are receiver set policies.

One way to think of CTV is it's precise the opcode that lets you "wrap"
someone's known address in arbitrary new scripts. E.g., if you gave me an
address X, but I need to (for whatever reason) add an additional 1 month
CSV.

So i just get the txn:

A:
    sequence 1mo
    1 input
    1 output: pay X 1 coin

then take the STH(A), and create B


B:
    ... inputs
    1 output pay `STH(A) CTV` 1 coin

I can also add other things, like secondary signers/alternatives

`IF {some checksig program} STH(A) CTV ELSE {multisig program} ENDIF



> As user policy choices, NOINPUT might be considered "MAY" conditions. A
> user MAY
> use NOINPUT on an output, but let's not require it.  Covenants on the oth=
er
> hand, are a MUST condition. The CTV proposal imposes "MUST" conditions on
> the
> existence of the covenant itself, as well as the number of inputs and
> outputs,
> to prevent txid malleability so that such transactions can be used in
> offline
> protocols. Txid non-malleability can be achieved by enforcing that the
> output
> must be spent using SIGHASH_ALL instead of committing to the number of
> inputs
> separately with a new opcode. The MUST condition also helps with sighash
> caching
> for batch validation.
>

ANYPREVOUT/ANYSCRIPT are actually weirder than that, because once it has
been used that key is permanently "burned". Hence ANYPREVOUT has such
pubkeys be explicity tagged as ANYPREVOUT compatible. So a user kind of has
to pre-decide if they want to have ANYPREVOUT semantics or not.
And in this case, key-reuse is relatively unsafe (as you need to track what
else you've signed) so I think what you're suggesting is not robust.

These "MUST" conditions sound nice, but they don't actually help with
validity caching because we want to be able to compute this information
before we've fetched the outputs from the database so we can't know what to
cache yet. Contextless things are things you can precompute not knowing
input scripts.

Again, I don't think this sender/redeemer framework is super useful but I
admire the attempt.



>
> INPUTINDEX is required in a CTV/CHECKSIGHASH world because of the
> half-spend
> problem. Normally outputs are spent uniquely as long as different
> addresses are
> used on the outputs. A transaction with the same address appearing twice
> would
> also have a half-spend problem. Anyone signing the first output and givin=
g
> that
> PSBT to another person can allow them to spend the second input. Therefor=
e
> one
> might even want INPUTINDEX for non-covenant transactions, though making a
> tx
> with the same address twice seems like a silly idea to me.
>

I'm confused. Transactions don't have addresses. What are you talking about=
?

Input indexes accomplish two goals.

One, they eliminate third-party malleability of input order (which would
muck with sighash singles too).
Two, they prevent half-spend.

Signatures today commit to this in the signature hash (the field is nIn,
which is confusing because nIn might also look like vin.size()).

So the half spend problem doesn't exist today...

>
> Therefore, assuming a CSV-type mechanism can be devised using sequence_no=
,
> CTV
> is equivalent to a flag in sequence_no that is logically
> MUST|ALL|NOSIG|INPUTINDEX and a redeemScript of <hash> <flags>.
>
> Lightning-like use cases might put sequence_no flags that are logically
> MAY|ALL|NOINPUT.
>
> The other mechanism for sender policy is scriptPubKey, which is heavily
> restricted by isStandard, but might be another place to specify flags lik=
e
> the
> above.
>
> Thoughts?
>
>

So OP_CAT already lets you do this kind of stuff with the SIGHASHes rather
than a new special-purpose verifier. Just pass the signature separately
from the flags, and cat them togehther for the checker but just look at the
flags for your new thing. Then check that the flags are exactly what you
wanted. If you don't want OP_CAT, you can also add OP_SUBSTRVERIFY wherein
you verify that a provided substr was inside another string. Then you pass
in the witness the full string you want, as well as sub-bits you want to
check properties on (like the flags).

It's not clear to me that we want this kind of stuff though. OP_CAT
requires very careful review because it has very surprising functional
consequences across the board.



> Does this idea address any of the NOINPUT footguns? (which I'm not up on)
> Is there a reason this cannot be done with sequence_no and OP_CSV?
>

ANYPREVOUT already precludes these by using a separate key type and
chaperone signatures.  I think a flag for MUST NOT ANYPREVOUT would maybe
help with making it safer. But this is a complete sidebar from CTV. This
exists already by generating a non-anyprevout capable key though...



> Is there a reason that a separate opcode (CTV) is different/better than
> this
> approach?
>
>
I'll let the email above serve as the answer to your question.

I don't think there's anything gained by expressing CTV as a sighash type
today, especially since a future soft fork (when we've taking the time to
deeply rethink sighash flags, like bitmask sighash flags proposed for
elements) can make CTV (as specified today) a valid hash in this new
language and use the OP_NOP4 with a non 32-byte argument as the new
CheckSig operator anyways.







But now I'll pose a different question: why shouldn't we compute the
sighash entirely as a type of Bitcoin Script? SIGHASH_FLAGS are essentially
a tiny, crappy, language for putting together a message digest. You can
think of SIGHASH_FLAGS as being like optimized "jets" for known programs.
For custom programs, you can construct the digest pattern you want in
script. This is essentially what the bitmask sighash flags proposal is. I
think you're going to waste a lot of mental-cycles trying to cram in all
this logic into flags. As this stuff gets more complicated, you should just
write an actual language for dealing with sighashes and go from there.

Now why don't we want this sighash language? Quadratic hashing. If every
output commits to some different complex thing, we end up doing a lot of
rehashing. Flags are actually kind of bad because a few different flags can
trigger a lot of rehashing. But the way flags are *today* is relatively OK
because we can cache the important parts so validation is cheap.

The more complicated you plan gets, the less context free validation we can
do.

CTV is fully compatible with context free validation optimizations,
trivially. It's not clear if your other stuff is, I suspect not.

--000000000000b2563f059da79a3b
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div dir=3D"ltr"><div class=3D"gmail_default" style=3D"fon=
t-family:arial,helvetica,sans-serif;font-size:small;color:#000000">I think =
these ideas shows healthy review of how OP_CTV is specified against alterna=
tives, but I think most of the ideas presented are ill advised.</div><div c=
lass=3D"gmail_default" style=3D"font-family:arial,helvetica,sans-serif;font=
-size:small;color:#000000"><br></div><div><div dir=3D"ltr" class=3D"gmail_s=
ignature" data-smartmail=3D"gmail_signature"><div dir=3D"ltr">--<br><a href=
=3D"https://twitter.com/JeremyRubin" target=3D"_blank">@JeremyRubin</a><a h=
ref=3D"https://twitter.com/JeremyRubin" target=3D"_blank"></a></div></div><=
/div><br></div><br><div class=3D"gmail_quote"><div dir=3D"ltr" class=3D"gma=
il_attr">On Sat, Feb 1, 2020 at 2:15 PM Bob McElrath via bitcoin-dev &lt;<a=
 href=3D"mailto:bitcoin-dev@lists.linuxfoundation.org">bitcoin-dev@lists.li=
nuxfoundation.org</a>&gt; wrote:<br></div><blockquote class=3D"gmail_quote"=
 style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);p=
adding-left:1ex">We propose that OP_CHECKTEMPLATEVERIFY should behave more =
like CHECKSIG,<br>
including a flags byte that specify what is hashed. This unifies the ways a=
<br>
SigHash is computed, differing only in the final checksig which is omitted =
in<br>
favor of chacking the hash directly. Having two paths to create a signature=
 hash<br>
introduces extra complexity, especially as concerns potential future SIGHAS=
H<br>
flag upgrades.</blockquote><div style=3D"font-family:arial,helvetica,sans-s=
erif;font-size:small;color:rgb(0,0,0)" class=3D"gmail_default">&lt;snip&gt;=
</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;b=
order-left:1px solid rgb(204,204,204);padding-left:1ex"><span class=3D"gmai=
l_default" style=3D"font-family:arial,helvetica,sans-serif;font-size:small;=
color:rgb(0,0,0)"><span class=3D"gmail_default" style=3D"font-family:arial,=
helvetica,sans-serif;font-size:small;color:rgb(0,0,0)"></span>I believe the=
 above may be possible *without* a new opcode and simply with a<br>
sighash flag. That is, consider a flag SIGHASH_NOSIG which behaves as follo=
ws:<br>
The stack is expected to contain &lt;hash&gt; &lt;flags&gt;, where the hash=
 to be checked is<br>
&lt;hash&gt; and is in the place where you&#39;d normally put a pubkey. The=
 byte &lt;flags&gt;<br>
is the second thing on the stack. This is intended to be an empty &quot;sig=
nature&quot;<br>
with the flags byte appended (which must contain SIGHASH_NOSIG to succeed).=
</span><br></blockquote><div><span class=3D"gmail_default" style=3D"font-fa=
mily:arial,helvetica,sans-serif;font-size:small;color:rgb(0,0,0)"></span>=
=C2=A0</div><div><br></div><div><div style=3D"font-family:arial,helvetica,s=
ans-serif;font-size:small;color:rgb(0,0,0)" class=3D"gmail_default">I&#39;v=
e previously brought this up in IRC <a href=3D"http://gnusha.org/bitcoin-wi=
zards/2019-11-28.log">http://gnusha.org/bitcoin-wizards/2019-11-28.log</a> =
</div><br></div><div><br></div><div><div style=3D"font-family:arial,helveti=
ca,sans-serif;font-size:small;color:rgb(0,0,0)" class=3D"gmail_default">AFA=
IK, using an actual CheckSig SIGHASH Flag as is is a bad idea because then =
you need to include an encoding valid signature and pubkey that map onto th=
e hash to check. This is not just extra 11 extra bytes of data (33 bytes Pu=
bKey + 9 bytes Signature + 2 push -32 bytes - 1 byte push), it&#39;s also a=
 very awkward API. I don&#39;t think you can soft-fork around these encodin=
g rules. But you&#39;re right that it&#39;s possible to add this as a SIGHA=
SH flag. I don&#39;t think doing CTV as a sighash flag is worth considering=
 further.</div><div style=3D"font-family:arial,helvetica,sans-serif;font-si=
ze:small;color:rgb(0,0,0)" class=3D"gmail_default"><br></div><div style=3D"=
font-family:arial,helvetica,sans-serif;font-size:small;color:rgb(0,0,0)" cl=
ass=3D"gmail_default">I get your point that CTV is kind of a signature hash=
, and that we might want to not have a separate path. This ignores, however=
, that the current SIGHASH code-path is kind of garbage and literally no on=
e likes it and it has been the source of nasty issues previously. Thus I po=
sit that a separate path creates less complexity, as we don&#39;t need to w=
orry about accidentally introducing a weird interaction with other sighash =
flags.<br></div></div><div><br></div><div><br></div><div>=C2=A0</div><block=
quote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1=
px solid rgb(204,204,204);padding-left:1ex">
CTV omits inputs as part of its semantics, so CTV-type functionality using<=
br>
CHECKSIG is also achievable if some form of NOINPUT flag is also deployed. =
With<br>
NOINPUT alone, a standard CHECKSIG can be used to implement a covenant -- t=
hough<br>
it uses an unnecessarily large number of bytes just to check a 32-byte hash=
.<br>
Therefore, any pitfalls CTV intends to evade can be evaded by using a CHECK=
SIG,<br>
if NOINPUT is deployed in some form, adding new flexibility.=C2=A0 Beyond w=
hat&#39;s<br>
possible with NOINPUT/ANYPREVOUT, CTV additionally commits to: <br>
<br>
=C2=BB=C2=B7=C2=B7=C2=B7=C2=B7=C2=B7=C2=B7=C2=B71. Number of inputs<br>
=C2=BB=C2=B7=C2=B7=C2=B7=C2=B7=C2=B7=C2=B7=C2=B72. Number of outputs<br>
=C2=BB=C2=B7=C2=B7=C2=B7=C2=B7=C2=B7=C2=B7=C2=B73. Index of input<br></bloc=
kquote><div><br></div><div><div style=3D"font-family:arial,helvetica,sans-s=
erif;font-size:small;color:rgb(0,0,0)" class=3D"gmail_default">NOINPUT as s=
pecified here <a href=3D"https://github.com/ajtowns/bips/blob/bip-anyprevou=
t/bip-anyprevout.mediawiki">https://github.com/ajtowns/bips/blob/bip-anypre=
vout/bip-anyprevout.mediawiki</a> (is this the latest?) isn&#39;t a great s=
urrogate for CTV because CTV commits to the input index which prevents half=
-spend. This also encumbers, as proposed, an additional chaperone signature=
 to fix it to a specific output.</div><div style=3D"font-family:arial,helve=
tica,sans-serif;font-size:small;color:rgb(0,0,0)" class=3D"gmail_default"><=
br></div><div style=3D"font-family:arial,helvetica,sans-serif;font-size:sma=
ll;color:rgb(0,0,0)" class=3D"gmail_default">This adds a lot of complexity =
and space to using CTV. Maybe NOINPUT could make changes to special-case CT=
V, but then we&#39;re back to CTV again.</div><br></div><div>=C2=A0</div><b=
lockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-le=
ft:1px solid rgb(204,204,204);padding-left:1ex">
<br>
The justification given for committing to the number of inputs and outputs =
is<br>
that &quot;it makes CTV hashes easier to compute with script&quot;, however=
 doing so would<br>
require OP_CAT. It&#39;s noted that both of these are actually redundant<br=
>
commitments. Since the constexpr requirement was removed, if OP_CAT were<br=
>
enabled, this commitment to the input index could be evaded by computing th=
e CTV<br>
hash within the script, modifying the input index using data taken from the=
<br>
witness. Therefore committing to the input index is a sender-specified-poli=
cy<br>
choice, and not an anti-footgun measure for the redeemer. As such, it&#39;s=
<br>
appropriate to consider committing to the input index using a flag instead.=
<br>
<br></blockquote><div><div style=3D"font-family:arial,helvetica,sans-serif;=
font-size:small;color:rgb(0,0,0)" class=3D"gmail_default">This is incorrect=
 almost entirely.</div><div style=3D"font-family:arial,helvetica,sans-serif=
;font-size:small;color:rgb(0,0,0)" class=3D"gmail_default"><br></div><div s=
tyle=3D"font-family:arial,helvetica,sans-serif;font-size:small;color:rgb(0,=
0,0)" class=3D"gmail_default">1. There is a semantic difference between the=
 *commitment* being strictly redundant, which has more to do with malleatio=
n, and being redundant from a feature perspective. I could maybe do a bette=
r job here of expanding what &quot;easier&quot; means here -- there are act=
ually some scripts which are quite difficult to write/impossible without th=
is. I&#39;ve described this a couple places outside of the BIP, but essenti=
ally it allows you to pin the number of inputs/outputs separately from the =
hashes themselves. So if you&#39;re trying to build the template in script,=
 you might want to allow the Sequences to be set to any value, and pass the=
m via a hash. But then from a hash you can&#39;t check the validity of the =
length. An external length commitment lets you do this, but without it you =
would have to pass in the sequences directly.</div><div style=3D"font-famil=
y:arial,helvetica,sans-serif;font-size:small;color:rgb(0,0,0)" class=3D"gma=
il_default">2. The constexpr requirement was implemented in a soft-fork re-=
moveable manner specifically so that if we wanted OP_CAT, we could add it w=
ithout also introducing constructing CTVs on the stack. Similarly, it would=
 be possible to specify with OP_CAT as a soft-fork removeable rule that if =
OP_CAT executes before an OP_CTV, the script is invalid. The constexpr rule=
 was removed on the sentiment that if we introduce OP_CAT, we almost surely=
 intend to introduce it for OP_CTV (or related) use cases.</div><div style=
=3D"font-family:arial,helvetica,sans-serif;font-size:small;color:rgb(0,0,0)=
" class=3D"gmail_default">3. Committing to the input-index is not a *sender=
* policy choice. It&#39;s a receiver policy choice. I tell a Payer my invoi=
ce/address, and they emit a transaction matching it. From an address contai=
ning a CTV, I as the receiver set the input_index. I don&#39;t see how this=
 is related to the anti-footgun-ness<br></div><div style=3D"font-family:ari=
al,helvetica,sans-serif;font-size:small;color:rgb(0,0,0)" class=3D"gmail_de=
fault">4. You write as if OP_CTV + OP_CAT allows the input index to strippe=
d *unconditionally*. That&#39;s wrong. It&#39;s an opt in if you write a sc=
ript taking it as a parameter. You can&#39;t evade it in general use.</div>=
<div style=3D"font-family:arial,helvetica,sans-serif;font-size:small;color:=
rgb(0,0,0)" class=3D"gmail_default">5. The &quot;anti-footgun&quot; measure=
 is that it precludes reused-keys being spent in the same transaction. Were=
 you to opt out of the mechanism (via OP_CAT input_index), then you opt out=
 of the reuse protection. (This only matters if there is more than one inpu=
t to begin with).</div><div style=3D"font-family:arial,helvetica,sans-serif=
;font-size:small;color:rgb(0,0,0)" class=3D"gmail_default">6. Committing to=
 it via a flag is strictly less flexible, because I can do a lot more with =
OP_CAT than with a flag. For instance, I can do &lt;input_index&gt; &lt;min=
&gt; &lt;max&gt; OP_WITHIN OP_VERIFY to ensure that it falls within a certa=
in range of inputs.</div><div style=3D"font-family:arial,helvetica,sans-ser=
if;font-size:small;color:rgb(0,0,0)" class=3D"gmail_default">7. A flag is a=
lso an extra byte somewhere or uses a sighash bit.<br></div><div style=3D"f=
ont-family:arial,helvetica,sans-serif;font-size:small;color:rgb(0,0,0)" cla=
ss=3D"gmail_default">8. Enabling a flag right away enables a big footgun ri=
ght off the bat. I think it&#39;s bad for use safety.</div><div style=3D"fo=
nt-family:arial,helvetica,sans-serif;font-size:small;color:rgb(0,0,0)" clas=
s=3D"gmail_default">9. Rather than add flags, if you wanted to add this, I =
would suggest reserving max input_index to specify a don&#39;t care value. =
Then you always check a given CTV against the don&#39;t care value and the =
specified value. Hashing the don&#39;t care value can be done in the PreCom=
putedTxData. But I don&#39;t think it&#39;s worth special casing or making =
available today because of 8.</div><div style=3D"font-family:arial,helvetic=
a,sans-serif;font-size:small;color:rgb(0,0,0)" class=3D"gmail_default"><br>=
</div><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0=
px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
There are probably reasons this might not work as a flag that I haven&#39;t=
<br>
discovered yet. Alternatively CTV might be considered to be an alternative =
type<br>
of CHECKSIG operator and might be renamed to CHECKSIGHASH, appending flag b=
ytes<br>
to the hash to be checked.<br></blockquote><div><br></div><div><div style=
=3D"font-family:arial,helvetica,sans-serif;font-size:small;color:rgb(0,0,0)=
" class=3D"gmail_default">Sure -- happy to go down the renaming path again.=
 Keep in mind that CTV currently only applies rules when the argument is 32=
-bytes. Future soft-forkers are welcome to define a rule for a 33byte 1st a=
rgument that treats it as a pubkey and has CHECKSIG semantics, and looks fo=
r another argument.<br></div><br></div><div>=C2=A0</div><blockquote class=
=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rg=
b(204,204,204);padding-left:1ex">
<br>
The flags discussed above, NOINPUT, NOSIG, INPUTINDEX are all really<br>
sender-policy choices, while SIGHASH flags are redeemer-choice as they usua=
lly<br>
occur in the witness. There&#39;s really no way currently for an output to =
specify<br>
that the redeemer must use a particular set of flags. One way to achieve th=
is is<br>
to put the CHECKSIG(HASH) including its flags into the redeemScript -- whic=
h is<br>
functionally what CTV does (or a CHECKSIG in a redeemScript using NOINPUT).=
<br>
This is committed to in outputs and therefore specifies sender policies, ho=
wever<br>
the redeemScript is specified by the receiver.=C2=A0 Perhaps an anti-footgu=
n measure<br>
would be to require that certain SIGHASH flags like these MUST be committed=
 to<br>
in the output, by the sender.<br>
<br></blockquote><div><br></div><div><div style=3D"font-family:arial,helvet=
ica,sans-serif;font-size:small;color:rgb(0,0,0)" class=3D"gmail_default">I =
think this &quot;sender/redeemer&quot; framework is a bit bunk. Ultimately =
all redeemers are senders, and you aren&#39;t forcing a choice on someone. =
You could be on to something though, but I think in general Bitcoin has gon=
e the way of opaque addresses so that people can&#39;t encumber arbitrary p=
olicies on your coins. Maybe it swings the other way...</div><br></div><div=
>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px =
0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
CSV (CHECKSEQUENCEVERIFY) is an example that redemption policies are commit=
ted<br>
to in the output by the sender via the sequence_no field, and then checked =
with<br>
an opcode OP_CSV to enable relative timelocks. It&#39;s probably possible t=
o add new<br>
flags to the sequence_no field, and check the new semantics with CSV instea=
d of<br>
an entiely new opcode.<br></blockquote><div><br></div><div><br></div><div s=
tyle=3D"font-family:arial,helvetica,sans-serif;font-size:small;color:rgb(0,=
0,0)" class=3D"gmail_default">The sender commits to them, but legally, if y=
ou add a contract that I didn&#39;t agree to as receipt (e.g., in segwit ad=
dress -- which the script is hashed) I won&#39;t even know I got paid. So t=
he way Bitcoin works today, these are receiver set policies.</div><div styl=
e=3D"font-family:arial,helvetica,sans-serif;font-size:small;color:rgb(0,0,0=
)" class=3D"gmail_default"><br></div><div style=3D"font-family:arial,helvet=
ica,sans-serif;font-size:small;color:rgb(0,0,0)" class=3D"gmail_default">On=
e way to think of CTV is it&#39;s precise the opcode that lets you &quot;wr=
ap&quot; someone&#39;s known address in arbitrary new scripts. E.g., if you=
 gave me an address X, but I need to (for whatever reason) add an additiona=
l 1 month CSV.</div><div style=3D"font-family:arial,helvetica,sans-serif;fo=
nt-size:small;color:rgb(0,0,0)" class=3D"gmail_default"><br></div><div styl=
e=3D"font-family:arial,helvetica,sans-serif;font-size:small;color:rgb(0,0,0=
)" class=3D"gmail_default">So i just get the txn:</div><div style=3D"font-f=
amily:arial,helvetica,sans-serif;font-size:small;color:rgb(0,0,0)" class=3D=
"gmail_default"><br></div><div style=3D"font-family:arial,helvetica,sans-se=
rif;font-size:small;color:rgb(0,0,0)" class=3D"gmail_default">A:</div><div =
style=3D"font-family:arial,helvetica,sans-serif;font-size:small;color:rgb(0=
,0,0)" class=3D"gmail_default">=C2=A0=C2=A0=C2=A0 sequence 1mo<br></div><di=
v style=3D"font-family:arial,helvetica,sans-serif;font-size:small;color:rgb=
(0,0,0)" class=3D"gmail_default">=C2=A0=C2=A0=C2=A0 1 input</div><div style=
=3D"font-family:arial,helvetica,sans-serif;font-size:small;color:rgb(0,0,0)=
" class=3D"gmail_default">=C2=A0=C2=A0=C2=A0 1 output: pay X 1 coin</div><d=
iv style=3D"font-family:arial,helvetica,sans-serif;font-size:small;color:rg=
b(0,0,0)" class=3D"gmail_default"><br></div><div style=3D"font-family:arial=
,helvetica,sans-serif;font-size:small;color:rgb(0,0,0)" class=3D"gmail_defa=
ult">then take the STH(A), and create B</div><div style=3D"font-family:aria=
l,helvetica,sans-serif;font-size:small;color:rgb(0,0,0)" class=3D"gmail_def=
ault"><br></div><div style=3D"font-family:arial,helvetica,sans-serif;font-s=
ize:small;color:rgb(0,0,0)" class=3D"gmail_default"><br></div><div style=3D=
"font-family:arial,helvetica,sans-serif;font-size:small;color:rgb(0,0,0)" c=
lass=3D"gmail_default">B:</div><div style=3D"font-family:arial,helvetica,sa=
ns-serif;font-size:small;color:rgb(0,0,0)" class=3D"gmail_default">=C2=A0=
=C2=A0=C2=A0 ... inputs</div><div style=3D"font-family:arial,helvetica,sans=
-serif;font-size:small;color:rgb(0,0,0)" class=3D"gmail_default">=C2=A0=C2=
=A0=C2=A0 1 output pay `STH(A) CTV` 1 coin<br></div><div><br></div><div><di=
v style=3D"font-family:arial,helvetica,sans-serif;font-size:small;color:rgb=
(0,0,0)" class=3D"gmail_default">I can also add other things, like secondar=
y signers/alternatives</div><br></div><div><div style=3D"font-family:arial,=
helvetica,sans-serif;font-size:small;color:rgb(0,0,0)" class=3D"gmail_defau=
lt">`IF {some checksig program} STH(A) CTV ELSE {multisig program} ENDIF<br=
></div><br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=
=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding=
-left:1ex">
As user policy choices, NOINPUT might be considered &quot;MAY&quot; conditi=
ons. A user MAY<br>
use NOINPUT on an output, but let&#39;s not require it.=C2=A0 Covenants on =
the other<br>
hand, are a MUST condition. The CTV proposal imposes &quot;MUST&quot; condi=
tions on the<br>
existence of the covenant itself, as well as the number of inputs and outpu=
ts,<br>
to prevent txid malleability so that such transactions can be used in offli=
ne<br>
protocols. Txid non-malleability can be achieved by enforcing that the outp=
ut<br>
must be spent using SIGHASH_ALL instead of committing to the number of inpu=
ts<br>
separately with a new opcode. The MUST condition also helps with sighash ca=
ching<br>
for batch validation.<br></blockquote><div><br></div><div><div style=3D"fon=
t-family:arial,helvetica,sans-serif;font-size:small;color:rgb(0,0,0)" class=
=3D"gmail_default">ANYPREVOUT/ANYSCRIPT are actually weirder than that, bec=
ause once it has been used that key is permanently &quot;burned&quot;. Henc=
e ANYPREVOUT has such pubkeys be explicity tagged as ANYPREVOUT compatible.=
 So a user kind of has to pre-decide if they want to have ANYPREVOUT semant=
ics or not.</div><div style=3D"font-family:arial,helvetica,sans-serif;font-=
size:small;color:rgb(0,0,0)" class=3D"gmail_default">And in this case, key-=
reuse is relatively unsafe (as you need to track what else you&#39;ve signe=
d) so I think what you&#39;re suggesting is not robust.</div><div style=3D"=
font-family:arial,helvetica,sans-serif;font-size:small;color:rgb(0,0,0)" cl=
ass=3D"gmail_default"><br></div><div style=3D"font-family:arial,helvetica,s=
ans-serif;font-size:small;color:rgb(0,0,0)" class=3D"gmail_default">These &=
quot;MUST&quot; conditions sound nice, but they don&#39;t actually help wit=
h validity caching because we want to be able to compute this information b=
efore we&#39;ve fetched the outputs from the database so we can&#39;t know =
what to cache yet. Contextless things are things you can precompute not kno=
wing input scripts.<br></div><div style=3D"font-family:arial,helvetica,sans=
-serif;font-size:small;color:rgb(0,0,0)" class=3D"gmail_default"><br></div>=
<div style=3D"font-family:arial,helvetica,sans-serif;font-size:small;color:=
rgb(0,0,0)" class=3D"gmail_default">Again, I don&#39;t think this sender/re=
deemer framework is super useful but I admire the attempt.</div><br></div><=
div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0=
px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
INPUTINDEX is required in a CTV/CHECKSIGHASH world because of the half-spen=
d<br>
problem. Normally outputs are spent uniquely as long as different addresses=
 are<br>
used on the outputs. A transaction with the same address appearing twice wo=
uld<br>
also have a half-spend problem. Anyone signing the first output and giving =
that<br>
PSBT to another person can allow them to spend the second input. Therefore =
one<br>
might even want INPUTINDEX for non-covenant transactions, though making a t=
x<br>
with the same address twice seems like a silly idea to me.<br></blockquote>=
<div><br></div><div style=3D"font-family:arial,helvetica,sans-serif;font-si=
ze:small;color:rgb(0,0,0)" class=3D"gmail_default">I&#39;m confused. Transa=
ctions don&#39;t have addresses. What are you talking about?</div><div styl=
e=3D"font-family:arial,helvetica,sans-serif;font-size:small;color:rgb(0,0,0=
)" class=3D"gmail_default"><br></div><div style=3D"font-family:arial,helvet=
ica,sans-serif;font-size:small;color:rgb(0,0,0)" class=3D"gmail_default">In=
put indexes accomplish two goals.</div><div style=3D"font-family:arial,helv=
etica,sans-serif;font-size:small;color:rgb(0,0,0)" class=3D"gmail_default">=
<br></div><div style=3D"font-family:arial,helvetica,sans-serif;font-size:sm=
all;color:rgb(0,0,0)" class=3D"gmail_default">One, they eliminate third-par=
ty malleability of input order (which would muck with sighash singles too).=
<br></div><div style=3D"font-family:arial,helvetica,sans-serif;font-size:sm=
all;color:rgb(0,0,0)" class=3D"gmail_default">Two, they prevent half-spend.=
<br></div><div style=3D"font-family:arial,helvetica,sans-serif;font-size:sm=
all;color:rgb(0,0,0)" class=3D"gmail_default"><br></div><div style=3D"font-=
family:arial,helvetica,sans-serif;font-size:small;color:rgb(0,0,0)" class=
=3D"gmail_default">Signatures today commit to this in the signature hash (t=
he field is nIn, which is confusing because nIn might also look like vin.si=
ze()).</div><div style=3D"font-family:arial,helvetica,sans-serif;font-size:=
small;color:rgb(0,0,0)" class=3D"gmail_default"><br></div><div style=3D"fon=
t-family:arial,helvetica,sans-serif;font-size:small;color:rgb(0,0,0)" class=
=3D"gmail_default">So the half spend problem doesn&#39;t exist today...<br>=
</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;b=
order-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
Therefore, assuming a CSV-type mechanism can be devised using sequence_no, =
CTV<br>
is equivalent to a flag in sequence_no that is logically<br>
MUST|ALL|NOSIG|INPUTINDEX and a redeemScript of &lt;hash&gt; &lt;flags&gt;.=
<br>
<br>
Lightning-like use cases might put sequence_no flags that are logically<br>
MAY|ALL|NOINPUT.<br>
<br>
The other mechanism for sender policy is scriptPubKey, which is heavily<br>
restricted by isStandard, but might be another place to specify flags like =
the<br>
above.<br>
<br>
Thoughts? <br>
<br></blockquote><div><br></div><div><br></div><div><div style=3D"font-fami=
ly:arial,helvetica,sans-serif;font-size:small;color:rgb(0,0,0)" class=3D"gm=
ail_default">So OP_CAT already lets you do this kind of stuff with the SIGH=
ASHes rather than a new special-purpose verifier. Just pass the signature s=
eparately from the flags, and cat them togehther for the checker but just l=
ook at the flags for your new thing. Then check that the flags are exactly =
what you wanted. If you don&#39;t want OP_CAT, you can also add OP_SUBSTRVE=
RIFY wherein you verify that a provided substr was inside another string. T=
hen you pass in the witness the full string you want, as well as sub-bits y=
ou want to check properties on (like the flags).</div><div style=3D"font-fa=
mily:arial,helvetica,sans-serif;font-size:small;color:rgb(0,0,0)" class=3D"=
gmail_default"><br></div><div style=3D"font-family:arial,helvetica,sans-ser=
if;font-size:small;color:rgb(0,0,0)" class=3D"gmail_default">It&#39;s not c=
lear to me that we want this kind of stuff though. OP_CAT requires very car=
eful review because it has very surprising functional consequences across t=
he board.<br></div><br></div><div>=C2=A0</div><blockquote class=3D"gmail_qu=
ote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,20=
4);padding-left:1ex">
Does this idea address any of the NOINPUT footguns? (which I&#39;m not up o=
n) <br>
Is there a reason this cannot be done with sequence_no and OP_CSV?<br></blo=
ckquote><div><br></div><div><div style=3D"font-family:arial,helvetica,sans-=
serif;font-size:small;color:rgb(0,0,0)" class=3D"gmail_default">ANYPREVOUT =
already precludes these by using a separate key type and chaperone signatur=
es.=C2=A0 I think a flag for MUST NOT ANYPREVOUT would maybe help with maki=
ng it safer. But this is a complete sidebar from CTV. This exists already b=
y generating a non-anyprevout capable key though...</div><br></div><div>=C2=
=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8e=
x;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Is there a reason that a separate opcode (CTV) is different/better than thi=
s<br>
approach?<br>
<br></blockquote><div><div style=3D"font-family:arial,helvetica,sans-serif;=
font-size:small;color:rgb(0,0,0)" class=3D"gmail_default"><br></div><div st=
yle=3D"font-family:arial,helvetica,sans-serif;font-size:small;color:rgb(0,0=
,0)" class=3D"gmail_default">I&#39;ll let the email above serve as the answ=
er to your question.</div><div style=3D"font-family:arial,helvetica,sans-se=
rif;font-size:small;color:rgb(0,0,0)" class=3D"gmail_default"><br></div><di=
v style=3D"font-family:arial,helvetica,sans-serif;font-size:small;color:rgb=
(0,0,0)" class=3D"gmail_default">I don&#39;t think there&#39;s anything gai=
ned by expressing CTV as a sighash type today, especially since a future so=
ft fork (when we&#39;ve taking the time to deeply rethink sighash flags, li=
ke bitmask sighash flags proposed for elements) can make CTV (as specified =
today) a valid hash in this new language and use the OP_NOP4 with a non 32-=
byte argument as the new CheckSig operator anyways.</div><div style=3D"font=
-family:arial,helvetica,sans-serif;font-size:small;color:rgb(0,0,0)" class=
=3D"gmail_default"><br></div><div style=3D"font-family:arial,helvetica,sans=
-serif;font-size:small;color:rgb(0,0,0)" class=3D"gmail_default"><br></div>=
<div style=3D"font-family:arial,helvetica,sans-serif;font-size:small;color:=
rgb(0,0,0)" class=3D"gmail_default"><br></div><div style=3D"font-family:ari=
al,helvetica,sans-serif;font-size:small;color:rgb(0,0,0)" class=3D"gmail_de=
fault"><br></div><div style=3D"font-family:arial,helvetica,sans-serif;font-=
size:small;color:rgb(0,0,0)" class=3D"gmail_default"><br></div><div style=
=3D"font-family:arial,helvetica,sans-serif;font-size:small;color:rgb(0,0,0)=
" class=3D"gmail_default"><br></div><div style=3D"font-family:arial,helveti=
ca,sans-serif;font-size:small;color:rgb(0,0,0)" class=3D"gmail_default"><br=
></div><div style=3D"font-family:arial,helvetica,sans-serif;font-size:small=
;color:rgb(0,0,0)" class=3D"gmail_default">But now I&#39;ll pose a differen=
t question: why shouldn&#39;t we compute the sighash entirely as a type of =
Bitcoin Script? SIGHASH_FLAGS are essentially a tiny, crappy, language for =
putting together a message digest. You can think of SIGHASH_FLAGS as being =
like optimized &quot;jets&quot; for known programs. For custom programs, yo=
u can construct the digest pattern you want in script. This is essentially =
what the bitmask sighash flags proposal is. I think you&#39;re going to was=
te a lot of mental-cycles trying to cram in all this logic into flags. As t=
his stuff gets more complicated, you should just write an actual language f=
or dealing with sighashes and go from there.</div><div style=3D"font-family=
:arial,helvetica,sans-serif;font-size:small;color:rgb(0,0,0)" class=3D"gmai=
l_default"><br></div><div style=3D"font-family:arial,helvetica,sans-serif;f=
ont-size:small;color:rgb(0,0,0)" class=3D"gmail_default">Now why don&#39;t =
we want this sighash language? Quadratic hashing. If every output commits t=
o some different complex thing, we end up doing a lot of rehashing. Flags a=
re actually kind of bad because a few different flags can trigger a lot of =
rehashing. But the way flags are *today* is relatively OK because we can ca=
che the important parts so validation is cheap.</div><div style=3D"font-fam=
ily:arial,helvetica,sans-serif;font-size:small;color:rgb(0,0,0)" class=3D"g=
mail_default"><br></div><div style=3D"font-family:arial,helvetica,sans-seri=
f;font-size:small;color:rgb(0,0,0)" class=3D"gmail_default">The more compli=
cated you plan gets, the less context free validation we can do.</div><div =
style=3D"font-family:arial,helvetica,sans-serif;font-size:small;color:rgb(0=
,0,0)" class=3D"gmail_default"><br></div><div style=3D"font-family:arial,he=
lvetica,sans-serif;font-size:small;color:rgb(0,0,0)" class=3D"gmail_default=
">CTV is fully compatible with context free validation optimizations, trivi=
ally. It&#39;s not clear if your other stuff is, I suspect not.<br></div></=
div></div></div>

--000000000000b2563f059da79a3b--