Compare commits

...

1154 Commits
gg ... master

Author SHA1 Message Date
reflecttypefor
764f75e338
script: check link format in nested mediawiki files (#2199)
* script: check link format in nested mediawiki files

Signed-off-by: reflecttypefor <reflecttypefor@outlook.com>
2026-06-26 12:25:30 -07:00
Jon Atack
b9883fbb4b
Merge pull request #2196 from fjahr/bip-t5-draft
Some checks failed
GitHub Actions Check / Diff Checks (fails until number assignment) (push) Has been cancelled
GitHub Actions Check / Typo Checks (push) Has been cancelled
GitHub Actions Check / Link-Format-Checks (push) Has been cancelled
GitHub Actions Check / Build-Table-Checks (push) Has been cancelled
BIP95: Testnet 5
2026-06-25 14:40:45 -07:00
Fabian Jahr
c134c7db55
BIP95: Testnet 5 2026-06-25 23:30:46 +02:00
Jon Atack
861e235e93
Merge pull request #2165 from murchandamus/bip52-closed
Some checks failed
GitHub Actions Check / Link-Format-Checks (push) Has been cancelled
GitHub Actions Check / Build-Table-Checks (push) Has been cancelled
GitHub Actions Check / Diff Checks (fails until number assignment) (push) Has been cancelled
GitHub Actions Check / Typo Checks (push) Has been cancelled
bip52: Update to Closed
2026-06-19 12:13:55 -07:00
Murch
4894bcc4eb
bip52: Update to Closed
This proposal appears abandoned, as it has not had any updates in over
four years, and cursory search did not produce any public discussions of
it since it was published either. Attempts to contact the authors did
not receive a response within four weeks.
2026-06-18 21:11:57 -07:00
conduition
6740c533e8
bip360: depth-zero script trees should be anyone-can-spend (#2198)
Some checks are pending
GitHub Actions Check / Link-Format-Checks (push) Waiting to run
GitHub Actions Check / Build-Table-Checks (push) Waiting to run
GitHub Actions Check / Diff Checks (fails until number assignment) (push) Waiting to run
GitHub Actions Check / Typo Checks (push) Waiting to run
* bip360: depth zero trees should be anyone-can-spend

* bip360: update changelog and bump version to 0.12.0
2026-06-18 18:14:23 -07:00
Jon Atack
40cd7b4dd6
Merge pull request #2197 from ajtowns/202606-434-complete
Some checks failed
GitHub Actions Check / Link-Format-Checks (push) Has been cancelled
GitHub Actions Check / Build-Table-Checks (push) Has been cancelled
GitHub Actions Check / Diff Checks (fails until number assignment) (push) Has been cancelled
GitHub Actions Check / Typo Checks (push) Has been cancelled
BIP-434: Add ref impl, mark complete / CI: add version check
2026-06-11 07:11:18 -07:00
Anthony Towns
50eaa0d730 process: Check for pre-1.0 versions in complete/deployed bips 2026-06-11 23:55:42 +10:00
Anthony Towns
b14d7c34e5 BIP-434: Add reference implementation, bump to 1.0.0, mark complete 2026-06-11 23:47:57 +10:00
Jon Atack
4f17dbfa27
script: update Typos section in CONTRIBUTING.md (#2193)
Some checks failed
GitHub Actions Check / Build-Table-Checks (push) Has been cancelled
GitHub Actions Check / Diff Checks (fails until number assignment) (push) Has been cancelled
GitHub Actions Check / Typo Checks (push) Has been cancelled
GitHub Actions Check / Link-Format-Checks (push) Has been cancelled
2026-06-08 18:22:17 -07:00
Jon Atack
2125990370
Merge pull request #2189 from jonatack/2026-06-update-typos-exclusions
Update typos exclusions
2026-06-08 10:54:39 -07:00
Jon Atack
c6c1559b3f
Merge pull request #2186 from DanGould/dangould/bip77-issue-1487-v1-fallback
BIP 77: Specify v1-fallback response mechanism
2026-06-08 10:47:26 -07:00
DanGould
9997e00576
BIP 77: Specify v1-fallback response mechanism
The receiver-to-sender response section presented HPKE encryption and
POST as the only path, when v2 receivers servicing v1 (BIP 78) senders
in the wild send the cleartext base64 PSBT via PUT to their own mailbox.
Add a forward-reference from the v2 path to Backwards compatibility,
and specify the v1-fallback response (no HPKE; PUT method; UTF-8 body;
receiver's own mailbox as target) normatively in that section.

Addresses payjoin/rust-payjoin#1487. Partially addresses
payjoin/rust-payjoin#844 (PUT/POST gap).
2026-06-09 00:52:41 +08:00
Jon Atack
2ffcd9a4a1
Merge pull request #2190 from guggero/bip322-version-fix
Some checks failed
GitHub Actions Check / Link-Format-Checks (push) Has been cancelled
GitHub Actions Check / Build-Table-Checks (push) Has been cancelled
GitHub Actions Check / Diff Checks (fails until number assignment) (push) Has been cancelled
GitHub Actions Check / Typo Checks (push) Has been cancelled
BIP-0322: use MAJOR version for address optionality
2026-06-05 08:11:26 -07:00
Oli
4061a54418
BIP-0322: use MAJOR version for address optionality
Addresses a review comment in #2188:
https://github.com/bitcoin/bips/pull/2188#issuecomment-4623250085
2026-06-05 08:32:18 +02:00
Jon Atack
c81d4236f3
Merge pull request #2188 from guggero/bip322-fix
Some checks are pending
GitHub Actions Check / Link-Format-Checks (push) Waiting to run
GitHub Actions Check / Build-Table-Checks (push) Waiting to run
GitHub Actions Check / Diff Checks (fails until number assignment) (push) Waiting to run
GitHub Actions Check / Typo Checks (push) Waiting to run
BIP-0322: remove address optionality for PoF
2026-06-04 07:42:12 -07:00
Oli
e94e3c5698
BIP-0322: clarify sequence semantics for Proof of Funds
This commit clarifies that even for Proof of Funds signatures the
sequence of the first input is considered as "age S".
The reasoning behind this is that only the first input is a synthetic
one that doesn't reference a real transaction to which the height could
be compared against. Even though the Proof of Funds inputs could have
higher sequence values, those heights might have already been long
reached and would make the sequence values irrelevant compared to the potential
restrictions in the challenge script.
2026-06-04 10:54:11 +02:00
Oli
2923854e7a
BIP-0322: remove address optionality for PoF
This is cleaning up an artifact that was left over from #1352.
The alternative to removing the optionality of the address
would be to assume OP_TRUE in case of an empty address.
But that sounds like it could open up any number of potential
vulnerabilities.
And a user still has the ability to use an OP_TRUE script
in a p2wsh or p2tr address.
2026-06-04 10:54:11 +02:00
Jon Atack
291ba6803a Update typos exclusions 2026-06-03 09:33:53 -06:00
Shinobi
b69b8fef21
bip343: change status from deployed to closed (#2187)
Some checks failed
GitHub Actions Check / Link-Format-Checks (push) Has been cancelled
GitHub Actions Check / Build-Table-Checks (push) Has been cancelled
GitHub Actions Check / Diff Checks (fails until number assignment) (push) Has been cancelled
GitHub Actions Check / Typo Checks (push) Has been cancelled
* Update bip-0343.mediawiki

As a co-author I would like to move this BIP's status to Closed due to its current irrelevance and lack of any known deployments on the network. 

If I could I would delete it fully, or better yet go back in time to prevent it from being written.

* bip343: Fix table entry for move to Closed

* bip343: Record Close reason

---------

Co-authored-by: Murch <murch@murch.one>
2026-06-01 17:56:45 -07:00
Jon Atack
42dc3270db
Merge pull request #2168 from stevenroose/complete-127
Some checks are pending
GitHub Actions Check / Link-Format-Checks (push) Waiting to run
GitHub Actions Check / Build-Table-Checks (push) Waiting to run
GitHub Actions Check / Diff Checks (fails until number assignment) (push) Waiting to run
GitHub Actions Check / Typo Checks (push) Waiting to run
BIP-0127: Prune some unfinished part and mark complete
2026-06-01 13:31:48 -07:00
Jon Atack
d58e12ae83
Merge pull request #2160 from omipheo/bip-0352-class-method-annotations
BIP352: complete type annotations on bitcoin_utils class methods
2026-06-01 13:11:40 -07:00
Jon Atack
e85e7ff2a7
Merge pull request #2185 from theStack/bip352-update-headers
Some checks are pending
GitHub Actions Check / Link-Format-Checks (push) Waiting to run
GitHub Actions Check / Build-Table-Checks (push) Waiting to run
GitHub Actions Check / Diff Checks (fails until number assignment) (push) Waiting to run
GitHub Actions Check / Typo Checks (push) Waiting to run
BIP-352: sync "Version" header, add "Requires" header
2026-05-31 08:45:50 -07:00
Sebastian Falbesoner
46e7339e9c BIP-352: update "Version" header, add "Requires" header 2026-05-31 13:19:21 +02:00
Jon Atack
1495b684ff
Merge pull request #2183 from evanlinjin/fix/174-explicitly-mention-proprietary-fields-as-unknown
Some checks failed
GitHub Actions Check / Link-Format-Checks (push) Has been cancelled
GitHub Actions Check / Build-Table-Checks (push) Has been cancelled
GitHub Actions Check / Diff Checks (fails until number assignment) (push) Has been cancelled
GitHub Actions Check / Typo Checks (push) Has been cancelled
2026-05-30 03:22:40 -07:00
志宇
a4668bb203
BIP174: Clarify proprietary fields are retained on finalization
Note that the Input Finalizer retains PSBT_IN_PROPRIETARY fields it does
not understand, treating them like unknown fields so it does not clear
proprietary data it cannot interpret.
2026-05-30 08:04:11 +00:00
Murch
790c777aeb
Merge pull request #2178 from pythcoiner/bip_68
Some checks are pending
GitHub Actions Check / Link-Format-Checks (push) Waiting to run
GitHub Actions Check / Build-Table-Checks (push) Waiting to run
GitHub Actions Check / Diff Checks (fails until number assignment) (push) Waiting to run
GitHub Actions Check / Typo Checks (push) Waiting to run
BIP68: fix wrong upper bound for nHeight
2026-05-29 16:22:11 -07:00
Murch
fae52468c9
Merge pull request #2182 from evanlinjin/fix/174-input-finalizer-clarification
BIP174: Mention sighash type requirement in Input Finalizer section
2026-05-29 12:00:38 -07:00
Jon Atack
b4241dc504
Merge pull request #2181 from ajtowns/202605-bip434-edits
BIP-434: Various rationale edits
2026-05-29 10:07:18 -07:00
志宇
9633048fc2
BIP174: Mention sighash type requirement in Input Finalizer section
This mirrors the existing PSBT_IN_SIGHASH_TYPE constraint from the
per-input field description. Added to the Input Finalizer section so it
is not missed.
2026-05-29 08:05:19 +00:00
Anthony Towns
18ff6bb77b BIP-434: Various rationale edits 2026-05-29 15:31:11 +10:00
Jon Atack
7f9434c9c8
Merge pull request #2093 from yyhrnk/fix/txfs-index-bounds
Some checks failed
GitHub Actions Check / Link-Format-Checks (push) Has been cancelled
GitHub Actions Check / Build-Table-Checks (push) Has been cancelled
GitHub Actions Check / Diff Checks (fails until number assignment) (push) Has been cancelled
GitHub Actions Check / Typo Checks (push) Has been cancelled
BIP-346: correct TxFieldSelector index upper bound
2026-05-28 12:15:54 -07:00
pythcoiner
6ac8c26870
BIP68: fix wrong upper bound for nHeight 2026-05-28 16:11:57 +02:00
Jeremy Rubin
76d434e5fc
BIP449: OP_TWEAKADD (#1944)
Some checks failed
GitHub Actions Check / Link-Format-Checks (push) Has been cancelled
GitHub Actions Check / Build-Table-Checks (push) Has been cancelled
GitHub Actions Check / Diff Checks (fails until number assignment) (push) Has been cancelled
GitHub Actions Check / Typo Checks (push) Has been cancelled
* BIP: OP_TWEAKADD

* BIP TweakAdd: note on commutativity of tweaking and add test cases

* BIP TweakAdd: Invert Argument Order

* BIP Tweakadd: fix typo & add note on even-y tweaking

* BIP TweakAdd -- add mailing list discussion

* BIP TweakAdd: Add Alpen and MATT mentions

* BIP TweakAdd Formatting Edits

* BIP TWEAKADD remove conventions section

* BIP TWEAKADD formatting fix

* BIP TWEAKADD Move Vectors to end

* BIP TweakAdd: Condense compatibility section

* [BIP-0449] Updates post assignemnt

* [BIP-0449] Normalize Metadata

* Update bip-0449.md Link Text to point to OP of ML Thread
2026-05-23 07:03:53 -07:00
phrwlk
2d12e67b00
BIP-119: use self.stack[-1] in execute_bip_119 (#2043)
Some checks are pending
GitHub Actions Check / Link-Format-Checks (push) Waiting to run
GitHub Actions Check / Build-Table-Checks (push) Waiting to run
GitHub Actions Check / Diff Checks (fails until number assignment) (push) Waiting to run
GitHub Actions Check / Typo Checks (push) Waiting to run
2026-05-22 17:22:38 -07:00
Murch
43a4941b37
Merge pull request #2172 from darosior/2605_bip54_complete
Some checks are pending
GitHub Actions Check / Link-Format-Checks (push) Waiting to run
GitHub Actions Check / Build-Table-Checks (push) Waiting to run
GitHub Actions Check / Diff Checks (fails until number assignment) (push) Waiting to run
GitHub Actions Check / Typo Checks (push) Waiting to run
BIP 54: progress to Complete
2026-05-22 11:20:32 -07:00
Antoine Poinsot
c47655654c bip-0054: move to complete 2026-05-22 13:53:51 -04:00
Antoine Poinsot
809ca9939a bip-0054: link to Bitcoin Core reference implementation rebased on latest version 2026-05-22 13:43:31 -04:00
Jon Atack
5b118aa337
Merge pull request #2171 from murchandamus/bip10-record-withdrawal
Some checks are pending
GitHub Actions Check / Link-Format-Checks (push) Waiting to run
GitHub Actions Check / Build-Table-Checks (push) Waiting to run
GitHub Actions Check / Diff Checks (fails until number assignment) (push) Waiting to run
GitHub Actions Check / Typo Checks (push) Waiting to run
bip10: Record Withdrawal in Changelog
2026-05-21 12:51:38 -07:00
Murch
a766a6e127
Merge pull request #2170 from darosior/bip54_rationale_additions
BIP 54: improve and deduplicate parts of rationale and motivation
2026-05-21 12:06:24 -07:00
Antoine Poinsot
6c61126d74 bip-0054: mention Luke's extranonce concern in rationale 2026-05-21 14:49:48 -04:00
Antoine Poinsot
b75238ffb3 bip-0054: rephrase/dedup motivation and rationale for BIP 34 cleanup
The rationale was duplicating some of the motivation. The motivation had a sentence that read weird.
While rephrasing the sentence, take the opportunity to link to the now-proposed Utreexo BIP. Also
remove a duplicate link reference.
2026-05-21 14:49:40 -04:00
Murch
7571cd4489
bip10: Record Withdrawal in Changelog 2026-05-21 10:54:22 -07:00
Jon Atack
242f7d2605
Merge pull request #2167 from murchandamus/bip1-record-close-reason
bip1: Record close reason
2026-05-21 09:54:12 -07:00
Murch
6d95a22232
bip176: Advance to Complete (#2169) 2026-05-21 08:35:25 -07:00
Murch
fefc5c1925
bip127: Add Changelog 2026-05-21 08:30:35 -07:00
Jon Atack
6a36c4d8b6
Merge pull request #2164 from murchandamus/bip38-deployed
bip38: Advance to Deployed
2026-05-21 08:25:41 -07:00
Steven Roose
ce477589c8
bip-127: Mark complete 2026-05-21 08:00:21 -07:00
Antoine Poinsot
ec24fd371c bip-0054: more correct worst case validation times
The sentence was misleading, with 'lower end devices' potentially applying to the whole range, and the range itself being understated.
2026-05-21 10:56:42 -04:00
Jon Atack
4fb5a8afd0
Merge pull request #2166 from murchandamus/bip78-Deployed
bip78: Advance to Deployed
2026-05-21 07:44:53 -07:00
Steven Roose
7563199c2d bip-127: Remove uncomplete and unused protocol buffers part
This part was never implemented by anyone and it is not complete in the
current state.
2026-05-21 16:27:34 +02:00
Murch
92d5ce5684
bip1: Record close reason
This commit forgoes introducing a version, as the BIP has been closed
for a decade and it is no longer necessary to update the readers
regarding specification changes of BIP1.
2026-05-20 17:41:21 -07:00
Murch
e872e76a3f
bip78: Advance to Deployed
According to the BIP78 itself, there are multiple projects that have
implemented support for this proposal on mainnet:
https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#implementations
2026-05-20 15:49:09 -07:00
Murch
885c7062cd
bip38: Advance to Deployed 2026-05-20 15:00:19 -07:00
Antoine Poinsot
19caed45a1 bip-0054: rephrase Timewarp motivation 2026-05-20 16:43:11 -04:00
Yuri S Villas Boas
d293ae1a10
BIP450: Formosa—Seed Encoding per Themed Mnemonic Stories (#2108)
Some checks failed
GitHub Actions Check / Link-Format-Checks (push) Has been cancelled
GitHub Actions Check / Build-Table-Checks (push) Has been cancelled
GitHub Actions Check / Diff Checks (fails until number assignment) (push) Has been cancelled
GitHub Actions Check / Typo Checks (push) Has been cancelled
* Formosa as BIP

Mnemonic *sentences* instead of words proposed as forwards- and backwards-compatible expansion to BIP39, itself as Bitcoin Improvement Proposal.

* Update bip.mediawiki

Co-authored-by: Mark "Murch" Erhardt <murch@murch.one>

* Update bip.mediawiki

Satisfying requirement of title in fewer than 50 characters.

* Formosa: address PR #2108 review feedback

Restructure the draft to follow BIP-3 conventions and resolve the issues
raised by reviewers in https://github.com/bitcoin/bips/pull/2108:

- Introduce explicit Specification section with a Terminology subsection
  that distinguishes 'word', 'category', 'theme', 'sentence' and
  'mnemonic' / 'mnemonic story', removing the ambiguity of using
  'sentence' at two different scales.
- Replace the unclear 'if the category is led by another category'
  wording with an explicit LED_BY field description and a step-by-step
  algorithm that covers both the leaderless and led cases.
- Reflow the theme-property list (previously a/b/c/d/e split by an
  intervening paragraph) into a single numbered list so it renders as a
  list rather than as code blocks.
- Add a dedicated Rationale section covering the 33-bit sentence size,
  themed sentences, free-form theme schema, the LED_BY mechanism, the
  re-encoding-through-BIP-39 design, and why custom themes are
  discouraged.
- Add a dedicated Backwards Compatibility section describing
  compatibility at the mnemonic, entropy, and seed levels.
- Add a worked Example section showing a 128-bit entropy being encoded
  into a 4-sentence mnemonic story under a small illustrative theme,
  including bit splitting, FILLING_ORDER vs NATURAL_ORDER, and the
  LED_BY lookup.
- Tighten the Abstract and Motivation; clarify that BIP-39 is itself a
  Formosa theme.

* Formosa: spell out abbreviated table labels

Reviewer on PR #2108 asked for no abbreviations in table labels. Replace:

- ENT / CS / S / MS column headers with 'Initial entropy bits',
  'Checksum bits', 'Total bits', 'Number of sentences', 'Mnemonic
  words (6-word theme)' and 'Mnemonic words (BIP-0039)'.
- 'List size / Bits / Chars to identify / Density (bits/char)' with
  'Wordlist size / Bits per word / Characters to identify / Density
  (bits per character)'.
- ADJ. with ADJECTIVE in the example bit-assignment diagram, and the
  surrounding narrative ENT/MS uses with the spelled-out forms.

The accompanying formulas now use the expanded names too, so the
algorithm description and the table column headers stay consistent.

* Formosa: rebuild Example on the real medieval_fantasy theme

Replace the previous hypothetical 5-category example with one that
mirrors the medieval_fantasy theme actually shipped at
https://github.com/Yuri-SVB/formosa/tree/master/src/mnemonic/themes,
including:

- the real 6 categories with their actual BIT_LENGTHs
  (VERB=5, SUBJECT=6, OBJECT=6, ADJECTIVE=5, WILDCARD=6, PLACE=5,
  summing to 33);
- the real FILLING_ORDER and NATURAL_ORDER;
- the real lead tree (VERB → SUBJECT; SUBJECT → OBJECT and WILDCARD;
  OBJECT → ADJECTIVE; WILDCARD → PLACE), showing that a single
  leader can have several dependent categories;
- a 33-bit block whose decoded indices (28, 32, 63, 27, 46, 29)
  pick existing words and existing sub-list entries: VERB[28]
  =unveil, SUBJECT_under_unveil[32]=king, OBJECT_under_king[63]
  =wine, ADJECTIVE_under_wine[27]=sweet, WILDCARD_under_king[46]
  =queen, PLACE_under_queen[29]=throne_room, yielding the sentence
  'king unveil sweet wine queen throne_room'.

This keeps the worked example faithful to the reference
implementation rather than to a fabricated theme, so that anyone can
reproduce the encoding by parsing medieval_fantasy.json.

* Formosa: explain LED_BY as a primitive next-word predictor

Add a paragraph to the LED_BY rationale clarifying that a Formosa theme
behaves as a primitive language model (next-word predictor): each LED_BY relation
skews the conditional distribution over the next word so that probability
mass falls only on the 2^BIT_LENGTH words compatible with the already-
chosen leader, and zero elsewhere. The theme designer plays the role of
training data, hand-curating which combinations are semantically coherent.
This framing makes explicit why themes produce sentences that 'sound right'
while still covering all 2^33 bit patterns of a sentence.

* Cite the companion project Mooncake (https://github.com/T3-Infosec/mooncake)
which builds on this property by rendering each Formosa category as an
on-screen table whose rows and columns are permuted per input session.

Combined with the randomized-indexation property,
an attacker watching only the screen still learns nothing without also
recovering the press sequence.

Add a Rationale paragraph explaining a further benefit of splitting the
vocabulary into several short wordlists (32-128 entries each): such tables
fit on a mobile-device screen and admit input via on-screen lookup, which
a single 2048-word list does not.

The randomized indexation:

- defeats pure key-logging (keystrokes alone don't reveal words; the
  attacker also needs the session permutation),
- raises the bar for shoulder surfing (same as key-logging: only keys
  AND session's permutation suffice. Either alone is uniformative).

This gives an operational, security-focused argument for the
many-small-lists design that complements the existing memorization and
information-density arguments.

Formosa: document Mooncake's volume-key input on mobile

Add a paragraph to the Mooncake rationale describing the proposed mobile
input mechanism: reuse of the volume-up / volume-down keys as a two-button
binary selector. Because every Formosa category is sized 2^BIT_LENGTH and
the on-screen table is laid out in rows, sub-rows and columns whose counts
are powers of two, narrowing to a single cell takes exactly BIT_LENGTH
presses (5 for a 32-entry category, 6 for 64, 7 for 128). The per-category
press count is invariant therefore uninformative, and equal to the bits of
entropy encoded, and the 'one bit per press' bound matches the existing
side-channel argument.

Add three concrete reasons why volume-key input on mobile resists visual

shoulder surfing better than an on-screen keyboard:

- Subtler input motions: a single finger pressing a side rocker, much
  harder to read from a distance than multi-finger taps on a glass
  keyboard.
- Easy occlusion with the second hand: both volume keys are on one edge
  of the device, so the free hand (or the holding hand's thumb) can
  cover them without obscuring the screen for the user.
- Pocket input via headphone volume buttons: because the protocol is
  purely binary, headphone volume controls are sufficient, letting the
  user keep the buttons in a pocket while operating it by feel and
  removing the input motion from the observer's field of view entirely.

* Update bip.mediawiki

Fixed typo from "dektop"  to "desktop"
Fixed agreement of number from "Those of a mobile device" to "Those of mobile devices"

* Update bip.mediawiki

Substituted triple hyphen for —

Co-authored-by: Murch <murch@murch.one>

* Update bip.mediawiki

Updated title to mention Formosa and be more self-explanatory.

Co-authored-by: Murch <murch@murch.one>

* renamed bip.mediawiki to bip-0450.mediawiki
added 450 to BIP number in preamble
added assigned date to 2023-05-02 (date of first mention in email group) in preamble
added correspondent entry on README.md table

* fixed assignment dated
shortened title

* BIP-450: fix CI lint failures (field order + README filename)

Two issues caused Build-Table-Checks and Diff-Checks to fail on PR #2108:

1. Preamble field order: scripts/buildtable.pl enforces @FieldOrder
   (...License, Discussion, ..., Requires...). The preamble had Requires
   before Discussion, causing buildtable.pl to die "Field order is
   incorrect", which fails Build-Table-Checks and cascades into
   Diff-Checks. Moved the Discussion block above Requires.

2. README table row referenced bip-0450.md, but the file is
   bip-0450.mediawiki. buildtable.pl emits the .mediawiki name, so the
   README row never matched the generated table and Diff-Checks failed.
   Corrected the link target to bip-0450.mediawiki.

Verified locally: buildtable.pl exits 0, diffcheck.sh reports "README
table matches expected table from BIP files", link-format-chk.sh passes.

* bip450: Add dates to discussion header
2026-05-20 12:51:22 -07:00
Jon Atack
16e81515be
Merge pull request #2159 from darosior/2505_64b_clarifications_and_rationale
Some checks are pending
GitHub Actions Check / Link-Format-Checks (push) Waiting to run
GitHub Actions Check / Build-Table-Checks (push) Waiting to run
GitHub Actions Check / Diff Checks (fails until number assignment) (push) Waiting to run
GitHub Actions Check / Typo Checks (push) Waiting to run
BIP 54: clarify 64-byte transactions item description and rationale
2026-05-19 15:57:51 -07:00
Jon Atack
53cc4e36e9
Merge pull request #2162 from scgbckbone/bip322_break_changes
BIP-322 nit fixes
2026-05-19 14:46:13 -07:00
Antoine Poinsot
f1f1c36ff2 bip-0054: add a footnote with known workarounds for SPV verifiers 2026-05-19 09:59:50 -04:00
Antoine Poinsot
9e8e357b03 bip-0054: disambiguate use of "mitigation"
Jon pointed that i use "mitigation" to refer both to the items of this
BIP, and for the existing workarounds to make SPV verifiers safe in the
presence of 64-byte txs. This commit rephrases the latter usage.
2026-05-19 09:59:40 -04:00
Antoine Poinsot
47a2d72539 bip-0054: less redundancy in 64-byte rationale, move caching risk to footnote 2026-05-19 09:58:44 -04:00
scgbckbone
6a36f95565 nit fixes 2026-05-19 12:35:02 +02:00
Antoine Poinsot
8ae3af58e0 bip-0054: state explicitly fake inclusion proofs only concern SPV verifier 2026-05-15 10:51:01 -04:00
omipheo
1259a23acc BIP352: complete type annotations on bitcoin_utils class methods
Direct follow-up to PR #2154 (which annotated the free-function half
of bip-0352/bitcoin_utils.py) and 2f7117c ("BIP352: fix Any typing").
The four classes in this file — COutPoint, VinInfo, CScriptWitness,
and CTxInWitness — still had unannotated `__init__`, `serialize`,
`deserialize`, and `is_null` methods. mypy could not flow types
through the surrounding reference.py code that constructs and passes
these objects.

Annotate every method on all four classes:

- COutPoint:    __init__ (hash, n), serialize -> bytes, deserialize -> None
- VinInfo:      __init__ (typed Optional defaults for the three
                construct-on-None fields)
- CScriptWitness: __init__ -> None, is_null -> bool, plus an inline
                stack: List[bytes] declaration matching what the
                rest of the file already assumes
- CTxInWitness: __init__ -> None, deserialize -> "CTxInWitness"
                (forward ref since it returns self), is_null -> bool

Adds Optional to the existing typing import (List was already added
by #2154). No behavior changes.

Verified: mypy --ignore-missing-imports ./bip-0352/bitcoin_utils.py
reports "Success: no issues found in 1 source file"; round-trip
smoke tests on COutPoint serialize/deserialize, CScriptWitness
is_null with empty + non-empty stack, CTxInWitness deserialize
returning self, and VinInfo default-construction all match the
pre-change behavior.
2026-05-15 11:24:44 +02:00
Antoine Poinsot
5c67f90fa8 bip-0054: clarify rationale for invalidating 64-byte txs
As Eric points out on the mailing list: 1. the rationale section should mention and address the
"seam" objection directly rather than burying it in a footnote; 2. the full node consensus split
issue should not be used as sole rationale for invalidating 64-byte txs (but it's fair to point out
it's fixed as a nice to have byproduct).

ML thread: https://gnusha.org/pi/bitcoindev/43996cb3-9133-4627-8944-5fe08427be68n@googlegroups.com/T/#md66e252f0748f4ef7569d5e15d42631e12b66c0b,
2026-05-14 09:09:56 -04:00
Murch
6deafd07ff
Merge pull request #2155 from guggero/bip-0322-follow-up
Some checks failed
GitHub Actions Check / Link-Format-Checks (push) Has been cancelled
GitHub Actions Check / Build-Table-Checks (push) Has been cancelled
GitHub Actions Check / Diff Checks (fails until number assignment) (push) Has been cancelled
GitHub Actions Check / Typo Checks (push) Has been cancelled
BIP-0322: polishing follow-up
2026-05-14 05:26:27 -07:00
Oli
46bfccd318
BIP-0322: grammar and readability touchup
Co-authored-by: Jon Atack <jon@atack.com>
2026-05-14 11:30:45 +02:00
Jon Atack
fa4e128f66
Merge pull request #2157 from arminsabouri/fix-bip322-link
Some checks are pending
GitHub Actions Check / Diff Checks (fails until number assignment) (push) Waiting to run
GitHub Actions Check / Typo Checks (push) Waiting to run
GitHub Actions Check / Link-Format-Checks (push) Waiting to run
GitHub Actions Check / Build-Table-Checks (push) Waiting to run
Fix bip322 link in bip174 type registry
2026-05-13 10:26:07 -07:00
Armin Sabouri
e5863eb96d
Fix bip322 link in bip174 type registry 2026-05-13 11:49:18 -04:00
Oli
352c66b783
BIP-0322: clarify sighash flag for P2TR 2026-05-13 12:49:05 +02:00
Oli
52b2e6d81b
BIP-0322: link to later sections for clarity 2026-05-13 12:49:05 +02:00
Oli
ad0e02f746
BIP-0322: change role to author, add required BIPs 2026-05-13 12:49:04 +02:00
Matt Corallo
622e47722c
Add BIP323: 24 nVersion bits for general purpose use (#2116)
Some checks are pending
GitHub Actions Check / Link-Format-Checks (push) Waiting to run
GitHub Actions Check / Build-Table-Checks (push) Waiting to run
GitHub Actions Check / Diff Checks (fails until number assignment) (push) Waiting to run
GitHub Actions Check / Typo Checks (push) Waiting to run
2026-05-12 16:06:55 -07:00
Jon Atack
fd250df396
Merge pull request #2154 from omipheo/bip-0352-typing-return-annotations
Some checks are pending
GitHub Actions Check / Build-Table-Checks (push) Waiting to run
GitHub Actions Check / Diff Checks (fails until number assignment) (push) Waiting to run
GitHub Actions Check / Typo Checks (push) Waiting to run
GitHub Actions Check / Link-Format-Checks (push) Waiting to run
BIP352: complete return type annotations in bitcoin_utils
2026-05-12 09:19:51 -07:00
Antoine Poinsot
346f93844f bip-0054: spell out in more places that 64 bytes is for witness-stripped size 2026-05-12 07:06:15 -04:00
omipheo
3b76c84d6f BIP352: complete return type annotations in bitcoin_utils
The serialization helpers in bip-0352/bitcoin_utils.py were partially
typed: ser_uint32, hash160, is_p2tr, is_p2wpkh, is_p2sh and is_p2pkh
already declare argument and return types, but the surrounding
from_hex / ser_uint256 / deser_uint256 / deser_txid / deser_compact_size
/ deser_string / deser_string_vector helpers omit them.

Annotate the missing return types (and fill in the obvious argument
types) so the file is consistent and so static analysis can flow types
through callers in reference.py. No behavior changes.
2026-05-08 07:39:17 +02:00
Jon Atack
9fce983a96
Merge pull request #2141 from guggero/bip-0322-finalization
Some checks failed
GitHub Actions Check / Link-Format-Checks (push) Has been cancelled
GitHub Actions Check / Build-Table-Checks (push) Has been cancelled
GitHub Actions Check / Diff Checks (fails until number assignment) (push) Has been cancelled
GitHub Actions Check / Typo Checks (push) Has been cancelled
BIP-0322: clarify motivation/purpose, add prefix, clarify Proof of Funds format, describe PSBT based signing
2026-05-07 20:13:01 -07:00
Jon Atack
e98e42cf0a Merge branch 'Snezhkko-chore/fix-create-outputs-recipients-typing'
* Snezhkko-chore/fix-create-outputs-recipients-typing:
  BIP352: fix Any typing
  BIP352: Fix recipients typing in create_outputs to List[Dict[str, str]]
2026-05-07 21:05:21 -06:00
Jon Atack
2f7117c6e9 BIP352: fix Any typing
`any` is a built-in logic function but not a valid type hint

Instead, use `Any`, the special construct from the typing module
that informs static analysis tools.
2026-05-07 21:04:24 -06:00
Snezhkko
c5c76f355a BIP352: Fix recipients typing in create_outputs to List[Dict[str, str]] 2026-05-07 21:04:11 -06:00
nervana21
acf99fc160
BIP 54: grammar improvements (#2151)
Some checks are pending
GitHub Actions Check / Link-Format-Checks (push) Waiting to run
GitHub Actions Check / Build-Table-Checks (push) Waiting to run
GitHub Actions Check / Diff Checks (fails until number assignment) (push) Waiting to run
GitHub Actions Check / Typo Checks (push) Waiting to run
* bip54: Clarify deployment cost wording

* bip54: Clarify merkle tree wording

* bip54: Clarify sigops wording

* bip54: Clarify timewarp wording

* bip54: Clarify miner preparation cost wording
2026-05-07 12:24:34 +02:00
Oli
40dc3e1a19
README+BIP-0322: add changelog, mark Complete 2026-05-06 12:20:12 +02:00
Oli
414e16f5a2
BIP-0322: remove comments, add discussion links
As described in BIP-0003, the comments section is no longer required.
Instead we add all relevant discussions.
2026-05-06 12:20:12 +02:00
Oli
e69e2f9717
BIP-0322: add guggero as deputy 2026-05-06 12:20:12 +02:00
Oli
d77863fb9e
BIP-0322: update test vectors
This commit updates the test vectors to reflect all the changes in the
previous commits and also introduces new test vectors for the Proof of
Funds variant.
2026-05-06 12:20:11 +02:00
Oli
0dd436e7d4
BIP-0174+BIP-0322: describe PSBT based signing
This commit proposes a new PSBT input field type for transporting the
message to be signed to different signers in a multisig signing use
case.
2026-05-06 12:20:11 +02:00
bubb1es71
2cf4272948
BIP451: Dust UTXO Disposal Protocol (#2150)
Some checks are pending
GitHub Actions Check / Link-Format-Checks (push) Waiting to run
GitHub Actions Check / Build-Table-Checks (push) Waiting to run
GitHub Actions Check / Diff Checks (fails until number assignment) (push) Waiting to run
GitHub Actions Check / Typo Checks (push) Waiting to run
* Add draft BIP for dust utxo disposal protocol

* Assign number 451, update preamble, rename BIP file, and add entry to README table

* Small edits

* Change title, abstract, motivation to focus on dust attack UTXOs
* Simpify dust selection section
* Add batching to address consolidation rules
* Fix core version in privacy preservation
* Fix table units

* Add confirmed utxo rationale

* Revert title back to original

* Change output to always be OP_RETURN ash
2026-05-06 09:22:45 +02:00
Jon Atack
ca418babb7
Merge pull request #2091 from EthanHeilman/fixlinks
Fix broken anchor links
2026-05-05 13:44:36 -07:00
Jon Atack
eda049e920
Merge pull request #2113 from schjonhaug/fix/bip119-pseudocode-typo
Some checks failed
GitHub Actions Check / Link-Format-Checks (push) Has been cancelled
GitHub Actions Check / Build-Table-Checks (push) Has been cancelled
GitHub Actions Check / Diff Checks (fails until number assignment) (push) Has been cancelled
GitHub Actions Check / Typo Checks (push) Has been cancelled
BIP-119: Fix missing self. prefix on stack reference in pseudocode
2026-05-01 13:16:17 -07:00
Murch
442e9628b3
Eliminate remaining "user-content" anchor links 2026-04-27 17:29:24 -07:00
Murch
b3a069464a
Fix other broken anchors
Used the following `sed` command and manually verified the unstaged
changes. Special cases that were not committed included external links
to Wikipedia which are case-sensitive, links specific lines in code, a
link to a title with a slash that had to be cleaned up, and links to
citations on the BIP repository that contain an underscore.

```
sed -E -i '
s/(\[\[[^][]*#)([^]|]*)(\||\]\])/\1\L\2\E\3/g
:again
s/(\[\[[^][]*#)([^]|]*)([: _]+)([^]|]*)(\||\]\])/\1\2-\4\5/g
t again
' bip-0*mediawiki
```
2026-04-27 17:26:49 -07:00
Murch
32b7adf847
BIP342: Fix anchor links 2026-04-27 17:26:47 -07:00
Murch
5137d59442
BIP23: Fix anchor links 2026-04-27 17:26:45 -07:00
Murch
42303cbdf8
BIP22: fix anchor links 2026-04-27 17:26:43 -07:00
Ethan Heilman
835e7107b8
Fix broken anchor links 2026-04-27 17:26:41 -07:00
craigraw
5253e9a294
BIP-0329: Add spscan label type for labelling silent payments wallets (#2149)
Some checks failed
GitHub Actions Check / Typo Checks (push) Has been cancelled
GitHub Actions Check / Link-Format-Checks (push) Has been cancelled
GitHub Actions Check / Build-Table-Checks (push) Has been cancelled
GitHub Actions Check / Diff Checks (fails until number assignment) (push) Has been cancelled
* Add spscan label type

* minor edits
2026-04-27 08:01:58 -07:00
Jon Atack
178ba65952
Merge pull request #1946 from strmfos/master
Some checks failed
GitHub Actions Check / Link-Format-Checks (push) Has been cancelled
GitHub Actions Check / Build-Table-Checks (push) Has been cancelled
GitHub Actions Check / Diff Checks (fails until number assignment) (push) Has been cancelled
GitHub Actions Check / Typo Checks (push) Has been cancelled
BIP-158: replace deprecated io/ioutil with os.ReadFile
2026-04-24 18:57:07 -07:00
Jon Atack
554be702d7
Merge pull request #2148 from boskodev790/fix/bip-0003-reference-broken-link-in-changelog-entries
Some checks are pending
GitHub Actions Check / Link-Format-Checks (push) Waiting to run
GitHub Actions Check / Build-Table-Checks (push) Waiting to run
GitHub Actions Check / Diff Checks (fails until number assignment) (push) Waiting to run
GitHub Actions Check / Typo Checks (push) Waiting to run
Fix BIP3 link in BIP360, touch up BIP3 reference in BIP347
2026-04-23 20:03:26 -07:00
SeedHammer
9eb67f5764
Merge pull request #1548 from seedhammer/master
BIP391: Binary Output Descriptors
2026-04-23 11:17:01 -07:00
Murch
78494dbcc0
Merge pull request #2144 from murchandamus/bip388-update-changelog
Some checks are pending
GitHub Actions Check / Diff Checks (fails until number assignment) (push) Waiting to run
GitHub Actions Check / Typo Checks (push) Waiting to run
GitHub Actions Check / Link-Format-Checks (push) Waiting to run
GitHub Actions Check / Build-Table-Checks (push) Waiting to run
bip388: Update Changelog
2026-04-23 07:56:28 -07:00
boskodev790
1609a4f576 Fix broken BIP 3 reference in bip-0347 and bip-0360 changelogs
Both BIPs added a changelog entry on 2026-01-23 referencing the updated
BIP Process meta-BIP with the wrong form:

- bip-0360.mediawiki:404 rendered `[[bip-0003.mediawiki|BIP 003]]`, but
  the actual file is `bip-0003.md`. The MediaWiki link therefore failed
  to resolve to the BIP 3 page on the bitcoin/bips GitHub wiki render
  and on the bips.dev / bip339 style mirrors — readers of the bip-0360
  changelog landed on a 404.

- bip-0347.mediawiki:170 wrote the same reference as bare text
  `BIP 003` with no link at all, so readers of bip-0347 had no way to
  navigate to the BIP 3 they were meant to follow.

Rewrite both entries to use the canonical form `[[bip-0003.md|BIP 3]]`:

- `bip-0003.md` matches the actual filename.
- `BIP 3` matches the display text convention the README (line 40) and
  every other BIP in this repository already use when linking to
  bip-0003 — "BIP 003" with the three-digit zero-pad appears nowhere
  else in the repo for any BIP and is not part of the display style
  described in BIP 2.

Also drops the trailing whitespace on the bip-0347 line while we are
there (the `typos` CI tolerates it but it is inconsistent with every
other line in the same changelog block).
2026-04-23 04:03:40 +02:00
Murch
69a63f629f
Merge pull request #2143 from murchandamus/bip174-fixup-changelog
Some checks are pending
GitHub Actions Check / Link-Format-Checks (push) Waiting to run
GitHub Actions Check / Build-Table-Checks (push) Waiting to run
GitHub Actions Check / Diff Checks (fails until number assignment) (push) Waiting to run
GitHub Actions Check / Typo Checks (push) Waiting to run
bip174: Explain BIP2 status in Changelog
2026-04-21 13:34:32 -07:00
Jon Atack
50c6ce7636
Merge pull request #2146 from conduition/361/corrections
Some checks failed
GitHub Actions Check / Link-Format-Checks (push) Has been cancelled
GitHub Actions Check / Build-Table-Checks (push) Has been cancelled
GitHub Actions Check / Diff Checks (fails until number assignment) (push) Has been cancelled
GitHub Actions Check / Typo Checks (push) Has been cancelled
Corrections to BIP-0361 on rescue protocols
2026-04-20 07:49:09 -07:00
Oli
c2850a0010
BIP-0322: add prefix to message signature 2026-04-20 09:43:30 +02:00
Oli
833a1a8a89
BIP-0322: encode finalized PSBT for Proof of Funds
This commit proposes a fix for the problem that an offline verifier
previously was not able to even verify the witness stack of additional
inputs. By providing the full finalized PSBT, a verifier has all the
input data necessary to run the script through the validation engine.

We require the PSBT to be finalized to make sure it contains the final
script witness or final script sig but no extra potentially
privacy-sensitive fields. The Non-Witness and Witness UTXO fields are
explicitly allowed for finalized PSBTs, which makes the format perfect
for the use case.
2026-04-20 09:43:30 +02:00
Oli
8a46a5bfa5
BIP-0322: clarify terminology used
Since the term "signature" can be pretty overloaded dependin on the
context, we clarify what it actually means in this BIP.
2026-04-20 09:43:30 +02:00
Oli
0a20483c65
BIP-0322: update motivation, clarify Proof of Funds purpose
This addresses two discussion items:
 - The list of UTXOs should not be interpreted as a "proof that no other
   UTXOs for an address exist".
 - The BIP only addresses "signer receives funds with the address" and
   not "signer sent a previous transaction" use case.
2026-04-20 09:43:30 +02:00
Oli
665d96065f
BIP-0322: reference btcd implementation 2026-04-20 09:43:30 +02:00
Oli
bbaf40ce1d
BIP-0322: small semantic and formatting fixes
This fixes small inconsistencies or incomplete definitions based on
previous, already merged changes.
2026-04-20 09:43:29 +02:00
Oli
6f3fce21e6
BIP-0322: wrap long lines at 100 characters
This re-formats the document for easier editing and diff viewing.
Wiki syntax is weird for lists and line wraps break them. Simple lists
were changed to <ul> or <ol> tags but complex lists remain as they are
to not bloat the diff too much.
2026-04-20 09:43:29 +02:00
conduition
da7cc678d5
Fix BIP32 links and consistency
Co-authored-by: Jon Atack <jon@atack.com>
2026-04-17 10:44:09 -06:00
Jon Atack
83c1fc8ed2
Merge pull request #2142 from macgyver13/bip352-intermediate-sum
Some checks failed
GitHub Actions Check / Link-Format-Checks (push) Has been cancelled
GitHub Actions Check / Build-Table-Checks (push) Has been cancelled
GitHub Actions Check / Diff Checks (fails until number assignment) (push) Has been cancelled
GitHub Actions Check / Typo Checks (push) Has been cancelled
BIP-352: add test vector for edge case - input key intermediate sum zero
2026-04-17 09:23:51 -07:00
conduition
ab2ebe2c5d
Corrections to BIP-0361 on rescue protocols 2026-04-17 15:22:59 +00:00
Murch
eec42583f0
Merge pull request #2046 from macgyver13/bip375-reference-testvectors-pr
BIP375: Add test vectors + validator
2026-04-16 17:47:48 -07:00
macgyver13
8c0a9bfa57 BIP-375: add changelog section
Add Changelog section
Begin with version 0.1.0 as this BIP is Draft phase
2026-04-16 14:03:48 -04:00
macgyver13
00957af80e BIP-352: update changelog and correct typo
Add patch version 1.1.1 to Changelog
Remove extra leading double-quote in CoinJoin ref name
2026-04-16 12:06:56 -04:00
macgyver13
c2ac36f48f BIP-352: add test vector for edge case - input key intermediate sum zero
Exercises [A, -A, A] input key pattern where the intermediate sum
hits zero after the first two keys, but the final sum is non-zero.
Implementations that validate after each pairwise addition (rather
than summing all keys first) will incorrectly reject this case.
2026-04-16 12:05:12 -04:00
Murch
e1755b8257
bip174: Fix relative paths to other BIPs 2026-04-16 06:57:49 -07:00
Murch
cfff971940
bip388: Add missing Version header, rename Changelog 2026-04-15 11:32:28 -07:00
Murch
db131ef7b9
bip388: Amend assignment date
BIP3 clarified the content of the ambiguous Created header and renamed it to Assigned.
BIP388 was assigned per
https://github.com/bitcoin/bips/pull/1389#pullrequestreview-1796535592
on 2023-12-26.
The prior "Created:" field content was moved to a Changelog entry.
2026-04-15 11:31:40 -07:00
Murch
78fcc3130b
Merge pull request #2122 from darosior/2603_bip54_improvements
Some checks are pending
GitHub Actions Check / Link-Format-Checks (push) Waiting to run
GitHub Actions Check / Build-Table-Checks (push) Waiting to run
GitHub Actions Check / Diff Checks (fails until number assignment) (push) Waiting to run
GitHub Actions Check / Typo Checks (push) Waiting to run
BIP 54 test vectors improvements following review in Inquisition
2026-04-15 10:44:47 -07:00
Murch
777ca76c2e
bip174: Explain BIP2 status in Changelog 2026-04-15 08:31:40 -07:00
Murch
588431816a
Merge pull request #2135 from murchandamus/2026-04-08-deduplicate-psbt-tables
Some checks are pending
GitHub Actions Check / Link-Format-Checks (push) Waiting to run
GitHub Actions Check / Build-Table-Checks (push) Waiting to run
GitHub Actions Check / Diff Checks (fails until number assignment) (push) Waiting to run
GitHub Actions Check / Typo Checks (push) Waiting to run
BIP174: Deduplicate type definitions by introducing registry file
2026-04-14 17:19:22 -07:00
Jameson Lopp
86dfa19bef
BIP361: Post Quantum Migration and Legacy Signature Sunset (#1895)
* BIP-361

* bip361: Fix background color

* address feedback
2026-04-14 07:37:58 -07:00
Ava Chow
d6ff1bec1d
174: Add changelog and version number 2026-04-13 08:12:35 -07:00
Murch
0a23dbf56a
BIP174: Deduplicate per-output type definitions 2026-04-13 08:12:30 -07:00
Murch
d71cd39f69
BIP174: Deduplicate input type definitions 2026-04-13 08:12:00 -07:00
Murch
762e8c785b
BIP174: Deduplicate global type definitions 2026-04-13 08:11:19 -07:00
Murch
eb497966e4
Merge pull request #2136 from guggero/bip-0322-clarifications
Some checks failed
GitHub Actions Check / Link-Format-Checks (push) Has been cancelled
GitHub Actions Check / Build-Table-Checks (push) Has been cancelled
GitHub Actions Check / Diff Checks (fails until number assignment) (push) Has been cancelled
GitHub Actions Check / Typo Checks (push) Has been cancelled
BIP-322: add clarifications and more test vectors
2026-04-10 16:47:56 -07:00
nymius
ef7703ed8a
BIP376: Spending Silent Payment outputs with PSBTs (#2089) 2026-04-10 15:06:48 -07:00
Oli
3ab70c98a7
BIP-0322: turn test vectors into JSON, add more
This commit turns the existing test vectors into a JSON and then adds
more test cases covering the most common script types.
2026-04-10 09:06:36 +02:00
Oli
805bb0b6fc
BIP-0322: clarify scriptSig on to_sign for legacy transactions
Before this commit it was not clear that non-native SegWit outputs
(e.g. P2PKH or P2SH-P2WPKH) only work if the correct scriptSig is
provided.
This then also makes it more clear why P2SH-P2WPKH outputs are NOT
supported by the "simple" variant.
2026-04-10 09:06:36 +02:00
Oli
4d36f73e7b
BIP-0322: add format clarification table
This commit adds a table that clarifies what script types are compatible
with what signing variant and also makes more clear what the exact
format for the signatures of the different variants are.
2026-04-10 09:06:36 +02:00
macgyver13
b217897a62 BIP-375: fix label byte order used by labelhash
Test vectors with labels now use big-endian byte order instead of little-endian, matching BIP-352 specification

Summary of test vector changes:
- psbt structure: missing PSBT_OUT_SP_V0_INFO field when PSBT_OUT_SP_V0_LABEL set
- can finalize: one P2WPKH input / two mixed outputs - labeled sp output and BIP 32 change
- can finalize: two sp outputs - output 0 uses label=3 / output 1 uses label=1
2026-04-09 18:07:10 -04:00
Oghenovo Usiwoma
c77a6c5996
BIP-352: warn against stopping scan due to wallet policy filtering (#2134)
Some checks failed
GitHub Actions Check / Diff Checks (fails until number assignment) (push) Has been cancelled
GitHub Actions Check / Typo Checks (push) Has been cancelled
GitHub Actions Check / Link-Format-Checks (push) Has been cancelled
GitHub Actions Check / Build-Table-Checks (push) Has been cancelled
Adds a warning to the "if no matches are found, stop" scanning
step. Without it, wallet developers may be tempted to apply policy
filtering (e.g. dust) before deciding to continue,
causing subsequent outputs for the same sender to be missed.
2026-04-07 13:51:12 -07:00
Murch
2dfdfba3e3
BIP440: Varops Budget for Script Runtime Constraint, BIP441: Restoration of disabled Script (tapleaf 0xc2) (#2118)
Some checks are pending
GitHub Actions Check / Link-Format-Checks (push) Waiting to run
GitHub Actions Check / Build-Table-Checks (push) Waiting to run
GitHub Actions Check / Diff Checks (fails until number assignment) (push) Waiting to run
GitHub Actions Check / Typo Checks (push) Waiting to run
* Varops: Two BIPs for Script Restoration: varops calculations and tapleaf version (0xc2).

Special thanks to Murch for teaching me mediawiki, and so much great
formatting and clarity advice.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>

* script restoration: fix MUL cost to account to round up B to word boundary.
Julian points out that the implementation does this, which improves accuracy
for the case of small B (since the term is multiplied: for normal OP_ADD etc
we don't bother, since the difference is very bounded).

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>

* BIP 440, 441: official numbers, into README.mediawiki and renamed.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>

---------

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2026-04-07 08:33:54 -07:00
craigraw
6c2023e542
Merge pull request #2099 from craigraw/descriptorannotations
BIP393: Output Script Descriptor Annotations
2026-04-07 08:31:42 -07:00
Murch
e3874ca825
Merge pull request #2111 from darosior/2603_bip370_output_amount
BIP 370: drop redundant requirement from PSBT_OUT_SCRIPT field description
2026-04-07 08:26:19 -07:00
Murch
02bdb13f13
Merge pull request #2132 from andrewtoth/bip370_missing_test_vectors
BIP370: missing test vectors
2026-04-07 08:24:52 -07:00
macgyver13
897455dab7 BIP-375: skip ineligible inputs when combining ecdh shares
add fake ecdh share and dleq proof to P2SH input for valid test: two inputs using per-input ECDH shares - only eligible inputs contribute shares (P2SH excluded)

remove unused return string from is_input_eligible
2026-04-05 20:52:23 -04:00
macgyver13
6295a70405 BIP-375: clarify eligible inputs restriction in Computing the Output Scripts text 2026-04-05 19:55:53 -04:00
macgyver13
9536c863cf BIP-375: clarify eligible input restriction in Signer text 2026-04-05 19:55:53 -04:00
macgyver13
7b4f1d6b4e BIP-375: address review feedback
correctly label witness_utxo vs non_witness_utxo key in supplementary inputs

Summary of test vector changes:
removed test: 
- psbt structure: empty PSBT_OUT_SCRIPT field when sending to non-sp output
modified test:
- ecdh coverage: only one ineligible P2SH multisig input when PSBT_OUT_SCRIPT set for sp output
- can finalize: one P2PKH input single-signer
- can finalize: two inputs using per-input ECDH shares - only eligible inputs contribute shares (P2SH excluded)
added test: 
- can finalize: two inputs using global ECDH share - only eligible inputs contribute shares (P2SH excluded)
2026-04-05 19:55:53 -04:00
Andrew Toth
1e15fc6fae
BIP-370: add invalid test vector for missing PSBT_GLOBAL_TX_VERSION in PSBTv2 2026-04-05 19:24:59 -04:00
Andrew Toth
a07ffa8ccb
BIP-370: add invalid test vector for PSBT_GLOBAL_UNSIGNED_TX in PSBTv2 2026-04-05 19:24:59 -04:00
Andrew Toth
87522e80e3
BIP-370: add invalid test vector for PSBT_IN_REQUIRED_HEIGHT_LOCKTIME of 0 2026-04-05 19:24:59 -04:00
macgyver13
cf7a16a5f9 BIP-375: update documentation
Update Test Vectors section
Add README.md to explain validation tooling and dependencies
2026-04-04 09:17:46 -04:00
macgyver13
fb105b7e51 BIP-375: add output scripts validation
Add support for computing bip352 output scripts
Extract ECDH shares and public key from PSBT and aggregate both if necessary
Refactor validate_ecdh_coverage to use collect_input_ecdh_and_pubkey
2026-04-04 09:17:46 -04:00
macgyver13
ab30224051 BIP-375: add input eligibility validation
Verify segwit version >1 not used if silent payment outputs present (bip352)
Verify SIGHASH_ALL requirement
2026-04-04 09:17:46 -04:00
macgyver13
6a91f88030 BIP-375: add ecdh coverage validation
Add deps/dleq.py (Adapted from bip-0374/reference.py)
Extract pubkey from PSBT inputs 
- PSBT_IN_BIP32_DERIVATION
- PSBT_IN_WITNESS_UTXO for P2TR
Add script type helpers
- bip352 input eligibility helpers
2026-04-04 09:17:46 -04:00
macgyver13
66053ae879 BIP-375: add test_runner and validate PSBT structure
Implement psbt structure checks
Add test_runner.py for processing test vectors
2026-04-04 09:17:46 -04:00
macgyver13
fc9918d8c0 BIP-375: add BIP375PSBT extension classes
BIP375PSBT (a PSBT subclass that deserializes into BIP375PSBTMap instances)
BIP375PSBTMap (a PSBTMap subclass with BIP-375 field access helpers)
2026-04-04 09:17:46 -04:00
macgyver13
8b46bd63b5 BIP-375: add test vector file 2026-04-04 09:17:46 -04:00
Rusty Russell
78e7562de3 BIP 440, 441: official numbers, into README.mediawiki and renamed.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2026-03-29 14:33:12 +10:30
Rusty Russell
32035058b4 script restoration: fix MUL cost to account to round up B to word boundary.
Julian points out that the implementation does this, which improves accuracy
for the case of small B (since the term is multiplied: for normal OP_ADD etc
we don't bother, since the difference is very bounded).

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2026-03-29 14:33:12 +10:30
Rusty Russell
977342a943 Varops: Two BIPs for Script Restoration: varops calculations and tapleaf version (0xc2).
Special thanks to Murch for teaching me mediawiki, and so much great
formatting and clarity advice.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2026-03-29 14:32:59 +10:30
moonsettler
805c9b54f6
BIP442: Update reference links (#2129)
Some checks failed
GitHub Actions Check / Link-Format-Checks (push) Has been cancelled
GitHub Actions Check / Build-Table-Checks (push) Has been cancelled
GitHub Actions Check / Diff Checks (fails until number assignment) (push) Has been cancelled
GitHub Actions Check / Typo Checks (push) Has been cancelled
2026-03-24 13:37:30 -07:00
macgyver13
e70510193f Merge commit '96000a36c22f6528e834c54f0d115db675198e57' as 'bip-0375/deps/secp256k1lab' 2026-03-23 17:42:04 -04:00
macgyver13
eedb7f9a31 Squashed 'bip-0375/deps/secp256k1lab/' content from commit 44dc4bd
git-subtree-dir: bip-0375/deps/secp256k1lab
git-subtree-split: 44dc4bd893b8f03e621585e3bf255253e0e0fbfb
2026-03-23 17:42:04 -04:00
macgyver13
a8aa5ed548 BIP-375: Add bitcoin test framework as dependency - deps/bitcoin_test 2026-03-23 17:42:04 -04:00
Mark "Murch" Erhardt
4e1d44ed72
Merge pull request #2127 from theStack/bip174-global_version-mandatory-in-v2
BIP-174: mark PSBT_GLOBAL_VERSION as required for v2
2026-03-23 11:37:52 -07:00
Sebastian Falbesoner
fa731d21c4 BIP-174: mark PSBT_GLOBAL_VERSION as required for v2 2026-03-20 16:45:50 +01:00
Gregory Sanders
2778442c21
Add BIP446: OP_TEMPLATEHASH, BIP448: Taproot-native (Re)bindable Transactions (#1974)
Co-authored-by: Antoine Poinsot <darosior@protonmail.com>
2026-03-17 13:01:23 -07:00
Oren
351ceef274
BIP-128: exact specification for the checksum calculation (#2121) 2026-03-16 11:25:46 -07:00
Antoine Poinsot
fa608987ea bip54: add another transaction size test case
Ariard mentioned he would like to see a test case for a 64-byte transaction spending a Taproot
output with an annex. I took the opportunity to also make the output be an OP_RETURN with a 2-byte
push, as another semi-realistic transaction.
2026-03-16 10:21:04 -04:00
Antoine Poinsot
977300dad6 bip54: restructure timestamp test vectors into a tree
The test vectors were initially designed to maximally simple, which led to much redundancy. That was
probably too close to one extreme on the spectrum between simplicity and efficiency.

Here we shave off 20k lines by simply representing the header chains as a tree instead of list of
lists by duplicating all common headers.
2026-03-16 10:21:04 -04:00
Antoine Poinsot
4f94c5f01f bip54: make test vectors POSIX-compliant (newline at EOF)
This was pointed out during the Bitcoin Inquisition PR review
2026-03-13 16:50:48 -04:00
Antoine Poinsot
78126a5f0c bip54: move comment as first element in txsize test vectors
This is part of feedback received during the Bitcoin Inquisition PR review.
2026-03-13 16:50:33 -04:00
Antoine Poinsot
ff39733e70 bip54: update sigops test vectors following Inquisition review
This is a batch update to the tests vectors for the limit on legacy signature-checking operations
introduced in BIP 54, following feedack received on the Bitcoin Inquisition PR and from Chris
Stewart's implementation in Bitcoin-S.
2026-03-13 16:50:32 -04:00
Antoine Poinsot
1f21139957 bip54: expand on rationale for non-final coinbase nSequence
Making sure that the coinbase is timelocked is a neat simplification in reasoning about duplicates,
but it has caused some confusions. For instance here:
https://gnusha.org/pi/bitcoindev/e758af9b-72fc-4fdd-8e07-e1126635780an@googlegroups.com/

Fix this by explicitly stating the implications.
2026-03-13 14:21:41 -04:00
Antoine Poinsot
aef4d9e084 bip54: reword "potentially executed" language in sigops limit specification
The paragraph in its entirety is already unambiguous that all signature-checking operations
*present* in the Script (as opposed to *executed*) are counted. However i received feedback that the
"potentially executed" language in the first sentence of this paragraph may be confusing. This is
because it is in theory possible to have a more accurate upper bound by analyzing the possible
spending paths and use the maximum number of signature-checking operations in either to check
against the limit.

This commit rewords the first sentence to use the word "present" to be extra-clear before even
describing how the accounting is performed in later sentences.
2026-03-13 11:14:20 -04:00
Mark "Murch" Erhardt
b382728379
Merge pull request #2087 from theStack/bip352-vendor-secp256k1lab
BIP-352: vendor secp256k1lab and use it for reference implementation
2026-03-06 14:39:56 -05:00
Sebastian Falbesoner
249bdef156 BIP-352: mention secp256k1lab in BIP text
also fix a small grammar nit (s/are provided/is provided/)
2026-03-06 15:19:09 +01:00
Jon Atack
c0644a054f
BIP32: edits by ddustin for clarity (picks up PR785) (#1903)
Co-authored-by: Dusty Daemon <dustinpaystaxes@gmail.com>
Co-authored-by: Pieter Wuille <pieter@wuille.net>
Co-authored-by: Murch <murch@murch.one>
2026-03-05 14:29:32 -05:00
Jon Atack
1656f62a44
Merge pull request #1943 from prestoalvarez/patch-1
BIP69: examples file fixes and update to python3
2026-03-05 10:52:14 -08:00
craigraw
41f9957630
BIP392: Silent Payment Output Script Descriptors (#2047)
* Add sp() output descriptor format for BIP352 Silent Payments

* Update headers and remove space after comma in descriptors

* Add label ranges with examples

* Update with assigned number and adjust preamble for BIP3

* BIP392: Add table entry to README

* Add two argument key expression form and remove birthday and label arguments

* Add BIP392 sp() descriptor to BIP380 script expressions table

* Add sp() descriptor to BIP390 allowed expressions and add musig() example to BIP392

* Add changelog and version header to BIP390
2026-03-05 11:02:52 -05:00
Luke Dashjr
b3ab91fa46 Merge remote-tracking branch 'origin-pull/2115/head' 2026-03-05 03:38:54 +00:00
Dathon Ohm
44b72212f2
BIP-110: Update deployment section with EXPIRED state; add GBT subsection to specification 2026-03-04 21:22:52 -06:00
Dathon Ohm
ddd5db9a63
BIP-110: Clarify rule 2 witness stack element exclusions 2026-03-04 21:01:23 -06:00
Antoine Poinsot
175790ee7f BIP 370: remove redundant field inclusion comment in OUT_SCRIPT description
There are already "Requiring inclusion" / "Requiring exclusion" columns that specify that.
2026-03-04 10:15:46 -05:00
Andreas Schjønhaug
703609f236
bip119: fix stack[-1] -> self.stack[-1] in pseudocode
The execute_bip_119 pseudocode references `stack[-1]` on line 74
instead of `self.stack[-1]`, inconsistent with all other stack
references in the function. The C++ reference implementation
correctly uses `stack.back()` throughout.
2026-03-04 13:39:30 +01:00
moonsettler
f61d4b8ba3
BIP442: OP_PAIRCOMMIT (#1699)
* Add: PAIRCOMMIT

* New revision with Brandon Black

* Fix: Authors and spelling merklize

* Fix: header

* Rework based on feedback from PR 1699

commit ae69991b77830021c34e31d1a65ac6987e2ca1ba
Author: moonsettler <moonsettler@protonmail.com>
Date:   Tue Sep 23 02:23:43 2025 +0200

    Update references

commit 6adcb4e559cd2b67553fa57d193474906c138721
Author: moonsettler <moonsettler@protonmail.com>
Date:   Tue Sep 23 02:15:14 2025 +0200

    General computation simplify wording

commit 2f911cb4ab4b938697e39cb34974fa6fc12bf3b2
Author: moonsettler <moonsettler@protonmail.com>
Date:   Tue Sep 23 01:36:41 2025 +0200

    Rework based on feedback from PR 1699

* More readeable scripts & fix footnotes

* Format and readability improvements

* Update general computation section

* THIKCS cost compare

* Reference BIP-446

* Standard -> Specification

Co-authored-by: Mark "Murch" Erhardt <murch@murch.one>

* Update header to BIP-3 compatible

Co-authored-by: Mark "Murch" Erhardt <murch@murch.one>

* Add: Post-History

* Update Cost comparison table

* Post-History -> Discussion

Co-authored-by: Mark "Murch" Erhardt <murch@murch.one>
2026-03-03 14:38:26 -05:00
Sebastian Falbesoner
f2ffa99a4a BIP-352: take use of vendored secp256k1lab for reference implementation
This allows to remove secp256k1.py and replace the secp256k1-specific
parts in the reference implementation. Replacement guide:

    * ECKey -> Scalar
    * ECKey.set(seckey_bytes) -> Scalar.from_bytes_checked(seckey_bytes)
    * seckey.get_pubkey() -> seckey * G
    * seckey.get_bytes() -> seckey.to_bytes()
    * seckey.add(tweak_bytes) -> seckey + Scalar.from_bytes_checked(tweak_bytes)
    * seckey.negate() -> seckey = -seckey
    * seckey.sign_schnorr -> schnorr_sign(..., seckey.to_bytes(), ...)

    * ECPubKey -> GE
    * ECPubKey.set(pubkey_bytes) -> GE.from_bytes_{xonly,compressed}(pubkey_bytes)
    * pubkey.get_y() % 2 == 0 -> pubkey.has_even_y()
    * pubkey.get_bytes(False) -> pubkey.to_bytes_compressed()
    * pubkey.get_bytes() -> pubkey.to_bytes_xonly()
    * not pubkey.valid -> pubkey.infinity
    * pubkey.verify_schnorr -> schnorr_verify(..., pubkey.to_bytes_xonly(), ...)

    * TaggedHash -> tagged_hash
    * hashlib.sha256(preimage).digest() -> hash_sha256(preimage)
2026-03-02 19:17:21 +01:00
Sebastian Falbesoner
511bb99dc4 Merge commit '53b590e190f798131a10a16194261243abdf6b4d' as 'bip-0352/secp256k1lab' 2026-03-02 19:16:00 +01:00
Sebastian Falbesoner
53b590e190 Squashed 'bip-0352/secp256k1lab/' content from commit 44dc4bd
git-subtree-dir: bip-0352/secp256k1lab
git-subtree-split: 44dc4bd893b8f03e621585e3bf255253e0e0fbfb
2026-03-02 19:16:00 +01:00
Casey Rodarmor
6eb7cb38fb
Merge pull request #2110 from casey/fix-readme-link
Fix mailing list link in readme
2026-03-02 11:56:42 -05:00
Mark "Murch" Erhardt
6eb01f01bc
Merge pull request #2106 from theStack/bip352_limit_max-k-PR
BIP-352: introduce per-group recipient limit K_max (=2323)
2026-03-02 11:54:09 -05:00
Ethan Heilman
9fb88a11b7
bip347: Complete OP_CAT (#2090)
* OP_CAT to BIP 0003 format, add usecase

* draft --> complete

* Update bip-0347.mediawiki

Co-authored-by: Mark "Murch" Erhardt <murch@murch.one>

* BIP347: Update table entry to complete

* Fix breaking test

* Add test vectors

---------

Co-authored-by: Mark "Murch" Erhardt <murch@murch.one>
2026-03-02 10:34:26 -05:00
Sebastian Falbesoner
b4bc0a88b7 BIP-352: add test vector for exceeding K_max limit [receiver side]
Test case: even though there are 2324 outputs targeted to the recipient,
only 2323 are found due to the introduced K_max limit. Any
implementation following the new BIP protocol rule wouldn't create such
a transaction in the first place, but an attacker might do.

Can be tested by
`$ ./bip-0352/reference.py ./bip-0352/send_and_receive_test_vectors.json`
2026-03-02 13:31:46 +01:00
Sebastian Falbesoner
9830fad214 BIP-352: add test vector for exceeding K_max limit [sender side]
Test case: as the (only) recipient group contains 2324 addresses and
thus exceeds the K_max limit by one, sending fails.

Can be tested by
`$ ./bip-0352/reference.py ./bip-0352/send_and_receive_test_vectors.json`
2026-03-02 13:27:28 +01:00
Sebastian Falbesoner
f14132fc77 BIP-352: test vectors: allow to check found output count for receiving
Introduce an optional "n_outputs" field as alternative to the detailed
"outputs" objects (the field was already specified, but not used so
far). Also update the documentation of the fields.
2026-03-02 13:26:31 +01:00
Sebastian Falbesoner
3aa17caaa3 BIP-352: test vectors: allow specifying repeated recipients for sending
Introduce an optional "count" field for recipient objects.
Also update the documentation of the fields.
2026-03-02 13:26:31 +01:00
Sebastian Falbesoner
f665c2c142 BIP-352: introduce per-group recipient limit K_max (=2323)
In theory this is a backwards incompatible protocol change.
Practically, no existing Silent Payments wallets out there supports
sending to such a high quantity of recipients (not even in terms of
_total_ number of recipients), so the K_max limit should be safe to
introduce, without any negative effects in the wallet ecosystem.
2026-03-02 13:26:25 +01:00
Jon Atack
ced24101c7
Merge pull request #2065 from lisenokdonbassenok/fix/bip310-min-bit-count-param 2026-02-28 05:41:50 -08:00
rkrux
0f307780aa
BIP-174: port public key terminology from BIP 373 (#2085)
The changes are ported from PR 1705 so that the same public key
terminology is reflected in BIP 174 as well. Please refer this
other PR for more details.
2026-02-27 17:16:00 -08:00
Jon Atack
95465e0b4f
BIP20,21: add Superseded-By and Replaces headers (#1984) 2026-02-27 15:43:46 -08:00
Jon Atack
0780663be1
BIP129: Add Requires header (#2019) 2026-02-27 15:18:38 -08:00
MoNyAvA
e76f0439b3
BIP-383: remove extra stray </tt> (#2061) 2026-02-27 15:03:55 -08:00
Mohammad Eglil
53dac1ba29
bip-0044: add Requires header for BIP32 and BIP43 (#2072) 2026-02-27 14:52:53 -08:00
MoNyAvA
edb6856d25
BIP-117: add missing BIP8 reference (#2080) 2026-02-27 14:40:25 -08:00
Oren
9ff061f8b9
BIP128: Timelock-Recovery Storage Format (#2068)
* new bip: timelock recovery storage format

* Comparison with Script-Based Wallets

* Type is Specification

Co-authored-by: Mark "Murch" Erhardt <murch@murch.one>

* Change Authors to a single Author

Co-authored-by: Mark "Murch" Erhardt <murch@murch.one>

* Replace OP_VAULT mention with OP_CHECKCONTRACTVERIFY

* Only the Alert Transaction needs to be non-malleable

* Adding discussion link

* limiting the transactions weight

This is important in order to prevent users from creating
recovery-plans that are hard to propagate.

* Explain anchor-addresses

* fix typo

Co-authored-by: Mark "Murch" Erhardt <murch@murch.one>

* add surname initial to author name

* Explain unintentional initiation of rrecovery-plan.

* limit alert_inputs length to 2439

* updating bip number to 128

* rename to bip-0128.mediawiki

* BIP 128: Timelock-Recovery storage format

* fix field order, change title to uppercase

* Making plugin_version optional

Relevant only in wallets where
the feature is implemented
via a plugin.

* Removing mainnet

Irrelevant. Obviously a monitoring
service for mainnet should
verify that the addresses
are on mainnet.
2026-02-27 12:24:33 -08:00
Mark "Murch" Erhardt
bd56416786
Merge pull request #2107 from murchandamus/2026-02-bip352-add-thestack
BIP352: Add Sebastian Falbesoner as Author
2026-02-25 10:22:21 -08:00
Murch
9e407af625
BIP352: Add Sebastian Falbesoner as Author 2026-02-24 12:55:34 -08:00
YoCheng
97781eae4d
BIP85: fix typo in byte value (#2100) 2026-02-13 11:18:59 -08:00
Hunter Beast
eae7d9fc57
BIP360: Pay to Merkle Root (P2MR) (#1670)
Review comments and assistance by:
  Armin Sabouri <armins88@gmail.com>
  D++ <82842780+dplusplus1024@users.noreply.github.com>
  Jameson Lopp <jameson.lopp@gmail.com>
  jbride <jbride2001@yahoo.com>
  Joey Yandle <xoloki@gmail.com>
  Jon Atack <jon@atack.com>
  Jonas Nick <jonasd.nick@gmail.com>
  Kyle Crews <kylecrews@Kyles-Mac-Studio.local>
  Mark "Murch" Erhardt <murch@murch.one>
  notmike-5 <notmike-5@users.noreply.github.com>
  Vojtěch Strnad <43024885+vostrnad@users.noreply.github.com>

Co-authored-by: Ethan Heilman <ethan.r.heilman@gmail.com>
Co-authored-by: Isabel Foxen Duke <110147802+Isabelfoxenduke@users.noreply.github.com>
2026-02-11 13:01:47 -08:00
Dathon Ohm
ed7af6ae7e
BIP 110: Reduced Data Temporary Softfork (#2017)
* Reduced Data Temporary Softfork

* BIP-RDTS: update and expand according to PR feedback

* BIP-RDTS: minor updates to wording to address feedback

* Address PR comments: update Reference Implementation and Deployment

* Address PR comments: Clarify deployment name and bit

* Address PR comments: Update BIP number, creation date, and README entry

* Address @murchandamus X comment: Add activation threshold

* Address PR comments: Update to BIP-3; clarify rationale and deployment

* Address PR comments: Clarify scriptPubKey limit rationale and LOCKED_IN behavior
2026-02-06 16:28:07 -08:00
Paul Miller
10c7888885
Escape pipe character in markdown table (#2095) 2026-02-04 14:39:50 -08:00
Jurvis Tan
57869d524a
BIP 89: Chain Code Delegation for Private Collaborative Custody (#2004)
* Add Chaincode Delegation BIP

* Update license to BSD-3-Clause and expand blinded signing documentation

* Address initial PR comments

* Update with BIP number assignment

* Fix delegator_sign test vector

* Upgrade secp256k1lab and add license file

- Upgrade vendored secp256k1lab to commit a265da1 (adds type annotations)
- Add COPYING file to satisfy MIT license requirements
- Document secp256k1lab commit reference in BIP text

* Fix type checker and linter issues in reference implementation

- Fix TweakContext to use Scalar types for gacc/tacc
- Replace HashFunction enum with Callable type alias
- Fix bytearray to bytes conversion in blind_sign
- Move imports to top of file
- Fix boolean comparison style (use 'not' instead of '== False')
- Add proper type annotations and casts for dict handling
- Remove unused imports and type ignore comments

* Address PR review comments on terminology and clarity

- Add intro explaining delegation naming (chain code is delegated, not
  signing authority)
- Reorder terminology to list Delegator before Delegatee
- Replace "quorum" with clearer "can co-sign for UTXOs" language
- Clarify derivation constraints in terms of delegatee's extended key
- Rename "Delegatee Signing" section to "Signing Modes"
- Fix "delegatee can apply" to "delegator can produce" (line 112)
- Replace undefined "caller" with "delegatee" (line 173)
- Clarify "Change outputs" to "Tweaks for change outputs" (line 98)
- Add note that message is separate from CCD bundle
- Add note on application-specific verification (addresses, amounts)
- Add transition sentence clarifying non-concurrent protocol scope

* Add changelog entry for 0.1.3

* Fix header: use Authors (plural) for multiple authors

* Fix BIP header format for CI compliance

- Change Type from 'Standards Track' to 'Specification' (valid type)
- Change 'Created' to 'Assigned' (correct field name per BIP format)
- Change 'Post-History' to 'Discussion' (recognized field in buildtable.pl)

* Apply suggestion from @murchandamus

---------

Co-authored-by: Jesse Posner <jesse.posner@gmail.com>
2026-02-04 12:58:08 -08:00
Mark "Murch" Erhardt
5d0f70a5cf
Merge pull request #2094 from ajtowns/202601-bip434-copyright
BIP 434: fix license inconsistency
2026-02-02 21:01:54 -08:00
Anthony Towns
3709d73c2f BIP 434: fix license inconsistency 2026-02-03 14:47:51 +10:00
Mark "Murch" Erhardt
29b48129b1
Merge pull request #2092 from ajtowns/202601-feature-shortid
BIP 324, 434: Specify p2p v2 one-byte identifier for FEATURE message
2026-02-02 16:22:41 -08:00
yyhrnk
e3c4dede41
fix: correct TxFieldSelector index upper bound 2026-02-02 19:48:05 +02:00
Anthony Towns
a50c0ea32b BIP324, BIP434: Assign message type id for "feature" message 2026-01-31 17:47:59 +10:00
Anthony Towns
df1f098a8b BIP324, BIP183: Add utreexo's p2pv2 message type ids 2026-01-31 17:46:29 +10:00
Anthony Towns
a3370b5c9d BIP 324: Add auxiliary file tracking assignments of one-byte message type IDs 2026-01-31 17:46:29 +10:00
Mark "Murch" Erhardt
43e3983e4b
Merge pull request #2086 from ajtowns/202512-bip324-shortid-alias
BIP 324: Clarify equivalence between 1 and 13 byte message types
2026-01-29 10:18:01 -08:00
Mark "Murch" Erhardt
e169a61940
Merge pull request #2084 from theStack/bip374-vendor-secp256k1lab
BIP-374: vendor secp256k1lab and use it for reference implementation
2026-01-28 10:31:32 -08:00
Mark "Murch" Erhardt
3177af3bbf
Merge pull request #2076 from ajtowns/202512-p2p-feature
BIP 434: Peer Feature Negotiation
2026-01-27 07:22:58 -08:00
Mark "Murch" Erhardt
4c2f6567b3
Merge pull request #1500 from stevenroose/txhash
BIP346: OP_TXHASH
2026-01-27 07:21:12 -08:00
Anthony Towns
40e6634a2e BIP324: define message_length 2026-01-24 16:38:00 +10:00
Anthony Towns
4c80568652 BIP324: supporting 1 byte message type ids means supporting the equivalent 12 byte ASCII message types 2026-01-24 16:38:00 +10:00
Steven Roose
6a0636da32 Add BIP-346: OP_TXHASH 2026-01-22 22:59:40 -03:00
Jon Atack
ecb074d487
Merge pull request #2088 from murchandamus/backfill-bip14-discussion 2026-01-16 20:35:03 -08:00
Murch
1761675f67
BIP14: Backfill discussion URLs 2026-01-16 13:11:13 -08:00
Anthony Towns
48c0f201aa BIP324: Add Version header and Changelog section 2026-01-16 10:04:38 +10:00
Anthony Towns
9630c4c8d0 BIP434: p2p feature negotiation 2026-01-15 17:20:45 +10:00
Sebastian Falbesoner
2b7f07986b BIP-374: mention secp256k1lab in BIP text 2026-01-15 01:55:55 +01:00
Sebastian Falbesoner
436a3dd1fa BIP-374: use tagged_hash and xor_bytes routines from secp256k1lab 2026-01-15 00:56:13 +01:00
Sebastian Falbesoner
459d977d9b BIP-374: replace secp256k1.py with vendored copy of secp256k1lab 2026-01-15 00:47:29 +01:00
Sebastian Falbesoner
4e18ee641b BIP-374: avoid using sys.path[0] to find current working directory
This approach is incompatible with the sys.path extension approach
in the next commit which is used to to find the vendored copy of
secp256k1lab, so use __file__ instead which works as well.
2026-01-15 00:45:33 +01:00
Sebastian Falbesoner
d2ceae1dd6 Merge commit '3050bb6b25c0c20b62e2fc1a23276a09d50d151b' as 'bip-0374/secp256k1lab' 2026-01-15 00:43:29 +01:00
Sebastian Falbesoner
3050bb6b25 Squashed 'bip-0374/secp256k1lab/' content from commit 44dc4bd
git-subtree-dir: bip-0374/secp256k1lab
git-subtree-split: 44dc4bd893b8f03e621585e3bf255253e0e0fbfb
2026-01-15 00:43:29 +01:00
Jack D
68df14bf8c
BIP174: Specify PSBT_IN_PREVIOUS_TXID serialization order (#2001)
* specify PSBT_IN_PREVIOUS_TXID serialization order

* fix: remove ambiguous use of endianness language
2026-01-14 13:44:17 -08:00
Mark "Murch" Erhardt
df57b45a63
Merge pull request #2083 from jonatack/2026-bip3-edits
README intro edits
2026-01-14 13:41:19 -08:00
Jon Atack
48beda420e README edits 2026-01-14 14:49:18 -06:00
Jon Atack
845e7d7005
Merge pull request #1820 from murchandamus/2025-04-bip3-activation
Process: Activate BIP3
2026-01-14 09:06:43 -08:00
Dan Gould
1c4fe8dfea
BIP77: Change sequence diagrams to text format (#2064)
Updated sequence diagrams to use text format instead of mermaid syntax.

I cargo cult'd the RFC Rules:

> “How are images handled for the plain text version of an RFC?”
> The RFC Editor will accept both ASCII art and SVG. If only ASCII art is provided, it will be included in all publication formats. If ASCII art and SVG are both provided, ASCII art will be included in the plain text, and SVG in all other outputs. A note indicating alternative artwork is available is strongly advised. If only SVG is provided, a URI will be included in the plain-text publication format pointing to the HTML version. All artwork and figures should have a complete written description to support assisted reader technology.

see: https://www.rfc-editor.org/rse/format-faq/

Since BIPs don't publish html/pdf renders, ASCII art seems like the right choice to render everywhere. Since normative prose is already provided, I chose not to include a written description of the diagrams to support assisted reader tech.
2026-01-13 12:50:52 -08:00
Murch
4486d6de91
process: Backfill missing Version headers
…for BIPs that have a Changelog section that mentions a version.
BIP 1 and BIP 340 have Changelog sections, but do not define versions.
2026-01-12 14:36:33 -08:00
Murch
76efa4aabf
process: Fix up license sections to match preamble
Co-authored-by: Jon Atack <jon@atack.com>
2026-01-12 14:30:03 -08:00
Tim Ruffing
8586c32fa2
process: Use "official" SPDX identifiers
See https://spdx.org/licenses/
2026-01-12 14:30:02 -08:00
Tim Ruffing
764409cb37
bip2: Use correct SPDX license ids in the text
See https://spdx.org/licenses/
2026-01-12 14:30:00 -08:00
Tim Ruffing
7c3fab6fa7
bip134: Remove wrong License header
The Copyright section specifies additional conditions, so the License
header is not correct (or at least misleading). So let's just remove it.
This is pragmatic because the field was only added as part of the
activation of BIP 2 anyway, and there are other old BIPs with a License
header.
2026-01-12 14:29:59 -08:00
Anthony Towns
2885f13d3f
Convert licenses to SPDX codes 2026-01-12 14:29:57 -08:00
Murch
24e96e870f
process: Created ↦ Assigned
```
sed -z -i 's/Created: /Assigned: /' bip-0*.md
sed -z -i 's/Created: /Assigned: /' bip-0*.mediawiki
```
2026-01-12 14:29:51 -08:00
Yuval Kogman
85c9385e20
Allow Version field in checks as per BIP 3 2026-01-12 14:29:16 -08:00
Murch
ebefd42cc8
editor: Remove outdated comment from README table 2026-01-12 14:29:15 -08:00
Murch
6829b943bd
process: Drop unused Discussions-To Header 2026-01-12 14:29:13 -08:00
Murch
38f525beac
BIP372: Drop redundant Discussions-To Header
BIP2 states that the Discussions-To header should only be used if the
proposal was discussed somewhere else beside the Bitcoin Developer
Mailing List. Therefore, the only use of the Discussions-To header in
the repository is unnecessary and can be removed before the header is
abolished.
2026-01-12 14:29:12 -08:00
Murch
b712509434
process: Update license check 2026-01-12 14:29:10 -08:00
Murch
fea4a0b0c5
process: Increase title limit 2026-01-12 14:29:09 -08:00
Murch
3fddf95984
process: Allow Deputies header 2026-01-12 14:29:07 -08:00
Murch
5207ef92a5
process: Author ↦ Authors
```
sed -z -i 's/Author: /Authors: /' bip-0*.md
sed -z -i 's/Author: /Authors: /' bip-0*.mediawiki
```

Also align correctly in case of multiple authors.
2026-01-12 14:29:00 -08:00
Murch
59730dec4f
process: Remove Comments-URI and -Summary
```
sed -i '0,/Comments-Summary/{/Comments-Summary/d}' bip-0*md
sed -i '0,/Comments-Summary/{/Comments-Summary/d}' bip-0*mediawiki
sed -i '0,/Comments-URI/{/Comments-URI/d}' bip-0*md
sed -i '0,/Comments-URI/{/Comments-URI/d}' bip-0*mediawiki
```

Then reset the BIPs with non-empty comment wikis:

- bip-0037.mediawiki
- bip-0038.mediawiki
- bip-0039.mediawiki
- bip-0042.mediawiki
- bip-0044.mediawiki
- bip-0047.mediawiki
- bip-0049.mediawiki
- bip-0060.mediawiki
- bip-0061.mediawiki
- bip-0074.mediawiki
- bip-0075.mediawiki
- bip-0077.md
- bip-0084.mediawiki
- bip-0090.mediawiki
- bip-0118.mediawiki
- bip-0125.mediawiki
- bip-0150.mediawiki
- bip-0151.mediawiki
- bip-0152.mediawiki
- bip-0171.mediawiki
- bip-0172.mediawiki
- bip-0173.mediawiki
- bip-0174.mediawiki
- bip-0176.mediawiki
- bip-0178.mediawiki
- bip-0199.mediawiki
- bip-0322.mediawiki
- bip-0340.mediawiki
- bip-0341.mediawiki
2026-01-12 14:28:37 -08:00
Murch
01352f7f40
process: Post-History ↦ Discussion
Also line up with additional items in the lines below.

```
sed -i -z 's/  Post-History: /  Discussion:   /' bip-0*.md
sed -i -z 's/  Post-History: /  Discussion:   /' bip-0*.mediawiki
```
2026-01-12 14:28:06 -08:00
Murch
863573ab0f
BIP135: Move discussion to correct header 2026-01-12 14:22:41 -08:00
Murch
a233bde4af
process: Standards Track ↦ Specification
```
sed -z -i 's/Type: Standards Track/Type: Specification/' bip-0*.md
sed -z -i 's/Type: Standards Track/Type: Specification/' bip-0*.mediawiki
```

After the scripted changes, the changes to BIP-40, BIP-41, and BIP-63
were undone, because it breaks CI.

These three BIPs only exist conceptually and their proposal documents
are missing which causes changes to them ot break the CI. I defer the
changes to these BIPs to a separate pull request to get CI to pass.
2026-01-12 14:22:40 -08:00
Murch
ff1f3b36f8
process: Superseded-By ↦ Proposed-Replacement
sed -z -i 's/Superseded-By: /Proposed-Replacement: /' bip-0*.md
sed -z -i 's/Superseded-By: /Proposed-Replacement: /' bip-0*.mediawiki
2026-01-12 14:22:38 -08:00
Murch
66defbdc03
process: Deferred/Obsolete/Rejected/Replaced/Withdrawn ↦ Closed
```
sed -z -i 's/Status: Deferred/Status: Closed/' bip-0*.md
sed -z -i 's/Status: Deferred/Status: Closed/' bip-0*.mediawiki
sed -z -i 's/Status: Obsolete/Status: Closed/' bip-0*.md
sed -z -i 's/Status: Obsolete/Status: Closed/' bip-0*.mediawiki
sed -z -i 's/Status: Rejected/Status: Closed/' bip-0*.md
sed -z -i 's/Status: Rejected/Status: Closed/' bip-0*.mediawiki
sed -z -i 's/Status: Replaced/Status: Closed/' bip-0*.md
sed -z -i 's/Status: Replaced/Status: Closed/' bip-0*.mediawiki
sed -z -i 's/Status: Withdrawn/Status: Closed/' bip-0*.md
sed -z -i 's/Status: Withdrawn/Status: Closed/' bip-0*.mediawiki
```

```
    sed -i 's/| Deferred/| Closed/' README.mediawiki
    sed -i 's/| Obsolete/| Closed/' README.mediawiki
    sed -i 's/| Rejected/| Closed/' README.mediawiki
    sed -i 's/| Replaced/| Closed/' README.mediawiki
    sed -i 's/| Withdrawn/| Closed/' README.mediawiki
```
2026-01-12 14:22:36 -08:00
Murch
5d3ceb3773
process: Final/Active ↦ Deployed
```
sed -z -i 's/Status: Active/Status: Deployed/' bip-0*.md
sed -z -i 's/Status: Active/Status: Deployed/' bip-0*.mediawiki
sed -z -i 's/Status: Final/Status: Deployed/' bip-0*.md
sed -z -i 's/Status: Final/Status: Deployed/' bip-0*.mediawiki
sed -i 's/| Active/| Deployed/' README.mediawiki
sed -i 's/| Final/| Deployed/' README.mediawiki
```
2026-01-12 14:22:33 -08:00
Murch
6760ba8738
process: Proposed ↦ Complete
Amend CI script to new statuses and update existing status field values
in table and BIPs.

```
sed -z -i 's/Status: Proposed/Status: Complete/' bip-0*.md
sed -z -i 's/Status: Proposed/Status: Complete/' bip-0*.mediawiki
sed -i 's/| Proposed/| Complete/' README.mediawiki
```
2026-01-12 14:22:30 -08:00
Murch
2f497a2bbe
process: Clarify handling of controversial BIPs
It is preferable to close PRs over having them stuck in controversy
limbo indefinitely.
2026-01-12 14:22:29 -08:00
Murch
68c12c7f7a
process: Update README to match BIP3 2026-01-12 14:22:27 -08:00
Murch
4f412a4af0
process: Activate BIP3, close BIP2 2026-01-12 14:22:25 -08:00
Olaoluwa Osuntokun
1a75a3dc13
Merge pull request #1982 from instagibbs/2025-09-p2a
BIP 433: Add P2A BIP
2026-01-08 19:18:05 -08:00
Tim Ruffing
e2f9fe0c04
BIP-327: correct DeterministicSign pubnonce and key length (#2071)
Co-authored-by: lisenokdonbassenok <lisdonbassa@gmail.com>
2026-01-05 10:23:11 -08:00
Jon Atack
fc00f51c22
Merge pull request #2057 from maradini77/patch-2
BIP158, refactor: remove duplicate conditional
2025-12-26 07:24:58 -08:00
Anthony Towns
04b448b599
CI: commit README.mediawiki delta from script to git (#2063)
Use a hardcoded delta rather than requiring the delta to never change,
so that it can be changed deliberately when desired without breaking CI.
Also avoids the need to checkout the previous commit, so no longer
changes the repository state.
2025-12-19 19:18:41 -08:00
lisenokdonbassenok
6441993757
BIP-310: fix version-rolling.min-bit-count parameter spec 2025-12-18 14:46:10 +02:00
Jon Atack
46858e5b1f
Merge pull request #2058 from kurahin/fix/bip322-proof-of-funds-inputs 2025-12-16 17:59:57 -08:00
VolodymyrBg
1e663c2150
BIP-337: fix incorrect reference in Input Data Outpoint row (#2053)
* BIP-337: fix incorrect reference in Input Data Outpoint row

* Fix typo in BIP 337
2025-12-15 18:17:04 -08:00
Jon Atack
f427295acc
Merge pull request #2051 from murchandamus/2025-12-bip3-address-activation-motion-feedback 2025-12-15 15:16:23 -08:00
Jon Atack
870c7629ae
Merge pull request #2056 from ajtowns/202512-bip325-signet-powlimit
bip-325: document signet minimum difficulty
2025-12-15 10:40:23 -08:00
Ben Westgate
98935ff1f9
BIP93: terminology, typo, and phrasing fixups (#2052)
* Change master seed to secret in most places, ''t'' to ''k'' and other term fixes

* Replace deleted linebreak, delete vestigal oxford commas

* errors->random errors, fix newlines, vector5: secret seed->codex32 secret

reduced the heading level of checksum and error correction to make the table of contents easier to parse.

Moved Master seed Encoding to be below Unshared Secret.

* BIP93: change codex32 characters to bech32 characters

* Fix hrp length off by 1 bug. Refactor validity condition to read easier.
2025-12-15 09:29:21 -08:00
kurahin
80b4b2a6bd
BIP-322: fix proof-of-funds inputs wording 2025-12-14 22:32:04 +02:00
maradini77
76059ea230
Update gentestvectors.go 2025-12-14 17:54:59 +01:00
Anthony Towns
56e909458b bip-325: document signet minimum difficulty
This was implicit in the genesis block's nbits value, but better to be clearer.
2025-12-14 06:00:53 +10:00
Murch
897fa1b9df
bip3: Do not waste community’s time
Co-authored-by: jon@atack.com
2025-12-11 13:30:24 -08:00
Murch
a9308f362e
bip3: Require technical soundness
Co-authored-by: jon@atack.com
2025-12-11 09:12:46 -08:00
Murch
41fe83f750
bip3: Add and backfill Changelog section
The Version header is omitted at this time, as it is not permitted under BIP 2.
2025-12-11 08:56:35 -08:00
Murch
f389e9b1bb
bip3: Avoid onus 2025-12-11 08:56:33 -08:00
Murch
f29514f21c
bip3: Fix capitalization and drop footnote 2025-12-11 08:56:31 -08:00
Luke Dashjr
5fd4162378
bip-0003: Changes from BIP 2: Make it match actual spec 2025-12-11 08:56:30 -08:00
Luke Dashjr
86d9737e41
bip-0003: Move Type header responsibility to the author(s) 2025-12-11 08:56:28 -08:00
Murch
e44d11ebb9
bip3: Clarify that draft needs to be discussed on ML 2025-12-11 08:56:27 -08:00
Murch
25810a0a4a
bip3: Avoid implying BIP editors must reply to every ML post
Co-authored-by: Luke Dashjr <luke-jr+git@utopios.org>
2025-12-11 08:56:25 -08:00
Murch
6f62034db8
bip3: Clarify editor assignment of BIP numbers
Adopted from:
a399d0791dk

Co-authored-by: luke+github_public@dashjr.org
2025-12-11 08:56:22 -08:00
Murch
56ac1c2686
bip3: Broaden reference implementation formats
Based on Luke Dashjr’s b46e8195914fc3479760fef4c443390c01825e63
2025-12-09 15:54:39 -08:00
Murch
3d07d12de5
Revert "BIP3: add guidance on originality, quality, LLMs"
This reverts commit d083ce5a9b.
2025-12-09 14:53:26 -08:00
Galoretka
6ce21f4eae
bip-373: Fix GLOBAL_XPUB key name and clean up compressed vs x-only note (#2007)
* bip-373: Fix GLOBAL_XPUB key name and clean up compressed vs x-only note

* add requires
2025-12-09 08:33:04 -08:00
Jon Atack
7635df6fd3
Merge pull request #2034 from hodlinator/2025/11/bip53/inversion_typo 2025-12-09 08:30:36 -08:00
Greg Sanders
ab9bc69f93 Add BIP433 Pay to Anchor (P2A) 2025-12-09 11:11:03 -05:00
Jon Atack
d00a52376d
Merge pull request #2009 from radik878/fix/bip-0371-psbt-key-sig-name
BIP-371: use canonical PSBT_IN_TAP_KEY_SIG in invalid test titles
2025-12-08 12:53:29 -08:00
Mark "Murch" Erhardt
618ce32488
Merge pull request #2028 from scgbckbone/bip-0373-wording
nit: improve `PSBT_IN_MUSIG2_PARTIAL_SIG` wording
2025-12-08 11:38:05 -08:00
Mark "Murch" Erhardt
e15bba9273
Merge pull request #1971 from brunoerg/2025-09-psbt-invalid-data-size
bip174: add test case for an invalid valuedata due to its size
2025-12-08 11:34:42 -08:00
Mark "Murch" Erhardt
28616a4d0c
Merge pull request #2050 from yyhrnk/fix/bip390-musig-rawtr-usage
BIP-390: allow musig() under rawtr()
2025-12-08 11:10:44 -08:00
Mark "Murch" Erhardt
afa18e4dbb
Merge pull request #2044 from darosior/2511_bip54_forward_compat
bip-0054: update forward compat section with Bitcoin Core v30
2025-12-08 10:21:46 -08:00
yyhrnk
7e8facb479
BIP-390: allow musig() under rawtr() 2025-12-08 18:14:55 +02:00
Hodlinator
c569e23641
BIP53: Use different notation for txids and tx-bytes 2025-11-27 21:03:42 +01:00
Hodlinator
cbaedf2dfc
BIP53: Clarify wording around implementation complexity
Co-authored-by: Chris Stewart <stewart.chris1234@gmail.com>
2025-11-26 17:30:44 +01:00
Jon Atack
9a30c28574
Merge pull request #2045 from darosior/bip54_vectors_link
bip-0054: correct link typo in test vectors README
2025-11-25 16:58:16 -08:00
Antoine Poinsot
a86abbe2c1 bip-0054: correct link typo in test vectors README 2025-11-25 18:18:01 -05:00
Antoine Poinsot
1076d90678 bip-0054: update forward compat section with Bitcoin Core v30
The BIP 54 sigops limit was made a standardness rules in Bitcoin Core 30.0.
2025-11-25 14:03:52 -05:00
Jon Atack
2624ef7b83
Merge pull request #2015 from darosior/2509_consensus_cleanup_test_vectors
BIP54: Consensus Cleanup test vectors
2025-11-25 09:56:13 -08:00
Jon Atack
3851847d0a
Merge pull request #2035 from Bashmunta/fix/bip8
BIP-116: add link to bip-8 and fix collision
2025-11-20 12:10:54 -08:00
Mark "Murch" Erhardt
66a41d32bf
Merge pull request #2036 from instagibbs/2025-11-bip54_sum_sigops
bip54: clarify sigops counting, borrow bip16 language
2025-11-17 10:45:55 -08:00
Greg Sanders
459298ab0e bip54: clarify sigops counting, borrow bip16 language 2025-11-14 10:18:38 -05:00
Mark "Murch" Erhardt
bbaea3182b
Merge pull request #2020 from jonatack/2025-10-bip3-dedicated-ML-thread
BIP 3: mention posting a dedicated ML thread
2025-11-12 16:57:50 -08:00
Bashmunta
22fc58d746
Update bip-0116.mediawiki 2025-11-11 23:30:23 +02:00
Mark "Murch" Erhardt
445e445144
Merge pull request #2022 from jonatack/2025-10-bip3-number-assignment
BIP3: clarify number assignment
2025-11-10 08:20:07 -08:00
scgbckbone
65daaf2fa3 nit: improve PSBT_IN_MUSIG2_PARTIAL_SIG wording 2025-11-02 02:19:20 +01:00
Jon Atack
b13e4913b0 bip3: clarify number assignment 2025-10-28 15:43:48 -06:00
Jon Atack
5607f64d0d bip3: mention posting a dedicated ML thread 2025-10-27 11:12:26 -06:00
Antoine Poinsot
0777a81367 bip-0054: document the test vectors 2025-10-27 04:10:26 -04:00
Jon Atack
c9a6ca6297
Merge pull request #2018 from sashass1315/fix-broken-link
BIP-119: fix broken link
2025-10-26 14:54:13 -07:00
sashass1315
5948b7243b
BIP-119: fix broken link 2025-10-26 20:35:30 +02:00
Jon Atack
fd7fe26a7e
Merge pull request #2016 from real-or-random/202510-fix-gen-test-vectors 2025-10-24 04:23:31 -07:00
Tim Ruffing
713f000a20 bip324: Update generated files 2025-10-23 14:18:35 +02:00
phrwlk
d51f2dcaeb BIP324: Fix features bitmask for decoding-case selection 2025-10-23 14:18:35 +02:00
Mark "Murch" Erhardt
964ce2d371
Merge pull request #1975 from brunoerg/2025-09-torv2
bip155: mark torv2 as no longer in use
2025-10-23 10:13:11 +02:00
Bruno Garcia
7fd375c0e9 bip155: add changelog 2025-10-23 09:52:13 +02:00
Jon Atack
34c584d54a
Merge pull request #2011 from Forostovec/master 2025-10-22 18:24:18 -07:00
Mark "Murch" Erhardt
6953b72947
Merge pull request #2006 from jonatack/2025-10-bip3-adjustments
BIP3: add guidance on originality, quality, LLMs
2025-10-22 09:24:37 +02:00
Jon Atack
d083ce5a9b BIP3: add guidance on originality, quality, LLMs
and soundness, and ensure it was proposed to the ML by one of the BIP authors
2025-10-21 09:32:48 -06:00
Antoine Poinsot
30b0084808 bip-0054: add test vectors for each mitigation
This introduces a set of test vectors for each of the 4 mitigations in the BIP. The sigops and
transaction size vectors were generated using the unit tests included with the Bitcoin Core
implementation of BIP54, available at https://github.com/darosior/bitcoin/tree/2509_inquisition_consensus_cleanup.
The timestamps and coinbases required mainnet blocks for maximum compatibility, and were generated
by two dedicated unit tests not included with the Bitcoin Core implementation above but available at
https://github.com/darosior/bitcoin/tree/bip54_miner.
2025-10-20 08:53:57 -04:00
Antoine Poinsot
89dfe03a64 bip-0054: add a reference implementation section 2025-10-20 08:53:51 -04:00
Forostovec
1bb1aee5b0
BIP-374: Pass G and m to VerifyProof in GenerateProof self-check 2025-10-19 13:21:14 +03:00
radik878
2bdb5ec72f
BIP-371: use canonical PSBT_IN_TAP_KEY_SIG in invalid test titles 2025-10-18 22:28:16 +03:00
Jon Atack
1d186274ea
Merge pull request #2002 from MozirDmitriy/fix/bip340-test-harness-keygen-failure-flag 2025-10-16 04:02:23 -07:00
3rd Iteration
ab9d5b8b5d
BIP85: fix datetime string to align with UNIX Epoch time (#1967)
* Fix BIP85 human-readable datetime string and update the Changelog

Genesis block time is correct in Unix time, but the human-readable datetime string is off by 10 minutes.

Co-authored-by: Jon Atack <jon@atack.com>
2025-10-15 10:14:53 -07:00
MozirDmitriy
f98774a68c
bip-340: set all_passed=False on key generation mismatch 2025-10-14 23:38:26 +03:00
Mark E. Jeftovic
1cf4130876
BIP‑353: Clarify TXT record structure and concatenation order (single RR; RDATA order; no cross‑RR joins) (#2000) 2025-10-10 17:12:06 -07:00
Mark "Murch" Erhardt
3d0bab3cc2
Merge pull request #1998 from jonatack/2025-10-typo-and-editorial-fixups
Collect and curate various minor fixups from Jul/Aug/Sept
2025-10-06 14:38:45 -07:00
viktorking7
664d376c8a CI: improve date validation regex in buildtable.pl
and quote filename variable in link format checker script

Co-authored-by: bigbear <155267841+aso20455@users.noreply.github.com>
Co-authored-by: Jon Atack <jon@atack.com>
2025-10-03 13:35:31 -06:00
sashaodessa
6340cecfbc BIPs 119, 330, 352: code typo and style fixups
Co-authored-by: Tomass <155266802+zeroprooff@users.noreply.github.com>
Co-authored-by: emmmm <155267286+eeemmmmmm@users.noreply.github.com>
2025-10-03 13:35:31 -06:00
Skylar Ray
9297c12729 BIPs 327, 340: remove unused imports
Co-authored-by: Snezhkko <snezhkodaria38@gmail.com>
2025-10-03 13:35:31 -06:00
Tomás Andróil
5d06b3b976 BIPs 16, 388, 443: typo and editorial fixups
Co-authored-by: futreall <86553580+futreall@users.noreply.github.com>
2025-10-03 13:34:51 -06:00
MozirDmitriy
a00fb712c5 BIP10: typo fix, replace TXSIGS with SIG in TxDP merge section 2025-10-03 13:13:05 -06:00
Bruno Garcia
c85c818e3f bip155: torv2 is no longer operational 2025-10-02 08:43:24 -03:00
Mark "Murch" Erhardt
b92cb0b627
Merge pull request #1983 from jonatack/2025-09-BIP321-add-reference-implementation
BIP321: add reference implementation, mention BIP21 replacement
2025-10-01 14:35:32 -07:00
Jon Atack
5e178c980c
Merge pull request #1996 from jonatack/2025-10-update-typos-linter
CI: appease typos linter
2025-10-01 12:35:55 -07:00
Jon Atack
6c725aa4f5 CI: appease typos linter 2025-10-01 13:31:48 -06:00
Jon Atack
c16a33647a BIP321: mention replacement of BIP21
rather than only modification, for consistency with the "Replaces: 21" header
2025-09-30 10:22:43 -06:00
Jon Atack
daf64c4253 BIP321: add reference implementation section 2025-09-30 10:22:25 -06:00
Jon Atack
c5cb824795
Merge pull request #1912 from TheBlueMatt/2025-08-dnssec-proof-tests
Add some BIP 353 DNSSEC proof test vectors and links
2025-09-24 15:49:24 -07:00
Jon Atack
898693d83e
Merge pull request #1980 from murchandamus/2025-09-active-to-final
BIP327,353: Update to Final and Proposed instead of Active
2025-09-24 08:20:30 -07:00
Matt Corallo
c02809a75a Correct monospacing in BIP 353
mediawiki doesn't render backticks, so we have to use
`<code></code>`.
2025-09-23 22:00:49 +00:00
Matt Corallo
87bafc1cd0 Add some BIP 353 DNSSEC proof test vectors and links 2025-09-23 21:58:18 +00:00
Murch
cc68e6d753
BIP327,353: Correct statuses
- 327 should be Final instead of Active
- 353 should be Proposed, as Testvectors are still in the works (see
  #1912)
2025-09-23 14:49:38 -07:00
Jon Atack
e757aaf19a
Merge pull request #1979 from murchandamus/2025-09-advance-BIP353
BIP353: Advance to Active
2025-09-23 14:17:12 -07:00
Murch
e9b1100912
BIP353: Advance to Active
BIP 353 has been implemented by multiple projects.
2025-09-23 13:56:54 -07:00
Jon Atack
1c4d41937b
Merge pull request #1911 from TheBlueMatt/2024-03-uris-without-bodies
Mark BIP21 as replaced by 321, update 321 from Draft to Proposed
2025-09-23 10:22:40 -07:00
Jon Atack
87f3fe1644
Merge pull request #1970 from murchandamus/2025-09-assigned-header
BIP3: Rename Created to Assigned
2025-09-19 16:31:04 -07:00
Bruno Garcia
97885721b8 bip174: add test case for an invalid valuedata due to its size 2025-09-18 16:58:20 -03:00
Murch
d7847195aa
BIP3: Rename Created to Assigned 2025-09-18 12:50:30 -07:00
Jon Atack
6730ee8a1e
Merge pull request #1926 from radik878/test/dleq-pass-message-in-tampered-proof
BIP374: in tests, pass message when verifying proof with message
2025-09-17 09:52:16 -07:00
Mark "Murch" Erhardt
869fd7765f
Merge pull request #1963 from jonatack/2025-09_update_BIPs_157-158_to_final
BIPs 157, 158: update status to Final, add Requires header
2025-09-15 13:53:46 -07:00
Jon Atack
02fb392db9 BIPs 157, 158: add "Requires" headers to each other 2025-09-10 21:37:39 -06:00
Jon Atack
662cc78c3e BIP158: update status from Draft to Final 2025-09-10 21:29:43 -06:00
Jon Atack
3ba957d8d5 BIP157: update status from Draft to Final 2025-09-10 21:29:05 -06:00
Mark "Murch" Erhardt
abf3bdab29
Merge pull request #1956 from jonatack/2025-09-update-BIP111-status-from-Proposed-to-Final
BIP111: update status from Proposed to Final
2025-09-10 14:10:03 -07:00
prestoalvarez
d9888173b6 Fix file permissions for bip-0069_examples.py 2025-09-07 23:29:24 +03:00
Jon Atack
d1af997a6f BIP111: update status from Proposed to Final 2025-09-05 11:19:59 -06:00
Jon Atack
eabb63cb53
Merge pull request #1953 from macgyver13/bip352-generate-intermediate-comp
BIP352: Add intermediate vector material for silent payments
2025-09-05 08:46:36 -07:00
macgyver13
b7c79dcbc0 address feedback (newline + extra whitespace) 2025-09-04 17:17:38 -04:00
Jon Atack
f420c7f614
Merge pull request #1952 from MozirDmitriy/mzd
BIP388: fix variable name in from_descriptor() to prevent NameError
2025-09-04 13:35:53 -07:00
macgyver13
b26f77db65 add intermediate vector material, validate added material in reference tests 2025-09-04 11:52:17 -04:00
MozirDmitriy
25ffcfcf36
fix(wallet_policies): use descriptor instead of desc to prevent NameError 2025-09-04 10:22:16 +03:00
Jon Atack
4d6cd518a0
Merge pull request #1950 from darosior/2509_bip54_fix_date
bip54: fix off-by-one in creation date
2025-09-03 14:06:40 -07:00
Antoine Poinsot
32bcfd6801 bip54: fix off-by-one in creation date 2025-09-03 16:55:29 -04:00
Jon Atack
d588494bec
Merge pull request #1947 from aso20455/master
BIP328: fix assignment in bytes_to_point function
2025-09-02 16:57:25 -07:00
Mark "Murch" Erhardt
260da85921
Merge pull request #1933 from jonatack/2025-08-update-BIP155-status
BIP155: update status from Draft to Final
2025-09-02 15:35:32 -07:00
Jon Atack
862d9ca106 BIP155: update Draft status to Final
BIP155 was deployed in Bitcoin Core version v0.21.0, and has been in use for
almost 5 years.

New networks may be added to the reserved network IDs table when they're
needed, either in this BIP or in a new one.

If BIP3 is activated, I think BIP155 would become Deployed.

Co-authored-by: Murch <murch@murch.one>
Co-authored-by: laanwj <126646+laanwj@users.noreply.github.com>
2025-09-01 09:08:50 -06:00
bigbear
9d3ca7f31f
fix: correct variable assignment in bytes_to_point function 2025-08-30 11:41:58 +02:00
strmfos
0712585a1c
BIP-158: replace deprecated io/ioutil with os.ReadFile 2025-08-28 13:11:57 +02:00
Mark "Murch" Erhardt
86b29c5d81
Merge pull request #1941 from jonatack/2025-08-bip2-licenses
BIP2: license section fixups
2025-08-25 11:58:40 -07:00
Alvarez
ba843e29b1 BIP69: fix output inconsistency and update to python3
- Fix print_outputs() to use sorted output tuples instead of unsorted
- Add Python 3 compatibility using functools.cmp_to_key()
- Convert string hashes to byte arrays in second example
- Make file executable with shebang for python3
- Add clearer output formatting with transaction hashes and section headers
2025-08-23 12:27:05 +03:00
Jon Atack
c23b8a958e BIP2: fix 301 redirects in license URLs
Co-authored-by: 1BitcoinBoWP1FZ4xwTNkq6XksKidmgYYw <contact@bitcoin.foundation>
2025-08-21 16:44:59 -06:00
Jon Atack
7511c7ec77 BIP2: update MIT license name
per both of:

- https://opensource.org/license/MIT
- https://spdx.org/licenses/MIT

Co-authored-by: Murch <murch@murch.one>
2025-08-21 16:44:34 -06:00
Mark "Murch" Erhardt
2e3dd3f273
Merge pull request #1940 from jonatack/2025-08-bip3-licenses
BIP3: license section updates
2025-08-21 14:34:35 -07:00
Jon Atack
3f2a403f69
Merge pull request #1939 from ethicnology/master
BIP85: replace Base64 by Base85 in PWD BASE85 section
2025-08-21 08:48:35 -07:00
ethicnology
3e9befd444
refactor: unify capitalization 2025-08-21 07:46:21 -04:00
ethicnology
2fc8da8871
fix: replace Base64 by Base85 encoding in PWD BASE85 section 2025-08-21 07:31:26 -04:00
Jon Atack
3f61b68f22 BIP3: update MIT license name
per both of:

- https://opensource.org/license/MIT
- https://spdx.org/licenses/MIT
2025-08-20 21:53:17 -06:00
1BitcoinBoWP1FZ4xwTNkq6XksKidmgYYw
e98fb73faa BIP3: add MIT-0 to acceptable licenses 2025-08-20 21:53:17 -06:00
1BitcoinBoWP1FZ4xwTNkq6XksKidmgYYw
d610c8a232 BIP3: fix license URLs with 301 redirects 2025-08-20 21:52:51 -06:00
sashass1315
4f00b499c9
BIP345: fix broken links (#1938)
* BIP345: fix broken links
2025-08-18 12:43:37 -07:00
Jon Atack
ebfcfa4808
Merge pull request #1935 from Fibonacci747/unused-import
BIP352: remove unused import from reference.py
2025-08-15 08:40:37 -07:00
Fibonacci747
4463068012
feat: remove unused permutations import from bip-0352/reference.py 2025-08-15 10:58:43 +02:00
Jon Atack
9a55a542cc
Merge pull request #1934 from strmfos/master
scripts: remove unused FILES variable in link-format-chk.sh
2025-08-14 07:05:45 -07:00
Jon Atack
e9181258a1
Merge pull request #1932 from ANtutov/broken-link
BIP345: fix broken link
2025-08-14 05:20:41 -07:00
strmfos
e8b9da9284
scripts: remove unused FILES variable in link-format-chk.sh 2025-08-14 11:53:03 +02:00
Jon Atack
9a2791bf8b
Merge pull request #1929 from jonatack/2025-08-ci-update
ci: update github actions checkout version
2025-08-13 07:40:26 -07:00
ANtutov
b786c64080
bip-0345: fix broken link 2025-08-13 08:56:35 +03:00
Jon Atack
647e40ea04
Merge pull request #1914 from Forostovec/fix/broken-link
BIP 70: fix link to payment request generator
2025-08-12 09:30:42 -07:00
Jon Atack
3eff7c9626 ci: update github actions checkout version
see https://github.com/actions/checkout/releases/tag/v5.0.0
2025-08-11 09:52:58 -06:00
radik878
90091a2d06
test(reference): pass message when verifying tampered proof 2025-08-11 10:36:43 +03:00
Jon Atack
4f1359d0f8
Merge pull request #1920 from strmfos/master
BIP374: remove debug print from test runner
2025-08-10 14:40:59 -07:00
strmfos
1421be407e
BIP374: remove debug print statement from BIP-374 test runner 2025-08-09 19:17:39 +02:00
Jon Atack
e97c908096
Merge pull request #1918 from murchandamus/bip3-reformat-existing-licenses
BIP3: Update License header format on activation
2025-08-09 10:05:07 -07:00
Murch
1fc26cbb24
BIP3: Update License header format on activation
Addresses follow-up from #1892
2025-08-08 17:21:17 -07:00
Jon Atack
3821aa3a1c
Merge pull request #1797 from shesek/patch-3 2025-08-08 11:59:09 -07:00
Matt Corallo
c7e9befc2e Mark BIP 21 as replaced (by BIP 321) and mark BIP 321 as Proposed 2025-08-07 11:57:06 +00:00
Forostovec
4a68f37bf7
fix: broken link to payment request generator 2025-08-07 12:48:58 +03:00
Mark "Murch" Erhardt
6c5d396fba
Merge pull request #1910 from bethoffman/fix-typo
BIP443: fix typo in the section "Transaction-wide initialization"
2025-08-05 15:40:32 -07:00
josie
3e15178a43
BIP352: add warning against omitting outputs (#1908)
* doc: add warning against omitting outputs

While implied by the specification, add an explicit warning that
generated outputs MUST not be omitted from the final transaction.

Co-authored-by: Mark "Murch" Erhardt <murch@murch.one>
2025-08-04 09:36:01 -07:00
hoffman
c72c59a8db
Update bip-0443.mediawiki 2025-08-02 11:42:07 +08:00
Jon Atack
31450c3dbd
Merge pull request #1905 from otc-png/patch-1
[bip-0010]: remove repeated "the"
2025-08-01 06:27:04 -07:00
Jon Atack
5dd89238bd
Merge pull request #1907 from anim001k/master
Fix dead link in BIP-70: Update Mozilla root store URL
2025-08-01 06:25:56 -07:00
Jon Atack
4dc2165dba
Merge pull request #1906 from GarmashAlex/links
Fix broken MES16.pdf link in BIP-347
2025-08-01 06:25:30 -07:00
anim001k
c038164697
Update bip-0070.mediawiki 2025-07-30 16:34:43 +02:00
Mark "Murch" Erhardt
b8a39dfba3
Merge pull request #1904 from jonatack/2025-07-remove-License-Code-from-BIP3
BIP3: drop optional License Code header
2025-07-29 08:33:01 -07:00
Jon Atack
6f2f4aa233 BIP3: refer to CC0 1.0 Universal
per https://creativecommons.org/publicdomain/zero/1.0/legalcode.en

and add a missing word

Co-authored-by: Tim Ruffing <crypto@timruffing.de>
2025-07-28 16:52:41 -06:00
Jon Atack
12dc0e04a2 BIP3: drop optional License Code header
Co-authored-by: Tim Ruffing <crypto@timruffing.de>
Co-authored-by: Murch <murch@murch.one>
2025-07-28 16:52:29 -06:00
GarmashAlex
f4787bdb6f
fix broken link 2025-07-29 00:28:51 +03:00
otc group
a3e4d14e0d
remove repeated "the" 2025-07-28 23:14:16 +02:00
Mark "Murch" Erhardt
7f13f8f9f5
Merge pull request #1899 from dplusplus1024/patch-7
BIP32: Use plural “bytes”
2025-07-28 13:53:04 -07:00
Jon Atack
0a8c271715
Merge pull request #1902 from josibake/bip352-updates
BIP352: be explicit for the input_hash corner case
2025-07-25 08:22:15 -07:00
josibake
c70bc9f018
doc: be explicit for the input_hash corner case 2025-07-25 15:07:52 +01:00
Jon Atack
e8c02024f0
Merge pull request #1901 from crStiv/typo
BIP77: fix links to Client/Directory interactions
2025-07-21 13:11:08 -07:00
crStiv
c83aeb8d28
Update bip-0077.md 2025-07-21 21:11:36 +02:00
Jon Atack
0f8a2269c2 Merge branch 'nothingmuch-field-ordering-pr'
* nothingmuch-field-ordering-pr:
  CI: Enforce BIP 2 & 3 field ordering requirements
  scripted-diff: fix BIP 2 field order violations
2025-07-20 14:29:41 -06:00
Yuval Kogman
0eb3718c5d CI: Enforce BIP 2 & 3 field ordering requirements
The specified field order is consistent with both BIPs 2 and 3. The
ordering of fields which are only present in one or the other is
ambiguous, e.g. as in `Proposed-Replacement` and `Superseded-By` but
only one of these applies to a given BIP.

The `Editor` field is spurious, only being used in BIP 69, and appears
after Author.
2025-07-20 14:29:13 -06:00
Yuval Kogman
cd19d89e58 scripted-diff: fix BIP 2 field order violations
-BEGIN VERIFY SCRIPT-
set -e
perl <<'-END PERL-'
use strict;
use warnings;

my $topbip = 9999;

my @FieldOrder = qw(
	BIP
	Layer
	Title
	Author
	Authors
	Editor
	Deputies
	Discussions-To
	Comments-Summary
	Comments-URI
	Status
	Type
	Created
	License
	License-Code
	Discussion
	Post-History
	Version
	Requires
	Replaces
	Proposed-Replacement
	Superseded-By
);

my $bipnum = 0;
while (++$bipnum <= $topbip) {
	my $fn = sprintf "bip-%04d.mediawiki", $bipnum;
	my $is_markdown = 0;
	if (!-e $fn) {
		$fn = sprintf "bip-%04d.md", $bipnum;
		$is_markdown = 1;
	}
	-e $fn || next;
	open my $F, "<", $fn or die "$!";

	my (@before, %preamble, @after);

	if ($is_markdown) {
		while (<$F>) {
			push @before, $_;
			last if m[^(?:\xef\xbb\xbf)?```$]
		}
		die "No ``` in $fn" if eof $F;
	} else {
		while (<$F>) {
			push @before, $_;
			last if m[^(?:\xef\xbb\xbf)?<pre>$];
		}
		die "No <pre> in $fn" if eof $F;
	}
	my %found;
	my ($title, $author, $status, $type, $layer);
	my ($field, $val, @field_order);
	while (<$F>) {
		push @after, $_ and last if ($is_markdown && m[^```$]);
		push @after, $_ and last if (!$is_markdown && m[^</pre>$]);

		if (m[^  ([\w-]+)\: (.*\S)$]) {
			$field = $1;
			$val = $2;
		} elsif (m[^  ( +)(.*\S)$]) {
			$val = $2;
		} else {
			die "Bad line in $fn preamble";
		}

		push @{$preamble{$field} ||= []}, $_;
	}
	push @after, <$F>;
	close $F or die $!;

	open my $W, ">", "$fn" or die "$!";

	print $W @before;
	print $W map { @$_ } grep { defined } delete @preamble{@FieldOrder};
	die "Unknown fields: @{[ keys %preamble ]}" if %preamble;
	print $W @after;

	close $W or die $!;
}
-END PERL-
-END VERIFY SCRIPT-
2025-07-20 14:29:13 -06:00
D++
651e273ee8
Fix: Use plural “bytes” in serialization table to match field size convention
Aligns the first field in the serialization table with the rest, which use plural “bytes” (e.g., “4 bytes: child number”) for consistency.
2025-07-19 18:07:10 -07:00
Jon Atack
340c1a3d53
Merge pull request #1892 from real-or-random/202507-spdx
bip3: Switch to SPDX identifiers
2025-07-18 13:45:02 -07:00
Tim Ruffing
88d29188c6 bip3: Editorial cleanup of the license lists 2025-07-18 13:29:46 +02:00
Tim Ruffing
7aa54dd696 bip3: Change License example to CC0-1.0 OR MIT
The actual reason why I suggest this is that I think that's a great
default choice for a new BIP, so it's a perfect example. CC0-1.0 is a
great liberal choice for the BIP document (and test vectors etc.), and
MIT is the common choice for code in our ecosystem. Putting both BIP and
code under the "OR" avoids any confusion about which part is licensed
under which terms and also avoids any hassle when reorganizing, e.g.,
when moving code out of the BIP Markdown file to a separate file etc.

But I don't want this PR to recommend a license, so let me sell this
change as an editorial change to an example, which is warranted because
the MIT is much more known than FSFAP, in particular in this ecosystem.
2025-07-18 13:29:46 +02:00
Tim Ruffing
0cc4d26e67 bip3: Editorial changes in "BIP Licensing" 2025-07-18 13:29:46 +02:00
Tim Ruffing
e1d72f0243 bip3: Recommend SPDX-License-Identifier comments 2025-07-18 13:29:46 +02:00
Tim Ruffing
3de6ed6dc0 bip3: Don't require omitting unacceptable licenses
I think that requirement is not helpful. I don't think hat including
additional licenses will be overwhelming to the reader. If anything, it
will obfuscates the actual licensing conditions. (Anyway, this should be
super rare.)
2025-07-18 13:29:46 +02:00
Tim Ruffing
d01e941188 bip3: Don't call CC0 a license
That's a bit of legal nitpicking, sorry. CC0 contains something like a
public domain dedication along with a fallback license, so it's neither
entirely. Some call it a "legal instrument". I prefer not calling it
anything.
2025-07-18 13:29:08 +02:00
Tim Ruffing
33d45d7f74 bip3: Use user-defined LicenseRef-PD instead of PD
SPDX doesn't have an official identifier for "public domain", at least
not for the simple "This document is placed into the public domain"
declarations used in some BIPs, see
https://wiki.spdx.org/view/Legal_Team/Decisions/Dealing_with_Public_Domain_within_SPDX_Files
for the rationale provided by their legal team. The rationale is sound,
but It's possible to create "user-defined" identifiers of the form
LicenseRef-X. This is a good idea here to make sure that all SPDX
expression will be formally valid.

And in our case, all "PD" BIPs match the following pseudo regex, so
there's not much potential for confusion:

    "This (document|BIP|work|proposal) is (hereby)? (placed)? in the
    public domain."

So it makes sense to keep using a single identifier for all of these.
2025-07-18 13:29:08 +02:00
Tim Ruffing
85a248f68e bip3: Fix SPDX id of Open Publication License 2025-07-18 13:29:08 +02:00
Tim Ruffing
e5748c9997 bip3: Fix SPDX id of FSF/GNU All Permissive 2025-07-18 13:29:08 +02:00
Tim Ruffing
c3b6691284 bip3: Switch to SPDX License Expressions 2025-07-18 13:29:08 +02:00
Mark "Murch" Erhardt
be3d2e4611
Merge pull request #1897 from Galoretka/rawe
BIP69: fix function name typo in example code
2025-07-16 16:27:14 -07:00
Galoretka
504c8439ce
Fix function name typo: use bytearr_cmp instead of bytearray_cmp 2025-07-16 21:35:15 +03:00
Mark "Murch" Erhardt
83ac8427e7
Merge pull request #1890 from nothingmuch/fragment-fixes
BIP 77: Delimit fragment params with  `-` instead of `+`
2025-07-10 15:04:58 -07:00
Yuval Kogman
8b83c34949 Specify lexicographical order for fragment params
The rationale for this change is that since `-` instead of `+` breaks
compatibility anyway, the marginal cost of removing this
unusual/surprising requirement for reverse lexicographical ordering is
zero.
2025-07-10 22:06:57 +02:00
Yuval Kogman
43f9688600 Separate fragment params with - instead of +
Since only Bull Bitcoin Mobile and Cake wallet are currently deployed in
production, both using PDK, and the `+` character is causing some
friction, this change seems justified to avoid similar issues with
future implementations.
2025-07-10 01:33:16 +02:00
Mark "Murch" Erhardt
c17a3dbceb
Merge pull request #1888 from achow101/380-drop-H
380: Disallow H as a hardened indicator
2025-07-03 14:49:16 -07:00
Guro
fd1955694b
bip373: add hyperlinks to other BIPs (#1886)
Co-authored-by: Mark "Murch" Erhardt <murch@murch.one>
2025-07-03 10:46:18 -07:00
Ava Chow
3cc71d7c22 380: Disallow H as a hardened indicator 2025-07-01 14:28:30 -07:00
Jon Atack
36618d1c3c
Merge pull request #1884 from scgbckbone/b388_fix_vector
BIP-0388: Fix test vector
2025-07-01 13:20:47 -07:00
scgbckbone
db8bad7ac9 fix: descriptor in "Taproot wallet policy with sortedmulti_a and a miniscript leaf" test vector which incorrectly uses @0 from keys info without key origin derivation 2025-06-30 12:44:04 +02:00
Mark "Murch" Erhardt
77b0bb297a
Merge pull request #1819 from murchandamus/2025-03-bip3-followups
BIP3: Address additional review
2025-06-27 10:17:21 -07:00
Murch
99b8541e09
bip3: Improve compatibility section 2025-06-27 10:15:26 -07:00
Murch
0bbe31b745
bip3: Restate recommendation to get early feedback 2025-06-27 10:15:24 -07:00
Murch
66cb7504b4
bip3: Explain why the Replaces header is unchanged 2025-06-27 10:15:23 -07:00
Murch
7101294a93
bip3: Describe acceptance as Adoption/Publication 2025-06-27 10:15:21 -07:00
Murch
2c57d8aee6
bip3: Fix minor phrasing and structure issues 2025-06-27 10:14:25 -07:00
Jon Atack
187d8859dc
Merge pull request #1876 from Merkleize/ccv-fixes
443: Fix some mistakes, and add paragraph on fees
2025-06-26 15:35:44 -07:00
Jon Atack
f9017e52a3
Merge pull request #1874 from bigspider/bip388-musig-fix
388: fix incorrect example
2025-06-25 10:41:05 -07:00
Kendra Karol Sevilla
f38f6c4e7b
[bip-390]: add hyperlinks to BIPs (327, 380, 389, 32) (#1877)
* add hyperlinks to BIPs

* Update bip-0390.mediawiki
2025-06-24 08:26:41 -07:00
Salvatore Ingala
e4e2b7ccd1
443: add paragraph on fee management 2025-06-22 20:46:37 +02:00
Salvatore Ingala
ff5703c755
443: fix some errors in the python pseudocode and a wrong reference. 2025-06-22 20:28:46 +02:00
Salvatore Ingala
dadbbc6de4
388: fix incorrect example
As per the test vectors, musig key expressions require the aggregation step
to precede the change/address_index derivations.
2025-06-21 12:03:15 +02:00
Jon Atack
e22eaa5a52
Merge pull request #1803 from quapka/hardened-indicator 2025-06-20 16:06:00 -07:00
Mark "Murch" Erhardt
db9e16eb5d
Merge pull request #1873 from lechpzn/master
[bip-0443]: fix link to bip-0341
2025-06-20 15:40:07 -07:00
Afounso Souza
0f47be10d6
BIP443: Fix links to other BIPs 2025-06-20 15:37:24 -07:00
Jon Atack
1889614e54
Merge pull request #1871 from achow101/desc-clarifications
390: clarifications on KEY expression restrictions
2025-06-19 19:20:40 -07:00
Ava Chow
c754a4d095 390: Additional clarifications on KEY expression restrictions 2025-06-18 17:13:07 -07:00
Ava Chow
bc66fdb166 descriptors: Require BIP 380
All of BIPs describing new descriptors require BIP 380
2025-06-18 15:09:43 -07:00
Mark "Murch" Erhardt
879ba82ab4
Merge pull request #1867 from achow101/390-clarifications
390: Allow repeated participant pubkeys and disallow ranged participants with aggregate derivation.
2025-06-18 14:10:44 -07:00
Ava Chow
530b91d86b 390: Allow repeated participant pubkeys 2025-06-18 12:32:52 -07:00
Jon Atack
a39a82f497
Merge pull request #1866 from rkrux/musig-multipath
390: mention about multipath key expression in musig descriptors
2025-06-18 11:23:02 -07:00
Mark "Murch" Erhardt
e82c925973 Merge pull request #1870 from notnout/patch-1
Update bip-0321.mediawiki to remove duplicate address example
2025-06-16 11:59:34 -07:00
Commander Nout
a211df4825
Update bip-0321.mediawiki to remove duplicate address example
Removing duplicate address example that's exactly the same as above.
2025-06-16 10:27:23 -05:00
rkrux
099b1807a4 390: mention about multipath key expression in musig descriptors
Also, adds an example for the same.
2025-06-06 13:29:11 +05:30
Jon Atack
dbb9617e5f
Merge pull request #1865 from achow101/383-fix-scripts
383: Fix output scripts and reword minimal encoding explanation
2025-06-05 13:32:51 -07:00
Ava Chow
ee7accaf5f 383: Fix output scripts and reword minimal encoding explanation
Co-Authored-By: Dr. Maxim Orlovsky <orlovsky@lnp-bp.org>
2025-06-05 13:22:17 -07:00
Jon Atack
820a044c81
Merge pull request #1861 from ethicnology/master
BIP21: clarify that example addresses are intentionally invalid
2025-06-04 13:24:38 -07:00
ethicnology
fad325e7a1
refactor: add warning about invalid example addresses in BIP-21 2025-06-04 15:57:44 -04:00
Mark "Murch" Erhardt
7d8b390c78
Merge pull request #1864 from jonatack/2025-06-various-fixups
BIPs 77, 175, 443: various fixups
2025-06-03 14:39:06 -07:00
strmfos
ca05d44e64 BIP175: remove out-of-date implementation (404) 2025-06-02 14:16:33 -06:00
Johan T. Halseth
6a311752dd BIP443: list stack elements in bottom-to-top order
and a few minor fixups
2025-06-02 14:16:33 -06:00
Brandon Lucas
88a1ae5782 BIP77: remove duplicate "the" 2025-06-02 14:16:27 -06:00
Jon Atack
72af87fc72
BIP77: remove redundant sentence line (#1858) 2025-05-28 11:56:35 -07:00
Dan Gould
ee587c5d2f
BIP 77: Async Payjoin (#1483)
* Draft payjoin v2 BIP

* Include mailing list feedback

* Include TABConf feedback

* Include padding

* Include production reference implementation

* Adopt BIP-77 for payjoin v2

* Distinguish payjoin directory from OHTTP Relay

* Detail OHTTP Key Configuration mechanism

* Fix punctuation

* Make base64URL references consistent

* Reference standardized Secp256k1 DHKEM for HPKE

* Add Comments-URI

* fixup: Format and spell check

Co-authored-by: spacebear <144076611+grizznaut@users.noreply.github.com>

* Add BIP 77 to README

* Add Payjoin V2 overview diagram

* Add Oblivious HTTP Sequence Diagram

* Correct links and spelling

Co-authored-by: thebrandonlucas <38222767+thebrandonlucas@users.noreply.github.com>

* Wrap <code> blocks

* Fix basic scheme actors

* Fix dead samourai links

* Orient motivation around a problem

* fix links

* Keyconfig s/should/must/ be provided

* Fix typos

Co-authored-by: thebrandonlucas <38222767+thebrandonlucas@users.noreply.github.com>

* s/pubkey/public key

* Incorporate jonatack's suggestions

* Incorporate more jonatack suggestions

* Incorporate satsie's suggesetions

* Rename "Async Payjoin"

* Replace BIP21 params with fragment params

* Revise document to describe Payjoin Sessions

Enrollment was a less clear than sessions

* Revise Sequence Diagram

* Spell initialize

* Update the bip to represent the stable protocol

* Spell according to Type Checks's job

* Mention the format of the ohttp fragment

* Reference BIP 78 attack vectors

* Remove straggling text

* Specify authorization mechanism

The specifics of a credential issuance are left out, however

* Use implicit session initialization

* Specify cryptographic handshake based on Noise IK

Co-authored-by: Yuval Kogman <nothingmuch@woobling.org>

* Add Spacebear's clarifications

Co-authored-by: spacebear <git@spacebear.dev>

* Document subdirectory Short IDs

* Require uppercase URL

bech32 fragment prefixes are case sensitive, and
alphanumeric mode only works on capital letters.

* Specify bech32 fragment parameter definitions

* Uppercase URL specifically only after subdirectory

* Note payload uniformity via padding and ellswift

* Include Message Byte Representations

This is the most straightforward way to explain the various padding
requirements.

* Document HPKE `info` strings

* Truncate lines to 120 characters

* Receiver's Original PSBT, not proposal

* Specify no mixed [output script]

* Remove extraneous pipe character

* Require BIPS 21, 78, 174

* Update checklist MUST/MUST NOT sections

MUST NOT contained MUST details. Move them to MUST.

* inputs ⇒ input

* Clarify BIP 78 payjoin version 1 connection

* Fix backwards compat language

* Payjoin version 2 URIs

* Reference Binary HTTP RFC

* Payjoin version 1 Proposal PSBTs

* Oblivous -> Oblivious

* Rm reference to 'production relays'

* Repeat the active agent by name

* Add Post-History

* Title 'Async Payjoin'

* Check spelling

* directory -> mailbox

* Move ohttp= fragment param to link to frag spec

* Mention URI keys as bootstrap mechanism

* Mailbox Discovery

* Remove superfluous word

* Clarify motivation

* Revise backwards compatiblity section for clarity

* Remove related protocol details

* Mv copyright out of flow

* Fix grammar (should be plural)

* Weaken language around addressing CIOH

"solves" implies this is the end of the story. Clarify that the problem
is the sole *explicit* problem mentioned in the paper.

* Simplify overview

- describe happy path protocol sequence
- introduce non-obvious key terms inherited from BIP 78
- no need for technical details that are clarified in the specification

* Describe optionality in overview

* Nitpicky sequence diagram fixes

* Clarify receiver's initial message in sequence diagram

* Simplify Basic Scheme section

* Mention OHTTP abbreviation on first mention

* Move sequence diagram up

* fragment parameter encoding corrections

- base64url was replaced by bech32
- formatting fixes
- some clarifications

* Use SHA-256 at independent mentions for consistency

* bootstrap grammar fix & correction

bootstrap would use a tor exit node, not a hidden service

* clarify proposal PSBT encryption layers

clarify which key is used for which layer of encryption (payjoin v2 e2ee vs.
OHTTP)

the message is not "authenticated" by the sender, rather it is tagged, it can be
authenticated during decryption.

* format original/proposal PSBT terms using italic, not <code>

* HRP of short ID is an implementation detail

it doesn't matter what is used since it's stripped after encoding

* Clarify checklist requirements

* "by intersection" unclear and unnecessary

* the fragment doesn't follow the pj param, it's part of it

* fix message diagram line intersections

* Correct encapsulated OHTTP diagram

The binary HTTP request is encrypted, and the AEAD tag is at the end, not the
beginning

* Clarifications for HPKE keys

Remove noise protocol framework mention. The IK pattern is not accurate, the
closest patterns are N or possibl NN, but neither is a perfect fit (N defines the
key as static, which it isn't, and NN is an interactive pattern)

* Remove note about forward secrecy

This is inaccurate, forward secrecy is defined with respect to long term
sessions, so the definition doesn't really extend to the request and response
messages, each of which is encrypted with ephemeral keys.

* Clarify OHTTP-relay bypassing by use of tor hidden service

* Update HPKE mode used for sender's message

Previously the reply key was included before the HPKE ciphertext, and the Auth
mode was used using this key. Since they are delivered together that only proves
the key was usable by the sender, not that the ciphertext is authentic. With the
key included as part of the encrypted plaintext, the HPKE mode was changed to
the base encryption to a public key mode with no authentication key.

* keep mailbox, but rename mailroom back to directory

Partly reverts a4d4065fa6f736f058e9173aa852e4fd12e75650, this change is hardly
more than a find & replace of mailroom to directory, and does not revert grammar
changes etc in addition to not reverting the subdirectory -> mailbox rename
which was the main point of confusion.

* Clarify allowed_purposes mechanism

First explain RFC 9540, then explain the extension mechanism.

Make roles in the interaction more explicit by changing the heading, "Directory
Discovery" sort of implies that clients discover these, when it describes relay
to directory interaction.

Clarify centralization pressure, that is alleviated by making senders' and
receivers' choices independent of each other.

* Correct payload uniformity section

We forgot about the OHTTP header which is 7 bytes of cleartext that also
specifies the DHKEM algoritm.

Additional clarifications and some restructuring to describe the details two
classes of messages each in its own self contained paragraph.

* rewrap paragraph to fix broken link

* fix bullet list formatting

- unindent to avoid <pre>
- fix broken URLs
- fix bullet items split into paragraphs

* rewrap section to fix broken links

* rewrap more paragraphs to fix broken links

* make attack vectors level 2 heading

as level 3 heading it was displayed under rationale in the table of contents

* Grammar/style fixes

* Order Requires

* Describe 'what' in the first sentence of the abstract.

* Be more specific about motivation.

* Make goal more explicit and consise

* Standardize "Common-input-ownership heuristic"

bitcoin wiki uses this.

* Replace Request expiration with Session Expiration

* Specify BIP 78 `v` parameter as redundant.

* Separate Short ID length rationale from spec

* Clairfy key nomeclature

- mailbox key
- reply key
- receiver key

as well as ephemerality and session nomeclature.

* Place byte diagrams with there respective message description.

* Include bitcoin URI subsection

* Top half reorg

* Add Yuval Kogman as Co-author

* NO mak typo

* Fix heirarchy

* Convert mediawiki to markdown

nix shell nixpkgs#pandoc --command bash -lc '
  pandoc -f mediawiki -t gfm bip-0077.mediawiki -o bip-0077.md'

rm bip-0077.mediawiki
reference bip-0077.md in README
surround bip-0077.md preamble in ``` to satisfy CI

* Strip link titles from mediawiki -> md conversion

sed -i.bak -E 's/\]\(([^ )]+) "[^"]*"\)/](\1)/g' bip-0077.md

* Strip leading/trailing spaces from inside links

sed -i.bak -E 's/\[[[:space:]]+/[/g; s/[[:space:]]+\]/]/g' bip-0077.md

* Fix spacing around inline code

* Take bitcoin URI example out of md link syntax

* Fence byte diagrams in backtics

* Replace sequence diagrams with mermaid

Better rendering and semantic source

* Collapse overview, basic scheme, and protocol sequence

These were all inconsitent levels of detail for the same thing. Leave the overview
the highest level and link to the specifics.

* Consistent short id singularity

* Remove straggling whitespace

* Link whitepaper

* Fix motivation flow

* Clarify abstract

* Clarify motivation

* Clarify overview

* Clarify bootstrapping

* Use singular to describe Payjoin URI

* Clarify mailbox endpoint

Specify that v2 mailboxes are OHTTP Targets.
Mention backwards compatibility.

* Clarify Receiver Fragment Parameters

* Revise messaging for clarity

* Add rationale for allowed_purposes

* Define ElligatorSwift according to BIP 324

* Clarify attacks, backwards compatibility

* Fix Receiver Proposal PSBT messaging header

for link.

* Add activation to sequence

* Correct #64-bit-short-id-length link

Co-authored-by: Yuval Kogman <nothingmuch@woobling.org>

* Clarify why not AES-GCM rationale

* Specify serialization of reply key in plaintext

* Specify the wire format for ChaCha20-Poly1305 ciphertext and tag

* Specify details of HPKE message wire format

Also clarifies that HPKE auth mode is used with the receiver's key,
authenticating the receiver as the sender of the encrypted Proposal PSBT.

* Correct diagram for OHTTP encapsulation

The order according to RFC 9458 and the code is is header, followed by
encapsulated key, followed by the ciphertext.

* OHTTP message encoding according to RFC 9458

* Rephrase abstract in active voice

* Deduplicate motivation word choice

- 'suitable for widespread implementation' vs appropriate, it's stronger
- 'mature solutions' to express that we chose those already based on iteration
- 'proven bitcoin primitives' to reflect the use of those battle tested like
  ElligatorSwift

* Simplify output batching motivation

* Reduce verbosity of linking exemplar conclusion

* Use PSBT 'update' verb in overview

Say 'appropriate intputs and/or outputs' because outputs might be merely
replaced, not necessarily added.

* Mention mutual exclusivity of Original and Proposal PSBTs

* Capitalize Uri -> URI

* Clarify URI parameter key/value distinction

* Backwards-compatible receivers *disable* pjos

* Use bech32 character set, not bech32

* Clarify session-specific parameter encoding

* Say 33-byte compressed public key

* Clarify v2 optional sender parameters application

* Clarify receiver session initiation overview

Co-authored-by: nothingmuch <nothingmuch@woobling.org>

* Mention sender's ephemeral mailbox in overview

Co-authored-by: nothingmuch <nothingmuch@woobling.org>

* Clarify cut-through optimization

* Replace mention of v1/v2 payjoin

Instead use 'This proposal', 'BIP 78', 'BIP 77', or omit the mention.

* Mention BIP 174 for PSBTv0

* Mention sender's *corresponding* public key

* Hyphenate '16-byte'

* Clarify who can post messagese direct to mailbox

* liu -> lieu

* Simplify cut through overview sentence structure

* Replace 'Payjoin exemplar' with 'A natural application..'

* Make motivation CIOH mention easier to read

Use language from sataoshi and don't mention input batching since the next
sentence already does.

* Specify Proposal PSBT MUST/MAY input/output inclusion rules

* remove duplicate 'and'

* Remove duplicate 'preserve'

Co-authored-by: Brandon Lucas <thebrandonlucas@gmail.com>

* The HRP is used as the parameter key

Co-authored-by: Yuval Kogman <nothingmuch@woobling.org>

* Add rationale for random padding in OHTTP

* Use "zero" instead of "0"

Co-authored-by: Mark "Murch" Erhardt <murch@murch.one>

* epehmeral -> ephemeral

Co-authored-by: Brandon Lucas <thebrandonlucas@gmail.com>

* subject match tense

Co-authored-by: Brandon Lucas <thebrandonlucas@gmail.com>

* Capitalize Payjoin for protocol

Co-authored-by: Brandon Lucas <thebrandonlucas@gmail.com>

* Capitalize Payjoin for protocol

Co-authored-by: Brandon Lucas <thebrandonlucas@gmail.com>

* Capitalize Payjoin for protocol

Co-authored-by: Brandon Lucas <thebrandonlucas@gmail.com>

* Capitalize Payjoin for protocol

Co-authored-by: Brandon Lucas <thebrandonlucas@gmail.com>

* Capitalize Payjoin for protocol

Co-authored-by: Brandon Lucas <thebrandonlucas@gmail.com>

* ("Version 2") relative to and described in ("Version 1")

Co-authored-by: Jon Atack <jon@atack.com>

* BIP78's requirements for Payjoin Version 1

Co-authored-by: Jon Atack <jon@atack.com>

* Include missing period

Co-authored-by: Jon Atack <jon@atack.com>

* which -> that

Co-authored-by: Jon Atack <jon@atack.com>

* Separate independent clauses with a semicolon

Co-authored-by: Jon Atack <jon@atack.com>

* Remove duplicate "at"

Co-authored-by: Jon Atack <jon@atack.com>

* Hyphenate "short-lived"

Co-authored-by: Jon Atack <jon@atack.com>

* Fix Attack Vectors URL

Co-authored-by: Jon Atack <jon@atack.com>

* which -> that

Co-authored-by: Jon Atack <jon@atack.com>

* Include colon to reference Oblivious HTTP Relay impl

Co-authored-by: Jon Atack <jon@atack.com>

* consist -> consists

Co-authored-by: Jon Atack <jon@atack.com>

* Remove double "the"

Co-authored-by: Jon Atack <jon@atack.com>

* Remove double "the"

Co-authored-by: Jon Atack <jon@atack.com>

* Correct Padded BHTTP Response length

144 bytes not 104

See: 87042266d1/payjoin-directory/src/lib.rs (L30-L31)

* which -> , which

* Note TLS is not available in Bitcoin Core

* Link to BIP21 forwards compatibility `reqparam`

* Require rev. lexicographical frag. param. order

A specific order might create a fingerprint for a specific wallet, imposing a privacy
risk. It seems impossible to impose an order on BIP21 parameters, but BIP 77 clients
may error on out-of-order fragment parameters to at least avoid some fingerprint there.

Reverse lecicographical ordering was chosen because that is how the existing implmentation
serializes the parameters already, so that no breaking change needs to be made.

Co-authored-by: nothingmuch <nothingmuch@woobling.org>

---------

Co-authored-by: spacebear <144076611+grizznaut@users.noreply.github.com>
Co-authored-by: thebrandonlucas <38222767+thebrandonlucas@users.noreply.github.com>
Co-authored-by: Yuval Kogman <nothingmuch@woobling.org>
Co-authored-by: spacebear <git@spacebear.dev>
Co-authored-by: spacebear <144076611+spacebear21@users.noreply.github.com>
Co-authored-by: Brandon Lucas <thebrandonlucas@gmail.com>
Co-authored-by: Mark "Murch" Erhardt <murch@murch.one>
Co-authored-by: Jon Atack <jon@atack.com>
2025-05-28 11:49:12 -07:00
Jon Atack
5c7120f418
Merge pull request #1857 from strmfos/master
BIP69: fix link
2025-05-22 17:26:03 -07:00
strmfos
10941b1880
replace error link bip-0069.mediawiki 2025-05-22 20:08:39 +02:00
Mark "Murch" Erhardt
43d4a1ecec
Merge pull request #1760 from Christewart/2024-12-20-64bytetxs
BIP 53: Disallow 64-byte transactions
2025-05-21 17:58:42 -07:00
Jon Atack
039de4fddd
Merge pull request #1850 from murchandamus/Revert-bip48-update 2025-05-21 18:46:52 -06:00
Chris Stewart
4d495ab1a0 BIP53: Disallow 64-byte transactions
Co-authored-by: Mark "Murch" Erhardt <murch@murch.one>

Co-authored-by: Jon Atack <jon@atack.com>
2025-05-21 19:10:59 -05:00
Jon Atack
fd413c162d
Merge pull request #1844 from torrpriius/fix/update
BIP-99: fix footnotes and drop missing reference
2025-05-21 14:59:47 -06:00
Mark "Murch" Erhardt
ebab9b369a
Merge pull request #1854 from jonatack/2025-05-replace-broken-twitter-link
BIP341: replace broken twitter link
2025-05-20 14:33:50 -07:00
Torprius
7ab94f8be4
BIP99: Drop missing reference, fix formatting
Co-authored-by: Murch <murch@murch.one>
2025-05-20 14:26:15 -07:00
Jon Atack
a093c34607 bip341: replace broken twitter link 2025-05-20 08:08:27 -06:00
Jon Atack
36daa362c3
Merge pull request #1853 from kcalvinalvin/patch-1
bip-0331: correct size of version field in sendpackages
2025-05-19 09:32:55 -06:00
Calvin Kim
5d82f82693
bip-0331: correct size of version field in sendpackages
Since the version is denoted as uint64, the size should be 8 bytes.
2025-05-19 12:29:39 +09:00
Mark "Murch" Erhardt
3b76d78bdb
Merge pull request #1793 from Merkleize/ccv
BIP 443: OP_CHECKCONTRACTVERIFY
2025-05-16 09:58:31 -07:00
Mark "Murch" Erhardt
25f63964d0
Merge pull request #1849 from mutestt/fix/fix
BIP-372: Fix references and links formatting and minor typos
2025-05-16 09:51:53 -07:00
Mark Diloff
50a692d82e
BIP372: Fix footnote formatting, minor issues 2025-05-16 09:49:54 -07:00
Murch
adafc92b98
BIP48: Remove invitation to add more script types 2025-05-14 15:12:42 -07:00
Murch
fc946e1989
BIP48: Move to final 2025-05-13 13:07:53 -07:00
Murch
b2ce382603
Revert P2TR example from "BIP48: Add P2SH-P2WSH and P2TR mainnet examples"
This partially reverts commit 9c22bcef63.
2025-05-13 13:07:51 -07:00
Murch
f29553e085
Revert "BIP48: Add p2tr script type derivation"
This reverts commit e7cf2e9149.
2025-05-13 13:07:49 -07:00
Salvatore Ingala
ed6b6132f8
BIP draft for OP_CHECKCONTRACTVERIFY 2025-05-13 09:28:28 +02:00
Murch
60ac0e8fec
Merge pull request #1848 via 'jamesob-25-05-withdraw-vault' 2025-05-08 11:38:05 -07:00
James O'Beirne
b771054d4d
BIP-345: withdraw 2025-05-08 11:33:31 -07:00
Jon Atack
b8702ef497
Merge pull request #1846 from ben-kaufman/bip48-mainnet-examples
BIP48: Add P2SH-P2WSH and P2TR mainnet examples
2025-05-08 11:31:42 -06:00
Murch
bce061f009
Merge pull request #1841 from 0ceanSlim
- Adds BIP172: Define Bitcoin Subunits as Satoshis
2025-05-08 10:28:56 -07:00
0ceanSlim
c37927174e
Add BIP172: Define Bitcoin Subunits as Satoshis 2025-05-08 10:24:02 -07:00
Mark "Murch" Erhardt
4aa3aef572
Merge pull request #1821 from BitcoinErrorLog/master
BIP177: Redefine Bitcoin’s Base Unit
2025-05-08 09:52:03 -07:00
John Carvalho
59527bd92b
Add BIP177: Redefine Bitcoin's Base Unit
- Redefine bitcoin base unit to smallest unit
- Propose BIP 21Q: Redefine bitcoin base unit to smallest indivisible unit
- Adds comments acknowledging and handling sats and satoshis
- Make use of "base unit" and variations more consistent and intentional
- Make "bitcoin" v "Bitcoin" consistent
- Made "bitcoin" v "Bitcoin" consistent by using Bitcoin for the protocol and idea, and bitcoin for the units, which I believe is conventional style.
2025-05-08 09:49:28 -07:00
benk10
9c22bcef63 BIP48: Add P2SH-P2WSH and P2TR mainnet examples 2025-05-04 08:46:13 +03:00
Jon Atack
3365fb7a7e
Merge pull request #1835 from ben-kaufman/bip48-p2tr
BIP48: Add p2tr script type derivation
2025-04-30 21:07:28 -06:00
Jon Atack
74fc5b92b0
Merge pull request #1800 from darosior/consensus_cleanup
BIP 54: Consensus Cleanup
2025-04-29 16:23:51 -06:00
Mark "Murch" Erhardt
2fa52fcb0e
Merge pull request #1842 from gap-editor/bip-0197
BIP 197: Update the invalid link
2025-04-29 13:28:56 -07:00
benk10
e7cf2e9149 BIP48: Add p2tr script type derivation 2025-04-29 19:17:05 +03:00
Mark "Murch" Erhardt
a1ce143fc4
Merge pull request #1839 from jonatack/2025-04-collect-typo-fixups
Collect and curate typo fixups from April
2025-04-28 14:19:41 -07:00
Maximilian Hubert
9d960e9906
Update bip-0197.mediawiki 2025-04-28 20:51:55 +02:00
Antoine Poinsot
1ee43519dd Consensus Cleanup BIP draft 2025-04-28 14:30:31 -04:00
Maximilian Hubert
22806674f4
BIP 99: update invalid link to hardfork-timewarp-0.11 branch (#1836)
* Update bip-0099.mediawiki

* Update bip-0099.mediawiki
2025-04-28 11:02:04 -07:00
Maximilian Hubert
9abe24d2c6
BIP 154: fix link to cuckoo-profile.pdf (#1840)
* Update bip-0154.mediawiki

* Update bip-0154.mediawiki
2025-04-28 10:57:28 -07:00
Jon Atack
8137279570 Monthly typo fixups
Co-authored-by: xiaobei0715 <1505929057@qq.com>
Co-authored-by: wgyt <wgythe@gmail.com>
Co-authored-by: Ragnar <rodiondenmark@gmail.com>
2025-04-28 10:29:11 -06:00
Maximilian Hubert
b60b886414
bip-0112: fix links to Deployable Lightning paper (#1837) 2025-04-28 08:19:21 -07:00
Jon Atack
c11792bf18
Merge pull request #1838 from gap-editor/bip-0119
BIP 119: fix link to MES16 paper
2025-04-28 08:58:16 -06:00
Maximilian Hubert
f5e4b5b89c
Update bip-0119.mediawiki 2025-04-28 16:49:57 +02:00
Mark "Murch" Erhardt
fd3878a279
Merge pull request #1555 from TheBlueMatt/2024-03-uris-without-bodies
BIP 321: URI Scheme (Replace BIP 21 with a new BIP containing information about more modern usage of it)
2025-04-24 21:52:29 -07:00
Matt Corallo
f5cb29f9b7 Update BIP 321 with information about more modern usage of it
As Bitcoin has grown, the introduction of new address formats
describing new forms of payment instructions has become
increasingly fraught with compatibility issues. Not only does there
exist traditional on-chain addresses, but some recipients wish to
receive Lightning (when the sender supports it) or newer formats
such as Silent Payments.

This has led to increasing use of the BIP 21 query parameters to
encode further optional payment instructions.

Looking forward, as new payment instructions get adopted, it makes
much more sense to include them in query parameters rather than
replace the existing address field, ensuring compatibility with
senders and recipients who may or may not be upgraded to support
all the latest payment instructions.

This updates BIP 321 to suggest that future address formats do this.

Further, it updates BIP 321 to allow an empty bitcoin address in
cases where new payment instructions have moved to becoming
mandatory. This isn't a backwards-incompatible change any more than
switching to a new address format is, so doesn't impact existing
BIP 21 implementations in a new way, however provides a nice
conclusion to the query-parameter-based upgrade path - once a form
of payment instructions has broad adoption, senders can simply drop
the existing address field, keeping their existing query parameter
encoding, rather than replace the existing address field. It also
addresses the question of what to do if a wallet no longer wishes
to receive some legacy on-chain address, but has multiple payment
instruction formats that they wish to include - deciding which one
to place in the address field would be a difficult task.

Finally, it defines a new query parameter, the `pop` parameter,
which allows the initiating application to receive callbacks for
proof of payment completion.
2025-04-23 14:51:51 +00:00
Nicolas Dorier
bf8f197553
BIP388: List BTCPay Server and NBitcoin implementations
* BTCPay Server and NBitcoin supporting BIP388
* BIP388: Spelling improvements

Co-authored-by: Salvatore Ingala <6681844+bigspider@users.noreply.github.com>
2025-04-23 05:50:33 -07:00
Janus
757e15e568 Reject 199 (expired) 2025-04-21 15:18:24 -07:00
Tronica
6ceafc51b1
BIP-0374: fix incorrect bit index and modernize CSV reader usage in test vector scripts (#1817)
* Update run_test_vectors.py

* Update gen_test_vectors.py

* Regenerate test vectors after fixing message tampering logic in gen_test_vectors.py
2025-04-16 07:10:16 -07:00
Jon Atack
05d546d581
Merge pull request #1779 from VolodymyrBg/AE5959595959
BIP374: add subtraction operator for GE class
2025-04-16 08:08:34 -06:00
VolodymyrBg
7c80a699ff Implement subtraction operator for GE class in BIP-0374 reference code
This commit implements the subtraction operator (sub) for the GE (Group Element) class in the secp256k1.py file as requested in the TODO comment in reference.py.

The implementation is straightforward, leveraging the existing neg method to define subtraction as addition with the negated element: self + (-a).

After implementing the operator, the code in reference.py was simplified by replacing expressions like:
s * G + (-e * A) with s * G - e * A

This makes the code more readable and directly matches the mathematical notation used in the BIP-0374 specification.

Co-Authored-By: Sebastian Falbesoner <sebastian.falbesoner@gmail.com>
2025-04-15 14:39:09 +03:00
VolodymyrBg
c5220f8c3b
BIPs 78 and 329: minor grammar and typo fix-ups (#1825)
* BIP 329 fix typo

* BIP 78 fix typos
2025-04-14 12:35:42 -07:00
wgyt
befa252b51
BIP3,37,39,42,52,62: fix typos (#1824)
Co-authored-by: Mark "Murch" Erhardt <murch@murch.one>
2025-04-14 08:22:17 -07:00
leopardracer
4b568f2c37
BIP75: fix typo (#1823) 2025-04-14 08:17:43 -07:00
FT
8375f71ee6
BIP15,20: add missing words (#1822)
* Update bip-0015.mediawiki

* Update bip-0020.mediawiki

* Update bip-0035.mediawiki
2025-04-12 07:55:08 -07:00
kilavvy
1447ab990d
BIP381, 382: minor grammar fixups (#1816)
* Update bip-0382.mediawiki

* Update bip-0381.mediawiki
2025-04-11 13:01:50 -07:00
Mark "Murch" Erhardt
1163f3ab69
Merge pull request #1814 from leopardracer/patch-1
BIP-0374: fix typo
2025-04-07 13:03:00 -07:00
Jon Atack
8455e258b0
Merge pull request #1812 from leopardracer/master
BIP-0324: fix typo
2025-04-07 09:43:45 -06:00
leopardracer
f64e8255c6
Update bip-0374.mediawiki 2025-04-06 23:22:43 +03:00
leopardracer
54c39b27b9
Update reference.py 2025-04-06 22:56:17 +03:00
D++
f958360a27 Update to include newer address types
Added bech32 and bech32m address types to reflect the newer SegWit and Taproot addresses.

Co-Authored-By: Reese Russell <reese.russell@ymail.com>
2025-04-04 16:37:24 +00:00
Matt Corallo
7e6a583c8d Copy BIP 21 into a new BIP 321 with only the header changed 2025-04-04 16:37:24 +00:00
Mark "Murch" Erhardt
3ccc59dbdb
Merge pull request #1811 from futreall/master
BIP352: minor docstring fixups
2025-04-04 06:35:59 -07:00
futreall
a6cbb79a3f
fix err has to hash reference.py 2025-04-03 09:10:20 +03:00
Mark "Murch" Erhardt
7bc88ba4e2
Merge pull request #1810 from jonatack/2025-04-bip340-url-fixup
BIP340: fix url to test-vectors.py
2025-04-02 09:05:34 -07:00
Jon Atack
480921f66f BIP340: fix url to test-vectors.py 2025-04-02 09:47:31 -06:00
Jon Atack
74eee4c353
Merge pull request #1807 from real-or-random/340-code-license-change 2025-04-02 08:45:25 -06:00
Tim Ruffing
84a64ec1c6 bip340: Change license of code and test vectors
See https://github.com/bitcoin/bips/commits/master/bip-0340 for a list
of contributors. I have obtained permission to do this change from all
contributors in private. Nevertheless, it would be good to get an ACK
from every contributor in order to have publicly available evidence.

 - [ ] @sipa
 - [ ] @jonasnick
 - [ ] @theStack
 - [ ] @ysangkok

I haven't contacted @Sajjon and @satsie, whose contributions constitute
of fixing not more than two typos and are thus below the threshold of
originality required for copyright to be applicable.
2025-04-02 15:38:56 +02:00
Jon Atack
9847bc7704
Merge pull request #1808 from futreall/master
BIP328: minor docstring fixups
2025-04-01 13:13:40 -06:00
futreall
5772c6b40d fix error Base48 to Base58
chore: fix error Base48 to Base58

fix error Base48 to Base58
2025-04-01 21:18:06 +03:00
quapka
fade15caa2
BIP380: minor grammar fixups (#1802)
* Use pronoun only after recalling the sentence object

* Use singular form

* Fix phrasal verb form

---------

Co-authored-by: quapka <>
2025-03-29 07:58:33 -07:00
Murch
a7075ee434
BIP3: Fix link to BIP 123 2025-03-29 07:42:31 -07:00
Litvintech
816181f0d4
Update dead link in bip-0003.md 2025-03-29 16:56:16 +03:00
Mark "Murch" Erhardt
04b2ec649b
Merge pull request #1804 from darosior/2503_bip3_nits
bip3: a couple nits
2025-03-28 13:25:17 -07:00
Antoine Poinsot
5dcb2d46c9 bip3: link to ownership transfer section for complete->closed transition
Reading from top to bottom, the passive voice "they become BIP's author or deputy" left me wondering
how it would concretely work in practice. Link to the transferring ownership section for
clarification.
2025-03-28 11:54:13 -04:00
Antoine Poinsot
617db7a0fe bip3: rename 'shareholder' to 'stakeholder'
Shareholder refers to an individual or a legal entity owning a share of a company's share capital.
Since the Bitcoin system is not a company, but different actors across the industry have a stake in
its operation, i think the word "stakeholder" better conveys the intended meaning of the original
author here.
2025-03-28 11:49:20 -04:00
quapka
3d7ff96d7b Make specs consistent about hardened indicators 2025-03-27 21:43:12 +01:00
Jon Atack
02ad0e01c2
Merge pull request #1794 from murchandamus/2025-03-propose-BIP3
BIP3: Move to Proposed
2025-03-24 12:55:27 -06:00
Jon Atack
d7cc40ed69
Merge pull request #1798 from sky-coderay/master
BIP69: typo fixup in bip-0069_examples.py
2025-03-24 12:47:34 -06:00
Skylar Ray
b09a0aa7ca
Update bip-0069_examples.py 2025-03-24 19:51:48 +02:00
Nadav Ivgi
f23e3c7318
BIP 345: Fix OP_VAULT_RECOVER specification for the recovery-sPK-hash
The recovery scriptPubKey needs to be prefixed with its CompactSize-encoded length.
2025-03-22 23:40:12 +02:00
Mark "Murch" Erhardt
65b6d6d66d
Merge pull request #1791 from wgyt/wgyt-bips-patch
BIPs 67 and 301: fix links
2025-03-21 18:26:29 -07:00
wgyt
0e3a56c681 fix links 2025-03-22 09:15:16 +08:00
Mark "Murch" Erhardt
09564837a9
Merge pull request #1778 from sky-coderay/patch-1
BIP379: add missing hexadecimal notations
2025-03-21 09:29:37 -07:00
Jon Atack
7a32141336
Merge pull request #1584 from jonatack/2024-04-bip32-amendment
BIP32 amendment: base58chk-encoded extended keys are always 111 chars
2025-03-21 09:06:38 -06:00
Jon Atack
2fd67e5bd4
Merge pull request #1777 from vipocenka/fix/fix
BIP158: minor error message fixup in `gentestvectors.go`
2025-03-21 08:56:51 -06:00
Murch
b650373ded
Merge branch 'BIP-0060' 2025-03-21 07:22:27 -07:00
Jon Atack
335edb3519
Merge pull request #1792 from JeremyRubin/119-edits-2025
[BIP-119] language overhaul & cleanup
2025-03-21 08:18:30 -06:00
Mark "Murch" Erhardt
e946c66c77
Merge pull request #1795 from guspan-tanadi/pdfpathlinks
bip-0068: current pdf path links
2025-03-19 06:53:41 -07:00
Guspan Tanadi
7523f8ed0a
fix pdf path links bip-0068 2025-03-19 20:04:15 +07:00
Murch
76132ec284
bip3: Move to Proposed 2025-03-18 19:31:49 -07:00
Jeremy Rubin
88c0fb9b5b [BIP-119] language overhaul & cleanup 2025-03-18 09:28:18 -04:00
Mark "Murch" Erhardt
8a75e437c5
Merge pull request #1790 from futreall/fix
bip-0375.mediawiki fix duplicate 'the'
2025-03-17 18:05:43 -07:00
Jon Atack
59e7cb4334
Merge pull request #1782 from Roasbeef/testnet4-spec-reword
BIP-0094: reformat specification section for clarity and readability
2025-03-17 18:50:14 -06:00
futreall
9ae0cdc9fe
Update bip-0375.mediawiki 2025-03-15 19:42:21 +02:00
Jon Atack
00c13baff0
Merge pull request #1783 from wgyt/wgyt-bips-fix-link
Fix links in BIP300
2025-03-13 13:29:25 -06:00
Jon Atack
050d422b2a
Merge pull request #1789 from darosior/2503_bip348_ref_bip342
bip-0348: correct BIP number in referencing unknown key types
2025-03-10 13:56:09 -07:00
Antoine Poinsot
1dee483436 Remove now unused reference to bip-0341 2025-03-10 16:20:42 -04:00
Antoine Poinsot
97a7edb0da bip-0348: correct reference to Tapscript unknown key types
Author confused bip-0341, which defines the Taproot construction, with bip-0342, which defines the
Tapscript scripting system. Unknown key types are defined in the latter, as part of the semantics of
the CHECKSIG{VERIFY} and CHECKSIGADD opcodes.
2025-03-10 16:16:36 -04:00
Jon Atack
7e15925f91
Merge pull request #1788 from EthnTuttle/patch-1
BIP119 fix grammatical typos
2025-03-10 11:15:49 -07:00
Ethan Tuttle
9573e060e3
fix: grammatical typos 2025-03-09 21:01:44 -04:00
Jon Atack
33231097c2
Merge pull request #1785 from jonatack/2025-03-bip94-touchup
BIP94 PR1781 editorial fixups
2025-03-07 12:57:05 -08:00
Jon Atack
954a78ea1f BIP94 PR1781 fixup 2025-03-07 14:55:50 -06:00
Jon Atack
a9e0745a36
Merge pull request #1784 from jonatack/2025-03-appease-typos-linter-in-BIP119
BIP119: appease typos linter
2025-03-07 12:46:53 -08:00
Jon Atack
61a39ce66d
Merge pull request #1781 from Roasbeef/testnet4-port
BIP-0094: add default p2p port for testnet4
2025-03-07 12:40:54 -08:00
Jon Atack
3ee89adf9e BIP119: appease typos linter 2025-03-07 12:54:17 -06:00
wgyt
0140e2864b fix links in bip-0300 2025-03-07 13:43:25 +08:00
Olaoluwa Osuntokun
0dd4d3ec61
BIP-0094: reformat specification section for clarity and readability
Restructured the specification section to make the consensus rules
clearer and more scannable. The previous section interleaved commentary
and historical tidbits with the motivation and new rules, making it
difficult to quickly identify the exact rule changes.

The updated format:
- Numbers each rule for easier reference
- Adds explicit "Rule Specification" sections
- Uses structured lists with MUST statements following RFC/IETF
  conventions
- Provides a clear problem statement before each solution
- Separates explanatory text from the actual rules

These changes make it much easier for implementers to understand what
changes are required without having to parse through multiple paragraphs
of text.
2025-03-06 15:11:34 -08:00
Olaoluwa Osuntokun
fcd5d7224e
BIP-0094: add default p2p port for testnet4 2025-03-06 14:47:20 -08:00
Skylar Ray
091824b3bb
Update bip-0379.md 2025-02-28 20:52:42 +02:00
Skylar Ray
6312ae3e24
Update bip-0379.md 2025-02-28 17:33:21 +02:00
Ocenka
6cbe26685a
fix gentestvectors.go 2025-02-28 15:27:47 +00:00
Andrew Toth
24b4354e64
BIP374: Add message to rand computation (#1758)
* BIP374: Add message to rand computation

* BIP374: Update reference and test vectors

* Add changelog

* Format changelog according to BIP3

* Add creation date

Co-authored-by: Jon Atack <jon@atack.com>

* Grammar fix

Co-authored-by: Jon Atack <jon@atack.com>

* update changelog

---------

Co-authored-by: Jon Atack <jon@atack.com>
2025-02-27 08:37:46 -08:00
Mark "Murch" Erhardt
cc81fde273
Merge pull request #1768 from jonatack/2025-02-bip159
BIP159 updates
2025-02-26 09:57:23 -05:00
Jon Atack
bab21271d7
Merge pull request #1776 from craigraw/wallet-labels-edits
BIP329: PR 1750 follow-up edits
2025-02-26 05:52:45 -08:00
Craig Raw
cd1a279877 add address heights clarification to align with transaction height specification 2025-02-26 11:24:27 +02:00
Craig Raw
5262b495af add minor previously approved edits 2025-02-26 10:42:34 +02:00
Jon Atack
d13c7240de
Merge pull request #1772 from costcould/master
BIP75: fix BIP70 extensions url and clarify text
2025-02-25 20:19:47 -08:00
costcould
4d6fdda871 BIP0075: fix 404 status URL
Signed-off-by: costcould <fliter@myyahoo.com>
2025-02-26 11:53:18 +08:00
Murch
d44f70e77a BIP159 Risks section: clarifications and fixups 2025-02-25 17:46:43 -05:00
Mark "Murch" Erhardt
6d2f0d64fc
Merge pull request #1774 from fjahr/bip94-status
BIP 94: Move status to Final
2025-02-25 16:49:41 -05:00
Fabian Jahr
d2cfbae4c1
BIP 94: Move to Final 2025-02-25 16:47:01 -05:00
doc-hex
c8e208fb6c
BIP329: add optional data fields, fix a JSON type (#1750)
* Correct type error in sample JSON

* first pass: moar data

* more fiat and edits

* more edits

* add per-txn value

* Update bip-0329.mediawiki

Co-authored-by: Jon Atack <jon@atack.com>

* Update bip-0329.mediawiki

Co-authored-by: Jon Atack <jon@atack.com>

* Update bip-0329.mediawiki

Co-authored-by: Jon Atack <jon@atack.com>

* Update bip-0329.mediawiki

Co-authored-by: Jon Atack <jon@atack.com>

* Update bip-0329.mediawiki

Co-authored-by: Jon Atack <jon@atack.com>

* Update bip-0329.mediawiki

Co-authored-by: Jon Atack <jon@atack.com>

* Update bip-0329.mediawiki

Co-authored-by: Jon Atack <jon@atack.com>

* Update bip-0329.mediawiki

Co-authored-by: Jon Atack <jon@atack.com>

* edit

* include @craigraw feedback

* typo fix

* add comment

* further edits

* broaden uses for address.heights

---------

Co-authored-by: Jon Atack <jon@atack.com>
2025-02-25 12:26:27 -08:00
Jon Atack
c84af0bf29
Merge pull request #1771 from murchandamus/2025-02-bip-3-follow-ups
BIP3: Address follow-ups from #1712
2025-02-25 11:35:44 -08:00
Murch
1ceb362897
BIP3: Address follow-ups from #1712 2025-02-25 14:24:34 -05:00
Jon Atack
22f7f0477c BIP159: unwillingly -> unwittingly
Not the same meaning, so not a purely editorial fixup, but I think "unwittingly"
expresses the intended meaning.
2025-02-22 09:57:27 -06:00
Jon Atack
5b85dbe120 BIP159: editorial fixups 2025-02-22 09:57:27 -06:00
Jon Atack
8118a14dc8 BIP159: clarify pruned means not signaling serving complete block chain
e.g. that NODE_NETWORK is not set

See reference implementation

https://github.com/bitcoin/bitcoin/pull/10387

and this comment in that pull

https://github.com/bitcoin/bitcoin/pull/10387#discussion_r156861038
2025-02-22 09:57:20 -06:00
Jon Atack
3f86dc4ea6 BIP159: emphasize minimum number of blocks 2025-02-22 09:18:31 -06:00
Jon Atack
7916231ff6
Merge pull request #1712 from murchandamus/2024-12-update-bip-process
BIP3: Updated BIP Process
2025-02-20 15:21:22 -08:00
Murch
d5c189f328
BIP3: Update BIP Process 2025-02-20 17:18:08 -05:00
Jon Atack
1096b5fcbc
Merge pull request #1769 from achow101/373-test-fix
373: Correct test data mismatches
2025-02-17 08:42:07 -08:00
Ava Chow
529a0458d8 373: Correct test data mismatches
Corrects the 2 mismatches in the test vectors pointed out in https://github.com/bitcoin/bips/pull/1764#issuecomment-2661667939
2025-02-16 18:20:48 -08:00
Mark "Murch" Erhardt
2e71a7e758
Merge pull request #1762 from achow101/328-tests
328: test vectors, reference implementation, update to Proposed
2025-02-14 09:28:51 -05:00
Ava Chow
151ec96c83
328: Draft -> Proposed 2025-02-14 09:26:11 -05:00
Mark "Murch" Erhardt
ee78520bfe
Merge pull request #1764 from achow101/373-tests
373: test vectors, reference implementation, update to Proposed
2025-02-14 09:24:21 -05:00
Ava Chow
3adf43df82 373: Draft -> Proposed 2025-02-13 12:52:19 -08:00
Ava Chow
cf948d47a0 373: Correct Created date 2025-02-13 12:50:40 -08:00
Jon Atack
ce13af21b5
Merge pull request #1767 from murchandamus/390-created-date
390: Fix created date
2025-02-13 12:31:02 -08:00
Murch
cde668d903
390: Fix created date 2025-02-13 15:26:29 -05:00
Mark "Murch" Erhardt
62ba831736
Merge pull request #1763 from achow101/390-ref-impl
390: Add reference implementation
2025-02-13 15:19:27 -05:00
Mark "Murch" Erhardt
6651d5c82f
Merge pull request #1766 from jonatack/2025-02-implementors-to-implementers
spelling: globally change "implementor" to "implementer"
2025-02-13 15:15:23 -05:00
Jon Atack
0203ede3b4
Merge pull request #1765 from 0xBEEFCAF3/patch-2
BIP119: Fix `OP_EQUALVERIFY` typo
2025-02-13 10:20:41 -08:00
Jon Atack
468e9759ba spelling: globally change "implementor" to "implementer"
Although the variant "implementor" predominated for much of the late 20th
century, today "implementer" is considered standard, and the former spelling
triggers the typos spelling checker.
2025-02-13 11:56:17 -06:00
Armin Sabouri
f5ff1d22b2
Fix typo in bip-0119 2025-02-13 11:00:13 -05:00
Ava Chow
3827648acc 328: Correct Created date
Date that the BIP number was assigned is 2024-06-04.
2025-02-12 09:59:59 -08:00
Ava Chow
4e335af8bc 373: Add reference implementation 2025-02-11 16:43:48 -08:00
Ava Chow
88f40411b1 373: Add test vectors 2025-02-11 16:43:48 -08:00
Ava Chow
574589f2a6 390: Add reference implementation 2025-02-11 12:43:40 -08:00
Ava Chow
7ab43ce11f 328: Add reference implementation 2025-02-11 12:41:17 -08:00
Ava Chow
081aa9a22e 328: Add test vectors 2025-02-11 12:37:48 -08:00
Jon Atack
3c7b0d6498
Merge pull request #1759 from murchandamus/render-email-in-.md
Render author email addresses in markdown BIPs
2025-02-10 12:22:31 -08:00
Anthony Towns
726df6f4d5 Use code block instead of pre for markdown 2025-02-08 20:06:23 +10:00
Jon Atack
ea7aae8d1f
Merge pull request #1754 from nymius/fix/typo-in-PSBT_OUT_SP_V0_LABEL-in-BIP-375-and-BIP-174 2025-02-06 10:20:20 -08:00
Mark "Murch" Erhardt
b9f9a8d6e8
Merge pull request #1680 from jonatack/2024-10-BIP39-license-and-copyright-section
BIP39: add license and copyright section
2025-02-04 13:10:53 -05:00
Jon Atack
1ddcfcea7a
Merge pull request #1751 from stratospher/2025_01_DLEQ_G 2025-02-01 10:34:42 -06:00
nymius
a9729b28d4 fix(BIP174,BIP375): typo in PSBT_OUT_SP_V0_LABEL
Assuming a by one increment in the keytype of the silent payments output
fields, the following numeral to 0x09 in the hexadecimal system is 0x0a,
not 0x10.
2025-01-31 12:24:18 -03:00
Jon Atack
5333e5e951
Merge pull request #1752 from brawncode/patch-1
BIP388: Fix incorrect use of return for raising exception
2025-01-29 13:49:52 -06:00
stratospher
5f42eb64d4 BIP374: add test vector for optional message
- added 1 more successful test vectors.
  now there are 8 test vectors[test vectors 0..7].
- test vector 5 has optional message
- test vectors 5, 6, 7 have G=GENERATOR
2025-01-28 06:40:58 +05:30
stratospher
41e0f34f76 BIP374: add test vectors for secp256k1 generator point
- added 2 more successful test vectors.
  now there are 7 test vectors[test vectors 0..6].
- test vectors 5, 6 have G=GENERATOR
2025-01-27 14:20:45 +05:30
Brawn
607cac148e
fix: Fix incorrect use of return for raising exceptions Update wallet_policies.py 2025-01-25 22:49:57 +03:00
Jon Atack
58ffd93812
Merge pull request #1605 from DanGould/bip78-mixed-inputs-ok
BIP78: Allow mixed inputs Redux
2025-01-14 08:14:42 -07:00
Jon Atack
f1ad9188b4
Merge branch 'master' into bip78-mixed-inputs-ok 2025-01-14 08:13:20 -07:00
Jon Atack
2f862f75d1
Merge pull request #1396 from DanGould/patch-1
Fix BIP 78 & BIP 174 Conflict: Keep input utxo data through input finalization
2025-01-14 07:52:16 -07:00
Jon Atack
8c494fc9b8
Merge branch 'master' into patch-1 2025-01-14 07:51:07 -07:00
Jon Atack
a0677935bb
Merge pull request #1687 from andrewtoth/silent-payments-psbt
BIP375: Sending Silent Payments in PSBTs
2025-01-13 13:51:25 -07:00
Mark "Murch" Erhardt
1f41c172bf
Merge pull request #1745 from shesek/patch-2
BIP345: fix OP_SUCCESS188 hex value
2025-01-13 14:52:28 -05:00
Andrew Toth
eb10cdb4ce
Update fields in bip174 2025-01-13 12:20:04 -05:00
Andrew Toth
144c4a3a15
Update to BIP375 2025-01-13 10:33:52 -05:00
Andrew Toth
4a7a7cf746
Split up shares and proofs into global or per input fields 2025-01-13 10:29:22 -05:00
Andrew Toth
651ffdded8
Add ref for why sighash_all is required 2025-01-13 10:29:22 -05:00
Andrew Toth
9952599f32
Add newline 2025-01-13 10:29:22 -05:00
Andrew Toth
d29e2f81af
Clarify output script and sp info mutual exclusion and unique id 2025-01-13 10:29:22 -05:00
Andrew Toth
c12ea5ac58
Move updater to before signer 2025-01-13 10:29:22 -05:00
Andrew Toth
0d5e14ce19
Clarify motivation 2025-01-13 10:29:22 -05:00
Andrew Toth
f746ae700f
Add post history and BIP dependencies 2025-01-13 10:29:22 -05:00
Andrew Toth
8e90f02dc5
Update size of ECDH share and unify spacing 2025-01-13 10:29:21 -05:00
Andrew Toth
eb115afa7f
Update bip-PSBT-SP.mediawiki
Co-authored-by: Yuval Kogman <nothingmuch@woobling.org>
2025-01-13 10:29:21 -05:00
Andrew Toth
d02eed4337
Bip Draft: Sending Silent Payments in PSBTs 2025-01-13 10:29:21 -05:00
Nadav Ivgi
c532b53ca2
Fix typo in BIP 345
`OP_SUCCESS188` is `0xbc`, not `0xbb`.
2025-01-11 06:12:14 +02:00
Jon Atack
6a6ef3585f
Merge pull request #1741 from jonatack/2025-01-BIP341-explain-64-byte-signature-format
BIP341: Explain the 64-byte signature format
2025-01-07 06:52:20 -08:00
David Bakin
5767f44499 BIP-341: Explain the 64-byte signature format
Co-authored-by: Pieter Wuille <pieter@wuille.net>
Co-authored-by: Anthony Towns <aj@erisian.com.au>
2025-01-06 16:08:33 -07:00
Jon Atack
cc67871886
Merge pull request #1740 from jonatack/2025-01-merge-misc-fixups
BIP372, BIP381: editorial fixups
2025-01-06 08:47:17 -08:00
Jon Atack
e36714eefa BIP372: editorial grammar fixups 2025-01-06 09:34:05 -07:00
Huberto
450cdbbdaf BIP372, BIP381: trivial spelling fixups 2025-01-06 09:33:47 -07:00
Jon Atack
708162951c
Merge pull request #1726 from epysqyli/patch-1
BIP158: fix btcutil gcs broken link.
2025-01-03 20:58:18 -08:00
Jon Atack
b15a0a1aa9
Merge pull request #1736 from jonatack/2024-12-bip374-make-python-files-executable
BIP374: update reference.py and secp256k1.py to be executable
2025-01-01 16:04:57 -08:00
Jon Atack
4827bdfe60
Merge pull request #1735 from theStack/bip374-add_generated_test_vectors
BIP-374: add generated test vector .csv files
2024-12-31 08:28:35 -08:00
Sebastian Falbesoner
a00064fcfa BIP-374: add generated test vector .csv files 2024-12-30 17:19:55 +01:00
Jon Atack
cce668de3c bip374: update secp256k1.py to be executable 2024-12-28 18:20:56 -07:00
Jon Atack
a261439d92 bip374: update reference.py to be executable 2024-12-28 18:20:33 -07:00
Jon Atack
6c807b7502
Merge pull request #1734 from guggero/bip-0374-test-vector-fix
bip-0374: fix challenge generation, use correct generator point
2024-12-28 13:17:58 -08:00
Oliver Gugger
e141b9501d
bip-0374: remove default value for G in dleq_challenge
To avoid the mistake fixed in the previous commit, we remove the default
value from the G parameter of dleq_challenge.
2024-12-28 21:42:07 +01:00
Oliver Gugger
8bc42a2673
bip-0374: fix challenge generation, use correct G
Both generating and verifying a proof allows for specifying a custom
generator point G. But that custom generator point was not passed into
the dleq_challenge function, resulting in the default (secp256k1)
generator point to be used. This lead to the test vectors being
incorrect.
2024-12-28 15:58:08 +01:00
Mark "Murch" Erhardt
27e1394895
Merge pull request #1733 from andrewtoth/andrew/fix-formatting
BIP374: Fix link and formatting in reference section
2024-12-27 13:14:51 -05:00
Andrew Toth
81668ec98b
BIP374: Fix link and formatting in reference section 2024-12-27 13:05:52 -05:00
Mark "Murch" Erhardt
75b12ac591
Merge pull request #1689 from andrewtoth/dleq
BIP374: Discrete Log Equality Proofs (DLEQ)
2024-12-27 10:29:46 -05:00
Andrew Toth
248540e2ac
fix typo 2024-12-27 10:26:35 -05:00
Mark "Murch" Erhardt
b509e6c85f
Merge pull request #1731 from JeremyRubin/patch-12
[BIP-0349] Add Re-Keying explanation to OP_INTERNALKEY
2024-12-27 10:06:03 -05:00
Andrew Toth
cb3afee850
Move test vectors to bip-0374 directory, add tests for G 2024-12-26 14:17:52 -05:00
Andrew Toth
1842120907
Clarify restraints on given points 2024-12-26 14:16:57 -05:00
Andrew Toth
9d6dc6b681
Update README table, post-history, and comments-uri 2024-12-26 12:10:52 -05:00
Andrew Toth
1350bc423e
BIP374 2024-12-26 12:06:44 -05:00
Andrew Toth
b533b92ed3
Update bip-DLEQ.mediawiki
Co-authored-by: Mark "Murch" Erhardt <murch@murch.one>
2024-12-26 11:52:51 -05:00
Andrew Toth
5799659da0
Update bip-DLEQ.mediawiki
Co-authored-by: Mark "Murch" Erhardt <murch@murch.one>
2024-12-26 11:52:39 -05:00
Mark "Murch" Erhardt
0b37449aa0
Merge pull request #1730 from Gudnessuche/patch-6
Update bip-0370.mediawiki
2024-12-26 11:05:31 -05:00
Mark "Murch" Erhardt
665712c727
Merge pull request #1729 from theStack/fix-bip0340-test-vector-gen_lift_x
BIP-340: fix `lift_x` calls in test vector generation script
2024-12-23 16:09:41 -05:00
Mark "Murch" Erhardt
a0d4fb16f1
Merge pull request #1728 from JeremyRubin/patch-11
[BIP-0349] OP_INTERNALKEY add credit section
2024-12-23 16:05:38 -05:00
Andrew Toth
a0d8aad1df
Fix typo 2024-12-21 16:18:24 -05:00
Andrew Toth
0b590d0d5d
Add footnote recommending using fresh randomness for each proof 2024-12-21 16:17:11 -05:00
Andrew Toth
90e7027f19
Remove changelog 2024-12-21 16:11:46 -05:00
Andrew Toth
fd60d8eded
Add description of proof 2024-12-21 16:11:12 -05:00
Jeremy Rubin
337f559150
[BIP-0349] Add Re-Keying explanation to OP_INTERNALKEY 2024-12-21 14:43:40 -05:00
Andrew Toth
f5d1c12aa9
Add acknowledgements 2024-12-21 13:16:48 -05:00
Andrew Toth
687198d72b
Fail if any point is infinity when verifying 2024-12-21 12:52:54 -05:00
Andrew Toth
1f875a3706
Add note about generating and running test vectors 2024-12-21 12:52:28 -05:00
Jeremy Rubin
d3d34c04f3
[BIP-0349] wrap discussion link
Co-authored-by: Mark "Murch" Erhardt <murch@murch.one>
2024-12-21 12:39:05 -05:00
Jesus Christ
bc300dddd9
Update bip-0370.mediawiki
Minor grammar and punctuation errors
2024-12-21 14:46:35 +00:00
Sebastian Falbesoner
6b16952422 Add test vectors for DLEQ proof generation/verification
Squashed from the following commits:
- Add skeleton for generating DLEQ proof test vectors
- Add run_test_vectors.py counterpart for generated DLEQ proofs
- Add DLEQ test vectors for proof verification
2024-12-21 01:04:44 +01:00
Sebastian Falbesoner
dab5571c37 bugfix: respect message m in DLEQ proof generation/verification 2024-12-21 01:04:00 +01:00
Sebastian Falbesoner
7d921e3314 BIP-340: fix lift_x calls in test vector generation script
The `lift_x` function in the BIP and the reference implementation
expect an integer to be passed rather than a byte array.

Can be tested with:
```
$ python3 test-vectors.py > expected.csv
$ diff test-vectors.csv expected.csv
```
2024-12-20 15:21:41 +01:00
Jeremy Rubin
b02d2db586
[BIP0-0349] OP_INTERNALKEY add credit section 2024-12-19 23:52:11 -05:00
Mark "Murch" Erhardt
2caa8e27b8
Merge pull request #1697 from bigspider/bip388-musig
388: Add support for `musig` in descriptor templates
2024-12-19 10:34:00 -05:00
Salvatore Ingala
2faf09d395
Move changelog to standalone section 2024-12-19 12:33:11 +01:00
Salvatore Ingala
c2026e1de6
Apply suggestions from code review
Co-authored-by: Jon Atack <jon@atack.com>
2024-12-19 12:33:11 +01:00
Salvatore Ingala
a4d9938ed2
Explicitly forbid repeated key indexes in musig() 2024-12-19 12:32:19 +01:00
Salvatore Ingala
e103ddeb1e
Consistency of multisig/multisignature/threshold wording 2024-12-19 12:26:37 +01:00
Salvatore Ingala
662f4c73d7
Add support for musig key placeholders 2024-12-19 12:25:59 +01:00
epysqyli
9815147ab6
BIP158: fix btcutil gcs broken link.
https://github.com/btcsuite/btcutil/blob/master/gcs leads to a broken link. I'm assuming the correct replacement is at https://github.com/btcsuite/btcd/tree/master/btcutil/gcs since `btcutil` is a sub-package in `btcd`, as stated in https://github.com/btcsuite/btcutil/tree/master?tab=readme-ov-file
2024-12-19 00:11:42 +01:00
Jon Atack
8e59f7414b
Merge pull request #1724 from savvar9991/fix-typo
BIP39: replace incorrect word in Italian wordlist special considerations
2024-12-18 07:25:07 -08:00
savvasmoke
e2cf352da4
Update bip-0039-wordlists.md 2024-12-18 21:19:47 +11:00
Jon Atack
671c4628e5
Merge pull request #1717 from kdmukai/patch-3
[BIP-373] Slight rewrite of evenness byte footnote for clarity
2024-12-17 13:07:42 -08:00
kdmukai
45e626feab Slight rewrite of evenness byte explanation for clarity 2024-12-17 08:01:26 -06:00
Maks
4c7d1292dd
Fix typos in BIP-0370 and BIP-0373 (#1718)
* Update bip-0370.mediawiki

* Update bip-0373.mediawiki
2024-12-17 05:18:20 -08:00
youyyytrok
f88f1e4392
Fix typos in BIPs 87/88/98 (#1716)
* typo bip-0087.mediawiki

* typos bip-0088.mediawiki

* typo bip-0098.mediawiki
2024-12-16 12:24:50 -08:00
Danbo
45fbec92cd
BIPs 348 and 379: spelling fixups (#1715)
* Update bip-0348.md

* Update bip-0379.md
2024-12-16 12:23:08 -08:00
Jon Atack
7150ef5f6d
Merge pull request #1714 from Gudnessuche/patch-5
BIP125: Update description of BIPs 68 and 112
2024-12-16 12:18:06 -08:00
Jesus Christ
192f2aca2f
Update for BIP 68 & 112
Given that both BIPs are now final, calling them drafts, seem very stale.
2024-12-14 23:05:00 +00:00
Jon Atack
6521dfdd2c
BIP348: trivial text correction (#1713)
BIP348: trivial text correction
2024-12-13 13:56:25 -08:00
Jesus Christ
7420c04e84
BIP157 grammar fixup: add missing word (#1711) 2024-12-10 19:04:22 -08:00
kdmukai
f799ea1fa0
Trivial text correction 2024-12-10 20:37:01 -06:00
Andrew Toth
b838696c97
Remove cbytes wrapper from m' 2024-12-10 19:20:50 -05:00
Andrew Toth
e4f1d7bb8e
Remove cbytes wrapper from m'
Co-authored-by: Sebastian Falbesoner <sebastian.falbesoner@gmail.com>
2024-12-10 19:18:16 -05:00
Andrew Toth
597004acef
Lowercase secp
Co-authored-by: Sebastian Falbesoner <sebastian.falbesoner@gmail.com>
2024-12-10 19:17:46 -05:00
Andrew Toth
b5d47dfef9
add theStack as co-author 2024-12-09 16:26:10 -05:00
Andrew Toth
ed98dc7b02
Add some more commentary 2024-12-09 14:00:22 -05:00
Andrew Toth
cc7bb12b24
Add optional message to DLEQ 2024-12-09 13:19:57 -05:00
Sebastian Falbesoner
0c7e54d780
BIP-DLEQ: add reference implementation for secp256k1 2024-12-09 11:40:40 -05:00
Jon Atack
45f2934c0c
Merge pull request #1705 from theStack/bip373_improve_pubkey_clarity
BIP-373: denote different public key types/purposes consistently
2024-12-08 19:19:36 -08:00
Mark "Murch" Erhardt
eb3bf03542
Merge pull request #1709 from jonatack/2024-12-bip125-status
BIP125: update status to Final
2024-12-06 13:36:10 -05:00
Mark "Murch" Erhardt
c7abd91cc9
Merge pull request #1535 from reardencode/csfs
BIP 348: OP_CHECKSIGFROMSTACK
2024-12-06 13:29:19 -05:00
Sebastian Falbesoner
50e820836d BIP-373: denote different public key types consistently
Improve the clarity of the BIP w.r.t. pubkeys in the following ways:
- be specific about the purpose of pubkey types in PSBT fields
  ("plain pubkey" alone doesn't say a lot, especially if it's used
   repeatedly within a field)
- replace all uses of "plain pubkey" by "compressed pubkey"
  (the only category that should matter is whether the pubkey type
   is "x-only" or "plain")
- use consistent word order, e.g. prefer
  "compressed aggregate public key" over "aggregate compressed public key"
2024-12-06 00:44:38 +01:00
Jon Atack
749c606281 BIP125: update status to Final 2024-12-05 14:23:32 -06:00
Jon Atack
410a7bc007
BIP340: minor grammar edits (#1706)
BIP340: minor grammar edits
2024-12-04 10:23:33 -08:00
Anurag Lint
81231dad91
Fix link in BIP-84 (#1708)
Fix link to considerations section in BIP-84
2024-12-04 09:57:43 -08:00
Jesus Christ
868c34527f
Update on Alternative Signing
In order for this section to fully be grasped by readers, minor grammatical errors need to be fixed, especially when explaining the "Nonce exfiltration protection"
2024-11-30 16:00:20 +00:00
Brandon Black
d2932bd00d
Add BIP 0348 - CHECKSGIFROMSTACK 2024-11-26 11:23:59 -08:00
Mark "Murch" Erhardt
532c4c10f2
BIP 119: Fix Typo
an template address ↦ a template address
2024-11-25 17:18:04 -05:00
Mark "Murch" Erhardt
66fceff5bb
Merge pull request #1534 from reardencode/internalkey
Add BIP 349: OP_INTERNALKEY
2024-11-25 10:48:08 -05:00
Jesus Christ
7460ad5508
Updated grammatical error relating to Forwarding Addresses
Second sentence in the second paragraph of the Forwarding Addresses section, had a slight grammatical error that needed correcting. 

Helpful for the flurry of interested people keen on reviewing the BIP (i.e. Institutions, non-English nation-states)
2024-11-24 14:31:17 +00:00
Jon Atack
f269890255
Merge pull request #1701 from ajtowns/202411-bip345-coauthor 2024-11-22 16:11:28 -08:00
Murch
217ae0dfa8
BIP349: Set Created header to number assignment 2024-11-14 16:36:54 -05:00
Murch
669d3b3570
BIP349: Fix preamble for CI issues 2024-11-14 16:36:45 -05:00
moonsettler
329b0d3db5
BIP-349 2024-11-14 16:30:28 -05:00
moonsettler
b35383b68f
Fixes and clarifications to address PR comments 2024-11-14 16:30:27 -05:00
Brandon Black
75351f2587
Add bip-internalkey 2024-11-14 16:30:24 -05:00
Jon Atack
16a23b777b
Merge pull request #1691 from akarve/bip85-details
BIP-85: formatting and changelog updates, and add word cases for application 39'
2024-11-13 18:24:11 -08:00
Anthony Towns
65b312fe4a Remove ajtowns from bip-345 coauthor. 2024-11-14 10:21:30 +10:00
Aneesh Karve
b398219e9c BIP-85: Move new reference to be near HMAC code 2024-11-09 14:30:02 -07:00
Aneesh Karve
88f4fc0ece BIP-85: Reorder sections to be more standard, convert HMAC discussion to footnote 2024-11-09 14:24:50 -07:00
Mark "Murch" Erhardt
c58a428fb6
Merge pull request #1677 from scgbckbone/bip39_final
BIP39: update status from Proposed to Final
2024-11-08 12:22:47 -05:00
Jon Atack
bffde65da1
Merge pull request #1695 from achow101/373-clarify-plain-pub
BIP373: Clarify where keys in MuSig fields may appear in the Taproot output
2024-11-08 09:02:58 -08:00
Jon Atack
711802c064
Merge pull request #1696 from bigspider/bip390-nit
BIP390: Clarify that musig cannot be used in top-level pk() or pkh()
2024-11-08 08:57:31 -08:00
Ava Chow
0ff32bd4c2 373: Clarify where keys in MuSig fields may appear in the Taproot output
- The aggregate pubkey in `PSBT_{IN,OUT}_MUSIG2_PARTICIPANT_PUBKEYS` does not have to
  appear anywhere in the Taproot output.
- The plain pubkeys in `PSBT_IN_MUSIG2_PUB_NONCE` and
  `PSBT_IN_MUSIG2_PARTIAL_SIG` must be either the output pubkey, or
  appears in a script, and not the internal key.
2024-11-08 11:43:15 -05:00
scgbckbone
829afccd1a change BIP39 status to Final 2024-11-08 11:32:40 +01:00
Salvatore Ingala
2e8f6ba5e7
Clarify that musig cannot be used in top-level pk() or pkh() 2024-11-08 10:11:47 +00:00
Jon Atack
a12ce760c6
Merge pull request #1694 from pad01g/bip-388-test-vectors-valid-policies
Fix wrong test vector in BIP-388. Sometimes /<0;1>/* is missing. Sometimes it is incorrectly written as <0,1>.
2024-11-07 11:26:30 -08:00
pad01g
dcb140a865 fix wrong test vector. sometimes /<0;1>/* is missing. sometimes incorrectly written as <0,1>. 2024-11-05 09:20:47 +00:00
Andrew Toth
4f5d87adc8
Bip Draft: DLEQ 2024-11-02 23:23:57 -04:00
Jon Atack
40e91fdb94
Merge pull request #1692 from jonatack/2024-10-update-bip125-status
BIP125: update status of Opt-in Full RBF Signaling to Obsolete
2024-10-30 17:51:52 -07:00
Jon Atack
3d86d94fa4 BIP125: update status from Proposed to Obsolete 2024-10-29 11:41:33 -06:00
Aneesh Karve
9133ab2451 BIP-85: Add 15 and 21 word entries to application 39' table 2024-10-25 12:05:56 -07:00
Aneesh Karve
e0cc4f0e3d BIP-85: Rename to 'changelog' and move above Reference implementation(s) 2024-10-25 12:03:06 -07:00
Jon Atack
17c04f9fa1
Merge pull request #1676 from scgbckbone/bip85_final
BIP85: update status to Final
2024-10-25 08:13:16 -07:00
Aneesh Karve
8eac367dae
BIP-85: Add co-author, language code & dice app, TPRV guidance, warn on BIP-32 divergence, grammar & clarity (#1679)
* BIP-85: Add language code, add dice app, warn on BIP-32 divergence, grammar clarity

* BIP-85: Add definite article

Co-authored-by: Jon Atack <jon@atack.com>

* BIP-85: PR suggestions on grammar, clarity

* BIP-85: Add change log

* BIP-85: Proper <references />, semver reference implementations, date on changelog, clarify warning language

* BIP-85: PR suggestion on range formatting

Co-authored-by: Jon Atack <jon@atack.com>

* BIP-85: wordsmith BIP-32 warning

Co-authored-by: Jon Atack <jon@atack.com>

* BIP-85: PR feedback on format, language, order of text

* BIP-85: PR grammar improvements

* BIP-85: Add dice app code to changelog

* BIP-85: Grammar and clarity from PR review

Co-authored-by: Jon Atack <jon@atack.com>

* BIP-85: Improve changelog and bump semvers accordingly; add alphanum password example to dice

* BIP-85: Rectify changelog dates and contents

* BIP-85: Correct 1.3.0 semver in changelog

* BIP-85: Remove fancy warning syntax b/c GH doesn't render it, wordsmith BIP32 warning

* BIP-85: Add and correct semvers in Reference Implementation section

---------

Co-authored-by: Jon Atack <jon@atack.com>
2024-10-25 08:11:00 -07:00
Jon Atack
52894e1aa7
Merge pull request #1681 from jonatack/2024-10-BIP2-update-URLs-to-https
BIP2: replace legacy http links with https
2024-10-22 14:51:39 -07:00
Jon Atack
385ac876d3
Merge pull request #1688 from jlopp/bip99
Fix BIP-99 Formatting
2024-10-20 08:45:33 -07:00
Jameson Lopp
b6ea55291f
fix formatting 2024-10-20 09:00:08 -04:00
Jon Atack
5284427971
Merge pull request #1683 from akarve/bip85-base64-vec-alone
BIP-85: Correct bad test vector for Base64
2024-10-15 09:45:25 -07:00
Jon Atack
0495fad99a
Merge pull request #1686 from psztorc/patch-1
BIP300: fix up markup in comment header
2024-10-15 07:58:43 -07:00
Paul Sztorc
b7bd93fed7
heading typo
this section is (rightly) commented out, but it still (wrongly) shows up at the table of contents in the beginning, this should fix it
2024-10-15 01:09:16 -04:00
Jon Atack
71aafb2a7f
Merge pull request #1685 from bskrksyp9/patch-1
BIP158: fix up code comment typo in gentestvectors.go
2024-10-14 13:01:01 -07:00
Bhaskar Kashyap
c4264ae980
fix typo
Corrected wording in comments
2024-10-14 22:35:43 +05:30
Aneesh Karve
2e98c7115c BIP-85: Correct bad test vector for Base64 2024-10-13 17:02:11 -07:00
Jon Atack
caf8f78f75
Merge pull request #1682 from jonatack/2024-10-update-BIP327-status 2024-10-12 13:15:11 -07:00
Jon Atack
2eb22b8ec6 BIP327: update status 2024-10-11 11:19:56 -06:00
Jon Atack
ca280b9762 BIP2: replace legacy http links with https 2024-10-08 11:03:37 -06:00
Jon Atack
541b6c4db4 BIP39: add license and copyright section
These are required per BIP-2, and they avoid user confusion as seen in

https://github.com/bitcoin/bips/pull/1395#issuecomment-2393915807
2024-10-08 10:54:43 -06:00
Jon Atack
83a1afd985
Merge pull request #1678 from JeremyRubin/patch-9
BIP119: remove James O'Beirne as co-author
2024-10-07 20:46:24 -06:00
Jeremy Rubin
80f8011e9c
Remove j amesob from README.mediawiki from bip-0119 2024-10-06 14:55:31 -04:00
scgbckbone
b0125501f8 change BIP85 status to Final 2024-10-05 16:07:40 +02:00
Jeremy Rubin
a34cb4f769
Remove j amesob from bip-0119.mediawiki coauthor. 2024-10-05 10:01:53 -04:00
Jon Atack
9f588247d8
Merge pull request #1674 from bitcoin/revert-1600-master
Revert "BIP85: Clarify spec, correct test vectors, add Portuguese language code, add dice application"
2024-10-04 16:43:54 -07:00
Jon Atack
3f4a0a17bc
Revert "BIP85: Update/clarify spec, add change log, Portuguese language code,…"
This reverts commit a1be309f91.
2024-10-04 16:18:52 -07:00
Jon Atack
758dfc9f55
Merge pull request #1672 from TheBlueMatt/2024-10-payment-expiry
Explicitly mention care around payment instruction expiry in 353
2024-10-02 11:09:20 -07:00
Matt Corallo
e1aab46c63 Explicitly mention care around payment instruction expiry in 353
If someone puts a lightning BOLT 12 offer in a BIP 353 entry with
the offer expiring before the DNS entry's TTL (plus now), they may
get stuck being unpayable, so its worth explicitly mentioning that
people should take care here.
2024-10-02 16:46:57 +00:00
Aneesh Karve
a1be309f91
BIP85: Update/clarify spec, add change log, Portuguese language code, dice application (#1600)
* BIP-85:

    * Add new maintainer (author unreachable)
    * Swap chain code and private key bytes in application 32' for consistentcy with BIP-32 (major change)
    * Correct derived entropy for application 128169' test vector (major change)
    * Clarify big endian serialization
    * Add the Portuguese language (9') to application 39'
    * Add dice application 89101'
    * Clarify Testnet support for XPRV application 32'
    * Minor grammar, format, clarity improvements
2024-09-25 08:00:54 -07:00
Paul Sztorc
34db0e99fa
Link to latest code -- also shorter/better explanations (#1666)
* Update to CUSF activation client +shorter +clearer

* remove superfluous images

* link to CUSF client, shorter and clearer BIP text
2024-09-23 16:02:34 -07:00
Jon Atack
22660ad307
Merge pull request #1665 from EthanHeilman/patch-1
Uses consistent source for "CAT and Schnorr Tricks"
2024-09-08 17:43:15 -07:00
Ethan Heilman
3350d941a8
Uses consistent source for "CAT and Schnorr Tricks"
For "CAT and Schnorr Tricks I" we used https://medium.com/blockstream/cat-and-schnorr-tricks-i-faf1b59bd298

but for "CAT and Schnorr Tricks II"
https://www.wpsoftware.net/andrew/blog/cat-and-schnorr-tricks-ii.html

This commit changes this so that the original source wpsoftware is used for both links.
2024-09-08 14:34:30 -04:00
Mark "Murch" Erhardt
69d8eeb169
Merge pull request #1657 from TheBlueMatt/2024-07-psbt-dns
Add a PSBT per-output field for BIP 353 DNSSEC Proofs
2024-08-29 16:15:19 -04:00
Matt Corallo
b0d5a07943 Add a PSBT per-output field for BIP 353 DNSSEC Proofs
When using BIP 353 for on-chain addresses (incl silent payments),
it is useful to be able to include DNSSEC proof information in
outputs of a PSBT, which we enable here by defining a standard
field for it.
2024-08-29 19:30:59 +00:00
Mark "Murch" Erhardt
97012a8206
Merge pull request #1644 from bigspider/bip388-updates
388 - Add more motivation, and links to miniscript BIP
2024-08-21 12:43:00 -04:00
Jon Atack
acb195f82e
Merge pull request #1660 from fjahr/bip94-rollback
Revert "Change BIP 94 timewarp delta to 7200 seconds"
2024-08-17 14:19:43 +00:00
Fabian Jahr
2c259b85fd
Revert "Change BIP 94 timewarp delta to 7200 seconds"
This reverts commit 0c2a2172f7.
2024-08-15 11:06:37 +02:00
Jon Atack
34f345335c
Merge pull request #1631 from azuchi/fix-bip386-test-vector
BIP-0386: Fix uncompressed private key test vector
2024-08-14 16:43:59 +00:00
Salvatore Ingala
1811613e07
Further improvements from PR review 2024-08-14 15:07:55 +02:00
Jon Atack
7c62ebea4c
Merge pull request #1654 from storopoli/master
Check typos in CI
2024-08-13 01:12:13 +00:00
Jose Storopoli
52fdb00b6d
ci: add typo checking
typos is a powerful source code spell checker.

Adds a CI job that runs on every PR and
push to master (but can also be run manually with
workflow_dispatch) that checks for typos.

Adds a config file .typos.toml that deals with
false positives and only checks for top-level/one-level
.mediawiki and .md files.
2024-08-12 14:31:41 -03:00
Jon Atack
a626ad6e2a
Merge pull request #1659 from azuchi/bix-bip94-typo
BIP-0094: Fix typo
2024-08-11 18:50:21 +00:00
azuchi
af9557b589 BIP-0094: fix block hex 2024-08-10 10:19:39 +09:00
Jose Storopoli
b87b21e7c1
bip-352: fix typo 2024-08-07 19:02:52 -03:00
Jose Storopoli
498668026e
bip-152: fix typo 2024-08-07 19:02:49 -03:00
Jose Storopoli
da1e3ad545
bip-119: fix typo 2024-08-07 19:02:47 -03:00
Jose Storopoli
c25032a3ff
bip-75: fix typo 2024-08-07 19:02:43 -03:00
Jose Storopoli
b6bf97ba9e
bip-46: fix typo 2024-08-07 19:02:39 -03:00
Mark "Murch" Erhardt
76550880d3
Merge pull request #1658 from fjahr/bip94-timewarp-delta
BIP94: Change timewarp delta to 7200 seconds
2024-08-07 11:31:40 -04:00
Fabian Jahr
0c2a2172f7
Change BIP 94 timewarp delta to 7200 seconds 2024-08-05 23:34:11 +02:00
Salvatore Ingala
00fbea5dcd
Nit from PR review
Co-authored-by: Mark "Murch" Erhardt <murch@murch.one>
2024-08-03 17:05:46 +02:00
Mark "Murch" Erhardt
5e87c919a7
Merge pull request #1601 from fjahr/testnet4
Add BIP94: Testnet 4
2024-08-02 14:01:32 -04:00
Fabian Jahr
a35650e14e
Add BIP 94 - Testnet 4 2024-07-31 16:43:31 -04:00
Matt Corallo
eeaf21d882 Consistently refer to them as "human-readable names", not addresses
It seems confusing to call BIP 353 names "addresses", and most of
the BIP refers to them as "names", but a few "human-readable
addresses" snuck in in a recent change, which are fixed here.
2024-07-31 13:45:09 +00:00
Salvatore Ingala
c2655e0ab9
More adjustments from PR review 2024-07-27 19:36:08 +02:00
Jon Atack
90312d2d67
Merge pull request #1655 from Crypt-iQ/bip324_aad
BIP 324: fix python aad in complete_handshake
2024-07-27 14:03:35 +00:00
Eugene Siegel
0963e43860
BIP 324: fix python aad in complete_handshake 2024-07-26 11:51:52 -04:00
Jon Atack
0f40dd7554
Merge pull request #1653 from OrfeasLitos/trailing-whitespace
Remove trailing whitespace from all BIPs
2024-07-26 15:33:53 +00:00
Orfeas Stefanos Thyfronitis Litos
f085cc2922
Make link title more specific (#1652) 2024-07-25 11:50:08 -07:00
Orfeas Stefanos Thyfronitis Litos
9a56d3544e Remove trailing whitespace from all BIPs 2024-07-25 18:35:39 +03:00
Mark "Murch" Erhardt
ad1d3bc2a7
Merge pull request #1647 from siv2r/minor-fixes
bip327: minor fixes
2024-07-23 13:26:21 -04:00
Jonas Nick
26bb1d8ea3 bip-0327: 1.0.1 -> 1.0.2
(cherry picked from commit 4f2e6e7ffbd2fdc095ab8d59827be9da18b790be)
2024-07-23 13:09:44 +05:30
Mark "Murch" Erhardt
511e670637
Merge pull request #1651 from michael1011/46-fix-pubkey
BIP46 clarify witness
2024-07-22 11:04:59 -04:00
Mark "Murch" Erhardt
3b72a7f129
Fix typos in BIP 388 and BIP 390
Fix typos
2024-07-22 09:37:07 -04:00
michael1011
f1a5c71094
BIP46 clarify witness 2024-07-21 18:32:51 +02:00
omahs
f61bdadafb
fix typo 2024-07-21 09:31:28 +02:00
omahs
bc1c18a289
fix typo 2024-07-21 09:26:16 +02:00
siv2r
0d79b5eeb5 remove P = None check as cpoint never returns None 2024-07-19 23:52:53 +05:30
siv2r
1c6ac0c4cf bip327: minor fixes
- An error test vector doesn’t specify the InvalidContributionError type
- In *DeterministicSign*, use GetXonlyPubkey instead of GetPubkey
- The key_agg_and_tweak fn doesn’t specify the return type
- In partial_sig_verify_internal, the pubkey arg should be PlainPk
- Remove unused enumerate() fn calls
- In test_sign_verify, add an additional assert statement
2024-07-19 23:52:41 +05:30
Mark "Murch" Erhardt
812907c2b0
Merge pull request #1649 from jonasschnelli/bip_159_update
159: Mark as final
2024-07-17 16:41:44 -04:00
Jonas Schnelli
dfacb8de6a
159: Mark as final 2024-07-17 22:09:22 +02:00
Mark "Murch" Erhardt
99cf00cb85
Merge pull request #1648 from jonasschnelli/bip_150_update
BIP150: Deferred

More robust and private protocols have been drafted and need to be formalized into a BIP
2024-07-17 16:08:17 -04:00
Jonas Schnelli
29312fbe91
BIP150: Deferred 2024-07-17 21:56:18 +02:00
Mark "Murch" Erhardt
cd44ec8739
Merge pull request #1646 from pinheadmz/353-cat-txt
bip353: concatenate strings in TXT record
2024-07-17 08:56:22 -04:00
Salvatore Ingala
0b3c79c257
Apply suggestions from code review
Co-authored-by: Mark "Murch" Erhardt <murch@murch.one>
2024-07-17 10:18:53 +02:00
Matthew Zipkin
8ba081f472
bip353: concatenate strings in TXT 2024-07-15 20:37:10 -04:00
Jon Atack
af8f9e470b
Merge pull request #1633 from josibake/update-bip352-appendix
BIP352: Update appendix
2024-07-12 13:29:05 +00:00
Jon Atack
ee56747677
Merge pull request #1645 from Sjors/2024/07/bip353
bip353: improve ₿-prefix instructions
2024-07-12 13:19:27 +00:00
Mark "Murch" Erhardt
891bfc4095
Merge pull request #1599 from theborakompanioni/bip-46
bip-0046: Address Scheme for Timelocked Fidelity Bonds
2024-07-12 08:15:48 -04:00
Sjors Provoost
ceb4f332a4
bip353: improve ₿-prefix instructions 2024-07-12 09:11:17 +02:00
josibake
7a8bc14b80
bip352: update appendix
Numbers from the appendix were slightly innaccurate and out of date. Update to mention non-dust UTXOs
and update the numbers to reflect current usage.

Considering the appendix is purely informational and the corrections here are minor, Ive left of
adding a changelong entry.
2024-07-12 09:05:35 +02:00
Jon Atack
bcc892c646
Merge pull request #1641 from achow101/finalize-370
370: Mark as final
2024-07-11 19:00:57 +00:00
Ava Chow
968c4ee200 370: Mark as final 2024-07-11 14:25:43 -04:00
Ava Chow
e7286a5356 370: Set reference implementation to Bitcoin Core PR. 2024-07-11 14:25:19 -04:00
Jon Atack
bee19da78a
Merge pull request #1642 from achow101/finalize-371
371: Mark as final
2024-07-11 17:41:50 +00:00
Jon Atack
db5e548c8b
Merge pull request #1640 from achow101/finalize-86
86: Mark as final
2024-07-11 17:36:37 +00:00
Salvatore Ingala
0adf7c36e1
Nit: it's not 'two' descriptors if one uses the multipath expressions per BIP-389 2024-07-11 10:33:13 +02:00
Salvatore Ingala
8c2f54d33b
Add references to the miniscript BIP-379 2024-07-11 10:31:01 +02:00
Jon Atack
dd08b3eb95
Merge pull request #1643 from achow101/finalize-descriptors
380-387: Mark basic descriptor BIPs as final
2024-07-10 23:12:02 +00:00
Ava Chow
d71428ade5 380-387: Mark basic descriptor BIPs as final 2024-07-10 19:06:05 -04:00
Ava Chow
516fae6726 86: Mark as final 2024-07-10 19:05:02 -04:00
Ava Chow
6b4a03bb5d 371: Mark as final 2024-07-10 19:04:46 -04:00
Mark "Murch" Erhardt
e766df42d3
Merge pull request #1636 from sdaftuar/patch-1
Move BIP 339 to Final
2024-07-10 15:49:10 -04:00
Suhas Daftuar
79e2d28efb Move BIP 339 to Final 2024-07-10 15:48:05 -04:00
Mark "Murch" Erhardt
96ddea3987
Merge pull request #1638 from sdaftuar/bip130-final
Move BIP 130 to Final
2024-07-10 15:44:34 -04:00
Mark "Murch" Erhardt
1dd09509df
Merge pull request #1637 from sipa/202407_bip324_final
Mark BIP324 as final
2024-07-10 15:43:03 -04:00
Mark "Murch" Erhardt
031e10f69e
Merge pull request #1639 from sdaftuar/bip338-withdrawn
Move BIP 338 to Withdrawn
2024-07-10 15:42:45 -04:00
Suhas Daftuar
56f7e70991 Move BIP 338 to Withdrawn
The PR implementing this BIP was never merged into Bitcoin Core,
in favor of an alternative approach.
2024-07-10 15:36:54 -04:00
Suhas Daftuar
729c44c4ea Move BIP 130 to Final 2024-07-10 15:19:47 -04:00
Jon Atack
0c0ae07b81
Merge pull request #1634 from achow101/389-no-dupes
389: Explicitly disallow duplicate multipath
2024-07-10 19:03:56 +00:00
Pieter Wuille
f3bd1eba67 Mark BIP324 as final 2024-07-10 14:59:46 -04:00
Salvatore Ingala
3fd971455a
Add paragraph on key reuse 2024-07-10 17:58:48 +02:00
Ava Chow
c88c3970ed 389: Explicitly disallow duplicate multipath 2024-07-09 15:15:13 -04:00
DanGould
bd01a269e5
BIP78: Doc amount parameter not required
It's an optional parameter in BIP 21 Bitcoin URIs, but it doesn't hurt
to make it explicit.

Co-authored-by: Martin Habovstiak <martin.habovstiak@gmail.com>
2024-07-08 13:57:30 -04:00
DanGould
72d8bb04b8
BIP78: Clarify output substitution
The original text is ambiguous to allowing transaction cut-through
or not. Transaction cut-through enables savings by posting multiple
transaction intents through a single 2-party payjoin and is used
in practice in payjoins today. Let's explicitly allow it in the text.

Co-authored-by: Martin Habovstiak <martin.habovstiak@gmail.com>
2024-07-08 13:57:30 -04:00
DanGould
539fd85498
BIP78: Allow mixed inputs
Disallowing mixed inputs was based on incorrect assumption that no
wallet supports mixed inputs and thus mixed inputs imply PayJoin.
However there are at least three wallets supporting mixed inputs.
(Confirmed: Bitcoin Core, LND, Coinomi) Thus it makes sense to enable
mixed inputs to avoid a payjoin-specific fingerptint. To avoid
compatibility issues a grace period is suggested.

Co-authored-by: Martin Habovstiak <martin.habovstiak@gmail.com>
2024-07-08 13:57:30 -04:00
Mark "Murch" Erhardt
0a78fc10bd
Merge pull request #1632 from douglaz/patch-1
Fix typo in bip-0065
2024-07-08 12:02:31 -04:00
theborakompanioni
4f788d69f5
docs(bip-0046): add endpoint signing example 2024-07-08 12:25:37 +02:00
theborakompanioni
b916adebae
docs(bip-0046): add cert format and clarify expiry param 2024-07-08 11:01:26 +02:00
theborakompanioni
0cdb745ee0
docs(bip-0046): apply minor wording improvement suggestions
by @AdamISZ
2024-07-08 10:48:53 +02:00
douglaz
d3ff66e984
Fix typo in bip-0065 2024-07-07 01:01:03 +00:00
azuchi
7acfe207e0 BIP-0386: Fix uncompressed private key test vector 2024-07-06 21:49:37 +09:00
Jon Atack
5a4b5ad67a
Merge pull request #1623 from satsie/satsie-bip78
BIP78: spelling and grammar updates
2024-07-04 01:14:39 +00:00
Stacie
5700a230dc BIP78: spelling and grammar updates
Co-authored-by: Dan Gould <d@ngould.dev>
Co-authored-by: Jon Atack <jon@atack.com>
2024-07-03 21:00:05 -04:00
Jon Atack
4f5a081d82
Merge pull request #1619 from real-or-random/patch-20
bip-0327: Remove obsolete paragraph
2024-07-01 18:52:43 +00:00
Jon Atack
2218f69829
BIP352: Improve input_hash wording (#1629)
BIP352: Improve `input_hash` wording
2024-06-29 15:15:35 +00:00
Sebastian Falbesoner
2a99b8f925
BIP-352: use own ripemd160 for reference implementation (#1616)
On some operating systems, Python doesn't provide the expected ripemd160
implementation anymore, so the reference implementation fails to start.
E.g. in Ubuntu 22.04:

----------------------------------------------------------------------------------------------
$ ./reference.py send_and_receive_test_vectors.json
Simple send: two inputs
Traceback (most recent call last):
  File "/usr/lib/python3.10/hashlib.py", line 160, in __hash_new
    return _hashlib.new(name, data, **kwargs)
ValueError: [digital envelope routines] unsupported

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/thestack/bips/bip-0352/./reference.py", line 228, in <module>
    pubkey = get_pubkey_from_input(vin)
  File "/home/thestack/bips/bip-0352/./reference.py", line 46, in get_pubkey_from_input
    pubkey_hash = hash160(pubkey_bytes)
  File "/home/thestack/bips/bip-0352/bitcoin_utils.py", line 130, in hash160
    return hashlib.new("ripemd160", hashlib.sha256(s).digest()).digest()
  File "/usr/lib/python3.10/hashlib.py", line 166, in __hash_new
    return __get_builtin_constructor(name)(data)
  File "/usr/lib/python3.10/hashlib.py", line 123, in __get_builtin_constructor
    raise ValueError('unsupported hash type ' + name)
ValueError: unsupported hash type ripemd160
----------------------------------------------------------------------------------------------

Fix this by providing a manual implementation, taken from the functional test framework
of Bitcoin Core. See corresponding issue https://github.com/bitcoin/bitcoin/issues/23710 and
PR https://github.com/bitcoin/bitcoin/pull/23716
2024-06-29 07:08:49 -07:00
josibake
8ac84bd344
BIP352: improve input_hash wording
Since https://github.com/bitcoin/bips/pull/1622, it makes more sense
to define input_hash inline, vs having its own section.
2024-06-29 14:31:32 +02:00
Ava Chow
3b99594660 BIP 379: Specify Miniscript
Co-Authored-By: Antoine Poinsot <darosior@protonmail.com>
2024-06-27 11:08:49 -06:00
Mark "Murch" Erhardt
5d77440479
Merge pull request #1540 from achow101/musig2
328, 390, 373: BIPs for MuSig2 derivation, descriptors, and PSBT fields
2024-06-25 17:36:09 -04:00
Elias Rad
3d299b4eb0
BIP39: fix grammar in wordlists doc (#1626) 2024-06-25 10:26:19 -07:00
Jon Atack
62161fb705
Merge pull request #1625 from OrfeasLitos/typo
BIP143: fix typo
2024-06-25 16:28:48 +00:00
Orfeas Stefanos Thyfronitis Litos
a1590ca121 Fix typo 2024-06-25 17:24:41 +01:00
Jon Atack
e8664b28fb
Merge pull request #1620 from theStack/bip352-mention-input_pubkey_sum-infinity-case
BIP-352: handle invalid privkey / pubkey sums for sending / scanning, add changelog
2024-06-22 20:02:56 +00:00
Sebastian Falbesoner
496e4295e7 BIP-352: add change log (SemVer format)
The first paragraph is taken from BIP-327, with the sentence
about MAJOR version zero removed, as it's not relevant here
(we don't track the pre-merge history).
2024-06-22 20:30:50 +02:00
Sebastian Falbesoner
59cc43d727 BIP-352: scanning: add step to skip tx if input pubkeys sum A is point at infinity
The input data for the test vector is taken from the signet transaction
fe788cf6578d547819def43d79e6c8f0153d4885f5a343d12bd03f34507aabd6
which spends two P2WPKH inputs with negated pubkeys (x, y) and (x, -y)
from the funding transaction 3a286147b25e16ae80aff406f2673c6e565418c40f45c071245cdebc8a94174e
(see also https://github.com/bitcoin-core/secp256k1/pull/1519#issuecomment-2143167510
and the output from the script in the previous commit message).

Co-authored-by: josibake <josibake@protonmail.com>
2024-06-22 01:48:44 +02:00
Sebastian Falbesoner
47033c62dc BIP-352: sending: add step to fail if input privkeys sum a is zero
The test vector data was generated with a Python script
(see bc15ea8d0f/contrib/silentpayments/submit_input_pubkeys_infinity_tx.py),
leading to the following output:

---------------------------------------------------------------------------------------------------------
     Privkey 1: a6df6a0bb448992a301df4258e06a89fe7cf7146f59ac3bd5ff26083acb22ceb
     Privkey 2: 592095f44bb766d5cfe20bda71f9575ed2df6b9fb9addc7e5fdffe0923841456
      Pubkey 1: 02557ef3e55b0a52489b4454c1169e06bdea43687a69c1f190eb50781644ab6975
      Pubkey 2: 03557ef3e55b0a52489b4454c1169e06bdea43687a69c1f190eb50781644ab6975
scriptPubKey 1: 00149d9e24f9fab4e35bf1a6df4b46cb533296ac0792
scriptPubKey 2: 00149860538b5575962776ed0814ae222c7d60c72d7b
     Address 1: tb1qnk0zf706kn34hudxma95dj6nx2t2cpujz7j5t5
     Address 2: tb1qnps98z64wktzwahdpq22ug3v04svwttm7gs8wn
-> Funding tx submitted: 3a286147b25e16ae80aff406f2673c6e565418c40f45c071245cdebc8a94174e

Taproot output address for spending tx: tb1pqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqkgkkf5
-> Spending tx submitted: fe788cf6578d547819def43d79e6c8f0153d4885f5a343d12bd03f34507aabd6
---------------------------------------------------------------------------------------------------------
2024-06-22 01:40:19 +02:00
Jon Atack
70a714372f
Merge pull request #1622 from theStack/bip352-simplify_input-hash_flow
BIP-352: generate `input_hash` after summing up keys (simplification)
2024-06-21 14:03:39 +00:00
theborakompanioni
0f1eba2a60
docs(bip-0046): add test certificate for the 960th timelocked address 2024-06-20 17:29:37 +02:00
Sebastian Falbesoner
fe0f83531e BIP-352: generate input_hash after summing up keys (simplification)
For both sender and receiver, generating the input hash is currently
listed as the first step. This already involves summing up the public
keys, even though summing up key material (private keys for sender,
public keys of inputs for receiver) is then again listed explicitly
in later steps.

It seems to be more obvious and less redundant (and also hopefully less
confusing for readers) to reorder the instructions to calculate the
input_hash _after_ the key aggregation is done to reuse the result. In
case of the sender, the private key sum has to be multiplicated with G
in order to the get to the corresponding input pubkey sum.

This also corresponds to the current BIP352 implementation in the
secp256k1 library (https://github.com/bitcoin-core/secp256k1/pull/1519).
The reference implementation in Python here is adapted for the sender
side, the receiver side has already generated the input_hash after
summing up the pubkeys.
2024-06-20 00:33:14 +02:00
theborakompanioni
b7a5f9ce60
docs(bip-0046): apply minor wording improvement suggestions
by @murchandamus
2024-06-19 14:06:41 +02:00
Ava Chow
806b8b886f BIP 373: add MuSig2 PSBT Fields BIP 2024-06-18 20:09:26 -04:00
Ava Chow
6b9138c1a1 BIP 390: Add MuSig2 descriptor BIP 2024-06-18 20:09:26 -04:00
Ava Chow
48ebcb2191 BIP 328: add MuSig2 derivation BIP 2024-06-18 20:09:26 -04:00
Tim Ruffing
6a7af366a5
bip-0327: Remove obsolete paragraph 2024-06-13 20:54:57 +02:00
Glen Cooper
85cda4e225
BIP 15: Remove broken hyperlink to Vanitygen (#1618) 2024-06-11 14:23:48 -04:00
Jon Atack
e21bf40e0c
Merge pull request #1617 from 1440000bytes/bip301
Fix bip number in specification
2024-06-10 20:46:44 +00:00
/dev/fd0
14af3d6fe9
fix bip number 2024-06-10 20:05:49 +00:00
Mark "Murch" Erhardt
1f8ce57410
Merge pull request #1615 from satsie/satsie-more-repeat-words
BIP340: remove repeat words
2024-06-10 13:31:04 -04:00
Dan Gould
e4267374fb
Keep input utxo data through input finalization
The reference sender implementation and \`payjoin proposal\` test vectors
are adjusted accordingly.

According to the psbt Input Finalizer spec "All other data except the
UTXO and unknown fields in the input key-value map should be cleared from
the PSBT. The UTXO should be kept to allow Transaction Extractors to
verify the final network serialized transaction."

I ran into a problem where an LND acting as sender FinalizePsbt gRPC
fails when sender utxo information is missing. I see no good reason to
remove utxo information from the PSBT.
2024-06-10 13:11:38 -04:00
Mark "Murch" Erhardt
9cfe3a4a90
Merge pull request #1551 from TheBlueMatt/2024-02-dns-payment-instructions
Add BIP 353: DNS Payment Instructions
2024-06-10 11:04:20 -04:00
Stacie
44984acde9 BIP340: remove repeat words 2024-06-09 21:56:51 -04:00
Jon Atack
bc520fade5
Merge pull request #1614 from satsie/satsie-bip79-edit
BIP79: remove repeat word
2024-06-09 03:23:04 +00:00
Stacie
b33c948f00 BIP79: remove repeat word 2024-06-08 23:00:17 -04:00
Murch
1957127894
Merge remote-tracking branch 'upstream/master' into bip-46
To fix the merge conflict caused by BIP 47 getting updated to final.
2024-06-07 11:16:51 -04:00
theborakompanioni
8f0962a1ba
chore(bip-0046): remove superfluous newline 2024-06-07 12:05:20 +02:00
theborakompanioni
821fb900f8
chore(bip-0046): less ambiguous message prefix style
by @AdamISZ
2024-06-07 12:04:30 +02:00
theborakompanioni
0a12bf8572
docs(bip-0046): apply minor wording improvement suggestions
by @AdamISZ
2024-06-06 14:20:22 +02:00
theborakompanioni
87bbc4aeb6
docs(bip-0046): add bip-0046 to readme 2024-06-06 12:51:44 +02:00
Matt Corallo
4f75edb2b8 Add a BIP which resolves human readable names into payment info
User behavior has clearly indicated a strong demand for the
resolution of human-readable names into payment instructions. This
BIP defines a protocol to do so using only the DNS, providing for
the ability to query such resolutions privately, while utilizing
DNSSEC to provide compact and simple to verify proofs of mappings.
2024-06-04 20:40:24 +00:00
Luke Dashjr
70d9b07ab8
Merge pull request #1598 from ChrisCho-H/master
bip-0322: add another valid sig vector not to confuse
2024-05-31 13:47:31 -04:00
Jon Atack
9636d9c683
Merge pull request #1603 from cocoyeal/remove_duplicated_words
Remove duplicated words
2024-05-31 04:15:59 +00:00
cocoyeal
46a2440718 remove duplicated words 2024-05-29 16:18:11 +08:00
Jon Atack
758a58ab54
Merge pull request #1602 from Sajjon/cyon_fix_typos
Fix typos on 17 files.
2024-05-28 20:04:43 -07:00
Jon Atack
10650becef
Merge pull request #1541 from glozow/2024-01-v3-prio
BIP431: Opt In Topologically Restricted Until Confirmation Transactions For More Robust Fee-bumping
2024-05-28 19:50:57 -07:00
Mark "Murch" Erhardt
79be0f9c52
Merge pull request #1556 from TomBriar/bip-tombriar-compressed-transactions
BIP 337: Compressed Transactions
2024-05-28 14:49:08 -04:00
Murch
f240c40284
BIP-0337: Add table entry, move to numbered file 2024-05-28 14:45:04 -04:00
Murch
73cfb05b94
BIP-0337: Fix Comments-URI 2024-05-28 14:44:29 -04:00
Tom Briar
996e31fa16
bip-tombriar-compressed-transactions 2024-05-28 14:44:27 -04:00
Alexander Cyon
1eefea0456 Fix typos on 17 files. 2024-05-28 19:25:46 +02:00
theborakompanioni
2bc326e6af
docs(bip-0046): add Rationale section 2024-05-27 10:33:48 +02:00
theborakompanioni
25361d28ed
chore(bip-0046): add tbk to Author header 2024-05-27 10:33:17 +02:00
theborakompanioni
a6f1cf3e0d
chore(bip-0046): improve timelock point in time explanation 2024-05-27 10:25:14 +02:00
theborakompanioni
722a388ae3
chore(bip-0046): fix date format in Post-History header 2024-05-27 10:13:28 +02:00
theborakompanioni
0b353bc7db
docs(bip-0046): add Backwards Compatibility section 2024-05-27 10:10:22 +02:00
glozow
04d3a0609b Define BIP431: TRUCs 2024-05-23 16:33:00 +01:00
theborakompanioni
f9d370d3da
chore(bip-0046): scriptPubKey -> witness programm 2024-05-23 15:52:46 +02:00
theborakompanioni
00c7d0b815
fix(bip-0046): change license from Public Domain to CC0-1.0 2024-05-23 15:48:23 +02:00
theborakompanioni
164412d08b
docs(bip-0046): add Copyright section 2024-05-23 14:30:48 +02:00
theborakompanioni
5209a28c1a
docs(bip-0046): add Comments-URI header 2024-05-23 14:27:20 +02:00
theborakompanioni
57f1fe3f4b
chore(bip-0046): remove (optional) Comments-Summary header 2024-05-23 14:24:42 +02:00
theborakompanioni
03a679958a
docs(bip-0046): change title to 'Address Scheme for Timelocked Fidelity Bonds' 2024-05-23 14:23:44 +02:00
theborakompanioni
64f93a239d
chore(bip-0046): fix typos and grammar 2024-05-23 14:23:07 +02:00
theborakompanioni
8e109f98de
docs(bip-0046): add bip number to header section 2024-05-23 14:18:08 +02:00
theborakompanioni
05e2c0c12f
chore(bip-0046): rename bip-fidelity-bonds to bip-0046 2024-05-23 14:16:38 +02:00
Jon Atack
e2f7481a13
Merge pull request #1445 from MarnixCroes/bip38-fix-links
BIP38: remove broken links
2024-05-22 05:06:25 -07:00
Marnix
4c08e2c0bf BIP38: remove dead links 2024-05-22 11:30:43 +02:00
Jon Atack
740e826c19
Merge pull request #1579 from achow101/stop-link-spam-38
38: Remove other implementation section and dead reference implementation link
2024-05-16 11:22:58 -07:00
Jon Atack
e3ef9a5646
Merge pull request #1580 from achow101/stop-link-spam-85
85: Remove other implementation sections
2024-05-16 07:05:48 -07:00
Chris Hyunhum Cho
2f311cc629
bip-0322: add another valid sig vector not to confuse 2024-05-15 11:51:28 +09:00
Jon Atack
96161aeaf5
Merge pull request #1591 from siv2r/bip327-fix-verify-fail-vector
Fix the first two test vectors of verify fail test
2024-05-14 01:59:40 -07:00
siv2r
508e3a6a40 Fix the four test vectors
- first two vectors of verify_fail_test
- first two vectors of verify_error_test
2024-05-14 07:39:38 +05:30
Mark "Murch" Erhardt
911e710cbb
Merge pull request #1595 from threewebcode/patch-1
bip-0114: fix typo
2024-05-13 13:03:49 -04:00
Mark "Murch" Erhardt
bc87508a0c
Merge pull request #1594 from jonatack/2024-05-bip352-coredev-link-fixup
BIP352: fix link to coredev discussion
2024-05-13 12:57:50 -04:00
Mark "Murch" Erhardt
77f081789f
Merge pull request #1593 from jonatack/2024-05-bip388-fixups
BIP388 fixups
2024-05-13 12:53:58 -04:00
Afanti
2157872faa
bip-0114: fix typo 2024-05-13 10:25:31 +08:00
Jon Atack
f4693dc0fd bip352: fix link to coredev discussion 2024-05-12 11:22:56 -06:00
Jon Atack
4c689f7cf9 bip-0388: make reference implementation executable 2024-05-12 11:08:30 -06:00
Jon Atack
e7fef46177 bip-0388: fix 3 links 2024-05-12 11:08:30 -06:00
Jon Atack
10e5f62a38
Merge pull request #1592 from bigspider/bip-388-proposed
BIP-388: change status to 'Proposed'
2024-05-12 09:31:45 -07:00
Salvatore Ingala
1d7f12d36a
Update BIP-388 status to 'Proposed' 2024-05-12 11:56:08 +02:00
Salvatore Ingala
3865057e2d
Improve formatting 2024-05-12 11:47:48 +02:00
Jon Atack
8256ea0134
Merge pull request #1590 from RandyMcMillan/patch-5
bip-0388:proof of registration - use wikimedia bold syntax
2024-05-10 14:00:22 -07:00
Jon Atack
85ccf2379b
Merge pull request #1469 from theborakompanioni/patch-1
fix(bip85): rectify pwd_length in PWD BASE85 table
2024-05-10 09:48:10 -07:00
@RandyMcMillan
99435fa0b5
bip-0388.mediawiki:proof of registration 2024-05-10 09:39:56 -04:00
Mark "Murch" Erhardt
cc2a9c71a0
Merge pull request #1589 from real-or-random/202405-0324-unusedcsv
BIP324: Remove obsolete test vector file
2024-05-09 14:07:50 -04:00
Tim Ruffing
3b77bc07fd BIP324: Remove obsolete test vector file 2024-05-09 10:12:42 +02:00
Olaoluwa Osuntokun
18956f177a
Merge pull request #1411 from john-moffett/patch-1
BIP-158: Fix description of M parameter
2024-05-08 16:49:25 -07:00
Mark "Murch" Erhardt
d2300bed33
Merge pull request #1458 from josibake/silent-payments-bip
BIP 352: Silent Payments
2024-05-08 13:22:03 -04:00
josibake
17e1d168e8
Minor fixups
- Fix link
- Add explanation for scalar multiplication
- Spelling error in test section
2024-05-08 18:34:39 +02:00
josibake
9929215dcf
Change status to Proposed 2024-05-08 18:34:34 +02:00
josibake
ef108e0e77
Add post-history 2024-05-08 18:14:56 +02:00
josie
0ccf42c869
Apply suggestions from code review
Punctuation and wording improvements.

Co-authored-by: Mark "Murch" Erhardt <murch@murch.one>
2024-05-08 18:14:56 +02:00
josibake
c2b27a0ce5
Update README 2024-05-08 18:14:55 +02:00
josibake
33a99a1a17
Add reference.py with test vectors
* reference.py contains the silent payment specific code
* secp256k1.py for doing the EC operations
* bech32m.py contains code for encoding/decoding bech32(m) addresses
* bitcoin_utils.py contains some helper code, not specific to silent
  payments
* send_and_receive_test_vectors.json contains the wallet unit test
  vectors

Co-Authored-By: S3RK <1466284+S3RK@users.noreply.github.com>
Co-Authored-By: Oghenovo Usiwoma <37949128+Eunovo@users.noreply.github.com>
Co-authored-by: S.Blagogee <34041358+setavenger@users.noreply.github.com>
2024-05-08 18:14:55 +02:00
josibake
96f4e5a4c4
Add BIP for Silent Payments
Co-Authored-By: Ruben Somsen <rsomsen@gmail.com>
2024-05-08 18:14:55 +02:00
Mark "Murch" Erhardt
56575ff533
Merge pull request #1389 from bigspider/bip-wallet-policies
BIP 388: Wallet Policies for Descriptor Wallets
2024-05-08 08:54:42 -04:00
Mark "Murch" Erhardt
690f70ce44
Merge pull request #1586 from katesalazar/20240504
BIP38, help GitHub intermediate syntax highlighter
2024-05-08 08:49:51 -04:00
Salvatore Ingala
7d0c08e38a
More nits from PR review 2024-05-07 22:24:23 +02:00
Salvatore Ingala
cf2250e27c
Apply suggestions from code review
Co-authored-by: Mark "Murch" Erhardt <murch@murch.one>
2024-05-07 22:10:44 +02:00
katesalazar
c88a018409 Update bip-0038.mediawiki
Separating the bold and the italic markup helps inconsistent parsing
(see screenshots in PR #1586).
2024-05-07 15:44:50 +00:00
katesalazar
4ddb0cc893 Update bip-0038.mediawiki
Add missing closing double single quote. The italicized paragraph gets
cautiously closed.
2024-05-07 15:34:37 +00:00
Salvatore Ingala
a0c8501f96
Added BIP-388 to README 2024-05-07 11:00:23 +02:00
Salvatore Ingala
95cf539161
Improvements from PR review.
- Removed large example of taproot policy; replaced with the textual description
- Added an example of a taproot wallet policy containing miniscript
2024-05-07 10:58:02 +02:00
Salvatore Ingala
40c7760d78
Apply suggestions from code review
Co-authored-by: Mark "Murch" Erhardt <murch@murch.one>
2024-05-07 10:58:02 +02:00
Salvatore Ingala
25657cbee6
Update assigned BIP number; change type to "Standards Track" 2024-05-07 10:58:01 +02:00
Salvatore Ingala
44798a2a9e
New BIP: Wallet Policies 2024-05-07 10:58:01 +02:00
Jon Atack
c4c5c69bdf
Merge pull request #1567 from achow101/multi_a
BIP 387: multi_a() descriptor
2024-05-06 17:00:58 -07:00
Ava Chow
945b281155 BIP 387: multi_a() descriptor 2024-05-06 18:26:11 -04:00
Mark "Murch" Erhardt
feacf8f2ed
Merge pull request #1525 from EthanHeilman/cat
BIP 347: OP_CAT in Tapscript
2024-05-06 14:02:38 -04:00
Ethan Heilman
7ad0f821dd
Adds stable URL for Liar, Liar, Coins on Fire! 2024-05-06 13:12:47 -04:00
Mark "Murch" Erhardt
8808e78883
Merge pull request #1583 from yannickseurin/BIP-340
Update BIP 340 with fresher info on multi-, threshold, and blind signatures
2024-05-06 12:05:32 -04:00
Yannick Seurin
5d10163efc
more precise wording
Co-authored-by: Tim Ruffing <crypto@timruffing.de>
2024-05-06 11:40:02 +02:00
Yannick Seurin
1f1f24f0ef
spelling out FROST
Co-authored-by: Tim Ruffing <crypto@timruffing.de>
2024-05-06 11:39:15 +02:00
Ethan Heilman
cda34eef1c
Improved accuracy of paragraph on OP_CAT's removal in 2010 2024-05-05 17:57:27 -04:00
Yannick Seurin
4dcdadee67 update changelog 2024-05-03 10:32:42 +02:00
Yannick Seurin
1ed7d03393 more precise wording for key-prefixing justification 2024-05-03 10:31:27 +02:00
Mark "Murch" Erhardt
f05e1627f9
Merge branch 'master' into cat 2024-05-02 22:00:03 -04:00
Murch
31f51927f1
Add BIP-347 OP_CAT to table 2024-05-02 21:57:31 -04:00
Ethan Heilman
6ea9fda9ac
Fixes link to liar liar 2024-05-02 18:39:58 -04:00
Jon Atack
24a15a6ae3 Merge branch 'ysangkok-final-bip-0133'
* ysangkok-final-bip-0133:
  Final BIP-0133
2024-05-01 16:56:11 -06:00
Janus
e2547df1cd Final BIP-0133 2024-05-01 16:55:55 -06:00
Jon Atack
fa24446df4
Merge pull request #1585 from achow101/fix-link-checks
ci: Fix link checks
2024-05-01 15:41:34 -07:00
Ava Chow
3a2031380d ci: Run link format check on all mediawiki documents 2024-05-01 18:04:35 -04:00
Ava Chow
3bd457c595 310: Fix incorrectly formatted link 2024-05-01 18:00:38 -04:00
Ava Chow
e155b58f13 197: Fix incorrectly formatted links 2024-05-01 17:59:53 -04:00
Jon Atack
253dd0999e
Merge pull request #1578 from achow101/fix-ci
ci: Update diff checks so that the task actually works
2024-05-01 14:22:37 -07:00
Ava Chow
602cd676cd
buildtable.pl: Also check .md files (#1577) 2024-05-01 17:02:36 -04:00
Ava Chow
09439bb662 ci: Clarify that diffchecks fails until a number is assigned 2024-05-01 17:02:06 -04:00
Ava Chow
94ca14f34e ci: Use actions/checkout@v4
v3 is deprecated
2024-05-01 17:02:06 -04:00
Ava Chow
98f000a6fb diffchecks.sh: Make success clear and exit with failure on error 2024-05-01 17:02:06 -04:00
Ethan Heilman
6815c39f93
Adds commas
Co-authored-by: Mark "Murch" Erhardt <murch@murch.one>
2024-05-01 16:32:28 -04:00
Ethan Heilman
e9e7636f7e
Increases commas and capital letters
This improves readability, thanks!

Co-authored-by: Mark "Murch" Erhardt <murch@murch.one>
2024-05-01 16:31:49 -04:00
Ethan Heilman
d670035b0c
Adds sentence suggested by murchandamus to quantum paragraph
Co-authored-by: Mark "Murch" Erhardt <murch@murch.one>
2024-05-01 16:30:38 -04:00
Ali Sherief
6fc75b1b21
[BIP322] remove empty message requirement for full (proof-of-funds) proofs (#1352)
* add bip-notatether-signedmessage

* minor heading correction

* minor formatting correction

* minor formatting correction

* minor formatting correction

* minor formatting correction

* minor formatting correction

* minor formatting correction

* fix some consistency errors

* Remove empty message for UTXO proofs

* Delete bip-notatether-signedmessage.mediawiki
2024-05-01 06:44:03 -07:00
Ethan Heilman
696cc1713b
Adds post history, fixes created date 2024-04-30 21:13:43 -04:00
MMGen
f1c296bb32 Base58chk-encoded extended keys are always 111 characters long. Amend wording of BIP accordingly.
-This results in a Base58-encoded string of up to 112 characters.
+This results in a Base58-encoded string of exactly 111 characters.

Version bytes: 0x0488b21e (“xpub”), 0x0488ade4 (“xprv”), 0x043587cf (“tpub”), 0x04358394 (“tprv”)

Largest “possible” key:
   kL = 0x0488b21effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff (78 bytes)
   b58chk(kL) = xpubEPi3iGSX9RiyuXPTijevUmMctBDQs2TWCMgUd3qKp6qCgUc8RUsPdPBrRC6whFeWTg37DcmnJJiKFL73DH4sjdApJkXBD3vFcBP4xHq3fPY (111 chars)

Smallest “possible” key:
   kS = 0x043583940000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (78 bytes)
   b58chk(kS) = tprv8ZgxMBicQKsPcsbCVeqqF1KVdH7gwDJbxbzpCxDUsoXHdb6SnTPYxdwSAKDC6KKJzv7khnNWRAJQsRA8BBQyiSfYnRt6zuu4vZQGKjeW4YF (111 chars)
2024-04-30 15:53:17 -06:00
Jon Atack
51b2d131be
Merge pull request #1184 from katesalazar/20210917
BIP 0009: Remove transparent background from figure.
2024-04-30 14:14:58 -07:00
John Bampton
f61885edcf
docs: fix spelling (#1117)
Co-authored-by: Mark "Murch" Erhardt <murch@murch.one>
2024-04-30 16:54:05 -04:00
Varunram Ganesh
2d9e431fbe
[trivial]: Correct spellings across bips (#675)
Co-authored-by: Mark "Murch" Erhardt <murch@murch.one>
2024-04-30 14:51:39 -04:00
Yannick Seurin
2c017b0c0b link to BIP327 2024-04-30 11:42:38 +02:00
Yannick Seurin
f75184b8d8 updating info on multi-, threshold, and blind signatures 2024-04-30 11:34:30 +02:00
Ethan Heilman
3d78cc0886
Fixes typos
Co-authored-by: Mark "Murch" Erhardt <murch@murch.one>
2024-04-29 21:04:15 -04:00
Ethan Heilman
1d5530443d
OP_CAT in Tapscript
Co-authored-by: Vojtěch Strnad <43024885+vostrnad@users.noreply.github.com>
2024-04-29 19:36:26 -04:00
Ethan Heilman
a05543cc58
Changes title of BIP to "Enable OP_CAT in Tapscript" 2024-04-29 18:44:24 -04:00
Jon Atack
8b28941b9c
Merge pull request #1390 from scgbckbone/update_bip129
update bip-0129.mediawiki
2024-04-27 06:39:42 -07:00
Jon Atack
584f4a732b
Merge pull request #1487 from theStack/bip158_remove_data_pushes_definition
bip-0158: remove unused and unrelated "data pushes" definition
2024-04-26 18:26:47 -07:00
Jon Atack
49ec00afae
Merge pull request #1238 from prusnak/bip155-yggdrasil
BIP 155: add Yggdrasil
2024-04-26 15:09:01 -07:00
Jon Atack
b151555daa
Merge pull request #823 from kanzure/bip-112-fix-typo
bip112: fix trivial typo
2024-04-26 14:52:21 -07:00
Jon Atack
998c426e15
Merge pull request #786 from lukechilds/patch-1
[bip38] Consistent hyphenation usage
2024-04-26 14:48:07 -07:00
Mark "Murch" Erhardt
d3576b9ddb
Merge pull request #1537 from sipa/202401_clarify_segwit_direct_push
Clarify exactly which scripts are witness outputs
2024-04-26 17:25:58 -04:00
Mark "Murch" Erhardt
156f066ac6
Merge pull request #1321 from katesalazar/202205132020
BIP 0174: bring back transparent background to figures
2024-04-26 17:22:19 -04:00
Mark "Murch" Erhardt
e641025e74
Merge pull request #1471 from theStack/fix_bip324_test_sage_decoding_git_instrs
bip-0324: fix git instruction order in test_sage_decoding.py
2024-04-26 17:17:46 -04:00
Mark "Murch" Erhardt
fb65481b45
Merge pull request #1507 from RealCocoArdo/master
BIP42: Update spelling of bitcoin
2024-04-26 16:42:53 -04:00
Ethan Heilman
dbc612edfa
Consistent formatting for Section Headings
Co-authored-by: Mark "Murch" Erhardt <murch@murch.one>
2024-04-26 14:02:13 -04:00
Ethan Heilman
5413e18fd9
Consistent formatting for Section Headings
Co-authored-by: Mark "Murch" Erhardt <murch@murch.one>
2024-04-26 14:01:59 -04:00
Ethan Heilman
c10870a390
Adds comma
Co-authored-by: Mark "Murch" Erhardt <murch@murch.one>
2024-04-26 13:59:28 -04:00
Pieter Wuille
50e750a882 Clarify exactly which scripts are witness outputs 2024-04-26 08:26:34 -04:00
Ethan Heilman
852502b9cf
Specifies exact tree signature limit (suggested by Ali Sherief) 2024-04-25 20:32:52 -04:00
Mark "Murch" Erhardt
d402abb797
Merge pull request #1582 from murchandamus/2024-04-reduce-bip173-to-v0
Reduce scope of BIP173 to native segwit v0
2024-04-25 14:21:46 -04:00
Murch
7a10449186
Mention that BIP350 reduces scope of bech32 to v0 2024-04-25 14:15:22 -04:00
Mark "Murch" Erhardt
5552e485bd
Merge pull request #1581 from achow101/stop-link-spam-21
21: Remove other libraries from reference implementations
2024-04-25 13:55:54 -04:00
Ethan Heilman
7ed8f6f38c
Better quantum resistant section based Tim's comments
Adds additional acks
2024-04-25 13:42:24 -04:00
Ethan Heilman
0a3869d102
Fixes comment URI 2024-04-25 13:16:55 -04:00
Ethan Heilman
6c729c4b41 Renamed to use BIP-0347 2024-04-25 13:03:00 -04:00
Jon Atack
d20d1f9e61
Merge pull request #1546 from 5atoshiNakamoto/patch-1
Update bip-0039-wordlists.md
2024-04-25 08:40:09 -07:00
Jon Atack
ee9de3d076
Merge pull request #1576 from achow101/stop-link-spam
39: Remove other implementation sections
2024-04-25 08:03:56 -07:00
Ava Chow
448de3cafd 21: Remove other libraries from reference implementations 2024-04-25 10:23:28 -04:00
Ava Chow
e3f7a26062 85: Remove other implementation sections 2024-04-25 10:19:40 -04:00
Ava Chow
a26656133b 38: Remove dead reference implementation link 2024-04-25 10:17:35 -04:00
Ava Chow
05b626debf 38: Remove other implementation sections 2024-04-25 10:17:31 -04:00
Ava Chow
fd5d424f55 39: Remove other implementation sections 2024-04-25 10:14:29 -04:00
Luke Dashjr
dd88f24eeb Fix README 2024-04-24 23:20:48 +00:00
Ava Chow
eb9007c869 diffchecks.sh: Build table first 2024-04-24 19:14:03 -04:00
Ava Chow
7be25f9fb2 ci: Fetch depth 2 for diffchecks 2024-04-24 19:13:38 -04:00
Bryan Bishop
7bd6c2c500
Merge pull request #596 from luke-jr/editors_typo_fix
BIP 2: Allow editors to fix typos
2024-04-24 13:47:51 -05:00
Jon Atack
e43c18ba40
Merge pull request #1382 from glozow/2022-10-package-relay
BIP 331: Ancestor Package Relay
2024-04-24 11:08:46 -07:00
Mark "Murch" Erhardt
fd8d58edb1
Merge pull request #1068 from OpenBitcoinPrivacyProject/bip47
Finalize BIP-47
2024-04-24 14:05:18 -04:00
glozow
632f143fad specify BIP331 Ancestor Package Relay 2024-04-24 17:03:54 +01:00
Jon Atack
1b87fc5c26
Merge pull request #984 from Enegnei/patch-1
BIP-32: Minor grammar fixes
2024-04-24 08:25:04 -07:00
Jon Atack
9600cefc3c
Merge pull request #746 from riordant/patch-2
BIP47: Missing word
2024-04-24 07:41:14 -07:00
Jon Atack
c60f6b6588
Merge pull request #748 from BankoWallet/patch
Typo of test data in bip 143
2024-04-24 07:29:12 -07:00
Jon Atack
ea6e905d61
Merge pull request #743 from riordant/patch-1
Fix typo in BIP47
2024-04-23 14:42:01 -07:00
Olaoluwa Osuntokun
11ceb96849
Merge pull request #733 from tuxcanfly/bip158-update-tests
bip158: update test vectors
2024-04-23 14:25:47 -07:00
Lucas Cullen
979ee894b8 Fix grammar 2024-04-23 15:18:37 -06:00
Jon Atack
c9d6e2aca2
Merge pull request #679 from nopara73/patch-3
Fix typos in BIP 126
2024-04-23 13:30:46 -07:00
Mark "Murch" Erhardt
0e60da79cf
Merge pull request #1522 from fakefraud/patch-2
BIP-60: typo fix
2024-04-23 16:17:20 -04:00
Mark "Murch" Erhardt
fc67948278
Merge pull request #1575 from murchandamus/2024-04-bip141-fix-typos
Fix typos in BIP141
2024-04-23 16:14:44 -04:00
Jon Atack
3deaeef958
Merge pull request #1486 from wangchun/master
Fix typo in bip-0087.mediawiki
2024-04-23 13:14:36 -07:00
Jon Atack
05072ac3f4
Merge pull request #1505 from GoodDaisy/master
Fix typos
2024-04-23 13:11:15 -07:00
Murch
6ced7dbb5a
Fix typos in BIP141
Co-authored-by: Greg Laun
2024-04-23 15:32:33 -04:00
Mark "Murch" Erhardt
4731fc407f
Merge pull request #487 from Christewart/patch-2
Specify which 1 byte push op codes are valid
2024-04-23 15:25:33 -04:00
Mark "Murch" Erhardt
eb7a787de0
Merge pull request #496 from azuchi/bip143-unify-coin-unit
BIP 143: Unify coin unit
2024-04-23 15:19:53 -04:00
Mark "Murch" Erhardt
f450bee7a4
Merge pull request #1573 from jonatack/2024-04-update-bip-editors
BIP2: update BIP editors
2024-04-23 14:07:23 -04:00
Jon Atack
fa95e34388 BIP2: update BIP editors 2024-04-23 11:45:02 -06:00
Mark "Murch" Erhardt
d06521f432
Merge pull request #1484 from git-sgmoore/master-1
added colon at end of if statement - bip-0119.mediawiki
2024-04-23 13:38:13 -04:00
Olaoluwa Osuntokun
43ce3a461d
Merge pull request #1530 from nau/patch-1
Remove duplicate word in bip-0085.mediawiki
2024-04-22 17:54:16 -07:00
Olaoluwa Osuntokun
749ce1f54e
Merge pull request #1564 from bitjson/patch-1
feat: add TypeScript BIP39 implementation
2024-04-22 17:52:49 -07:00
Mark "Murch" Erhardt
ac062dc76d
Merge pull request #1560 from Christewart/2024-04-01-bip380-fix
Fix Descriptor BIP typos
2024-04-22 17:40:47 -04:00
Mark "Murch" Erhardt
9ad691a1d3
Merge pull request #1558 from prusnak/account-bips
BIP-00{43,49,84}: move to Standards Track + BIP-0044: mark as Final
2024-04-22 16:11:48 -04:00
Jon Atack
57c3d4a0d7
Merge pull request #1554 from bitcoin/gg
Update Bitcoin dev mailing list to Google Groups
2024-04-22 10:11:03 -07:00
Jon Atack
109886ad5e
Merge pull request #1393 from dplusplus1024/patch-2
BIP21: Update Anchor Link
2024-04-22 10:05:58 -07:00
Jon Atack
c66583158b
Merge pull request #1510 from momodaka/bip0380
Update BIP-380: fix typo
2024-04-22 09:38:16 -07:00
Jon Atack
d1cde72f9d
Merge pull request #1549 from siv2r/bip327-fix-link
BIP327: Fix Broken Links
2024-04-22 09:27:25 -07:00
Jon Atack
078b72eefe
Merge pull request #1562 from murchandamus/2024-04-markdown-clarification
Clarify permitted status of markdown
2024-04-22 09:17:53 -07:00
Jon Atack
785077d57b
Merge pull request #1521 from fakefraud/patch-1
BIP-10: typo fix
2024-04-22 09:15:44 -07:00
Jon Atack
b59384d868
Merge pull request #608 from philsmd/patch-1
bip38 typo: specifid -> specified
2024-04-22 09:15:03 -07:00
Jason Dreyzehner
ee0a17ef08
feat: add TypeScript BIP39 implementation 2024-04-15 17:12:02 -04:00
Ethan Heilman
f8ad6ede57
Changes OP_CAT BIP based on feedback given by Bob Summerwill
Bob Summerwill proposed a number of changes to the OP_CAT BIP to better follow BIP-2. This commit makes these changes:

* Using the section order specified in BIP-2
* Adding a Rationale section
* Expand the specification section by moving details from the abstract into the specification

Additionally this commit as rewords some confusing language.

Thanks Bob
2024-04-12 08:48:54 -04:00
Chris Stewart
4a937e1887 Fix typo in BIP384 expected descriptors 2024-04-06 09:26:59 -05:00
Murch
0092a4318f
Clarify permitted status of markdown
Originally BIP-2 disallowed markdown, but markdown formatting was
permitted via #1504.
2024-04-04 16:27:56 -04:00
Chris Stewart
8a9e574414 Fix unsatisfiable test vector in BIP381 2024-04-03 15:00:42 -05:00
Chris Stewart
8795003831 Fix unsatisfiable test vector in BIP382 2024-04-03 10:02:10 -05:00
Chris Stewart
109811e4b9 Fix BIP380 typos 2024-04-01 13:33:48 -05:00
Ethan Heilman
c235aa4939
Adds more acknowledgements 2024-03-26 20:36:19 -04:00
Ethan Heilman
ac231a17c2
Fixes broken mediawiki link 2024-03-20 23:53:53 -04:00
Ethan Heilman
35641a87d7
Merge pull request #3 from 0xBEEFCAF3/cat
Update OP_CAT implementation code
2024-03-20 23:39:53 -04:00
Armin Sabouri
b3493746b1
update OP_CAT implementation 2024-03-20 18:33:02 -04:00
Pavol Rusnak
0278bf3d71
BIP-0044: mark as Final 2024-03-18 23:48:44 +01:00
Pavol Rusnak
5658236e6c
BIP-00{43,49,84}: move to Standards Track 2024-03-18 23:48:22 +01:00
siv2r
ddf5b25fc7 bip327: fix broken links 2024-02-26 17:14:18 +05:30
2014
1818752171
Update bip-0039-wordlists.md
typos, grammar, clarity
2024-01-29 23:45:16 +02:00
Ethan Heilman
2b5ab3b1fd
Merge pull request #2 from 0xBEEFCAF3/patch-1
add clarifying note about the current opcode
2024-01-07 18:36:10 -05:00
Armin Sabouri
5dde7ea5cf
revert changes to abstract 2024-01-07 18:18:46 -05:00
Armin Sabouri
2cec73a5b4
rm comment on disabled CAT opcode 2024-01-07 18:18:09 -05:00
Armin Sabouri
799dc0c96d
Merge branch 'cat' into patch-1 2024-01-07 17:18:59 -05:00
Ethan Heilman
f9e100e9de
Notes that the opcode used is the same as the original cat opcode 2024-01-07 16:34:23 -05:00
Armin Sabouri
ae68ef11cb
add clarifying note about the current opcode
And some grammar + spelling cleanup
2024-01-07 13:24:04 -05:00
Ethan Heilman
82fe9fc3db
specify the hex value of the opcode 2023-12-29 18:29:00 -05:00
Ethan Heilman
e91621efce
Merge pull request #1 from 0xBEEFCAF3/patch-1
Add backwards compatibility section
2023-12-29 12:23:39 -05:00
Armin Sabouri
785b11e861
Add backwards compatibility section 2023-12-29 12:14:45 -05:00
momodaka
3671465ce6 Update BIP-380: fix typo
revert: fix
2023-12-27 09:38:41 +08:00
Ethan Heilman
e492a90fec
Better reference for OP_CAT removal 2023-12-18 20:28:22 -05:00
Ethan Heilman
e3dc3ba361
Italicize variables
Co-authored-by: Vojtěch Strnad <43024885+vostrnad@users.noreply.github.com>
2023-12-17 12:53:07 -05:00
Ethan Heilman
97635f5c09
Lowercase the signatures 2023-12-17 12:49:46 -05:00
Ethan Heilman
4f39e4b9d5
Avoids designing or discussing how to add post-quantum commitments to Bitcoin 2023-12-16 16:23:49 -05:00
Ethan Heilman
77509f6c23
Period to colon
Co-authored-by: Vojtěch Strnad <43024885+vostrnad@users.noreply.github.com>
2023-12-15 15:57:08 -05:00
Ethan Heilman
0b8a7e4b64
Code formatting
Co-authored-by: Vojtěch Strnad <43024885+vostrnad@users.noreply.github.com>
2023-12-15 15:56:12 -05:00
Ethan Heilman
82198302cd
Code formatting
Co-authored-by: Vojtěch Strnad <43024885+vostrnad@users.noreply.github.com>
2023-12-15 15:52:05 -05:00
Ethan Heilman
0a143d3969
Use BSD-3 license 2023-12-15 15:46:49 -05:00
Ethan Heilman
beb5802cc6
Adds subsection header
Co-authored-by: Vojtěch Strnad <43024885+vostrnad@users.noreply.github.com>
2023-12-15 15:27:22 -05:00
Ethan Heilman
d4f85b1146
Lowercase bytes
Co-authored-by: Vojtěch Strnad <43024885+vostrnad@users.noreply.github.com>
2023-12-15 14:44:07 -05:00
Ethan Heilman
6f5a74d83e
Increases conciseness and clarity
Co-authored-by: Vojtěch Strnad <43024885+vostrnad@users.noreply.github.com>
2023-12-15 10:04:36 -05:00
Ethan Heilman
7180c1cf8c
Prefer bytes to Bytes
Co-authored-by: Vojtěch Strnad <43024885+vostrnad@users.noreply.github.com>
2023-12-15 09:54:50 -05:00
Alexander Nemish
b434f1813c
Update bip-0085.mediawiki
Fix doublicated word
2023-12-15 11:00:10 +01:00
Ethan Heilman
945e2a3742
Typos
TIL that it is "a one" rather than "an one"

Co-authored-by: kallewoof <kalle.alm@gmail.com>
2023-12-14 23:48:46 -05:00
Ethan Heilman
01db3acab0
Removes space in ref
Co-authored-by: kallewoof <kalle.alm@gmail.com>
2023-12-14 23:47:58 -05:00
Ethan Heilman
6a790ec526
Removes space in ref
Co-authored-by: kallewoof <kalle.alm@gmail.com>
2023-12-14 23:47:50 -05:00
Ethan Heilman
a2b0100671
Typo
Co-authored-by: kallewoof <kalle.alm@gmail.com>
2023-12-14 23:47:36 -05:00
Ethan Heilman
848352f408
Phrasing
Co-authored-by: kallewoof <kalle.alm@gmail.com>
2023-12-14 23:45:04 -05:00
Ethan Heilman
c5d66d6706
Better phrasing
Co-authored-by: kallewoof <kalle.alm@gmail.com>
2023-12-14 23:44:44 -05:00
Ethan Heilman
9779dc9920
Keeps past tense consistant
Co-authored-by: kallewoof <kalle.alm@gmail.com>
2023-12-14 23:44:14 -05:00
Ethan Heilman
bb725e6523
Wording
Co-authored-by: kallewoof <kalle.alm@gmail.com>
2023-12-14 23:43:42 -05:00
Ethan Heilman
3d31e5c894
Adds brackets
Co-authored-by: kallewoof <kalle.alm@gmail.com>
2023-12-12 08:59:03 -05:00
Ethan Heilman
0335c9d188
Grammar fix
Co-authored-by: kallewoof <kalle.alm@gmail.com>
2023-12-12 08:27:35 -05:00
Ethan Heilman
26e8e5f7fc
Better fits bitcoin style guide
"If an if only has a single-statement then-clause, it can appear on the same line as the if, without braces. In every other case, braces are required, and the then and else clauses must appear correctly indented on a new line."

Co-authored-by: kallewoof <kalle.alm@gmail.com>
2023-12-12 08:26:36 -05:00
Ethan Heilman
f1169dd1fc
Fixes typo
Co-authored-by: kallewoof <kalle.alm@gmail.com>
2023-12-12 08:24:39 -05:00
Ethan Heilman
83ca57f222
Create bip-???-cat.mediawiki 2023-12-11 18:11:22 -05:00
Vehorny
682fd8bc58
Update bip-0060.mediawiki 2023-12-07 02:13:58 +01:00
Vehorny
3732ac478b
Update bip-0010.mediawiki 2023-12-07 02:12:27 +01:00
Coco_Ardo
44794188ec
Update bip-0042.mediawiki spelling
Bitcoin the network is written with a capital B. The unit is writting with small b.
2023-10-20 20:51:06 +02:00
GoodDaisy
6fd7de46b7 Fix typos 2023-10-13 09:05:19 +08:00
Sebastian Falbesoner
496b6c9ecc bip-0158: remove unused and unrelated "data pushes" definition
This BIP is not in any way connected to the rules of Bitcoin script,
i.e. the "data pushes" term is also not used anywhere and its definition
can hence be removed.
2023-08-29 23:39:04 +02:00
Chun
91bbe3307c
Update bip-0087.mediawiki
typo fix
2023-08-20 07:59:19 +00:00
sgmoore
2f1e2bc4d8
added colon at end of if statement - bip-0119.mediawiki
Python requires a colon at the end of an if statement to denote the beginning of the block of code that will be executed if the condition is True. If the colon is omitted, a syntax error will occur, and the code will not run. Since the syntax error will prevent the code from running, it won't introduce any vulnerabilities by itself. However, it will cause the application to fail at the point where the code is parsed, which might expose other issues if error handling is not implemented properly.
2023-08-15 12:54:34 -07:00
Sebastian Falbesoner
9f25645be5 bip-0324: fix git instruction order in test_sage_decoding.py
Tiny fix correcting the order of commands, for `git checkout` one has
to change into the repository directory first.
2023-07-06 16:38:38 +02:00
Thebora Kompanioni
265d64cae5
fix(bip85): rectify pwd_length in PWD BASE85 table 2023-06-30 10:19:55 +02:00
John Moffett
fa4eeeef38
Fix description of M parameter
The M parameter is used as the inverse of the false probability rate, so change its incorrect usage in two places.
2023-01-31 13:12:53 -05:00
D++
3e10085c09
Update Anchor Link
Fixed the link to the #simpler-syntax portion of the BIP.
2022-12-18 21:49:26 -06:00
scgbckbone
9df0b19c24
update bip-0129.mediawiki 2022-11-22 01:47:46 +01:00
chris-belcher
bf2eb4f680 Specify BIP-fidelity-bonds
For storing fidelity bonds in HD wallets
2022-07-04 20:10:21 +01:00
katesalazar
3248581928 Bring back transparent background to figures
Black arrows are visible only in light theme (unless white background
for dark theme). Two-color arrows are visible in light theme and in
dark theme.
2022-05-22 10:38:46 +02:00
Pavol Rusnak
4fb3cf55eb
BIP 155: add Yggdrasil 2021-11-18 23:55:55 +01:00
katesalazar
497ad1c81a Remove transparent background from figure.
Before this change, the figure presented black text on transparent
background, which might be unconvenient when using a browser able to
pass a dark theme preference to some environments where this document
is published, currently notably GitHub. A white background could help
a better visualization compromise. White background on the figure is
the single purpose of this revision.

This PNG was compiled using:

    dot -Tpng states.gv -o states.png
2021-11-16 10:00:09 +01:00
Justus Ranvier
bc069fa050 Finalize BIP-47 2021-02-15 06:22:42 -09:00
Justus Ranvier
5ec9df085e BIP-0047: Adjust text to match test vectors
The original implementation of BIP-47 in Samourai Wallet reversed
the parameters in the calculation of the HMAC-SHA512 step of
notification transaction blinding.

This change adjusts the text to match the as-implementend behavior
in deployed BIP-47 wallets and the test vectors.
2021-02-15 06:09:04 -09:00
Enegnei
688b0dabab
A few more minor grammar fixes / improvements 2020-08-30 22:41:52 +02:00
Enegnei
a0481edf92
Minor grammar fix 2020-08-30 22:01:46 +02:00
Bryan Bishop
62c759eae6
bip112: fix trivial typo 2019-08-03 13:55:29 -05:00
Janus
3b6a92973e Reject BIP-0060 (three years inactivity) 2019-06-20 16:04:19 -05:00
Luke Childs
c7cc17f14e
[bip38] Consistent hyphenation usage 2019-06-07 14:26:45 +07:00
Javed Khan
9b03604c5b
bip158: update test vectors 2019-02-13 16:18:49 +05:30
Chm
e5c708b3e7
Typo of test data in bip 143
Transaction signature got sigHashType byte missing in decomposed block.
2018-12-22 23:50:26 +08:00
tadhg
a66d1852a2
Missing word 2018-12-07 01:25:19 +01:00
tadhg
1dcb4eef30
Fix typo in BIP47 2018-11-30 18:37:42 +01:00
nopara73
9d879aaf5c
Fix typos 2018-05-12 21:51:18 +07:00
philsmd
b84deb2adf
bip38 typo: specifid -> specified
There was a small typo in the bip38 specification. If I'm not totally mistaken the word should be "specified" (not specifid)
Thx
2017-11-07 22:19:47 +01:00
Luke Dashjr
ce5d831516 BIP 2: Allow editors to fix typos 2017-09-27 18:50:05 +00:00
azuchi
b2b24b5393 BIP 143: Unify coin unit 2017-02-19 16:19:17 +09:00
Chris Stewart
608d5dc95f Update bip-0141.mediawiki
Clarifying rewording, `OP_0` is not a 1 byte push op code since it pushes the empty byte vector onto the stack.
2017-01-03 17:46:14 -06:00
Chris Stewart
d84186c01c Specify which 1 byte push op codes are valid
This adds documentation to BIP141 about which 1 byte push op codes are valid for segwit. This is needed because `OP_1NEGATE` is a 1 byte push op code, but is NOT a valid 1 byte push op code for segwit. See the implementation here for why `OP_1NEGATE` is not valid: 14d01309be/src/script/script.cpp (L228)
2017-01-03 17:07:37 -06:00
424 changed files with 54696 additions and 4011 deletions

View File

@ -5,15 +5,27 @@ jobs:
Link-Format-Checks:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v5
- run: scripts/link-format-chk.sh
Build-Table-Checks:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v5
- run: scripts/buildtable.pl >/tmp/table.mediawiki || exit 1
Diff-Checks:
name: "Diff Checks (fails until number assignment)"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v5
with:
fetch-depth: 2
- run: scripts/diffcheck.sh
Typo-Checks:
name: "Typo Checks"
runs-on: ubuntu-latest
steps:
- name: Checkout Actions Repository
uses: actions/checkout@v5
- name: Check spelling
uses: crate-ci/typos@master

6
.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
bip-0174/coinjoin-workflow.aux
bip-0174/coinjoin-workflow.log
bip-0174/coinjoin-workflow.pdf
bip-0174/multisig-workflow.aux
bip-0174/multisig-workflow.log
bip-0174/multisig-workflow.pdf

44
.typos.toml Normal file
View File

@ -0,0 +1,44 @@
[default]
extend-ignore-re = [
# NOTE: use here for regex patterns
"xpub.*",
"xprv.*",
"3.*", # address
"5.*", # address
"private_key .*",
"privkey .*",
"tt.*", # <tt> tags
"code.*", # <code> tags
"\\w*<sub>", # prefix for <sub> tags
"OP_SUCCESSx|\\d+",
"pay.*",
"ser.*",
"prefix.*",
"value: .*",
"pqNTRUsign",
"Strnad",
]
[default.extend-words]
# NOTE: use here for false-positives
anc = "anc"
PSBT = "PSBT"
ser = "ser"
# Names
Atack = "Atack"
Falke = "Falke"
Meni = "Meni"
Ono = "Ono"
Toom = "Toom"
[files]
extend-exclude = [
"/*/*.csv",
"/*/*.d*",
"/*/*.go",
"/*/*.json",
"/*/*/*.json",
"/*/*/*/*/*/*.o",
"/*/*/*/*/*/*/*/*.o",
"/*/*.t*",
]

12
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,12 @@
# Contributing Guidelines
## Typos
Among other tasks, the CI verifies that changes do not contain common typos.
This check is done using [`typos`](https://github.com/crate-ci/typos).
To run this task locally, install [`typos`](https://github.com/crate-ci/typos)
and then run in the root directory:
```bash
typos
```

File diff suppressed because it is too large Load Diff

View File

@ -1,13 +1,11 @@
<pre>
BIP: 1
Title: BIP Purpose and Guidelines
Author: Amir Taaki <genjix@riseup.net>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0001
Status: Replaced
Authors: Amir Taaki <genjix@riseup.net>
Status: Closed
Type: Process
Created: 2011-09-19
Superseded-By: 2
Assigned: 2011-09-19
Proposed-Replacement: 2
</pre>
==What is a BIP?==
@ -23,7 +21,7 @@ Because the BIPs are maintained as text files in a versioned repository, their r
There are three kinds of BIP:
* A Standards Track BIP describes any change that affects most or all Bitcoin implementations, such as a change to the network protocol, a change in block or transaction validity rules, or any change or addition that affects the interoperability of applications using Bitcoin.
* An Informational BIP describes a Bitcoin design issue, or provides general guidelines or information to the Bitcoin community, but does not propose a new feature. Informational BIPs do not necessarily represent a Bitcoin community consensus or recommendation, so users and implementors are free to ignore Informational BIPs or follow their advice.
* An Informational BIP describes a Bitcoin design issue, or provides general guidelines or information to the Bitcoin community, but does not propose a new feature. Informational BIPs do not necessarily represent a Bitcoin community consensus or recommendation, so users and implementers are free to ignore Informational BIPs or follow their advice.
* A Process BIP describes a process surrounding Bitcoin, or proposes a change to (or an event in) a process. Process BIPs are like Standards Track BIPs but apply to areas other than the Bitcoin protocol itself. They may propose an implementation, but not to Bitcoin's codebase; they often require community consensus; unlike Informational BIPs, they are more than recommendations, and users are typically not free to ignore them. Examples include procedures, guidelines, changes to the decision-making process, and changes to the tools or environment used in Bitcoin development. Any meta-BIP is also considered a Process BIP.
==BIP Work Flow==
@ -38,7 +36,7 @@ BIP authors are responsible for collecting community feedback on both the initia
It is highly recommended that a single BIP contain a single key proposal or new idea. The more focused the BIP, the more successful it tends to be. If in doubt, split your BIP into several well-focused ones.
The BIP editors assign BIP numbers and change their status. Please send all BIP-related email to the BIP editor, which is listed under [[#BIP_Editors|BIP Editors]] below. Also see [[#BIP_Editor_Responsibilities__Workflow|BIP Editor Responsibilities & Workflow]]. The BIP editor reserves the right to reject BIP proposals if they appear too unfocused or too broad.
The BIP editors assign BIP numbers and change their status. Please send all BIP-related email to the BIP editor, which is listed under [[#bip-editors|BIP Editors]] below. Also see [[#bip-editor-responsibilities--workflow|BIP Editor Responsibilities & Workflow]]. The BIP editor reserves the right to reject BIP proposals if they appear too unfocused or too broad.
Authors MUST NOT self assign BIP numbers, but should use an alias such as "bip-johndoe-infinitebitcoins" which includes the author's name/nick and the BIP subject.
@ -179,6 +177,9 @@ This document was derived heavily from Python's PEP-0001. In many places text wa
==Changelog==
10 Oct 2015 - Added clarifications about submission process and BIP number assignment.
01 Jan 2016 - Clarified early stages of BIP idea championing, collecting community feedback, etc.
* 2016-12-14:
** Closed: [https://github.com/bitcoin/bips/pull/478 Superseded by BIP2]
* 2016-01-01:
** Clarified early stages of BIP idea championing, collecting community feedback, etc.
* 2015-10-10:
** Added clarifications about submission process and BIP number assignment.

View File

@ -1,15 +1,13 @@
<pre>
BIP: 2
Title: BIP process, revised
Author: Luke Dashjr <luke+bip@dashjr.org>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0002
Status: Active
Authors: Luke Dashjr <luke+bip@dashjr.org>
Status: Closed
Type: Process
Created: 2016-02-03
License: BSD-2-Clause
OPL
Assigned: 2016-02-03
License: BSD-2-Clause OR OPUBL-1.0
Replaces: 1
Proposed-Replacement: 3
</pre>
==Abstract==
@ -67,8 +65,12 @@ If you are interested in assuming ownership of a BIP, send a message asking to t
The current BIP editors are:
* Bryan Bishop ([[mailto:kanzure@gmail.com|kanzure@gmail.com]])
* Jon Atack ([[mailto:jon@atack.com|jon@atack.com]])
* Luke Dashjr ([[mailto:luke_bipeditor@dashjr.org|luke_bipeditor@dashjr.org]])
* Kalle Alm ([[mailto:karljohan-alm@garage.co.jp|karljohan-alm@garage.co.jp]])
* Mark "Murch" Erhardt ([[mailto:murch@murch.one|murch@murch.one]])
* Olaoluwa Osuntokun ([[mailto:laolu32@gmail.com|laolu32@gmail.com]])
* Ruben Somsen ([[mailto:rsomsen@gmail.com|rsomsen@gmail.com]])
===BIP Editor Responsibilities & Workflow===
@ -98,6 +100,8 @@ The BIP editor will:
The BIP editors are intended to fulfill administrative and editorial responsibilities. The BIP editors monitor BIP changes, and update BIP headers as appropriate.
BIP editors may also, at their option, unilaterally make and merge strictly-editorial changes to BIPs, such as correcting misspellings, fixing broken links, etc.
==BIP format and structure==
===Specification===
@ -106,11 +110,11 @@ BIPs should be written in mediawiki or markdown format.
Each BIP should have the following parts:
* Preamble -- Headers containing metadata about the BIP ([[#BIP header preamble|see below]]).
* Preamble -- Headers containing metadata about the BIP ([[#bip-header-preamble|see below]]).
* Abstract -- A short (~200 word) description of the technical issue being addressed.
* Copyright -- The BIP must be explicitly licensed under acceptable copyright terms ([[#BIP licensing|see below]]).
* Copyright -- The BIP must be explicitly licensed under acceptable copyright terms ([[#bip-licensing|see below]]).
* Specification -- The technical specification should describe the syntax and semantics of any new feature. The specification should be detailed enough to allow competing, interoperable implementations for any of the current Bitcoin platforms.
@ -177,7 +181,7 @@ BIPs may include auxiliary files such as diagrams. Auxiliary files should be inc
There are three kinds of BIP:
* A Standards Track BIP describes any change that affects most or all Bitcoin implementations, such as a change to the network protocol, a change in block or transaction validity rules, or any change or addition that affects the interoperability of applications using Bitcoin. Standards Track BIPs consist of two parts, a design document and a reference implementation.
* An Informational BIP describes a Bitcoin design issue, or provides general guidelines or information to the Bitcoin community, but does not propose a new feature. Informational BIPs do not necessarily represent a Bitcoin community consensus or recommendation, so users and implementors are free to ignore Informational BIPs or follow their advice.
* An Informational BIP describes a Bitcoin design issue, or provides general guidelines or information to the Bitcoin community, but does not propose a new feature. Informational BIPs do not necessarily represent a Bitcoin community consensus or recommendation, so users and implementers are free to ignore Informational BIPs or follow their advice.
* A Process BIP describes a process surrounding Bitcoin, or proposes a change to (or an event in) a process. Process BIPs are like Standards Track BIPs but apply to areas other than the Bitcoin protocol itself. They may propose an implementation, but not to Bitcoin's codebase; they often require community consensus; unlike Informational BIPs, they are more than recommendations, and users are typically not free to ignore them. Examples include procedures, guidelines, changes to the decision-making process, and changes to the tools or environment used in Bitcoin development. Any meta-BIP is also considered a Process BIP.
==BIP status field==
@ -353,40 +357,40 @@ In this case, only the acceptable license(s) should be listed in the License and
====Recommended licenses====
* BSD-2-Clause: [https://opensource.org/licenses/BSD-2-Clause OSI-approved BSD 2-clause license]
* BSD-3-Clause: [https://opensource.org/licenses/BSD-3-Clause OSI-approved BSD 3-clause license]
* BSD-2-Clause: [https://opensource.org/license/BSD-2-Clause OSI-approved BSD 2-clause license]
* BSD-3-Clause: [https://opensource.org/license/BSD-3-Clause OSI-approved BSD 3-clause license]
* CC0-1.0: [https://creativecommons.org/publicdomain/zero/1.0/ Creative Commons CC0 1.0 Universal]
* GNU-All-Permissive: [http://www.gnu.org/prep/maintain/html_node/License-Notices-for-Other-Files.html GNU All-Permissive License]
* FSFAP: [https://www.gnu.org/prep/maintain/html_node/License-Notices-for-Other-Files.html FSF All Permissive License]
In addition, it is recommended that literal code included in the BIP be dual-licensed under the same license terms as the project it modifies. For example, literal code intended for Bitcoin Core would ideally be dual-licensed under the MIT license terms as well as one of the above with the rest of the BIP text.
====Not recommended, but acceptable licenses====
* Apache-2.0: [http://www.apache.org/licenses/LICENSE-2.0 Apache License, version 2.0]
* BSL-1.0: [http://www.boost.org/LICENSE_1_0.txt Boost Software License, version 1.0]
* Apache-2.0: [https://www.apache.org/licenses/LICENSE-2.0 Apache License, version 2.0]
* BSL-1.0: [https://www.boost.org/LICENSE_1_0.txt Boost Software License, version 1.0]
* CC-BY-4.0: [https://creativecommons.org/licenses/by/4.0/ Creative Commons Attribution 4.0 International]
* CC-BY-SA-4.0: [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Attribution-ShareAlike 4.0 International]
* MIT: [https://opensource.org/licenses/MIT Expat/MIT/X11 license]
* AGPL-3.0+: [http://www.gnu.org/licenses/agpl-3.0.en.html GNU Affero General Public License (AGPL), version 3 or newer]
* FDL-1.3: [http://www.gnu.org/licenses/fdl-1.3.en.html GNU Free Documentation License, version 1.3]
* GPL-2.0+: [http://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html GNU General Public License (GPL), version 2 or newer]
* LGPL-2.1+: [http://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html GNU Lesser General Public License (LGPL), version 2.1 or newer]
* MIT: [https://opensource.org/license/MIT The MIT License]
* AGPL-3.0+: [https://www.gnu.org/licenses/agpl-3.0.en.html GNU Affero General Public License (AGPL), version 3 or newer]
* FDL-1.3: [https://www.gnu.org/licenses/fdl-1.3.en.html GNU Free Documentation License, version 1.3]
* GPL-2.0+: [https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html GNU General Public License (GPL), version 2 or newer]
* LGPL-2.1+: [https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html GNU Lesser General Public License (LGPL), version 2.1 or newer]
====Not acceptable licenses====
All licenses not explicitly included in the above lists are not acceptable terms for a Bitcoin Improvement Proposal unless a later BIP extends this one to add them.
However, BIPs predating the acceptance of this BIP were allowed under other terms, and should use these abbreviation when no other license is granted:
* OPL: [http://opencontent.org/openpub/ Open Publication License, version 1.0]
* OPUBL-1.0: [https://opencontent.org/openpub/ Open Publication License, version 1.0]
* PD: Released into the public domain
===Rationale===
BIP 1 allowed the Open Publication License or releasing into the public domain; was this insufficient?
* The OPL is generally regarded as obsolete, and not a license suitable for new publications.
* Many are unfamiliar with the OPL terms, and may just prefer to use the public domain rather than license under uncertain terms.
* The OPL license terms allowed for the author to prevent publication and derived works, which was widely considered inappropriate for Bitcoin standards.
* The OPUBL-1.0 is generally regarded as obsolete, and not a license suitable for new publications.
* Many are unfamiliar with the OPUBL-1.0 terms, and may just prefer to use the public domain rather than license under uncertain terms.
* The OPUBL-1.0 license terms allowed for the author to prevent publication and derived works, which was widely considered inappropriate for Bitcoin standards.
* Public domain is not universally recognised as a legitimate action, thus it is inadvisable.
Why are there software licenses included?
@ -409,7 +413,6 @@ Why is Public Domain no longer acceptable for new BIPs?
* Non-image auxiliary files are permitted in the bip-XXXX subdirectory.
* Email addresses are now required for authors.
* The Post-History header may be provided as a link instead of a simple date.
* Markdown format is no longer permitted for BIPs.
* The Resolution header has been dropped, as it is not applicable to a decentralised system where no authority exists to make final decisions.
==See Also==

802
bip-0003.md Normal file
View File

@ -0,0 +1,802 @@
```
BIP: 3
Title: Updated BIP Process
Authors: Murch <murch@murch.one>
Status: Deployed
Type: Process
Assigned: 2025-01-09
License: BSD-2-Clause
Discussion: https://github.com/murchandamus/bips/pull/2
https://gnusha.org/pi/bitcoindev/59fa94cea6f70e02b1ce0da07ae230670730171c.camel@timruffing.de/#t
Version: 1.4.0
Requires: 123
Replaces: 2
```
## Abstract
This _Bitcoin Improvement Proposal (BIP)_ provides information about the preparation of BIPs and policies relating to
the publication of BIPs. It replaces [BIP2](bip-0002.mediawiki) with a streamlined process, and may be amended to
address the evolving needs of the BIP process.
## Motivation
BIP2 was written in 2016.
This BIP revisits aspects of the BIP2 process
that did not achieve broad adoption, reduces the judgment calls assigned to the BIP Editor role, delineates the
BIPtypes more clearly, and generalizes the BIP process to fit the communitys use of the repository.
## Fundamentals
### What is a BIP?
BIPs are improvement proposals for Bitcoin. The main topic is information and technologies that support and expand the utility of the Bitcoin
currency. Most BIPs provide a concise, self-contained, technical description of one new concept, feature, or standard.
Some BIPs describe processes, implementation guidelines, best practices, incident reports (e.g.,
[BIP50](bip-0050.mediawiki)), or other information relevant to the Bitcoin community. However, any topics related to
the Bitcoin protocol, peer-to-peer network, and client software may be acceptable.
BIPs are intended to be a means for proposing new protocol features, coordinating client standards, and
documenting design decisions that have gone into implementations. BIPs may be submitted by anyone, provided the
content is of high quality, e.g., does not waste the communitys time.
The scope of the BIPs
repository is limited to BIPs that do not oppose the fundamental principle that Bitcoin constitutes a peer-to-peer
electronic cash system for the Bitcoin currency.
### BIP Ownership
Each BIP is primarily owned by its authors and represents the authors opinion or recommendation. The authors are
expected to foster discussion, address feedback and dissenting opinions, and, if applicable, advance the adoption of
their proposal within the Bitcoin community. As a BIP progresses through the workflow, it becomes increasingly
co-owned by the Bitcoin community.
#### Authors and Deputies
Authors may want additional help with the BIP process after writing an initial draft. In that case, they may assign
one or more Deputies to their BIP. Deputies are stand-in owners of a BIP who were not involved in writing the
document. They support the authors in advancing the proposal, or act as a point of contact for the BIP in the absence of the
authors. Deputies may perform the role of Authors for any aspect of the BIP process unless overruled by an Author.
Deputies share ownership of the BIP at the discretion of the Authors.
### What is the Significance of BIPs?
BIPs do not define what Bitcoin is: individual BIPs do not represent Bitcoin community consensus or a general
recommendation for implementation. A BIP represents a personal recommendation by the BIP authors to the Bitcoin
community. Some BIPs may never be adopted. Some BIPs may be adopted by one or more Bitcoin clients or other related
software. Some may even end up changing the consensus rules that the Bitcoin ecosystem jointly enforces.
### What is the Purpose of the BIPs Repository?
The [BIPs repository](https://github.com/bitcoin/bips/) serves as a publication medium and archive for mature proposals.
Through its high visibility, it facilitates the community-wide consideration of BIPs and provides a well-established
source to retrieve the latest version of any BIP. The repository transparently records all changes to each BIP and
allows any community member to retain a complete copy of the archive easily.
The BIPs repository neither tracks community sentiment[^acceptance] nor ecosystem adoption[^adoption] of BIPs beyond
the brief overview provided via the BIP status (see [Workflow](#workflow) below).
Proposals are published in this repository if they are on-topic and fulfill the editorial criteria.
No formal or informal decision body governs Bitcoin development or decides adoption of BIPs.
## BIP Format and Structure
### Specification
Authors may choose to submit BIPs in MediaWiki or Markdown[^markdown] format.
Each BIP must have a _Preamble_, an _Abstract_, a _Copyright_, and a _Motivation_ section. Authors should consider all issues in the
following list and address each as appropriate.
* Preamble — Headers containing metadata about the BIP (see the section [BIP Header Preamble](#bip-header-preamble)
below).
* Abstract — A short description of the issue being addressed.
* Motivation — Why is this BIP being written? Clearly explain how the existing situation presents a problem and why the proposed idea resolves the
issue or improves upon the current situation.
* Specification — The technical specification should describe the syntax and semantics of any new feature. The
specification should be detailed enough to enable any Bitcoin project to create an interoperable implementation.
* Rationale — The rationale fleshes out the specification by describing what inspired the design and why particular
design decisions were made. It should describe related work and alternate designs that were considered. The rationale
should record relevant objections or important concerns that were raised and addressed as this proposal was developed.
* Backward Compatibility — Any BIP that introduces incompatibilities must include a section describing these incompatibilities and their severity as well as provide instructions on how
implementers and users should deal with these incompatibilities.
* Reference Implementation — Where applicable, a reference implementation, test vectors, and documentation must be
finished before the BIP can be given the status "Complete". Test vectors must be provided in the BIP or
as auxiliary files (see [Auxiliary Files](#auxiliary-files)) under an acceptable license. The reference implementation
can be provided in the BIP, as an auxiliary file, or per linking another code reference that is expected to remain
available permanently such as a pull request, a dedicated branch, a new repository, or similar.
* Changelog — A section to track modifications to a BIP after reaching Complete status.
* Copyright — The BIP must be placed under an acceptable license (see [BIP Licensing](#bip-licensing) below).
#### BIP Header Preamble
Each BIP must begin with an [RFC 822-style header preamble](https://www.w3.org/Protocols/rfc822/). The headers must
appear in the following order. Headers marked with "\*" are optional. All other headers are required.
##### Overview
```
BIP: <BIP number, or "?" before assignment>
* Layer: <Consensus (soft fork) | Consensus (hard fork) | Peer Services | API/RPC | Applications>
Title: <BIP title (50 characters)>
Authors: <Authors names and email addresses>
* Deputies: <Deputies names and email addresses>
Status: <Draft | Complete | Deployed | Closed>
Type: <Specification | Informational | Process>
Assigned: <Date of number assignment (yyyy-mm-dd), or "?" before assignment>
License: <SPDX License Expression>
* Discussion: <Noteworthy discussion threads in "yyyy-mm-dd: URL" format>
* Version: <MAJOR.MINOR.PATCH>
* Requires: <BIP number(s)>
* Replaces: <BIP number(s)>
* Proposed-Replacement: <BIP number(s)>
```
##### Header Descriptions
* BIP — The assigned number of the BIP (without leading zeros). Please use "?" before a number has been assigned by the BIP Editors.
* Layer — The layer of Bitcoin the BIP applies to using the BIP classification defined in [BIP123](bip-0123.mediawiki).
* Authors — The names (or pseudonyms) and email addresses of all authors of the BIP. The format of each authors header
value must be
Random J. User <address@dom.ain>
Multiple authors are recorded on separate lines:
Authors: Random J. User <address@dom.ain>
Anata Sample <anata@domain.example>
* Deputies — Additional owners of the BIP that are not authors. The Deputies header uses the same format as the
Authors header. See the [BIP Ownership](#bip-ownership) section above.
* Status — The stage of the workflow of the proposal. See the [Workflow](#workflow) section below.
* Type — See the [BIP Types](#bip-types) section below for a description of the three BIP types.
* Assigned The date a BIP was assigned its number. Please use "?" before a number has been assigned by the BIP Editors.
* License — The License header specifies SPDX License Expressions describing the terms under which the
BIP and its auxiliary files are available. See the [BIP Licensing](#bip-licensing) section below.
* Discussion — The Discussion header points the audience to relevant discussions of the BIP, e.g., the mailing list
thread in which the idea for the BIP was discussed, a thread where a new version of the BIP was presented, or relevant
discussion threads on other platforms. Entries take the format "yyyy-mm-dd: URL", e.g., `2009-01-09:
https://www.mail-archive.com/cryptography@metzdowd.com/msg10142.html`, using the date and URL of the start of the
conversation. Multiple discussions should be listed on separate lines.
* Version — The current version number of this BIP. See the [Changelog](#changelog-section-and-version-header) section below.
* Requires — A list of existing BIPs the new proposal depends on. If multiple BIPs
are required, they should be listed in one line separated by a comma and space (e.g., "1, 2").
* Replaces[^proposes-to-replace] — BIP authors may put the numbers of one or more prior BIPs in the Replaces header to recommend that their
BIP succeeds, supersedes, or renders obsolete those prior BIPs.
* Proposed-Replacement[^superseded-by-proposed-replacement] — When a later BIP indicates that it intends to supersede an
existing BIP, the later BIPs number is added to the Proposed-Replacement header of the existing BIP to indicate the
potential successor BIP.
#### Auxiliary Files
BIPs may include auxiliary files such as diagrams and source code. Auxiliary files must be included in a subdirectory
for that BIP named `bip-XXXX`, where "XXXX" is the BIP number zero-padded to four digits. File names in the subdirectory
do not need to adhere to a specific convention.
### BIP Types
* A **Specification BIP** defines a set of technical rules describing a new feature or affecting the interoperability of implementations. The
distinguishing characteristic of a Specification BIP is that it can be implemented, and implementations can be compliant with
it. Specification BIPs must have a Specification section, must have a Backward Compatibility section (if incompatibilities are introduced), and can only be advanced to Complete after they contain or refer to a reference implementation and test vectors.
* An **Informational BIP** describes a Bitcoin design issue, or provides general guidelines or other information to the
Bitcoin community.
* A **Process BIP** describes a process surrounding Bitcoin, or proposes a change to (or an event in) a process. Process
BIPs are like Specification BIPs, but apply to topics other than the Bitcoin protocol and Bitcoin implementations.
They often require community consensus and are typically binding for the corresponding process. Examples include
procedures, guidelines, and changes to decision-making processes such as the BIP process.
## Workflow
The BIP process starts with a new idea for Bitcoin. Each potential BIP must have authors—people who write the BIP,
gather feedback, shepherd the discussion in the appropriate forums, and finally recommend a mature proposal to the
community.
![Status Diagram](bip-0003/status-diagram.png "Status Diagram for the BIP Workflow")
### Ideation
After having an idea, the authors should evaluate whether it meets the criteria to become a BIP, as described in this
BIP. The idea must be of interest to the broader community or relevant to multiple software projects. Minor improvements
and matters concerning only a single project usually do not require standardization and should instead be brought up directly to
the relevant project.
The authors should first research whether their idea has been considered before. Ideas in Bitcoin are often rediscovered,
and prior related discussions may inform the authors of the issues that may arise in its progression. After some investigation,
the novelty and viability of the idea should be tested by posting a new, dedicated thread about the idea to the [Bitcoin Development Mailing
List](https://groups.google.com/g/bitcoindev). Prior correspondence can be found in the [mailing list
archive](https://gnusha.org/pi/bitcoindev/).
It is recommended that authors establish before or at the start of working on a draft whether their idea may be of
interest to the Bitcoin community.
Authors should avoid opening a pull request with a BIP draft out of the blue.
Vetting an idea publicly before investing time and effort to formally describe the idea is meant to save time for both the authors and
the community. Not only may someone point out relevant discussion topics that were missed in the authors
research, or that an idea is guaranteed to be rejected based on prior discussions, but describing an idea publicly also
tests whether it is of interest to more people beside the authors.
As a first sketch of the proposal is taking shape, the authors should present it to the [Bitcoin Development Mailing
List](https://groups.google.com/g/bitcoindev). This gives the authors a chance to collect initial feedback and address
fundamental concerns. If the authors wish to work in public on the proposal at this stage, it is recommended that they
open a pull request against one of their forks of the BIPs repository instead of the main BIPs repository.
It is recommended that complicated proposals be split into separate BIPs that each focus on a specific component of the
overall proposal.
### Progression through BIP Statuses
The following sections refer to BIP Status field values. The BIP Status field is defined in the Header Preamble
specification above.
#### Draft
After fleshing out the proposal further and ensuring that it is of high quality and properly formatted, the authors
should open a pull request to the [BIPs repository](https://github.com/bitcoin/bips). The document must adhere to the
formatting requirements specified above and should be provided as a file named with a working title of the form
"bip-title.[md|mediawiki]". Only BIP Editors may assign BIP numbers. Until one has done so, authors should refer to their
BIP by name only.
BIPs that (1) adhere to the formatting requirements, (2) are on-topic, and (3) have materially progressed beyond the
ideation phase, e.g., by generating substantial public discussion and commentary from diverse contributors, by
independent Bitcoin projects working on adopting the proposal, or by the authors working for an extended period toward
improving the proposal based on community feedback, will be assigned a number by a BIP Editor. A number may be
considered assigned only after it has been publicly announced in the pull request by a BIP Editor. The BIP Editors should
not assign a number when they perceive a proposal being met with lack of interest: number assignment facilitates the
distributed discussion of ideas, but before a proposal garners some interest in the Bitcoin community, there is no need
to refer to it by a number.
Proposals are also not ready for number assignment if they duplicate efforts, disregard formatting rules, are too
unfocused or too broad, fail to provide proper motivation, fail to address backward compatibility where necessary, or
fail to specify the feature clearly and comprehensively. Reviewers and BIP Editors should provide guidance on how the
proposal may be improved to progress toward readiness. Pull requests that are proposing off-topic ideas or
have stopped making progress may be closed.
When the proposal is ready and has been assigned a number, a BIP Editor will merge it into the BIPs repository. After the
BIP has been merged to the repository, its main focus should no longer shift significantly, even while the authors may
continue to update the proposal as necessary. Updates to merged documents by the authors should also be submitted as
pull requests.
#### Complete[^complete]
When the authors have concluded all planned work on their proposal, are confident that their BIP represents a net
improvement, is clear, comprehensive, and is
ready for adoption by the Bitcoin community, they may update the BIPs status to Complete to indicate that they
recommend adoption, implementation, or deployment of the BIP. Where applicable, the authors must ensure that any
proposed specification is solid, not unduly complicated, and definitive. Specification BIPs must come with or refer to a working reference implementation and comprehensive test vectors before they can be moved to Complete. Subsequently, the BIPs content should only be
adjusted in minor details, e.g., to improve language, clarify ambiguities, backfill omissions in the specification, add
test vectors for edge cases, or address other issues discovered as the BIP is being adopted.
A Complete BIP can only move to Deployed or Closed. Any necessary changes to the specification should be minimal and
interfere as little as possible with ongoing adoption. If a Complete BIP is found to need substantial functional
changes, it may be preferable to move it to Closed[^new-BIP], and to start a new BIP with the changes instead.
Otherwise, it could cause confusion as to what being compliant with the BIP means.
A BIP may remain in the Complete status indefinitely unless its authors or deputies decide to move it to Closed or it is advanced to
Deployed.
Complete is the final status for most successful Informational BIPs.
#### Deployed
A Complete BIP should only be moved to Deployed once it is settled: after its approach has solidified, its
Specification has been put through its paces, feedback from early adopters has been processed, and amendments to the BIP have stopped.
Then, a BIP may be advanced to Deployed upon request by any community member with evidence[^evidence] that
the BIP is in active use. Convincing evidence includes for example: an established project having deployed support
for the BIP in mainnet software releases, a soft fork proposals activation criteria having been met on the network, or
rough consensus for the BIP having been demonstrated.
Once Deployed, the BIP is considered final.
Any modifications to the BIP beyond bug fixes, other minor amendments, additions to the test vectors, or editorial
changes should be avoided.
Any breaking changes to the BIPs Specification should be proposed as a new separate BIP.[^new-BIP]
##### Process BIPs
A Process BIP may change status from Complete to Deployed when it achieves rough consensus on the Bitcoin Development Mailing List. A
proposal is said to have rough consensus if its advancement has been open to discussion on the mailing list for at least
one month, the discussion achieved meaningful engagement, and no person maintains any unaddressed substantiated objections to it. Addressed or obstructive objections
may be ignored/overruled by general agreement that they have been sufficiently addressed, but clear reasoning must be
given in such circumstances. Deployed Process BIPs may be modified indefinitely as long as a proposed modification has
rough consensus per the same criteria.[^living-documents]
#### Closed[^closed]
A BIP that is of historical interest only, and is not being actively worked on, promoted or in active use, should be
marked as Closed. The reason for moving the
proposal to (or from) Closed should be recorded in the Changelog section in the same commit that updates the status.
BIPs do not get deleted, they are retained even after being updated to Closed.
Transitions involving the Closed state are:
##### Draft ↦ Closed
BIP authors may decide on their own to change their BIPs status from Draft to Closed. If a Draft BIP stops making
progress, sees accumulated feedback unaddressed, or otherwise appears stalled for a year, anyone may propose the BIP
status be updated to Closed. The BIP is then updated to Closed unless the authors assert that they intend to continue work within four weeks of being contacted.
##### Complete ↦ Closed
BIPs that had attained the Complete status, i.e., that had been recommended for adoption, may be moved to Closed per the
authors announcement to the Bitcoin Development Mailing List[^bip-announcements-to-list]. However, if someone volunteers to adopt the proposal
within four weeks, they become the BIP's author or deputy (see [Transferring BIP Ownership](#transferring-bip-ownership) below), and the BIP will
remain Complete instead.
##### Deployed ↦ Closed
A BIP may evolve from Deployed to Closed when it is no longer in active use. Any community member may initiate this
Status update by announcing it to the mailing list[^bip-announcements-to-list], and proceed if no objections have been raised for four weeks.
##### Closed ↦ Draft
The Closed status is generally intended to be a final status for BIPs,
and if BIP authors decide to make another attempt at a previously Closed BIP, it is generally recommended to create a new
proposal. (Obviously, the authors may borrow any amount of inspiration or actual text from any prior BIPs as licensing
permits.) The authors should take special care to address the issues that caused the prior attempts abandonment. Even
if the prior attempt had been assigned a number, the new BIP will generally be assigned a distinct number. However, if it is
obvious that the new attempt directly continues work on the same idea, it may be reasonable to return the
Closed BIP to Draft status.
### Changelog Section and Version Header
To help implementers understand updates to a BIP, any changes after it has reached Complete must be tracked with version,
date, and description in a Changelog section sorted by most recent version first. The version number is inspired by semantic versioning (MAJOR.MINOR.PATCH).
The MAJOR version is incremented if changes to the BIPs Specification are introduced that are incompatible with prior
versions (which should be rare after a BIP is Complete, and only happen in well-grounded exceptional cases to a BIP that
is Deployed). The MINOR version is incremented whenever the specification of the BIP is changed or extended in a
backward-compatible way. The PATCH version is incremented for other changes to the BIP that are noteworthy (bug fixes,
test vectors, important clarifications, etc.). Version 1.0.0 is used to label the promotion to
Complete. A Changelog section may be introduced during the Draft phase to record significant changes (using versions 0.x.y).
Example:
> __Changelog__
>
> * __2.0.0__ (2025-01-22):
> * Introduce a breaking change in the specification to fix a bug.
> * __1.1.0__ (2025-01-17):
> * Add a backward compatible extension to the BIP.
> * __1.0.1__ (2025-01-15):
> * Clarify an edge case and add corresponding test vectors.
> * __1.0.0__ (2025-01-14):
> * Complete planned work on the BIP.
After a BIP receives a Changelog, the
Preamble must indicate the latest version in the Version header. The Changelog highlights revisions to BIPs to human readers. A single
BIP shall not recommend more than one variant of an idea at the same time. A different or
competing variant of an existing BIP must be published as a separate BIP.
### Adoption of Proposals
The BIPs repository does not track the sentiment on proposals and does not track the adoption of BIPs beyond whether they
are in active use or not. It is not intended for BIPs to list additional implementations beyond the reference
implementation: the BIPs repository is not a signpost where to find implementations.[^OtherImplementations] After a BIP
is advanced to Complete, it is up to the Bitcoin community to evaluate, adopt, ignore, or reject a BIP. Individual
Bitcoin projects are encouraged to publish a list of BIPs they implement. A good example of this at the time of writing
this BIP can be observed in Bitcoin Cores [doc/bips.md](https://github.com/bitcoin/bitcoin/blob/master/doc/bips.md)
file.
### Transferring BIP Ownership
It occasionally becomes necessary to transfer ownership of BIPs to new owners. In general, it would be preferable to
retain the original authors of the transferred BIP, but that is up to the original authors. A good reason to transfer
ownership is because the original authors no longer have the time or interest in updating it or following through with
the BIP process, or are unreachable or unresponsive. A bad reason
to transfer ownership is because someone doesn't agree with the direction of the BIP. The community tries to build
consensus around a BIP, but if that's not possible, rather than fighting over control, the dissenters should supply a
competing BIP.
If someone is interested in assuming ownership of a BIP, they should send an email asking to take over, addressed to the
original authors, the BIPEditors, and the Bitcoin Development Mailing List[^bip-announcements-to-list]. If the authors are unreachable or do not respond in a timely
manner (e.g., four weeks), the BIP Editors will make a unilateral decision whether to appoint the applicants as
[Authors or Deputies](#authors-and-deputies) (which may be amended should the original authors make a delayed reappearance).
## BIP Licensing
The Bitcoin project develops a global peer-to-peer digital cash system. Open standards are indispensable for continued
interoperability. Open standards reduce friction, and encourage anybody and everyone to contribute, compete, and
innovate on a level playing field. Only freely licensed contributions are accepted to the BIPs repository.
### Specification
Each new BIP must specify in two ways under which license terms it is made available. First, it must specify an [SPDX
License Expression](https://spdx.dev/ids/) in the License field in the preamble. Second, it must include a matching
Copyright section, possibly providing further details on licensing.
For example, a preamble might include the following License header:
License: CC0-1.0 OR MIT
In this case, the BIP (including all auxiliary files) is made available under the terms of both CC0 1.0 Universal as well as the
MIT License, and anyone may modify and redistribute it provided they comply with the terms of
*either* license, at their option. In other words, the license list is an "OR choice", not an "AND also" requirement. See the [SPDX
documentation](https://spdx.dev/ids/) and the [SPDX License List](https://spdx.org/licenses/) for further details.
Wherever different from those specified in the License header, an auxiliary file or directory should specify the license terms under which it is made available as is common in
software (e.g., with a [`SPDX-License-Identifier: <SPDX License Expression>` comment](https://spdx.dev/ids/),
a license header, or a LICENSE/COPYING file). Such exceptions should also be mentioned in the Copyright section. It is recommended to make any test vectors available
under CC0-1.0 or FSFAP in addition to any other licenses to allow anyone to copy test vectors into their
implementations without introducing license hindrances.
A few BIP2-era BIPs (98, 116, 117, 330, 340) have a no longer used "License-Code" header indicating the license terms applicable to auxiliary source code files. For such cases, please refer to BIP2.
It is recommended that source code included in a BIP (whether within the text or in auxiliary files) be licensed under the same license terms as the project it
is proposed to modify, if any. For example, changes intended for Bitcoin Core would ideally be licensed (also) under the MIT
License.
In all cases, details of the licensing terms must be provided in the Copyright section of the BIP.
#### Acceptable Licenses[^licenses]
Each new BIP must be made available under at least one acceptable license as listed below. BIPs are not required to be
*exclusively* licensed under approved terms, and may also be licensed under other licenses *in addition to* at least one
acceptable license.
In other words, a new BIP must specify an SPDX License Expression that is either "L" or equivalent to "L OR E" for some
acceptable license L from the following list and another SPDX License Expression E.
* BSD-2-Clause: [BSD 2-Clause License](https://opensource.org/license/BSD-2-Clause)
* BSD-3-Clause: [BSD 3-Clause License](https://opensource.org/license/BSD-3-Clause)
* CC0-1.0: [CC0 1.0 Universal](https://creativecommons.org/publicdomain/zero/1.0/)
* FSFAP: [FSF All Permissive License](https://www.gnu.org/prep/maintain/html_node/License-Notices-for-Other-Files.html)
* CC-BY-4.0: [Creative Commons Attribution 4.0 International](https://creativecommons.org/licenses/by/4.0/)
* MIT: [The MIT License](https://opensource.org/license/MIT)
* MIT-0: [MIT No Attribution License](https://opensource.org/license/MIT-0)
* Apache-2.0: [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0)
* BSL-1.0: [Boost Software License 1.0](https://www.boost.org/LICENSE_1_0.txt)
#### Not Acceptable Licenses
All licenses not explicitly included in the above lists are not acceptable terms for a Bitcoin Improvement Proposal.
However, BIPs predating this proposal were accepted under other terms, and should use one of the following identifiers.
* LicenseRef-PD: Placed into the public domain
* OPUBL-1.0: [Open Publication License 1.0](https://opencontent.org/openpub/)
## BIP Editors
The current BIP Editors are:
* Bryan Bishop ([kanzure@gmail.com](mailto:kanzure@gmail.com))
* Jon Atack ([jon@atack.com](mailto:jon@atack.com))
* Luke Dashjr ([luke_bipeditor@dashjr.org](mailto:luke_bipeditor@dashjr.org))
* Mark "Murch" Erhardt ([murch@murch.one](mailto:murch@murch.one))
* Olaoluwa Osuntokun ([laolu32@gmail.com](mailto:laolu32@gmail.com))
* Ruben Somsen ([rsomsen@gmail.com](mailto:rsomsen@gmail.com))
### BIP Editor Responsibilities and Workflow
The BIP Editors subscribe to the Bitcoin Development Mailing List and watch the [BIPs
repository](https://github.com/bitcoin/bips).
When either a new BIP idea or an early draft is submitted to the mailing list, BIP Editors or other community members should comment in regard
to:
* Novelty of the idea
* Viability, utility, and relevance of the concept
* Readiness of the proposal
* On-topic for the Bitcoin community
Discussion in pull request comments can often be hard to follow as feedback gets marked as resolved when it is addressed
by authors. Substantive discussion of ideas may be more accessible to a broader audience on the mailing list, where it
is also more likely to be retained by the community memory.
If the BIP needs more work, an editor should ensure that constructive, actionable feedback is provided to the authors
for revision. Once the BIP is ready it should be submitted as a "pull request" to the [BIPs
repository](https://github.com/bitcoin/bips) where it may get further feedback.
For each new BIP pull request that comes in, an editor checks the following:
* The idea has been previously proposed to the Bitcoin Development Mailing List and discussed there
* The described idea is on-topic for the repository
* A draft of the BIP by one of the authors has been previously discussed on the Bitcoin Development Mailing List
* Title accurately describes the content
* Proposal is of general interest and/or pertains to more than one Bitcoin project/implementation
* Document is properly formatted
* Licensing terms are acceptable
* Motivation, Rationale, and Backward Compatibility have been addressed
* Specification provides sufficient detail for implementation
* The defined Layer and Type headers must be correctly assigned for the given specification
* The BIP is ready: it is comprehensible, technically feasible and sound, and all aspects are addressed as necessary
Editors do NOT evaluate whether the proposal is likely to be adopted.
Then, a BIP Editor will:
* Assign a BIP number in the pull request
* Ensure that the BIP is listed in the [README](README.mediawiki)
* Merge the pull request when it is ready
The BIP Editors are intended to fulfill administrative and editorial responsibilities. The BIP Editors monitor BIP
changes, and update BIP headers as appropriate.
BIP Editors may also, at their option, unilaterally make and merge strictly editorial changes to BIPs, such as
correcting misspellings, mending grammar mistakes, fixing broken links, etc. as long as they do not change the meaning or conflict with the
original intent of the authors. Such a change must be recorded in the Changelog if its noteworthy per the criteria
mentioned in the [Changelog](#changelog) section.
## Backward Compatibility
### Changes from BIP2
#### Workflow
- Status field values are reduced from nine to four:
- Deferred, Obsolete, Rejected, Replaced, and Withdrawn are gathered up into Closed.[^closed]
- Final and Active are collapsed into Deployed.
- Proposed is renamed to Complete.
- The remaining statuses are Draft, Complete, Deployed, and Closed.
- The comment system is abolished.[^comments]
- A BIP in Draft or Complete status may no longer be closed solely on grounds of not making progress for three years.[^rejection]
- A BIP in Draft status may be updated to Closed status if it appears to have stopped making progress for at least a
year and its authors do not assert within four weeks of being contacted that they intend to continue working on it.
- Complete BIPs can only be moved to Closed by its authors and may remain in Complete indefinitely.
- A Changelog section is introduced to track significant changes to BIPs after they have reached the Complete status.
- Process BIPs are living documents that do not ossify and may be modified indefinitely.
- Some judgment calls previously required from BIP Editors are reassigned either to the BIP authors or the repositorys
audience.
#### BIP Format
- The Standards Track type is superseded by the similar Specification type.[^standard-track]
- Many sections are declared optional; it is up to the authors and reviewers to judge whether all relevant topics have
been comprehensively addressed and which topics require a designated section to do so.
- "Other Implementations" sections are discouraged.[^OtherImplementations]
- Auxiliary files are only permitted in the corresponding BIPs subdirectory, as no one used the alternative of labeling
them with the BIP number.
- Tracking of community consensus and adoption is out of scope for the BIPs repository, except to determine
whether a BIP is in active use for the move into or out of the Deployed status.
- The distinction between recommended and acceptable licenses was dropped.
- Most licenses that have not been used in the BIP process have been dropped from the list of acceptable licenses.
#### Preamble
- "Comments-URI" and "Comments-Summary" headers are dropped from the preamble.[^comments]
- The "Superseded-By" header is replaced with the "Proposed-Replacement" header.
- The "Post-History" header is replaced with the "Discussion" header.
- The optional "Version" header is introduced.
- The "Discussions-To" header is dropped, as it has never been used in any BIP.
- The "License-Code" header has been sunset, as it was used by only five BIPs (98, 116, 117, 330, 340) and created more ambiguity than clarity.
- The "Created" header is renamed to "Assigned", as the headers value is the date of number assignment.[^assigned]
- Introduce Deputies and optional "Deputies" header.
- The BIP "Title" header may now contain up to 50 characters (increased from 44 in BIP2).
- The "Layer" header is optional for Specification BIPs or Informational BIPs, as it does not make sense for all BIPs.[^layer]
- Rename the "Author" field to "Authors".
### Updates to Existing BIPs should this BIP be Activated
#### Previous BIP Process
This BIP replaces BIP2 as the guideline for the BIPprocess.
#### BIP Types
Standards Track BIPs and eligible Informational BIPs are assigned the Specification type. The Standards Track type is
considered obsolete. Specification BIPs use the Layer header rules specified in [BIP123](bip-0123.mediawiki).
#### Comments
The Comments-URI and Comments-Summary headers should be removed from all BIPs whose comment page in the wiki is empty.
For existing BIPs whose comment page has content, BIP Authors may keep both headers or remove both headers at their
discretion. It is recommended that existing wiki pages are not modified due to the activation of this BIP.
#### Status Field
After the activation of this BIP, the Status fields of existing BIPs that do not fit the specification in this BIP are
updated to the corresponding values prescribed in this BIP. BIPs that have had Draft status for extended periods will be
moved to Complete or Deployed as applicable in collaboration with their authors. The authors of incomplete Draft BIPs
will be contacted to learn whether the BIPs are still in progress toward Complete, and will otherwise be updated to
Closed as described in the [Workflow](#workflow) section above.
#### Authors Header
The Author header is replaced with the Authors header in all BIPs.
#### Discussion Header
The Post-History header is replaced with the Discussion header in all BIPs.
#### Proposed-Replacement Header
The Superseded-By header is replaced with the Proposed-Replacement header in all BIPs.
#### Licenses
Existing BIPs retain their license terms unchanged.
The License and License-Code headers of BIPs are updated to express those terms using SPDX License Expressions.
## Changelog
* __1.4.0__ (2025-12-09):
* Revert AI guidance, add Changelog section, broaden reference implementation formats, move Type header responsibility to authors, other editorial changes
* __1.3.1__ (2025-11-10):
* Reiterate that numbers are assigned by BIP Editors in pull requests
* __1.3.0__ (2025-10-22):
* Restrict use of AI/LLM tools, require original work.
* __1.2.1__ (2025-09-19):
* Clarify that idea should be discussed on dedicated mailing list thread
* __1.2.0__ (2025-09-19):
* Rename Created header to Assigned to clarify that it holds the date of number assignment
* __1.1.0__ (2025-07-18):
* Switch to SPDX License Expressions, drop License-Code header, and make editorial changes to BIP Licensing section.
* __1.0.1__ (2025-06-27):
* Improve description of acceptance, purpose of the BIPs repository, when Draft BIPs can be closed due to not
making progress, and make other minor improvements to phrasing.
* __1.0.0__ (2025-03-18):
* Complete planned work and move to Proposed.
## Copyright
This BIP is licensed under the [BSD-2-Clause License](https://opensource.org/licenses/BSD-2-Clause). Some content was
adapted from [BIP2](bip-0002.mediawiki) which was also licensed under the BSD-2-Clause.
## Related Work
- [BIP1: BIP Purpose and Guidelines](bip-0001.mediawiki)
- [BIP2: BIP Process, revised](bip-0002.mediawiki)
- [BIP123: BIP Classification](bip-0123.mediawiki)
- [RFC 822: Standard for ARPA Internet Text Messages](https://datatracker.ietf.org/doc/html/rfc822)
- [RFC 2223: Instructions to RFC Authors](https://datatracker.ietf.org/doc/html/rfc2223)
- [RFC 7282: On Consensus and Humming in the IETF](https://tools.ietf.org/html/rfc7282)
## Acknowledgements
We thank AJ Towns, Jon Atack, Jonas Nick, Larry Ruane, Pieter Wuille, Tim Ruffing, and others for their review,
feedback, and helpful comments.
## Rationale
[^assigned]: **Why was the Created header renamed to Assigned?**
Both BIP1 and BIP2 described the Created header as "date created on" in the preamble template, but followed that
up with "Created header records the date that the BIP was assigned a number" as the description of the field. This
has frequently led to confusion, with authors using the date of opening the pull request, the date they started
writing their proposal, the date of number assignment (as prescribed), or various other dates. Aligning the name of
the header and the text in the preamble template with the descriptions will reduce the confusion.
[^standard-track]: **Why was the Specification type introduced?**
The definitions of Informational and Standards Track BIPs caused some confusion in the past. Due to Informational
BIPs being described as optional, Standards Track BIPs were sometimes misunderstood to be generally recommended.
This has led to a number of BIPs that propose new features affecting interoperability of implementations being
assigned the Informational type. The situation is remedied by introducing a new _Specification BIP_ type that is
inclusive of any BIPs that can be implemented and affect interoperability of Bitcoin applications. Since all BIPs
are individual recommendations by the authors (even if some may eventually achieve endorsement by the majority of
the community), the prior reminder that Informational BIPs are optional is dropped.
[^comments]: **Why were comments, Comments-URI, and Comments-Summary removed from the process?**
The comments feature saw insignificant adoption. Few BIPs received any comments and barely any more than two with
only a handful of contributors commenting at all. This led to many situations in which one or two comments ended up
dominating the comment summary. While some of those comments may have been representative of broadly held opinions,
it also overstated the importance of individual comments directly in the Preamble of BIPs. As collecting feedback in
this accessible fashion failed, the new process puts the burden back on the audience to make their own evaluation.
[^layer]: **Why is the layer header now permitted for other BIP types?**
The layer header had already been used by many Informational BIPs, so the rule that it is only available to
Standards Track BIPs is dropped.
[^OtherImplementations]: **What is the issue with "Other Implementations" sections in BIPs?**
In the past, some BIPs had "Other Implementations" sections that caused frequent change requests to existing BIPs.
This put a burden on the BIP authors and BIP Editors, and frequently led to lingering pull requests due to the corresponding BIPs
authors no longer participating in the process. Many of these alternative implementations eventually became
unmaintained or were low-quality to begin with. Therefore, "Other Implementations" sections are heavily discouraged.
[^complete]: **Why was the Proposed status renamed to Complete?**
Some reviewers of this BIP raised that in a process which outlines the workflow of Bitcoin Improvement _Proposals_
using "Proposed" as a status field value was overloading the term: clearly _proposals_ are proposed at all stages of
the process. "Complete" expresses that the authors have concluded planned work on all parts of the proposal and are
ready to recommend their BIP for adoption. The term "ready" was also considered, but considered too subjective.
[^rejection]: **Why can proposals remain in Draft or Complete indefinitely?**
The automatic 3-year timeout of BIPs has led to some disagreement in the past and seems unnecessary in cases where
the authors remain active in the community and still consider their idea worth pursuing. On the other hand,
Draft proposals that appear stale may be closed after only one year, which should achieve the main goal of
the original rule by limiting the effort and attention spent on proposals that never reach Complete.
[^closed]: **Why was the Closed Status introduced?**
The Closed Status provides value to the audience by indicating which documents are only of historical significance.
Previously, the process had Deferred, Obsolete, Rejected, Replaced, and Withdrawn, which all meant some flavor of
"work has stopped on this." The many statuses complicated the process, may have contributed to process fatigue, and
may have resulted in BIPs statuses not being maintained well. The author of this BIP feels that all of the
aforementioned can be represented by _Closed_ without significantly impacting the information quality of the
overview table. Where the many Status variants provided minuscule additional information, the simplification is more
valuable and the Changelog section now collects specific details.
[^acceptance]: **When is a BIP "accepted"?**
Many standards processes such as the PEPs or the IETF have a mechanism for a proposal to be formally accepted by
some council or committee. The BIP Process does not have such a decision body. Bitcoin development and "acceptance"
of BIPs emerges from the participation of stakeholders across the ecosystem, and refers to some vague notion of community
interest and support for a proposal.
BIP2 had made an attempt to gather community feedback into comment summaries in BIPs directly. Given the low
participation and corresponding low information quality of the summaries that resulted from that feature, this BIP
instead intends to leave the evaluation of BIPs to the reviewers and users.
[^adoption]: **Why does the BIPs repository no longer track adoption?**
In the past, some BIPs maintained lists of projects that had implemented the BIP. These lists generated
noise for subscribers of the repository, often listed implementations of questionable quality, and quickly
grew outdated, therefore providing little value. The repository no longer tracks which projects have implemented
BIPs. Instead, it is recommended that projects publish a list of the BIPs they implement.
[^markdown]: **Which flavor of Markdown is allowed?**
The author of this proposal has no opinion on Markdown flavors, but recommends that proposals stick to the basic
Markdown syntax features commonly shared across Markdown dialects.
[^living-documents]: **Why are Process BIPs living documents?**
In the past years, the existing BIPs process has not always provided a clear approach to all situations. For
example, the content of BIP2 appears to have been penned especially with fork proposals in mind. It seems clear
that Bitcoin development will evolve in many surprising ways in the future. Instead of mandating the effort of
writing a new process document every time new situations arise, it seems preferable to allow the process to adapt to
the concerns of the future in specific aspects. Therefore, Process BIPs are defined as living documents that remain
open to amendment. If a Process BIP requires large modifications or even a complete overhaul, a new BIP should be
preferred.
[^new-BIP]: **Why should the specification of an implemented BIP no longer be changed?**
After a Complete or Deployed BIP has been deployed by one or more implementations, breaking changes to the
specification could lead to a situation where multiple "compliant" implementations fail at being interoperable,
because they implemented different versions of the same BIP. Therefore, even changes to the specification of
Complete BIPs should be avoided, but Deployed BIPs should never be subject to breaking changes to their
specification.
[^bip-announcements-to-list]: **Why are some BIP status changes announced to the mailing list?**
The BIPs repository does not and cannot track who might be interested in or has deployed a BIP. While concerns were
raised that making announcements to the Bitcoin Developer Mailing List would introduce unnecessary noise, our
rationale is that 1) moving Complete and Deployed BIPs to the Closed status will be a rare occurrence, 2) status
updates will usually not generate a lot of discussion, 3) while the mailing list should preferably only used for
getting review for new BIPs, it is the only channel available to us that can be considered a public announcement to
the audience of the BIPs repository: even if the authors, implementers, or other parties interested in a BIP do not
see the announcement themselves, they may be made aware by someone that does see it.
[^superseded-by-proposed-replacement]: **Why is Superseded-By replaced with Proposed-Replacement?**
Reviewers asked who should get to decide whether a BIP is superseded in case of a disagreement among the authors of
the original BIP, the authors of the new BIP, the editors, or the community? This is addressed by making the
"Replaces" header part of the recommendation of the authors of the new document, and replacing the "Superseded-By"
header with the "Proposed-Replacement" header that lists any proposals that recommend replacing the original document.
[^proposes-to-replace]: **Why was "Replaces" retained instead of changing it to "Proposes-to-Replace"?**
When one BIP proposes to supersede another, it is on the original BIP where things get complicated. The BIP is an
author document, but depending on its progress through the workflow, it may meanwhile be co-owned by the community. Who may decide
whether the original document should endorse a potential replacement BIP? Is it the original authors, the authors of the new
proposal, the BIP Editors, some sort of community process, or a mix of all of the above?
On the new BIP these problems dont exist in the same manner. As it is freshly written, it is wholly owned by its
authors. The community is not yet invested and the original BIPs authors do not have a privileged role
in determining the content of the new BIP. The authors of the new BIP can unilaterally recommend that it be
considered a replacement for a prior BIP. From there, the community can evaluate the proposal and adopt or
reject it, thus establishing whether it is successful in superseding the original or not.
[^evidence]: **How is evidence for advancing to Deployed evaluated?**
Whether evidence is deemed convincing to move a BIP to Deployed is up to the BIP Editors and Bitcoin community.
Running a single instance of a personal fork of a software project might be rejected, while a small software project with
dozens of users may be sufficient. The main point of the Deployed status is to indicate that changes to the BIP
could negatively impact users of projects that have already implemented support.
[^licenses]: **Why were some licenses dropped?**
Among the 141 BIPs with licenses in the repository, only nine licenses have ever been used to license BIPs
(although, some BIPs were made available under more than one license) and only one license has been used to license
code:
Licenses used:
* BSD-2-Clause: 55
* PD: 42
* CC0-1.0: 23
* BSD-3-Clause: 19
* OPUBL-1.0: 5
* CC-BY-SA-4.0: 4
* FSFAP: 3
* MIT: 2
* CC-BY-4.0: 1
License-Code used (previous BIP2 format):
* BSD-2-Clause: 1
* CC0-1.0: 1
* MIT: 5
The following previously acceptable licenses were retained per request of reviewers, even though they have so far
never been used in the BIPs process:
* Apache-2.0: [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0)
* BSL-1.0: [Boost Software License 1.0](https://www.boost.org/LICENSE_1_0.txt)
The following previously acceptable licenses have never been used in the BIPs Process and have been dropped:
* AGPL-3.0+: [GNU Affero General Public License (AGPL) 3](https://www.gnu.org/licenses/agpl-3.0.en.html)
* FDL-1.3: [GNU Free Documentation License 1.3](https://www.gnu.org/licenses/fdl-1.3.en.html)
* GPL-2.0+: [GNU General Public License (GPL) 2 or newer](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
* LGPL-2.1+: [GNU Lesser General Public License (LGPL) 2.1 or newer](https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html)
Why are software licenses included?
* Some BIPs, in particular those concerning the consensus layer, may include literal code in the BIP itself which
may not be available under the license terms the authors wish to use for the BIP.
* The author of this BIP has been provided with a learned opinion indicating that software licenses are perfectly
acceptable for licensing "human code" i.e., text as well as Markdown or MediaWiki code.
Why is CC-BY-SA-4.0 no longer acceptable for new BIPs?
* Specification BIPs are required to have a Reference Implementation and Test Vectors to be advanced to Complete. As
the BIPs repository is aiming to make proposals easily adoptable, the intention is for the reference
implementation and test vectors to be as accessible as possible. Copyleft licenses may introduce friction here,
and therefore CC-BY-SA-4.0 (and the GPL-flavors) is no longer considered acceptable for new BIPs. As mentioned
above, existing BIPs will retain their original licensing.
Why are Open Publication License and Public Domain no longer acceptable for new BIPs?
* Public domain is not universally recognised as a legitimate action, thus it is inadvisable.
* The Open Publication License is generally regarded as obsolete, and not a license suitable for new publications.

BIN
bip-0003/status-diagram.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

View File

@ -1,15 +1,12 @@
<pre>
BIP: 8
Title: Version bits with lock-in by height
Author: Shaolin Fry <shaolinfry@protonmail.ch>
Luke Dashjr <luke+bip@dashjr.org>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0008
Authors: Shaolin Fry <shaolinfry@protonmail.ch>
Luke Dashjr <luke+bip@dashjr.org>
Status: Draft
Type: Informational
Created: 2017-02-01
License: BSD-3-Clause
CC0-1.0
Assigned: 2017-02-01
License: BSD-3-Clause OR CC0-1.0
</pre>
==Abstract==

View File

@ -1,15 +1,13 @@
<pre>
BIP: 9
Title: Version bits with timeout and delay
Author: Pieter Wuille <pieter.wuille@gmail.com>
Peter Todd <pete@petertodd.org>
Greg Maxwell <greg@xiph.org>
Rusty Russell <rusty@rustcorp.com.au>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0009
Status: Final
Authors: Pieter Wuille <pieter.wuille@gmail.com>
Peter Todd <pete@petertodd.org>
Greg Maxwell <greg@xiph.org>
Rusty Russell <rusty@rustcorp.com.au>
Status: Deployed
Type: Informational
Created: 2015-10-04
Assigned: 2015-10-04
License: PD
</pre>
@ -119,7 +117,7 @@ other one simultaneously transitions to STARTED, which would mean both would dem
Note that a block's state never depends on its own nVersion; only on that of its ancestors.
case STARTED:
case STARTED:
if (GetMedianTimePast(block.parent) >= timeout) {
return FAILED;
}

22
bip-0009/states.gv Normal file
View File

@ -0,0 +1,22 @@
/* There are many ways to compile this, but one of them is:
*
* $ dot -Tpng states.gv -o states.png
*/
digraph {
/* States. */
DEFINED; FAILED; STARTED; LOCKED_IN; ACTIVE;
/* Relationships between states, labeled where applicable. */
DEFINED -> DEFINED;
DEFINED -> FAILED [label = "timeout ≤ MTP"];
DEFINED -> STARTED [label = "starttime ≤ MTP < timeout"];
FAILED -> FAILED;
STARTED -> STARTED;
STARTED -> FAILED [label = "timeout ≤ MTP"];
STARTED -> LOCKED_IN [label = "(MTP < timeout) AND (threshold reached)"];
LOCKED_IN -> ACTIVE [label = "Always"];
ACTIVE -> ACTIVE;
/* Visualization hack to unclutter output. */
nodesep = 1.2;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 49 KiB

View File

@ -2,12 +2,10 @@
BIP: 10
Layer: Applications
Title: Multi-Sig Transaction Distribution
Author: Alan Reiner <etotheipi@gmail.com>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0010
Status: Withdrawn
Authors: Alan Reiner <etotheipi@gmail.com>
Status: Closed
Type: Informational
Created: 2011-10-28
Assigned: 2011-10-28
</pre>
A multi-signature transaction is one where a certain number of Bitcoins are "encumbered" with more than one recipient address. The subsequent transaction that spends these coins will require each party involved (or some subset, depending on the script), to see the proposed transaction and sign it with their private key. This necessarily requires collaboration between all parties -- to propose a distribution of encumbered funds, collect signatures from all necessary participants, and then broadcast the completed transaction.
@ -28,7 +26,7 @@ This BIP proposes the following process, with terms in quotes referring to recom
# One party will initiate this process by creating a "Distribution Proposal", which could be abbreviated DP, or TxDP
# The user creating the TxDP (the preparer) will create the transaction as they would like to see it spent, but with blank TxIn scripts (where the signatures scripts will eventually go).
# The proposed transaction will be spending a set of unspent TxOuts available in the blockchain. The full transactions containing these TxOuts will be serialized and included, as well. This so that the values of the TxIns can be verified before signing (the prev-tx-hash is part of the data being signed, but the value is not). By including the full tx, the signing party can verify that the tx matches the OutPoint hash, and then verify input values, all without any access to the blockchain.
# The TxDP will have an "DP ID" or "Unsigned ID" which is the hash of the proposed transaction with blanked scripts, in Base58. This is a specific naming convention to make sure it is not confused with the actual the transaction ID that it will have after it is broadcast (the transaction ID cannot be determined until after all signatures are collected). The final Tx ID can be referred to as its "Broadcast ID", in order to distinguish it from the pre-signed ID.
# The TxDP will have an "DP ID" or "Unsigned ID" which is the hash of the proposed transaction with blanked scripts, in Base58. This is a specific naming convention to make sure it is not confused with the actual transaction ID that it will have after it is broadcast (the transaction ID cannot be determined until after all signatures are collected). The final Tx ID can be referred to as its "Broadcast ID", in order to distinguish it from the pre-signed ID.
# The TxDP will have a potentially-unordered list of sig-pubkey pairs which represent collected signatures. If you receive a TxDP missing only your signature, you can broadcast it as soon as you sign it.
# Identical TxDP objects with different signatures can be easily combined. This allows one party to send out all the requests for signatures at once, and combine them all when they are received (instead of having to "pass it around".
# For cases where the TxDP might be put into a file or sent via email, it should use .txdp or .btcdp suffix
@ -93,10 +91,17 @@ The following is an example TxDP from Armory, produced while running on the test
In this transaction, there are two inputs, one of 150 BTC and the other of 12 BTC. This transaction combines 162 BTC to create two outputs, one of 160 BTC, one 1.9995 BTC, and a tx fee of 0.0005. In this TxDP, both inputs have been signed, and thus could broadcast immediately.
The style of communication is taken directly from PGP/GPG, which uses blocks of ASCII like this to communicate encrypted messages and signatures. This serialization is compact, and will be interpretted the same in all character encodings. It can be copied inline into an email, or saved in a text file. The advantage over the analogous PGP encoding is that there are some human readable elements to it, for users that wish to examine the TxDP packet manually, instead of requiring a program to parse the core elements of the TxDP.
The style of communication is taken directly from PGP/GPG, which uses blocks of ASCII like this to communicate encrypted messages and signatures. This serialization is compact, and will be interpreted the same in all character encodings. It can be copied inline into an email, or saved in a text file. The advantage over the analogous PGP encoding is that there are some human readable elements to it, for users that wish to examine the TxDP packet manually, instead of requiring a program to parse the core elements of the TxDP.
A party receiving this TxDP can simply add their signature to the appropriate _TXINPUT_ line. If that is the last signature required, they can broadcast it themselves. Any software that implements this standard should be able to combine multiple TxDPs into a single TxDP. However, even without the programmatic support, a user could manually combine them by copying the appropriate _TXSIGS_ lines between serializations, though it is not the recommended method for combining TxDPs.
A party receiving this TxDP can simply add their signature to the appropriate _TXINPUT_ line. If that is the last signature required, they can broadcast it themselves. Any software that implements this standard should be able to combine multiple TxDPs into a single TxDP. However, even without the programmatic support, a user could manually combine them by copying the appropriate _SIG_ lines between serializations, though it is not the recommended method for combining TxDPs.
== Changelog ==
* 2014-11-26:
** Withdrawn after Armory stopped using BIP10 and no other projects were known to implement support (see [https://github.com/bitcoin/bips/pull/125 bips#125]).
* 2011-10-28:
** Original Draft published.
== Reference Implementation ==
This proposal was implemented and tested in the older versions of ''Armory'' Bitcoin software for use in offline-wallet transaction signing (as a 1-of-1 transaction). Implementation can be found in https://github.com/etotheipi/BitcoinArmory/blob/v0.91-beta/armoryengine/Transaction.py under the class PyTxDistProposal. However, as of verion 0.92 released in July 2014, Armory no longer uses this proposal for offline wallet transaction signing and has moved on to a new format.
This proposal was implemented and tested in the older versions of ''Armory'' Bitcoin software for use in offline-wallet transaction signing (as a 1-of-1 transaction). Implementation can be found in https://github.com/etotheipi/BitcoinArmory/blob/v0.91-beta/armoryengine/Transaction.py under the class PyTxDistProposal. However, as of version 0.92 released in July 2014, Armory no longer uses this proposal for offline wallet transaction signing and has moved on to a new format.

View File

@ -2,13 +2,11 @@
BIP: 11
Layer: Applications
Title: M-of-N Standard Transactions
Author: Gavin Andresen <gavinandresen@gmail.com>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0011
Status: Final
Type: Standards Track
Created: 2011-10-18
Post-History: 2011-10-02
Authors: Gavin Andresen <gavinandresen@gmail.com>
Status: Deployed
Type: Specification
Assigned: 2011-10-18
Discussion: 2011-10-02
</pre>
==Abstract==

View File

@ -2,12 +2,10 @@
BIP: 12
Layer: Consensus (soft fork)
Title: OP_EVAL
Author: Gavin Andresen <gavinandresen@gmail.com>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0012
Status: Withdrawn
Type: Standards Track
Created: 2011-10-18
Authors: Gavin Andresen <gavinandresen@gmail.com>
Status: Closed
Type: Specification
Assigned: 2011-10-18
</pre>
==Abstract==

View File

@ -2,12 +2,10 @@
BIP: 13
Layer: Applications
Title: Address Format for pay-to-script-hash
Author: Gavin Andresen <gavinandresen@gmail.com>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0013
Status: Final
Type: Standards Track
Created: 2011-10-18
Authors: Gavin Andresen <gavinandresen@gmail.com>
Status: Deployed
Type: Specification
Assigned: 2011-10-18
</pre>
==Abstract==

View File

@ -2,14 +2,13 @@
BIP: 14
Layer: Peer Services
Title: Protocol Version and User Agent
Author: Amir Taaki <genjix@riseup.net>
Patrick Strateman <bitcoin-bips@covertinferno.org>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0014
Status: Final
Type: Standards Track
Created: 2011-11-10
Post-History: 2011-11-02
Authors: Amir Taaki <genjix@riseup.net>
Patrick Strateman <bitcoin-bips@covertinferno.org>
Status: Deployed
Type: Specification
Assigned: 2011-11-10
Discussion: 2011-11-02: https://gnusha.org/pi/bitcoindev/1320268981.72296.YahooMailNeo@web121003.mail.ne1.yahoo.com/
2011-11-10: https://gnusha.org/pi/bitcoindev/1320959761.36702.YahooMailNeo@web121014.mail.ne1.yahoo.com/
</pre>
In this document, bitcoin will be used to refer to the protocol while Satoshi will refer to the current client in order to prevent confusion.
@ -28,7 +27,7 @@ Version bumping can also introduce incompatibilities and fracture the network. I
By using a protocol version, we set all implementations on the network to a common standard. Everybody is able to agree within their confines what is protocol and what is implementation-dependent. A user agent string is offered as a 'vanity-plate' for clients to distinguish themselves in the network.
Separation of the network protocol from the implemention, and forming development of said protocol by means of a mutual consensus among participants, has the democratic disadvantage when agreement is hard to reach on contentious issues. To mitigate this issue, strong communication channels and fast release schedules are needed, and are outside the scope of this document (concerning a process-BIP type).
Separation of the network protocol from the implementation, and forming development of said protocol by means of a mutual consensus among participants, has the democratic disadvantage when agreement is hard to reach on contentious issues. To mitigate this issue, strong communication channels and fast release schedules are needed, and are outside the scope of this document (concerning a process-BIP type).
User agents provide extra tracking information that is useful for keeping tabs on network data such as client implementations used or common architectures/operating-systems. In the rare case they may even provide an emergency method of shunning faulty clients that threaten network health- although this is strongly unrecommended and extremely bad form. The user agent does not provide a method for clients to work around and behave differently to different implementations, as this will lead to protocol fracturing.

View File

@ -2,17 +2,15 @@
BIP: 15
Layer: Applications
Title: Aliases
Author: Amir Taaki <genjix@riseup.net>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0015
Status: Deferred
Type: Standards Track
Created: 2011-12-10
Authors: Amir Taaki <genjix@riseup.net>
Status: Closed
Type: Specification
Assigned: 2011-12-10
</pre>
[[bip-0070.mediawiki|BIP 0070]] (payment protocol) may be seen as the alternative to Aliases.
Using vanilla bitcoin, to send funds to a destination, an address in the form 1Hd44nkJfNAcPJeZyrGC5sKJS1TzgmCTjjZ is needed. The problem with using addresses is they are not easy to remember. An analogy can be thought if one were required to enter the IP address of their favourite websites if domain names did not exist.
Using vanilla bitcoin, to send funds to a destination, an address in the form 1Hd44nkJfNAcPJeZyrGC5sKJS1TzgmCTjjZ is needed. The problem with using addresses is that they are not easy to remember. An analogy can be thought if one were required to enter the IP address of their favourite websites if domain names did not exist.
This document aims to layout through careful argument, a bitcoin alias system. This is a big modification to the protocol that is not easily changed in the future and has big ramifications. There is impetus in getting it correct the first time. Aliases have to be robust and secure.
@ -36,7 +34,7 @@ Their FirstBits alias becomes:
It is enough information to be given the FirstBits alias ''1brmlab''. When someone wishes to make a purchase, without FirstBits, they either have to type out their address laboriously by hand, scan their QR code (which requires a mobile handset that this author does not own) or find their address on the internet to copy and paste into the client to send bitcoins. FirstBits alleviates this impracticality by providing an easy method to make payments.
Together with [[vanitygen|Vanitygen (vanity generator)]], it becomes possible to create memorable unique named addresses. Addresses that are meaningful, rather than an odd assemblage of letters and numbers but add context to the destination.
Together with Vanitygen (vanity generator), it becomes possible to create memorable unique named addresses. Addresses that are meaningful, rather than an odd assemblage of letters and numbers but add context to the destination.
However FirstBits has its own problems. One is that the possible aliases one is able to generate is limited by the available computing power available. It may not be feasible to generate a complete or precise alias that is wanted- only approximates may be possible. It is also computationally resource intensive which means a large expenditure of power for generating unique aliases in the future, and may not scale up to the level of individuals at home or participants with hand-held devices in an environment of ubiquitous computing.
@ -208,7 +206,7 @@ NameResolutionService::~NameResolutionService()
void NameResolutionService::ExplodeHandle(const string& strHandle, string& strNickname, string& strDomain)
{
// split address at @ furthrest to the right
// split address at @ furthest to the right
size_t nPosAtsym = strHandle.rfind('@');
strNickname = strHandle.substr(0, nPosAtsym);
strDomain = strHandle.substr(nPosAtsym + 1, strHandle.size());
@ -348,7 +346,7 @@ By using DNS lookups, the MITM problem with IP transactions could be mitigated b
=== Namecoin ID ===
This proposal uses the Namecoin blockchain to associate an alias with a bitcoin address. Bitcoin queries a namecoin node. This retreives the structured data containing the bitcoin address(es) associated with this alias.
This proposal uses the Namecoin blockchain to associate an alias with a bitcoin address. Bitcoin queries a namecoin node. This retrieves the structured data containing the bitcoin address(es) associated with this alias.
Using a decentralised domain name system like Namecoin, means no external server or entity needs to be trusted unlike the other proposals listed here. This indicates a system with the advantage of having a high availability and ease of entry (no restrictions for users to create aliases).
@ -401,4 +399,4 @@ Any text can be put into the brackets, allowing merchants to adapt it to all the
New features can be added later to support uncovered cases.
See the specification of [http://dot-bit.org/Namespace:Identity Namecoin ID] for more informations.
See the specification of [http://dot-bit.org/Namespace:Identity Namecoin ID] for more information.

View File

@ -2,12 +2,10 @@
BIP: 16
Layer: Consensus (soft fork)
Title: Pay to Script Hash
Author: Gavin Andresen <gavinandresen@gmail.com>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0016
Status: Final
Type: Standards Track
Created: 2012-01-03
Authors: Gavin Andresen <gavinandresen@gmail.com>
Status: Deployed
Type: Specification
Assigned: 2012-01-03
</pre>
==Abstract==
@ -58,7 +56,7 @@ Examples:
+3 signature operations:
{2 [pubkey1] [pubkey2] [pubkey3] 3 OP_CHECKMULTISIG}
+22 signature operations
+22 signature operations:
{OP_CHECKSIG OP_IF OP_CHECKSIGVERIFY OP_ELSE OP_CHECKMULTISIGVERIFY OP_ENDIF}
==Rationale==
@ -74,7 +72,7 @@ The signature operation counting rules are intended to be easy and quick to impl
There is a 1-confirmation attack on old implementations, but it is expensive and difficult in practice. The attack is:
# Attacker creates a pay-to-script-hash transaction that is valid as seen by old software, but invalid for new implementation, and sends themselves some coins using it.
# Attacker also creates a standard transaction that spends the pay-to-script transaction, and pays the victim who is running old software.
# Attacker also creates a standard transaction that spends the pay-to-script-hash transaction, and pays the victim who is running old software.
# Attacker mines a block that contains both transactions.
If the victim accepts the 1-confirmation payment, then the attacker wins because both transactions will be invalidated when the rest of the network overwrites the attacker's invalid block.
@ -116,4 +114,5 @@ https://gist.github.com/gavinandresen/3966071
* [[bip-0016/qa.mediawiki|Quality Assurance test checklist]]
== References ==
<references>
<references/>

View File

@ -2,12 +2,10 @@
BIP: 17
Layer: Consensus (soft fork)
Title: OP_CHECKHASHVERIFY (CHV)
Author: Luke Dashjr <luke+bip17@dashjr.org>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0017
Status: Withdrawn
Type: Standards Track
Created: 2012-01-18
Authors: Luke Dashjr <luke+bip17@dashjr.org>
Status: Closed
Type: Specification
Assigned: 2012-01-18
License: BSD-2-Clause
</pre>
@ -86,7 +84,7 @@ Avoiding a block-chain split by malicious pay-to-script transactions requires ca
* A pay-to-script-hash transaction that is invalid for new clients/miners but valid for old clients/miners.
To gracefully upgrade and ensure no long-lasting block-chain split occurs, more than 50% of miners must support full validation of the new transaction type and must switch from the old validation rules to the new rules at the same time.
To gracefully upgrade and ensure no long-lasting block-chain split occurs, more than 50% of miners must support full validation of the new transaction type and must switch from the old validation rules to the new rules at the same time.
To judge whether or not more than 50% of hashing power supports this BIP, miners are asked to upgrade their software and put the string "p2sh/CHV" in the input of the coinbase transaction for blocks that they create.

View File

@ -2,12 +2,10 @@
BIP: 18
Layer: Consensus (soft fork)
Title: hashScriptCheck
Author: Luke Dashjr <luke+bip17@dashjr.org>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0018
Status: Proposed
Type: Standards Track
Created: 2012-01-27
Authors: Luke Dashjr <luke+bip17@dashjr.org>
Status: Complete
Type: Specification
Assigned: 2012-01-27
License: BSD-2-Clause
</pre>

View File

@ -2,12 +2,10 @@
BIP: 19
Layer: Applications
Title: M-of-N Standard Transactions (Low SigOp)
Author: Luke Dashjr <luke+bip17@dashjr.org>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0019
Status: Rejected
Type: Standards Track
Created: 2012-01-30
Authors: Luke Dashjr <luke+bip17@dashjr.org>
Status: Closed
Type: Specification
Assigned: 2012-01-30
License: BSD-2-Clause
</pre>

View File

@ -2,13 +2,12 @@
BIP: 20
Layer: Applications
Title: URI Scheme
Author: Luke Dashjr <luke+bip@dashjr.org>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0020
Status: Replaced
Type: Standards Track
Created: 2011-01-10
Authors: Luke Dashjr <luke+bip@dashjr.org>
Status: Closed
Type: Specification
Assigned: 2011-01-10
License: BSD-2-Clause
Proposed-Replacement: 21
</pre>
BIP 0020 is based off an earlier document by Nils Schneider. '''And has been replaced by BIP 0021'''
@ -34,7 +33,7 @@ Graphical bitcoin clients SHOULD register themselves as the handler for the "bit
=== BNF grammar ===
(See also [[#Simpler syntax|a simpler representation of syntax]])
(See also [[#simpler-syntax|a simpler representation of syntax]])
bitcoinurn = "bitcoin:" bitcoinaddress [ ";version=" bitcoinversion ] [ "?" bitcoinparams ]
bitcoinaddress = base58 *base58
@ -54,8 +53,8 @@ Graphical bitcoin clients SHOULD register themselves as the handler for the "bit
*label: Label for that address (e.g. name of receiver)
*address: bitcoin address
*message: message that shown to the user after scanning the QR code
*size: amount of base bitcoin units ([[#Transfer amount/size|see below]])
*message: message that is shown to the user after scanning the QR code
*size: amount of base bitcoin units ([[#transfer-amountsize|see below]])
*send: used to send bitcoin, rather than to request them
*(others): optional, for future extensions
@ -97,7 +96,7 @@ Make it possible for later generations to improve our work, to mend our errors,
=== Simpler syntax ===
This section is non-normative and does not cover all possible syntax.
Please see the [[#BNF grammar|BNF grammar]] above for the normative syntax.
Please see the [[#bnf-grammar|BNF grammar]] above for the normative syntax.
[foo] means optional, &lt;bar&gt; are placeholders

View File

@ -2,15 +2,21 @@
BIP: 21
Layer: Applications
Title: URI Scheme
Author: Nils Schneider <nils.schneider@gmail.com>
Matt Corallo <bip21@bluematt.me>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0021
Status: Final
Type: Standards Track
Created: 2012-01-29
Authors: Nils Schneider <nils.schneider@gmail.com>
Matt Corallo <bip21@bluematt.me>
Status: Closed
Type: Specification
Assigned: 2012-01-29
Replaces: 20
Proposed-Replacement: 321
</pre>
=Superseded by BIP 321=
This BIP has been superseded and replaced with BIP 321. Please see [[bip-0321.mediawiki|BIP 321]] instead.
=Original BIP=
This BIP is a modification of an earlier [[bip-0020.mediawiki|BIP 0020]] by Luke Dashjr. BIP 0020 was based off an earlier document by Nils Schneider. The alternative payment amounts in BIP 0020 have been removed.
==Abstract==
@ -37,7 +43,7 @@ Elements of the query component may contain characters outside the valid range.
=== ABNF grammar ===
(See also [[#Simpler syntax|a simpler representation of syntax]])
(See also [[#simpler-syntax|a simpler representation of syntax]])
bitcoinurn = "bitcoin:" bitcoinaddress [ "?" bitcoinparams ]
bitcoinaddress = *base58
@ -57,7 +63,7 @@ The scheme component ("bitcoin:") is case-insensitive, and implementations must
*label: Label for that address (e.g. name of receiver)
*address: bitcoin address
*message: message that describes the transaction to the user ([[#Examples|see examples below]])
*message: message that describes the transaction to the user ([[#examples|see examples below]])
*(others): optional, for future extensions
==== Transfer amount ====
@ -100,6 +106,8 @@ Please see the BNF grammar above for the normative syntax.
=== Examples ===
Note: The addresses used in these examples are intentionally invalid to prevent accidental transactions.
Just the address:
bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W
@ -120,11 +128,6 @@ Some future version that has variables which are (currently) not understood but
Characters must be URI encoded properly.
== Reference Implementations ==
=== Bitcoin clients ===
* Bitcoin-Qt supports the old version of Bitcoin URIs (ie without the req- prefix), with Windows and KDE integration as of commit 70f55355e29c8e45b607e782c5d76609d23cc858.
== Reference Implementation ==
=== Libraries ===
* Javascript - https://github.com/bitcoinjs/bip21
* Java - https://github.com/SandroMachado/BitcoinPaymentURI
* Swift - https://github.com/SandroMachado/BitcoinPaymentURISwift
Bitcoin-Qt supports the old version of Bitcoin URIs (ie without the req- prefix), with Windows and KDE integration as of commit 70f55355e29c8e45b607e782c5d76609d23cc858.

View File

@ -2,12 +2,10 @@
BIP: 22
Layer: API/RPC
Title: getblocktemplate - Fundamentals
Author: Luke Dashjr <luke+bip22@dashjr.org>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0022
Status: Final
Type: Standards Track
Created: 2012-02-28
Authors: Luke Dashjr <luke+bip22@dashjr.org>
Status: Deployed
Type: Specification
Assigned: 2012-02-28
License: BSD-2-Clause
</pre>
@ -26,7 +24,7 @@ This BIP is licensed under the BSD 2-clause license.
A JSON-RPC method is defined, called "getblocktemplate".
It accepts exactly one argument, which MUST be an Object of request parameters.
If the request parameters include a "mode" key, that is used to explicitly select between the default "template" request or a [[bip-0023.mediawiki#Block Proposal|"proposal"]].
If the request parameters include a "mode" key, that is used to explicitly select between the default "template" request or a [[bip-0023.mediawiki#block-proposal|"proposal"]].
Block template creation can be influenced by various parameters:
{| class="wikitable"
@ -34,7 +32,7 @@ Block template creation can be influenced by various parameters:
|-
! Key !! Required !! Type !! Description
|-
| capabilities || No || Array of Strings || SHOULD contain a list of the following, to indicate client-side support: [[#Optional: Long Polling|"longpoll"]], "coinbasetxn", "coinbasevalue", [[bip-0023.mediawiki#Block Proposal|"proposal"]], [[bip-0023.mediawiki#Logical Services|"serverlist"]], "workid", and any of the [[bip-0023.mediawiki#Mutations|mutations]]
| capabilities || No || Array of Strings || SHOULD contain a list of the following, to indicate client-side support: [[#optional-long-polling|"longpoll"]], "coinbasetxn", "coinbasevalue", [[bip-0023.mediawiki#block-proposal|"proposal"]], [[bip-0023.mediawiki#logical-services|"serverlist"]], "workid", and any of the [[bip-0023.mediawiki#mutations|mutations]]
|-
| mode || No || String || MUST be "template" or omitted
|}
@ -57,17 +55,17 @@ getblocktemplate MUST return a JSON Object containing the following keys:
|-
| sizelimit || No || Number || number of bytes allowed in blocks
|-
| transactions || Should || Array of Objects || Objects containing [[#Transactions Object Format|information for Bitcoin transactions]] (excluding coinbase)
| transactions || Should || Array of Objects || Objects containing [[#transactions-object-format|information for Bitcoin transactions]] (excluding coinbase)
|-
| version || Yes || Number || always 1 or 2 (at least for bitcoin) - clients MUST understand the implications of the version they use (eg, comply with [[bip-0034.mediawiki|BIP 0034]] for version 2)
|-
| coinbaseaux || No || Object || data that SHOULD be included in the coinbase's scriptSig content. Only the values (hexadecimal byte-for-byte) in this Object should be included, not the keys. This does not include the block height, which is required to be included in the scriptSig by [[bip-0034.mediawiki|BIP 0034]]. It is advisable to encode values inside "PUSH" opcodes, so as to not inadvertently expend SIGOPs (which are counted toward limits, despite not being executed).
|-
| coinbasetxn || this or ↓ || Object || [[#Transactions Object Format|information for coinbase transaction]]
| coinbasetxn || this or ↓ || Object || [[#transactions-object-format|information for coinbase transaction]]
|-
| coinbasevalue || this or ↑ || Number || total funds available for the coinbase (in Satoshis)
|-
| workid || No || String || if provided, this value must be returned with results (see [[#Block Submission|Block Submission]])
| workid || No || String || if provided, this value must be returned with results (see [[#block-submission|Block Submission]])
|}
==== Transactions Object Format ====

View File

@ -2,12 +2,10 @@
BIP: 23
Layer: API/RPC
Title: getblocktemplate - Pooled Mining
Author: Luke Dashjr <luke+bip22@dashjr.org>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0023
Status: Final
Type: Standards Track
Created: 2012-02-28
Authors: Luke Dashjr <luke+bip22@dashjr.org>
Status: Deployed
Type: Specification
Assigned: 2012-02-28
License: BSD-2-Clause
</pre>
@ -29,15 +27,15 @@ Something can be said to have BIP 23 Level 1 support if it implements at least:
* [http://www.ietf.org/rfc/rfc1945.txt RFC 1945]
* [http://json-rpc.org/wiki/specification JSON-RPC 1.0]
* [[bip-0022.mediawiki|BIP 22 (non-optional sections)]]
* [[bip-0022.mediawiki#Optional: Long Polling|BIP 22 Long Polling]]
* [[#Basic Pool Extensions|BIP 23 Basic Pool Extensions]]
* [[#Mutations|BIP 23 Mutation "coinbase/append"]]
* [[#Submission Abbreviation|BIP 23 Submission Abbreviation "submit/coinbase"]]
* [[#Mutations|BIP 23 Mutation "time/increment"]] (only required for servers)
* [[bip-0022.mediawiki#optional-long-polling|BIP 22 Long Polling]]
* [[#basic-pool-extensions|BIP 23 Basic Pool Extensions]]
* [[#mutations|BIP 23 Mutation "coinbase/append"]]
* [[#submission-abbreviation|BIP 23 Submission Abbreviation "submit/coinbase"]]
* [[#mutations|BIP 23 Mutation "time/increment"]] (only required for servers)
It can be said to have BIP 23 Level 2 support if it also implements:
* [[#Mutations|BIP 23 Mutation "transactions/add"]]
* [[#Block Proposals|BIP 23 Block Proposals]]
* [[#mutations|BIP 23 Mutation "transactions/add"]]
* [[#block-proposals|BIP 23 Block Proposals]]
===Basic Pool Extensions===

View File

@ -2,12 +2,10 @@
BIP: 30
Layer: Consensus (soft fork)
Title: Duplicate transactions
Author: Pieter Wuille <pieter.wuille@gmail.com>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0030
Status: Final
Type: Standards Track
Created: 2012-02-22
Authors: Pieter Wuille <pieter.wuille@gmail.com>
Status: Deployed
Type: Specification
Assigned: 2012-02-22
License: BSD-2-Clause
</pre>

View File

@ -2,12 +2,10 @@
BIP: 31
Layer: Peer Services
Title: Pong message
Author: Mike Hearn <hearn@google.com>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0031
Status: Final
Type: Standards Track
Created: 2012-04-11
Authors: Mike Hearn <hearn@google.com>
Status: Deployed
Type: Specification
Assigned: 2012-04-11
</pre>
==Abstract==

View File

@ -10,12 +10,10 @@ RECENT CHANGES:
BIP: 32
Layer: Applications
Title: Hierarchical Deterministic Wallets
Author: Pieter Wuille <pieter.wuille@gmail.com>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0032
Status: Final
Authors: Pieter Wuille <pieter.wuille@gmail.com>
Status: Deployed
Type: Informational
Created: 2012-02-11
Assigned: 2012-02-11
License: BSD-2-Clause
</pre>
@ -25,7 +23,7 @@ This document describes hierarchical deterministic wallets (or "HD Wallets"): wa
The specification is intended to set a standard for deterministic wallets that can be interchanged between different clients. Although the wallets described here have many features, not all are required by supporting clients.
The specification consists of two parts. In a first part, a system for deriving a tree of keypairs from a single seed is presented. The second part demonstrates how to build a wallet structure on top of such a tree.
The specification consists of two parts. In the first part, a system for deriving a tree of keypairs from a single seed is presented. The second part demonstrates how to build a wallet structure on top of such a tree.
==Copyright==
@ -37,7 +35,7 @@ The Bitcoin reference client uses randomly generated keys. In order to avoid the
Deterministic wallets do not require such frequent backups, and elliptic curve mathematics permit schemes where one can calculate the public keys without revealing the private keys. This permits for example a webshop business to let its webserver generate fresh addresses (public key hashes) for each order or for each customer, without giving the webserver access to the corresponding private keys (which are required for spending the received funds).
However, deterministic wallets typically consist of a single "chain" of keypairs. The fact that there is only one chain means that sharing a wallet happens on an all-or-nothing basis. However, in some cases one only wants some (public) keys to be shared and recoverable. In the example of a webshop, the webserver does not need access to all public keys of the merchant's wallet; only to those addresses which are used to receive customer's payments, and not for example the change addresses that are generated when the merchant spends money. Hierarchical deterministic wallets allow such selective sharing by supporting multiple keypair chains, derived from a single root.
However, deterministic wallets typically consist of a single "chain" of keypairs. The fact that there is only one chain means that sharing a wallet happens on an all-or-nothing basis. However, in some cases one only wants some (public) keys to be shared and recoverable. In the example of a webshop, the webserver does not need access to all public keys of the merchant's wallet; only to those addresses which are used to receive customers' payments, and not for example the change addresses that are generated when the merchant spends money. Hierarchical deterministic wallets allow such selective sharing by supporting multiple keypair chains, derived from a single root.
==Specification: Key derivation==
@ -52,10 +50,10 @@ Addition (+) of two coordinate pair is defined as application of the EC group op
Concatenation (||) is the operation of appending one byte sequence onto another.
As standard conversion functions, we assume:
* point(p): returns the coordinate pair resulting from EC point multiplication (repeated application of the EC group operation) of the secp256k1 base point with the integer p.
* point(p): returns the coordinate pair resulting from EC point multiplication (repeated application of the EC group operation) of the secp256k1 base point with the integer p (i.e., the operation used to compute a public key from a private key).
* ser<sub>32</sub>(i): serialize a 32-bit unsigned integer i as a 4-byte sequence, most significant byte first.
* ser<sub>256</sub>(p): serializes the integer p as a 32-byte sequence, most significant byte first.
* ser<sub>P</sub>(P): serializes the coordinate pair P = (x,y) as a byte sequence using SEC1's compressed form: (0x02 or 0x03) || ser<sub>256</sub>(x), where the header byte depends on the parity of the omitted y coordinate.
* ser<sub>P</sub>(P): serializes the coordinate pair P = (x,y) (i.e., the public key) as a byte sequence using [https://www.secg.org/sec1-v2.pdf SEC1]'s compressed form: (0x02 or 0x03) || ser<sub>256</sub>(x), where the header byte depends on the parity of the omitted y coordinate.
* parse<sub>256</sub>(p): interprets a 32-byte sequence as a 256-bit number, most significant byte first.
@ -104,7 +102,7 @@ The function N((k, c)) &rarr; (K, c) computes the extended public key correspond
To compute the public child key of a parent private key:
* N(CKDpriv((k<sub>par</sub>, c<sub>par</sub>), i)) (works always).
* CKDpub(N(k<sub>par</sub>, c<sub>par</sub>), i) (works only for non-hardened child keys).
The fact that they are equivalent is what makes non-hardened keys useful (one can derive child public keys of a given parent key without knowing any private key), and also what distinguishes them from hardened keys. The reason for not always using non-hardened keys (which are more useful) is security; see further for more information.
The fact that they are equivalent is what makes non-hardened keys useful (one can derive child public keys of a given parent key without knowing any private key), and also what distinguishes them from hardened keys. The reason for not always using non-hardened keys (which are more useful) is security; see further below for more information.
====Public parent key &rarr; private child key====
@ -130,14 +128,14 @@ The first 32 bits of the identifier are called the key fingerprint.
===Serialization format===
Extended public and private keys are serialized as follows:
* 4 byte: version bytes (mainnet: 0x0488B21E public, 0x0488ADE4 private; testnet: 0x043587CF public, 0x04358394 private)
* 4 bytes: version bytes (mainnet: 0x0488B21E public, 0x0488ADE4 private; testnet: 0x043587CF public, 0x04358394 private)
* 1 byte: depth: 0x00 for master nodes, 0x01 for level-1 derived keys, ....
* 4 bytes: the fingerprint of the parent's key (0x00000000 if master key)
* 4 bytes: child number. This is ser<sub>32</sub>(i) for i in x<sub>i</sub> = x<sub>par</sub>/i, with x<sub>i</sub> the key being serialized. (0x00000000 if master key)
* 32 bytes: the chain code
* 33 bytes: the public key or private key data (ser<sub>P</sub>(K) for public keys, 0x00 || ser<sub>256</sub>(k) for private keys)
This 78 byte structure can be encoded like other Bitcoin data in Base58, by first adding 32 checksum bits (derived from the double SHA-256 checksum), and then converting to the Base58 representation. This results in a Base58-encoded string of up to 112 characters. Because of the choice of the version bytes, the Base58 representation will start with "xprv" or "xpub" on mainnet, "tprv" or "tpub" on testnet.
This 78 byte structure can be encoded like other Bitcoin data in Base58, by first adding 32 checksum bits (derived from the double SHA-256 checksum), and then converting to the Base58 representation. This results in a Base58-encoded string of exactly 111 characters. Because of the choice of the version bytes, the Base58 representation will start with "xprv" or "xpub" on mainnet, "tprv" or "tpub" on testnet.
Note that the fingerprint of the parent only serves as a fast way to detect parent and child nodes in software, and software must be willing to deal with collisions. Internally, the full 160-bit identifier could be used.
@ -184,7 +182,7 @@ When a business has several independent offices, they can all use wallets derive
====Recurrent business-to-business transactions: N(m/i<sub>H</sub>/0)====
In case two business partners often transfer money, one can use the extended public key for the external chain of a specific account (M/i h/0) as a sort of "super address", allowing frequent transactions that cannot (easily) be associated, but without needing to request a new address for each payment.
Such a mechanism could also be used by mining pool operators as variable payout address.
Such a mechanism could also be used by mining pool operators as a variable payout address.
====Unsecure money receiver: N(m/i<sub>H</sub>/0)====
@ -212,7 +210,7 @@ Private and public keys must be kept safe as usual. Leaking a private key means
Somewhat more care must be taken regarding extended keys, as these correspond to an entire (sub)tree of keys.
One weakness that may not be immediately obvious, is that knowledge of a parent extended public key plus any non-hardened private key descending from it is equivalent to knowing the parent extended private key (and thus every private and public key descending from it). This means that extended public keys must be treated more carefully than regular public keys.
It is also the reason for the existence of hardened keys, and why they are used for the account level in the tree. This way, a leak of account-specific (or below) private key never risks compromising the master or other accounts.
It is also the reason for the existence of hardened keys, and why they are used for the account level in the tree. This way, a leak of account-specific (or below) private keys never risks compromising the master or other accounts.
==Test Vectors==

View File

@ -2,12 +2,10 @@
BIP: 33
Layer: Peer Services
Title: Stratized Nodes
Author: Amir Taaki <genjix@riseup.net>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0033
Status: Rejected
Type: Standards Track
Created: 2012-05-15
Authors: Amir Taaki <genjix@riseup.net>
Status: Closed
Type: Specification
Assigned: 2012-05-15
</pre>
== Abstract ==

View File

@ -2,12 +2,10 @@
BIP: 34
Layer: Consensus (soft fork)
Title: Block v2, Height in Coinbase
Author: Gavin Andresen <gavinandresen@gmail.com>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0034
Status: Final
Type: Standards Track
Created: 2012-07-06
Authors: Gavin Andresen <gavinandresen@gmail.com>
Status: Deployed
Type: Specification
Assigned: 2012-07-06
</pre>
==Abstract==

View File

@ -2,12 +2,10 @@
BIP: 35
Layer: Peer Services
Title: mempool message
Author: Jeff Garzik <jgarzik@exmulti.com>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0035
Status: Final
Type: Standards Track
Created: 2012-08-16
Authors: Jeff Garzik <jgarzik@exmulti.com>
Status: Deployed
Type: Specification
Assigned: 2012-08-16
</pre>
==Abstract==
@ -16,7 +14,7 @@ Make a network node's transaction memory pool accessible via a new "mempool" mes
==Motivation==
Several use cases make it desireable to expose a network node's transaction memory pool:
Several use cases make it desirable to expose a network node's transaction memory pool:
# SPV clients, wishing to obtain zero-confirmation transactions sent or received.
# Miners, to avoid missing lucrative fees, downloading existing network transactions after a restart.
# Remote network diagnostics.
@ -24,7 +22,7 @@ Several use cases make it desireable to expose a network node's transaction memo
==Specification==
# The mempool message is defined as an empty message where pchCommand == "mempool"
# Upon receipt of a "mempool" message, the node will respond with an "inv" message containing MSG_TX hashes of all the transactions in the node's transaction memory pool, if any.
# Upon receipt of a "mempool" message, the node will respond with an "inv" message containing MSG_TX hashes of all the transactions in the node's transaction memory pool, if any.
# The typical node behavior in response to an "inv" is "getdata". However, the reference Satoshi implementation ignores requests for transaction hashes outside that which is recently relayed. To support "mempool", an implementation must extend its "getdata" message support to querying the memory pool.
# Feature discovery is enabled by checking two "version" message attributes:
## Protocol version >= 60002

View File

@ -2,12 +2,10 @@
BIP: 36
Layer: Peer Services
Title: Custom Services
Author: Stefan Thomas <justmoon@members.fsf.org>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0036
Status: Rejected
Type: Standards Track
Created: 2012-08-03
Authors: Stefan Thomas <justmoon@members.fsf.org>
Status: Closed
Type: Specification
Assigned: 2012-08-03
License: PD
</pre>
@ -26,7 +24,7 @@ Two new fields are added to the <code>version</code> command, after <code>extra_
{|class="wikitable"
! Field Size !! Description !! Data type !! Comments
|-
| 1+ || service_count || [[Protocol_specification#Variable_length_integer|var_int]] || Number of extra services
| 1+ || service_count || [[Protocol_specification#variable-length-integer|var_int]] || Number of extra services
|-
| ? || service_list || service[] || List of service definitions
|}
@ -36,11 +34,11 @@ The service definitions <code>service[]</code> are given in the following format
{|class="wikitable"
! Field Size !! Description !! Data type !! Comments
|-
| ? || service_name || [[#Variable length string|var_str]] || Unique service identifier
| ? || service_name || [[#variable-length-string|var_str]] || Unique service identifier
|-
| 4 || service_version || uint32_t || Identifies service version being used by the node
|-
| ? || service_data || [[#Variable length string|var_str]] || Additional service-specific data
| ? || service_data || [[#variable-length-string|var_str]] || Additional service-specific data
|}
A node MUST NOT announce two services with the same <code>service_name</code>. If a remote node sends such a <code>version</code> message the client MAY disconnect.

View File

@ -2,13 +2,13 @@
BIP: 37
Layer: Peer Services
Title: Connection Bloom filtering
Author: Mike Hearn <hearn@google.com>
Matt Corallo <bip37@bluematt.me>
Authors: Mike Hearn <hearn@google.com>
Matt Corallo <bip37@bluematt.me>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0037
Status: Final
Type: Standards Track
Created: 2012-10-24
Status: Deployed
Type: Specification
Assigned: 2012-10-24
License: PD
</pre>
@ -159,7 +159,7 @@ A ''Merkle tree'' is a way of arranging a set of items as leaf nodes of tree in
** Check whether this node corresponds to a leaf node (transaction) that is to be included OR any parent thereof:
*** If so, append a '1' bit to the flag bits
*** Otherwise, append a '0' bit.
** Check whether this node is a internal node (non-leaf) AND is the parent of an included leaf node:
** Check whether this node is an internal node (non-leaf) AND is the parent of an included leaf node:
*** If so:
**** Descend into its left child node, and process the subtree beneath it entirely (depth-first).
**** If this node has a right child node too, descend into it as well.

View File

@ -2,13 +2,13 @@
BIP: 38
Layer: Applications
Title: Passphrase-protected private key
Author: Mike Caldwell <mcaldwell@swipeclock.com>
Aaron Voisine <voisine@gmail.com>
Authors: Mike Caldwell <mcaldwell@swipeclock.com>
Aaron Voisine <voisine@gmail.com>
Comments-Summary: Unanimously Discourage for implementation
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0038
Status: Draft (Some confusion applies: The announcements for this never made it to the list, so it hasn't had public discussion)
Type: Standards Track
Created: 2012-11-20
Status: Deployed
Type: Specification
Assigned: 2012-11-20
License: PD
</pre>
@ -36,10 +36,10 @@ Password and passphrase-protected private keys enable new practical use cases fo
This proposal is hereby placed in the public domain.
==Rationale==
:'''''User story:''' As a Bitcoin user who uses paper wallets, I would like the ability to add encryption, so that my Bitcoin paper storage can be two factor: something I have plus something I know.''
:'''''User story:''' As a Bitcoin user who would like to pay a person or a company with a private key, I do not want to worry that any part of the communication path may result in the interception of the key and theft of my funds. I would prefer to offer an encrypted private key, and then follow it up with the password using a different communication channel (e.g. a phone call or SMS).''
:'''''User story:''' (EC-multiplied keys) As a user of physical bitcoins, I would like a third party to be able to create password-protected Bitcoin private keys for me, without them knowing the password, so I can benefit from the physical bitcoin without the issuer having access to the private key. I would like to be able to choose a password whose minimum length and required format does not preclude me from memorizing it or engraving it on my physical bitcoin, without exposing me to an undue risk of password cracking and/or theft by the manufacturer of the item.''
:'''''User story:''' (EC multiplied keys) As a user of paper wallets, I would like the ability to generate a large number of Bitcoin addresses protected by the same password, while enjoying a high degree of security (highly expensive scrypt parameters), but without having to incur the scrypt delay for each address I generate.
:'' '''User story:''' As a Bitcoin user who uses paper wallets, I would like the ability to add encryption, so that my Bitcoin paper storage can be two factor: something I have plus something I know.''
:'' '''User story:''' As a Bitcoin user who would like to pay a person or a company with a private key, I do not want to worry that any part of the communication path may result in the interception of the key and theft of my funds. I would prefer to offer an encrypted private key, and then follow it up with the password using a different communication channel (e.g. a phone call or SMS).''
:'' '''User story:''' (EC-multiplied keys) As a user of physical bitcoins, I would like a third party to be able to create password-protected Bitcoin private keys for me, without them knowing the password, so I can benefit from the physical bitcoin without the issuer having access to the private key. I would like to be able to choose a password whose minimum length and required format does not preclude me from memorizing it or engraving it on my physical bitcoin, without exposing me to an undue risk of password cracking and/or theft by the manufacturer of the item.''
:'' '''User story:''' (EC-multiplied keys) As a user of paper wallets, I would like the ability to generate a large number of Bitcoin addresses protected by the same password, while enjoying a high degree of security (highly expensive scrypt parameters), but without having to incur the scrypt delay for each address I generate.''
==Specification==
This proposal makes use of the following functions and definitions:
@ -47,12 +47,12 @@ This proposal makes use of the following functions and definitions:
*'''AES256Encrypt, AES256Decrypt''': the simple form of the well-known AES block cipher without consideration for initialization vectors or block chaining. Each of these functions takes a 256-bit key and 16 bytes of input, and deterministically yields 16 bytes of output.
*'''SHA256''', a well-known hashing algorithm that takes an arbitrary number of bytes as input and deterministically yields a 32-byte hash.
*'''scrypt''': A well-known key derivation algorithm. It takes the following parameters: (string) password, (string) salt, (int) n, (int) r, (int) p, (int) length, and deterministically yields an array of bytes whose length is equal to the length parameter.
*'''ECMultiply''': Multiplication of an elliptic curve point by a scalar integer with respect to the [[secp256k1]] elliptic curve.
*'''G, N''': Constants defined as part of the [[secp256k1]] elliptic curve. G is an elliptic curve point, and N is a large positive integer.
*'''[[Base58Check]]''': a method for encoding arrays of bytes using 58 alphanumeric characters commonly used in the Bitcoin ecosystem.
*'''ECMultiply''': Multiplication of an elliptic curve point by a scalar integer with respect to the secp256k1 elliptic curve.
*'''G, N''': Constants defined as part of the secp256k1 elliptic curve. G is an elliptic curve point, and N is a large positive integer.
*'''Base58Check''': a method for encoding arrays of bytes using 58 alphanumeric characters commonly used in the Bitcoin ecosystem.
===Prefix===
It is proposed that the resulting Base58Check-encoded string start with a '6'. The number '6' is intended to represent, from the perspective of the user, "a private key that needs something else to be usable" - an umbrella definition that could be understood in the future to include keys participating in multisig transactions, and was chosen with deference to the existing prefix '5' most commonly observed in [[Wallet Import Format]] which denotes an unencrypted private key.
It is proposed that the resulting Base58Check-encoded string start with a '6'. The number '6' is intended to represent, from the perspective of the user, "a private key that needs something else to be usable" - an umbrella definition that could be understood in the future to include keys participating in multisig transactions, and was chosen with deference to the existing prefix '5' most commonly observed in Wallet Import Format which denotes an unencrypted private key.
It is proposed that the second character ought to give a hint as to what is needed as a second factor, and for an encrypted key requiring a passphrase, the uppercase letter P is proposed.
@ -64,7 +64,7 @@ To keep the size of the encrypted key down, no initialization vectors (IVs) are
* How the user sees it: 58 characters always starting with '6P'
** Visual cues are present in the third character for visually identifying the EC-multiply and compress flag.
* Count of payload bytes (beyond prefix): 37
** 1 byte (''flagbyte''):
** 1 byte (''flagbyte''):
*** the most significant two bits are set as follows to preserve the visibility of the compression flag in the prefix, as well as to keep the payload within the range of allowable values that keep the "6P" prefix intact. For non-EC-multiplied keys, the bits are 11. For EC-multiplied keys, the bits are 00.
*** the bit with value 0x20 when set indicates the key should be converted to a base58check encoded P2PKH bitcoin address using the DER compressed public key format. When not set, it should be a base58check encoded P2PKH bitcoin address using the DER uncompressed public key format.
*** the bits with values 0x10 and 0x08 are reserved for a future specification that contemplates using multisig as a way to combine the factors such that parties in possession of the separate factors can independently sign a proposed transaction without requiring that any party possess both factors. These bits must be 0 to comply with this version of the specification.
@ -75,10 +75,10 @@ To keep the size of the encrypted key down, no initialization vectors (IVs) are
**16 bytes: lasthalf: An AES-encrypted key material record (contents depend on whether EC multiplication is used)
* Range in base58check encoding for non-EC-multiplied keys without compression (prefix 6PR):
** Minimum value: 6PRHv1jg1ytiE4kT2QtrUz8gEjMQghZDWg1FuxjdYDzjUkcJeGdFj9q9Vi (based on 01 42 C0 plus thirty-six 00's)
** Maximum value: 6PRWdmoT1ZursVcr5NiD14p5bHrKVGPG7yeEoEeRb8FVaqYSHnZTLEbYsU (based on 01 42 C0 plus thirty-six FF's)
** Maximum value: 6PRWdmoT1ZursVcr5NiD14p5bHrKVGPG7yeEoEeRb8FVaqYSHnZTLEbYsU (based on 01 42 C0 plus thirty-six FF's)
* Range in base58check encoding for non-EC-multiplied keys with compression (prefix 6PY):
** Minimum value: 6PYJxKpVnkXUsnZAfD2B5ZsZafJYNp4ezQQeCjs39494qUUXLnXijLx6LG (based on 01 42 E0 plus thirty-six 00's)
** Maximum value: 6PYXg5tGnLYdXDRZiAqXbeYxwDoTBNthbi3d61mqBxPpwZQezJTvQHsCnk (based on 01 42 E0 plus thirty-six FF's)
** Maximum value: 6PYXg5tGnLYdXDRZiAqXbeYxwDoTBNthbi3d61mqBxPpwZQezJTvQHsCnk (based on 01 42 E0 plus thirty-six FF's)
* Range in base58check encoding for EC-multiplied keys without compression (prefix 6Pf):
** Minimum value: 6PfKzduKZXAFXWMtJ19Vg9cSvbFg4va6U8p2VWzSjtHQCCLk3JSBpUvfpf (based on 01 43 00 plus thirty-six 00's)
** Maximum value: 6PfYiPy6Z7BQAwEHLxxrCEHrH9kasVQ95ST1NnuEnnYAJHGsgpNPQ9dTHc (based on 01 43 00 plus thirty-six FF's)
@ -170,7 +170,7 @@ To recalculate the address:
# Derive ''passfactor'' using scrypt with ''ownerentropy'' and the user's passphrase and use it to recompute ''passpoint''
# Derive decryption key for ''pointb'' using scrypt with ''passpoint'', ''addresshash'', and ''ownerentropy''
# Decrypt ''encryptedpointb'' to yield ''pointb''
# ECMultiply ''pointb'' by ''passfactor''. Use the resulting EC point as a public key and hash it into ''address'' using either compressed or uncompressed public key methodology as specifid in ''flagbyte''.
# ECMultiply ''pointb'' by ''passfactor''. Use the resulting EC point as a public key and hash it into ''address'' using either compressed or uncompressed public key methodology as specified in ''flagbyte''.
=====Decryption=====
# Collect encrypted private key and passphrase from user.
@ -184,7 +184,7 @@ To recalculate the address:
# Hash the Bitcoin address, and verify that ''addresshash'' from the encrypted private key record matches the hash. If not, report that the passphrase entry was incorrect.
==Backwards compatibility==
Backwards compatibility is minimally applicable since this is a new standard that at most extends [[Wallet Import Format]]. It is assumed that an entry point for private key data may also accept existing formats of private keys (such as hexadecimal and [[Wallet Import Format]]); this draft uses a key format that cannot be mistaken for any existing one and preserves auto-detection capabilities.
Backwards compatibility is minimally applicable since this is a new standard that at most extends Wallet Import Format. It is assumed that an entry point for private key data may also accept existing formats of private keys (such as hexadecimal and Wallet Import Format); this draft uses a key format that cannot be mistaken for any existing one and preserves auto-detection capabilities.
==Suggestions for implementers of proposal with alt-chains==
If this proposal is accepted into alt-chains, it is requested that the unused flag bytes not be used for denoting that the key belongs to an alt-chain.
@ -209,14 +209,10 @@ The preliminary values of 16384, 8, and 8 are hoped to offer the following prope
==Reference implementation==
Added to alpha version of Casascius Bitcoin Address Utility for Windows available at:
* via https: https://casascius.com/btcaddress-alpha.zip
* at github: https://github.com/casascius/Bitcoin-Address-Utility
* https://github.com/casascius/Bitcoin-Address-Utility
Click "Tools" then "PPEC Keygen" (provisional name)
==Other implementations==
* Javascript - https://github.com/bitcoinjs/bip38
==Test vectors==
===No compression, no EC multiply===
@ -276,7 +272,7 @@ Test 2:
Test 1:
*Passphrase: MOLON LABE
*Passphrase code: passphraseaB8feaLQDENqCgr4gKZpmf4VoaT6qdjJNJiv7fsKvjqavcJxvuR1hy25aTu5sX
*Passphrase code: passphraseaB8feaLQDENqCgr4gKZpmf4VoaT6qdjJNJiv7fsKvjqavcJxvuR1hy25aTu5sX
*Encrypted key: 6PgNBNNzDkKdhkT6uJntUXwwzQV8Rr2tZcbkDcuC9DZRsS6AtHts4Ypo1j
*Bitcoin address: 1Jscj8ALrYu2y9TD8NrpvDBugPedmbj4Yh
*Unencrypted private key (WIF): 5JLdxTtcTHcfYcmJsNVy1v2PMDx432JPoYcBTVVRHpPaxUrdtf8
@ -284,9 +280,9 @@ Test 1:
*Confirmation code: cfrm38V8aXBn7JWA1ESmFMUn6erxeBGZGAxJPY4e36S9QWkzZKtaVqLNMgnifETYw7BPwWC9aPD
*Lot/Sequence: 263183/1
Test 2:
Test 2:
*Passphrase (all letters are Greek - test UTF-8 compatibility with this): ΜΟΛΩΝ ΛΑΒΕ
*Passphrase code: passphrased3z9rQJHSyBkNBwTRPkUGNVEVrUAcfAXDyRU1V28ie6hNFbqDwbFBvsTK7yWVK
*Passphrase code: passphrased3z9rQJHSyBkNBwTRPkUGNVEVrUAcfAXDyRU1V28ie6hNFbqDwbFBvsTK7yWVK
*Encrypted private key: 6PgGWtx25kUg8QWvwuJAgorN6k9FbE25rv5dMRwu5SKMnfpfVe5mar2ngH
*Bitcoin address: 1Lurmih3KruL4xDB5FmHof38yawNtP9oGf
*Unencrypted private key (WIF): 5KMKKuUmAkiNbA3DazMQiLfDq47qs8MAEThm4yL8R2PhV1ov33D

View File

@ -2,15 +2,16 @@
BIP: 39
Layer: Applications
Title: Mnemonic code for generating deterministic keys
Author: Marek Palatinus <slush@satoshilabs.com>
Pavol Rusnak <stick@satoshilabs.com>
Aaron Voisine <voisine@gmail.com>
Sean Bowe <ewillbefull@gmail.com>
Authors: Marek Palatinus <slush@satoshilabs.com>
Pavol Rusnak <stick@satoshilabs.com>
Aaron Voisine <voisine@gmail.com>
Sean Bowe <ewillbefull@gmail.com>
Comments-Summary: Unanimously Discourage for implementation
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0039
Status: Proposed
Type: Standards Track
Created: 2013-09-10
Status: Deployed
Type: Specification
Assigned: 2013-09-10
License: MIT
</pre>
==Abstract==
@ -22,6 +23,10 @@ It consists of two parts: generating the mnemonic and converting it into a
binary seed. This seed can be later used to generate deterministic wallets using
BIP-0032 or similar methods.
==Copyright==
This BIP falls under the MIT License.
==Motivation==
A mnemonic code or sentence is superior for human interaction compared to the
@ -138,69 +143,3 @@ Also see https://github.com/bip32JP/bip32JP.github.io/blob/master/test_JP_BIP39.
Reference implementation including wordlists is available from
http://github.com/trezor/python-mnemonic
==Other Implementations==
Go:
* https://github.com/tyler-smith/go-bip39
Python:
* https://github.com/meherett/python-hdwallet
Elixir:
* https://github.com/aerosol/mnemo
Objective-C:
* https://github.com/nybex/NYMnemonic
Haskell:
* https://github.com/haskoin/haskoin
.NET (Standard):
* https://www.nuget.org/packages/dotnetstandard-bip39/
.NET C# (PCL):
* https://github.com/Thashiznets/BIP39.NET
.NET C# (PCL):
* https://github.com/NicolasDorier/NBitcoin
JavaScript:
* https://github.com/bitpay/bitcore/tree/master/packages/bitcore-mnemonic
* https://github.com/bitcoinjs/bip39 (used by [[https://github.com/blockchain/My-Wallet-V3/blob/v3.8.0/src/hd-wallet.js#L121-L146|blockchain.info]])
* https://github.com/dashhive/DashPhrase.js
* https://github.com/hujiulong/web-bip39
Java:
* https://github.com/bitcoinj/bitcoinj/blob/master/core/src/main/java/org/bitcoinj/crypto/MnemonicCode.java
Ruby:
* https://github.com/sreekanthgs/bip_mnemonic
Rust:
* https://github.com/maciejhirsz/tiny-bip39/
* https://github.com/koushiro/bip0039-rs
Smalltalk:
* https://github.com/eMaringolo/pharo-bip39mnemonic
Swift:
* https://github.com/CikeQiu/CKMnemonic
* https://github.com/yuzushioh/WalletKit
* https://github.com/pengpengliu/BIP39
* https://github.com/matter-labs/web3swift/blob/develop/Sources/web3swift/KeystoreManager/BIP39.swift
* https://github.com/zcash-hackworks/MnemonicSwift
* https://github.com/ShenghaiWang/BIP39
* https://github.com/anquii/BIP39
C++:
* https://github.com/libbitcoin/libbitcoin-system/blob/master/include/bitcoin/system/wallet/mnemonic.hpp
C (with Python/Java/Javascript bindings):
* https://github.com/ElementsProject/libwally-core
Python:
* https://github.com/scgbckbone/btc-hd-wallet
Dart:
* https://github.com/dart-bitcoin/bip39

View File

@ -28,7 +28,7 @@ for two smaller words (This would be a problem with any of the 3 character sets
### Spanish
1. Words can be uniquely determined typing the first 4 characters (sometimes less).
1. Words can be uniquely determined by typing the first 4 characters (sometimes less).
2. Special Spanish characters like 'ñ', 'ü', 'á', etc... are considered equal to 'n', 'u', 'a', etc... in terms of identifying a word. Therefore, there is no need to use a Spanish keyboard to introduce the passphrase, an application with the Spanish wordlist will be able to identify the words after the first 4 chars have been typed even if the chars with accents have been replaced with the equivalent without accents.
@ -50,10 +50,10 @@ Credits: @Kirvx @NicolasDorier @ecdsa @EricLarch
4. Only infinitive verbs, adjectives and nouns.
5. No pronouns, no adverbs, no prepositions, no conjunctions, no interjections (unless a noun/adjective is also popular than its interjection like "mince;chouette").
6. No numeral adjectives.
7. No words in the plural (except invariable words like "univers", or same spelling than singular like "heureux").
7. No words in the plural (except invariable words like "univers", or same spelling as singular like "heureux").
8. No female adjectives (except words with same spelling for male and female adjectives like "magique").
9. No words with several senses AND different spelling in speaking like "verre-vert", unless a word has a meaning much more popular than another like "perle" and "pairle".
10. No very similar words with 1 letter of difference.
10. No very similar words with only 1 letter of difference.
11. No essentially reflexive verbs (unless a verb is also a noun like "souvenir").
12. No words with "ô;â;ç;ê;œ;æ;î;ï;û;ù;à;ë;ÿ".
13. No words ending by "é;ée;è;et;ai;ait".
@ -76,7 +76,7 @@ Words chosen using the following rules:
6. No plural words.
7. No words that remind negative/sad/bad things.
8. If both female/male words are available, choose male version.
9. No words with double vocals (like: lineetta).
9. No words with double vowels (like: lineetta).
10. No words already used in other language mnemonic sets.
11. If 3 of the first 4 letters are already used in the same sequence in another mnemonic word, there must be at least other 3 different letters.
12. If 3 of the first 4 letters are already used in the same sequence in another mnemonic word, there must not be the same sequence of 3 or more letters.
@ -92,26 +92,26 @@ Credits: @zizelevak (Jan Lansky zizelevak@gmail.com)
Words chosen using the following rules:
1. Words are 4-8 letters long.
2. Words can be uniquely determined typing the first 4 letters.
3. Only words containing all letters without diacritical marks. (It was the hardest task, because in one third of all Czech letters has diacritical marks.)
2. Words can be uniquely determined by typing the first 4 letters.
3. Only words containing all letters without diacritical marks. (It was the hardest task, because one third of all Czech letters has diacritical marks.)
4. Only nouns, verbs and adverbs, no other word types. All words are in basic form.
5. No personal names or geographical names.
6. No very similar words with 1 letter of difference.
7. Words are sorting according English alphabet (Czech sorting has difference in "ch").
8. No words already used in other language mnemonic sets (english, italian, french, spanish). Letters with diacritical marks from these sets are counted as analogous letters without diacritical marks.
7. Words are sorted according to English alphabet (Czech sorting has difference in "ch").
8. No words already used in other language mnemonic sets (english, italian, french, spanish). Letters with diacritical marks from these sets are counted as analogous letters without diacritical marks.
### Portuguese
Credits: @alegotardo @bitmover-studio @brenorb @kuthullu @ninjastic @sabotag3x @Trimegistus
1. Words can be uniquely determined typing the first 4 characters.
1. Words can be uniquely determined by typing the first 4 characters.
2. No accents or special characters.
3. No complex verb forms.
4. No plural words, unless there's no singular form.
5. No words with double spelling.
6. No words with the exact sound of another word with different spelling.
6. No words with the exact sound as another word with different spelling.
7. No offensive words.
8. No words already used in other language mnemonic sets.
9. The words which have not the same spelling in Brazil and in Portugal are excluded.
10. No words that remind negative/sad/bad things.
11. No very similar words with 1 letter of difference.
10. No words that remind one of negative/sad/bad things.
11. No very similar words with only 1 letter of difference.

View File

@ -2,20 +2,20 @@
BIP: 42
Layer: Consensus (soft fork)
Title: A finite monetary supply for Bitcoin
Author: Pieter Wuille <pieter.wuille@gmail.com>
Authors: Pieter Wuille <pieter.wuille@gmail.com>
Comments-Summary: Unanimously Recommended for implementation
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0042
Status: Final
Type: Standards Track
Created: 2014-04-01
Status: Deployed
Type: Specification
Assigned: 2014-04-01
License: PD
</pre>
==Abstract==
Although it is widely believed that Satoshi was an inflation-hating goldbug he never said this, and in fact programmed Bitcoin's money supply to grow indefinitely, forever. He modeled the monetary supply as 4 gold mines being discovered per mibillenium (1024 years), with equal intervals between them, each one being depleted over the course of 140 years.
Although it is widely believed that Satoshi was an inflation-hating goldbug he never said this, and in fact programmed Bitcoin's money supply to grow indefinitely, forever. He modeled the monetary supply as 4 gold mines being discovered per mibillennium (1024 years), with equal intervals between them, each one being depleted over the course of 140 years.
This poses obvious problems, however. Prominent among them is the discussion on what to call 1 billion Bitcoin, which symbol color to use for it, and when wallet clients should switch to it by default.
This poses obvious problems, however. Prominent among them is the discussion on what to call 1 billion bitcoin, which symbol color to use for it, and when wallet clients should switch to it by default.
To combat this, this document proposes a controversial change: making Bitcoin's monetary supply finite.
@ -42,7 +42,7 @@ Note that several other programming languages do not exhibit this behaviour, mak
===Floating-point approximation===
An obvious solution would be to reimplement the shape of the subsidy curve using floating-point approximations, such as simulated annealing or quantitative easing, which have already proven their worth in consensus systems. Unfortunately, since the financial crisis everyone considers numbers with decimal points in them fishy, and integers are not well supported by Javascript.
An obvious solution would be to reimplement the shape of the subsidy curve using floating-point approximations, such as simulated annealing or quantitative easing, which have already proven their worth in consensus systems. Unfortunately, since the financial crisis everyone considers numbers with decimal points in them fishy, and integers are not well supported by Javascript.
===Truncation===

View File

@ -2,13 +2,11 @@
BIP: 43
Layer: Applications
Title: Purpose Field for Deterministic Wallets
Author: Marek Palatinus <slush@satoshilabs.com>
Pavol Rusnak <stick@satoshilabs.com>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0043
Status: Final
Type: Informational
Created: 2014-04-24
Authors: Marek Palatinus <slush@satoshilabs.com>
Pavol Rusnak <stick@satoshilabs.com>
Status: Deployed
Type: Specification
Assigned: 2014-04-24
</pre>
==Abstract==
@ -20,7 +18,7 @@ based on algorithm described in BIP-0032 (BIP32 from now on).
Although Hierarchical Deterministic Wallet structure as described by BIP32
is an important step in user experience and security of the cryptocoin wallets,
the BIP32 specification offers implementors too many degrees of freedom.
the BIP32 specification offers implementers too many degrees of freedom.
Multiple implementations may claim they are BIP32 compatible, but in fact
they can produce wallets with different logical structures making them
non-interoperable. This situation unfortunately renders "BIP32 compatible"

View File

@ -2,13 +2,14 @@
BIP: 44
Layer: Applications
Title: Multi-Account Hierarchy for Deterministic Wallets
Author: Marek Palatinus <slush@satoshilabs.com>
Pavol Rusnak <stick@satoshilabs.com>
Authors: Marek Palatinus <slush@satoshilabs.com>
Pavol Rusnak <stick@satoshilabs.com>
Comments-Summary: Mixed review (one person)
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0044
Status: Proposed
Type: Standards Track
Created: 2014-04-24
Status: Deployed
Type: Specification
Assigned: 2014-04-24
Requires: 32, 43
</pre>
==Abstract==

View File

@ -2,14 +2,12 @@
BIP: 45
Layer: Applications
Title: Structure for Deterministic P2SH Multisignature Wallets
Author: Manuel Araoz <manu@bitpay.com>
Ryan X. Charles <ryan@bitpay.com>
Matias Alejo Garcia <matias@bitpay.com>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0045
Status: Proposed
Type: Standards Track
Created: 2014-04-25
Authors: Manuel Araoz <manu@bitpay.com>
Ryan X. Charles <ryan@bitpay.com>
Matias Alejo Garcia <matias@bitpay.com>
Status: Complete
Type: Specification
Assigned: 2014-04-25
</pre>
==Abstract==

192
bip-0046.mediawiki Normal file
View File

@ -0,0 +1,192 @@
<pre>
BIP: 46
Layer: Applications
Title: Address Scheme for Timelocked Fidelity Bonds
Authors: Chris Belcher <belcher@riseup.net>
Thebora Kompanioni <theborakompanioni+bip46@gmail.com>
Status: Draft
Type: Specification
Assigned: 2022-04-01
License: CC0-1.0
Discussion: 2022-05-01: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-May/020389.html
</pre>
== Abstract ==
This BIP defines the derivation scheme for HD wallets which create timelocked addresses used for creating fidelity bonds. It also gives advice to wallet developers on how to use fidelity bonds to sign over messages, such as certificates, which are needed when using fidelity bonds that are stored offline.
== Copyright ==
This document is licensed under the Creative Commons CC0 1.0 Universal license.
== Motivation ==
Fidelity bonds are used to resist sybil attacks in certain decentralized anonymous protocols. They are created by locking up bitcoins using the `OP_CHECKLOCKTIMEVERIFY` opcode.
Having a common derivation scheme allows users of wallet software to have a backup of their fidelity bonds by storing only the HD seed and a reference to this BIP. Importantly the user does not need to backup any timelock values.
We largely use the same approach used in BIPs 49, 84 and 86 for ease of implementation.
This allows keeping the private keys of fidelity bonds in cold storage, which increases the sybil resistance of a system without hot wallet risk.
== Backwards Compatibility ==
This BIP is not backwards compatible by design as described in the Considerations section of [[bip-0049.mediawiki|BIP 49]]. An incompatible wallet will not discover fidelity bonds at all and the user will notice that something is wrong.
== Background ==
=== Fidelity bonds ===
A fidelity bond is a mechanism where bitcoin value is deliberately sacrificed to make a cryptographic identity expensive to obtain. A way to create a fidelity bond is to lock up bitcoins by sending them to a timelocked address. The valuable thing being sacrificed is the time-value-of-money.
The sacrifice must be done in a way that can be proven to a third party. This proof can be made by showing the UTXO outpoint, the address redeemscript and a signature which signs a message using the private key corresponding to the public key in the redeemscript.
The sacrificed value is an objective measurement that can't be faked and which can be verified by anybody (just like, for example PoW mining). Sybil attacks can be made very expensive by forcing a hypothetical sybil attacker to lock up many bitcoins for a long time. JoinMarket implements fidelity bonds for protection from sybil attackers. At the time of writing over 600 BTC in total have been locked up with some for many years. Their UTXOs and signatures have been advertised to the world as proof. We can calculate that for a sybil attacker to succeed in unmixing all the CoinJoins, they would have to lock up over 100k BTC for several years.
=== Fidelity bonds in cold storage ===
To allow for holding fidelity bonds in cold storage, there is an intermediate keypair called the certificate.
UTXO key ---signs---> certificate ---signs---> endpoint
Where the endpoint might be a IRC nickname or Tor onion hostname. The certificate keypair can be kept online and used to prove ownership of the fidelity bond. Even if the hot wallet private keys are stolen, the coins in the timelocked address will still be safe, although the thief will be able to impersonate the fidelity bond until the expiry.
== Rationale ==
It is useful for the user to avoid having to keep a record of the timelocks in the time-locked addresses. So only a limited small set of timelocks are defined by this BIP. This way the user must only store their seed phrase, and knowledge that they have coins stored using this BIP standard. The user doesn't need to remember or store any dates.
This standard is already implemented and deployed in JoinMarket. As most changes would require a protocol change of a live system, there is limited scope for changing this standard in review. This BIP is more about documenting something which already exists, warts and all.
== Specifications ==
This BIP defines the two needed steps to derive multiple deterministic addresses based on a [[bip-0032.mediawiki|BIP 32]] master private key. It also defines the format of the certificate that can be signed by the deterministic address key.
=== Public key derivation ===
To derive a public key from the root account, this BIP uses a similar account-structure as defined in BIP [[bip-0084.mediawiki|44]] but with <tt>change</tt> set to <tt>2</tt>.
<pre>
m / 84' / 0' / 0' / 2 / index
</pre>
A key derived with this derivation path pattern will be referred to as <tt>derived_key</tt> further
in this document.
For <tt>index</tt>, addresses are numbered from 0 in a sequentially increasing manner with a fixed upper bound: The index only goes up to <tt>959</tt> inclusive. Only 960 addresses can be derived for a given BIP32 master key. Furthermore there is no concept of a gap limit, instead wallets must always generate all 960 addresses and check for all of them if they have a balance and history.
=== Timelock derivation ===
The timelock used in the time-locked address is derived from the <tt>index</tt>. The timelock is a unix time. It is always at the start of the first second at the beginning of the month (see [[#test-vectors|Test vectors]]). The <tt>index</tt> counts upwards the months from January 2020, ending in December 2099. At 12 months per year for 80 years this totals 960 timelocks. Note that care must be taken with the year 2038 problem on 32-bit systems.
<pre>
year = 2020 + index // 12
month = 1 + index % 12
</pre>
=== Address derivation ===
To derive the address from the above calculated public key and timelock, we create a <tt>witness script</tt> which locks the funds until the <tt>timelock</tt>, and then checks the signature of the <tt>derived_key</tt>. The <tt>witness script</tt> is hashed with SHA256 to produce a 32-byte hash value that forms the <tt>witness program</tt> in the output script of the P2WSH address.
witnessScript: <timelock> OP_CHECKLOCKTIMEVERIFY OP_DROP <derived_key> OP_CHECKSIG
witness: <signature> <witnessScript>
scriptSig: (empty)
scriptPubKey: 0 <32-byte-hash>
(0x0020{32-byte-hash})
=== Message signing ===
In order to support signing of certificates, implementers should support signing ASCII messages.
The certificate message is defined as `"fidelity-bond-cert" || "|" || cert_pubkey || "|" || cert_expiry`.
The certificate expiry `cert_expiry` is the number of the 2016-block period after which the certificate is no longer valid. For example, if `cert_expiry` is 330 then the certificate will become invalid after block height 665280 (:=330x2016). The purpose of the expiry parameter is so that in case the certificate keypair is compromised, the attacker can only impersonate the fidelity bond for a limited amount of time.
A certificate message can be created by another application external to this standard. It is then prepended with the string `0x18 || "Bitcoin Signed Message:\n"` and a byte denoting the length of the certificate message. The whole thing is then signed with the private key of the <tt>derived_key</tt>. This part is identical to the "Sign Message" function which many wallets already implement.
Almost all wallets implementing this standard can use their already-existing "Sign Message" function to sign the certificate message. As the certificate message itself is always an ASCII string, the wallet may not need to specially implement this section at all but just rely on users copypasting their certificate message into the already-existing "Sign Message" user interface. This works as long as the wallet knows how to use the private key of the timelocked address for signing messages.
It is most important for wallet implementations of this standard to support creating the certificate signature. Verifying the certificate signature is less important.
== Test vectors ==
<pre>
mnemonic = abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about
rootpriv = xprv9s21ZrQH143K3GJpoapnV8SFfukcVBSfeCficPSGfubmSFDxo1kuHnLisriDvSnRRuL2Qrg5ggqHKNVpxR86QEC8w35uxmGoggxtQTPvfUu
rootpub = xpub661MyMwAqRbcFkPHucMnrGNzDwb6teAX1RbKQmqtEF8kK3Z7LZ59qafCjB9eCRLiTVG3uxBxgKvRgbubRhqSKXnGGb1aoaqLrpMBDrVxga8
// First timelocked address = m/84'/0'/0'/2/0
derived private_key = L2tQBEdhC48YLeEWNg3e4msk94iKfyVa9hdfzRwUERabZ53TfH3d
derived public_key = 02a1b09f93073c63f205086440898141c0c3c6d24f69a18db608224bcf143fa011
unix locktime = 1577836800
string locktime = 2020-01-01 00:00:00
redeemscript = 0400e10b5eb1752102a1b09f93073c63f205086440898141c0c3c6d24f69a18db608224bcf143fa011ac
scriptPubKey = 0020bdee9515359fc9df912318523b4cd22f1c0b5410232dc943be73f9f4f07e39ad
address = bc1qhhhf29f4nlyalyfrrpfrknxj9uwqk4qsyvkujsa7w0ulfur78xkspsqn84
// Test certificate using the first timelocked address
// Note that as signatures contains a random nonce, it might not be exactly the same when your code generates it
// p2pkh address is the p2pkh address corresponding to the derived public key, it can be used to verify the message
// signature in any wallet that supports Verify Message.
// As mentioned before, it is more important for implementers of this standard to support signing such messages, not verifying them
message = fidelity-bond-cert|020000000000000000000000000000000000000000000000000000000000000001|375
address = bc1qhhhf29f4nlyalyfrrpfrknxj9uwqk4qsyvkujsa7w0ulfur78xkspsqn84
p2pkh address = 16vmiGpY1rEaYnpGgtG7FZgr2uFCpeDgV6
signature = H2b/90XcKnIU/D1nSCPhk8OcxrHebMCr4Ok2d2yDnbKDTSThNsNKA64CT4v2kt+xA1JmGRG/dMnUUH1kKqCVSHo=
// 2nd timelocked address = m/84'/0'/0'/2/1
derived private_key = KxctaFBzetyc9KXeUr6jxESCZiCEXRuwnQMw7h7hroP6MqnWN6Pf
derived public_key = 02599f6db8b33265a44200fef0be79c927398ed0b46c6a82fa6ddaa5be2714002d
unix locktime = 1580515200
string locktime = 2020-02-01 00:00:00
redeemscript = 0480bf345eb1752102599f6db8b33265a44200fef0be79c927398ed0b46c6a82fa6ddaa5be2714002dac
scriptPubKey = 0020b8f898643991608524ed04e0c6779f632a57f1ffa3a3a306cd81432c5533e9ae
address = bc1qhrufsepej9sg2f8dqnsvvaulvv490u0l5w36xpkds9pjc4fnaxhq7pcm4h
// timelocked address after the year 2038 = m/84'/0'/0'/2/240
derived private_key = L3SYqae23ZoDDcyEA8rRBK83h1MDqxaDG57imMc9FUx1J8o9anQe
derived public_key = 03ec8067418537bbb52d5d3e64e2868e67635c33cfeadeb9a46199f89ebfaab226
unix locktime = 2208988800
string locktime = 2040-01-01 00:00:00
redeemscript = 05807eaa8300b1752103ec8067418537bbb52d5d3e64e2868e67635c33cfeadeb9a46199f89ebfaab226ac
scriptPubKey = 0020e7de0ad2720ae1d6cc9b6ad91af57eb74646762cf594c91c18f6d5e7a873635a
address = bc1qul0q45njptsadnymdtv34at7karyva3v7k2vj8qc7m2702rnvddq0z20u5
// last timelocked address = m/84'/0'/0'/2/959
derived private_key = L5Z9DDMnj5RZMyyPiQLCvN48Xt7GGmev6cjvJXD8uz5EqiY8trNJ
derived public_key = 0308c5751121b1ae5c973cdc7071312f6fc10ab864262f0cbd8134f056166e50f3
unix locktime = 4099766400
string locktime = 2099-12-01 00:00:00
redeemscript = 0580785df400b175210308c5751121b1ae5c973cdc7071312f6fc10ab864262f0cbd8134f056166e50f3ac
scriptPubKey = 0020803268e042008737cf439748cbb5a4449e311da9aa64ae3ac56d84d059654f85
address = bc1qsqex3czzqzrn0n6rjayvhddygj0rz8df4fj2uwk9dkzdqkt9f7zs5c493u
// Test certificate and endpoint signing using the first timelocked address = m/84'/0'/0'/2/0 (see above)
bond private_key = L2tQBEdhC48YLeEWNg3e4msk94iKfyVa9hdfzRwUERabZ53TfH3d
bond p2pkh address = 16vmiGpY1rEaYnpGgtG7FZgr2uFCpeDgV6
certificate private_key = KyZpNDKnfs94vbrwhJneDi77V6jF64PWPF8x5cdJb8ifgg2DUc9d
certificate public_key = 0330d54fd0dd420a6e5f8d3624f5f3482cae350f79d5f0753bf5beef9c2d91af3c
certificate p2pkh address = 1JaUQDVNRdhfNsVncGkXedaPSM5Gc54Hso
certificate message = fidelity-bond-cert|0330d54fd0dd420a6e5f8d3624f5f3482cae350f79d5f0753bf5beef9c2d91af3c|375
certificate signature = INOP3cB9UW7F1e1Aglj8rI9QhnyxmgWDEPt+nOMvl7hJJne7rH/KCNDYvLiqNuB9qWaWUojutjRsgPJrvyDQ+0Y=
// example endpoint signing two IRC nicknames (used in JoinMarket)
endpoint message = J54LS6YyJPoseqFS|J55VZ6U6ZyFDNeuv
endpoint signature = H18WE4MugDNoWZIf9jU0njhQptdUyBDUf7lToG9bpMKmeJK0lOoABaDs5bKnohSuZ0e9gnSco5OL9lXdKU7gP5E=
</pre>
Code generating these test vectors can be found here: https://github.com/chris-belcher/timelocked-addresses-fidelity-bond-bip-testvectors
== Reference ==
* [[https://gist.github.com/chris-belcher/18ea0e6acdb885a2bfbdee43dcd6b5af/|Design for improving JoinMarket's resistance to sybil attacks using fidelity bonds]]
* [[https://github.com/JoinMarket-Org/joinmarket-clientserver/blob/master/docs/fidelity-bonds.md|JoinMarket fidelity bonds doc page]]
* [[bip-0065.mediawiki|BIP65 - OP_CHECKLOCKTIMEVERIFY]]
* [[bip-0032.mediawiki|BIP32 - Hierarchical Deterministic Wallets]]
* [[bip-0044.mediawiki|BIP44 - Multi-Account Hierarchy for Deterministic Wallets]]
* [[bip-0049.mediawiki|BIP49 - Derivation scheme for P2WPKH-nested-in-P2SH based accounts]]
* [[bip-0084.mediawiki|BIP84 - Derivation scheme for P2WPKH based accounts]]
* [[bip-0086.mediawiki|BIP86 - Key Derivation for Single Key P2TR Outputs]]

View File

@ -1,20 +1,26 @@
RECENT CHANGES:
* (15 Feb 2021) Finalize specification
* (28 Sep 2017) Adjust text to match test vectors
* (19 Apr 2016) Define version 2 payment codes
* (17 Apr 2016) Clarify usage of outpoints in notification transactions
* (18 Dec 2015) Update explanations to resolve FAQs
<pre>
BIP: 47
Layer: Applications
Title: Reusable Payment Codes for Hierarchical Deterministic Wallets
Author: Justus Ranvier <justus@openbitcoinprivacyproject.org>
Authors: Justus Ranvier <justus@openbitcoinprivacyproject.org>
Comments-Summary: Unanimously Discourage for implementation
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0047
Status: Draft
Status: Deployed
Type: Informational
Created: 2015-04-24
Assigned: 2015-04-24
</pre>
==Status==
This BIP can be considered final in terms of enabling compatibility with wallets that implement version 1 and version 2 reusable payment codes, however future developments of the reusable payment codes specification will not be distributed via the BIP process.
The Open Bitcoin Privacy Project RFC repo should be consulted for specifications related to version 3 or higher payment codes: https://github.com/OpenBitcoinPrivacyProject/rfc
==Abstract==
This BIP defines a technique for creating a payment code which can be publicly advertised and associated with a real-life identity without creating the loss of security or privacy inherent to P2PKH address reuse.
@ -150,7 +156,7 @@ It is assumed that Alice can easily obtain Bob's payment code via a suitable met
Prior to the first time Alice initiates a transaction to Bob, Alice MUST inform Bob of her payment code via the following procedure:
Note: this procedure is used if Bob uses a version 1 payment code (regardless of the the version of Alice's payment code). If Bob's payment code is not version 1, see the appropriate section in this specification.
Note: this procedure is used if Bob uses a version 1 payment code (regardless of the version of Alice's payment code). If Bob's payment code is not version 1, see the appropriate section in this specification.
# Alice constructs a transaction which sends a small quantity of bitcoins to Bob's notification address (notification transaction)
## The inputs selected for this transaction MUST NOT be easily associated with Alice's notification address
@ -158,7 +164,7 @@ Note: this procedure is used if Bob uses a version 1 payment code (regardless of
## Alice selects the private key corresponding to the designated pubkey: <pre>a</pre>
## Alice selects the public key associated with Bob's notification address: <pre>B, where B = bG</pre>
## Alice calculates a secret point: <pre>S = aB</pre>
## Alice calculates a 64 byte blinding factor: <pre>s = HMAC-SHA512(x, o)</pre>
## Alice calculates a 64 byte blinding factor: <pre>s = HMAC-SHA512(o, x)</pre>
### "x" is the x value of the secret point
### "o" is the outpoint being spent by the designated input
# Alice serializes her payment code in binary form.
@ -229,7 +235,7 @@ The following actions are recommended to reduce this risk:
<img src="bip-0047/reusable_payment_codes-04.png" />
<img src="bip-0047/reusable_payment_codes-05.png" />
# Bob is watching for incoming payments on B' ever since he received the notification transaction from Alice.
## Bob calculates n shared secrets with Alice, using the 0<sup>th</sup> public key derived Alice's payment code, and private keys 0 - n derived from Bob's payment code, where n is his desired lookahead window.
## Bob calculates n shared secrets with Alice, using the 0<sup>th</sup> public key derived from Alice's payment code, and private keys 0 - n derived from Bob's payment code, where n is his desired lookahead window.
## Bob calculates the ephemeral deposit addresses using the same procedure as Alice: <pre>B' = B + sG</pre>
## Bob calculate the private key for each ephemeral address as: <pre>b' = b + s</pre>
<img src="bip-0047/reusable_payment_codes-02.png" />
@ -269,7 +275,7 @@ Normal operation of a payment code-enabled wallet can be performed by an SPV cli
Recovering a wallet from a seed, however, does require access to a fully-indexed blockchain.
The required data may be obtained from copy of the blockchain under the control of the user, or via a publicly-queriable blockchain explorer.
The required data may be obtained from copy of the blockchain under the control of the user, or via a publicly-queryable blockchain explorer.
When querying a public blockchain explorer, wallets SHOULD connect to the explorer through Tor (or equivalent) and SHOULD avoid grouping queries in a manner that associates ephemeral addresses with each other.
@ -344,12 +350,12 @@ Version 2 payment codes behave identifically to version 1 payment codes, except
====Definitions====
* Notification change output: the change output from a notification transaction which which resides in the sender's wallet, but can be automatically located by the intended recipient
* Notification change output: the change output from a notification transaction which resides in the sender's wallet, but can be automatically located by the intended recipient
* Payment code identifier: a 33 byte representation of a payment code constructed by prepending 0x02 to the SHA256 hash of the binary serialization of the payment code
====Notification Transaction====
Note: this procedure is used if Bob uses a version 2 payment code (regardless of the the version of Alice's payment code). If Bob's payment code is not version 2, see the appropriate section in this specification.
Note: this procedure is used if Bob uses a version 2 payment code (regardless of the version of Alice's payment code). If Bob's payment code is not version 2, see the appropriate section in this specification.
# Construct a notification transaction as per the version 1 instructions, except do not create the output to Bob's notification address
# Create a notification change address as follows:

View File

@ -2,12 +2,10 @@
BIP: 48
Layer: Applications
Title: Multi-Script Hierarchy for Multi-Sig Wallets
Author: Fontaine <dentondevelopment@protonmail.com>
Comments-Summary: No comments
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0048
Status: Proposed
Type: Standards Track
Created: 2020-12-16
Authors: Fontaine <dentondevelopment@protonmail.com>
Status: Deployed
Type: Specification
Assigned: 2020-12-16
License: MIT
</pre>
@ -113,9 +111,6 @@ The following path represents Native Segwit (p2wsh) mainnet, account 0:
The recommended default for wallets is pay to witness script hash <code>m/48'/0'/0'/2'</code>.
To add new script types submit a PR to this specification and include it in the list above:
<code>X'</code>: Future script type <code>m/48'/0'/0'/X'</code></br>
===Change===
Constant 0 is used for external chain and constant 1 for internal chain (also
@ -145,6 +140,13 @@ Public derivation is used at this level.
|-
|mainnet
|first
|p2sh-p2wsh
|external
|first
|m / 48' / 0' / 0' / 1' / 0 / 0
|-
|mainnet
|first
|p2wsh
|external
|first

View File

@ -2,12 +2,12 @@
BIP: 49
Layer: Applications
Title: Derivation scheme for P2WPKH-nested-in-P2SH based accounts
Author: Daniel Weigl <DanielWeigl@gmx.at>
Authors: Daniel Weigl <DanielWeigl@gmx.at>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0049
Status: Final
Type: Informational
Created: 2016-05-19
Status: Deployed
Type: Specification
Assigned: 2016-05-19
License: PD
</pre>
@ -92,10 +92,10 @@ This BIP is not backwards compatible by design as described under [[#considerati
// Account 0, first receiving private key = m/49'/1'/0'/0/0
account0recvPrivateKey = cULrpoZGXiuC19Uhvykx7NugygA3k86b3hmdCeyvHYQZSxojGyXJ
account0recvPrivateKeyHex = 0xc9bdb49cfbaedca21c4b1f3a7803c34636b1d7dc55a717132443fc3f4c5867e8
account0recvPublickKeyHex = 0x03a1af804ac108a8a51782198c2d034b28bf90c8803f5a53f76276fa69a4eae77f
account0recvPublicKeyHex = 0x03a1af804ac108a8a51782198c2d034b28bf90c8803f5a53f76276fa69a4eae77f
// Address derivation
keyhash = HASH160(account0recvPublickKeyHex) = 0x38971f73930f6c141d977ac4fd4a727c854935b3
keyhash = HASH160(account0recvPublicKeyHex) = 0x38971f73930f6c141d977ac4fd4a727c854935b3
scriptSig = <0 <keyhash>> = 0x001438971f73930f6c141d977ac4fd4a727c854935b3
addressBytes = HASH160(scriptSig) = 0x336caa13e08b96080a32b5d818d59b4ab3b36742

View File

@ -1,12 +1,10 @@
<pre>
BIP: 50
Title: March 2013 Chain Fork Post-Mortem
Author: Gavin Andresen <gavinandresen@gmail.com>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0050
Status: Final
Authors: Gavin Andresen <gavinandresen@gmail.com>
Status: Deployed
Type: Informational
Created: 2013-03-20
Assigned: 2013-03-20
License: PD
</pre>

View File

@ -2,15 +2,12 @@
BIP: 52
Layer: Consensus (hard fork)
Title: Durable, Low Energy Bitcoin PoW
Author: Michael Dubrovsky <mike+bip@powx.org>
Bogdan Penkovsky <bogdan+bip@powx.org>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0052
Status: Draft
Type: Standards Track
Created: 2021-05-13
License: BSD-2-Clause
OPL
Authors: Michael Dubrovsky <mike+bip@powx.org>
Bogdan Penkovsky <bogdan+bip@powx.org>
Status: Closed
Type: Specification
Assigned: 2021-05-13
License: BSD-2-Clause OR OPUBL-1.0
</pre>
@ -25,7 +22,7 @@ Bitcoin network cannot profitably mine Bitcoin even if they have the capital to
invest in mining hardware. From a practical perspective, Bitcoin adoption by
companies like Tesla (which recently rescinded its acceptance of Bitcoin as
payment) has been hampered by its massive energy consumption and perceived
environmental impact.
environmental impact.
<img src="bip-0052/btc_energy-small.png"></img>
@ -118,7 +115,7 @@ The HeavyHash is performed in three stages:
# Keccak hash
# Matrix-vector multiplication
# Keccak of the result xorred with the hashed input
# Keccak of the result xored with the hashed input
Note that the most efficient matrix-vector multiplication is performed on a
photonic miner. However, this linear algebra operation can be performed on any
@ -137,7 +134,7 @@ x1 <- keccak(input)
x2 <- reshape(x1, 64)
// Perform a matrix-vector multiplication.
// The result is 64-vector of 14-bit unsigned.
// The result is 64-vector of 14-bit unsigned.
x3 <- vector_matrix_mult(x2, M)
// Truncate all values to 4 most significant bits.
@ -287,13 +284,15 @@ With significant progress in optical and analog matrix-vector-multiplication chi
PoWx will also be publishing the designs of the current optical miner prototypes in the near term under an open-source hardware license.
== Changelog ==
* 2026-06-18:
** Updated to Closed after the proposal has not made progress for several years and [https://groups.google.com/g/bitcoindev/c/Vrh7oED9b9Q/m/TrCEKRjNAAAJ attempts to contact the authors] did not succeed.
== Acknowledgments ==
We thank all the members of the Bitcoin community who have already given us feedback over the last several years as well as others in the optical computing community and beyond that have given their input.
[1] M. Dubrovsky et al. Towards Optical Proof of Work, CES conference (2020) https://assets.pubpub.org/xi9h9rps/01581688887859.pdf
[2] https://sciencex.com/news/2020-05-powering-bitcoin-silicon-photonics-power.html

159
bip-0053.mediawiki Normal file
View File

@ -0,0 +1,159 @@
<pre>
BIP: 53
Layer: Consensus (soft fork)
Title: Disallow 64-byte transactions
Authors: Chris Stewart <stewart.chris1234@gmail.com>
Status: Draft
Type: Specification
Assigned: 2025-04-11
License: BSD-3-Clause
</pre>
==Abstract==
This BIP describes the rationale for disallowing transactions that are serialized to 64 bytes without the transaction's witness.
We describe the weaknesses to the Merkle tree included in Bitcoin block headers, and various exploits for those weaknesses.
==Specification==
This BIP disallows Bitcoin transactions that are serialized to 64 bytes in length without their witness.
==Motivation==
Bitcoin block headers include a commitment to the set of transactions in a given
block, which is implemented by constructing a Merkle tree of transaction ids
(double-SHA256 hash of a transaction) and including the root of the tree in the
block header. This in turn allows for proving to a Bitcoin light client that a
given transaction is in a given block by providing a path through the tree to the
transaction. However, Bitcoins particular construction of the Merkle tree has
several security weaknesses, including at least two forms of block malleability
that have an impact on the consensus logic of Bitcoin Core, and an attack on
light clients, where an invalid transaction could be ”proven” to appear in a block
by doing substantially less work than a SHA256 hash collision would require.
This has been mitigated by Bitcoin Core's relay policy and the RPC interface since 2018<ref>[https://github.com/bitcoin/bitcoin/pull/11423/commits/7485488e907e236133a016ba7064c89bf9ab6da3 PR #11423 disallows transactions that are less than 82 bytes in size from Bitcoin Core relay and RPC interface]</ref><ref>[https://github.com/bitcoin/bitcoin/commit/8c5b3646b5afe8a61f5c66478d8e11f0d2ce5108 Reduces the minimum transaction size required for a transaction to be considered standard from 82 bytes to 65 bytes]</ref>.
=== Block malleability ===
64-byte transactions introduce block malleability. Malicious peers can construct consensus valid and invalid 64-byte
transactions that have the same serialization as the concatenation of 2 hashes in the Merkle tree.
Assume we have a valid Bitcoin block with 2 transactions in it with Txid<sub>0</sub> and Txid<sub>1</sub>.
The Merkle root for this block is H(Txid<sub>0</sub>||Txid<sub>1</sub>).
A malicious user could find a 64-byte transaction T<sub>m</sub> that serializes to Txid<sub>0</sub>||Txid<sub>1</sub>.
Next that user relays the block containing the malicious T<sub>m</sub> rather than the
valid Bitcoin transactions that correspond to Txid<sub>0</sub> and Txid<sub>1</sub>.
==== Block malleability with consensus INVALID transactions ====
The peer receiving the malicious block marks the block as invalid, as T<sub>m</sub>
is not a valid transaction according to network consensus rules.
Other peers on the network receive the valid block containing T<sub>0</sub> and T<sub>1</sub>
and add the block to their blockchain. Peers that receive the invalid block before the valid block
will never come to consensus with their peers due to the malicious user finding a collision
within the block's Merkle root. Finding this collision is approximately 22 bits worth of work.<ref>[[bip-0053/2-BitcoinMerkle.pdf|to produce a block having a Merkle root that
is a hash of a 64-byte quantity that deserializes validly, its enough
to just do 8 bits of work to find a workable coinbase (which will hash to the first
32 bytes), plus another ≈22 bits of work ((1/5) 224, so slightly less) to find
a workable second transaction that will hash to the second 32 bytes) a very
small amount of computation.]]</ref>
This attack vector was fixed in Bitcoin Core 0.6.2<ref>[https://bitcoin.org/en/alert/2012-05-14-dos#risks CVE-2012-2459]</ref>, re-introduced in 0.13.x<ref>[https://github.com/bitcoin/bitcoin/pull/7225 #7225]</ref> and patched again in
0.14<ref>[https://github.com/bitcoin/bitcoin/pull/9765 #9765]</ref>.
==== Block malleability with consensus VALID transactions ====
Producing a valid Bitcoin transaction T<sub>m</sub> that adheres to network consensus
rules requires 224 bits of work<ref>[[bip-0053/2-BitcoinMerkle.pdf|Note that the first transaction in a block must be a coinbase, and as discussed
above, that largely constrains the first 32 bytes of the first transaction: only
the 4 version bytes are unconstrained. So it would take at least 28*8= 224 bits
of work to find the first node in a given row of the tree that would match the
first half of a coinbase, in addition to the amount of work required to grind the
second half of the transaction to something meaningful (which is much easier
only 16 bytes or so are constrained, so approximately 128 bits of work to find a collision). Of course, any of the rows in the Merkle tree could be used, but it nevertheless seems clear that this should be computationally infeasible.]]</ref>.
This is computationally and financially expensive but theoretically possible. This can lead to a persistent chain split on the network.
=== Attack on SPV clients ===
BIP37<ref>[https://github.com/bitcoin/bips/blob/master/bip-0037.mediawiki BIP37]</ref>provides a partial Merkle tree format<ref>[https://github.com/bitcoin/bips/blob/master/bip-0037.mediawiki#partial-merkle-branch-format Partial Merkle Tree Format]</ref>
that allows you to verify that your Bitcoin transaction is included in a Merkle root embedded in a Bitcoin block header.
Notably this format does not commit to the height of the Merkle tree.
Suppose a (valid) 64-byte transaction T is included in a block with the property that the second 32 bytes (which
are less constrained than the first 32 bytes) are constructed so that they collide
with the hash of some other fake, invalid transaction F. The attacker can fool the SPV client into believing that F
was included in a Bitcoin block rather than T with 81 bits<ref>[[bip-0053/2-BitcoinMerkle.pdf|An attacker who can do 81 bits of work (followed by another 40 bits of work, to
construct the funding transaction whose coins will be spent by this one) is able
to fool an SPV client in this way.]]</ref> of work. Disallowing 64-byte transactions reduces implementation complexity for SPV wallets<ref>[https://delvingbitcoin.org/t/great-consensus-cleanup-revival/710/43 The steps needed to make sure a Merkle proof for a 64-byte transaction is secure.]</ref>.
==Rationale==
===SPV clients===
Attacks on SPV clients could be mitigated by knowing the depth of the Merkle tree. Requiring SPV clients to request both the coinbase and payment transaction could mitigate this attack.
To produce a valid coinbase transaction at the same depth that our fake transaction F occurs at would require 224 bits of work.
As mentioned above, this is computationally and financially expensive, but theoretically possible. This design would increase the size
of SPV proofs by 70%.<ref>[https://delvingbitcoin.org/t/great-consensus-cleanup-revival/710/29 Base proof: 80-byte header + 448-byte partial Merkle tree = 528 bytes. Proof with coinbase tx, assuming the coinbase tx is in the left half of the tree and the tx to prove is in the right half of the tree: 80-byte header + 416 bytes partial Merkle tree for coinbase tx + 416 bytes partial Merkle tree for tx = 912 bytes.]</ref>
==Backward compatibility==
There have been 5 64-byte transactions that have occurred in the Bitcoin blockchain as of this
writing <ref>[[bip-0053/64byte-tx-mainnet.txt|64-byte transactions in the Bitcoin blockchain]]</ref>
with the last transaction 7f2efc6546011ad3227b2da678be0d30c7f4b08e2ce57b5edadd437f9e27a612<ref>[https://mempool.space/tx/7f2efc6546011ad3227b2da678be0d30c7f4b08e2ce57b5edadd437f9e27a612 Last 64-byte transaction in the Bitcoin blockchain]</ref>
occurring at block height 419,606<ref>[https://mempool.space/block/000000000000000000308f1efc24419f34a3bafcc2b53c32dd57e4502865fd84 Block 419,606]</ref>.
====Pre-segwit 64-byte transactions====
Pre-segwit 64-byte transactions cannot spend a UTXO protected by a digital signature.<ref>[https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki After BIP66 was activated on the Bitcoin network, Bitcoin transactions cannot have a digital signature smaller than 9 bytes.]</ref>
The largest scriptSig a pre-segwit 64-byte transaction can have is 4 bytes.<ref>[https://delvingbitcoin.org/t/great-consensus-cleanup-revival/710/73]</ref>
There are 6<ref>[[bip-0053/non-standard-hashlock-utxos.txt|As of block `00000000000000000001194ae6be942619bf61aa70822b9643d01c1a441bf2b7` there exist 6 non-standard hashlock UTXOs that could theoretically have a 0-3 byte pre-image. None of them have a 0-3 byte pre-image.]]</ref>
non standard hashlock UTXOs in the Bitcoin blockchain. None of them have a 0-3 byte pre-image. This means they cannot be spent by a 64-byte transaction.
Pre-segwit 64-byte transactions that spend a non-standard UTXO that are inherently malleable.<ref>[https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#trust-free-unconfirmed-transaction-dependency-chain Details on how to malleate a pre-segwit transaction]</ref>
Policy rules such as CLEANSTACK, MINIMALDATA, PUSHONLY are not consensus rules. If a user has a way to confirm an already non-standard
64-byte transaction - they can malleate the transaction by violating policy rules to change the size of the transaction to a size other than 64 bytes.
====Segwit 64-byte transactions====
This BIP disallows single-input single-output segwit transactions that pay to a 2-byte witness program.<ref>[https://delvingbitcoin.org/t/great-consensus-cleanup-revival/710/73#p-4382-future-segwit-versions-10 BIP141 says witness programs can be 2 bytes in size, which makes the scriptPubKey a total of 4 bytes]</ref>
The only known use case<ref>[https://bitcoin.stackexchange.com/a/110664 Why do we have 2-byte witness programs? The original rationale for the lower end of the range of valid witness program lengths is that 2 bytes is enough to guarantee no ambiguity of how the program would be pushed (some 1-byte values can - and according to standardness, must - be pushed with OP_n, and dealing with those would have complicated the matter).]</ref>
for this type of transaction is ephemeral anchor outputs.<ref>[https://bitcoinops.org/en/topics/ephemeral-anchors/ What are ephemeral anchor outputs? This allows anyone on the network to use that output as the input to a child transaction. This allows anyone to create the fee-paying child, even if they dont receive any of the other outputs from the parent transaction. This allows ephemeral anchors to function as fee sponsorship but without requiring any consensus changes.]</ref>
==Reference implementation==
<source lang="cpp">
/**
* We want to enforce certain rules (specifically the 64-byte transaction check)
* before we call CheckBlock to check the Merkle root. This allows us to enforce
* malleability checks which may interact with other CheckBlock checks.
* This is currently called both in AcceptBlock prior to writing the block to
* disk and in ConnectBlock.
* Note that as this function is called before merkle-tree checks, it must never return a
* non-malleable error condition.
*/
static bool ContextualBlockPreCheck(const CBlock& block, BlockValidationState& state, const ChainstateManager& chainman, const CBlockIndex* pindexPrev)
{
if (DeploymentActiveAfter(pindexPrev, chainman, Consensus::DEPLOYMENT_64BYTETX)) {
for (const auto& tx : block.vtx) {
if (::GetSerializeSize(TX_NO_WITNESS(tx)) == 64) {
return state.Invalid(BlockValidationResult::BLOCK_MUTATED, "64-byte-transaction", strprintf("size of tx %s without witness is 64 bytes", tx->GetHash().ToString()));
}
}
}
return true;
}
</source>
The sample implementation is currently open here:
https://github.com/bitcoin-inquisition/bitcoin/pull/24/files
<references />
==Copyright==
This BIP is licensed under the [https://opensource.org/license/BSD-3-Clause BSD-3-Clause License].
==Acknowledgements==
Suhas Daftuar, AJ Towns, Sergio Demian Lerner, Greg Maxwell, Matt Corallo, Antoine Poinsot, Dave Harding and Eric Voskuil

Binary file not shown.

View File

@ -0,0 +1,5 @@
892f44a49de6f5b212cdbea514d09e692d9fed5d897f37bcef14bd0eedebf193
bbf71454857438c6dfd64c0d92a7c5360a8d8d57c9202f5806449e5b0d26b848
6713d61a83e3d095582211ea8d6db452ac7561e863decba7c4046fb9f6d88aa0
7f2efc6546011ad3227b2da678be0d30c7f4b08e2ce57b5edadd437f9e27a612
5302e01dc4b7e34314a34c7c3347107e612b9524be684d388cd4d2ca35ff1ec9

View File

@ -0,0 +1,6 @@
af32bb06f12f2ae5fdb7face7cd272be67c923e86b7a66a76ded02d954c2f94d:0
faf8989ed87c5a667a1ead813aea718727e01767c124193297eaf409ff4645e5:1
c4b46c5d88327d7af6254820562327c5f11b6ee5449da04b7cfd3710b48b6f55:0
702c36851ed202495c2bec1dd0cefb448b50fafd3a5cdd5058c18ca53fc2c3d1:0
6f8a70aac37786b1f619d40250b8bca1a1f6da487146a7e81091f611068a23ef:0
fb01987b540ec286973aac248fab643de82813af452d958056fee8de9f4535ab:0

266
bip-0054.md Normal file
View File

@ -0,0 +1,266 @@
```
BIP: 54
Layer: Consensus (soft fork)
Title: Consensus Cleanup
Authors: Antoine Poinsot <mail@antoinep.com>
Matt Corallo <bips@bluematt.me>
Status: Complete
Type: Specification
Assigned: 2025-04-11
License: CC0-1.0
```
## Abstract
This document proposes new consensus rules in order to fix the timewarp attack, reduce the worst
case block validation time, prevent Merkle tree weaknesses, and avoid duplicate transactions without
[bip-0030][BIP30] validation.
## Motivation
This proposal addresses a number of long-standing vulnerabilities and weaknesses in the Bitcoin
protocol. Bundling these fixes together amortizes the fixed cost of deploying a Bitcoin soft fork.
The [timewarp bug][SE timewarp] makes it possible for a majority-hashrate attacker to arbitrarily
lower mining difficulty, and therefore arbitrarily increase the block rate. In the worst case, an
attacker can bring down the difficulty to its minimum within 38 days of starting the attack. Besides
empowering a 51% attacker, the presence of this bug makes it harder to reason about miners'
incentives. Accelerating the block rate allows an attacker to steal block subsidy from future
miners and increases available block space. It may be in the interest of short-sighted users and
miners to exploit this vulnerability to materially increase the block rate without fatally hurting
the network.
Specially crafted blocks may be expensive to process, [taking up to][Delving worst block] several
minutes to validate even on high-end devices, and up to a few hours on lower-end devices. Long block
validation times are a nuisance to users, increasing the cost to independently fully validate the
consensus rules. In addition they can be used by miners to attack their competition, creating
perverse incentives, centralization pressures and leading to reduced network security.
In computing a block's Merkle root, a transaction with exactly 64 bytes of non-witness data can be
interpreted both as an intermediate node in the tree and as a leaf in the tree. This makes it
possible to trick an SPV verifier into accepting an inclusion proof for a transaction that is not
part of a block, by pretending a 64-byte block transaction is actually an inner node[^9]. Invalidating
64-byte transactions addresses this vulnerability without requiring users of SPV verifiers, or
any other user of Merkle proofs, to rely on one of the available workarounds[^13] or even to know one is
necessary in the first place.
Since [bip-0034][BIP34] activation, explicit [bip-0030][BIP30] validation is not necessary until
block height 1,983,702[^0]. Resuming [bip-0030][BIP30] validation would unnecessarily increase block
validation overhead and preclude alternative full node designs (such as [bip-0182][BIP182] Utreexo).
Enforcing that new coinbase transactions are different from the early [bip-0034][BIP34] violations
makes it possible to get rid of [bip-0030][BIP30] validation forever.
## Specification
For all blocks after activation the following new rules apply.
Given a block at height `N`:
- if `N % 2016` is equal to 0, the timestamp of the block must be set to a value higher than or
equal to the value of the timestamp of block at height `N-1` minus 7200 (T<sub>N</sub> &ge;
T<sub>N1</sub> 7200);
- if `N % 2016` is equal to 2015, the timestamp of the block must be set to a value higher than
or equal to the value of the timestamp of the block at height `N-2015` (T<sub>N</sub> &ge;
T<sub>N2015</sub>).
A limit is set on the number of signature operations present in the scripts used to validate a
transaction. It applies to all transactions in the block except the coinbase transaction[^1]. For
each input in the transaction, count the number of `CHECKSIG` and `CHECKMULTISIG` in the input
scriptSig and previous output's scriptPubKey, including the P2SH redeemScript. If the total summed
over all transaction inputs is strictly higher than 2500, the transaction is invalid. The accounting is the
same as for [bip-0016][BIP16 specs], evaluating the scriptSig, scriptPubKey, and P2SH redeemScript
separately:
1. `CHECKSIG` and `CHECKSIGVERIFY` count as 1 signature operation, whether or not they are evaluated.
2. `CHECKMULTISIG` and `CHECKMULTISIGVERIFY` immediately preceded by `OP_1` through `OP_16` are counted as 1 to 16 signature operations, whether or not they are evaluated.
3. All other `CHECKMULTISIG` and `CHECKMULTISIGVERIFY` are counted as 20 signature operations, whether or not they are evaluated.
Transactions whose witness-stripped serialized size is exactly 64 bytes are invalid.
The coinbase transaction's `nLockTime` field must be set to the height of the block minus 1[^2]
and its `nSequence` field must not be equal to 0xffffffff.
## Rationale
The restrictions on the timestamp of the first and last blocks of a difficulty adjustment period fix
the timewarp and MurchZawy vulnerabilities[^3]. The latter poses mostly theoretical concerns but is
extremely low risk to fix: the duration of an adjustment period has never been, and should never be,
negative. The former is fixed by preventing the timestamp of the first block of a difficulty period
from being lower than the previous block's, with a two-hour grace period. A [previous
proposal][BIP-XXXX] to fix the timewarp attack used a ten-minute grace period instead, and this
approach has been adopted for [testnet4][BIP94 timewarp]. Out of an abundance of caution and because it only trivially worsens the
block rate increase under attack, a two-hour grace period is used here[^4].
Disabling some Script operations and functionalities was [previously proposed][BIP-XXXX] to reduce
the worst case block validation time but was met with resistance due to confiscation concerns[^5]. A
delicate balance needs to be struck between minimizing the confiscation risks of a mitigation, even
if merely theoretical, and bounding the costs one could impose on all other users of the system. To
that end, limiting potentially executed signature operations targets the exact harmful behaviour while
preserving maximal flexibility in Script usage.
Such a limit reduces the worst case block validation time by a factor of 40 and drastically
increases the preparation cost of an attack, making it uneconomical for a miner[^6]. The maximum of
2500 was chosen as the tightest value that did not make any non-pathological standard transaction
invalid[^7].
64-byte transactions can only contain a scriptPubKey that lets anyone spend the funds, or one that
burns them. They have also been non-standard since 2019 and never been used since 2016. Several
alternatives to invalidating them were previously proposed. Some believe the improvements for users
of Merkle proofs are too marginal to be worth introducing a discontinuity in the set of valid
witness-stripped transaction sizes. Others have suggested instead committing to the Merkle
tree depth in the header's version field[^8], which would make one workaround for a known
vulnerability easier to deploy. The authors believe it is preferable to address the root cause by
invalidating 64-byte transactions, fixing the vulnerability without Merkle proof users having to
rely on any workaround or even know one is necessary in the first place. See [this post][64 bytes
debate] for an attempt at summarizing the arguments for both sides of this debate.
The `nLockTime` field of transactions is a natural place to store a block height and is currently
unused in coinbase transactions. Using it to enforce that new coinbase transactions differ from
early [bip-0034][BIP34] violations also allows applications to recover the block height without
having to parse Script. Leveraging the existing timelock mechanism makes the check self-contained:
the same coinbase transaction cannot have been valid in a previous block[^11]. This simplifies both
reasoning and client implementation, since the [bip-0030][BIP30] check can be skipped entirely past
Consensus Cleanup activation, regardless of the [bip-0034][BIP34] activation status[^12]. One person
[raised the concern][miningdev nLockTime] that the `nLockTime` field would be an ideal extranonce
for ASIC controllers if such controllers ever became a bottleneck in mining operations. Others
[replied][miningdev nLockTime] that the same benefits could be achieved by using a dummy output
instead, should that ever become necessary. The authors [believe][ML remaining concerns] the
benefits of using `nLockTime` to differentiate coinbase transactions outweigh the theoretical
cost of making it unavailable for extranonce rolling by ASIC controllers.
## Backward compatibility
This proposal only tightens the block validation rules: there is no block that is valid under the
rules proposed in this BIP but not under the existing Bitcoin consensus rules. As a consequence
these changes are backward-compatible with non-upgraded node software. That said, the authors
strongly encourage node operators to upgrade in order to fully validate all consensus rules.
## Miner forward compatibility
Bitcoin Core version [29.0][Core 29.0] and later will not generate a block template that violates
the timestamp restrictions introduced in this BIP. Although it would be extremely unlikely due to
the grace period used in this proposal, miners should use the `curtime` or `mintime` field from the
`getblocktemplate` result for their block's timestamp to make sure they always create blocks valid
according to this proposal. Note this is not a new requirement: using a timestamp lower than the
`mintime` field from the `getblocktemplate` result already leads to creating an invalid block.
Bitcoin Core version [30.0][Core 30.0] and later will not generate a block template including a
transaction that violates the signature operations limit introduced in this BIP.
Bitcoin Core version [0.16.1][Core 0.16.1] and later will neither relay nor create block templates
that include transactions whose witness-stripped serialized size is exactly 64 bytes.
The coinbase transaction is usually crafted by mining pool software. To the best of the authors'
knowledge, there does not exist an open source reference broadly in use today for such software.
We encourage mining pools to update their software to craft coinbase transactions that are
forward-compatible with the changes proposed in this BIP.
## Reference implementation
An implementation of BIP54 for Bitcoin Core is available [here][Core BIP 54 implem].
## Test vectors
Documented test vectors are available [here](./bip-0054/test_vectors/) for all mitigations
introduced in this BIP.
## Acknowledgements
This document builds upon an [earlier proposal][BIP-XXXX] by Matt Corallo.
The authors would like to thank everyone involved in researching the most appropriate mitigation for
each of these bugs. We would like to thank in particular Anthony Towns and Sjors Provoost for their
direct contributions to this proposal, as well as @0xb10c and Brian Groll for providing the authors
with data to analyze the proposed mitigations. Thanks to Chris Stewart for digging up historical
violations to the new transaction size rule, which are partially reused in this BIP's test vectors.
## Copyright
This document is licensed under the Creative Commons CC0 1.0 Universal license.
## Changelog
* __1.0.0__ (2026-05-22):
* Complete planned work on the BIP.
[^0]: Block 1,983,702 is the earliest future block which could contain a duplicate coinbase
transaction while still respecting [bip-0034][BIP34]. See [this post][Delving duplicable] for a list
of all such future blocks.
[^1]: Technically this limit *cannot* apply to a coinbase transaction as the size of its sole
input's scriptSig is limited.
[^2]: The locktime validation, which is also performed for coinbase transactions, enforces that the
nLockTime value is the last block at which a transaction is invalid, not the first one at which it
is valid.
[^3]: The timewarp attack is described [here][SE timewarp] and the MurchZawy attack [here][Delving
Murch-Zawy].
[^4]: The testnet4 difficulty exception pushed blocks' timestamps in the future when abused,
revealing how some broken pool software may produce blocks that don't respect a 10 minutes grace
period. Some [raised concerns][Sjors grace period] similarly broken software might be used on
mainnet. Using a grace period of 2 hours instead of 10 minutes only reduces the expected block
interval time under attack by ~2.2 seconds. See [this post][grace period debate summary] for more.
[^5]: The argument is about someone having a timelocked presigned transaction using some of those
features in its output script. The transaction cannot be mined before activation. Such outputs would
not be covered by an amnesty for old UTxOs. See for instance [here][O'Connor OP_CODESEPARATOR] and
[here][O'Connor sighash type] for discussions on this topic.
[^6]: It is important to reduce the worst case block validation time as well as the ratio of
validation time imposed over preparation cost. The former is to limit the damages an externally
motivated attacker can do. The latter is to disincentivize miners slowing down their competition by
mining expensive blocks. See [this thread][ML thread validation time] for more.
[^7]: A non-pathological transaction would have a public key per signature operation and at least
one signature per input. Per standardness a single P2SH input may not have more than 15 signature
operations. Even by using 1-of-15 `CHECKMULTISIG`s a transaction would bump against the maximum
standard transaction size before running into the newly introduced limit. To run against the newly
introduced limit but not the transaction size a transaction would need to spend P2SH inputs with a
redeem script similar to `CHECKSIG DROP CHECKSIG DROP ...`. This type of redeem script serves no
purpose beyond increasing its validation cost, which is exactly what this proposal aims to mitigate.
[^8]: By Sergio Demian Lerner in a [blog post][Sergio post].
[^9]: Conversely, pretending that the inner nodes on one level of the tree are the actual block
transactions is another source of complexity for full node implementations, which previously
resulted in consensus bugs. For instance, Bitcoin Core versions between 0.13.0 and 0.13.2
implemented caching that made it vulnerable to this attack. See [this writeup][Suhas Merkle] by
Suhas Daftuar for a detailed explanation. Invalidating 64-byte transactions may avoid this risk, but
the issue is largely orthogonal to this proposal: it is fundamentally about caching validation
status for malleable blocks.
[^11]: Technically it could be argued a duplicate could in principle always be possible before block
31,001 when `nLockTime` enforcement [was originally soft-forked][Harding nLockTime]. But treating
coinbase transactions as not having duplicate past Consensus Cleanup activation would be consistent
for any implementation which enforces `nLockTime` from the genesis block, which is the behaviour
notably of Bitcoin Core but also of all other implementations the authors are aware of.
[^12]: For instance Bitcoin Core only disables [bip-0030][BIP30] validation for a specific chain
where [bip-0034][BIP34] violations have been manually inspected (see [here][Core validation.cpp
BIP34]). Without the guarantee given by enforcing the timelock on coinbase transactions, this would
have to be perpetuated for the Consensus Cleanup.
[^13]: The authors are aware of three workarounds for SPV verifiers. The first is to request a
Merkle proof for the coinbase transaction in addition to the transaction of interest, to infer the
depth of the Merkle tree. The second is to reject Merkle proofs in which any inner node is also a
valid serialisation of a Bitcoin transaction. More details about these are available [here][Sergio
post]. A third workaround is to change the Merkle proof structure by requiring inner nodes to be
provided as the single-SHA256 of their preimage, instead of the double-SHA256. See [here][Sergio
MERKLEBLOCK] for a full description.
[Delving worst block]: https://delvingbitcoin.org/t/great-consensus-cleanup-revival/710/93
[BIP30]: https://github.com/bitcoin/bips/blob/master/bip-0030.mediawiki
[BIP182]: https://github.com/bitcoin/bips/pull/1923
[BIP-XXXX]: https://github.com/TheBlueMatt/bips/blob/7f9670b643b7c943a0cc6d2197d3eabe661050c2/bip-XXXX.mediawiki
[BIP34]: https://github.com/bitcoin/bips/blob/master/bip-0034.mediawiki
[BIP16 specs]: https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki#specification
[SE timewarp]: https://bitcoin.stackexchange.com/questions/75831/what-is-time-warp-attack-and-how-does-it-work-in-general/75834#75834
[Delving Murch-Zawy]: https://delvingbitcoin.org/t/zawy-s-alternating-timestamp-attack/1062#variant-on-zawys-attack-2
[BIP94 timewarp]: https://github.com/bitcoin/bips/blob/master/bip-0094.mediawiki#time-warp-fix
[Sjors grace period]: https://delvingbitcoin.org/t/timewarp-attack-600-second-grace-period/1326
[grace period debate summary]: https://delvingbitcoin.org/t/great-consensus-cleanup-revival/710/66
[O'Connor OP_CODESEPARATOR]: https://gnusha.org/pi/bitcoindev/CAMZUoKneArC+YZ36YFwxNTKsDtJhEz5P2cosXKxJS8Rf_3Nyuw@mail.gmail.com
[O'Connor sighash type]: https://gnusha.org/pi/bitcoindev/CAMZUoK=1kgZLR1YZ+cJgzwmEOwrABYFs=2Ri=xGX=BCr+w=VQw@mail.gmail.com
[ML thread validation time]: https://gnusha.org/pi/bitcoindev/VsltJ2PHqWfzG4BU9YETTXjL7fYBbJhjVXKZQyItemySIA1okvNee9kf0zAOyLMeJ4Nqv1VOrYbWns5nP4TANCWvPJYu1ew_yxQSaudizzk=@protonmail.com
[Suhas Merkle]: https://gnusha.org/pi/bitcoindev/CAFp6fsGtEm9p-ZQF_XqfqyQGzZK7BS2SNp2z680QBsJiFDraEA@mail.gmail.com
[Sergio post]: https://bitslog.com/2018/06/09/leaf-node-weakness-in-bitcoin-merkle-tree-design
[Sergio MERKLEBLOCK]: https://bitslog.com/2018/08/21/simple-change-to-the-bitcoin-merkleblock-command-to-protect-from-leaf-node-weakness-in-transaction-merkle-tree/
[64 bytes debate]: https://delvingbitcoin.org/t/great-consensus-cleanup-revival/710/41
[Harding nLockTime]: https://bitcoin.stackexchange.com/questions/90229/nlocktime-in-bitcoin-core
[Delving duplicable]: https://delvingbitcoin.org/t/great-consensus-cleanup-revival/710/4
[Core 0.16.1]: https://bitcoincore.org/en/releases/0.16.1
[Core 29.0]: https://bitcoincore.org/en/releases/29.0
[Core BIP 54 implem]: https://github.com/darosior/bitcoin/tree/bip54
[Core 30.0]: https://bitcoincore.org/en/releases/30.0
[Core validation.cpp BIP34]: https://github.com/bitcoin/bitcoin/blob/390e7d61bd531505bb3d13f38316c282b85ed1dd/src/validation.cpp#L2401-L2459
[miningdev nLockTime]: https://groups.google.com/g/bitcoinminingdev/c/jlqlNHHNSNk
[ML remaining concerns]: https://gnusha.org/pi/bitcoindev/UsKuvCXXhSAnNVx5a0K2UfP3srAr3slW9mcOjtYk9LnolaOXfWrW9jpqbxsQQPkyQuZogkhz2Hbfwii2VsTm79vRDpgKduxk35hpBu_t7Do=@protonmail.com/

View File

@ -0,0 +1,102 @@
## BIP54 test vectors
This folder contains a set of test vectors for each mitigation introduced in the BIP. This document
presents them in more detail.
The code used to generate half of the test vectors is included with the implementation and available
[here][other-vectors]. The other half requires mining mainnet blocks and is [published
separately][bip54-miner]. In both cases it is implemented as a regular Bitcoin Core unit test, and
the test vectors are persisted as a JSON file if the `UPDATE_JSON_TESTS` preprocessor directive is
set (off by default).
To compile the [header][header-miner] and [block][block-miner] miners you may have to link to
libatomic explicitly. This can be achieved like so:
```
cmake -B atomicbuild -DAPPEND_LDFLAGS="-latomic"
cmake --build atomicbuild/ -j $(nproc)
```
[Premined headers][premined-headers] are also provided along with the header miner to allow changing
some of the last headers without having to re-generate the whole chain.
### Difficulty adjustment exploits
The [`timestamps.json`](./timestamps.json) test vectors exercise the two constraints on block header
timestamps introduced by BIP54 to mitigate the Timewarp and Murch-Zawy attacks. Each test case
features a chain of mainnet headers starting from the genesis block, and whether this header chain
is valid by BIP54 rules. Each test case also contains a comment describing why this particular chain
is (in)valid according to BIP54. All test cases are valid according to current Bitcoin consensus
rules. It is intended to be used to test a BIP54 implementation by feeding the header chain to a
Bitcoin node implementation, enforcing the BIP54 rules on this chain from genesis.
The test vector file features a JSON array of JSON objects, each corresponding to a test case. Each
JSON object features the following entries:
- `header_chain`: a JSON array of strings. An ordered list of hex-encoded mainnet block headers.
- `valid`: a JSON boolean. Whether this chain of headers is valid according to BIP54.
- `comment`: a JSON string. Description of the test case.
For the purpose of testing a Timewarp fix, a Timewarp attack was included early on in the history of
testnet3. An implementer of BIP54 may want to ensure that syncing testnet3 by enforcing BIP54 since
genesis will treat block `00000000118da1e2165a19307b86f87eba814845e8a0f99734dce279ca3fb029` as
invalid.
### Long block validation time
The [`sigops.json`](sigops.json) file contains test vectors for the limit on the number of
potentially-executed legacy signature operations in a single transaction, introduced by BIP54 in
order to mitigate long block validation times. Each test case represents a transaction and whether a
block containing it would be valid according to BIP54. The test cases feature an extensive set of
combinations of inputs and output types, ways to run into the limit, historical violations and some
pathological transactions exhibiting the specific implementation details. All test cases but those
belonging to this last category feature transactions that are valid under current Bitcoin consensus
rules. Each test case also features a comment describing why the transaction is (in)valid according
to BIP54.
The test vector file features a JSON array of JSON objects, each corresponding to a test case. Each
JSON object features the following entries:
- `spent_outputs`: a JSON array of strings. An ordered list of hex-encoded Bitcoin-serialized
transaction outputs spent by each input of this test case's transaction.
- `tx`: a JSON string. A hex-encoded Bitcoin-serialized transaction to be evaluated.
- `valid`: a JSON boolean. Whether this transaction is valid according to current consensus rules
supplemented by BIP54.
- `comment`: a JSON string. Description of the test case.
### Merkle tree malleability with 64-byte transactions
The [`txsize.json`](./txsize.json) file contains test cases exercising the new constraint on
non-witness transaction size introduced in BIP54. Each test case contains a transaction and whether
it would be valid according to BIP54, as well as a comment describing why it is (in)valid. All test
cases are otherwise valid according to current Bitcoin consensus rules.
The test vector file features a JSON array of JSON objects, each corresponding to a test case. Each
JSON object features the following entries:
- `tx`: a JSON string. A hex-encoded Bitcoin-serialized transaction to be evaluated.
- `valid`: a JSON boolean. Whether this transaction is valid according to BIP54.
- `comment`: a JSON string. Description of the test case.
### Possibility of duplicate coinbase transactions
The [`coinbases.json`](./coinbases.json) file contains test cases exercising the new restrictions on
coinbase transactions introduced in BIP54 to prevent duplicate coinbase transactions without
resorting to BIP30 validation. Each test case contains a chain of mainnet blocks (including the
genesis block), and whether this block chain is valid according to BIP54. All test cases are valid
according to current Bitcoin's consensus rules, except one that features a block containing a
coinbase transaction timelocked to a future block height.
The test vector file features a JSON array of JSON objects, each corresponding to a test case. Each
JSON object features the following entries:
- `block_chain`: a JSON array of strings. An ordered list of hex-encoded mainnet blocks.
- `valid`: a JSON boolean. Whether this block chain is valid according to current Bitcoin consensus
rules supplemented by BIP54.
- `comment`: a JSON string. Description of the test case.
[bip54-miner]: https://github.com/darosior/bitcoin/commits/bip54_miner/
[header-miner]: https://github.com/darosior/bitcoin/blob/bip54_miner/src/test/bip54_header_miner.cpp
[block-miner]: https://github.com/darosior/bitcoin/blob/bip54_miner/src/test/bip54_block_miner.cpp
[other-vectors]: https://github.com/darosior/bitcoin/blob/2509_inquisition_consensus_cleanup/src/test/bip54_tests.cpp
[premined-headers]: https://github.com/darosior/bitcoin/blob/bip54_miner/src/test/bip54_premined_headers.h

View File

@ -0,0 +1,80 @@
[
{
"block_chain": [
"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab5f49ffff001d1dac2b7c0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000",
"010000006fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d619000000000068fcdbe419c7d12484fd7e1f7cc22c98e4afab982539e2333ca8ce9a317a592f81ad5f49ffff001d846f5e090101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff025100feffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000",
"01000000a58a17b4a4487b9c83ab80ed6a9ccbb9de25925193cc084f41872bd700000000462c6597dd11214ae6f20905dc3828c000a693c3e4b17df82469e528dd9eeab8d9af5f49ffff001dd6bbd40a0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff05520360ae0afeffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac01000000",
"010000005702226e10bfe0b24a41a05f406c73046b9ad6fca09255968d3a954b00000000d72d147d9b46612e6adb7168821448e3eca3231ffce8c812a1503ab30001e3bd31b25f49ffff001d7b1408060101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff05530320d613feffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac02000000",
"01000000131cda7ce756b84bd95dd3ee07333f2224e286bb9a5e13ed99613746000000003e699c73b70d61674235d749cfcc240c91df1b658ab774fce2779679f6867d4189b45f49ffff001dc1adcf010101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff055403e0c810feffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac15000000"
],
"valid": false,
"comment": "Block at height 4 with coinbase's nLockTime set to 21 and non-final nSequence."
},
{
"block_chain": [
"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab5f49ffff001d1dac2b7c0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000",
"010000006fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d619000000000068fcdbe419c7d12484fd7e1f7cc22c98e4afab982539e2333ca8ce9a317a592f81ad5f49ffff001d846f5e090101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff025100feffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000",
"01000000a58a17b4a4487b9c83ab80ed6a9ccbb9de25925193cc084f41872bd700000000462c6597dd11214ae6f20905dc3828c000a693c3e4b17df82469e528dd9eeab8d9af5f49ffff001dd6bbd40a0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff05520360ae0afeffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac01000000",
"010000005702226e10bfe0b24a41a05f406c73046b9ad6fca09255968d3a954b00000000d72d147d9b46612e6adb7168821448e3eca3231ffce8c812a1503ab30001e3bd31b25f49ffff001d7b1408060101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff05530320d613feffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac02000000",
"01000000131cda7ce756b84bd95dd3ee07333f2224e286bb9a5e13ed996137460000000082cf0907a8dfb0b461f9c3f4a807cff5fb85df8e54fcc5d8b5a6208b1144fac289b45f49ffff001d094390190101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff05540320d613921000000100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac04000000"
],
"valid": false,
"comment": "Block at height 4 with coinbase's nLockTime set to 4 and non-final nSequence."
},
{
"block_chain": [
"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab5f49ffff001d1dac2b7c0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000",
"010000006fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d619000000000068fcdbe419c7d12484fd7e1f7cc22c98e4afab982539e2333ca8ce9a317a592f81ad5f49ffff001d846f5e090101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff025100feffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000",
"01000000a58a17b4a4487b9c83ab80ed6a9ccbb9de25925193cc084f41872bd700000000462c6597dd11214ae6f20905dc3828c000a693c3e4b17df82469e528dd9eeab8d9af5f49ffff001dd6bbd40a0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff05520360ae0afeffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac01000000",
"010000005702226e10bfe0b24a41a05f406c73046b9ad6fca09255968d3a954b00000000d72d147d9b46612e6adb7168821448e3eca3231ffce8c812a1503ab30001e3bd31b25f49ffff001d7b1408060101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff05530320d613feffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac02000000",
"01000000131cda7ce756b84bd95dd3ee07333f2224e286bb9a5e13ed9961374600000000da08acbf43b797bea5a20bb65f0a02871f6272cd0dbd5d192de0b8b241a285aa89b45f49ffff001d5077290a0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff055403400d03feffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac02000000"
],
"valid": false,
"comment": "Block at height 4 with coinbase's nLockTime set to 2 and non-final nSequence."
},
{
"block_chain": [
"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab5f49ffff001d1dac2b7c0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000",
"010000006fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d619000000000068fcdbe419c7d12484fd7e1f7cc22c98e4afab982539e2333ca8ce9a317a592f81ad5f49ffff001d846f5e090101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff025100feffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000",
"01000000a58a17b4a4487b9c83ab80ed6a9ccbb9de25925193cc084f41872bd700000000462c6597dd11214ae6f20905dc3828c000a693c3e4b17df82469e528dd9eeab8d9af5f49ffff001dd6bbd40a0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff05520360ae0afeffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac01000000",
"010000005702226e10bfe0b24a41a05f406c73046b9ad6fca09255968d3a954b00000000d72d147d9b46612e6adb7168821448e3eca3231ffce8c812a1503ab30001e3bd31b25f49ffff001d7b1408060101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff05530320d613feffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac02000000",
"01000000131cda7ce756b84bd95dd3ee07333f2224e286bb9a5e13ed99613746000000000035fba8f8f05b94463822ffd007213ff095c4b82e5bc166fd51c8ba01e0659189b45f49ffff001d394a4d070101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff025400fb4003000100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac03000000"
],
"valid": true,
"comment": "Block at height 4 with coinbase's nLockTime set to 3 and non-final nSequence."
},
{
"block_chain": [
"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab5f49ffff001d1dac2b7c0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000",
"010000006fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d619000000000068fcdbe419c7d12484fd7e1f7cc22c98e4afab982539e2333ca8ce9a317a592f81ad5f49ffff001d846f5e090101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff025100feffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000",
"01000000a58a17b4a4487b9c83ab80ed6a9ccbb9de25925193cc084f41872bd700000000462c6597dd11214ae6f20905dc3828c000a693c3e4b17df82469e528dd9eeab8d9af5f49ffff001dd6bbd40a0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff05520360ae0afeffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac01000000",
"010000005702226e10bfe0b24a41a05f406c73046b9ad6fca09255968d3a954b00000000d72d147d9b46612e6adb7168821448e3eca3231ffce8c812a1503ab30001e3bd31b25f49ffff001d7b1408060101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff05530320d613feffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac02000000",
"01000000131cda7ce756b84bd95dd3ee07333f2224e286bb9a5e13ed9961374600000000e7822dba53b0868472211017555701e69bbd9c3e2ec5502347dce64e963cff0989b45f49ffff001dfb8e6e110101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff05540360ae0afeffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac03000000"
],
"valid": true,
"comment": "Block at height 4 with coinbase's nLockTime set to 3 and maximum non-final nSequence."
},
{
"block_chain": [
"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab5f49ffff001d1dac2b7c0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000",
"010000006fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d619000000000068fcdbe419c7d12484fd7e1f7cc22c98e4afab982539e2333ca8ce9a317a592f81ad5f49ffff001d846f5e090101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff025100feffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000",
"01000000a58a17b4a4487b9c83ab80ed6a9ccbb9de25925193cc084f41872bd700000000462c6597dd11214ae6f20905dc3828c000a693c3e4b17df82469e528dd9eeab8d9af5f49ffff001dd6bbd40a0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff05520360ae0afeffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac01000000",
"010000005702226e10bfe0b24a41a05f406c73046b9ad6fca09255968d3a954b00000000d72d147d9b46612e6adb7168821448e3eca3231ffce8c812a1503ab30001e3bd31b25f49ffff001d7b1408060101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff05530320d613feffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac02000000",
"01000000131cda7ce756b84bd95dd3ee07333f2224e286bb9a5e13ed9961374600000000a392d0e70a32b369e2ec509ec0b5cdfad3db5f78d594f855588d6193d7e5bef889b45f49ffff001d5ec3630c0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff05540320d613ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac03000000"
],
"valid": false,
"comment": "Block at height 4 with coinbase's nLockTime set to 3 and final nSequence."
},
{
"block_chain": [
"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab5f49ffff001d1dac2b7c0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000",
"010000006fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d619000000000068fcdbe419c7d12484fd7e1f7cc22c98e4afab982539e2333ca8ce9a317a592f81ad5f49ffff001d846f5e090101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff025100feffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000",
"01000000a58a17b4a4487b9c83ab80ed6a9ccbb9de25925193cc084f41872bd700000000462c6597dd11214ae6f20905dc3828c000a693c3e4b17df82469e528dd9eeab8d9af5f49ffff001dd6bbd40a0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff05520360ae0afeffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac01000000",
"010000005702226e10bfe0b24a41a05f406c73046b9ad6fca09255968d3a954b00000000d72d147d9b46612e6adb7168821448e3eca3231ffce8c812a1503ab30001e3bd31b25f49ffff001d7b1408060101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff05530320d613feffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac02000000",
"01000000131cda7ce756b84bd95dd3ee07333f2224e286bb9a5e13ed99613746000000002be83903e9da68744e4da285d3641faf33694531e1717724d415265bc987bfbb89b45f49ffff001dbfe17c1f0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff05540340420ffeffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac88b45f49"
],
"valid": false,
"comment": "Block at height 4 with coinbase's nLockTime set to block's nTime minus 1 and maximum non-final nSequence."
}
]

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,67 @@
[
{
"comment": "A 63-byte legacy transaction.",
"tx": "0200000001827da3d85a6547d6b03662d2cb86982d655a6f390547285a3bf9ec9f28e0c8831500000000ffffffff0100000000000000000300515200000000",
"valid": true
},
{
"comment": "A 61-byte legacy transaction with a witness.",
"tx": "02000000000101827da3d85a6547d6b03662d2cb86982d655a6f390547285a3bf9ec9f28e0c8831500000000ffffffff01000000000000000000010000000000",
"valid": true
},
{
"comment": "A 64-byte legacy transaction (4 bytes in spk).",
"tx": "0200000001827da3d85a6547d6b03662d2cb86982d655a6f390547285a3bf9ec9f28e0c8831500000000ffffffff010000000000000000040051525400000000",
"valid": false
},
{
"comment": "A 64-byte legacy transaction (4 bytes in scriptsig).",
"tx": "0200000001827da3d85a6547d6b03662d2cb86982d655a6f390547285a3bf9ec9f28e0c883150000000403424242ffffffff010040075af07507000000000000",
"valid": false
},
{
"comment": "A 65-byte legacy transaction.",
"tx": "0200000001827da3d85a6547d6b03662d2cb86982d655a6f390547285a3bf9ec9f28e0c8831500000000ffffffff01000000000000000005005152545800000000",
"valid": true
},
{
"comment": "A 64-byte Segwit transaction.",
"tx": "02000000000101827da3d85a6547d6b03662d2cb86982d655a6f390547285a3bf9ec9f28e0c8831500000000ffffffff01000000000000000004005152540108213245576281941200000000",
"valid": false
},
{
"comment": "A 64-byte Segwit transaction (1 p2tr input, 1 p2a output).",
"tx": "02000000000101827da3d85a6547d6b03662d2cb86982d655a6f390547285a3bf9ec9f28e0c8831500000000ffffffff0100000000000000000451024e7301415a78b5a14a2527feb02c08b8124e74c3b9bcc1bd3dba1fbfa87f1c930f28a46fea2bf375105dfd835e212c9127aad4976c46ef86be02edbb681e6f38f9a9e06f0100000000",
"valid": false
},
{
"comment": "A 64-byte Segwit transaction (1 p2tr input with annex, 1 OP_RETURN output).",
"tx": "02000000000101827da3d85a6547d6b03662d2cb86982d655a6f390547285a3bf9ec9f28e0c8831500000000ffffffff010000000000000000046a02ab0102415a78b5a14a2527feb02c08b8124e74c3b9bcc1bd3dba1fbfa87f1c930f28a46fea2bf375105dfd835e212c9127aad4976c46ef86be02edbb681e6f38f9a9e06f01064242ffab212100000000",
"valid": false
},
{
"comment": "Historical 64-byte transaction 892f44a49de6f5b212cdbea514d09e692d9fed5d897f37bcef14bd0eedebf193",
"tx": "0200000001deb98691723fa71260ffca6ea0a7bc0a63b0a8a366e1b585caad47fb269a2ce401000000030251b201000000010000000000000000016a00000000",
"valid": false
},
{
"comment": "Historical 64-byte transaction bbf71454857438c6dfd64c0d92a7c5360a8d8d57c9202f5806449e5b0d26b848",
"tx": "01000000010d0afe3d74062ee60c0ec55579d691d8c8af5c04eb97b777157a21a8c5fb143d00000000035101b100000000010000000000000000016a01000000",
"valid": false
},
{
"comment": "Historical 64-byte transaction 6713d61a83e3d095582211ea8d6db452ac7561e863decba7c4046fb9f6d88aa0",
"tx": "02000000011658a33df410379bb512206659910c9fbd0e50bfb732f7be9936558ff036919401000000035101b201000000010000000000000000016a00000000",
"valid": false
},
{
"comment": "Historical 64-byte transaction 7f2efc6546011ad3227b2da678be0d30c7f4b08e2ce57b5edadd437f9e27a612",
"tx": "02000000011a7a4cf262fb7e53e2e6e0b2ef8b763f6ee97d8681ca968d1938418d56e6c38700000000035101b201000000010000000000000000016a00000000",
"valid": false
},
{
"comment": "Historical 64-byte transaction 5302e01dc4b7e34314a34c7c3347107e612b9524be684d388cd4d2ca35ff1ec9",
"tx": "01000000019222bbb054bb9f94571dfe769af5866835f2a97e883959fa757de4064bed8bca01000000035101b100000000010000000000000000016a01000000",
"valid": false
}
]

View File

@ -2,12 +2,12 @@
BIP: 60
Layer: Peer Services
Title: Fixed Length "version" Message (Relay-Transactions Field)
Author: Amir Taaki <genjix@riseup.net>
Authors: Amir Taaki <genjix@riseup.net>
Comments-Summary: Discouraged for implementation (one person)
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0060
Status: Draft
Type: Standards Track
Created: 2013-06-16
Status: Closed
Type: Specification
Assigned: 2013-06-16
License: PD
</pre>
@ -23,14 +23,14 @@ The implementation is problematic because the RelayTransactions flag is an optio
One property of Bitcoin messages is their fixed number of fields. This keeps the format simple and easily understood. Adding optional fields to messages will cause deserialisation issues when other fields come after the optional one.
As an example, the length of version messages might be checked to ensure the byte stream is consistent. With optional fields, this checking is no longer possible. This is desirable to check for consistency inside internal deserialization code, and proper formatting of version messages originating from other nodes. In the future with diversification of the Bitcoin network, it will become desirable to enforce this kind of strict adherance to standard messages with field length compliance with every protocol version.
As an example, the length of version messages might be checked to ensure the byte stream is consistent. With optional fields, this checking is no longer possible. This is desirable to check for consistency inside internal deserialization code, and proper formatting of version messages originating from other nodes. In the future with diversification of the Bitcoin network, it will become desirable to enforce this kind of strict adherence to standard messages with field length compliance with every protocol version.
Another property of fixed-length field messages is the ability to pass stream operators around for deserialization. This property is also lost, as now the deserialisation code must know the remaining length of bytes to parse. The parser now requires an additional piece of information (remaining size of the stream) for parsing instead of being a dumb reader.
==Specification==
=== version ===
When a node creates an outgoing connection, it will immediately advertise its version. The remote node will respond with its version. No futher communication is possible until both peers have exchanged their version.
When a node creates an outgoing connection, it will immediately advertise its version. The remote node will respond with its version. No further communication is possible until both peers have exchanged their version.
Payload:

View File

@ -2,12 +2,12 @@
BIP: 61
Layer: Peer Services
Title: Reject P2P message
Author: Gavin Andresen <gavinandresen@gmail.com>
Authors: Gavin Andresen <gavinandresen@gmail.com>
Comments-Summary: Controversial; some recommendation, and some discouragement
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0061
Status: Final
Type: Standards Track
Created: 2014-06-18
Status: Deployed
Type: Specification
Assigned: 2014-06-18
</pre>
==Abstract==
@ -57,7 +57,7 @@ Every reject message begins with the following fields. Some messages append extr
|}
The human-readable string is intended only for debugging purposes; in particular, different implementations may
use different strings. The string should not be shown to users or used for anthing besides diagnosing
use different strings. The string should not be shown to users or used for anything besides diagnosing
interoperability problems.
The following reject code categories are used; in the descriptions below, "server" is the peer generating
@ -149,7 +149,7 @@ The reject message is backwards-compatible; older peers that do not recognize th
== Implementation notes ==
Implementors must consider what happens if an attacker either sends them
Implementers must consider what happens if an attacker either sends them
reject messages for valid transactions/blocks or sends them random
reject messages, and should beware of possible denial-of-service attacks.
For example, notifying the user of every reject message received

View File

@ -4,12 +4,10 @@
BIP: 62
Layer: Consensus (soft fork)
Title: Dealing with malleability
Author: Pieter Wuille <pieter.wuille@gmail.com>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0062
Status: Withdrawn
Type: Standards Track
Created: 2014-03-12
Authors: Pieter Wuille <pieter.wuille@gmail.com>
Status: Closed
Type: Specification
Assigned: 2014-03-12
License: BSD-2-Clause
</pre>
@ -34,7 +32,7 @@ Several sources of malleability are known:
# '''Non-DER encoded ECDSA signatures''' Right now, the Bitcoin reference client uses OpenSSL to validate signatures. As OpenSSL accepts more than serializations that strictly adhere to the DER standard, this is a source of malleability. Since v0.8.0, non-DER signatures are no longer relayed already.
# '''Non-push operations in scriptSig''' Any sequence of script operations in scriptSig that results in the intended data pushes, but is not just a push of that data, results in an alternative transaction with the same validity.
# '''Push operations in scriptSig of non-standard size type''' The Bitcoin scripting language has several push operators (OP_0, single-byte pushes, data pushes of up to 75 bytes, OP_PUSHDATA1, OP_PUSHDATA2, OP_PUSHDATA4). As the later ones have the same result as the former ones, they result in additional possibilities.
# '''Push operations in scriptSig of non-standard size type''' The Bitcoin scripting language has several push operators (OP_0, single-byte pushes, data pushes of up to 75 bytes, OP_PUSHDATA1, OP_PUSHDATA2, OP_PUSHDATA4). As the latter ones have the same result as the former ones, they result in additional possibilities.
# '''Zero-padded number pushes''' In cases where scriptPubKey opcodes use inputs that are interpreted as numbers, they can be zero padded.
# '''Inherent ECDSA signature malleability''' ECDSA signatures themselves are already malleable: taking the negative of the number S inside (modulo the curve order) does not invalidate it.
# '''Superfluous scriptSig operations''' Adding extra data pushes at the start of scripts, which are not consumed by the corresponding scriptPubKey, is also a source of malleability.

View File

@ -2,12 +2,10 @@
BIP: 64
Layer: Peer Services
Title: getutxo message
Author: Mike Hearn <hearn@vinumeris.com>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0064
Status: Obsolete
Type: Standards Track
Created: 2014-06-10
Authors: Mike Hearn <hearn@vinumeris.com>
Status: Closed
Type: Specification
Assigned: 2014-06-10
</pre>
==Abstract==
@ -86,7 +84,7 @@ If the requesting client is looking up outputs for a signed transaction that the
client can partly verify the returned output by running the input scripts with it. Currently this
verifies only that the script is correct. A future version of the Bitcoin protocol is likely to also
allow the value to be checked in this way. It does not show that the output is really unspent or was
ever actually created in the block chain however. Additionally, the form of the provided scriptPubKey
ever actually created in the block chain however. Additionally, the form of the provided scriptPubKey
should be checked before execution to ensure the remote peer doesn't just set the script to OP_TRUE.
If the requesting client has a mapping of chain heights to block hashes in the best chain e.g.

View File

@ -2,12 +2,10 @@
BIP: 65
Layer: Consensus (soft fork)
Title: OP_CHECKLOCKTIMEVERIFY
Author: Peter Todd <pete@petertodd.org>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0065
Status: Final
Type: Standards Track
Created: 2014-10-01
Authors: Peter Todd <pete@petertodd.org>
Status: Deployed
Type: Specification
Assigned: 2014-10-01
License: PD
</pre>
@ -170,7 +168,7 @@ Proving the sacrifice of some limited resource is a common technique in a
variety of cryptographic protocols. Proving sacrifices of coins to mining fees
has been proposed as a ''universal public good'' to which the sacrifice could
be directed, rather than simply destroying the coins. However doing so is
non-trivial, and even the best existing technqiue - announce-commit sacrifices
non-trivial, and even the best existing technique - announce-commit sacrifices
- could encourage mining centralization. CHECKLOCKTIMEVERIFY can be used to
create outputs that are provably spendable by anyone (thus to mining fees
assuming miners behave optimally and rationally) but only at a time
@ -205,19 +203,19 @@ transaction output ''can'' be spent.
Refer to the reference implementation, reproduced below, for the precise
semantics and detailed rationale for those semantics.
case OP_NOP2:
{
// CHECKLOCKTIMEVERIFY
//
// (nLockTime -- nLockTime )
if (!(flags & SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY))
break; // not enabled; treat as a NOP
if (stack.size() < 1)
return false;
// Note that elsewhere numeric opcodes are limited to
// operands in the range -2**31+1 to 2**31-1, however it is
// legal for opcodes to produce results exceeding that
@ -233,13 +231,13 @@ semantics and detailed rationale for those semantics.
// to 5-byte bignums, which are good until 2**32-1, the
// same limit as the nLockTime field itself.
const CScriptNum nLockTime(stacktop(-1), 5);
// In the rare event that the argument may be < 0 due to
// some arithmetic being done first, you can always use
// 0 MAX CHECKLOCKTIMEVERIFY.
if (nLockTime < 0)
return false;
// There are two types of nLockTime: lock-by-blockheight
// and lock-by-blocktime, distinguished by whether
// nLockTime < LOCKTIME_THRESHOLD.
@ -252,12 +250,12 @@ semantics and detailed rationale for those semantics.
(txTo.nLockTime >= LOCKTIME_THRESHOLD && nLockTime >= LOCKTIME_THRESHOLD)
))
return false;
// Now that we know we're comparing apples-to-apples, the
// comparison is a simple numeric one.
if (nLockTime > (int64_t)txTo.nLockTime)
return false;
// Finally the nLockTime feature can be disabled and thus
// CHECKLOCKTIMEVERIFY bypassed if every txin has been
// finalized by setting nSequence to maxint. The
@ -270,9 +268,9 @@ semantics and detailed rationale for those semantics.
// required to prove correct CHECKLOCKTIMEVERIFY execution.
if (txTo.vin[nIn].IsFinal())
return false;
break;
}
https://github.com/petertodd/bitcoin/commit/ab0f54f38e08ee1e50ff72f801680ee84d0f1bf4

View File

@ -2,12 +2,10 @@
BIP: 66
Layer: Consensus (soft fork)
Title: Strict DER signatures
Author: Pieter Wuille <pieter.wuille@gmail.com>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0066
Status: Final
Type: Standards Track
Created: 2015-01-10
Authors: Pieter Wuille <pieter.wuille@gmail.com>
Status: Deployed
Type: Specification
Assigned: 2015-01-10
License: BSD-2-Clause
</pre>
@ -75,7 +73,7 @@ bool static IsValidSignatureEncoding(const std::vector<unsigned char> &sig) {
// Verify that the length of the signature matches the sum of the length
// of the elements.
if ((size_t)(lenR + lenS + 7) != sig.size()) return false;
// Check whether the R element is an integer.
if (sig[2] != 0x02) return false;
@ -140,7 +138,7 @@ An implementation for the reference client is available at https://github.com/bi
==Acknowledgements==
This document is extracted from the previous BIP62 proposal, which had input from various people, in particular Greg Maxwell and Peter Todd, who gave feedback about this document as well.
This document is extracted from the previous BIP62 proposal, which had input from various people, in particular Greg Maxwell and Peter Todd, who gave feedback about this document as well.
==Disclosures==

View File

@ -2,14 +2,12 @@
BIP: 67
Layer: Applications
Title: Deterministic Pay-to-script-hash multi-signature addresses through public key sorting
Author: Thomas Kerin <me@thomaskerin.io>
Jean-Pierre Rupp <root@haskoin.com>
Ruben de Vries <ruben@rubensayshi.com>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0067
Status: Proposed
Type: Standards Track
Created: 2015-02-08
Authors: Thomas Kerin <me@thomaskerin.io>
Jean-Pierre Rupp <root@haskoin.com>
Ruben de Vries <ruben@rubensayshi.com>
Status: Complete
Type: Specification
Assigned: 2015-02-08
License: PD
</pre>
@ -19,7 +17,7 @@ This BIP describes a method to deterministically generate multi-signature pay-to
==Motivation==
Pay-to-script-hash (BIP-0011<ref>[https://github.com/bitcoin/bips/blob/master/bip-0011.mediawiki BIP-0011]</ref>) is a transaction type that allows funding of arbitrary scripts, where the recipient carries the cost of fee's associated with using longer, more complex scripts.
Pay-to-script-hash (BIP-0011<ref>[https://github.com/bitcoin/bips/blob/master/bip-0011.mediawiki BIP-0011]</ref>) is a transaction type that allows funding of arbitrary scripts, where the recipient carries the cost of fee's associated with using longer, more complex scripts.
Multi-signature pay-to-script-hash transactions are defined in BIP-0016<ref>[https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki BIP-0016]</ref>. The redeem script does not require a particular ordering or encoding for public keys. This means that for a given set of keys and number of required signatures, there are as many as 2(n!) possible standard redeem scripts, each with its separate P2SH address. Adhering to an ordering and key encoding would ensure that a multi-signature “account” (set of public keys and required signature count) has a canonical P2SH address.
@ -27,36 +25,36 @@ By adopting a sorting and encoding standard, compliant wallets will always produ
While most web wallets do not presently facilitate the setup of multisignature accounts with users of a different service, conventions which ensure cross-compatibility should make it easier to achieve this.
Many wallet as a service providers use a 2of3 multi-signature schema where the user stores 1 of the keys (offline) as backup while using the other key for daily use and letting the service cosign his transactions.
Many wallet as a service providers use a 2of3 multi-signature schema where the user stores 1 of the keys (offline) as backup while using the other key for daily use and letting the service cosign his transactions.
This standard will help in enabling a party other than the service provider to recover the wallet without any help from the service provider.
==Specification==
For a set of public keys, ensure that they have been received in compressed form:
022df8750480ad5b26950b25c7ba79d3e37d75f640f8e5d9bcd5b150a0f85014da
03e3818b65bcc73a7d64064106a859cc1a5a728c4345ff0b641209fba0d90de6e9
03e3818b65bcc73a7d64064106a859cc1a5a728c4345ff0b641209fba0d90de6e9
021f2f6e1e50cb6a953935c3601284925decd3fd21bc445712576873fb8c6ebc18
Sort them lexicographically according to their binary representation:
Sort them lexicographically according to their binary representation:
021f2f6e1e50cb6a953935c3601284925decd3fd21bc445712576873fb8c6ebc18
022df8750480ad5b26950b25c7ba79d3e37d75f640f8e5d9bcd5b150a0f85014da
03e3818b65bcc73a7d64064106a859cc1a5a728c4345ff0b641209fba0d90de6e9
..before using the resulting list of keys in a standard multisig redeem script:
..before using the resulting list of keys in a standard multisig redeem script:
OP_2 021f2f6e1e50cb6a953935c3601284925decd3fd21bc445712576873fb8c6ebc18 022df8750480ad5b26950b25c7ba79d3e37d75f640f8e5d9bcd5b150a0f85014da 03e3818b65bcc73a7d64064106a859cc1a5a728c4345ff0b641209fba0d90de6e9 OP_3 OP_CHECKMULTISIG
Hash the redeem script according to BIP-0016 to get the P2SH address.
3Q4sF6tv9wsdqu2NtARzNCpQgwifm2rAba
==Compatibility==
* Uncompressed keys are incompatible with this specificiation. A compatible implementation should not automatically compress keys. Receiving an uncompressed key from a multisig participant should be interpreted as a sign that the user has an incompatible implementation.
* P2SH addressses do not reveal information about the script that is receiving the funds. For this reason it is not technically possible to enforce this BIP as a rule on the network. Also, it would cause a hard fork.
* Uncompressed keys are incompatible with this specification. A compatible implementation should not automatically compress keys. Receiving an uncompressed key from a multisig participant should be interpreted as a sign that the user has an incompatible implementation.
* P2SH addresses do not reveal information about the script that is receiving the funds. For this reason it is not technically possible to enforce this BIP as a rule on the network. Also, it would cause a hard fork.
* Implementations that do not conform with this BIP will have compatibility issues with strictly-compliant wallets.
* Implementations which do adopt this standard will be cross-compatible when choosing multisig addressses.
* Implementations which do adopt this standard will be cross-compatible when choosing multisig addresses.
* If a group of users were not entirely compliant, there is the possibility that a participant will derive an address that the others will not recognize as part of the common multisig account.
==Test vectors==
@ -75,11 +73,11 @@ Vector 1
** 39bgKC7RFbpoCRbtD5KEdkYKtNyhpsNa3Z
Vector 2 (Already sorted, no action required)
* List:
* List:
** 02632b12f4ac5b1d1b72b2a3b508c19172de44f6f46bcee50ba33f3f9291e47ed0
** 027735a29bae7780a9755fae7a1c4374c656ac6a69ea9f3697fda61bb99a4f3e77
** 02e2cc6bd5f45edd43bebe7cb9b675f0ce9ed3efe613b177588290ad188d11b404
* Sorted:
* Sorted:
** 02632b12f4ac5b1d1b72b2a3b508c19172de44f6f46bcee50ba33f3f9291e47ed0
** 027735a29bae7780a9755fae7a1c4374c656ac6a69ea9f3697fda61bb99a4f3e77
** 02e2cc6bd5f45edd43bebe7cb9b675f0ce9ed3efe613b177588290ad188d11b404
@ -89,12 +87,12 @@ Vector 2 (Already sorted, no action required)
** 3CKHTjBKxCARLzwABMu9yD85kvtm7WnMfH
Vector 3:
* List:
* List:
** 030000000000000000000000000000000000004141414141414141414141414141
** 020000000000000000000000000000000000004141414141414141414141414141
** 020000000000000000000000000000000000004141414141414141414141414140
** 030000000000000000000000000000000000004141414141414141414141414140
* Sorted:
* Sorted:
** 020000000000000000000000000000000000004141414141414141414141414140
** 020000000000000000000000000000000000004141414141414141414141414141
** 030000000000000000000000000000000000004141414141414141414141414140
@ -105,11 +103,11 @@ Vector 3:
** 32V85igBri9zcfBRVupVvwK18NFtS37FuD
Vector 4: (from bitcore)
* List:
* List:
** 022df8750480ad5b26950b25c7ba79d3e37d75f640f8e5d9bcd5b150a0f85014da
** 03e3818b65bcc73a7d64064106a859cc1a5a728c4345ff0b641209fba0d90de6e9
** 03e3818b65bcc73a7d64064106a859cc1a5a728c4345ff0b641209fba0d90de6e9
** 021f2f6e1e50cb6a953935c3601284925decd3fd21bc445712576873fb8c6ebc18
* Sorted:
* Sorted:
** 021f2f6e1e50cb6a953935c3601284925decd3fd21bc445712576873fb8c6ebc18
** 022df8750480ad5b26950b25c7ba79d3e37d75f640f8e5d9bcd5b150a0f85014da
** 03e3818b65bcc73a7d64064106a859cc1a5a728c4345ff0b641209fba0d90de6e9
@ -119,14 +117,14 @@ Vector 4: (from bitcore)
** 3Q4sF6tv9wsdqu2NtARzNCpQgwifm2rAba
==Acknowledgements==
The authors wish to thank BtcDrak and Luke-Jr for their involvement & contributions in the early discussions of this BIP.
The authors wish to thank BtcDrak and Luke-Jr for their involvement & contributions in the early discussions of this BIP.
==Usage & Implementations==
* [[https://github.com/bitcoin/bips/blob/master/bip-0045.mediawiki#address-generation-procedure|BIP-0045]] - Structure for Deterministic P2SH Multisignature Wallets
* [[https://github.com/bitpay/bitcore/blob/50a868cb8cdf2be04bb1c5bf4bcc064cc06f5888/lib/script/script.js#L541|Bitcore]]
==Usage & Implementations==
* [[https://github.com/bitcoin/bips/blob/master/bip-0045.mediawiki#address-generation-procedure|BIP-0045]] - Structure for Deterministic P2SH Multisignature Wallets
* [[https://github.com/bitpay/bitcore/blob/50a868cb8cdf2be04bb1c5bf4bcc064cc06f5888/lib/script/script.js#L541|Bitcore]]
* [[https://github.com/haskoin/haskoin-core/blob/b41b1deb0989334a7ead6fc993fb8b02f0c00810/haskoin-core/Network/Haskoin/Script/Parser.hs#L112-L122|Haskoin]] - Bitcoin implementation in Haskell
* [[https://github.com/etotheipi/BitcoinArmory/blob/268db0f3fa20c989057bd43343a43b2edbe89aeb/armoryengine/ArmoryUtils.py#L1441|Armory]]
* [[https://github.com/bitcoinj/bitcoinj/blob/master/core/src/main/java/org/bitcoinj/script/ScriptBuilder.java#L331|BitcoinJ]]
* [[https://github.com/etotheipi/BitcoinArmory/blob/268db0f3fa20c989057bd43343a43b2edbe89aeb/armoryengine/ArmoryUtils.py#L1441|Armory]]
* [[https://github.com/bitcoinj/bitcoinj/blob/f7ea0b92a619800c143b0142dc70306da33119a9/core/src/main/java/org/bitcoinj/script/ScriptBuilder.java#L331|BitcoinJ]]
== References ==
<references>

View File

@ -2,15 +2,13 @@
BIP: 68
Layer: Consensus (soft fork)
Title: Relative lock-time using consensus-enforced sequence numbers
Author: Mark Friedenbach <mark@friedenbach.org>
BtcDrak <btcdrak@gmail.com>
Nicolas Dorier <nicolas.dorier@gmail.com>
kinoshitajona <kinoshitajona@gmail.com>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0068
Status: Final
Type: Standards Track
Created: 2015-05-28
Authors: Mark Friedenbach <mark@friedenbach.org>
BtcDrak <btcdrak@gmail.com>
Nicolas Dorier <nicolas.dorier@gmail.com>
kinoshitajona <kinoshitajona@gmail.com>
Status: Deployed
Type: Specification
Assigned: 2015-05-28
</pre>
==Abstract==
@ -21,7 +19,7 @@ This BIP introduces relative lock-time (RLT) consensus-enforced semantics of the
Bitcoin transactions have a sequence number field for each input. The original idea appears to have been that a transaction in the mempool would be replaced by using the same input with a higher sequence value. Although this was not properly implemented, it assumes miners would prefer higher sequence numbers even if the lower ones were more profitable to mine. However, a miner acting on profit motives alone would break that assumption completely. The change described by this BIP repurposes the sequence number for new use cases without breaking existing functionality. It also leaves room for future expansion and other use cases.
The transaction nLockTime is used to prevent the mining of a transaction until a certain date. nSequence will be repurposed to prevent mining of a transaction until a certain age of the spent output in blocks or timespan. This, among other uses, allows bi-directional payment channels as used in [https://github.com/ElementsProject/lightning/raw/master/doc/deployable-lightning.pdf Hashed Timelock Contracts (HTLCs)] and [https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki#Bidirectional_Payment_Channels BIP112].
The transaction nLockTime is used to prevent the mining of a transaction until a certain date. nSequence will be repurposed to prevent mining of a transaction until a certain age of the spent output in blocks or timespan. This, among other uses, allows bi-directional payment channels as used in [https://github.com/ElementsProject/lightning/raw/master/doc/miscellaneous/deployable-lightning.pdf Hashed Timelock Contracts (HTLCs)] and [https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki#Bidirectional_Payment_Channels BIP112].
==Specification==
@ -33,7 +31,7 @@ If bit (1 << 31) of the sequence number is set, then no consensus meaning is app
If bit (1 << 31) of the sequence number is not set, then the sequence number is interpreted as an encoded relative lock-time.
The sequence number encoding is interpreted as follows:
The sequence number encoding is interpreted as follows:
Bit (1 << 22) determines if the relative lock-time is time-based or block based: If the bit is set, the relative lock-time specifies a timespan in units of 512 seconds granularity. The timespan starts from the median-time-past of the outputs previous block, and ends at the MTP of the previous block. If the bit is not set, the relative lock-time specifies a number of blocks.
@ -65,7 +63,7 @@ enum {
/* Interpret sequence numbers as relative lock-time constraints. */
LOCKTIME_VERIFY_SEQUENCE = (1 << 0),
};
/* Setting nSequence to this value for every input in a transaction
* disables nLockTime. */
static const uint32_t SEQUENCE_FINAL = 0xffffffff;
@ -203,7 +201,7 @@ bool CheckSequenceLocks(const CTransaction &tx, int flags)
return error("%s: Missing input", __func__);
}
if (coins.nHeight == MEMPOOL_HEIGHT) {
// Assume all mempool transaction confirm in the next block
// Assume all mempool transactions are confirmed in the next block
prevheights[txinIndex] = tip->nHeight + 1;
} else {
prevheights[txinIndex] = coins.nHeight;
@ -242,10 +240,10 @@ Additionally, this BIP specifies only 16 bits to actually encode relative lock-t
The most efficient way to calculate sequence number from relative lock-time is with bit masks and shifts:
<pre>
// 0 <= nHeight < 65,535 blocks (1.25 years)
// 0 <= nHeight <= 65,535 blocks (1.25 years)
nSequence = nHeight;
nHeight = nSequence & 0x0000ffff;
// 0 <= nTime < 33,554,431 seconds (1.06 years)
nSequence = (1 << 22) | (nTime >> 9);
nTime = (nSequence & 0x0000ffff) << 9;
@ -261,5 +259,5 @@ BIP112: https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki
BIP113: https://github.com/bitcoin/bips/blob/master/bip-0113.mediawiki
Hashed Timelock Contracts (HTLCs): https://github.com/ElementsProject/lightning/raw/master/doc/deployable-lightning.pdf
Hashed Timelock Contracts (HTLCs): https://github.com/ElementsProject/lightning/raw/master/doc/miscellaneous/deployable-lightning.pdf

View File

@ -2,13 +2,11 @@
BIP: 69
Layer: Applications
Title: Lexicographical Indexing of Transaction Inputs and Outputs
Author: Kristov Atlas <kristov@openbitcoinprivacyproject.org>
Authors: Kristov Atlas <kristov@openbitcoinprivacyproject.org>
Editor: Daniel Cousens <bips@dcousens.com>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0069
Status: Proposed
Status: Complete
Type: Informational
Created: 2015-06-12
Assigned: 2015-06-12
License: PD
</pre>
@ -162,7 +160,7 @@ Outputs:
* [[https://github.com/bitcoinjs/bip69/blob/master/test/fixtures.json|BitcoinJS Test Fixtures]]
* [[https://www.npmjs.com/package/bip69|NodeJS]]
* [[https://github.com/blockchain/My-Wallet-V3/blob/v3.8.0/src/transaction.js#L120-L142|Blockchain.info public beta]]
* [[https://github.com/btcsuite/btcutil/blob/master/txsort/txsort.go|Btcsuite]]
* [[https://github.com/btcsuite/btcd/blob/master/btcutil/txsort/txsort.go|Btcsuite]]
==Acknowledgements==

22
bip-0069/bip-0069_examples.py Normal file → Executable file
View File

@ -1,4 +1,6 @@
#!/usr/bin/env python3
import binascii
from functools import cmp_to_key
#returns -1 if barr1 is less, 1 if barr1 is greater, and 0 if equal
def bytearr_cmp(barr1, barr2):
@ -29,12 +31,13 @@ def input_cmp(input_tuple1, input_tuple2):
elif (input_tuple1[1] > input_tuple2[1]):
return 1
else:
raise ValueError('Matching previous transaction hash and previous transaction output index for two disinct inputs. Invalid!')
raise ValueError('Matching previous transaction hash and previous transaction output index for two distinct inputs. Invalid!')
def sort_inputs(input_tuples):
return sorted(input_tuples, cmp=input_cmp)
return sorted(input_tuples, key=cmp_to_key(input_cmp))
def print_inputs(ordered_input_tuples):
print("inputs")
index = 0
for prev_tx_hash_byte_arr_little_endian, prev_tx_output_index in ordered_input_tuples:
prev_tx_hash_hex = binascii.hexlify(bytearray(prev_tx_hash_byte_arr_little_endian))
@ -49,12 +52,13 @@ def output_cmp(output_tuple1, output_tuple2):
elif (output_tuple1[0] > output_tuple2[0]):
return 1
#tie-breaker: scriptPubKey_byte_arr
return bytearray_cmp(output_tuple1[1], output_tuple2[1])
return bytearr_cmp(output_tuple1[1], output_tuple2[1])
def sort_outputs(output_tuples):
return sorted(output_tuples, cmp=output_cmp)
return sorted(output_tuples, key=cmp_to_key(output_cmp))
def print_outputs(ordered_output_tuples):
print("outputs")
index = 0
for amount, scriptPubKey_byte_arr in ordered_output_tuples:
scriptPubKey_hex = binascii.hexlify(bytearray(scriptPubKey_byte_arr))
@ -82,6 +86,7 @@ def main():
([0x7d, 0x03, 0x7c, 0xeb, 0x2e, 0xe0, 0xdc, 0x03, 0xe8, 0x2f, 0x17, 0xbe, 0x79, 0x35, 0xd2, 0x38, 0xb3, 0x5d, 0x1d, 0xea, 0xbf, 0x95, 0x3a, 0x89, 0x2a, 0x45, 0x07, 0xbf, 0xbe, 0xeb, 0x3b, 0xa4], 1),
([0x6c, 0x1d, 0x56, 0xf3, 0x1b, 0x2d, 0xe4, 0xbf, 0xc6, 0xaa, 0xea, 0x28, 0x39, 0x6b, 0x33, 0x31, 0x02, 0xb1, 0xf6, 0x00, 0xda, 0x9c, 0x6d, 0x61, 0x49, 0xe9, 0x6c, 0xa4, 0x3f, 0x11, 0x02, 0xb1], 1),
([0xb4, 0x11, 0x2b, 0x8f, 0x90, 0x0a, 0x7c, 0xa0, 0xc8, 0xb0, 0xe7, 0xc4, 0xdf, 0xad, 0x35, 0xc6, 0xbe, 0x5f, 0x6b, 0xe4, 0x6b, 0x34, 0x58, 0x97, 0x49, 0x88, 0xe1, 0xcd, 0xb2, 0xfa, 0x61, 0xb8], 0)]
print("\ntx 0a6a357e2f7796444e02638749d9611c008b253fb55f5dc88b739b230ed0c4c3")
tx_0a6a_sorted_input_tuples = sort_inputs(tx_0a6a_input_tuples)
print_inputs(tx_0a6a_sorted_input_tuples)
@ -94,10 +99,11 @@ def main():
#reference data: https://blockchain.info/rawtx/28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f thanks @quantabytes!
tx_2820_input_tuples = [
# (prev_tx_hash, prev_tx_output_index)
("35288d269cee1941eaebb2ea85e32b42cdb2b04284a56d8b14dcc3f5c65d6055", 0),
("35288d269cee1941eaebb2ea85e32b42cdb2b04284a56d8b14dcc3f5c65d6055", 1)] #duplicate prev_tx_hash
# (prev_tx_hash_byte_arr_little_endian, prev_tx_output_index)
([0x55, 0x60, 0x5d, 0xc6, 0x5f, 0x3c, 0xcc, 0x4d, 0xb1, 0xd8, 0x56, 0x4a, 0x28, 0x04, 0x2b, 0xdb, 0x2c, 0x2b, 0xe3, 0x85, 0xea, 0xb2, 0xeb, 0xea, 0x41, 0x19, 0xee, 0x9c, 0x26, 0x8d, 0x28, 0x35], 0),
([0x55, 0x60, 0x5d, 0xc6, 0x5f, 0x3c, 0xcc, 0x4d, 0xb1, 0xd8, 0x56, 0x4a, 0x28, 0x04, 0x2b, 0xdb, 0x2c, 0x2b, 0xe3, 0x85, 0xea, 0xb2, 0xeb, 0xea, 0x41, 0x19, 0xee, 0x9c, 0x26, 0x8d, 0x28, 0x35], 1)] #duplicate prev_tx_hash
print("\ntx 28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f")
tx_2820_sorted_input_tuples = sort_inputs(tx_2820_input_tuples)
print_inputs(tx_2820_sorted_input_tuples)
@ -106,7 +112,7 @@ def main():
(100000000, [0x41, 0x04, 0x6a, 0x07, 0x65, 0xb5, 0x86, 0x56, 0x41, 0xce, 0x08, 0xdd, 0x39, 0x69, 0x0a, 0xad, 0xe2, 0x6d, 0xfb, 0xf5, 0x51, 0x14, 0x30, 0xca, 0x42, 0x8a, 0x30, 0x89, 0x26, 0x13, 0x61, 0xce, 0xf1, 0x70, 0xe3, 0x92, 0x9a, 0x68, 0xae, 0xe3, 0xd8, 0xd4, 0x84, 0x8b, 0x0c, 0x51, 0x11, 0xb0, 0xa3, 0x7b, 0x82, 0xb8, 0x6a, 0xd5, 0x59, 0xfd, 0x2a, 0x74, 0x5b, 0x44, 0xd8, 0xe8, 0xd9, 0xdf, 0xdc, 0x0c, 0xac]),
(2400000000, [0x41, 0x04, 0x4a, 0x65, 0x6f, 0x06, 0x58, 0x71, 0xa3, 0x53, 0xf2, 0x16, 0xca, 0x26, 0xce, 0xf8, 0xdd, 0xe2, 0xf0, 0x3e, 0x8c, 0x16, 0x20, 0x2d, 0x2e, 0x8a, 0xd7, 0x69, 0xf0, 0x20, 0x32, 0xcb, 0x86, 0xa5, 0xeb, 0x5e, 0x56, 0x84, 0x2e, 0x92, 0xe1, 0x91, 0x41, 0xd6, 0x0a, 0x01, 0x92, 0x8f, 0x8d, 0xd2, 0xc8, 0x75, 0xa3, 0x90, 0xf6, 0x7c, 0x1f, 0x6c, 0x94, 0xcf, 0xc6, 0x17, 0xc0, 0xea, 0x45, 0xaf, 0xac])]
tx_2820_sorted_output_tuples = sort_outputs(tx_2820_output_tuples)
print_outputs(tx_2820_output_tuples)
print_outputs(tx_2820_sorted_output_tuples)
if __name__ == "__main__":
main()

View File

@ -2,13 +2,11 @@
BIP: 70
Layer: Applications
Title: Payment Protocol
Author: Gavin Andresen <gavinandresen@gmail.com>
Mike Hearn <mhearn@bitcoinfoundation.org>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0070
Status: Final
Type: Standards Track
Created: 2013-07-29
Authors: Gavin Andresen <gavinandresen@gmail.com>
Mike Hearn <mhearn@bitcoinfoundation.org>
Status: Deployed
Type: Specification
Assigned: 2013-07-29
</pre>
==Abstract==
@ -262,7 +260,7 @@ occurs.
Trusted root certificates may be obtained from the operating system;
if validation is done on a device without an operating system, the
[http://www.mozilla.org/projects/security/certs/included/index.html Mozilla root store] is recommended.
[https://www.mozilla.org/about/governance/policies/security-group/certs/policy/ Mozilla root store] is recommended.
==Extensibility==
@ -302,7 +300,7 @@ Protocol Buffers : https://developers.google.com/protocol-buffers/
==Reference implementation==
Create Payment Request generator : https://bitcoincore.org/~gavin/createpaymentrequest.php ([[https://github.com/gavinandresen/paymentrequest|source]])
Create Payment Request generator : https://developer.bitcoin.org/examples/payment_processing.html ([[https://github.com/gavinandresen/paymentrequest|source]])
BitcoinJ : https://bitcoinj.github.io/payment-protocol#introduction

View File

@ -2,12 +2,10 @@
BIP: 71
Layer: Applications
Title: Payment Protocol MIME types
Author: Gavin Andresen <gavinandresen@gmail.com>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0071
Status: Final
Type: Standards Track
Created: 2013-07-29
Authors: Gavin Andresen <gavinandresen@gmail.com>
Status: Deployed
Type: Specification
Assigned: 2013-07-29
</pre>
==Abstract==

View File

@ -2,12 +2,10 @@
BIP: 72
Layer: Applications
Title: bitcoin: uri extensions for Payment Protocol
Author: Gavin Andresen <gavinandresen@gmail.com>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0072
Status: Final
Type: Standards Track
Created: 2013-07-29
Authors: Gavin Andresen <gavinandresen@gmail.com>
Status: Deployed
Type: Specification
Assigned: 2013-07-29
</pre>
==Abstract==
@ -69,4 +67,4 @@ bitcoin:?r=https://merchant.com/pay.php?h%3D2a8628fc2fbe
==References==
[[http://www.w3.org/Protocols/rfc2616/rfc2616.html|RFC 2616]] : Hypertext Transfer Protocol -- HTTP/1.1
[[http://www.w3.org/Protocols/rfc2616/rfc2616.html|RFC 2616]] : Hypertext Transfer Protocol -- HTTP/1.1

View File

@ -2,12 +2,10 @@
BIP: 73
Layer: Applications
Title: Use "Accept" header for response type negotiation with Payment Request URLs
Author: Stephen Pair <stephen@bitpay.com>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0073
Status: Final
Type: Standards Track
Created: 2013-08-27
Authors: Stephen Pair <stephen@bitpay.com>
Status: Deployed
Type: Specification
Assigned: 2013-08-27
</pre>
==Abstract==

View File

@ -2,12 +2,12 @@
BIP: 74
Layer: Applications
Title: Allow zero value OP_RETURN in Payment Protocol
Author: Toby Padilla <tobypadilla@gmail.com>
Authors: Toby Padilla <tobypadilla@gmail.com>
Comments-Summary: Unanimously Discourage for implementation
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0074
Status: Rejected
Type: Standards Track
Created: 2016-01-29
Status: Closed
Type: Specification
Assigned: 2016-01-29
License: PD
</pre>

View File

@ -2,15 +2,15 @@
BIP: 75
Layer: Applications
Title: Out of Band Address Exchange using Payment Protocol Encryption
Author: Justin Newton <justin@netki.com>
Matt David <mgd@mgddev.com>
Aaron Voisine <voisine@gmail.com>
James MacWhyte <macwhyte@gmail.com>
Authors: Justin Newton <justin@netki.com>
Matt David <mgd@mgddev.com>
Aaron Voisine <voisine@gmail.com>
James MacWhyte <macwhyte@gmail.com>
Comments-Summary: Recommended for implementation (one person)
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0075
Status: Final
Type: Standards Track
Created: 2015-11-20
Status: Deployed
Type: Specification
Assigned: 2015-11-20
License: CC-BY-4.0
</pre>
@ -18,11 +18,11 @@
This BIP is an extension to BIP 70 that provides two enhancements to the existing Payment Protocol.
# It allows the requester (Sender) of a PaymentRequest to voluntarily sign the original request and provide a certificate to allow the payee to know the identity of who they are transacting with.
# It allows the requester (Sender) of a PaymentRequest to voluntarily sign the original request and provide a certificate to allow the payee to know the identity of who they are transacting with.
# It encrypts the PaymentRequest that is returned, before handing it off to the SSL/TLS layer to prevent man in the middle viewing of the Payment Request details.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and
"OPTIONAL" in this document are to be interpreted as described in RFC 2119.
==Copyright==
@ -125,13 +125,13 @@ message InvoiceRequest {
|-
| memo || Human-readable description of invoice request for the receiver
|-
| notification_url || Secure (usually TLS-protected HTTP) location where an [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] SHOULD be sent when ready
| notification_url || Secure (usually TLS-protected HTTP) location where an [[#encryptedprotocolmessage|EncryptedProtocolMessage]] SHOULD be sent when ready
|-
| signature || PKI-dependent signature
|}
===ProtocolMessageType Enum===
This enum is used in the newly defined [[#ProtocolMessage|ProtocolMessage]] and [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] messages to define the serialized message type. The '''ProtocolMessageType''' enum is defined in an extensible way to allow for new message type additions to the Payment Protocol.
This enum is used in the newly defined [[#protocolmessage|ProtocolMessage]] and [[#encryptedprotocolmessage|EncryptedProtocolMessage]] messages to define the serialized message type. The '''ProtocolMessageType''' enum is defined in an extensible way to allow for new message type additions to the Payment Protocol.
<pre>
enum ProtocolMessageType {
UNKNOWN_MESSAGE_TYPE = 0;
@ -177,7 +177,7 @@ This BIP introduces version 1 of this protocol. All messages sent using these ba
When initiating communication, the version field of the first message SHOULD be set to the highest version number the sender understands. All clients MUST be able to understand all version numbers less than the highest number they support. If a client receives a message with a version number higher than they understand, they MUST send the message back to the sender with a status code of 101 ("version too high") and the version field set to the highest version number the recipient understands. The sender must then resend the original message using the same version number returned by the recipient or abort.
===EncryptedProtocolMessage===
The '''EncryptedProtocolMessage''' message is an encapsualting wrapper for any Payment Protocol message. It allows two-way, authenticated and encrypted communication of Payment Protocol messages in order to keep their contents secret. The message also includes a status code and status message that is used for error communication such that the protocol does not rely on transport-layer error handling.
The '''EncryptedProtocolMessage''' message is an encapsulating wrapper for any Payment Protocol message. It allows two-way, authenticated and encrypted communication of Payment Protocol messages in order to keep their contents secret. The message also includes a status code and status message that is used for error communication such that the protocol does not rely on transport-layer error handling.
<pre>
message EncryptedProtocolMessage {
required uint64 version = 1 [default = 1];
@ -217,14 +217,14 @@ message EncryptedProtocolMessage {
|}
==Payment Protocol Process with InvoiceRequests==
The full process overview for using '''InvoiceRequests''' in the Payment Protocol is defined below.
The full process overview for using '''InvoiceRequests''' in the Payment Protocol is defined below.
<br/><br/>
All Payment Protocol messages MUST be encapsulated in either a [[#ProtocolMessage|ProtocolMessage]] or [[#EncryptedProcotolMessage|EncryptedProtocolMessage]]. Once the process begins using [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] messages, all subsequent communications MUST use [[#EncryptedProtocolMessage|EncryptedProtocolMessages]].
All Payment Protocol messages MUST be encapsulated in either a [[#protocolmessage|ProtocolMessage]] or [[#encryptedprotocolmessage|EncryptedProtocolMessage]]. Once the process begins using [[#encryptedprotocolmessage|EncryptedProtocolMessage]] messages, all subsequent communications MUST use [[#encryptedprotocolmessage|EncryptedProtocolMessages]].
<br/><br/>
All Payment Protocol messages SHOULD be communicated using [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] encapsulating messages with the exception that an [[#InvoiceRequest|InvoiceRequest]] MAY be communicated using the [[#ProtocolMessage|ProtocolMessage]] if the receiver's public key is unknown.
All Payment Protocol messages SHOULD be communicated using [[#encryptedprotocolmessage|EncryptedProtocolMessage]] encapsulating messages with the exception that an [[#invoicerequest|InvoiceRequest]] MAY be communicated using the [[#protocolmessage|ProtocolMessage]] if the receiver's public key is unknown.
<br/><br/>
The process of creating encrypted Payment Protocol messages is enumerated in [[#Sending_Encrypted_Payment_Protocol_Messages_using_EncryptedProtocolMessages|Sending Encrypted Payment Protocol Messages using EncryptedProtocolMessages]], and the process of decrypting encrypted messages can be found under [[#Validating_and_Decrypting_Payment_Protocol_Messages_using_EncryptedProtocolMessages|Validating and Decrypting Payment Protocol Messages using EncryptedProtocolMessages]].
The process of creating encrypted Payment Protocol messages is enumerated in [[#sending-encrypted-payment-protocol-messages-using-encryptedprotocolmessages|Sending Encrypted Payment Protocol Messages using EncryptedProtocolMessages]], and the process of decrypting encrypted messages can be found under [[#validating-and-decrypting-payment-protocol-messages-using-encryptedprotocolmessages|Validating and Decrypting Payment Protocol Messages using EncryptedProtocolMessages]].
A standard exchange from start to finish would look like the following:
@ -238,7 +238,7 @@ A standard exchange from start to finish would look like the following:
# Sender validates PaymentRequest retrieved from the EncryptedProtocolMessage
# The PaymentRequest is processed according to [[bip-0070.mediawiki|BIP70]], including optional Payment and PaymentACK messages encapsulated in EncryptedProtocolMessage messages.
'''NOTE:''' See [[#Initial_Public_Key_Retrieval_for_InvoiceRequest_Encryption|Initial Public Key Retrieval for InvoiceRequest Encryption]] for possible options to retrieve Receiver's public key.
'''NOTE:''' See [[#initial-public-key-retrieval-for-invoicerequest-encryption|Initial Public Key Retrieval for InvoiceRequest Encryption]] for possible options to retrieve Receiver's public key.
<img src="bip-0075/encrypted-invoice-request-process.png" alt="Flow diagram of Encrypted InvoiceRequest">
@ -257,14 +257,14 @@ When communicated via '''HTTP''', the listed messages MUST be transmitted via TL
===Payment Protocol Status Communication===
Every [[#ProtocolMessage|ProtocolMessage]] or [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] MUST include a status code which conveys information about the last message received, if any (for the first message sent, use a status of 1 "OK" even though there was no previous message). In the case of an error that causes the Payment Protocol process to be stopped or requires that message be retried, a ProtocolMessage or EncryptedProtocolMessage SHOULD be returned by the party generating the error. The content of the message MUST contain the same '''serialized_message''' or '''encrypted_message''' and identifier (if present) and MUST have the status_code set appropriately.
Every [[#protocolmessage|ProtocolMessage]] or [[#encryptedprotocolmessage|EncryptedProtocolMessage]] MUST include a status code which conveys information about the last message received, if any (for the first message sent, use a status of 1 "OK" even though there was no previous message). In the case of an error that causes the Payment Protocol process to be stopped or requires that message be retried, a ProtocolMessage or EncryptedProtocolMessage SHOULD be returned by the party generating the error. The content of the message MUST contain the same '''serialized_message''' or '''encrypted_message''' and identifier (if present) and MUST have the status_code set appropriately.
<br/><br/>
The status_message value SHOULD be set with a human readable explanation of the status code.
====Payment Protocol Status Codes====
{| class="wikitable"
! Status Code !! Description
|-
|-
| 1 || OK
|-
| 2 || Cancel
@ -301,7 +301,7 @@ The status_message value SHOULD be set with a human readable explanation of the
If a participant to a transaction would like to inform the other party that a previous message should be canceled, they can send the same message with a status code of 2 ("Cancel") and, where applicable, an updated nonce. How recipients make use of the "Cancel" message is up to developers. For example, wallet developers may want to offer users the ability to cancel payment requests they have sent to other users, and have that change reflected in the recipient's UI. Developers using the non-encrypted ProtocolMessage may want to ignore "Cancel" messages, as it may be difficult to authenticate that the message originated from the same user.
===Transport Layer Communication Errors===
Communication errors MUST be communicated to the party that initiated the communication via the communication layer's existing error messaging faciltiies. In the case of TLS-protected HTTP, this SHOULD be done through standard HTTP Status Code messaging ([https://tools.ietf.org/html/rfc7231 RFC 7231 Section 6]).
Communication errors MUST be communicated to the party that initiated the communication via the communication layer's existing error messaging facilities. In the case of TLS-protected HTTP, this SHOULD be done through standard HTTP Status Code messaging ([https://tools.ietf.org/html/rfc7231 RFC 7231 Section 6]).
==Extended Payment Protocol Process Details==
This BIP extends the Payment Protocol as defined in [[bip-0070.mediawiki|BIP70]].
@ -311,27 +311,27 @@ For the following we assume the Sender already knows the Receiver's public key,
'''nonce''' MUST be set to a non-repeating number '''and''' MUST be chosen by the encryptor. The current epoch time in microseconds SHOULD be used, unless the creating device doesn't have access to a RTC (in the case of a smart card, for example). The service receiving the message containing the '''nonce''' MAY use whatever method to make sure that the '''nonce''' is never repeated.
===InvoiceRequest Message Creation===
* Create an [[#InvoiceRequest|InvoiceRequest]] message
* Create an [[#invoicerequest|InvoiceRequest]] message
* '''sender_public_key''' MUST be set to the public key of an EC keypair
* '''amount''' is optional. If the amount is not specified by the [[#InvoiceRequest|InvoiceRequest]], the Receiver MAY specify the amount in the returned PaymentRequest. If an amount is specified by the [[#InvoiceRequest|InvoiceRequest]] and a PaymentRequest cannot be generated for that amount, the [[#InvoiceRequest|InvoiceRequest]] SHOULD return the same [[#InvoiceRequest|InvoiceRequest]] in a [[#ProtocolMessage|ProtocolMessage]] or [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] with the status_code and status_message fields set appropriately.
* '''amount''' is optional. If the amount is not specified by the [[#invoicerequest|InvoiceRequest]], the Receiver MAY specify the amount in the returned PaymentRequest. If an amount is specified by the [[#invoicerequest|InvoiceRequest]] and a PaymentRequest cannot be generated for that amount, the [[#invoicerequest|InvoiceRequest]] SHOULD return the same [[#invoicerequest|InvoiceRequest]] in a [[#protocolmessage|ProtocolMessage]] or [[#encryptedprotocolmessage|EncryptedProtocolMessage]] with the status_code and status_message fields set appropriately.
* '''memo''' is optional. This MAY be set to a human readable description of the InvoiceRequest
* Set '''notification_url''' to URL that the Receiver will submit completed PaymentRequest (encapsulated in an [[#EncryptedProtocolMessage|EncryptedProtocolMessage]]) to
* Set '''notification_url''' to URL that the Receiver will submit completed PaymentRequest (encapsulated in an [[#encryptedprotocolmessage|EncryptedProtocolMessage]]) to
* If NOT including certificate, set '''pki_type''' to "none"
* If including certificate:
** Set '''pki_type''' to "x509+sha256"
** Set '''pki_data''' as it would be set in BIP-0070 ([https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki#Certificates Certificates])
** Sign [[#InvoiceRequest|InvoiceRequest]] with signature = "" using the X509 Certificate's private key
** Sign [[#invoicerequest|InvoiceRequest]] with signature = "" using the X509 Certificate's private key
** Set '''signature''' value to the computed signature
===InvoiceRequest Validation===
* Validate '''sender_public_key''' is a valid EC public key
* Validate '''sender_public_key''' is a valid EC public key
* Validate '''notification_url''', if set, contains characters deemed valid for a URL (avoiding XSS related characters, etc).
* If '''pki_type''' is None, [[#InvoiceRequest|InvoiceRequest]] is VALID
* If '''pki_type''' is x509+sha256 and '''signature''' is valid for the serialized [[#InvoiceRequest|InvoiceRequest]] where signature is set to "", [[#InvoiceRequest|InvoiceRequest]] is VALID
* If '''pki_type''' is None, [[#invoicerequest|InvoiceRequest]] is VALID
* If '''pki_type''' is x509+sha256 and '''signature''' is valid for the serialized [[#invoicerequest|InvoiceRequest]] where signature is set to "", [[#invoicerequest|InvoiceRequest]] is VALID
===Sending Encrypted Payment Protocol Messages using EncryptedProtocolMessages===
* Encrypt the serialized Payment Protocol message using AES-256-GCM setup as described in [[#ECDH_Point_Generation_and_AES256_GCM_Mode_Setup|ECDH Point Generation and AES-256 (GCM Mode) Setup]]
* Create [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] message
* Encrypt the serialized Payment Protocol message using AES-256-GCM setup as described in [[#ecdh-point-generation-and-aes256-gcm-mode-setup|ECDH Point Generation and AES-256 (GCM Mode) Setup]]
* Create [[#encryptedprotocolmessage|EncryptedProtocolMessage]] message
* Set '''encrypted_message''' to be the encrypted value of the Payment Protocol message
* '''version''' SHOULD be set to the highest version number the client understands (currently 1)
* '''sender_public_key''' MUST be set to the public key of the Sender's EC keypair
@ -339,14 +339,14 @@ For the following we assume the Sender already knows the Receiver's public key,
* '''nonce''' MUST be set to the nonce used in the AES-256-GCM encryption operation
* Set '''identifier''' to the identifier value received in the originating InvoiceRequest's ProtocolMessage or EncryptedProtocolMessage wrapper message
* Set '''signature''' to ""
* Sign the serialized [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] message with the communicating party's EC public key
* Sign the serialized [[#encryptedprotocolmessage|EncryptedProtocolMessage]] message with the communicating party's EC public key
* Set '''signature''' to the result of the signature operation above
'''SIGNATURE NOTE:''' [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] messages are signed with the public keys of the party transmitting the message. This allows a Store & Forward server or other transmission system to prevent spam or other abuses. For those who are privacy conscious and don't want the server to track the interactions between two public keys, the Sender can generate a new public key for each interaction to keep their identity anonymous.
'''SIGNATURE NOTE:''' [[#encryptedprotocolmessage|EncryptedProtocolMessage]] messages are signed with the public keys of the party transmitting the message. This allows a Store & Forward server or other transmission system to prevent spam or other abuses. For those who are privacy conscious and don't want the server to track the interactions between two public keys, the Sender can generate a new public key for each interaction to keep their identity anonymous.
===Validating and Decrypting Payment Protocol Messages using EncryptedProtocolMessages===
* The '''nonce''' MUST not be repeated. The service receiving the [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] MAY use whatever method to make sure that the nonce is never repeated.
* Decrypt the serialized Payment Protocol message using AES-256-GCM setup as described in [[#ECDH_Point_Generation_and_AES256_GCM_Mode_Setup|ECDH Point Generation and AES-256 (GCM Mode) Setup]]
* The '''nonce''' MUST not be repeated. The service receiving the [[#encryptedprotocolmessage|EncryptedProtocolMessage]] MAY use whatever method to make sure that the nonce is never repeated.
* Decrypt the serialized Payment Protocol message using AES-256-GCM setup as described in [[#ecdh-point-generation-and-aes256-gcm-mode-setup|ECDH Point Generation and AES-256 (GCM Mode) Setup]]
* Deserialize the serialized Payment Protocol message
===ECDH Point Generation and AES-256 (GCM Mode) Setup===
@ -366,10 +366,10 @@ For the following we assume the Sender already knows the Receiver's public key,
The 16 byte authentication tag resulting from the AES-GCM encrypt operation MUST be prefixed to the returned ciphertext. The decrypt operation will use the first 16 bytes of the ciphertext as the GCM authentication tag and the remainder of the ciphertext as the ciphertext in the decrypt operation.
====AES-256 GCM Additional Authenticated Data====
When either '''status_code''' OR '''status_message''' are present, the AES-256 GCM authenticated data used in both the encrypt and decrypt operations MUST be: STRING(status_code) || status_message. Otherwise, there is no additional authenticated data. This provides that, while not encrypted, the status_code and status_message are authenticated.
When either '''status_code''' OR '''status_message''' are present, the AES-256 GCM authenticated data used in both the encrypt and decrypt operations MUST be: STRING(status_code) || status_message. Otherwise, there is no additional authenticated data. This provides that, while not encrypted, the status_code and status_message are authenticated.
===Initial Public Key Retrieval for InvoiceRequest Encryption===
Initial public key retrieval for [[#InvoiceRequest|InvoiceRequest]] encryption via [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] encapsulation can be done in a number of ways including, but not limited to, the following:
Initial public key retrieval for [[#invoicerequest|InvoiceRequest]] encryption via [[#encryptedprotocolmessage|EncryptedProtocolMessage]] encapsulation can be done in a number of ways including, but not limited to, the following:
# Wallet Name public key asset type resolution - DNSSEC-validated name resolution returns Base64 encoded DER-formatted EC public key via TXT Record [https://www.ietf.org/rfc/rfc5480.txt RFC 5480]
# Key Server lookup - Key Server lookup (similar to PGP's pgp.mit.edu) based on key server identifier (i.e., e-mail address) returns Base64 encoded DER-formatted EC public key [https://www.ietf.org/rfc/rfc5480.txt RFC 5480]
# QR Code - Use of QR-code to encode SEC-formatted EC public key [https://www.ietf.org/rfc/rfc5480.txt RFC 5480]
@ -387,7 +387,7 @@ Clients SHOULD keep in mind Receivers can broadcast a transaction without return
==Public Key & Signature Encoding==
* All x.509 certificates included in any message defined in this BIP MUST be DER [ITU.X690.1994] encoded.
* All EC public keys ('''sender_public_key''', '''receiver_public_key''') in any message defined in this BIP MUST be [[SECP256k1|http://www.secg.org/sec2-v2.pdf]] ECDSA Public Key ECPoints encoded using [[SEC 2.3.3 Encoding|http://www.secg.org/sec1-v2.pdf]]. Encoding MAY be compressed.
* All EC public keys ('''sender_public_key''', '''receiver_public_key''') in any message defined in this BIP MUST be [[SECP256k1|http://www.secg.org/sec2-v2.pdf]] ECDSA Public Key ECPoints encoded using [[SEC 2.3.3 Encoding|http://www.secg.org/sec1-v2.pdf]]. Encoding MAY be compressed.
* All ECC signatures included in any message defined in this BIP MUST use the SHA-256 hashing algorithm and MUST be DER [ITU.X690.1994] encoded.
* All OpenPGP certificates must follow [[https://tools.ietf.org/html/rfc4880|RFC4880]], sections 5.5 and 12.1.
@ -408,12 +408,12 @@ The following flowchart is borrowed from [[bip-0070.mediawiki|BIP70]] and expand
==Mobile to Mobile Examples==
===Full Payment Protocol===
The following diagram shows a sample flow in which one mobile client is sending value to a second mobile client with the use of an InvoiceRequest, a Store & Forward server, PaymentRequest, Payment and PaymentACK. In this case, the PaymentRequest, Payment and PaymentACK messages are encrypted using [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] '''and''' the Receiver submits the transaction to the Bitcoin network.
The following diagram shows a sample flow in which one mobile client is sending value to a second mobile client with the use of an InvoiceRequest, a Store & Forward server, PaymentRequest, Payment and PaymentACK. In this case, the PaymentRequest, Payment and PaymentACK messages are encrypted using [[#encryptedprotocolmessage|EncryptedProtocolMessage]] '''and''' the Receiver submits the transaction to the Bitcoin network.
<img src="bip-0075/mobile-sf-ir-with-payment.png" alt="Payment Required flow diagram">
===Encrypting Initial InvoiceRequest via EncryptedProtocolMessage===
The following diagram shows a sample flow in which one mobile client is sending value to a second mobile client using an [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] to transmit the InvoiceRequest using encryption, Store & Forward server, and PaymentRequest. In this case, all Payment Protocol messages are encrypting using [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] '''and''' the Sender submits the transaction to the Bitcoin network.
The following diagram shows a sample flow in which one mobile client is sending value to a second mobile client using an [[#encryptedprotocolmessage|EncryptedProtocolMessage]] to transmit the InvoiceRequest using encryption, Store & Forward server, and PaymentRequest. In this case, all Payment Protocol messages are encrypting using [[#encryptedprotocolmessage|EncryptedProtocolMessage]] '''and''' the Sender submits the transaction to the Bitcoin network.
<img src="bip-0075/mobile-sf-encrypted-ir-without-payment.png" alt="Encrypted InvoiceRequest without payment">

View File

@ -2,8 +2,8 @@
// Simple Bitcoin Payment Protocol messages
//
// Use fields 1000+ for extensions;
// to avoid conflicts, register extensions via pull-req at
// https://github.com/bitcoin/bips/bip-0070/extensions.mediawiki
// to avoid conflicts, register extensions via pull request to update
// https://github.com/bitcoin/bips/blob/master/bip-0070/extensions.mediawiki
//
package payments;

783
bip-0077.md Normal file
View File

@ -0,0 +1,783 @@
```
BIP: 77
Layer: Applications
Title: Async Payjoin
Authors: Dan Gould <d@ngould.dev>
Yuval Kogman <nothingmuch@woobling.org>
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0077
Status: Draft
Type: Specification
Assigned: 2023-08-08
License: BSD-2-Clause
Discussion: https://github.com/bitcoin/bips/pull/1483
https://gnusha.org/pi/bitcoindev/7B11AE34-27A7-46ED-95BF-66CA13BA26F3@ngould.dev/#t
https://gnusha.org/pi/bitcoindev/3C0A6E4C-444E-4E75-829C-1A21D8EE40E0@ngould.dev/#t
Version: 0.2.0
Requires: 21, 78, 173, 174
```
## Copyright
This BIP is licensed under the 2-clause BSD license.
## Abstract
Payjoin lets Bitcoin senders and receivers interact to make batched
transactions.
This document proposes a second, backwards-compatible, asynchronous version of
the Payjoin protocol ("Version 2") relative to and described in [BIP 78](bip-0078.mediawiki) ("Version 1"). An untrusted
third-party "directory server" replaces the requirement
for a receiver to host a secure public endpoint for interactions. HTTP clients
access the directory server using an asynchronous protocol and authenticated,
encrypted payloads. The design preserves complete Payjoin receiver
functionality, including payment
output substitution. Authenticated encryption depends only on cryptographic
primitives available in Bitcoin Core. Requests use [Oblivious
HTTP](https://www.ietf.org/rfc/rfc9458.html) (OHTTP) to
prevent the directory and other Payjoin clients from linking requests to client
IP addresses.
## Motivation
Satoshi Nakamoto pointed out one specific privacy risk in the
[whitepaper](https://bitcoin.org/en/bitcoin-paper),
that transactions with multiple inputs "necessarily reveal that
their inputs were owned by the same owner."
Payjoin addresses that risk, the _common-input-ownership heuristic_,
by making it practical to spend inputs owned by multiple parties
in one transaction.
While addressing Bitcoin's primal privacy risk, Payjoin *input* batching
also improves on the widespread non-interactive *output* batching practice
deployed by exchanges. When combined, the same movement of funds can use
less block weight and save fees.
A natural application of Payjoin would be to combine
getting paid with consolidating UTXOs into one transaction. But Payjoin
can also secure [transaction
cut-through](https://bitcointalk.org/index.php?topic=281848.0),
allowing a sender to transfer funds to a receiver who also transfers
funds to a third party in the same transaction. For example, deposits to an
exchange may "cut through" in a single transaction that also satisfies
withdrawals instead of with a second transaction that spends the deposited
funds. Payjoin enables more blockspace-efficient transactions that
reduce fees while addressing privacy risks.
However, BIP 78's requirements for Payjoin Version 1 have proven to be an
obstacle to adoption. Version 1 receivers must host a secured
public-facing HTTP server. Mobile and web environments limit the ability
to fulfil such a requirement. Version 1 also requires synchronous
communication. Both sender and receiver must be online simultaneously.
Wallet developers [
regard](https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-January/018358.html)
these requirements as barriers to Payjoin adoption.
To address these limitations, our goal is to specify a practical
coordination mechanism suitable for widespread implementation. This proposal
leverages mature solutions to common problems, building on established web
standards and proven Bitcoin primitives.
## Overview
A Payjoin *sender* and *receiver* interact so that they may both contribute to a
transaction. In this proposal, they exchange asynchronous end-to-end
encrypted messages by relaying them to a store-and-forward *directory* server
using OHTTP.
Before initiating the protocol, the receiver must secure communications with
the directory by [bootstrapping](#ohttp-bootstrapping).
- The receiver [initiates a Payjoin Session](#session-initiation)
by sharing a [Payjoin URI](#payjoin-uri) that includes the URL of an
ephemeral mailbox hosted on the directory, where it can receive a message
from the sender.
- The sender [posts a message](#sender-original-psbt-messaging)
containing a fully signed fallback transaction, known as the *Original PSBT*,
to the mailbox.
- The receiver gets this message and
[posts a message containing a *Proposal
PSBT*](#receiver-proposal-psbt-messaging)
to the sender's ephemeral mailbox, by updating the Original PSBT with
appropriate inputs and/or outputs.
- The sender gets the Proposal PSBT, [checks it, signs, and
broadcasts](#sender-signing-and-broadcast) the final transaction.
At any point, either party may choose to broadcast the
fallback transaction described by the Original PSBT instead of proceeding.
Because the Original PSBT and Proposal PSBT spend the same input(s) they are
mutually exclusive and only one can be confirmed.
Messages are buffered in the directory, allowing both parties to tolerate
temporary disconnections and resume communication by polling.
### Async Payjoin Directory Mediated Sequence Diagram
```text
+----------+ +------------+ +----------+ +----------+
| Receiver | | Directory | | Sender | | Network |
+----+-----+ +-----+------+ +----+-----+ +----+-----+
| | | |
| Payjoin URI (BIP21), out-of-band | |
+------------------------------------------------>| |
| | | |
| Poll GET: original PSBT (repeat until available) |
+- - - - - - - - - - - ->+ | |
| # POST: original PSBT | |
| #<-----------------------+ |
| 200 OK: original PSBT # | |
|<-----------------------+ | |
| | | |
| | Poll GET: proposal PSBT (repeat until available)
| +<- - - - - - - - - - - -+ |
| POST: proposal PSBT # | |
+-----------------------># | |
| # 200 OK: proposal PSBT | |
| +----------------------->| |
| | | |
| | | Broadcast payjoin |
| | +---------------------->|
| | | |
```
## Specification
### OHTTP Bootstrapping
Before initiating a Payjoin Session a receiver must first discover the
directory's
[OHTTP Key Configuration](https://www.ietf.org/rfc/rfc9458.html#section-3.1),
via an authenticated
bootstrap mechanism. The key configuration contains information to establish
[Hybrid Public Key Encryption](#secp256k1-hybrid-public-key-encryption) (HPKE) in order to secure communications between the client and the directory in
lieu of TLS.
The bootstrap mechanism may vary by implementation but must
follow [OHTTP Consistency
Requirements](https://datatracker.ietf.org/doc/html/draft-ietf-privacypass-key-consistency-01)
and should not reveal a receiver IP address to the directory. Some
examples of suitable mechanisms include getting a key configuration
from a Payjoin URI, a trusted application binary, or fetching using https-in-http
CONNECT method, https-in-WebSocket, Tor, or a VPN.
Directory OHTTP Gateways MUST support [RFC 9540 Key Configuration
Fetching](https://www.rfc-editor.org/rfc/rfc9540.html#name-key-configuration-fetching)
via GET request. RFC 9540 defines the
gateway location as `/.well-known/ohttp-gateway`.
### Session Initiation
A receiver initiates a session by sharing a Payjoin URI. Because a URI
contains sensitive information, such as a receiver address, it should be shared
over a confidential channel.
#### Payjoin URI
Bitcoin URIs ([BIP
21](https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki)
or [BIP
321](https://github.com/bitcoin/bips/blob/master/bip-0321.mediawiki))
are a standard way to request bitcoin.
A Payjoin URI is a Bitcoin URI that contains a `pj` parameter. The `pj`
parameter value is a URL in both BIP 78 and BIP 77.
Senders that understand Bitcoin URI but don't support Payjoin will just
ignore the `pj` parameter and proceed to typical address-based
transaction flows.
A `req-pj` parameter may be used as a [BIP 21 forwards compatibility `reqparam`](https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki#forward-compatibility) instead of
`pj` to signal that Payjoin is required.
The parameter value must be [uppercased and the parameter should be placed last in the URI](#uppercase-url).
Since BIP 78 payloads are neither encrypted nor authenticated,
a directory used for backwards-compatible payloads is known
as an ["unsecured payjoin server" in BIP 78
parlance](https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#unsecured-payjoin-server).
Backwards-compatible receivers MUST disable output substitution
by setting `pjos=0` to prevent modification by a malicious directory.
##### Mailbox endpoint
In this proposal the URL in the `pj` parameter value is the mailbox
endpoint URL. Mailboxes are shared HTTP resources hosted by the
directory and serve as OHTTP Target Resources. Clients use these endpoints
to relay encrypted messages. They `POST` messages to and `GET` messages from
mailbox endpoints via OHTTP.
Senders that support BIP 78 but not this proposal may POST messages directly to
mailbox endpoints for [backwards compatibility](#backwards-compatibility).
###### Short ID
A Short ID identifies a mailbox based on its associated public key. The Short
ID is the path component of the mailbox endpoint. One is derived by hashing the
33-byte compressed public key encoding with SHA-256, truncating it to
[8 bytes (64 bits)](#64-bit-short-id-length), and encoding it in
[uppercase](#uppercase-url) using the bech32 character set (like a bech32 string without the HRP, separator and checksum).
##### Receiver fragment parameters
This proposal introduces session-specific parameters which the
receiver shares encoded in the URI.
Instead of defining new Bitcoin URI parameters, the session-specific
parameters are encoded in the [
fragment](https://datatracker.ietf.org/doc/html/rfc3986#section-3.5)
of the mailbox endpoint URL.
The `#` fragment separator character must be [RFC 3986
percent-encoded](https://datatracker.ietf.org/doc/html/rfc3986#section-2.1)
as `%23`, because it separates the
fragment of the mailbox endpoint URL included in the `pj` parameter, not the
fragment of the Bitcoin URI.
These session-specific parameters use a bech32-inspired encoding.
The HRP is used as the parameter key, followed by the '1' separator,
followed by the parameter value encoded using the bech32 character set in
[uppercase](#uppercase-url). No checksum is used. Parameters are separated
by a `-` character.
The following parameters are defined, and must be provided in lexicographical
order:
- `EX`: specifies a [session
expiration](#session-expiration) in [unix
time](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_16).
- `OH`: encodes an alternate format of the OHTTP Key Configuration of
the directory. It consists of a 33-byte compressed public key of the
directory's OHTTP Gateway, prefixed by the 2-byte Key Identifier. A [
RFC 9458 Key
Configuration](https://www.ietf.org/rfc/rfc9458.html#section-3.1)
is reconstructed by assuming the HPKE KEM ID and Symmetric Algorithms
are [fixed](#secp256k1-hybrid-public-key-encryption).
- `RK`: encodes the *receiver key* as a 33-byte compressed public key.
Senders will initiate HPKE with the receiver using this key.
For example, a properly encoded endpoint Bitcoin URI looks like this
`bitcoin:tb1q6q6de88mj8qkg0q5lupmpfexwnqjsr4d2gvx2p?amount=0.00666666&pjos=0&pj=HTTPS://PAYJO.IN/TXJCGKTKXLUUZ%23EX1WKV8CEC-OH1QYPM59NK2LXXS4890SUAXXYT25Z2VAPHP0X7YEYCJXGWAG6UG9ZU6NQ-RK1Q0DJS3VVDXWQQTLQ8022QGXSX7ML9PHZ6EDSF6AKEWQG758JPS2EV`
Until 2026 implementations SHOULD also accept `+` as a fragment parameter
separator and not enforce parameter ordering requirements, for compatibility
with the [previous version of this document](#changelog).
### Sender Original PSBT Messaging
The sender constructs the fallback transaction, a typical transaction
spending funds to the receiver's address specified in the Payjoin URI.
This transaction is serialized as a BIP 174 PSBTv0, satisfying
[the receiver checklist](#receivers-original-psbt-checklist).
The Original PSBT MUST:
- Include complete UTXO data.
- Be fully signed.
- Exclude unnecessary fields such as global xpubs or keypath
information.
- Be broadcastable.
The Original PSBT MAY:
- Include outputs unrelated to the sender-receiver transfer for batching
purposes.
This *Original PSBT* is encoded as base64, followed by the query
parameter string on a new line containing [optional sender
parameters](#optional-sender-parameters).
The sender generates an ephemeral mailbox key. The corresponding public key is
known as the *reply key*, and it is prepended to the base64 plaintext string,
serialized in compressed form as 33 bytes.
This plaintext string is encrypted to the receiver key according to [HPKE Base
mode](https://www.rfc-editor.org/rfc/rfc9180.html#name-encryption-to-a-public-key).
The HPKE `info` string, used for domain separation, is `PjV2MsgA`. The
ciphertext ensures message secrecy and integrity when passed to the receiver
using the mailbox endpoint. The 16-byte authentication tag is appended to the
ciphertext.
RFC 9180 [does not
specify](https://www.rfc-editor.org/rfc/rfc9180.html#section-10) the wire format
encoding of HPKE messages. To construct an HPKE payload, the secp256k1 public
key from the DHKEM is encoded using ElligatorSwift in 64 bytes. Note that
ElligatorSwift is only the wire format; when deriving shared secrets, the curve
point is re-serialized in uncompressed form.
```
PjV2MsgA Byte Representation (7168 bytes total)
+---------------------------------------------------------------------------------------+
| ElligatorSwift | Ciphertext |
| (64 bytes) | (7104 bytes) |
| +-----------------------+---------------------------------+------------+
| | Reply Key | Padded Plaintext | AEAD Tag |
| | (33 bytes) | (7055 bytes = 7168-64-33-16) | (16 bytes) |
+---------------------------------------------------------------------------------------+
```
The resulting HPKE payload is the body of a POST request to the
receiver's mailbox. This request is then [
encapsulated](#clientdirectory-interactions) according to
Oblivious HTTP to the directory's OHTTP Gateway. OHTTP serializes the
inner request as BHTTP, and provides another layer of HPKE encryption,
between the client and directory.
Upon receipt, the directory's OHTTP Gateway decapsulates the OHTTP
request and handles the inner POST request at the receiver's mailbox
endpoint, which stores the HPKE encrypted payload to be forwarded to the
receiver.
The sender then polls OHTTP encapsulated GET requests to the sender's
mailbox endpoint until it receives a response from the directory
containing the receiver's *Proposal PSBT*, and proceeds to
[sign and broadcast](#sender-signing-and-broadcast).
It stops polling after expiration.
#### Optional sender parameters
[BIP 78's optional sender parameters](https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#optional-parameters)
may be used in this proposal, but must be included in
the body as part of the ciphertext rather than as a query string.
HPKE binds ciphertexts to application-specific `info` strings. Because
of this domain separation, BIP 78's `v` parameter is redundant and
should be omitted for this proposal.
### Receiver Proposal PSBT Messaging
After sharing the Payjoin URI with the sender, the receiver polls via
OHTTP encapsulated GET requests to the receiver's mailbox endpoint. So
long as the mailbox contains no message, the directory responds with
status 202 ACCEPTED. Once a mailbox contains a message, the directory
returns it in the response body with status 200 OK.
Upon receiving an encapsulated 200 OK response, the receiver decrypts
the payload and checks the *Original PSBT* therein according to the
[receiver checklist](#receivers-original-psbt-checklist).
The receiver then updates the *Original PSBT* to include new signed
inputs and outputs, invalidating the sender's signature(s). The receiver
may also adjust the transaction fee. The result, called the *Proposal
PSBT*, must satisfy the [sender checklist](#senders-proposal-psbt-checklist)
The Proposal PSBT MUST:
- Include complete UTXO data.
- Include all inputs from the Original PSBT.
- Include all outputs which do not belong to the receiver from the
Original PSBT.
- Use a random index if additional inputs or outputs are added.
The Proposal PSBT sender MAY:
- Add inputs at random indices.
- Add outputs at random indices.
- Remove or modify Original PSBT outputs under the control of the
receiver (i.e. not sender change).
The Proposal PSBT MUST NOT:
- Shuffle the order of inputs or outputs contained in the Original PSBT.
- Decrease the absolute fee of the Original PSBT.
The receiver encrypts the *Proposal PSBT* to the sender's reply key according to
[HPKE Auth
mode](https://www.rfc-editor.org/rfc/rfc9180.html#name-authentication-using-an-asy),
using the receiver's key for authentication. The HPKE `info` string is
`PjV2MsgB`. The HPKE wire format is the same as in the [sender's
message](#sender-original-psbt-messaging).
```
PjV2MsgB Byte Representation (7168 bytes total)
+---------------------------------------------------------------------------------------+
| ElligatorSwift | Ciphertext |
| (64 bytes) | (7104 bytes) |
| +---------------------------------------------------------+------------+
| | Padded Plaintext | AEAD Tag |
| | (7088 bytes = 7168-64-16) | (16 bytes) |
+---------------------------------------------------------------------------------------+
```
The receiver makes the resulting HPKE payload the body of a POST request to the
sender's mailbox whose Short ID is derived from the sender's reply key. This request is then [
encapsulated](#clientdirectory-interactions) according to
Oblivious HTTP to the directory's OHTTP Gateway. OHTTP serializes the
inner request as BHTTP, and provides another layer of HPKE encryption,
between the client and directory.
The above describes the receiver's reply path when the sender used
Version 2. When the sender used the BIP 78 backwards-compatible path
(the Original PSBT was a BIP 78 cleartext payload rather than an
HPKE-encrypted v2 message), the receiver's response MUST instead follow
[Backwards compatibility](#backwards-compatibility): the *Proposal PSBT*
is not HPKE-encrypted and the request method is `PUT`.
Once the receiver makes this request, they wait for either transaction from the
Original PSBT or Proposal PSBT to be broadcast to the Bitcoin network.
#### Receiver's Original PSBT checklist
The receiver checklist is the same as [the BIP 78 receiver
checklist](https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#receivers-original-psbt-checklist).
### Sender signing and broadcast
The sender validates the *Proposal PSBT* it receives against a
checklist. If the checks pass, it may sign and broadcast the resulting
Payjoin transaction.
#### Sender's Proposal PSBT checklist
This proposal's sender checklist is the same as [the BIP 78 sender
checklist](https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#senders-payjoin-proposal-checklist).
### Client/Directory interactions
The Payjoin Directory provides a rendezvous point for senders and
receivers to exchange messages. The directory stores Payjoin payloads to
support asynchronous communication. Async Payjoin requests must be
submitted as encapsulated messages to the directory's OHTTP Gateway.
The wire format OHTTP request is specified in [RFC
9458](https://www.ietf.org/rfc/rfc9458.html#name-hpke-encapsulation). HPKE
requires the directory's OHTTP key configuration. The plaintext is a binary
encoded HTTP request ([RFC 9292](https://www.rfc-editor.org/rfc/rfc9292.html))
intended for the OHTTP target resource, usually a mailbox endpoint, padded to
8104 bytes with [random data](#random-padding).
```
OHTTP Encapsulated Request Byte Representation (8192 bytes total)
+--------------+-------------------------+------------------------------------------+
| OHTTP Header | HPKE KEM | Ciphertext |
| (7 bytes) | Uncompressed Public Key | (8120 bytes = 8192-65-7) +
| | (65 bytes) +-----------------------------+------------+
| | | Padded BHTTP Request | AEAD Tag |
| | | (8104 bytes = 8192-65-16-7) | (16 bytes) |
+--------------+-------------------------+------------------------------------------+
```
Response encryption uses the Export functionality of the request HPKE context to
establish a shared secret, and therefore consists of a 32 byte nonce followed by
the AEAD ciphertext and tag.
```
OHTTP Encapsulated Response Byte Representation (8192 bytes total)
+---------------------+------------------------------------------+
| Nonce | Ciphertext |
| (32 bytes) | (8160 bytes = 8192-32) +
| +-----------------------------+------------+
| | Padded BHTTP Response | AEAD Tag |
| | (8144 bytes = 8192-32-16) | (16 bytes) |
+---------------------+------------------------------------------+
```
GET requests on an empty mailbox should block until a message is posted
or a timeout occurs. The timeout should be 30 seconds because that will
not exceed the default timeout for most HTTP clients.
The directory may optionally accept HTTP/1.1 POST requests without OHTTP
to mailbox endpoint URLs for backwards compatibility with BIP 78 senders.
#### OHTTP Sequence Diagram
```text
.-------------------------------------------.
| Payjoin Directory |
+--------+ +-----------+ | +-------------+ +--------------+ |
| Client | | OHTTP | | | OHTTP | | HTTP | |
| | | Relay | | | Gateway | | Resource | |
+---+----+ +------+----+ | +-----+-------+ +------+-------+ |
| | `--------|-----------------------|----------'
| Relay Request | | |
| [ + Encapsulated | | |
| Request ] | | |
+------------------->| Gateway Request | |
| | [ + Encapsulated | |
| | Request ] | |
| +------------------->| Request |
| | +---------------------->|
| | | |
| | | Response |
| | Gateway |<----------------------+
| | Response | |
| | [ + Encapsulated | |
| | Response ] | |
| Relay |<-------------------+ |
| Response | | |
| [ + Encapsulated | | |
| Response ] | | |
|<-------------------+ | |
| | | |
```
### Relay/Directory interactions
RFC 9458 requires each OHTTP Relay to be configured to forward requests
to exactly one OHTTP Gateway. This requirement prevents receivers from
being able to choose any directory, and senders from choosing relays
independently. Without addressing this limitation, senders would have to
know which relays are appropriate to use for each directory, creating a
tendency for one directory and its affiliated relays to monopolize the
protocol.
In order to allow OHTTP Relays to be used with any directory, a
directory's OHTTP Gateway may advertise this allowed purpose. This
advertisement prevents OHTTP Relays from acting as open internet proxies,
which would otherwise allow anonymized access to arbitrary resources and
expose them to denial-of-service attacks, as well as other forms of abuse.
When the directory receives a GET request to the `/.well-known/ohttp-gateway`
path with an `allowed_purposes` query parameter, its response body
should contain a magic string in the same format as a TLS ALPN protocol
list (a U16BE length encoded list of U8 length encoded strings). The
magic string is `BIP77 454403bb-9f7b-4385-b31f-acd2dae20b7e`, offering
an unambiguous signal to relays that this OHTTP Gateway will accept
requests associated with this purpose from any relay.
By supporting this `allowed_purposes` parameter, the directory signals
to OHTTP Relays that it is willing to handle requests related to BIP 77,
removing the RFC 9458's requirement that relays and
Gateways be configured in a one-to-one relationship.
## Rationale
### Uppercase URL
In order to simplify parsing and allow QR encoders to use [Alphanumeric
QR
mode](https://www.rfc-editor.org/rfc/rfc9285.html#name-the-alphabet-used-in-base45),
which is more compact than Byte mode, the mailbox endpoint URL,
including the fragment parameters, is encoded in uppercase.
Unlike Bitcoin URI parameters, which require switching back to Byte
mode, the use of the URL fragment for session-specific parameters makes
it possible to stay in Alphanumeric mode.
### Parameter Ordering
The order of fragment parameters, Bitcoin URI parameters, as well as in the
sender's optional parameters have no defined meaning.
In the BIP 21 URI, the `pj` parameter mailbox endpoint URL SHOULD be the last
parameter to avoid QR mode switching.
Since variations might create a fingerprint for particular wallet software,
this document requires that fragment parameters MUST appear in reverse
lexicographical order.
### Session Expiration
The directory may hold a message for an offline Payjoin client until that
client comes online. However, the BIP 78 spec [
recommends](https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#receiver-does-not-need-to-be-a-full-node)
broadcasting Original PSBTs in the case of an offline counterparty.
Doing so exposes a naïve, surveillance-vulnerable transaction, which
Payjoin intends to avoid.
Because BIP 78 is a synchronous protocol without a standard expiration
mechanism, and automated receivers are vulnerable to probing attacks,
BIP 78 encourages receivers to broadcast the Original PSBT after some
undefined expiration time.
Because BIP 77 is an asynchronous protocol, it requires an explicit [
session-specific fragment
parameter](#receiver-fragment-parameters), `EX`, to
communicate this expiration time to the sender.
There is no way for a sender to prevent a receiver from broadcasting the
fallback transaction extracted from the Original PSBT before the
receiver-specified expiration time.
### 64-bit Short ID Length
64 bits are sufficient to make the probability of experiencing a random
collision negligible. As of writing, the UTXO set has ~2^28 elements.
This is a very loose upper bound for the number of concurrent (non-spam)
sessions, for which the probability of a random collision will be less
than 1%. The actual number of sessions will of course be (orders of
magnitudes) lower given that sessions are short-lived. With ~2^21
sessions (a loose bound on number of transactions that can be confirmed
in 24 hours) the probability is less than 1e-6. These figures bound the
probability of a collision existing anywhere in the entire set, whereas
the probability for an individual session to experience a collision is
\<\< 1e-10 in either case.
### Complete UTXO Data
Complete UTXO data is required because this information is required for
signing and calculating fees for some input types.
### HTTP
HTTP is ubiquitous. Using simple HTTP polling allows even Bitcoin Core
to consider an implementation. Unlike a WebSockets protocol, plain HTTP
can benefit from metadata protection by using Oblivious HTTP.
### Oblivious HTTP
OHTTP protects sender and receiver IP addresses both from one another
and from the directory. This makes it more difficult for a directory to
correlate many Payjoin transactions with specific IP addresses.
OHTTP relays can be run as basic HTTP proxies from wallet providers or
third parties.
### Uniform Payloads
Encapsulated OHTTP payloads seen by the relay and directory, and
encrypted messages seen by the directory, are constructed to be uniform
so that these third-party services are unable to distinguish between
them.
Encapsulated OHTTP messages are 8192 bytes long, and begin with a
cleartext OHTTP header and an uncompressed key which is distinguishable
from random bytes but uniform across different encapsulated requests.
End-to-end encrypted messages are 7168 bytes long, and should be
indistinguishable from uniformly random bytes.
[ElligatorSwift as defined in BIP 324](https://github.com/bitcoin/bips/blob/master/bip-0324.mediawiki#elligatorswift-encoding-of-curve-x-coordinates)
is used to encode encapsulated HPKE public keys prepended to the HPKE ciphertext
so that the directory can't distinguish between key material, the
ciphertext, and randomness. This ensures the two different protocol
messages are indistinguishable from each other as well as any protocol
extensions.
These padded sizes are sufficient for most PSBTs without exceeding the [
8KB
limit](https://www.geekersdigest.com/max-http-request-header-size-server-comparison/)
of many HTTP/1.1 web servers. 8KB is also too small for image sharing,
making misuse of the directory impractical.
#### Random Padding
The typical [zero padding recommended by the BHTTP
specification](https://www.rfc-editor.org/rfc/rfc9292.html#name-padding-and-truncation)
would make future use of [multi-hop OHTTP inspired by the Sphinx mix
format](https://github.com/orgs/payjoin/discussions/582) detectable from the
point of view of the directory. Random padding is allowed so long as the BHTTP
encoded request is not truncated.
By randomly padding OHTTP messages, any future use of such techniques would be
indistinguishable from clients that only implement standardized OHTTP. Since
this would limit a malicious directory's ability to censor any such requests in
the future, and such requests significantly bolster the privacy threat model
against malicious OHTTP relays or traffic analysis by a global passive
adversary, it is desirable to do so for standard OHTTP requests as well.
### Secp256k1 Hybrid Public Key Encryption
[RFC 9180 Hybrid Public Key
Encryption](https://www.rfc-editor.org/rfc/rfc9180.html)
(HPKE) is a modern IETF standard for secure
message exchange without TLS, since TLS is not available in Bitcoin Core.
This proposal uses `DHKEM(Secp256k1, HKDF-SHA256)` and
`ChaCha20Poly1305` AEAD for both OHTTP encapsulation and for end-to-end
encryption between the sender and receiver.
The receiver transmits its receiver key in [receiver fragment
parameters](#receiver-fragment-parameters). The sender shares
its reply key along with the Original PSBT. These keys are ephemeral and
must only be used for a single Payjoin Session.
#### Secp256k1-based DHKEM
[Secp256k1-based DHKEM for
HPKE](https://www.ietf.org/archive/id/draft-wahby-cfrg-hpke-kem-secp256k1-01.html)
is most appropriate because of secp256k1's availability in bitcoin
contexts.
#### ChaCha20Poly1305 AEAD
This authenticated encryption with additional data [
algorithm](https://en.wikipedia.org/wiki/ChaCha20-Poly1305)
is standardized in [RFC
8439](https://www.rfc-editor.org/rfc/rfc8439) and has high
performance. ChaCha20Poly1305 AEAD has been implemented [in Bitcoin
Core](https://github.com/bitcoin/bitcoin/pull/15649) for [
BIP 324 Encrypted
Transport](https://github.com/bitcoin/bips/blob/master/bip-0324.mediawiki)
as well. This has widespread support in browsers and common
cryptographic libraries. AES-GCM is more widespread but slower without
hardware support and not typically already a dependency in bitcoin software.
#### HKDF-SHA256
SHA-256 is necessarily available in bitcoin contexts.
## Attack vectors
In addition to the attack vectors and mitigations in
[BIP 78](https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#attack-vectors),
this proposal has the following attack vectors.
### Directory Denial of Service
Since each mailbox stores arbitrary encrypted payloads, directories are
vulnerable to flooding. To mitigate such denial of service attacks,
directory operators may respond with `401` unauthorized unless an
authorization token is provided. Authorization tokens must be unlinkable
to preserve client privacy. A specific unlinkable authorization token
mechanism is out of the scope of this proposal.
### Network privacy
Oblivious HTTP must be used to protect the IP addresses of both sender
and receiver from the directory. This requires an OHTTP Key
Configuration to be shared in the Payjoin URI and for the directory to
support Oblivious HTTP.
Unlike BIP 78 implementations, sender and receiver clients will only see
the IP address of the directory and not that of the client they are
interacting with.
Senders that submit requests directly to the directory, without using
an OHTTP Relay, may reveal their IP address to the receiver since that
receiver also specifies the directory.
## Backwards compatibility
Senders not supporting Payjoin will just ignore the `pj` parameter and
proceed to typical address-based transaction flows.
All Payjoin versions use [Bitcoin URIs](#payjoin-uri).
Receivers may choose to accept BIP 78 payloads at their discretion.
A BIP 78 sender posts their request to the directory, which stores
and forwards it to the BIP 77 receiver. A backwards-compatible
receiver proceeds with the BIP 78 checks if the encapsulated response
body is UTF-8 plaintext, signifying BIP 78. In order to service the
request, a BIP 78 response must be returned to the sender within 30
seconds or else the directory should respond with an `unavailable` JSON
error code as [defined in BIP
78](https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#receivers-well-known-errors).
When responding to a BIP 78 sender, the receiver MUST NOT HPKE-encrypt
the *Proposal PSBT*. The receiver MUST send the *Proposal PSBT* as the
body of a PUT request, with the body being the base64-encoded PSBT,
encoded as ASCII bytes. The target mailbox endpoint MUST be the
receiver's own mailbox (the same mailbox at which the sender posted the
*Original PSBT*), because a BIP 78 sender provides no reply key from which
a sender-side reply mailbox could be derived. The PUT request is then
OHTTP-encapsulated to the directory's OHTTP Gateway as for any other
Payjoin Directory interaction.
## Reference implementation
A production reference implementation client can be found at
<https://crates.io/crates/payjoin-cli>. Source code for the clients, the
directory, and development kit may be found here:
<https://github.com/payjoin/rust-payjoin>. Source code for an Oblivious
HTTP relay implementation may be found here:
<https://github.com/payjoin/ohttp-relay>.
## Changelog
- 0.2.0 2025-07-08
- Change fragment parameter delimiter from `+` to `-` to improve
compatibility with generic URI parsing libraries, and order them
lexicographically. `+` can cause issues due to a common convention (not
specified in RFC 3986, but in RFC 1866, in relation to HTML form
submission and query parameters) of interpreting `+` as ` ` when decoding
URIs.
- 0.1.0 2025-05-28
- First merged Draft version of BIP 77

View File

@ -2,14 +2,12 @@
BIP: 78
Layer: Applications
Title: A Simple Payjoin Proposal
Author: Nicolas Dorier <nicolas.dorier@gmail.com>
Replaces: 79
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0078
Status: Draft
Type: Standards Track
Created: 2019-05-01
Authors: Nicolas Dorier <nicolas.dorier@gmail.com>
Status: Deployed
Type: Specification
Assigned: 2019-05-01
License: BSD-2-Clause
Replaces: 79
</pre>
==Introduction==
@ -95,7 +93,7 @@ The payjoin proposal PSBT is sent in the HTTP response body, base64 serialized w
To ensure compatibility with web-wallets and browser-based-tools, all responses (including errors) must contain the HTTP header <code>Access-Control-Allow-Origin: *</code>.
The sender must ensure that the url refers to a scheme or protocol using authenticated encryption, for example TLS with certificate validation, or a .onion link to a hidden service whose public key identifier has already been communicated via a TLS connection. Senders SHOULD NOT accept a url representing an unencrypted or unauthenticated connection.
The sender must ensure that the URL refers to a scheme or protocol using authenticated encryption, for example TLS with certificate validation, or a .onion link to a hidden service whose public key identifier has already been communicated via a TLS connection. Senders SHOULD NOT accept a URL representing an unencrypted or unauthenticated connection.
The original PSBT MUST:
* Have all the <code>witnessUTXO</code> or <code>nonWitnessUTXO</code> information filled in.
@ -106,14 +104,20 @@ The original PSBT MUST:
The original PSBT MAY:
* Have outputs unrelated to the payment for batching purpose.
The original PSBT SHOULD NOT:
* Include mixed input types until September 2024. Mixed inputs were previously completely disallowed so this gives some grace period for receivers to update.
The payjoin proposal MUST:
* Use all the inputs from the original PSBT.
* Use all the outputs which do not belongs to the receiver from the original PSBT.
* Use all the outputs which do not belong to the receiver from the original PSBT.
* Only finalize the inputs added by the receiver. (Referred later as <code>additional inputs</code>)
* Only fill the <code>witnessUTXO</code> or <code>nonWitnessUTXO</code> for the additional inputs.
The payjoin proposal MAY:
* Add, remove or modify the outputs belonging to the receiver.
* Add, or replace the outputs belonging to the receiver unless output substitution is disabled.
The payjoin proposal SHOULD NOT:
* Include mixed input types until September 2024. Mixed inputs were previously completely disallowed so this gives some grace period for senders to update.
The payjoin proposal MUST NOT:
* Shuffle the order of inputs or outputs, the additional outputs or additional inputs must be inserted at a random index.
@ -125,6 +129,8 @@ This proposal is defining the following new [[bip-0021.mediawiki|BIP 21 URI]] pa
* <code>pj=</code>: Represents an http(s) endpoint which the sender can POST the original PSBT.
* <code>pjos=0</code>: Signal to the sender that they MUST disallow [[#output-substitution|payment output substitution]]. (See [[#unsecured-payjoin|Unsecured payjoin server]])
Note: the <code>amount</code> parameter is *not* required.
===<span id="optional-params"></span>Optional parameters===
When the payjoin sender posts the original PSBT to the receiver, he can optionally specify the following HTTP query string parameters:
@ -143,7 +149,7 @@ If the receiver does not support the version of the sender, they should send an
}
</pre>
* <code>additionalfeeoutputindex=</code>, if the sender is willing to pay for increased fee, this indicate output can have its value substracted to pay for it.
* <code>additionalfeeoutputindex=</code>, if the sender is willing to pay for increased fee, this indicate output can have its value subtracted to pay for it.
If the <code>additionalfeeoutputindex</code> is out of bounds or pointing to the payment output meant for the receiver, the receiver should ignore the parameter. See [[#fee-output|fee output]] for more information.
@ -187,10 +193,10 @@ The well-known error codes are:
|The receiver rejected the original PSBT.
|}
The receiver is allowed to return implementation specific errors which may assist the sender to diagnose any issue.
The receiver is allowed to return implementation-specific errors which may assist the sender to diagnose any issue.
However, it is important that error codes that are not well-known and that the message do not appear on the sender's software user interface.
Such error codes or messages could be used maliciously to phish a non technical user.
Such error codes or messages could be used maliciously to phish a non-technical user.
Instead those errors or messages can only appear in debug logs.
It is advised to hard code the description of the well known error codes into the sender's software.
@ -198,9 +204,9 @@ It is advised to hard code the description of the well known error codes into th
===<span id="fee-output"></span>Fee output===
In some situation, the sender might want to pay some additional fee in the payjoin proposal.
If such is the case, the sender must use both [[#optional-params|optional parameters]] <code>additionalfeeoutputindex=</code> and <code>maxadditionalfeecontribution=</code> to indicate which output and how much the receiver can substract fee.
If such is the case, the sender must use both [[#optional-params|optional parameters]] <code>additionalfeeoutputindex=</code> and <code>maxadditionalfeecontribution=</code> to indicate which output and how much the receiver can subtract fee.
There is several cases where a fee output is useful:
There are several cases where a fee output is useful:
* The sender's original transaction's fee rate is at the minimum accepted by the network, aka <code>minimum relay transaction fee rate</code>, which is typically 1 satoshi per vbyte.
@ -213,28 +219,9 @@ To prevent this, the sender can agree to pay more fee so the receiver make sure
* The sender's transaction is time sensitive.
When a sender pick a specific fee rate, the sender expects the transaction to be confirmed after a specific amount of time. But if the receiver adds an input without bumping the fee of the transaction, the payjoin transaction fee rate will be lower, and thus, longer to confirm.
Our recommendation for <code>maxadditionalfeecontribution=</code> is <code>originalPSBTFeeRate * vsize(sender_input_type)</code>.
{| class="wikitable"
!sender_input_type
!vsize(sender_input_type)
|-
|P2WPKH
|68
|-
|P2PKH
|148
|-
|P2SH-P2WPKH
|91
|-
|P2TR
|58
|}
When a sender picks a specific fee rate, the sender expects the transaction to be confirmed after a specific amount of time. But if the receiver adds an input without bumping the fee of the transaction, the payjoin transaction fee rate will be lower, and thus, longer to confirm.
Our recommendation for <code>maxadditionalfeecontribution=</code> is <code>originalPSBTFeeRate * 110</code>.
===Receiver's original PSBT checklist===
@ -242,10 +229,9 @@ The receiver needs to do some check on the original PSBT before proceeding:
* Non-interactive receivers (like a payment processor) need to check that the original PSBT is broadcastable. <code>*</code>
* If the sender included inputs in the original PSBT owned by the receiver, the receiver must either return error <code>original-psbt-rejected</code> or make sure they do not sign those inputs in the payjoin proposal.
* If the sender's inputs are all from the same scriptPubKey type, the receiver must match the same type. If the receiver can't match the type, they must return error <code>unavailable</code>.
* Make sure that the inputs included in the original transaction have never been seen before.
** This prevent [[#probing-attack|probing attacks]].
** This prevent reentrant payjoin, where a sender attempts to use payjoin transaction as a new original transaction for a new payjoin.
** This prevents [[#probing-attack|probing attacks]].
** This prevents reentrant payjoin, where a sender attempts to use payjoin transaction as a new original transaction for a new payjoin.
<code>*</code>: Interactive receivers are not required to validate the original PSBT because they are not exposed to [[#probing-attack|probing attacks]].
@ -257,26 +243,24 @@ The sender should check the payjoin proposal before signing it to prevent a mali
* If the receiver's BIP21 signalled <code>pjos=0</code>, disable payment output substitution.
* Verify that the transaction version, and the nLockTime are unchanged.
* Check that the sender's inputs' sequence numbers are unchanged.
* For each inputs in the proposal:
** Verify that no keypaths is in the PSBT input
* For each input in the proposal:
** Verify that no keypaths are in the PSBT input
** Verify that no partial signature has been filled
** If it is one of the sender's input
** If it is one of the sender's inputs:
*** Verify that input's sequence is unchanged.
*** Verify the PSBT input is not finalized
*** Verify that <code>non_witness_utxo</code> and <code>witness_utxo</code> are not specified.
** If it is one of the receiver's input
** If it is one of the receiver's inputs:
*** Verify the PSBT input is finalized
*** Verify that <code>non_witness_utxo</code> or <code>witness_utxo</code> are filled in.
** Verify that the payjoin proposal did not introduced mixed input's sequence.
** Verify that the payjoin proposal did not introduced mixed input's type.
** Verify that the payjoin proposal inputs all specify the same sequence value.
** Verify that all of sender's inputs from the original PSBT are in the proposal.
* For each outputs in the proposal:
** Verify that no keypaths is in the PSBT output
* For each output in the proposal:
** Verify that no keypaths are in the PSBT output
** If the output is the [[#fee-output|fee output]]:
*** The amount that was substracted from the output's value is less than or equal to <code>maxadditionalfeecontribution</code>. Let's call this amount <code>actual contribution</code>.
*** Make sure the actual contribution is only paying fee: The <code>actual contribution</code> is less than or equals to the difference of absolute fee between the payjoin proposal and the original PSBT.
*** Make sure the actual contribution is only paying for fee incurred by additional inputs: <code>actual contribution</code> is less than or equals to <code>originalPSBTFeeRate * vsize(sender_input_type) * (count(payjoin_proposal_inputs) - count(original_psbt_inputs))</code>. (see [[#fee-output|Fee output]] section)
** If the output is the payment output and payment output substitution is allowed.
*** The amount that was subtracted from the output's value is less than or equal to <code>maxadditionalfeecontribution</code>. Let's call this amount <code>actual contribution</code>.
*** Make sure the actual contribution is only going towards fees: The <code>actual contribution</code> is less than or equals to the difference of absolute fee between the payjoin proposal and the original PSBT.
*** Make sure the actual contribution is only paying for fees incurred by additional inputs: <code>actual contribution</code> is less than or equal to <code>originalPSBTFeeRate * vsize(sender_input_type) * (count(payjoin_proposal_inputs) - count(original_psbt_inputs))</code>. (see [[#fee-output|Fee output]] section)
** If the output is the payment output and payment output substitution is allowed,
*** Do not make any check
** Else
*** Make sure the output's value did not decrease.
@ -287,15 +271,15 @@ The sender must be careful to only sign the inputs that were present in the orig
Note:
* The sender must allow the receiver to add/remove or modify the receiver's own outputs. (if payment output substitution is disabled, the receiver's outputs must not be removed or decreased in value)
* The sender should allow the receiver to not add any inputs. This is useful for the receiver to change the paymout output scriptPubKey type.
* If no input have been added, the sender's wallet implementation should accept the payjoin proposal, but not mark the transaction as an actual payjoin in the user interface.
* The sender should allow the receiver to not add any inputs. This is useful for the receiver to change the payment output scriptPubKey type.
* If the receiver added no inputs, the sender's wallet implementation should accept the payjoin proposal, but not mark the transaction as an actual payjoin in the user interface.
Our method of checking the fee allows the receiver and the sender to batch payments in the payjoin transaction.
It also allows the receiver to pay the fee for batching adding his own outputs.
==Rationale==
There is several consequences of our proposal:
There are several consequences of our proposal:
* The receiver can bump the fee of the original transaction.
* The receiver can modify the outputs of the original PSBT.
@ -344,8 +328,8 @@ On top of this the receiver can poison analysis by randomly faking a round amoun
===<span id="output-substitution"></span>Payment output substitution===
Unless disallowed by sender explicitely via `disableoutputsubstitution=true` or by the BIP21 url via query parameter the `pjos=0`, the receiver is free to decrease the amount, remove, or change the scriptPubKey output paying to himself.
Note that if payment output substitution is disallowed, the reveiver can still increase the amount of the output. (See [[#reference-impl|the reference implementation]])
Unless disallowed by the sender explicitly via <code>disableoutputsubstitution=true</code> or by the BIP21 URL via the query parameter <code>pjos=0</code>, the receiver is free to decrease the amount or change the scriptPubKey output paying to himself.
Note that if payment output substitution is disallowed, the receiver can still increase the amount of the output. (See [[#reference-impl|the reference implementation]])
For example, if the sender's scriptPubKey type is P2WPKH while the receiver's payment output in the original PSBT is P2SH, then the receiver can substitute the payment output to be P2WPKH to match the sender's scriptPubKey type.
@ -358,7 +342,7 @@ A compromised payjoin server could steal the hot wallet outputs of the receiver,
===Impacted heuristics===
Our proposal of payjoin is breaking the following blockchain heuristics:
Our proposal of payjoin breaks the following blockchain heuristics:
* Common inputs heuristics.
@ -408,12 +392,12 @@ With payjoin, the maximum amount of money that can be lost is equal to two payme
==<span id="reference-impl"></span>Reference sender's implementation==
Here is pseudo code of a sender implementation.
<code>RequestPayjoin</code> takes the bip21 URI of the payment, the wallet and the <code>signedPSBT</code>.
<code>RequestPayjoin</code> takes the BIP21 URI of the payment, the wallet and the <code>signedPSBT</code>.
The <code>signedPSBT</code> represents a PSBT which has been fully signed, but not yet finalized.
We then prepare <code>originalPSBT</code> from the <code>signedPSBT</code> via the <code>CreateOriginalPSBT</code> function and get back the <code>proposal</code>.
While we verify the <code>proposal</code>, we also import into it informations about our own inputs and outputs from the <code>signedPSBT</code>.
While we verify the <code>proposal</code>, we also import into it information about our own inputs and outputs from the <code>signedPSBT</code>.
At the end of this <code>RequestPayjoin</code>, the proposal is verified and ready to be signed.
We logged the different PSBT involved, and show the result in our [[#test-vectors|test vectors]].
@ -429,7 +413,6 @@ public async Task<PSBT> RequestPayjoin(
var endpoint = bip21.ExtractPayjointEndpoint();
if (signedPSBT.IsAllFinalized())
throw new InvalidOperationException("The original PSBT should not be finalized.");
ScriptPubKeyType inputScriptType = wallet.ScriptPubKeyType();
PSBTOutput feePSBTOutput = null;
bool allowOutputSubstitution = !optionalParameters.DisableOutputSubstitution;
@ -497,9 +480,6 @@ public async Task<PSBT> RequestPayjoin(
// Verify the PSBT input is not finalized
if (proposedPSBTInput.IsFinalized())
throw new PayjoinSenderException("The receiver finalized one of our inputs");
// Verify that <code>non_witness_utxo</code> and <code>witness_utxo</code> are not specified.
if (proposedPSBTInput.NonWitnessUtxo != null || proposedPSBTInput.WitnessUtxo != null)
throw new PayjoinSenderException("The receiver added non_witness_utxo or witness_utxo to one of our inputs");
sequences.Add(proposedTxIn.Sequence);
// Fill up the info from the original PSBT input so we can sign and get fees.
@ -520,9 +500,6 @@ public async Task<PSBT> RequestPayjoin(
if (proposedPSBTInput.NonWitnessUtxo == null && proposedPSBTInput.WitnessUtxo == null)
throw new PayjoinSenderException("The receiver did not specify non_witness_utxo or witness_utxo for one of their inputs");
sequences.Add(proposedTxIn.Sequence);
// Verify that the payjoin proposal did not introduced mixed inputs' type.
if (inputScriptType != proposedPSBTInput.GetInputScriptPubKeyType())
throw new PayjoinSenderException("Mixed input type detected in the proposal");
}
}
@ -554,18 +531,19 @@ public async Task<PSBT> RequestPayjoin(
if (isOriginalOutput || substitutedOutput)
{
originalOutputs.Dequeue();
if (output.OriginalTxOut == feeOutput)
if (originalOutput.OriginalTxOut == feeOutput)
{
var actualContribution = feeOutput.Value - proposedPSBTOutput.Value;
// The amount that was substracted from the output's value is less than or equal to maxadditionalfeecontribution
// The amount that was subtracted from the output's value is less than or equal to maxadditionalfeecontribution
if (actualContribution > optionalParameters.MaxAdditionalFeeContribution)
throw new PayjoinSenderException("The actual contribution is more than maxadditionalfeecontribution");
// Make sure the actual contribution is only paying fee
if (actualContribution > additionalFee)
throw new PayjoinSenderException("The actual contribution is not only paying fee");
// Make sure the actual contribution is only paying for fee incurred by additional inputs
// This assumes an additional input can be up to 110 bytes.
int additionalInputsCount = proposalGlobalTx.Inputs.Count - originalGlobalTx.Inputs.Count;
if (actualContribution > originalFeeRate * GetVirtualSize(inputScriptType) * additionalInputsCount)
if (actualContribution > originalFeeRate * 110 * additionalInputsCount)
throw new PayjoinSenderException("The actual contribution is not only paying for additional inputs");
}
else if (allowOutputSubstitution && output.OriginalTxOut.ScriptPubKey == paymentScriptPubKey)
@ -600,21 +578,6 @@ public async Task<PSBT> RequestPayjoin(
return proposal;
}
int GetVirtualSize(ScriptPubKeyType? scriptPubKeyType)
{
switch (scriptPubKeyType)
{
case ScriptPubKeyType.Legacy:
return 148;
case ScriptPubKeyType.Segwit:
return 68;
case ScriptPubKeyType.SegwitP2SH:
return 91;
default:
return 110;
}
}
// Finalize the signedPSBT and remove confidential information
PSBT CreateOriginalPSBT(PSBT signedPSBT)
{
@ -642,7 +605,7 @@ A successful exchange with:
{| class="wikitable"
!InputScriptType
!Orginal PSBT Fee rate
!Original PSBT Fee rate
!maxadditionalfeecontribution
!additionalfeeoutputindex
|-
@ -659,7 +622,7 @@ A successful exchange with:
<pre>cHNidP8BAHMCAAAAAY8nutGgJdyYGXWiBEb45Hoe9lWGbkxh/6bNiOJdCDuDAAAAAAD+////AtyVuAUAAAAAF6kUHehJ8GnSdBUOOv6ujXLrWmsJRDCHgIQeAAAAAAAXqRR3QJbbz0hnQ8IvQ0fptGn+votneofTAAAAAAEBIKgb1wUAAAAAF6kU3k4ekGHKWRNbA1rV5tR5kEVDVNCHAQcXFgAUx4pFclNVgo1WWAdN1SYNX8tphTABCGsCRzBEAiB8Q+A6dep+Rz92vhy26lT0AjZn4PRLi8Bf9qoB/CMk0wIgP/Rj2PWZ3gEjUkTlhDRNAQ0gXwTO7t9n+V14pZ6oljUBIQMVmsAaoNWHVMS02LfTSe0e388LNitPa1UQZyOihY+FFgABABYAFEb2Giu6c4KO5YW0pfw3lGp9jMUUAAA=</pre>
<code>payjoin proposal</code>
<pre>cHNidP8BAJwCAAAAAo8nutGgJdyYGXWiBEb45Hoe9lWGbkxh/6bNiOJdCDuDAAAAAAD+////jye60aAl3JgZdaIERvjkeh72VYZuTGH/ps2I4l0IO4MBAAAAAP7///8CJpW4BQAAAAAXqRQd6EnwadJ0FQ46/q6NcutaawlEMIcACT0AAAAAABepFHdAltvPSGdDwi9DR+m0af6+i2d6h9MAAAAAAAEBIICEHgAAAAAAF6kUyPLL+cphRyyI5GTUazV0hF2R2NWHAQcXFgAUX4BmVeWSTJIEwtUb5TlPS/ntohABCGsCRzBEAiBnu3tA3yWlT0WBClsXXS9j69Bt+waCs9JcjWtNjtv7VgIge2VYAaBeLPDB6HGFlpqOENXMldsJezF9Gs5amvDQRDQBIQJl1jz1tBt8hNx2owTm+4Du4isx0pmdKNMNIjjaMHFfrQAAAA==</pre>
<pre>cHNidP8BAJwCAAAAAo8nutGgJdyYGXWiBEb45Hoe9lWGbkxh/6bNiOJdCDuDAAAAAAD+////jye60aAl3JgZdaIERvjkeh72VYZuTGH/ps2I4l0IO4MBAAAAAP7///8CJpW4BQAAAAAXqRQd6EnwadJ0FQ46/q6NcutaawlEMIcACT0AAAAAABepFHdAltvPSGdDwi9DR+m0af6+i2d6h9MAAAAAAQEgqBvXBQAAAAAXqRTeTh6QYcpZE1sDWtXm1HmQRUNU0IcAAQEggIQeAAAAAAAXqRTI8sv5ymFHLIjkZNRrNXSEXZHY1YcBBxcWABRfgGZV5ZJMkgTC1RvlOU9L+e2iEAEIawJHMEQCIGe7e0DfJaVPRYEKWxddL2Pr0G37BoKz0lyNa02O2/tWAiB7ZVgBoF4s8MHocYWWmo4Q1cyV2wl7MX0azlqa8NBENAEhAmXWPPW0G3yE3HajBOb7gO7iKzHSmZ0o0w0iONowcV+tAAAA</pre>
<code>payjoin proposal filled with sender's information</code>
<pre>cHNidP8BAJwCAAAAAo8nutGgJdyYGXWiBEb45Hoe9lWGbkxh/6bNiOJdCDuDAAAAAAD+////jye60aAl3JgZdaIERvjkeh72VYZuTGH/ps2I4l0IO4MBAAAAAP7///8CJpW4BQAAAAAXqRQd6EnwadJ0FQ46/q6NcutaawlEMIcACT0AAAAAABepFHdAltvPSGdDwi9DR+m0af6+i2d6h9MAAAAAAQEgqBvXBQAAAAAXqRTeTh6QYcpZE1sDWtXm1HmQRUNU0IcBBBYAFMeKRXJTVYKNVlgHTdUmDV/LaYUwIgYDFZrAGqDVh1TEtNi300ntHt/PCzYrT2tVEGcjooWPhRYYSFzWUDEAAIABAACAAAAAgAEAAAAAAAAAAAEBIICEHgAAAAAAF6kUyPLL+cphRyyI5GTUazV0hF2R2NWHAQcXFgAUX4BmVeWSTJIEwtUb5TlPS/ntohABCGsCRzBEAiBnu3tA3yWlT0WBClsXXS9j69Bt+waCs9JcjWtNjtv7VgIge2VYAaBeLPDB6HGFlpqOENXMldsJezF9Gs5amvDQRDQBIQJl1jz1tBt8hNx2owTm+4Du4isx0pmdKNMNIjjaMHFfrQABABYAFEb2Giu6c4KO5YW0pfw3lGp9jMUUIgICygvBWB5prpfx61y1HDAwo37kYP3YRJBvAjtunBAur3wYSFzWUDEAAIABAACAAAAAgAEAAAABAAAAAAA=</pre>
@ -674,7 +637,7 @@ A successful exchange with:
==Backward compatibility==
The receivers are advertising payjoin capabilities through [[bip-0021.mediawiki|BIP21's URI Scheme]].
The receivers advertise payjoin capabilities through [[bip-0021.mediawiki|BIP21's URI Scheme]].
Senders not supporting payjoin will just ignore the <code>pj</code> variable and thus, will proceed to normal payment.

View File

@ -2,14 +2,12 @@
BIP: 79
Layer: Applications
Title: Bustapay :: a practical coinjoin protocol
Author: Ryan Havar <rhavar@protonmail.com>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0079
Status: Replaced
Authors: Ryan Havar <rhavar@protonmail.com>
Status: Closed
Type: Informational
Created: 2018-10-05
Assigned: 2018-10-05
License: CC0-1.0
Superseded-By: 78
Proposed-Replacement: 78
</pre>
@ -74,7 +72,7 @@ Should the receiver reject a transaction, it should not attempt to propagate it
The receiver must add at least one input to the transaction (the "contributed inputs"). If the receiver has no inputs, it should use a 500 internal server error, so the client can send the transaction as per normal (or try again later). Its generally advised to only add a single contributed input, however they are circumstances where adding more than a single input can be useful.
To prevent an attack where a receiver is continually sent variations of the same transaction to enumerate the receivers utxo set, it is essential that the receiver always returns the same contributed inputs when it's seen the same inputs.
To prevent an attack where a receiver is continually sent variations of the same transaction to enumerate the receiver's utxo set, it is essential that the receiver always returns the same contributed inputs when it's seen the same inputs.
It is strongly preferable that the receiver makes an effort to pick a contributed input of the same type as the other transaction inputs if possible.
@ -84,7 +82,7 @@ After adding inputs to the transaction, the receiver generally will want to adju
=== Returning the partial transaction ===
The receiver must sign all contributed inputs in the partial transaction. The partial transaction should also remove all witnesses from the the original template transaction as they are no longer valid, and need to be recalculated by the sender. The receiver returns the partial transaction as a binary-encoded HTTP response with a status code of 200. To ensure compatibility with web-wallets and browser-based-tools, all responses (including errors) must contain the HTTP header "Access-Control-Allow-Origin: *"
The receiver must sign all contributed inputs in the partial transaction. The partial transaction should also remove all witnesses from the original template transaction as they are no longer valid, and need to be recalculated by the sender. The receiver returns the partial transaction as a binary-encoded HTTP response with a status code of 200. To ensure compatibility with web-wallets and browser-based-tools, all responses (including errors) must contain the HTTP header "Access-Control-Allow-Origin: *"
=== Sender Validation ===
@ -97,7 +95,7 @@ The sender *must* do important validation on the partial transaction. They *must
=== Creating Final Transaction ===
After validating the partial transaction, the sender signs all its inputs to create what is now the final transaction. It is important that the sender is careful to not be tricked by the receiver into signing other inputs it owns. The sender must only sign inputs that existed in the template transaction. If the sender is not careful the receiver may "contribute" inputs that are actually owned with by the sender, with the hope the sender blindly signs everything.
After validating the partial transaction, the sender signs all its inputs to create what is now the final transaction. It is important that the sender is careful to not be tricked by the receiver into signing other inputs it owns. The sender must only sign inputs that existed in the template transaction. If the sender is not careful the receiver may "contribute" inputs that are actually owned by the sender, with the hope the sender blindly signs everything.
=== Transaction Publishing ===

View File

@ -1,13 +1,11 @@
<pre>
BIP: 80
Title: Hierarchy for Non-Colored Voting Pool Deterministic Multisig Wallets
Author: Justus Ranvier <justus@opentransactions.org>
Jimmy Song <jimmy@monetas.net>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0080
Status: Deferred
Authors: Justus Ranvier <justus@opentransactions.org>
Jimmy Song <jimmy@monetas.net>
Status: Closed
Type: Informational
Created: 2014-08-11
Assigned: 2014-08-11
License: PD
</pre>
@ -35,7 +33,7 @@ Each level has a special meaning, described in the chapters below.
===Purpose===
Purpose is a constant set following the BIP43 recommendation to: the ASCII value of "80" with the most signifigant bit set to indicate hardened derivation (0x80000050). It indicates that the subtree of this node is used according to this specification.
Purpose is a constant set following the BIP43 recommendation to: the ASCII value of "80" with the most significant bit set to indicate hardened derivation (0x80000050). It indicates that the subtree of this node is used according to this specification.
Hardened derivation is used at this level.

View File

@ -1,13 +1,11 @@
<pre>
BIP: 81
Title: Hierarchy for Colored Voting Pool Deterministic Multisig Wallets
Author: Justus Ranvier <justus@opentransactions.org>
Jimmy Song <jimmy@monetas.net>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0081
Status: Deferred
Authors: Justus Ranvier <justus@opentransactions.org>
Jimmy Song <jimmy@monetas.net>
Status: Closed
Type: Informational
Created: 2014-08-11
Assigned: 2014-08-11
License: PD
</pre>
@ -35,7 +33,7 @@ Each level has a special meaning, described in the chapters below.
===Purpose===
Purpose is a constant set following the BIP43 recommendation to: the ASCII value of "81" with the most signifigant bit set to indicate hardened derivation (0x80000051). It indicates that the subtree of this node is used according to this specification.
Purpose is a constant set following the BIP43 recommendation to: the ASCII value of "81" with the most significant bit set to indicate hardened derivation (0x80000051). It indicates that the subtree of this node is used according to this specification.
Hardened derivation is used at this level.

View File

@ -2,12 +2,10 @@
BIP: 83
Layer: Applications
Title: Dynamic Hierarchical Deterministic Key Trees
Author: Eric Lombrozo <eric@ciphrex.com>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0083
Status: Rejected
Type: Standards Track
Created: 2015-11-16
Authors: Eric Lombrozo <eric@ciphrex.com>
Status: Closed
Type: Specification
Assigned: 2015-11-16
License: PD
</pre>
@ -53,7 +51,7 @@ p //' n instead of p / 0' / n
Rather than specifying upfront which path is to be used for a specific purpose (i.e. external invoicing vs. internal change), different applications can specify arbitrary parent nodes and derivation paths. This allows for nesting of sublevels to arbitrary depth with application-specified semantics. Rather than trying to specify use cases upfront, we leave the design completely open-ended. Different applications can exchange these mappings for interoperability. Eventually, if certain mappings become popular, application user interfaces can provide convenient shortcuts or use them as defaults.
Note that BIP32 suggests reserving child 0 for the derivation of signing keys rather than sublevels. It is not really necessary to reserve signing key parents, however, as each key's parent's path can be explicitly stated. But unless we reserve a child for sublevel derivation, we lose the ability to nest deeper levels into the hierarchy. While we could reserve any arbitrary index for nesting sublevels, reserving child 0 seems simplest to implement, leaving all indices > 0 for contiguously indexed signing keys. We could also use MAX_INDEX (2<sup>31</sup> - 1) for this purpose. However, we believe doing so introduces more ideosyncracies into the semantics and will present a problem if we ever decide to extend the scheme to use indices larger than 31 bits.
Note that BIP32 suggests reserving child 0 for the derivation of signing keys rather than sublevels. It is not really necessary to reserve signing key parents, however, as each key's parent's path can be explicitly stated. But unless we reserve a child for sublevel derivation, we lose the ability to nest deeper levels into the hierarchy. While we could reserve any arbitrary index for nesting sublevels, reserving child 0 seems simplest to implement, leaving all indices > 0 for contiguously indexed signing keys. We could also use MAX_INDEX (2<sup>31</sup> - 1) for this purpose. However, we believe doing so introduces more idiosyncrasies into the semantics and will present a problem if we ever decide to extend the scheme to use indices larger than 31 bits.
==Use Cases==
@ -83,7 +81,7 @@ We can continue creating subaccounts indefinitely using this scheme.
In order to create a bidirectional payment channel, it is necessary that previous commitments be revokable. In order to revoke previous commitments, each party reveals a secret to the other that would allow them to steal the funds in the channel if a transaction for a previous commitment is inserted into the blockchain.
By allowing for arbitrary nesting of sublevels, we can construct decision trees of arbitrary depth and revoke an entire branch by revealing a parent node used to derive all the children.
By allowing for arbitrary nesting of sublevels, we can construct decision trees of arbitrary depth and revoke an entire branch by revealing a parent node used to derive all the children.
==References==

View File

@ -2,12 +2,12 @@
BIP: 84
Layer: Applications
Title: Derivation scheme for P2WPKH based accounts
Author: Pavol Rusnak <stick@satoshilabs.com>
Authors: Pavol Rusnak <stick@satoshilabs.com>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0084
Status: Final
Type: Informational
Created: 2017-12-28
Status: Deployed
Type: Specification
Assigned: 2017-12-28
License: CC0-1.0
</pre>
@ -61,7 +61,7 @@ Additional registered version bytes are listed in [[https://github.com/satoshila
==Backwards Compatibility==
This BIP is not backwards compatible by design as described under [#considerations]. An incompatible wallet will not discover accounts at all and the user will notice that something is wrong.
This BIP is not backwards compatible by design as described under [[#considerations|considerations]]. An incompatible wallet will not discover accounts at all and the user will notice that something is wrong.
==Test vectors==

View File

@ -2,27 +2,30 @@
BIP: 85
Layer: Applications
Title: Deterministic Entropy From BIP32 Keychains
Author: Ethan Kosakovsky <ethankosakovsky@protonmail.com>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0085
Status: Draft
Authors: Ethan Kosakovsky <ethankosakovsky@protonmail.com>
Aneesh Karve <dowsing.seaport0d@icloud.com>
Status: Deployed
Type: Informational
Created: 2020-03-20
License: BSD-2-Clause
OPL
Assigned: 2020-03-20
License: BSD-2-Clause OR OPUBL-1.0
Version: 2.0.0
</pre>
==Abstract==
''"One Seed to rule them all,''
''One Key to find them,''
''One Path to bring them all,''
''"One Seed to rule them all,''<br>
''One Key to find them,''<br>
''One Path to bring them all,''<br>
''And in cryptography bind them."''
It is not possible to maintain one single (mnemonic) seed backup for all keychains used across various wallets because there are a variety of incompatible standards. Sharing of seeds across multiple wallets is not desirable for security reasons. Physical storage of multiple seeds is difficult depending on the security and redundancy required.
As HD keychains are essentially derived from initial entropy, this proposal provides a way to derive entropy from the keychain which can be fed into whatever method a wallet uses to derive the initial mnemonic seed or root key.
==Copyright==
This BIP is dual-licensed under the Open Publication License and BSD 2-clause license.
==Definitions==
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.
@ -33,13 +36,16 @@ The terminology related to keychains used in the wild varies widely, for example
# '''BIP39 mnemonic''' is the mnemonic phrase that is calculated from the entropy used before hashing of the mnemonic in BIP39.
# '''BIP39 seed''' is the result of hashing the BIP39 mnemonic seed.
When in doubt, assume big endian byte serialization, such that the leftmost
byte is the most significant.
==Motivation==
Most wallets implement BIP32 which defines how a BIP32 root key can be used to derive keychains. As a consequence, a backup of just the BIP32 root key is sufficient to include all keys derived from it. BIP32 does not have a human friendly serialization of the BIP32 root key (or BIP32 extended keys in general) which makes paper backups or manually restoring the key more error-prone. BIP39 was designed to solve this problem but rather than serialize the BIP32 root key, it takes some entropy, encoded to a "seed mnemonic", which is then hashed to derive the BIP39 seed which can be turned into the BIP32 root key. Saving the BIP39 mnemonic is enough to reconstruct the entire BIP32 keychain, but a BIP32 root key cannot be reversed back to the BIP39 mnemonic.
Most wallets implement BIP32 which defines how a BIP32 root key can be used to derive keychains. As a consequence, a backup of just the BIP32 root key is sufficient to include all keys derived from it. BIP32 does not have a human-friendly serialization of the BIP32 root key (or BIP32 extended keys in general), which makes paper backups or manually restoring the key more error-prone. BIP39 was designed to solve this problem, but rather than serialize the BIP32 root key, it takes some entropy, encoded to a "seed mnemonic", which is then hashed to derive the BIP39 seed, which can be turned into the BIP32 root key. Saving the BIP39 mnemonic is enough to reconstruct the entire BIP32 keychain, but a BIP32 root key cannot be reversed back to the BIP39 mnemonic.
Most wallets implement BIP39, so on initialization or restoration, the user must interact with a BIP39 mnemonic. Most wallets do not support BIP32 extended private keys, so each wallet must either share the same BIP39 mnemonic, or have a separate BIP39 mnemonic entirely. Neither scenarios are particularly satisfactory for security reasons. For example, some wallets may be inherently less secure like hot wallets on smartphones, Join Market servers, or Lightning Network nodes. Having multiple seeds is far from desirable, especially for those who rely on split key or redundancy backups in different geological locations. Adding is necessarily difficult and may result in users being more lazy with subsequent keys, resulting in compromised security or loss of keys.
Most wallets implement BIP39, so on initialization or restoration, the user must interact with a BIP39 mnemonic. Most wallets do not support BIP32 extended private keys, so each wallet must either share the same BIP39 mnemonic, or have a separate BIP39 mnemonic entirely. Neither scenario is particularly satisfactory for security reasons. For example, some wallets may be inherently less secure, like hot wallets on smartphones, JoinMarket servers, or Lightning Network nodes. Having multiple seeds is far from desirable, especially for those who rely on split key or redundancy backups in different geological locations. Adding keys is necessarily difficult and may result in users being more lazy with subsequent keys, resulting in compromised security or loss of keys.
There is added complication with wallets that implement other standards, or no standards at all. Bitcoin Core wallet uses a WIF as the ''hdseed'', and yet other wallets like Electrum use different mnemonic schemes to derive the BIP32 root key. Other cryptocurrencies like Monero also use an entirely different mnemonic scheme.
There is an added complication with wallets that implement other standards, or no standards at all. The Bitcoin Core wallet uses a WIF as the ''hdseed'', and yet other wallets, like Electrum, use different mnemonic schemes to derive the BIP32 root key. Other cryptocurrencies, like Monero, use an entirely different mnemonic scheme.
Ultimately, all of the mnemonic/seed schemes start with some "initial entropy" to derive a mnemonic/seed, and then process the mnemonic into a BIP32 key, or private key. We can use BIP32 itself to derive the "initial entropy" to then recreate the same mnemonic or seed according to the specific application standard of the target wallet. We can use a BIP44-like categorization to ensure uniform derivation according to the target application type.
@ -47,9 +53,13 @@ Ultimately, all of the mnemonic/seed schemes start with some "initial entropy" t
We assume a single BIP32 master root key. This specification is not concerned with how this was derived (e.g. directly or via a mnemonic scheme such as BIP39).
For each application that requires its own wallet, a unique private key is derived from the BIP32 master root key using a fully hardened derivation path. The resulting private key (k) is then processed with HMAC-SHA512, where the key is "bip-entropy-from-k", and the message payload is the private key k: <code>HMAC-SHA512(key="bip-entropy-from-k", msg=k)</code>. The result produces 512 bits of entropy. Each application SHOULD use up to the required number of bits necessary for their operation truncating the rest.
For each application that requires its own wallet, a unique private key is derived from the BIP32 master root key using a fully hardened derivation path. The resulting private key (k) is then processed with HMAC-SHA512, where the key is "bip-entropy-from-k", and the message payload is the private key k: <code>HMAC-SHA512(key="bip-entropy-from-k", msg=k)</code>
<ref name="hmac-sha512">
The reason for running the derived key through HMAC-SHA512 and truncating the result as necessary is to prevent leakage of the parent tree should the derived key (''k'') be compromised. While the specification requires the use of hardened key derivation which would prevent this, we cannot enforce hardened derivation, so this method ensures the derived entropy is hardened. Also, from a semantic point of view, since the purpose is to derive entropy and not a private key, we are required to transform the child key. This is done out of an abundance of caution, in order to ward off unwanted side effects should ''k'' be used for a dual purpose, including as a nonce ''hash(k)'', where undesirable and unforeseen interactions could occur.
</ref>.
The result produces 512 bits of entropy. Each application SHOULD use up to the required number of bits necessary for their operation, and truncate the rest.
The HMAC-SHA512 function is specified in [http://tools.ietf.org/html/rfc4231 RFC 4231].
The HMAC-SHA512 function is specified in [https://tools.ietf.org/html/rfc4231 RFC 4231].
===Test vectors===
@ -78,7 +88,7 @@ BIP85-DRNG-SHAKE256 is a deterministic random number generator for cryptographic
RSA key generation is an example of a function that requires orders of magnitude more than 64 bytes of random input. Further, it is not possible to precalculate the amount of random input required until the function has completed.
drng_reader = BIP85DRNG.new(bip85_entropy)
rsa_key = RSA.generate_key(4096, drng_reader.read())
rsa_key = RSA.generate_key(4096, drng_reader.read)
===Test Vectors===
INPUT:
@ -91,28 +101,13 @@ OUTPUT
* DRNG(80 bytes)=b78b1ee6b345eae6836c2d53d33c64cdaf9a696487be81b03e822dc84b3f1cd883d7559e53d175f243e4c349e822a957bbff9224bc5dde9492ef54e8a439f6bc8c7355b87a925a37ee405a7502991111
==Reference Implementation==
* Python library implementation: [https://github.com/ethankosakovsky/bip85]
* JavaScript library implementation: [https://github.com/hoganri/bip85-js]
===Other Implementations===
* JavaScript library implementation: [https://github.com/hoganri/bip85-js]
* Coldcard Firmware: [https://github.com/Coldcard/firmware/pull/39]
* Ian Coleman's Mnemonic Code Converter: [https://github.com/iancoleman/bip39] and [https://iancoleman.io/bip39/]
* AirGap Vault: [https://github.com/airgap-it/airgap-vault/commit/d64332fc2f332be622a1229acb27f621e23774d6]
* btc_hd_wallet: [https://github.com/scgbckbone/btc-hd-wallet]
==Applications==
The Application number defines how entropy will be used post processing. Some basic examples follow:
Derivation path uses the format <code>m/83696968'/{app_no}'/{index}'</code> where ''{app_no}'' is the path for the application, and ''{index}'' is the index.
Derivation paths follow the format <code>m/83696968'/{app_no}'/{index}'</code>, where ''{app_no}'' is the path for the application, and ''{index}'' is the index.
Application numbers should be semantic in some way, such as a BIP number or ASCII character code sequence.
===BIP39===
Application number: 39'
@ -155,6 +150,10 @@ Language Table
|-
| Czech
| 8'
|-
| Portuguese
| 9'
|-
|}
Words Table
@ -168,10 +167,18 @@ Words Table
| 128 bits
| 12'
|-
| 15 words
| 160 bits
| 15'
|-
| 18 words
| 192 bits
| 18'
|-
| 21 words
| 224 bits
| 21'
|-
| 24 words
| 256 bits
| 24'
@ -193,7 +200,7 @@ OUTPUT:
====18 English words====
BIP39 English 18 word mnemonic seed
196 bits of entropy as input to BIP39 to derive 18 word mnemonic
192 bits of entropy as input to BIP39 to derive 18 word mnemonic
INPUT:
* MASTER BIP32 ROOT KEY: xprv9s21ZrQH143K2LBWUUQRFXhucrQqBpKdRRxNVq2zBqsx8HVqFk2uYo8kmbaLLHRdqtQpUm98uKfu3vca1LqdGhUtyoFnCNkfmXRyPXLjbKb
@ -219,7 +226,16 @@ OUTPUT:
===HD-Seed WIF===
Application number: 2'
Uses 256 bits[1] of entropy as the secret exponent to derive a private key and encode as a compressed WIF which will be used as the hdseed for Bitcoin Core wallets.
Uses the most significant 256 bits<ref name="curve-order">
There is a very small chance that you'll make an invalid
key that is zero or larger than the order of the curve. If this occurs, software
should hard fail (forcing users to iterate to the next index). From BIP32:
<blockquote>
In case parse<sub>256</sub>(I<sub>L</sub>) ≥ n or k<sub>i</sub> = 0, the resulting key is invalid, and one should proceed with the next value for i. (Note: this has probability lower than 1 in 2<sup>127</sup>.)
</blockquote>
</ref>
of entropy as the secret exponent to derive a private key and encode as a compressed
WIF that will be used as the hdseed for Bitcoin Core wallets.
Path format is <code>m/83696968'/2'/{index}'</code>
@ -234,7 +250,11 @@ OUTPUT
===XPRV===
Application number: 32'
Taking 64 bytes of the HMAC digest, the first 32 bytes are the chain code, and second 32 bytes[1] are the private key for BIP32 XPRV value. Child number, depth, and parent fingerprint are forced to zero.
Taking 64 bytes of the HMAC digest, the first 32 bytes are the chain code, and the second 32 bytes<ref name="curve-order" /> are the private key for the BIP32 XPRV value. Child number, depth, and parent fingerprint are forced to zero.
''Warning'': The above order reverses the order of BIP32, which takes the first 32 bytes as the private key, and the second 32 bytes as the chain code.
Applications may support Testnet by emitting TPRV keys if and only if the input root key is a Testnet key.
Path format is <code>m/83696968'/32'/{index}'</code>
@ -269,12 +289,12 @@ The derivation path format is: <code>m/83696968'/707764'/{pwd_len}'/{index}'</co
`20 <= pwd_len <= 86`
[https://datatracker.ietf.org/doc/html/rfc4648 Base64] encode the all 64 bytes of entropy.
Remove any spaces or new lines inserted by Base64 encoding process. Slice base64 result string
[https://datatracker.ietf.org/doc/html/rfc4648 Base64] encode all 64 bytes of entropy.
Remove any spaces or new lines inserted by Base64 encoding process. Slice Base64 result string
on index 0 to `pwd_len`. This slice is the password. As `pwd_len` is limited to 86, passwords will not contain padding.
Entropy calculation:<br>
R = 64 (base64 - do not count padding)<br>
R = 64 (Base64 - do not count padding)<br>
L = pwd_len<br>
Entropy = log2(R ** L)<br>
@ -297,7 +317,7 @@ INPUT:
* PATH: m/83696968'/707764'/21'/0'
OUTPUT
* DERIVED ENTROPY=d7ad61d4a76575c5bad773feeb40299490b224e8e5df6c8ad8fe3d0a6eed7b85ead9fef7bcca8160f0ee48dc6e92b311fc71f2146623cc6952c03ce82c7b63fe
* DERIVED ENTROPY=74a2e87a9ba0cdd549bdd2f9ea880d554c6c355b08ed25088cfa88f3f1c4f74632b652fd4a8f5fda43074c6f6964a3753b08bb5210c8f5e75c07a4c2a20bf6e9
* DERIVED PWD=dKLoepugzdVJvdL56ogNV
===PWD BASE85===
@ -307,8 +327,8 @@ The derivation path format is: <code>m/83696968'/707785'/{pwd_len}'/{index}'</co
`10 <= pwd_len <= 80`
Base85 encode the all 64 bytes of entropy.
Remove any spaces or new lines inserted by Base64 encoding process. Slice base85 result string
Base85 encode all 64 bytes of entropy.
Remove any spaces or new lines inserted by Base85 encoding process. Slice Base85 result string
on index 0 to `pwd_len`. This slice is the password. `pwd_len` is limited to 80 characters.
Entropy calculation:<br>
@ -327,7 +347,7 @@ Entropy = log2(R ** L)<br>
|-
| 30 || 192.0
|-
| 20 || 512.0
| 80 || 512.0
|}
INPUT:
@ -360,39 +380,104 @@ Keys allocated for RSA-GPG purposes use the following scheme:
Note on timestamps:
The resulting RSA key can be used to create a GPG key where the creation date MUST be fixed to unix Epoch timestamp 1231006505 (the Bitcoin genesis block time <code>'2009-01-03 18:05:05'</code> UTC) because the key fingerprint is affected by the creation date (Epoch timestamp 0 was not chosen because of legacy behavior in GNUPG implementations for older keys). Additionally, when importing sub-keys under a key in GNUPG, the system time must be frozen to the same timestamp before importing (e.g. by use of <code>faketime</code>).
The resulting RSA key can be used to create a GPG key where the creation date MUST be fixed to UNIX Epoch timestamp 1231006505 (the Bitcoin genesis block time <code>'2009-01-03 18:15:05'</code> UTC)<ref>The human-readable datetime string was incorrectly noted as '2009-01-03 18:05:05' prior to v2.0.0 of this BIP, so implementations that relied on it rather than UNIX Epoch timestamp 1231006505 will produce different key fingerprints.</ref> because the key fingerprint is affected by the creation date (Epoch timestamp 0 was not chosen because of legacy behavior in GNUPG implementations for older keys). Additionally, when importing sub-keys under a key in GNUPG, the system time must be frozen to the same timestamp before importing (e.g. by use of <code>faketime</code>).
Note on GPG key capabilities on smartcard/hardware devices:
GPG capable smart-cards SHOULD be be loaded as follows: The encryption slot SHOULD be loaded with the ENCRYPTION capable key; the authentication slot SHOULD be loaded with the AUTHENTICATION capable key. The signature capable slot SHOULD be loaded with the SIGNATURE capable key.
GPG capable smart-cards SHOULD be loaded as follows: The encryption slot SHOULD be loaded with the ENCRYPTION capable key; the authentication slot SHOULD be loaded with the AUTHENTICATION capable key. The signature capable slot SHOULD be loaded with the SIGNATURE capable key.
However, depending on available slots on the smart-card, and preferred policy, the CERTIFY capable key MAY be flagged with CERTIFY and SIGNATURE capabilities and loaded into the SIGNATURE capable slot (for example where the smart-card has only three slots and the CERTIFY capability is required on the same card). In this case, the SIGNATURE capable sub-key would be disregarded because the CERTIFY capable key serves a dual purpose.
===DICE===
Application number: 89101'
The derivation path format is: <code>m/83696968'/89101'/{sides}'/{rolls}'/{index}'</code>
2 <= sides <= 2^32 - 1
1 <= rolls <= 2^32 - 1
Use this application to generate PIN numbers, numeric secrets, and secrets over custom alphabets.
For example, applications could generate alphanumeric passwords from a 62-sided die (26 + 26 + 10).
Roll values are zero-indexed, such that an N-sided die produces values in the range
<code>[0, N-1]</code>, inclusive. Applications should separate printed rolls by a comma or similar.
Create a BIP85 DRNG whose seed is the derived entropy.
Calculate the following integers:
bits_per_roll = ceil(log_2(sides))
bytes_per_roll = ceil(bits_per_roll / 8)
Read <code>bytes_per_roll</code> bytes from the DRNG.
Trim any bits in excess of <code>bits_per_roll</code> (retain the most
significant bits). The resulting integer represents a single roll or trial.
If the trial is greater than or equal to the number of sides, skip it and
move on to the next one. Repeat as needed until all rolls are complete.
INPUT:
* MASTER BIP32 ROOT KEY: xprv9s21ZrQH143K2LBWUUQRFXhucrQqBpKdRRxNVq2zBqsx8HVqFk2uYo8kmbaLLHRdqtQpUm98uKfu3vca1LqdGhUtyoFnCNkfmXRyPXLjbKb
* PATH: m/83696968'/89101'/6'/10'/0'
OUTPUT
* DERIVED ENTROPY=5e41f8f5d5d9ac09a20b8a5797a3172b28c806aead00d27e36609e2dd116a59176a738804236586f668da8a51b90c708a4226d7f92259c69f64c51124b6f6cd2
* DERIVED ROLLS=1,0,0,2,0,1,5,5,2,4
==Backwards Compatibility==
This specification is not backwards compatible with any other existing specification.
This specification relies on BIP32 but is agnostic to how the BIP32 root key is derived. As such, this standard is able to derive wallets with initialization schemes like BIP39 or Electrum wallet style mnemonics.
==Discussion==
The reason for running the derived key through HMAC-SHA512 and truncating the result as necessary is to prevent leakage of the parent tree should the derived key (''k'') be compromized. While the specification requires the use of hardended key derivation which would prevent this, we cannot enforce hardened derivation, so this method ensures the derived entropy is hardened. Also, from a semantic point of view, since the purpose is to derive entropy and not a private key, we are required to transform the child key. This is done out of an abundance of caution, in order to ward off unwanted side effects should ''k'' be used for a dual purpose, including as a nonce ''hash(k)'', where undesirable and unforeseen interactions could occur.
==Acknowledgements==
Many thanks to Peter Gray and Christopher Allen for their input, and to Peter for suggesting extra application use cases.
==References==
BIP32, BIP39
==Reference Implementations==
* 1.3.0 Python 3.x library implementation: [https://github.com/akarve/bipsea]
* 1.1.0 Python 2.x library implementation: [https://github.com/ethankosakovsky/bip85]
* 1.0.0 JavaScript library implementation: [https://github.com/hoganri/bip85-js]
==Changelog==
===2.0.0 (2025-09-19)===
====Fixed====
* Fixed the human-readable datetime string for BIP85 GPG Keys that was incorrectly stated as '2009-01-03 18:05:05' rather than '2009-01-03 18:15:05'. Implementations that relied on the previously incorrect datetime string instead of UNIX Epoch timestamp 1231006505 will produce different key fingerprints.
===1.3.0 (2024-10-22)===
====Added====
* Dice application 89101'
* Czech language code to application 39'
* TPRV guidance for application 32'
* Warning on application 32' key and chain code ordering
===1.2.0 (2022-12-04)===
====Added====
* Base64 application 707764'
* Base85 application 707785'
===1.1.0 (2020-11-19)===
====Added====
* BIP85-DRNG-SHAKE256
* RSA application 828365'
===1.0.0 (2020-06-11)===
* Initial version
==Footnotes==
[1] There is a very small chance that you'll make an invalid key that is zero or bigger than the order of the curve. If this occurs, software should hard fail (forcing users to iterate to the next index).
<references />
From BIP32:
In case parse<sub>256</sub>(I<sub>L</sub>) is 0 or ≥ n, the resulting key is invalid, and one should proceed with the next value for i. (Note: this has probability lower than 1 in 2<sup>127</sup>.)
==Acknowledgements==
==Copyright==
This BIP is dual-licensed under the Open Publication License and BSD 2-clause license.
Many thanks to Peter Gray and Christopher Allen for their input, and to Peter for suggesting extra application use cases.

View File

@ -2,12 +2,10 @@
BIP: 86
Layer: Applications
Title: Key Derivation for Single Key P2TR Outputs
Author: Ava Chow <me@achow101.com>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0086
Status: Draft
Type: Standards Track
Created: 2021-06-22
Authors: Ava Chow <me@achow101.com>
Status: Deployed
Type: Specification
Assigned: 2021-06-22
License: BSD-2-Clause
</pre>

View File

@ -2,12 +2,10 @@
BIP: 87
Layer: Applications
Title: Hierarchy for Deterministic Multisig Wallets
Author: Robert Spigler <RobertSpigler@ProtonMail.ch>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0087
Status: Proposed
Type: Standards Track
Created: 2020-03-11
Authors: Robert Spigler <RobertSpigler@ProtonMail.ch>
Status: Complete
Type: Specification
Assigned: 2020-03-11
License: BSD-2-Clause
</pre>
@ -40,7 +38,7 @@ A modern standardization is needed for multisig derivation paths. There are som
m / purpose' / cosigner_index / change / address_index
</pre>
BIP45 unecessarily demands a single script type (here, P2SH). In addition, BIP45 sets <code>cosigner_index</code> in order to sort the <code>purpose'</code> public keys of each cosigner. This too is redundant, as descriptors can set the order of the public keys with <code>multi</code> or have them sorted lexicographically (as described in [https://github.com/bitcoin/bips/blob/master/bip-0067.mediawiki BIP67]) with <code>sortedmulti</code>. Sorting public keys between cosigners in order to create the full derivation path, prior to sending the key record to the coordinator to create the descriptor, merely adds additional unnecessary communication rounds.
BIP45 unnecessarily demands a single script type (here, P2SH). In addition, BIP45 sets <code>cosigner_index</code> in order to sort the <code>purpose'</code> public keys of each cosigner. This too is redundant, as descriptors can set the order of the public keys with <code>multi</code> or have them sorted lexicographically (as described in [https://github.com/bitcoin/bips/blob/master/bip-0067.mediawiki BIP67]) with <code>sortedmulti</code>. Sorting public keys between cosigners in order to create the full derivation path, prior to sending the key record to the coordinator to create the descriptor, merely adds additional unnecessary communication rounds.
The second multisignature "standard" in use is m/48', which specifies:
@ -48,7 +46,7 @@ The second multisignature "standard" in use is m/48', which specifies:
m / purpose' / coin_type' / account' / script_type' / change / address_index
</pre>
Rather than following in BIP 44/49/84's path and having a separate BIP per script after P2SH (BIP45), vendors decided to insert <code>script_type'</code> into the derivation path (where P2SH-P2WSH=1, P2WSH=2, Future_Script=3, etc). As described previously, this is unnecessary, as the descriptor sets the script. While it attempts to reduce maintainence work by getting rid of new BIPs-per-script, it still requires maintaining an updated, redundant, <code>script_type</code> list.
Rather than following in BIP 44/49/84's path and having a separate BIP per script after P2SH (BIP45), vendors decided to insert <code>script_type'</code> into the derivation path (where P2SH-P2WSH=1, P2WSH=2, Future_Script=3, etc). As described previously, this is unnecessary, as the descriptor sets the script. While it attempts to reduce maintenance work by getting rid of new BIPs-per-script, it still requires maintaining an updated, redundant, <code>script_type</code> list.
The structure proposed later in this paper solves these issues and is quite comprehensive. It allows for the handling of multiple accounts, external and internal chains per account, and millions of addresses per chain, in a multi-party, multisignature, hierarchical deterministic wallet regardless of the script type <ref>'''Why propose this structure only for multisignature wallets?''' Currently, single-sig wallets are able to restore funds using just the master private key data (in the format of BIP39 usually). Even if the user doesn't recall the derivation used, the wallet implementation can iterate through common schemes (BIP44/49/84). With this proposed hierarchy, the user would either have to now backup additional data (the descriptor), or the wallet would have to attempt all script types for every account level when restoring. Because of this, even though the descriptor language handles the signature type just like it does the script type, it is best to restrict this script-agnostic hierarchy to multisignature wallets only.</ref>.
@ -105,7 +103,7 @@ Hardened derivation is used at this level.
It is crucial that this level is increased for each new wallet joined or private/public keys created; for both privacy and cryptographic purposes.
For example, before sending a new key record to a coordinator, the wallet must increment the <code>account'</code> level.
This prevents key reuse - across ECDSA and Schnorr signatures, across different script types, and inbetween the same wallet types.
This prevents key reuse - across ECDSA and Schnorr signatures, across different script types, and in between the same wallet types.
===Change===

View File

@ -2,12 +2,10 @@
BIP: 88
Layer: Applications
Title: Hierarchical Deterministic Path Templates
Author: Dmitry Petukhov <dp@simplexum.com>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0088
Status: Proposed
Authors: Dmitry Petukhov <dp@simplexum.com>
Status: Complete
Type: Informational
Created: 2020-06-23
Assigned: 2020-06-23
License: BSD-2-Clause
</pre>
@ -27,7 +25,7 @@ This BIP is licensed under the 2-clause BSD license.
BIP32 derivation path format is universal, and a number of schemes for derivation were proposed
in BIP43 and other documents, such as BIPs 44,45,49,84. The flexibility of the format also allowed
industry participants to implement custom derivation shemes that fit particular purposes,
industry participants to implement custom derivation schemes that fit particular purposes,
but not necessarily useful in general.
Even when existing BIPs for derivation schemes are used, their usage is not uniform across
@ -41,18 +39,18 @@ addresses differently than the one they used before.
The problem is common enough to warrant the creation of a dedicated website
([https://walletsrecovery.org/ walletsrecovery.org]) that tracks paths used by different wallets.
At the time of writing, this website has used their own format to succintly describe multiple
derivation paths. As far as author knows, it was the only publicitly used format to describe
At the time of writing, this website has used their own format to succinctly describe multiple
derivation paths. As far as author knows, it was the only publicly used format to describe
path templates before introduction of this BIP. The format was not specified anywhere beside
the main page of the website. It used <code>|</code> to denote alternative derivation indexes
(example: <code>m/|44'|49'|84'/0'/0'</code>) or whole alternative paths (<code>m/44'/0'/0'|m/44'/1'/0'</code>).
It was not declared as a template format to use for processing by software, and seems to be
an ad-hoc format only intended for illustration. In contrast to this ad-hoc format, the format
described in this BIP is intended for unambigouos parsing by software, and to be easily read by humans
described in this BIP is intended for unambiguous parsing by software, and to be easily read by humans
at the same time. Humans can visually detect the 'templated' parts of the path more easily than the use
of <code>|</code> in the template could allow. Wider range of paths can be defined in a single template more
succintly and unambiguously.
succinctly and unambiguously.
===Intended use and advantages===
@ -71,7 +69,7 @@ into using well-known paths, or convince other vendors to support their custom p
scales poorly.
A flexible approach proposed in this document is to define a standard notation for "BIP32 path templates"
that succintly describes the constraints to impose on the derivation path.
that succinctly describes the constraints to impose on the derivation path.
Wide support for these path templates will increase interoperability and flexibility of solutions,
and will allow vendors and individual developers to easily define their own custom restrictions.
@ -89,7 +87,7 @@ installation of malicious or incorrect profiles, though.
==Specification==
The format for the template was choosen to make it easy to read, convenient and visually unambigous.
The format for the template was chosen to make it easy to read, convenient and visually unambiguous.
Template starts with optional prefix <code>m/</code>, and then one or more sections delimited by the slash character (<code>/</code>).
@ -127,13 +125,13 @@ Constraints:
# To avoid ambiguity, an index range that matches a single value MUST be specified as Unit range.
# To avoid ambiguity, an index range <code>0-2147483647</code> is not allowed, and MUST be specified as Wildcard index template instead
# For Non-unit range, range_end MUST be larger than range_start.
# If there is more than one index range within the Ranged index template, range_start of the second and any subsequent range MUST be larger than the range_end of the preceeding range.
# If there is more than one index range within the Ranged index template, range_start of the second and any subsequent range MUST be larger than the range_end of the preceding range.
# To avoid ambiguity, all representations of integer values larger than 0 MUST NOT start with character <code>0</code> (no leading zeroes allowed).
# If hardened marker appears within any section in the path template, all preceding sections MUST also specify hardened matching.
# To avoid ambiguity, if a hardened marker appears within any section in the path template, all preceding sections MUST also use the same hardened marker (either <code>h</code> or <code>'</code>).
# To avoid ambiguity, trailing slashes (for example, <code>1/2/</code>) and duplicate slashes (for example, <code>0//1</code>) MUST NOT appear in the template.
It may be desireable to have fully unambiguous encoding, where for each valid path template string, there is no other valid template string that matches the exact same set of paths. This would enable someone to compare templates for equality through a simple string equality check, without any parsing.
It may be desirable to have fully unambiguous encoding, where for each valid path template string, there is no other valid template string that matches the exact same set of paths. This would enable someone to compare templates for equality through a simple string equality check, without any parsing.
To achieve this, two extra rules are needed:
@ -212,7 +210,7 @@ There is a discussion on path templating for bitcoin script descriptors at https
<code>m/{44,49,84}'/0'/0'/{0-1}/{0-50000}</code> specifies a full template that matches both external and internal chains of BIP44, BIP49 and BIP84 paths, with a constraint that the address index cannot be larger than 50000
Its representation after parsing can be (using Python syntax, ignoring full/partial distinction):
[[(2147483692, 2147483692), (2147483697, 2147483697), (2147483732, 2147483732)),
[[(2147483692, 2147483692), (2147483697, 2147483697), (2147483732, 2147483732)],
[(2147483648, 2147483648)],
[(2147483648, 2147483648)],
[(0, 1)],

405
bip-0089.mediawiki Normal file
View File

@ -0,0 +1,405 @@
<pre>
BIP: 89
Layer: Applications
Title: Chain Code Delegation
Authors: Jesse Posner <jesse@vora.io>
Jurvis Tan <jurvis@block.xyz>
Comments-Summary: No comments yet.
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0089
Status: Draft
Type: Specification
Assigned: 2025-12-03
License: BSD-3-Clause
Discussion: https://delvingbitcoin.org/t/chain-code-delegation-private-access-control-for-bitcoin-keys/1837
Requires: 32, 340, 341
</pre>
== Abstract ==
Chain Code Delegation (CCD) is a method for multi-signature wallets in which a privileged participant withholds BIP32 chain codes from one or more non-privileged participants, and supplies per-input scalar tweaks at signing time. This allows non-privileged participants to co-sign transactions without learning wallet-wide derivations, balances, or signing activity from other spending combinations. CCD defines the tweak exchange needed for verification and signing behavior when the signer does not possess a chain code.
== Motivation ==
In multisig deployments, sharing extended public keys (xpubs) or descriptors enables all participants to scan the chain and infer counterparties' activity. CCD limits that visibility by ensuring non-privileged participants only ever hold a non-extended keypair and only receive the minimum per-spend data needed to sign. The procedure keeps policy enforcement feasible for the non-privileged signer while preserving balance privacy, which is particularly useful in collaborative custody arrangements where the wallet owner wants balance privacy from their custodian.
== Terminology ==
In CCD, the chain code is the object of delegation—not signing authority. A participant who gives up their chain code delegates it to another.
* A "Delegator" is a participant who delegates their chain code to another party. They hold only a non-extended keypair and receive scalar tweaks from the delegatee when asked to sign.
* A "Delegatee" is a participant who receives and retains a delegated chain code for another participant's public key, and computes derivation tweaks for that participant.
* A "Participant" is any key holder that can co-sign for UTXOs in the wallet (including delegators and delegatees).
* A "Non-hardened derivation" is a BIP32 child derivation where index &lt; 2^31.
== Overview ==
CCD operates by having Delegatees deprive Delegators of BIP32 chain codes during setup and later conveying the aggregated scalar tweak computed as the sum of non-hardened derivation tweaks along the remaining path to the child key used by a given input or change output. A Delegator uses the tweak to compute the child keys for verification and signing without being able to derive or recognize keys for other paths.
== Specification ==
=== Key material and setup ===
* '''Delegator key:''' Each delegator generates a standard (non-extended) secp256k1 keypair and provides the public key to the counterparties. A delegator MUST NOT retain or be provided a chain code for this key.
* '''Delegated chain code:''' A designated delegatee computes and retains a BIP32 chain code bound to the delegator's public key, forming an xpub that MUST NOT be disclosed to the delegator. The delegatee MAY share this xpub with other delegatees.
* '''Other participants:''' Non-delegator participants use conventional extended keys and share the public half as appropriate for the wallet descriptor.
* '''Derivation constraints:''' The delegatee holds an extended public key for the delegator. All derivation from this extended key MUST be non-hardened, as hardened derivation requires the private key, which the delegatee does not possess.
=== Notation ===
The following conventions are used, with constants as defined for [https://www.secg.org/sec2-v2.pdf secp256k1]. We note that adapting this proposal to other elliptic curves is not straightforward and can result in an insecure scheme.
* Lowercase variables represent integers or byte arrays.
** The constant ''p'' refers to the field size, ''0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F''.
** The constant ''n'' refers to the curve order, ''0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141''.
* Uppercase variables refer to points on the curve with equation ''y<sup>2</sup> = x<sup>3</sup> + 7'' over the integers modulo ''p''.
** ''is_infinite(P)'' returns whether ''P'' is the point at infinity.
** ''x(P)'' and ''y(P)'' are integers in the range ''0..p-1'' and refer to the X and Y coordinates of a point ''P'' (assuming it is not infinity).
** The constant ''G'' refers to the base point, for which ''x(G) = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798'' and ''y(G) = 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8''.
** Addition of points refers to the usual [https://en.wikipedia.org/wiki/Elliptic_curve#The_group_law elliptic curve group operation].
** [https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication Multiplication (⋅) of an integer and a point] refers to the repeated application of the group operation.
* Functions and operations:
** ''||'' refers to byte array concatenation.
** The function ''x[i:j]'', where ''x'' is a byte array and ''i, j &ge; 0'', returns a ''(j - i)''-byte array with a copy of the ''i''-th byte (inclusive) to the ''j''-th byte (exclusive) of ''x''.
** The function ''bytes(n, x)'', where ''x'' is an integer, returns the n-byte encoding of ''x'', most significant byte first.
** The constant ''empty_bytestring'' refers to the empty byte array. It holds that ''len(empty_bytestring) = 0''.
** The function ''xbytes(P)'', where ''P'' is a point for which ''not is_infinite(P)'', returns ''bytes(32, x(P))''.
** The function ''len(x)'' where ''x'' is a byte array returns the length of the array.
** The function ''has_even_y(P)'', where ''P'' is a point for which ''not is_infinite(P)'', returns ''y(P) mod 2 == 0''.
** The function ''with_even_y(P)'', where ''P'' is a point, returns ''P'' if ''is_infinite(P)'' or ''has_even_y(P)''. Otherwise, ''with_even_y(P)'' returns ''-P''.
** The function ''cbytes(P)'', where ''P'' is a point for which ''not is_infinite(P)'', returns ''a || xbytes(P)'' where ''a'' is a byte that is ''2'' if ''has_even_y(P)'' and ''3'' otherwise.
** The function ''int(x)'', where ''x'' is a 32-byte array, returns the 256-bit unsigned integer whose most significant byte first encoding is ''x''.
** The function ''lift_x(x)'', where ''x'' is an integer in range ''0..2<sup>256</sup>-1'', returns the point ''P'' for which ''x(P) = x''<ref>
Given a candidate X coordinate ''x'' in the range ''0..p-1'', there exist either exactly two or exactly zero valid Y coordinates. If no valid Y coordinate exists, then ''x'' is not a valid X coordinate either, i.e., no point ''P'' exists for which ''x(P) = x''. The valid Y coordinates for a given candidate ''x'' are the square roots of ''c = x<sup>3</sup> + 7 mod p'' and they can be computed as ''y = &plusmn;c<sup>(p+1)/4</sup> mod p'' (see [https://en.wikipedia.org/wiki/Quadratic_residue#Prime_or_prime_power_modulus Quadratic residue]) if they exist, which can be checked by squaring and comparing with ''c''.</ref> and ''has_even_y(P)'', or fails if ''x'' is greater than ''p-1'' or no such point exists. The function ''lift_x(x)'' is equivalent to the following pseudocode:
*** Fail if ''x &gt; p-1''.
*** Let ''c = x<sup>3</sup> + 7 mod p''.
*** Let ''y' = c<sup>(p+1)/4</sup> mod p''.
*** Fail if ''c &ne; y'<sup>2</sup> mod p''.
*** Let ''y = y' '' if ''y' mod 2 = 0'', otherwise let ''y = p - y' ''.
*** Return the unique point ''P'' such that ''x(P) = x'' and ''y(P) = y''.
** The function ''cpoint(x)'', where ''x'' is a 33-byte array (compressed serialization), sets ''P = lift_x(int(x[1:33]))'' and fails if that fails. If ''x[0] = 2'' it returns ''P'' and if ''x[0] = 3'' it returns ''-P''. Otherwise, it fails.
** The function ''hash256<sub>tag</sub>(x)'' where ''tag'' is a UTF-8 encoded tag name and ''x'' is a byte array returns the 32-byte hash ''SHA256(SHA256(tag) || SHA256(tag) || x)''.
** The function ''hash512<sub>tag</sub>(x)'' where ''tag'' is a UTF-8 encoded tag name and ''x'' is a byte array returns the 64-byte hash ''SHA512(SHA512(tag) || SHA512(tag) || x)''.
* Other:
** Tuples are written by listing the elements within parentheses and separated by commas. For example, ''(2, 3, 1)'' is a tuple.
=== Tweak Calculation ===
To produce CCD tweak data, a delegatee computes a per-participant scalar that aggregates the non-hardened derivation tweaks along the remaining path. Let the extended key retained by the delegatee be P at depth d, and let the target index vector be I = (i<sub>d+1</sub>, …, i<sub>n</sub>) with each i<sub>k</sub> < 2<sup>31</sup>.
<div>
Algorithm ''ComputeBIP32Tweak(P, I)'':
* Inputs:
** ''P'': base public key at depth ''d''
** ''I = (i<sub>d+1</sub>, …, i<sub>n</sub>)'': ordered sequence of non-hardened child indices
* Let ''t = 0'' and ''E = P''.
* For each index ''i'' in ''I'' (from left to right):
** Run the BIP32 non-hardened derivation ''CKDpub'' on ''E'' with child index ''i'', yielding the child extended key ''P<sub>child</sub>'' and its scalar tweak ''δ'' (the parse<sub>256</sub>(''I<sub>L</sub>'') term from BIP32).
** Let ''t = (t + δ) mod n''.
** Let ''E = P<sub>child</sub>''.
* If ''I'' is empty, let ''P = P''; otherwise let ''P = P<sub>child</sub>'' from the final iteration.
* Return ''(t, P)''.
</div>
Any attempt to apply a hardened derivation (index ≥ 2<sup>31</sup>) MUST fail. Delegatees MAY discard P after extracting t if it is not otherwise required.
=== Delegation Bundle ===
CCD requires the delegatee to provide per-participant tweaks for inputs and (optionally) change outputs. Tweaks for change outputs are only required if a delegator wants to be able to compute the amount of bitcoin they are spending.
A delegatee MUST provide each delegator with, for every signing context, a collection of tuples (P<sub>i</sub>, t<sub>i</sub>) where P<sub>i</sub> is the participant's base public key disclosed to the delegator and t<sub>i</sub> is the aggregated tweak returned by ''ComputeBIP32Tweak''. The scalar t<sub>i</sub> MUST be encoded as a 32-byte big-endian integer.
The transport that carries this bundle is out of scope for this proposal; implementers MAY use PSBT proprietary keys, RPC payloads, or bespoke messages as long as the delegator can authenticate the origin of the data. Delegatees SHOULD attach the witness script (or sufficient script template information) built with the tweaked keys when the delegator is expected to verify the input or enforce spending policy on change outputs.
Delegators use the supplied CCD tweak bundle during verification (see ''Delegator input and change verification'') and signature generation (see ''DelegatorSign''). The message to be signed is provided separately as part of the standard signing protocol and is not part of the CCD-specific bundle.
=== Signing Modes ===
This BIP supports two modes:
* '''Nonblinded.''' The delegator receives the tweak for the child public key and the message. The delegator learns only about the specific child keys and transactions it signs for; it does not learn the wider address space.
* '''Blinded.''' The delegator receives only a blinded challenge and parity bits. The delegator learns nothing about the message or child key for which it produces a signature.
Both modes produce valid BIP340 signatures.
====Non-Blinded Signing====
For non-blinded signing, the delegator can produce signatures as usual using the tweaked key.
=====Delegator input and change verification (Optional)=====
A delegator MAY validate the data it receives before producing signatures.
For example, input verification reassures the delegator that every tweaked key they are asked to sign for corresponds to a wallet input they recognise. Change verification lets them establish the net outflow and enforce spending policy.
Both checks rely on the same delegated tweak bundle described above.
=====Input verification=====
For each input, the delegatee SHOULD disclose the descriptor template, the untweaked participant keys, the input witness script, and the per-participant tweaks. The delegator then applies the following procedure.
<div>
Algorithm ''InputVerification(D, W, T)'':
* Inputs:
** ''D'': wallet policy or descriptor template expressed in terms of the untweaked participant keys ''P<sub>i</sub>''
** ''W'': witness script disclosed for the input under review
** ''T'': mapping from each ''P<sub>i</sub>'' to a 32-byte big-endian tweak scalar ''t<sub>i</sub>''
* For each participant key ''P<sub>i</sub>'' referenced in ''D'':
** Retrieve ''t<sub>i</sub>'' from ''T''; fail if the entry is missing or malformed.
** If the verifier controls the corresponding private key ''d<sub>i</sub>'', let ''d<sub>i</sub> = (d<sub>i</sub> + t<sub>i</sub>) mod n'' and ''P<sub>i</sub> = d<sub>i</sub> · G''; otherwise let ''P<sub>i</sub> = P<sub>i</sub> + t<sub>i</sub> · G''.
* Let ''D'' be the descriptor formed by substituting every occurrence of ''P<sub>i</sub>'' in ''D'' with ''P<sub>i</sub>''.
* Derive the witness script ''W'' from ''D''.
* Return <code>true</code> if ''W = W'', otherwise <code>false</code>.
</div>
Successful verification of an input confirms that the delegator is signing for a script that belongs to the wallet and that the aggregate tweak values align with the expected policy.
=====Change-output verification=====
When change outputs are disclosed, the delegator can perform an analogous check to ensure the destination script matches their policy template and to calculate outflows. Let D be the descriptor expressed in untweaked keys, W the provided witness script, and T the tweak mapping:
<div>
Algorithm ''ChangeOutputVerification(D, W, T)'':
* Inputs:
** ''D'': wallet policy or descriptor template expressed in terms of the untweaked participant keys ''P<sub>i</sub>''
** ''W'': witness script disclosed for the change output
** ''T'': mapping from each ''P<sub>i</sub>'' to a 32-byte big-endian tweak scalar ''t<sub>i</sub>''
* For each participant key ''P<sub>i</sub>'' referenced in ''T'':
** Retrieve ''t<sub>i</sub>'' from ''T''; fail if the entry is missing or malformed.
** If the verifier controls the corresponding private key ''d<sub>i</sub>'', let ''d<sub>i</sub> = (d<sub>i</sub> + t<sub>i</sub>) mod n'' and ''P<sub>i</sub> = d<sub>i</sub> · G''; otherwise let ''P<sub>i</sub> = P<sub>i</sub> + t<sub>i</sub> · G''.
* Let ''D'' be the descriptor formed by substituting every occurrence of ''P<sub>i</sub>'' in ''D'' with ''P<sub>i</sub>''.
* Derive the witness script ''W'' from ''D''.
* Return <code>true</code> if ''W = W'', otherwise <code>false</code>.
</div>
Successful verification ensures the change output commits to the tweaked participant keys implied by the CCD tweaks, preserving the intended policy.
The delegator may perform additional application-specific verification on the transaction (e.g., recipient addresses, amounts, compliance checks) using the message ''m''. In the concurrently secure blinded mode, such policies can be enforced via zero-knowledge proofs that encode predicates about ''m''. Specification of such policies is outside the scope of this BIP.
=====Delegator Signing=====
A delegator that holds only its base secret key <code>x</code> and public key <code>P</code> uses the delegated tweak bundle to derive per-input signing keys. The delegator MAY first call ''InputVerification'' and ''ChangeOutputVerification'' on any input and change output that provides a tweak in order to confirm outflow or policy requirements before signing.
<div>
Algorithm ''DelegatorSign(t, x, m)'':
* Inputs:
** ''t'': aggregated tweak for the signing context (scalar mod ''n'')
** ''x'': delegator base secret key
** ''m'': message to be signed (for example, a transaction digest under the desired SIGHASH policy)
* Let ''x = (x + t) mod n''.
* Use secret key ''x'' to produce the required signature ''σ'' under the indicated policy.
* Return ''σ''.
</div>
The delegatee is responsible for inserting ''σ'' into the surrounding protocol (e.g., a PSBT, transaction witness, or adaptor signature exchange).
====Blinded Signing====
The delegator learns neither the message, the challenge, or the public key used in the BIP340 signature, only a blinded challenge e'.
This blindsigning protocol specifies how a delegator can produce a blind partial Schnorr signature that a delegatee can unblind into a standard [https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki BIP340] signature under a possibly tweaked Xonly public key. The notation, algorithmic patterns, and testvector style are adapted from [BIP327 (MuSig2)] and from the [https://github.com/siv2r/bip-frost-signing FROST Signing BIP]. The design follows the “plain” blind Schnorr flow described in Concurrently Secure Blind Schnorr Signatures ([https://eprint.iacr.org/2022/1676 ePrint 2022/1676]), but without the concurrency hardening from that work.
The output signature is a BIP340 Schnorr signature valid under an Xonly key obtained by applying a sequence of plain (e.g. BIP32) and Xonly (e.g. Tapscript) tweaks to the signers plain public key. Consequently the protocol is compatible with [https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki BIP341]. The delegator learns neither the message, the challenge, or the public key used in the BIP340 signature, only a blinded challenge e'.
The plain protocol here is '''not''' concurrently secure. A signer '''MUST NOT''' run multiple blind signing sessions in parallel or interleave state across sessions. A signer '''MUST''' refuse any new blindnonce requests while a previous blindsignature request is outstanding, or '''MUST''' irrevocably discard (and never reuse) any inflight blind nonce commitments that have not resulted in a signature, before accepting new ones.
To obtain concurrency security as in ([https://eprint.iacr.org/2022/1676 ePrint 2022/1676]), the delegatee first sends an encryption of (m, a, b) before the signer commits to the blind nonce; later, the delegatee includes a zeroknowledge proof binding the produced challenge to that encrypted tuple. That proof can additionally encode policy predicates about m (spend limits, velocity controls, etc.). A complete specification of this variant is outside the scope of this BIP.
The following sections fully specify the non-concurrent blind signing protocol.
===== Overview =====
* '''Round 1 (blind nonce).''' The delegator runs ''BlindNonceGen'' to produce ''blindsecnonce'' and ''blindpubnonce'' and sends ''blindpubnonce'' to the delegatee.
* '''Round 2 (challenge).''' The delegatee runs ''BlindChallengeGen'' using the message ''m'', ''blindpubnonce'', the base public key ''pk'', and a list of ordinary and X-only tweaks, to produce a ''session context'' (kept locally for unblinding), a ''blindchallenge'', and two booleans ''pk_parity'' and ''nonce_parity''. The delegatee sends ''blindchallenge'', ''pk_parity'', and ''nonce_parity'' to the signer.
* '''Round 3 (blind signature).''' The delegator runs ''BlindSign'' with ''sk'', ''blindchallenge'', ''blindsecnonce'', ''pk_parity'', and ''nonce_parity'' and returns ''blindsignature''. The delegatee completes by calling ''UnblindSignature'' with the stored session context and ''blindsignature'' to obtain the final BIP340 signature ''sig''.
''BlindSign'' '''MUST NOT''' be executed twice with the same ''blindsecnonce''. As a defense, implementations '''SHOULD''' overwrite the first 64 bytes of ''blindsecnonce'' with zeros after they have been read by ''BlindSign''.
=====Key Tweaking=====
======Tweak Context======
The Tweak Context is a data structure consisting of the following elements:
* The point ''Q'' representing the potentially tweaked public key: an elliptic curve point
* The accumulated tweak ''tacc'': an integer with ''0 &le; tacc < n''
* The value ''gacc'' : 1 or -1 mod n
We write "Let ''(Q, gacc, tacc) = tweak_ctx''" to assign names to the elements of a Tweak Context.
<div>
Algorithm ''TweakCtxInit(pk)'':
* Input:
** The base public key pk: a 33-byte array
* Let ''Q = cpoint(pk)''
* Fail if ''is_infinite(Q)''
* Let ''gacc = 1''
* Let ''tacc = 0''
* Return ''tweak_ctx = (Q, gacc, tacc)''
</div>
<div>
Algorithm ''ApplyTweak(tweak_ctx, tweak, is_xonly_t)'':
* Inputs:
** The ''tweak_ctx'': a [[#tweak-context|Tweak Context]] data structure
** The ''tweak'': a 32-byte array
** The tweak mode ''is_xonly_t'': a boolean
* Let ''(Q, gacc, tacc) = tweak_ctx''
* If ''is_xonly_t'' and ''not has_even_y(Q)'':
** Let ''g = -1 mod n''
* Else:
** Let ''g = 1''
* Let ''t = int(tweak)''; fail if ''t &ge; n''
* Let ''Q' = g⋅Q + t⋅G''
** Fail if ''is_infinite(Q')''
* Let ''gacc' = g⋅gacc mod n''
* Let ''tacc' = t + g⋅tacc mod n''
* Return ''tweak_ctx' = (Q', gacc', tacc')''
</div>
=====Blind Nonce Generation=====
<div>
Algorithm ''BlindNonceGen(sk, pk, aggpk, m, extra_in)'':
* Inputs:
** The base secret signing key ''sk'': a 32-byte array (optional argument)
** The base public key ''pk'': a 33-byte array (optional argument)
** The auxiliary input ''extra_in'': a byte array with ''0 &le; len(extra_in) &le; 2<sup>32</sup>-1'' (optional argument)
* Let ''rand' '' be a 32-byte array freshly drawn uniformly at random
* If the optional argument ''sk'' is present:
** Let ''rand'' be the byte-wise xor of ''sk'' and ''hash256<sub>CCD/aux</sub>(rand')''<ref>The random data is hashed (with a unique tag) as a precaution against situations where the randomness may be correlated with the secret signing key itself. It is xored with the secret key (rather than combined with it in a hash) to reduce the number of operations exposed to the actual secret key.</ref>
* Else:
** Let ''rand = rand' ''
* If the optional argument ''extra_in'' is not present:
** Let ''extra_in = empty_bytestring''
* Let ''k' = int(hash256<sub>CCD/blindnonce</sub>(rand || bytes(1, len(pk)) || pk || bytes(4, len(extra_in)) || extra_in )) mod n''
* Fail if ''k' = 0''
* Let ''R' = k'⋅G''
* Let ''blindpubnonce = cbytes(R')''
* Let ''blindsecnonce = bytes(32, k' || pk)''<ref name="blindsecnonce">The algorithms as specified here assume that the ''blindsecnonce'' is stored as a 65-byte array using the serialization ''blindsecnonce = bytes(32, k') || pk''. The same format is used in the reference implementation and in the test vectors. However, since the ''blindsecnonce'' is not meant to be sent over the wire, compatibility between implementations is not a concern, and this method of storing the ''blindsecnonce'' is merely a suggestion.<br />
The ''blindsecnonce'' is effectively a local data structure of the signer which comprises the value double ''(k', pk)'', and implementations may choose any suitable method to carry it from ''BlindNonceGen'' (first communication round) to ''BlindSign'' (third communication round). In particular, implementations may choose to hide the ''blindsecnonce'' in internal state without exposing it in an API explicitly, e.g., in an effort to prevent callers from reusing a ''blindsecnonce'' accidentally.</ref>
* Return ''(secnonce, pubnonce)''
</div>
=====Session Context=====
The Session Context is a data structure consisting of the following elements:
* The base public key ''pk'': a 33-byte array
* The blind factor ''blindfactor'': a 32-byte array
* The challenge hash ''challenge'': a 32-byte array
* The public nonce ''pubnonce'': a 33-byte array
* The number ''v'' of tweaks with ''0 &le; v < 2^32''
* The tweaks ''tweak<sub>1..v</sub>'': ''v'' 32-byte arrays
* The tweak modes ''is_xonly_t<sub>1..v</sub>'' : ''v'' booleans
We write "Let ''(pk, blindfactor, challenge, pubnonce, v, tweak<sub>1..v</sub>, is_xonly_t<sub>1..v</sub>) = session_ctx''" to assign names to the elements of a Session Context.
<div>
Algorithm ''GetSessionValues(session_ctx)'':
* Let ''(pk, blindfactor, challenge, pubnonce, v, tweak<sub>1..v</sub>, is_xonly_t<sub>1..v</sub>) = session_ctx''
* Let ''tweak_ctx<sub>0</sub> = TweakCtxInit(pk)''; fail if that fails
* For ''i = 1 .. v'':
** Let ''tweak_ctx<sub>i</sub> = ApplyTweak(tweak_ctx<sub>i-1</sub>, tweak<sub>i</sub>, is_xonly_t<sub>i</sub>)''; fail if that fails
* Let ''(Q, gacc, tacc) = tweak_ctx<sub>v</sub>''
* Let ''a = int(blindfactor)''; fail if ''a ≥ n''
* Let ''b = int(blindfactor)''; fail if ''b ≥ n''
* Let ''e = int(challenge)''; fail if ''e ≥ n''
* Let ''R = cpoint(pubnonce)''; fail if that fails
* Return ''(Q, gacc, tacc, a, e, R)''
</div>
=====Blind Challenge Generation=====
<div>
Algorithm ''BlindChallengeGen(m, blindpubnonce, pk, tweak<sub>1..v</sub>, is_xonly<sub>1..v</sub>, extra_in)'':
* Inputs:
** The message ''m'': a byte array
** The blind public nonce ''blindpubnonce'': a 33-byte array
** The base public key ''pk'': a 33-byte array
** The tweaks ''tweak<sub>1..v</sub>'': ''v'' 32-byte arrays
** The tweak modes ''is_xonly<sub>1..v</sub>'': ''v'' booleans
** The auxiliary input ''extra_in'': a byte array with ''0 &le; len(extra_in) &le; 2<sup>32</sup>-1'' (optional argument)
* If ''extra_in'' is not present:
** Let ''extra_in = empty_bytestring''
* Let ''(Q, gacc, tacc) = TweakCtxInit(pk)''
* For ''i = 1 .. v'':
** Let ''(Q, gacc, tacc) = ApplyTweak((Q, gacc, tacc), tweak<sub>i</sub>, is_xonly<sub>i</sub>)''; fail if that fails
* Let ''cpk = cbytes(Q)''
* Draw 32 random bytes ''rand''
* Let ''z = hash512<sub>CCD/blindfactor</sub>(rand || bytes(1, len(cpk)) || cpk || bytes(1, len(blindpubnonce)) || blindpubnonce || bytes(8, len(m)) || m || bytes(4, len(extra_in)) || extra_in)''
* Let ''a' = int(z[0:32]) mod n''; fail if ''a' = 0''
* Let ''b' = int(z[32:64]) mod n''; fail if ''b' = 0''
* Let ''g = 1'' if ''has_even_y(Q)'', else ''g = 1 mod n''
* Let ''pk_parity = (g⋅gacc mod n == 1)''
* Let ''X' = cpoint(pk)''; let ''X = X' '' if ''pk_parity'' else ''X' ''
* Let ''R' = cpoint(blindpubnonce)''
* Let ''R = R' + a'⋅G + b'⋅X''; fail if ''is_infinite(R)''
* Let ''nonce_parity = has_even_y(R)''
* If ''nonce_parity'':
** Let ''a = a' '', ''b = b' ''
* Else:
** Let ''a = n a' '', ''b = n b' ''
* Let ''e = int(hash<sub>BIP0340/challenge</sub>(xbytes(R) || xbytes(Q) || m)) mod n''
* Let ''e' = (e + b) mod n''
* Let ''session_ctx = (pk, bytes(32, a), bytes(32, e), cbytes(R), tweak<sub>1..v</sub>, is_xonly<sub>1..v</sub>)''
* Return ''(session_ctx, bytes(32, e'), pk_parity, nonce_parity)''
</div>
=====Blind Signing=====
<div>
Algorithm ''BlindSign(sk, blindchallenge, blindsecnonce, pk_parity, nonce_parity)'':
* Inputs:
** The secret key ''sk'': a 32-byte array
** The blind challenge ''blindchallenge'': a 32-byte array ''e' ''
** The secret nonce ''blindsecnonce'': a byte array whose first 32 bytes are ''k'' (remaining bytes are implementation-defined)
** ''pk_parity'': boolean (from ''BlindChallengeGen'')
** ''nonce_parity'': boolean (from ''BlindChallengeGen'')
* Let ''d' = int(sk)''; fail if ''d' = 0'' or ''d' ≥ n''
* Let ''P = d'⋅G''; fail if ''is_infinite(P)''
* Let ''d = d' '' if ''pk_parity'' else ''n d' ''
* Let ''e' = int(blindchallenge)''; fail if ''e' ≥ n''
* Let ''k' = int(blindsecnonce[0:32])''; fail if ''k' = 0'' or ''k' ≥ n''
* Let ''k = k' '' if ''nonce_parity'' else ''n k' ''
* Overwrite ''blindsecnonce[0:64]'' with 64 zero bytes<ref> This helps prevent accidental nonce reuse. A zeroed ''blindsecnonce'' MUST cause subsequent ''BlindSign'' calls to fail.</ref>
* Let ''R' = k'⋅G''; fail if ''is_infinite(R')''<ref> This check holds except with negligible probability.</ref>
* Let ''s' = (k + e'⋅d) mod n''
* If ''VerifyBlindSignature(cbytes(P), cbytes(R'), blindchallenge, bytes(32, s'), pk_parity, nonce_parity)'' returns failure, abort
* Return ''blindsignature = bytes(32, s')''
</div>
<div>
Algorithm ''VerifyBlindSignature(pk, blindpubnonce, blindchallenge, blindsignature, pk_parity, nonce_parity)'':
* Inputs:
** ''pk'': a 33-byte compressed public key
** ''blindpubnonce'': the signers 33-byte ''R' = k'⋅G''
** ''blindchallenge'': 32-byte ''e' ''
** ''blindsignature'': 32-byte ''s' ''
** ''pk_parity, nonce_parity'': booleans
* Let ''P' ' = cpoint(pk)''; let ''P = P' '' if ''pk_parity'' else ''P' '' ; fail if ''is_infinite(P)''
* Let ''R' ' = cpoint(blindpubnonce)''; let ''R = R' '' if ''nonce_parity'' else ''R' ''
* Let ''e' = int(blindchallenge)'', ''s' = int(blindsignature)''
* Return success iff ''s'⋅G == R + e'⋅P''
</div>
=====Unblinding=====
<div>
Algorithm ''UnblindSignature(session_ctx, blindsignature)'':
* Inputs:
** ''session_ctx'': as defined above
** ''blindsignature'': the 32-byte ''s' '' returned by the signer
* Let ''(Q, gacc, tacc, a, e, R) = GetSessionValues(session_ctx)''; fail if that fails
* Let ''g = 1'' if ''has_even_y(Q)'', else ''g = 1 mod n''
* Let ''s' = int(blindsignature)''; fail if ''s' ≥ n''
* Let ''s = (s' + a + e⋅g⋅tacc) mod n''
* Return the BIP340 signature ''sig = xbytes(R) || bytes(32, s)''
</div>
== Security Considerations ==
* Exposure of any delegated tweak scalar <code>t</code> enables signing only for the specific child key(s) that scalar was derived for, and is typically short-lived if disclosed immediately before spending.
* Delegatees MUST ensure every delegated path remains non-hardened and that ''ComputeBIP32Tweak'' yields the correct tweak <code>t</code>; incorrect scalars could render the delegator incapable of producing a signature.
* Delegators MUST verify change outputs when tweak data is provided (for example via ''ChangeOutputVerification'') to avoid authorizing unexpected scripts.
* Reusing the same k' (first 32 bytes in blindsecnonce) across two BlindSign calls allows recovery of the base secret key.
* When using blinded signing, opening multiple sessions concurrently against the same signer can allow an attacker to learn the base secret key. If concurrency is required, use the concurrently secure variant (encryption + ZK) instead (not specified in this BIP).
== Test Vectors ==
A [[bip-0089/vectors|collection of JSON test vectors]] are provided, along with a [[bip-0089/reference.py|python reference implementation]].
It uses a vendored copy of the [https://github.com/secp256k1lab/secp256k1lab/ secp256k1lab] library
(commit [https://github.com/secp256k1lab/secp256k1lab/commit/a265da139aea27386085a2a8760f8698e1bda64e
a265da139aea27386085a2a8760f8698e1bda64e]).
You may also find example code of CCD in action [https://github.com/jurvis/chaincode-delegation here].
== Changelog ==
* '''0.1.3''' (2026-02-02): Upgrade secp256k1lab and add license file; fix type checker and linter issues; clarify Delegator/Delegatee terminology, derivation constraints, signing modes, and verification scope.
* '''0.1.2''' (2025-12-03): Updated to reflect BIP number assignment.
* '''0.1.1''' (2025-11-30): Fix acknowledgments spelling, BIP3 formatting, and use "Chain Code" with a space throughout.
* '''0.1.0''' (2025-10-14): Publication of draft BIP
== Acknowledgements ==
* Arik Sosman and Wilmer Paulino for the initial discussions and validation of this idea.
* Sanket Kajalkar, Jordan Mecom, Gregory Sanders, ZmnSCPxj, Yuval Kogman, and John Cantrell for code and design review.
== Copyright ==
This BIP is licensed under the BSD 3-Clause license.

170
bip-0089/bip32.py Normal file
View File

@ -0,0 +1,170 @@
"""BIP32 helpers for the CCD reference implementation."""
from __future__ import annotations
from dataclasses import dataclass
import hmac
from hashlib import new as hashlib_new, sha256, sha512
from typing import List, Tuple, Mapping, Sequence
from secp256k1lab.secp256k1 import G, GE, Scalar
CURVE_N = Scalar.SIZE
def int_to_bytes(value: int, length: int) -> bytes:
return value.to_bytes(length, "big")
def bytes_to_int(data: bytes) -> int:
return int.from_bytes(data, "big")
def compress_point(point: GE) -> bytes:
if point.infinity:
raise ValueError("Cannot compress point at infinity")
return point.to_bytes_compressed()
def decompress_point(data: bytes) -> GE:
return GE.from_bytes_compressed(data)
def apply_tweak_to_public(base_public: bytes, tweak: int) -> bytes:
base_point = GE.from_bytes_compressed(base_public)
tweaked_point = base_point + (tweak % CURVE_N) * G
if tweaked_point.infinity:
raise ValueError("Tweaked key is at infinity")
return tweaked_point.to_bytes_compressed()
def apply_tweak_to_secret(base_secret: int, tweak: int) -> int:
if not (0 < base_secret < CURVE_N):
raise ValueError("Invalid base secret scalar")
return (base_secret + tweak) % CURVE_N
def decode_path(path_elements: Sequence[object]) -> List[int]:
result: List[int] = []
for element in path_elements:
if isinstance(element, int):
index = element
else:
element_str = str(element)
hardened = element_str.endswith("'") or element_str.endswith("h")
suffix = element_str[:-1] if hardened else element_str
if not suffix:
raise AssertionError("invalid derivation index")
index = int(suffix)
if hardened:
index |= HARDENED_INDEX
result.append(index)
return result
HARDENED_INDEX = 0x80000000
def _hash160(data: bytes) -> bytes:
return hashlib_new("ripemd160", sha256(data).digest()).digest()
@dataclass
class ExtendedPublicKey:
point: GE
chain_code: bytes
depth: int = 0
parent_fingerprint: bytes = b"\x00\x00\x00\x00"
child_number: int = 0
def fingerprint(self) -> bytes:
return _hash160(compress_point(self.point))[:4]
def derive_child(self, index: int) -> Tuple[int, "ExtendedPublicKey"]:
tweak, child_point, child_chain = derive_public_child(self.point, self.chain_code, index)
child = ExtendedPublicKey(
point=child_point,
chain_code=child_chain,
depth=self.depth + 1,
parent_fingerprint=self.fingerprint(),
child_number=index,
)
return tweak, child
def derive_public_child(parent_point: GE, chain_code: bytes, index: int) -> Tuple[int, GE, bytes]:
if index >= HARDENED_INDEX:
raise ValueError("Hardened derivations are not supported for delegates")
data = compress_point(parent_point) + int_to_bytes(index, 4)
il_ir = hmac.new(chain_code, data, sha512).digest()
il, ir = il_ir[:32], il_ir[32:]
tweak = bytes_to_int(il)
if tweak >= CURVE_N:
raise ValueError("Invalid tweak derived (>= curve order)")
child_point_bytes = apply_tweak_to_public(compress_point(parent_point), tweak)
child_point = decompress_point(child_point_bytes)
return tweak, child_point, ir
def parse_path(path: str) -> List[int]:
if not path or path in {"m", "M"}:
return []
if path.startswith(("m/", "M/")):
path = path[2:]
components: List[int] = []
for element in path.split("/"):
if element.endswith("'") or element.endswith("h"):
raise ValueError("Hardened steps are not allowed in CCD derivations")
index = int(element)
if index < 0 or index >= HARDENED_INDEX:
raise ValueError("Derivation index out of range")
components.append(index)
return components
def parse_extended_public_key(data: Mapping[str, object]) -> ExtendedPublicKey:
compressed_hex = data.get("compressed")
if not isinstance(compressed_hex, str):
raise ValueError("Compressed must be a string")
chain_code_hex = data.get("chain_code")
if not isinstance(chain_code_hex, str):
raise ValueError("Chain code must be a string")
depth = data.get("depth")
if not isinstance(depth, int):
raise ValueError("Depth must be an integer")
child_number = data.get("child_number", 0)
if not isinstance(child_number, int):
raise ValueError("Child number must be an integer")
parent_fp_hex = data.get("parent_fingerprint", "00000000")
compressed = bytes.fromhex(compressed_hex)
chain_code = bytes.fromhex(chain_code_hex)
parent_fp = bytes.fromhex(str(parent_fp_hex))
return build_extended_public_key(
compressed,
chain_code,
depth=depth,
parent_fingerprint=parent_fp,
child_number=child_number,
)
def build_extended_public_key(
compressed: bytes,
chain_code: bytes,
*,
depth: int = 0,
parent_fingerprint: bytes = b"\x00\x00\x00\x00",
child_number: int = 0,
) -> ExtendedPublicKey:
if len(chain_code) != 32:
raise ValueError("Chain code must be 32 bytes")
point = decompress_point(compressed)
return ExtendedPublicKey(
point=point,
chain_code=chain_code,
depth=depth,
parent_fingerprint=parent_fingerprint,
child_number=child_number,
)

42
bip-0089/descriptor.py Normal file
View File

@ -0,0 +1,42 @@
"""Helpers for working with minimal SortedMulti descriptor templates."""
from __future__ import annotations
from dataclasses import dataclass
from typing import Sequence
@dataclass(frozen=True)
class SortedMultiDescriptorTemplate:
"""Minimal representation of a ``wsh(sortedmulti(m, ...))`` descriptor."""
threshold: int
def witness_script(self, tweaked_keys: Sequence[bytes]) -> bytes:
"""Return the witness script for ``wsh(sortedmulti(threshold, tweaked_keys))``."""
if not tweaked_keys:
raise ValueError("sortedmulti requires at least one key")
if not 1 <= self.threshold <= len(tweaked_keys):
raise ValueError("threshold must satisfy 1 <= m <= n")
for key in tweaked_keys:
if len(key) != 33:
raise ValueError("sortedmulti keys must be 33-byte compressed pubkeys")
sorted_keys = sorted(tweaked_keys)
script = bytearray()
script.append(_op_n(self.threshold))
for key in sorted_keys:
script.append(len(key))
script.extend(key)
script.append(_op_n(len(sorted_keys)))
script.append(0xAE) # OP_CHECKMULTISIG
return bytes(script)
def _op_n(value: int) -> int:
if not 0 <= value <= 16:
raise ValueError("OP_N value out of range")
if value == 0:
return 0x00
return 0x50 + value

784
bip-0089/reference.py Normal file
View File

@ -0,0 +1,784 @@
# BIPXXX reference implementation
#
# WARNING: This implementation is for demonstration purposes only and _not_ to
# be used in production environments. The code is vulnerable to timing attacks,
# for example.
from typing import Dict, Mapping, Optional, Sequence, Tuple, NewType, NamedTuple, List, Callable, Any, cast
import hashlib
import json
import os
import secrets
import sys
from bip32 import (
CURVE_N,
ExtendedPublicKey,
apply_tweak_to_public,
apply_tweak_to_secret,
int_to_bytes,
parse_extended_public_key,
compress_point,
decode_path,
)
from descriptor import SortedMultiDescriptorTemplate
from secp256k1lab.bip340 import schnorr_sign, schnorr_verify
from secp256k1lab.keys import pubkey_gen_plain
from secp256k1lab.secp256k1 import G, GE, Scalar
HashFunc = Callable[[bytes], Any]
PlainPk = NewType('PlainPk', bytes)
XonlyPk = NewType('XonlyPk', bytes)
def xbytes(P: GE) -> bytes:
return P.to_bytes_xonly()
def cbytes(P: GE) -> bytes:
return P.to_bytes_compressed()
def cpoint(x: bytes) -> GE:
return GE.from_bytes_compressed(x)
TweakContext = NamedTuple('TweakContext', [('Q', GE),
('gacc', Scalar),
('tacc', Scalar)])
def tweak_ctx_init(pk: PlainPk) -> TweakContext:
Q = cpoint(pk)
if Q.infinity:
raise ValueError('The public key cannot be infinity.')
gacc = Scalar(1)
tacc = Scalar(0)
return TweakContext(Q, gacc, tacc)
def apply_tweak(tweak_ctx: TweakContext, tweak: bytes, is_xonly: bool) -> TweakContext:
if len(tweak) != 32:
raise ValueError('The tweak must be a 32-byte array.')
Q, gacc, tacc = tweak_ctx
if is_xonly and not Q.has_even_y():
g = Scalar(-1)
else:
g = Scalar(1)
try:
t = Scalar.from_bytes_checked(tweak)
except ValueError:
raise ValueError('The tweak must be less than n.')
Q_ = g * Q + t * G
if Q_.infinity:
raise ValueError('The result of tweaking cannot be infinity.')
gacc_ = g * gacc
tacc_ = t + g * tacc
return TweakContext(Q_, gacc_, tacc_)
# Return the plain public key corresponding to a given secret key
def individual_pk(seckey: bytes) -> PlainPk:
return PlainPk(pubkey_gen_plain(seckey))
def bytes_xor(a: bytes, b: bytes) -> bytes:
return bytes(x ^ y for x, y in zip(a, b))
# This implementation can be sped up by storing the midstate after hashing
# tag_hash instead of rehashing it all the time.
def tagged_hash(tag: str, msg: bytes, hash_func: HashFunc = hashlib.sha256) -> bytes:
tag_hash = hash_func(tag.encode()).digest()
return hash_func(tag_hash + tag_hash + msg).digest()
def nonce_hash(rand: bytes, pk: PlainPk, extra_in: bytes) -> bytes:
buf = b''
buf += rand
buf += len(pk).to_bytes(1, 'big')
buf += pk
buf += len(extra_in).to_bytes(4, 'big')
buf += extra_in
return tagged_hash('CCD/blindnonce', buf)
def blind_nonce_gen_internal(rand_: bytes, sk: Optional[bytes], pk: Optional[PlainPk], extra_in: Optional[bytes]) -> Tuple[bytearray, bytes]:
if sk is not None:
rand = bytes_xor(sk, tagged_hash('CCD/aux', rand_))
else:
rand = rand_
if pk is None:
pk = PlainPk(b'')
if extra_in is None:
extra_in = b''
k = Scalar.from_bytes_wrapping(nonce_hash(rand, pk, extra_in))
# k == 0 cannot occur except with negligible probability.
assert k != 0
R = k * G
assert R is not None
blindpubnonce = cbytes(R)
blindsecnonce = bytearray(k.to_bytes() + pk)
return blindsecnonce, blindpubnonce
def blind_nonce_gen(sk: Optional[bytes], pk: Optional[PlainPk], extra_in: Optional[bytes]) -> Tuple[bytearray, bytes]:
if sk is not None and len(sk) != 32:
raise ValueError('The optional byte array sk must have length 32.')
rand_ = secrets.token_bytes(32)
return blind_nonce_gen_internal(rand_, sk, pk, extra_in)
SessionContext = NamedTuple('SessionContext', [('pk', PlainPk),
('blindfactor', bytes),
('challenge', bytes),
('pubnonce', bytes),
('tweaks', List[bytes]),
('is_xonly', List[bool])])
def blind_factor_hash(rand: bytes, cpk: PlainPk, blindpubnonce: bytes, msg: bytes, extra_in: bytes) -> bytes:
buf = b''
buf += rand
buf += len(cpk).to_bytes(1, 'big')
buf += cpk
buf += len(blindpubnonce).to_bytes(1, 'big')
buf += blindpubnonce
buf += len(msg).to_bytes(8, 'big')
buf += msg
buf += len(extra_in).to_bytes(4, 'big')
buf += extra_in
return tagged_hash('CCD/blindfactor', buf, hashlib.sha512)
def blind_challenge_gen_internal(rand: bytes, msg: bytes, blindpubnonce: bytes, pk: PlainPk, tweaks: List[bytes], is_xonly: List[bool], extra_in: Optional[bytes]) -> Tuple[SessionContext, bytes, bool, bool]:
if extra_in is None:
extra_in = b''
Q, gacc, tacc = pubkey_and_tweak(pk, tweaks, is_xonly)
cpk = PlainPk(cbytes(Q))
k = blind_factor_hash(rand, cpk, blindpubnonce, msg, extra_in)
a_ = Scalar.from_bytes_wrapping(k[0:32])
assert a_ != 0
b_ = Scalar.from_bytes_wrapping(k[32:64])
assert b_ != 0
g = Scalar(1) if Q.has_even_y() else Scalar(-1)
pk_parity = g * gacc == 1
X_ = cpoint(pk)
X = X_ if pk_parity else -X_
R_ = cpoint(blindpubnonce)
R = R_ + (a_ * G) + (b_ * X)
if R is None:
raise ValueError('The result of nonce blinding cannot be infinity.')
nonce_parity = R.has_even_y()
if not nonce_parity:
a = -a_
b = -b_
else:
a = a_
b = b_
e = Scalar.from_bytes_wrapping(tagged_hash("BIP0340/challenge", xbytes(R) + xbytes(Q) + msg))
e_ = e + b
session_ctx = SessionContext(pk, a.to_bytes(), e.to_bytes(), cbytes(R), tweaks, is_xonly)
return session_ctx, e_.to_bytes(), pk_parity, nonce_parity
def blind_challenge_gen(msg: bytes, blindpubnonce: bytes, pk: PlainPk, tweaks: List[bytes], is_xonly: List[bool], extra_in: Optional[bytes]) -> Tuple[SessionContext, bytes, bool, bool]:
rand = secrets.token_bytes(32)
return blind_challenge_gen_internal(rand, msg, blindpubnonce, pk, tweaks, is_xonly, extra_in)
def blind_sign(sk: bytes, blindchallenge: bytes, blindsecnonce: bytearray, pk_parity: bool, nonce_parity: bool) -> bytes:
try:
d_ = Scalar.from_bytes_checked(sk)
if d_ == 0:
raise ValueError('The secret key cannot be zero.')
except ValueError:
raise ValueError('The secret key is out of range.')
P = d_ * G
if P.infinity:
raise ValueError('The public key cannot be infinity.')
d = d_ if pk_parity else -d_
e_ = Scalar.from_bytes_checked(blindchallenge)
k_ = Scalar.from_bytes_checked(bytes(blindsecnonce[0:32]))
k = k_ if nonce_parity else -k_
# Overwrite the secnonce argument with zeros such that subsequent calls of
# sign with the same secnonce raise a ValueError.
blindsecnonce[:64] = bytearray(b'\x00'*64)
R_ = k_ * G
if R_.infinity:
raise ValueError('The blindpubnonce cannot be infinity.')
s_ = k + (e_ * d)
pk = PlainPk(cbytes(P))
blindsignature = s_.to_bytes()
assert verify_blind_signature(pk, cbytes(R_), blindchallenge, blindsignature, pk_parity, nonce_parity)
return blindsignature
def verify_blind_signature(pk: PlainPk, blindpubnonce: bytes, blindchallenge: bytes, blindsignature: bytes, pk_parity: bool, nonce_parity: bool) -> bool:
P_ = cpoint(pk)
P = P_ if pk_parity else -P_
if P.infinity:
raise ValueError('The public key cannot be infinity.')
R_ = cpoint(blindpubnonce)
R = R_ if nonce_parity else -R_
e_ = Scalar.from_bytes_checked(blindchallenge)
s_ = Scalar.from_bytes_checked(blindsignature)
R_calc = (s_ * G) + (-e_ * P)
if R_calc.infinity:
return False
return R == R_calc
def pubkey_and_tweak(pk: PlainPk, tweaks: List[bytes], is_xonly: List[bool]) -> TweakContext:
if len(tweaks) != len(is_xonly):
raise ValueError('The tweaks and is_xonly arrays must have the same length.')
tweak_ctx = tweak_ctx_init(pk)
v = len(tweaks)
for i in range(v):
tweak_ctx = apply_tweak(tweak_ctx, tweaks[i], is_xonly[i])
return tweak_ctx
def get_session_values(session_ctx: SessionContext) -> Tuple[GE, Scalar, Scalar, GE, Scalar, Scalar]:
(pk, blindfactor, challenge, pubnonce, tweaks, is_xonly) = session_ctx
Q, gacc, tacc = pubkey_and_tweak(pk, tweaks, is_xonly)
a = Scalar.from_bytes_checked(blindfactor)
e = Scalar.from_bytes_checked(challenge)
R = cpoint(pubnonce)
return Q, a, e, R, gacc, tacc
def unblind_signature(session_ctx: SessionContext, blindsignature: bytes) -> bytes:
Q, a, e, R, gacc, tacc = get_session_values(session_ctx)
s_ = Scalar.from_bytes_checked(blindsignature)
g = Scalar(1) if Q.has_even_y() else Scalar(-1)
s = s_ + a + (e * g * tacc)
return xbytes(R) + s.to_bytes()
#
# The following code is only used for testing.
#
def hx(s: str) -> bytes:
return bytes.fromhex(s)
def fromhex_all(l): # noqa: E741
return [hx(l_i) for l_i in l]
def get_error_details(tc):
et = tc["error"]["type"]
# Resolve to real class from name
exc_cls = getattr(__builtins__, et, None) or getattr(__import__("builtins"), et)
# Optional message predicate
msg = tc["error"].get("message")
if msg is None:
return exc_cls, (lambda e: True)
return exc_cls, (lambda e: msg in str(e))
def assert_raises(exc_cls, fn, pred):
try:
fn()
except Exception as e:
assert isinstance(e, exc_cls), f"Raised {type(e).__name__}, expected {exc_cls.__name__}"
assert pred(e), f"Exception message predicate failed: {e}"
return
assert False, f"Expected {exc_cls.__name__} but no exception was raised"
def build_session_ctx(obj):
pk = PlainPk(bytes.fromhex(obj["pk"]))
a = bytes.fromhex(obj["blindfactor"])
e = bytes.fromhex(obj["challenge"])
R = bytes.fromhex(obj["pubnonce"])
tweaks = fromhex_all(obj["tweaks"])
is_xonly = obj["is_xonly"]
return (pk, a, e, R, tweaks, is_xonly)
def test_blind_nonce_gen_vectors():
with open(os.path.join(sys.path[0], 'vectors', 'blind_nonce_gen_vectors.json')) as f:
tv = json.load(f)
for tc in tv["test_cases"]:
def get_bytes(key) -> bytes:
return bytes.fromhex(tc[key])
def get_bytes_maybe(key) -> Optional[bytes]:
v = tc.get(key)
return None if v is None else bytes.fromhex(v)
rand_ = get_bytes("rand_")
sk = get_bytes_maybe("sk")
pk = get_bytes_maybe("pk")
if pk is not None:
pk = PlainPk(pk)
extra_in = get_bytes_maybe("extra_in")
expected_blindsecnonce = get_bytes("expected_blindsecnonce")
expected_blindpubnonce = get_bytes("expected_blindpubnonce")
blindsecnonce, blindpubnonce = blind_nonce_gen_internal(rand_, sk, pk, extra_in)
assert bytes(blindsecnonce) == expected_blindsecnonce
assert blindpubnonce == expected_blindpubnonce
pk_len = 0 if tc["pk"] is None else 33
assert len(expected_blindsecnonce) == 32 + pk_len
assert len(expected_blindpubnonce) == 33
def test_blind_challenge_gen_vectors():
with open(os.path.join(sys.path[0], 'vectors', 'blind_challenge_gen_vectors.json')) as f:
tv = json.load(f)
# ---------- Valid cases ----------
for tc in tv["test_cases"]:
rand = bytes.fromhex(tc["rand"])
msg = bytes.fromhex(tc["msg"]) if tc["msg"] != "" else b""
blindpubnonce = bytes.fromhex(tc["blindpubnonce"])
pk = PlainPk(bytes.fromhex(tc["pk"]))
tweaks = fromhex_all(tc["tweaks"])
is_xonly = tc["is_xonly"]
extra_in = None if tc["extra_in"] is None else bytes.fromhex(tc["extra_in"])
expected_a = bytes.fromhex(tc["expected_blindfactor"])
expected_e = bytes.fromhex(tc["expected_challenge"])
expected_R = bytes.fromhex(tc["expected_pubnonce"])
expected_e_prime = bytes.fromhex(tc["expected_blindchallenge"])
expected_pk_parity = bool(tc["expected_pk_parity"])
expected_nonce_parity = bool(tc["expected_nonce_parity"])
session_ctx, blindchallenge, pk_parity, nonce_parity = blind_challenge_gen_internal(
rand, msg, blindpubnonce, pk, tweaks, is_xonly, extra_in
)
# Check tuple outputs
assert blindchallenge == expected_e_prime
assert pk_parity == expected_pk_parity
assert nonce_parity == expected_nonce_parity
# Check session_ctx fields
pk_sc, blindfactor_sc, challenge_sc, pubnonce_sc, tweaks_sc, is_xonly_sc = session_ctx
assert pk_sc == pk
assert blindfactor_sc == expected_a
assert challenge_sc == expected_e
assert pubnonce_sc == expected_R
assert tweaks_sc == tweaks
assert is_xonly_sc == is_xonly
# Extra sanity: recompute Q and e and compare
Q, gacc, tacc = pubkey_and_tweak(pk, tweaks, is_xonly)
R = cpoint(expected_R)
e_check = tagged_hash("BIP0340/challenge", xbytes(R) + xbytes(Q) + msg)
assert e_check == expected_e
# Length sanity
assert len(expected_a) == 32
assert len(expected_e) == 32
assert len(expected_R) == 33
assert len(expected_e_prime) == 32
# ---------- Error cases ----------
for tc in tv.get("error_test_cases", []):
rand = bytes.fromhex(tc["rand"])
msg = bytes.fromhex(tc["msg"]) if tc["msg"] != "" else b""
blindpubnonce = bytes.fromhex(tc["blindpubnonce"])
pk = PlainPk(bytes.fromhex(tc["pk"]))
tweaks = fromhex_all(tc["tweaks"])
is_xonly = tc["is_xonly"]
extra_in = None if tc["extra_in"] is None else bytes.fromhex(tc["extra_in"])
err = tc["error"]
err_type = err["type"]
err_message = err.get("message")
raised = False
try:
_ = blind_challenge_gen_internal(rand, msg, blindpubnonce, pk, tweaks, is_xonly, extra_in)
except Exception as e:
raised = True
# Type check
assert e.__class__.__name__ == err_type
# Optional substring match on message, if provided
if err_message is not None:
assert err_message in str(e)
assert raised, "Expected an exception but none was raised"
def test_blind_sign_and_verify_vectors():
with open(os.path.join(sys.path[0], 'vectors', 'blind_sign_and_verify_vectors.json')) as f:
tv = json.load(f)
# ------------------ Valid ------------------
for test_case in tv["valid_test_cases"]:
sk = hx(test_case["sk"])
pk = PlainPk(hx(test_case["pk"]))
blindsecnonce_all = hx(test_case["blindsecnonce"])
blindpubnonce = hx(test_case["blindpubnonce"])
blindchallenge = hx(test_case["blindchallenge"])
pk_parity = bool(test_case["pk_parity"])
nonce_parity = bool(test_case["nonce_parity"])
# R' consistency check: cbytes(k'*G) == blindpubnonce
k_ = Scalar.from_bytes_checked(blindsecnonce_all[0:32])
R_prime = k_ * G
assert cbytes(R_prime) == blindpubnonce
expected_sprime = hx(test_case["expected"]["blindsignature"])
# Copy because blind_sign zeroizes the first 64 bytes of the buffer
secnonce_buf = bytearray(blindsecnonce_all)
s_prime = blind_sign(sk, blindchallenge, secnonce_buf, pk_parity, nonce_parity)
assert s_prime == expected_sprime
checks = test_case.get("checks", {})
if checks.get("secnonce_prefix_zeroed_after_sign", False):
assert all(b == 0 for b in secnonce_buf[:64])
if checks.get("verify_returns_true", True):
ok = verify_blind_signature(pk, blindpubnonce, blindchallenge, s_prime, pk_parity, nonce_parity)
assert ok is True
if checks.get("second_call_raises_valueerror", False):
# Reuse the same (now zeroized) buffer; must raise
def try_again():
blind_sign(sk, blindchallenge, secnonce_buf, pk_parity, nonce_parity)
raised = False
try:
try_again()
except ValueError:
raised = True
assert raised, "Expected ValueError on nonce reuse"
# ------------------ Sign errors (exceptions) ------------------
for test_case in tv.get("sign_error_test_cases", []):
exception, except_fn = get_error_details(test_case)
sk = hx(test_case["sk"])
blindsecnonce_all = hx(test_case["blindsecnonce"])
blindchallenge = hx(test_case["blindchallenge"])
pk_parity = bool(test_case["pk_parity"])
nonce_parity = bool(test_case["nonce_parity"])
repeat = int(test_case.get("repeat", 1))
if repeat == 1:
# Single-call error (e.g., out-of-range e')
assert_raises(exception, lambda: blind_sign(sk, blindchallenge, bytearray(blindsecnonce_all), pk_parity, nonce_parity), except_fn)
else:
# Two-call error (nonce reuse)
buf = bytearray(blindsecnonce_all)
# First call should succeed
_ = blind_sign(sk, blindchallenge, buf, pk_parity, nonce_parity)
# Second call must raise
assert_raises(exception, lambda: blind_sign(sk, blindchallenge, buf, pk_parity, nonce_parity), except_fn)
# ------------------ Verify returns False (no exception) ------------------
for test_case in tv.get("verify_fail_test_cases", []):
pk = PlainPk(hx(test_case["pk"]))
blindpubnonce = hx(test_case["blindpubnonce"])
blindchallenge = hx(test_case["blindchallenge"])
blindsignature = hx(test_case["blindsignature"])
pk_parity = bool(test_case["pk_parity"])
nonce_parity = bool(test_case["nonce_parity"])
assert verify_blind_signature(pk, blindpubnonce, blindchallenge, blindsignature, pk_parity, nonce_parity) is False
# ------------------ Verify errors (exceptions) ------------------
for test_case in tv.get("verify_error_test_cases", []):
exception, except_fn = get_error_details(test_case)
pk = PlainPk(hx(test_case["pk"]))
blindpubnonce = hx(test_case["blindpubnonce"])
blindchallenge = hx(test_case["blindchallenge"])
blindsignature = hx(test_case["blindsignature"])
pk_parity = bool(test_case["pk_parity"])
nonce_parity = bool(test_case["nonce_parity"])
assert_raises(exception, lambda: verify_blind_signature(pk, blindpubnonce, blindchallenge, blindsignature, pk_parity, nonce_parity), except_fn)
def test_unblind_signature_vectors():
with open(os.path.join(sys.path[0], 'vectors', 'unblind_signature_vectors.json')) as f:
tv = json.load(f)
# ---------- Valid ----------
for tc in tv["valid_test_cases"]:
session_ctx = build_session_ctx(tc["session_ctx"])
msg = bytes.fromhex(tc["msg"]) if tc["msg"] != "" else b""
blindsignature = bytes.fromhex(tc["blindsignature"])
expected_sig = bytes.fromhex(tc["expected_bip340_sig"])
sig = unblind_signature(session_ctx, blindsignature)
assert sig == expected_sig
# Verify BIP340 with tweaked Q
pk, _, _, _, tweaks, is_xonly = session_ctx
Q, _, _ = pubkey_and_tweak(pk, tweaks, is_xonly)
assert schnorr_verify(msg, xbytes(Q), sig)
# ---------- Errors ----------
for tc in tv.get("error_test_cases", []):
session_ctx = build_session_ctx(tc["session_ctx"])
msg = bytes.fromhex(tc["msg"]) if tc["msg"] != "" else b""
blindsignature = bytes.fromhex(tc["blindsignature"])
err = tc["error"]
err_type = err["type"]
err_msg = err.get("message")
raised = False
try:
_ = unblind_signature(session_ctx, blindsignature)
except Exception as e:
raised = True
assert e.__class__.__name__ == err_type
if err_msg is not None:
assert err_msg in str(e)
assert raised, "Expected an exception but none was raised"
def test_sign_and_verify_random(iters: int) -> None:
for _ in range(iters):
sk = Scalar.from_bytes_wrapping(secrets.token_bytes(32))
pk = individual_pk(sk.to_bytes())
msg = Scalar.from_bytes_wrapping(secrets.token_bytes(32))
v = secrets.randbelow(4)
tweaks = [secrets.token_bytes(32) for _ in range(v)]
tweak_modes = [secrets.choice([False, True]) for _ in range(v)]
Q, _, _ = pubkey_and_tweak(pk, tweaks, tweak_modes)
assert not Q.infinity
# Round 1
# Signer
extra_in_1 = secrets.token_bytes(32)
blindsecnonce, blindpubnonce = blind_nonce_gen(sk.to_bytes(), pk, extra_in_1)
# User
extra_in_2 = secrets.token_bytes(32)
session_ctx, blindchallenge, pk_parity, nonce_parity = blind_challenge_gen(msg.to_bytes(), blindpubnonce, pk, tweaks, tweak_modes, extra_in_2)
# Round 2
# Signer
blindsignature = blind_sign(sk.to_bytes(), blindchallenge, blindsecnonce, pk_parity, nonce_parity)
# User
sig = unblind_signature(session_ctx, blindsignature)
assert schnorr_verify(msg.to_bytes(), xbytes(Q), sig)
def compute_bip32_tweak(xpub: ExtendedPublicKey, path: Sequence[int]) -> Tuple[int, ExtendedPublicKey]:
"""Compute the CCD tweak scalar for a non-hardened derivation path."""
aggregate = 0
current = xpub
for index in path:
tweak, child = current.derive_child(index)
aggregate = (aggregate + tweak) % CURVE_N
current = child
return aggregate, current
def input_verification(
descriptor_template: SortedMultiDescriptorTemplate,
witness_script: Optional[bytes],
tweaks: Mapping[bytes, int],
) -> bool:
"""Check that an input script matches the tweaked policy from CCD data."""
return _verify_tweaked_descriptor(
descriptor_template,
witness_script,
tweaks,
)
def change_output_verification(
descriptor_template: SortedMultiDescriptorTemplate,
witness_script: Optional[bytes],
tweaks: Mapping[bytes, int],
) -> bool:
"""Validate a change output script using delegated CCD tweak data."""
return _verify_tweaked_descriptor(
descriptor_template,
witness_script,
tweaks,
)
def _verify_tweaked_descriptor(
descriptor_template: SortedMultiDescriptorTemplate,
witness_script: Optional[bytes],
tweaks: Mapping[bytes, int],
) -> bool:
if witness_script is None or not tweaks:
return False
if descriptor_template.threshold > len(tweaks):
return False
tweaked_keys: List[bytes] = []
for base_key, tweak in sorted(tweaks.items(), key=lambda item: item[0]):
if len(base_key) != 33:
return False
tweaked_key = apply_tweak_to_public(base_key, tweak % CURVE_N)
tweaked_keys.append(tweaked_key)
try:
expected_witness_script = descriptor_template.witness_script(tweaked_keys)
except ValueError:
return False
return witness_script == expected_witness_script
def delegator_sign(
tweak: int,
base_secret: int,
message: bytes,
) -> bytes:
"""Derive the delegated key, sign ``message``, and return signature."""
child_secret = int_to_bytes(apply_tweak_to_secret(base_secret, tweak), 32)
message_digest = hashlib.sha256(message).digest()
signature = schnorr_sign(message_digest, child_secret, bytes(32))
return signature
def test_compute_tweak_vectors() -> None:
with open(os.path.join(sys.path[0], 'vectors', 'compute_bip32_tweak_vectors.json')) as f:
data = json.load(f)
default_xpub_data = data.get("xpub")
if default_xpub_data is None:
raise AssertionError("compute_bip32_tweak_vectors.json missing top-level 'xpub'")
for case in data.get("valid_test_cases", []):
xpub_data = case.get("xpub", default_xpub_data)
xpub = parse_extended_public_key(xpub_data)
path = decode_path(case.get("path", []))
expected = case.get("expected")
if not isinstance(expected, Mapping):
raise AssertionError("valid compute_tweak case missing 'expected'")
tweak_hex = expected.get("tweak")
if not isinstance(tweak_hex, str):
raise AssertionError("expected 'tweak' must be a string")
derived = expected.get("derived_xpub", {})
derived_compressed = derived.get("compressed")
if not isinstance(derived_compressed, str):
raise AssertionError("expected 'derived_xpub.compressed' must be a string")
derived_chain_code = derived.get("chain_code")
if not isinstance(derived_chain_code, str):
raise AssertionError("expected 'derived_xpub.chain_code' must be a string")
tweak, child = compute_bip32_tweak(xpub, path)
actual_tweak_hex = f"{tweak:064x}"
if actual_tweak_hex != tweak_hex.lower():
raise AssertionError(f"tweak mismatch: expected {tweak_hex}, got {actual_tweak_hex}")
actual_compressed = compress_point(child.point).hex()
actual_chain_code = child.chain_code.hex()
if actual_compressed != derived_compressed.lower():
raise AssertionError("derived public key mismatch")
if actual_chain_code != derived_chain_code.lower():
raise AssertionError("derived chain code mismatch")
for case in data.get("error_test_cases", []):
xpub_data = case.get("xpub", default_xpub_data)
xpub = parse_extended_public_key(xpub_data)
path = decode_path(case.get("path", []))
error_spec = case.get("error", {})
exc_type, message = resolve_error_spec(error_spec)
try:
compute_bip32_tweak(xpub, path)
except exc_type as exc:
if message and message.lower() not in str(exc).lower():
raise AssertionError(f"expected error containing '{message}' but got '{exc}'")
else:
raise AssertionError("expected failure but case succeeded")
def test_delegator_sign_vectors() -> None:
with open(os.path.join(sys.path[0], 'vectors', 'delegator_sign_vectors.json')) as f:
data = json.load(f)
for case in data.get("test_cases", []):
base_secret_hex = case.get("base_secret")
tweak_hex = case.get("tweak")
message_hex = case.get("message")
base_secret = int(base_secret_hex, 16)
tweak = int(tweak_hex, 16)
message = message_hex.encode('utf-8')
expected = case.get("expected")
if not isinstance(expected, Mapping):
raise AssertionError("delegator_sign case missing 'expected'")
expected_signature_hex = expected.get("signature")
if not isinstance(expected_signature_hex, str):
raise AssertionError("expected 'signature' must be a string")
expected_signature = bytes.fromhex(expected_signature_hex)
signature = delegator_sign(
tweak,
base_secret,
message,
)
if signature != expected_signature:
raise AssertionError("signature mismatch")
def test_input_verification_vectors() -> None:
with open(os.path.join(sys.path[0], 'vectors', 'input_verification_vectors.json')) as f:
data = json.load(f)
for case in data.get("test_cases", []):
descriptor = SortedMultiDescriptorTemplate(threshold=2)
witness_hex = case.get("witness_script")
# Get the tweak map of the bare public keys to the BIP 32 tweak
tweaks_raw = case.get("tweak_map", {})
tweaks = parse_tweak_map(tweaks_raw)
expected_bool = bool(case.get("expected", False))
result = input_verification(
descriptor,
bytes.fromhex(witness_hex),
tweaks,
)
if result != expected_bool:
raise AssertionError(
f"input_verification result {result} did not match expected {expected_bool}"
)
def test_change_output_verification_vectors() -> None:
with open(os.path.join(sys.path[0], 'vectors', 'change_output_verification_vectors.json')) as f:
data = json.load(f)
for case in data.get("test_cases", []):
descriptor = SortedMultiDescriptorTemplate(threshold=2)
witness_hex = case.get("witness_script")
# Get the tweak map of the bare public keys to the BIP 32 tweak
tweaks_raw = case.get("tweak_map", {})
tweaks = parse_tweak_map(tweaks_raw)
expected_bool = bool(case.get("expected", False))
result = change_output_verification(
descriptor,
bytes.fromhex(witness_hex),
tweaks,
)
if result != expected_bool:
raise AssertionError(
f"change_output_verification result {result} did not match expected {expected_bool}"
)
def parse_tweak_map(raw: Mapping[str, object]) -> Dict[bytes, int]:
tweaks: Dict[bytes, int] = {}
for key_hex, tweak_hex in raw.items():
base_key = bytes.fromhex(key_hex)
if not isinstance(tweak_hex, str):
raise ValueError(f"tweak value for key {key_hex} must be a string")
tweak_value = int(tweak_hex, 16)
tweaks[base_key] = tweak_value % CURVE_N
return tweaks
def resolve_error_spec(raw: object) -> Tuple[type[Exception], Optional[str]]:
mapping: Dict[str, type[Exception]] = {"value": ValueError, "assertion": AssertionError, "runtime": RuntimeError}
if not isinstance(raw, dict):
return ValueError, None
raw_dict = cast(Dict[str, Any], raw)
name = str(raw_dict.get("type", "value")).lower()
message = raw_dict.get("message")
exc_type = mapping.get(name, ValueError)
return exc_type, None if message is None else str(message)
if __name__ == '__main__':
test_blind_nonce_gen_vectors()
test_blind_challenge_gen_vectors()
test_blind_sign_and_verify_vectors()
test_unblind_signature_vectors()
test_sign_and_verify_random(6)
test_compute_tweak_vectors()
test_delegator_sign_vectors()
test_input_verification_vectors()
test_change_output_verification_vectors()
print("All tests passed")

View File

@ -0,0 +1,23 @@
The MIT License (MIT)
Copyright (c) 2009-2024 The Bitcoin Core developers
Copyright (c) 2009-2024 Bitcoin Developers
Copyright (c) 2025- The secp256k1lab Developers
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

View File

@ -0,0 +1,73 @@
# The following functions are based on the BIP 340 reference implementation:
# https://github.com/bitcoin/bips/blob/master/bip-0340/reference.py
from .secp256k1 import FE, GE, G
from .util import int_from_bytes, bytes_from_int, xor_bytes, tagged_hash
def pubkey_gen(seckey: bytes) -> bytes:
d0 = int_from_bytes(seckey)
if not (1 <= d0 <= GE.ORDER - 1):
raise ValueError("The secret key must be an integer in the range 1..n-1.")
P = d0 * G
assert not P.infinity
return P.to_bytes_xonly()
def schnorr_sign(
msg: bytes, seckey: bytes, aux_rand: bytes, tag_prefix: str = "BIP0340"
) -> bytes:
d0 = int_from_bytes(seckey)
if not (1 <= d0 <= GE.ORDER - 1):
raise ValueError("The secret key must be an integer in the range 1..n-1.")
if len(aux_rand) != 32:
raise ValueError("aux_rand must be 32 bytes instead of %i." % len(aux_rand))
P = d0 * G
assert not P.infinity
d = d0 if P.has_even_y() else GE.ORDER - d0
t = xor_bytes(bytes_from_int(d), tagged_hash(tag_prefix + "/aux", aux_rand))
k0 = (
int_from_bytes(tagged_hash(tag_prefix + "/nonce", t + P.to_bytes_xonly() + msg))
% GE.ORDER
)
if k0 == 0:
raise RuntimeError("Failure. This happens only with negligible probability.")
R = k0 * G
assert not R.infinity
k = k0 if R.has_even_y() else GE.ORDER - k0
e = (
int_from_bytes(
tagged_hash(
tag_prefix + "/challenge", R.to_bytes_xonly() + P.to_bytes_xonly() + msg
)
)
% GE.ORDER
)
sig = R.to_bytes_xonly() + bytes_from_int((k + e * d) % GE.ORDER)
assert schnorr_verify(msg, P.to_bytes_xonly(), sig, tag_prefix=tag_prefix)
return sig
def schnorr_verify(
msg: bytes, pubkey: bytes, sig: bytes, tag_prefix: str = "BIP0340"
) -> bool:
if len(pubkey) != 32:
raise ValueError("The public key must be a 32-byte array.")
if len(sig) != 64:
raise ValueError("The signature must be a 64-byte array.")
try:
P = GE.from_bytes_xonly(pubkey)
except ValueError:
return False
r = int_from_bytes(sig[0:32])
s = int_from_bytes(sig[32:64])
if (r >= FE.SIZE) or (s >= GE.ORDER):
return False
e = (
int_from_bytes(tagged_hash(tag_prefix + "/challenge", sig[0:32] + pubkey + msg))
% GE.ORDER
)
R = s * G - e * P
if R.infinity or (not R.has_even_y()) or (R.x != r):
return False
return True

View File

@ -0,0 +1,16 @@
import hashlib
from .secp256k1 import GE, Scalar
def ecdh_compressed_in_raw_out(seckey: bytes, pubkey: bytes) -> GE:
"""TODO"""
shared_secret = Scalar.from_bytes_checked(seckey) * GE.from_bytes_compressed(pubkey)
assert not shared_secret.infinity # prime-order group
return shared_secret
def ecdh_libsecp256k1(seckey: bytes, pubkey: bytes) -> bytes:
"""TODO"""
shared_secret = ecdh_compressed_in_raw_out(seckey, pubkey)
return hashlib.sha256(shared_secret.to_bytes_compressed()).digest()

View File

@ -0,0 +1,15 @@
from .secp256k1 import GE, G
from .util import int_from_bytes
# The following function is based on the BIP 327 reference implementation
# https://github.com/bitcoin/bips/blob/master/bip-0327/reference.py
# Return the plain public key corresponding to a given secret key
def pubkey_gen_plain(seckey: bytes) -> bytes:
d0 = int_from_bytes(seckey)
if not (1 <= d0 <= GE.ORDER - 1):
raise ValueError("The secret key must be an integer in the range 1..n-1.")
P = d0 * G
assert not P.infinity
return P.to_bytes_compressed()

View File

View File

@ -0,0 +1,483 @@
# Copyright (c) 2022-2023 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test-only implementation of low-level secp256k1 field and group arithmetic
It is designed for ease of understanding, not performance.
WARNING: This code is slow and trivially vulnerable to side channel attacks. Do not use for
anything but tests.
Exports:
* FE: class for secp256k1 field elements
* GE: class for secp256k1 group elements
* G: the secp256k1 generator point
"""
from __future__ import annotations
from typing import Self
# TODO Docstrings of methods still say "field element"
class APrimeFE:
"""Objects of this class represent elements of a prime field.
They are represented internally in numerator / denominator form, in order to delay inversions.
"""
# The size of the field (also its modulus and characteristic).
SIZE: int
def __init__(self, a: int | Self = 0, b: int | Self = 1) -> None:
"""Initialize a field element a/b; both a and b can be ints or field elements."""
if isinstance(a, type(self)):
num = a._num
den = a._den
else:
assert isinstance(a, int)
num = a % self.SIZE
den = 1
if isinstance(b, type(self)):
den = (den * b._num) % self.SIZE
num = (num * b._den) % self.SIZE
else:
assert isinstance(b, int)
den = (den * b) % self.SIZE
assert den != 0
if num == 0:
den = 1
self._num: int = num
self._den: int = den
def __add__(self, a: int | Self) -> Self:
"""Compute the sum of two field elements (second may be int)."""
if isinstance(a, type(self)):
return type(self)(self._num * a._den + self._den * a._num, self._den * a._den)
if isinstance(a, int):
return type(self)(self._num + self._den * a, self._den)
return NotImplemented
def __radd__(self, a: int) -> Self:
"""Compute the sum of an integer and a field element."""
return type(self)(a) + self
@classmethod
def sum(cls, *es: Self) -> Self:
"""Compute the sum of field elements.
sum(a, b, c, ...) is identical to (0 + a + b + c + ...)."""
return sum(es, start=cls(0))
def __sub__(self, a: int | Self) -> Self:
"""Compute the difference of two field elements (second may be int)."""
if isinstance(a, type(self)):
return type(self)(self._num * a._den - self._den * a._num, self._den * a._den)
if isinstance(a, int):
return type(self)(self._num - self._den * a, self._den)
return NotImplemented
def __rsub__(self, a: int) -> Self:
"""Compute the difference of an integer and a field element."""
return type(self)(a) - self
def __mul__(self, a: int | Self) -> Self:
"""Compute the product of two field elements (second may be int)."""
if isinstance(a, type(self)):
return type(self)(self._num * a._num, self._den * a._den)
if isinstance(a, int):
return type(self)(self._num * a, self._den)
return NotImplemented
def __rmul__(self, a: int) -> Self:
"""Compute the product of an integer with a field element."""
return type(self)(a) * self
def __truediv__(self, a: int | Self) -> Self:
"""Compute the ratio of two field elements (second may be int)."""
if isinstance(a, type(self)) or isinstance(a, int):
return type(self)(self, a)
return NotImplemented
def __pow__(self, a: int) -> Self:
"""Raise a field element to an integer power."""
return type(self)(pow(self._num, a, self.SIZE), pow(self._den, a, self.SIZE))
def __neg__(self) -> Self:
"""Negate a field element."""
return type(self)(-self._num, self._den)
def __int__(self) -> int:
"""Convert a field element to an integer in range 0..SIZE-1. The result is cached."""
if self._den != 1:
self._num = (self._num * pow(self._den, -1, self.SIZE)) % self.SIZE
self._den = 1
return self._num
def sqrt(self) -> Self | None:
"""Compute the square root of a field element if it exists (None otherwise)."""
raise NotImplementedError
def is_square(self) -> bool:
"""Determine if this field element has a square root."""
# A more efficient algorithm is possible here (Jacobi symbol).
return self.sqrt() is not None
def is_even(self) -> bool:
"""Determine whether this field element, represented as integer in 0..SIZE-1, is even."""
return int(self) & 1 == 0
def __eq__(self, a: object) -> bool:
"""Check whether two field elements are equal (second may be an int)."""
if isinstance(a, type(self)):
return (self._num * a._den - self._den * a._num) % self.SIZE == 0
elif isinstance(a, int):
return (self._num - self._den * a) % self.SIZE == 0
return False # for other types
def to_bytes(self) -> bytes:
"""Convert a field element to a 32-byte array (BE byte order)."""
return int(self).to_bytes(32, 'big')
@classmethod
def from_int_checked(cls, v: int) -> Self:
"""Convert an integer to a field element (no overflow allowed)."""
if v >= cls.SIZE:
raise ValueError
return cls(v)
@classmethod
def from_int_wrapping(cls, v: int) -> Self:
"""Convert an integer to a field element (reduced modulo SIZE)."""
return cls(v % cls.SIZE)
@classmethod
def from_bytes_checked(cls, b: bytes) -> Self:
"""Convert a 32-byte array to a field element (BE byte order, no overflow allowed)."""
v = int.from_bytes(b, 'big')
return cls.from_int_checked(v)
@classmethod
def from_bytes_wrapping(cls, b: bytes) -> Self:
"""Convert a 32-byte array to a field element (BE byte order, reduced modulo SIZE)."""
v = int.from_bytes(b, 'big')
return cls.from_int_wrapping(v)
def __str__(self) -> str:
"""Convert this field element to a 64 character hex string."""
return f"{int(self):064x}"
def __repr__(self) -> str:
"""Get a string representation of this field element."""
return f"{type(self).__qualname__}(0x{int(self):x})"
class FE(APrimeFE):
SIZE = 2**256 - 2**32 - 977
def sqrt(self) -> Self | None:
# Due to the fact that our modulus p is of the form (p % 4) == 3, the Tonelli-Shanks
# algorithm (https://en.wikipedia.org/wiki/Tonelli-Shanks_algorithm) is simply
# raising the argument to the power (p + 1) / 4.
# To see why: (p-1) % 2 = 0, so 2 divides the order of the multiplicative group,
# and thus only half of the non-zero field elements are squares. An element a is
# a (nonzero) square when Euler's criterion, a^((p-1)/2) = 1 (mod p), holds. We're
# looking for x such that x^2 = a (mod p). Given a^((p-1)/2) = 1, that is equivalent
# to x^2 = a^(1 + (p-1)/2) mod p. As (1 + (p-1)/2) is even, this is equivalent to
# x = a^((1 + (p-1)/2)/2) mod p, or x = a^((p+1)/4) mod p.
v = int(self)
s = pow(v, (self.SIZE + 1) // 4, self.SIZE)
if s**2 % self.SIZE == v:
return type(self)(s)
return None
class Scalar(APrimeFE):
"""TODO Docstring"""
SIZE = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
@classmethod
def from_int_nonzero_checked(cls, v: int) -> Self:
"""Convert an integer to a scalar (no zero or overflow allowed)."""
if not (0 < v < cls.SIZE):
raise ValueError
return cls(v)
@classmethod
def from_bytes_nonzero_checked(cls, b: bytes) -> Self:
"""Convert a 32-byte array to a scalar (BE byte order, no zero or overflow allowed)."""
v = int.from_bytes(b, 'big')
return cls.from_int_nonzero_checked(v)
class GE:
"""Objects of this class represent secp256k1 group elements (curve points or infinity)
GE objects are immutable.
Normal points on the curve have fields:
* x: the x coordinate (a field element)
* y: the y coordinate (a field element, satisfying y^2 = x^3 + 7)
* infinity: False
The point at infinity has field:
* infinity: True
"""
# TODO The following two class attributes should probably be just getters as
# classmethods to enforce immutability. Unfortunately Python makes it hard
# to create "classproperties". `G` could then also be just a classmethod.
# Order of the group (number of points on the curve, plus 1 for infinity)
ORDER = Scalar.SIZE
# Number of valid distinct x coordinates on the curve.
ORDER_HALF = ORDER // 2
@property
def infinity(self) -> bool:
"""Whether the group element is the point at infinity."""
return self._infinity
@property
def x(self) -> FE:
"""The x coordinate (a field element) of a non-infinite group element."""
assert not self.infinity
return self._x
@property
def y(self) -> FE:
"""The y coordinate (a field element) of a non-infinite group element."""
assert not self.infinity
return self._y
def __init__(self, x: int | FE | None = None, y: int | FE | None = None) -> None:
"""Initialize a group element with specified x and y coordinates, or infinity."""
if x is None:
# Initialize as infinity.
assert y is None
self._infinity = True
else:
# Initialize as point on the curve (and check that it is).
assert x is not None
assert y is not None
fx = FE(x)
fy = FE(y)
assert fy**2 == fx**3 + 7
self._infinity = False
self._x = fx
self._y = fy
def __add__(self, a: GE) -> GE:
"""Add two group elements together."""
# Deal with infinity: a + infinity == infinity + a == a.
if self.infinity:
return a
if a.infinity:
return self
if self.x == a.x:
if self.y != a.y:
# A point added to its own negation is infinity.
assert self.y + a.y == 0
return GE()
else:
# For identical inputs, use the tangent (doubling formula).
lam = (3 * self.x**2) / (2 * self.y)
else:
# For distinct inputs, use the line through both points (adding formula).
lam = (self.y - a.y) / (self.x - a.x)
# Determine point opposite to the intersection of that line with the curve.
x = lam**2 - (self.x + a.x)
y = lam * (self.x - x) - self.y
return GE(x, y)
@staticmethod
def sum(*ps: GE) -> GE:
"""Compute the sum of group elements.
GE.sum(a, b, c, ...) is identical to (GE() + a + b + c + ...)."""
return sum(ps, start=GE())
@staticmethod
def batch_mul(*aps: tuple[Scalar, GE]) -> GE:
"""Compute a (batch) scalar group element multiplication.
GE.batch_mul((a1, p1), (a2, p2), (a3, p3)) is identical to a1*p1 + a2*p2 + a3*p3,
but more efficient."""
# Reduce all the scalars modulo order first (so we can deal with negatives etc).
naps = [(int(a), p) for a, p in aps]
# Start with point at infinity.
r = GE()
# Iterate over all bit positions, from high to low.
for i in range(255, -1, -1):
# Double what we have so far.
r = r + r
# Add then add the points for which the corresponding scalar bit is set.
for (a, p) in naps:
if (a >> i) & 1:
r += p
return r
def __rmul__(self, a: int | Scalar) -> GE:
"""Multiply an integer or scalar with a group element."""
if self == G:
return FAST_G.mul(Scalar(a))
return GE.batch_mul((Scalar(a), self))
def __neg__(self) -> GE:
"""Compute the negation of a group element."""
if self.infinity:
return self
return GE(self.x, -self.y)
def __sub__(self, a: GE) -> GE:
"""Subtract a group element from another."""
return self + (-a)
def __eq__(self, a: object) -> bool:
"""Check if two group elements are equal."""
if not isinstance(a, type(self)):
return False
return (self - a).infinity
def has_even_y(self) -> bool:
"""Determine whether a non-infinity group element has an even y coordinate."""
assert not self.infinity
return self.y.is_even()
def to_bytes_compressed(self) -> bytes:
"""Convert a non-infinite group element to 33-byte compressed encoding."""
assert not self.infinity
return bytes([3 - self.y.is_even()]) + self.x.to_bytes()
def to_bytes_compressed_with_infinity(self) -> bytes:
"""Convert a group element to 33-byte compressed encoding, mapping infinity to zeros."""
if self.infinity:
return 33 * b"\x00"
return self.to_bytes_compressed()
def to_bytes_uncompressed(self) -> bytes:
"""Convert a non-infinite group element to 65-byte uncompressed encoding."""
assert not self.infinity
return b'\x04' + self.x.to_bytes() + self.y.to_bytes()
def to_bytes_xonly(self) -> bytes:
"""Convert (the x coordinate of) a non-infinite group element to 32-byte xonly encoding."""
assert not self.infinity
return self.x.to_bytes()
@staticmethod
def lift_x(x: int | FE) -> GE:
"""Return group element with specified field element as x coordinate (and even y)."""
y = (FE(x)**3 + 7).sqrt()
if y is None:
raise ValueError
if not y.is_even():
y = -y
return GE(x, y)
@staticmethod
def from_bytes_compressed(b: bytes) -> GE:
"""Convert a compressed to a group element."""
assert len(b) == 33
if b[0] != 2 and b[0] != 3:
raise ValueError
x = FE.from_bytes_checked(b[1:])
r = GE.lift_x(x)
if b[0] == 3:
r = -r
return r
@staticmethod
def from_bytes_compressed_with_infinity(b: bytes) -> GE:
"""Convert a compressed to a group element, mapping zeros to infinity."""
if b == 33 * b"\x00":
return GE()
else:
return GE.from_bytes_compressed(b)
@staticmethod
def from_bytes_uncompressed(b: bytes) -> GE:
"""Convert an uncompressed to a group element."""
assert len(b) == 65
if b[0] != 4:
raise ValueError
x = FE.from_bytes_checked(b[1:33])
y = FE.from_bytes_checked(b[33:])
if y**2 != x**3 + 7:
raise ValueError
return GE(x, y)
@staticmethod
def from_bytes(b: bytes) -> GE:
"""Convert a compressed or uncompressed encoding to a group element."""
assert len(b) in (33, 65)
if len(b) == 33:
return GE.from_bytes_compressed(b)
else:
return GE.from_bytes_uncompressed(b)
@staticmethod
def from_bytes_xonly(b: bytes) -> GE:
"""Convert a point given in xonly encoding to a group element."""
assert len(b) == 32
x = FE.from_bytes_checked(b)
r = GE.lift_x(x)
return r
@staticmethod
def is_valid_x(x: int | FE) -> bool:
"""Determine whether the provided field element is a valid X coordinate."""
return (FE(x)**3 + 7).is_square()
def __str__(self) -> str:
"""Convert this group element to a string."""
if self.infinity:
return "(inf)"
return f"({self.x},{self.y})"
def __repr__(self) -> str:
"""Get a string representation for this group element."""
if self.infinity:
return "GE()"
return f"GE(0x{int(self.x):x},0x{int(self.y):x})"
def __hash__(self) -> int:
"""Compute a non-cryptographic hash of the group element."""
if self.infinity:
return 0 # 0 is not a valid x coordinate
return int(self.x)
# The secp256k1 generator point
G = GE.lift_x(0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798)
class FastGEMul:
"""Table for fast multiplication with a constant group element.
Speed up scalar multiplication with a fixed point P by using a precomputed lookup table with
its powers of 2:
table = [P, 2*P, 4*P, (2^3)*P, (2^4)*P, ..., (2^255)*P]
During multiplication, the points corresponding to each bit set in the scalar are added up,
i.e. on average ~128 point additions take place.
"""
def __init__(self, p: GE) -> None:
self.table: list[GE] = [p] # table[i] = (2^i) * p
for _ in range(255):
p = p + p
self.table.append(p)
def mul(self, a: Scalar | int) -> GE:
result = GE()
a_ = int(a)
for bit in range(a_.bit_length()):
if a_ & (1 << bit):
result += self.table[bit]
return result
# Precomputed table with multiples of G for fast multiplication
FAST_G = FastGEMul(G)

View File

@ -0,0 +1,24 @@
import hashlib
# This implementation can be sped up by storing the midstate after hashing
# tag_hash instead of rehashing it all the time.
def tagged_hash(tag: str, msg: bytes) -> bytes:
tag_hash = hashlib.sha256(tag.encode()).digest()
return hashlib.sha256(tag_hash + tag_hash + msg).digest()
def bytes_from_int(x: int) -> bytes:
return x.to_bytes(32, byteorder="big")
def xor_bytes(b0: bytes, b1: bytes) -> bytes:
return bytes(x ^ y for (x, y) in zip(b0, b1))
def int_from_bytes(b: bytes) -> int:
return int.from_bytes(b, byteorder="big")
def hash_sha256(b: bytes) -> bytes:
return hashlib.sha256(b).digest()

View File

@ -0,0 +1,51 @@
{
"test_cases": [
{
"rand": "92950940B9C21B956D2950EA4C2CBD966D5DCF32517D2419636C3B434E7E7243",
"msg": "33DF4B220B36836C25198D4AFCFD25D1EE2E7B237C3021D7A0EDBA137E70958C",
"blindpubnonce": "02866A953BB982D4755FC9DCF0E09CC8EA56E2F75040DCAFE0C17A2A6FB5D4AC6E",
"pk": "0232D9E2657C0AA02A6E5AFF67175757832D1B3260A915970EA1CD95E2C9838B52",
"tweaks": ["7F91E8EA5D4FD39AAEB0FCDE90ABAAA8681D2610AF0FDDF132DEFBD5E1183580", "8F4ECAB71A22CDB15945BD2898DF005A8623B8DC50013F12700E678E92837406", "FD890EE6226ECA9EFB889DC1EC77B5D59FE0AF1D876C35F2CBE9F25F6B8FB760"],
"is_xonly": [true, true, false],
"extra_in": "FD8AA0C64B66C38EA627FABB0CFCCE5BB905D130470101ED88771E0A62331AC9",
"expected_blindfactor": "545AB2AAB17406BE3270D0DFB7B13568F9ED5FAD5ABC5E9ACBAFC8D17131CC37",
"expected_challenge": "AC03DF1F1DA05BFD6E01E11BD7B95E3A6A0752BBB0E31EA26251675CECCE3A15",
"expected_pubnonce": "0367E34DAB4F1377CD8F3E7C5CD3E1E4A4D3B27BEAB9C0C0DC6717C9C52275D03B",
"expected_blindchallenge": "B5B3A3D63771818E930E55D3F91EBF11ED16BCDB11E0F1B5DF06F636F870DFB5",
"expected_pk_parity": true,
"expected_nonce_parity": false
}
],
"error_test_cases": [
{
"rand": "2B01EE16681AE0C2D8845C5F1D3F05F92453E95E7AC053DD5CABC736322B6CA3",
"msg": "6C22FC98FEEB69347A04BDE44B99FA50428689608E63B307D9F5904F86FE0B28",
"blindpubnonce": "02D9F53C5816BD205B8208A11491530CD6BD1EC35FFA31F026AD3444EFEA329440",
"pk": "03E9EBFEEAF165FBA6CD394EB1DBD514AE45CE8EA0AE56D54C8B5D7931D79FFBAF",
"tweaks": ["E3DD85653AAFDF2D94312FB8133D6B7E12DFC94B1B82A4E98D85E69D6F2F179A"],
"is_xonly": [true, false],
"extra_in": "C8BB4B046334864F71173C39BDE2A305289AA1AB5C0E0C624EC2D30A0A182310",
"error": {
"type": "ValueError",
"message": "The tweaks and is_xonly arrays must have the same length."
},
"comment": "mismatched arrays"
},
{
"rand": "A8F932BD0BAC6F31824002482A42493B7AA1CAC2814D80D470A716D47ADCDF86",
"msg": "1776037E19AA1A2BF2C9DB770CA12A5AB683E2D7B436090BAC8CE48CB22582E0",
"blindpubnonce": "04411898DF38979F1DA000CEFF9166EE258AB6B0F696B8537F90E551751AA3C6F2",
"pk": "0333438C1C269BD73BADE95C62EDA258F74B093DA359DEDBF990E923CEC95BD6A4",
"tweaks": [],
"is_xonly": [],
"extra_in": null,
"error": {
"type": "ValueError"
},
"comment": "invalid blindpubnonce encoding"
}
]
}

View File

@ -0,0 +1,22 @@
{
"test_cases": [
{
"rand_": "0F6166D1645791EAD551572348A43CA9293E02CF0ED32B17EA5E1AEC6BC41931",
"sk": "F22F1B584D8B5CE15ED8F561DAD077B3FB743E6AABB97DBA758AFD88852DB490",
"pk": "0204B445C4EF4E822DA5842965BC03CBDC865EF846774FD27ACDE063F40CD7812C",
"extra_in": "887BEFE686260D09F471715719B7CB2D48E4116BD346319D9C002A4FC9D82857",
"expected_blindsecnonce": "A4B954BBCB05059CF0ACE8BC2C82BEA5ABD0D2C39B03D7A7205DB41E9BE9CA610204B445C4EF4E822DA5842965BC03CBDC865EF846774FD27ACDE063F40CD7812C",
"expected_blindpubnonce": "0355A32C1B472EE1874924CD9A1BF2536D6A2B214413684FBDFC5B84870EFDCEF8",
"comment": "All params present"
},
{
"rand_": "D4B20323E12CEC7E21B41A4FD2395844F93D4B3E9F3FED13CF3234C32702A242",
"sk": null,
"pk": null,
"extra_in": null,
"expected_blindsecnonce": "78ACDD864846BB5C18017A421E792CC771D63EDA6B63A6CDC3825F298CAC7788",
"expected_blindpubnonce": "025CA329F7676AECEAC10C29566D9C7883A661DB2574454AE491476EADEE3CD430",
"comment": "Every optional parameter is absent"
}
]
}

Some files were not shown because too many files have changed in this diff Show More