11import * as bcrypto from '../crypto' ;
22import { bitcoin as BITCOIN_NETWORK } from '../networks' ;
33import * as bscript from '../script' ;
4- import { Payment , PaymentOpts , StackFunction } from './index' ;
4+ import { Payment , PaymentOpts , StackElement , StackFunction } from './index' ;
55import * as lazy from './lazy' ;
66const typef = require ( 'typeforce' ) ;
77const OPS = bscript . OPS ;
8+ const ecc = require ( 'tiny-secp256k1' ) ;
89
910const bech32 = require ( 'bech32' ) ;
1011
@@ -18,6 +19,15 @@ function stacksEqual(a: Buffer[], b: Buffer[]): boolean {
1819 } ) ;
1920}
2021
22+ function chunkHasUncompressedPubkey ( chunk : StackElement ) : boolean {
23+ if ( Buffer . isBuffer ( chunk ) && chunk . length === 65 ) {
24+ if ( ecc . isPoint ( chunk ) ) return true ;
25+ else return false ;
26+ } else {
27+ return false ;
28+ }
29+ }
30+
2131// input: <>
2232// witness: [redeemScriptSig ...] {redeemScript}
2333// output: OP_0 {sha256(redeemScript)}
@@ -59,6 +69,9 @@ export function p2wsh(a: Payment, opts?: PaymentOpts): Payment {
5969 const _rchunks = lazy . value ( ( ) => {
6070 return bscript . decompile ( a . redeem ! . input ! ) ;
6171 } ) as StackFunction ;
72+ const _rochunks = lazy . value ( ( ) => {
73+ return bscript . decompile ( a . redeem ! . output ! ) ;
74+ } ) as StackFunction ;
6275
6376 let network = a . network ;
6477 if ( ! network ) {
@@ -187,15 +200,25 @@ export function p2wsh(a: Payment, opts?: PaymentOpts): Payment {
187200 ! stacksEqual ( a . witness , a . redeem . witness )
188201 )
189202 throw new TypeError ( 'Witness and redeem.witness mismatch' ) ;
203+ if (
204+ ( a . redeem . input && _rchunks ( ) . some ( chunkHasUncompressedPubkey ) ) ||
205+ ( a . redeem . output && _rochunks ( ) . some ( chunkHasUncompressedPubkey ) )
206+ ) {
207+ throw new TypeError (
208+ 'redeem.input or redeem.output contains uncompressed pubkey' ,
209+ ) ;
210+ }
190211 }
191212
192- if ( a . witness ) {
213+ if ( a . witness && a . witness . length > 0 ) {
214+ const wScript = a . witness [ a . witness . length - 1 ] ;
215+ if ( a . redeem && a . redeem . output && ! a . redeem . output . equals ( wScript ) )
216+ throw new TypeError ( 'Witness and redeem.output mismatch' ) ;
193217 if (
194- a . redeem &&
195- a . redeem . output &&
196- ! a . redeem . output . equals ( a . witness [ a . witness . length - 1 ] )
218+ a . witness . some ( chunkHasUncompressedPubkey ) ||
219+ ( bscript . decompile ( wScript ) || [ ] ) . some ( chunkHasUncompressedPubkey )
197220 )
198- throw new TypeError ( 'Witness and redeem.output mismatch ' ) ;
221+ throw new TypeError ( 'Witness contains uncompressed pubkey ' ) ;
199222 }
200223 }
201224
0 commit comments