bsv-bap 0.1.10 → 0.1.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +122 -882
- package/dist/MasterID.d.ts +7 -3
- package/dist/index.cjs +8 -0
- package/dist/index.d.ts +43 -18
- package/dist/index.modern.js +5 -5
- package/dist/index.modern.js.map +4 -4
- package/dist/index.module.js +5 -5
- package/dist/index.module.js.map +4 -4
- package/package.json +1 -1
package/README.md
CHANGED
@@ -1,959 +1,199 @@
|
|
1
|
-
# Bitcoin Attestation Protocol
|
2
|
-
> A simple protocol to create a chain of trust for any kind of data on the Bitcoin blockchain
|
3
|
-
|
4
|
-
Authors: Siggi
|
5
|
-
|
6
|
-
Special thanks to Attila Aros & Satchmo
|
7
|
-
|
8
|
-
Inspired by the [AUTHOR IDENTITY Protocol](https://github.com/BitcoinFiles/AUTHOR_IDENTITY_PROTOCOL)
|
9
|
-
|
10
|
-
NOTE: All examples in this document use fake identity keys, addresses and signatures. See the test data sets for real world examples that can be used in a test suite when developing a library.
|
11
|
-
|
12
|
-
- [Intro](#intro)
|
13
|
-
- [Protocol](#protocol)
|
14
|
-
* [URN - Uniform Resource Names](#urn---uniform-resource-names)
|
15
|
-
* [Attributes are defined at schema.org](#attributes-are-defined-at-schemaorg)
|
16
|
-
- [Creating an identity (ID)](#creating-an-identity-id)
|
17
|
-
- [Usage in an identity system (BAP-ID)](#usage-in-an-identity-system-bap-id)
|
18
|
-
* [Attesting (ATTEST)](#attesting-attest)
|
19
|
-
* [Verifying an identity attribute](#verifying-an-identity-attribute)
|
20
|
-
* [Delegating signing to another identity](#delegating-signing-to-another-identity)
|
21
|
-
* [Publishing Identity information (ALIAS)](#publishing-identity-information-alias)
|
22
|
-
* [BAP uniKey](#bap-unikey)
|
23
|
-
- [Publishing data (DATA)](#publishing-data)
|
24
|
-
- [Using as a Power of Attorney](#using-as-a-power-of-attorney)
|
25
|
-
- [Blacklisting](#blacklisting)
|
26
|
-
* [Blacklisting transactions / addresses](#blacklisting-transactions--addresses)
|
27
|
-
* [Blacklisting IP addresses](#blacklisting-ip-addresses)
|
28
|
-
* [Final note on blacklisting](#final-note-on-blacklisting)
|
29
|
-
- [Giving consent to access of data](#giving-consent-to-access-of-data)
|
30
|
-
- [Simple asserts](#simple-asserts)
|
31
|
-
- [Revoking an attestation](#revoking-an-attestation)
|
32
|
-
- [BAP on the BSV Metanet - PROVISIONAL](#bap-on-the-bsv-metanet---provisional)
|
33
|
-
- [BAP w3c DID - PROVISIONAL](#bap-w3c-did---provisional)
|
34
|
-
- [Bitcoin Backup Compatible Export Methods](#bitcoin-backup-compatible-export-methods)
|
35
|
-
- [Extending the protocol](#extending-the-protocol)
|
36
|
-
|
37
|
-
# TODO
|
38
|
-
- Finish DID specs - help needed
|
39
|
-
- Request feedback
|
40
|
-
|
41
|
-
# Intro
|
42
|
-
|
43
|
-
The design goals:
|
44
|
-
|
45
|
-
1. A simple protocol for generic attestation of data, without the need to publish the data itself
|
46
|
-
2. Decouple the signing with an address from the funding source address (ie: does not require any on-chain transactions from the signing identity address)
|
47
|
-
3. Allow for rotation of signing keys without having to change the existing attestations
|
48
|
-
4. Allow for creation of an infinite amount of identities, but still allow for proving of attested attributes between the identities
|
49
|
-
|
50
|
-
## Library Features
|
51
|
-
|
52
|
-
This JavaScript/TypeScript implementation of BAP includes:
|
53
|
-
- Full protocol implementation for creating and managing identities
|
54
|
-
- Hierarchical Deterministic (HD) key derivation
|
55
|
-
- ECIES encryption/decryption for secure data transmission
|
56
|
-
- Bitcoin-backup compatible export methods for secure identity storage
|
57
|
-
- Comprehensive API for attestations, delegations, and identity management
|
58
|
-
|
59
|
-
# Protocol
|
60
|
-
|
61
|
-
The protocol is defined using the [Bitcom](https://bitcom.bitdb.network/) convention. The signing is done using the [AUTHOR IDENTITY Protocol](https://github.com/BitcoinFiles/AUTHOR_IDENTITY_PROTOCOL).
|
62
|
-
|
63
|
-
- The prefix of the protocol is `1BAPSuaPnfGnSBM3GLV9yhxUdYe4vGbdMT`;
|
1
|
+
# BAP - Bitcoin Attestation Protocol
|
64
2
|
|
65
|
-
|
66
|
-
1BAPSuaPnfGnSBM3GLV9yhxUdYe4vGbdMT
|
67
|
-
[ID|ATTEST|ALIAS|DATA|REVOKE]
|
68
|
-
[ID Key|URN Attestation Hash]
|
69
|
-
[Sequence|Address|Data]
|
70
|
-
|
|
71
|
-
[AIP protocol address]
|
72
|
-
[AIP Signing Algorithm]
|
73
|
-
[AIP Signing Address]
|
74
|
-
[AIP Signature]
|
75
|
-
```
|
76
|
-
By default, all fields are signed, so the optional indices of the AIP can be left out.
|
77
|
-
|
78
|
-
The `Sequence` is added to the transaction to prevent replay of the transaction in case of a revocation. The transaction from the same signatory, with the highest `Sequence` is the current one.
|
79
|
-
|
80
|
-
The fourth field is used for the bitcoin signing address in an `ID` transaction only.
|
81
|
-
|
82
|
-
Example:
|
83
|
-
|
84
|
-
```
|
85
|
-
1BAPSuaPnfGnSBM3GLV9yhxUdYe4vGbdMT
|
86
|
-
ATTEST
|
87
|
-
d4bcdd0f437d0d3bc588bb4e861d2e83e26e8bf9566ae541a5d43329213b1b13
|
88
|
-
0
|
89
|
-
|
|
90
|
-
15PciHG22SNLQJXMoSUaWVi7WSqc7hCfva
|
91
|
-
BITCOIN_ECDSA
|
92
|
-
1Po6MLAPJsSAGyE8sXw3CgWcgxumNGjyqm
|
93
|
-
G8wW0NOCPFgGSoCtB2DZ+0CrLrh9ywAl0C5hnx78Q+7QNyPYzsFtkt4/TXkzkTwqbOT3Ofb1CYdNUv5a/jviPVA=
|
94
|
-
```
|
95
|
-
|
96
|
-
## URN - Uniform Resource Names
|
97
|
-
The protocol makes use of URN's as a data carrier for the attestation data, as defined by the [w3c](https://www.w3.org/TR/uri-clarification/).
|
98
|
-
|
99
|
-
URN's look like:
|
100
|
-
|
101
|
-
```
|
102
|
-
urn:[namespace identifier]:[...URN]
|
103
|
-
```
|
104
|
-
|
105
|
-
Examples for use in BAP:
|
106
|
-
|
107
|
-
Identity:
|
108
|
-
```
|
109
|
-
urn:bap:id:[Attribute name]:[Attribute value]:[Nonce]
|
110
|
-
|
111
|
-
urn:bap:id:name:John Doe:e2c6fb4063cc04af58935737eaffc938011dff546d47b7fbb18ed346f8c4d4fa
|
112
|
-
```
|
113
|
-
|
114
|
-
Attestations:
|
115
|
-
```
|
116
|
-
urn:bap:attest:[Attribute hash]:[Identity key]
|
117
|
-
|
118
|
-
urn:bap:attest:42d2396ddfc3dec6acbd96830b844a10b8b2f065e60fbd5238b5267ab086bf4f:1CCWY6EXZwNqbrtW1SXGNFWdwipYT7Ur1Q
|
119
|
-
```
|
120
|
-
|
121
|
-
The URN is hashed using sha256 when used in a transaction sent to the blockchain.
|
122
|
-
|
123
|
-
## Attributes are defined at schema.org
|
124
|
-
|
125
|
-
Attributes used in BAP should be defined at https://schema.org.
|
126
|
-
|
127
|
-
Especially the Person attributes, found at https://schema.org/Person, should be used in BAP.
|
128
|
-
|
129
|
-
# Creating an identity (ID)
|
130
|
-
|
131
|
-
To create a new identity in BAP, we need to create 2 private keys and compute they public keys and the corresponding addresses. For easy management of the keys, it is recommended to use an [HD Private key](https://docs.moneybutton.com/docs/bsv-hd-private-key.html) with known derivations.
|
132
|
-
|
133
|
-
```
|
134
|
-
rootAddress: 1WffojxvgpQBmUTigoss7VUdfN45JiiRK
|
135
|
-
firstAddress: 1K4c6YXR1ixNLAqrL8nx5HUQAPKbACTwDo
|
136
|
-
```
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
Signing identities in BAP are created by linking a unique identity key with bitcoin signing addresses. The identity key should be computed as a hash of the rootAddress. This links the 2 together and prevents others from creating an identity using the same identity key to create confusion.
|
141
|
-
|
142
|
-
The identity key follows the way a Bitcoin address is hashed to reduce the size of the key.
|
143
|
-
|
144
|
-
```
|
145
|
-
identityKey = base58( ripemd160 ( sha256 ( rootAddress ) ) )
|
146
|
-
```
|
147
|
-
|
148
|
-
Example identity key, note the hex values are fed as binary buffers to the hash functions and not as a string:
|
149
|
-
|
150
|
-
```
|
151
|
-
sha256(1WffojxvgpQBmUTigoss7VUdfN45JiiRK) = c38bc59316de9783b5f7a8ba19bc5d442f6c9b0988c48a241d1c58a1f4e9ae19
|
152
|
-
|
153
|
-
ripemd160(c38bc59316de9783b5f7a8ba19bc5d442f6c9b0988c48a241d1c58a1f4e9ae19) = afb3dcf52c2c661c35c8ec6a92cecbfc691ba371
|
154
|
-
|
155
|
-
base58(afb3dcf52c2c661c35c8ec6a92cecbfc691ba371) = 3SyWUZXvhidNcEHbAC3HkBnKoD2Q
|
156
|
-
|
157
|
-
identityKey: 3SyWUZXvhidNcEHbAC3HkBnKoD2Q
|
158
|
-
```
|
159
|
-
|
160
|
-
**NOTE:** This has been changed with the release of the BAP library. This allows a verifier to link the root address to the identity key. In the past the identity key was random. Older identites created at random will still work with the BAP library, but new identities should be created in this way.
|
161
|
-
|
162
|
-
To link this identity key to the root address and the signing address, an `ID` transaction is sent to the blockchain:
|
163
|
-
|
164
|
-
```
|
165
|
-
1BAPSuaPnfGnSBM3GLV9yhxUdYe4vGbdMT
|
166
|
-
ID
|
167
|
-
3SyWUZXvhidNcEHbAC3HkBnKoD2Q
|
168
|
-
1K4c6YXR1ixNLAqrL8nx5HUQAPKbACTwDo
|
169
|
-
|
|
170
|
-
15PciHG22SNLQJXMoSUaWVi7WSqc7hCfva
|
171
|
-
BITCOIN_ECDSA
|
172
|
-
1WffojxvgpQBmUTigoss7VUdfN45JiiRK
|
173
|
-
HB6Ye7ekxjKDkblJYL9lX3J2vhY75vl+WfVCq+wW3+y6S7XECkgYwUEVH3WEArRuDb/aVZ8ntLI/D0Yolb1dhD8=
|
174
|
-
```
|
175
|
-
|
176
|
-
The address `1WffojxvgpQBmUTigoss7VUdfN45JiiRK` associated with the first instance of the identity key on-chain, is the identity control address (or rootAddress). This address should no be used anywhere, but can be used to destroy the identity, in case the latest linked key has been compromised.
|
177
|
-
|
178
|
-
When the signing address is rotated to a new key, a new ID transaction is created, this time signed by the previous address:
|
179
|
-
|
180
|
-
```
|
181
|
-
1BAPSuaPnfGnSBM3GLV9yhxUdYe4vGbdMT
|
182
|
-
ID
|
183
|
-
3SyWUZXvhidNcEHbAC3HkBnKoD2Q
|
184
|
-
1JfMQDtBKYi6z65M9uF2gxgLv7E8pPR6MA
|
185
|
-
|
|
186
|
-
15PciHG22SNLQJXMoSUaWVi7WSqc7hCfva
|
187
|
-
BITCOIN_ECDSA
|
188
|
-
1K4c6YXR1ixNLAqrL8nx5HUQAPKbACTwDo
|
189
|
-
HB6Ye7ekxjKDkblJYL9lX3J2vhY75vl+WfVCq+wW3+y6S7XECkgYwUEVH3WEArRuDb/aVZ8ntLI/D0Yolb1dhD8=
|
190
|
-
```
|
191
|
-
|
192
|
-
In this way, we have created a way to rotate the signing keys for a certain identity as often as we want, with each signing key being immutably saved on the blockchain.
|
193
|
-
|
194
|
-
Any signatures done for the identity key should be done using the active key at that time.
|
195
|
-
|
196
|
-
To destroy the identity, an ID transaction is sent to 0, signed with the address from the first ever transaction `1WffojxvgpQBmUTigoss7VUdfN45JiiRK`;
|
197
|
-
|
198
|
-
```
|
199
|
-
1BAPSuaPnfGnSBM3GLV9yhxUdYe4vGbdMT
|
200
|
-
ID
|
201
|
-
3SyWUZXvhidNcEHbAC3HkBnKoD2Q
|
202
|
-
0
|
203
|
-
|
|
204
|
-
15PciHG22SNLQJXMoSUaWVi7WSqc7hCfva
|
205
|
-
BITCOIN_ECDSA
|
206
|
-
1WffojxvgpQBmUTigoss7VUdfN45JiiRK
|
207
|
-
HB6Ye7ekxjKDkblJYL9lX3J2vhY75vl+WfVCq+wW3+y6S7XECkgYwUEVH3WEArRuDb/aVZ8ntLI/D0Yolb1dhD8=
|
208
|
-
```
|
209
|
-
|
210
|
-
# Usage in an identity system (BAP-ID)
|
211
|
-
|
212
|
-
A BAP identity is defined as an identity key that has attested identity attributes, verified by one or more authorities. These authorities are outside the scope of this description, but are not governed or controlled.
|
213
|
-
|
214
|
-
All identity attributes have the following characteristics:
|
215
|
-
|
216
|
-
```
|
217
|
-
urn:bap:id:[Attribute name]:[Attribute value]:[Nonce]
|
218
|
-
```
|
219
|
-
|
220
|
-
Attribute | Description
|
221
|
-
--------- | ----------
|
222
|
-
Attribute name | The name of the attribute being described
|
223
|
-
Attribute value | The value of the attribute being described with the name
|
224
|
-
Nonce | A unique random string to make sure the entropy of hashing the urn will not cause collision and not allow for dictionary attacks
|
225
|
-
|
226
|
-
A user may want to create multiple identities with a varying degree of details available about that identity. Let's take a couple of examples:
|
227
|
-
|
228
|
-
Identity 1 (`3SyWUZXvhidNcEHbAC3HkBnKoD2Q`):
|
229
|
-
```
|
230
|
-
urn:bap:id:name:John Doe:e2c6fb4063cc04af58935737eaffc938011dff546d47b7fbb18ed346f8c4d4fa
|
231
|
-
urn:bap:id:birthday:1990-05-22:e61f23cbbb2284842d77965e2b0e32f0ca890b1894ca4ce652831347ee3596d9
|
232
|
-
urn:bap:id:over18:1:480ca17ccaacd671b28dc811332525f2f2cd594d8e8e7825de515ce5d52d30e8
|
233
|
-
urn:bap:id:address:51391 Moorpark Ave #104, San Jose, CA 95129, United States:44d47d2375c8346c7ceeab1904360aaf572b1c940c1bd66ffd5cf88fdf06bc05
|
234
|
-
urn:bap:id:passportNr:US2343242:9c06a0fb0e2d9cef4928855076255e4df3375e2807cf37bc028ddb282f811ac8
|
235
|
-
urn:bap:id:passportExpiration:2022-02-23:d61a39afb463b42c3e419463a028deb3e9e2cebf67953864e9f9e7869677e7cb
|
236
|
-
```
|
237
|
-
|
238
|
-
Identity 2 (`b71a658ec49a9cb099fd5d3cf0aafce28f1d464fa6e496f61c8048d8ed56edc1`):
|
239
|
-
```
|
240
|
-
urn:bap:id:name:John Doe:6637be9df2e114ce19a287ff48841899ef4a5762a5f9dc47aef62fe4f579bf93
|
241
|
-
urn:bap:id:email:john.doen@example.com:2864fd138ab1e9ddaaea763c77a45898dac64a26229f9f3d0f2280e4bfa915de
|
242
|
-
urn:bap:id:over18:1:5f48f9be1644834933cec74a299d109d18f01e77c9552545d2eae4d0c929000b
|
243
|
-
```
|
244
|
-
|
245
|
-
Identity 3 (`10ef2b1bb05185d0dbae41e1bfefe0c2deb2d389f38fe56daa2cc28a9ba82fc7`):
|
246
|
-
```
|
247
|
-
urn:bap:id:alternateName:Johnny:7a8d693bce6b6c1cf1dd81468a52b69829e465ff9b0762cf77965309df3ad4c8
|
248
|
-
```
|
249
|
-
|
250
|
-
NOTE: The random nonce should not be re-used across identities. Always create a new random secret for each attribute.
|
251
|
-
|
252
|
-
## Attesting (ATTEST)
|
253
|
-
|
254
|
-
Anyone can attest for any identity by broadcasting a bitcoin transaction with a signature from their private key of the attributes of the identity.
|
255
|
-
|
256
|
-
All attestations have the following characteristics:
|
257
|
-
|
258
|
-
```
|
259
|
-
urn:bap:attest:[Attribute hash]:[Identity key]
|
260
|
-
```
|
261
|
-
|
262
|
-
Attribute | Description
|
263
|
-
--------- | ----------
|
264
|
-
Attribute hash | A hash of the urn attribute being attested
|
265
|
-
Identity key | The unique identity key of the owner of the attestation
|
266
|
-
|
267
|
-
Take for example a bank, Banco De Bitcoin, with a known and trusted identity key of `ezY2h8B5sj7SHGw8i1KhHtRvgM5` which is linked via an `ID` transaction to `1K4c6YXR1ixNLAqrL8nx5HUQAPKbACTwDo`. To attest that the bank has seen the information in the identity attribute and that it is correct, the bank would sign an attestation with the identity information together with the given identity key.
|
268
|
-
|
269
|
-
```
|
270
|
-
1BAPSuaPnfGnSBM3GLV9yhxUdYe4vGbdMT
|
271
|
-
ATTEST
|
272
|
-
[Attestation hash]
|
273
|
-
[Sequence]
|
274
|
-
|
|
275
|
-
15PciHG22SNLQJXMoSUaWVi7WSqc7hCfva
|
276
|
-
[Signature algorithm]
|
277
|
-
[Address of signer]
|
278
|
-
[Signature]
|
279
|
-
```
|
280
|
-
|
281
|
-
For the name urn for the Identity 1 (`3SyWUZXvhidNcEHbAC3HkBnKoD2Q`) in above example:
|
282
|
-
|
283
|
-
- We take the hash of `urn:bap:id:name:John Doe:e2c6fb4063cc04af58935737eaffc938011dff546d47b7fbb18ed346f8c4d4fa` = `b17c8e606afcf0d8dca65bdf8f33d275239438116557980203c82b0fae259838`
|
284
|
-
- Then create an attestation urn for the address: `urn:bap:id:attest:b17c8e606afcf0d8dca65bdf8f33d275239438116557980203c82b0fae259838:3SyWUZXvhidNcEHbAC3HkBnKoD2Q`
|
285
|
-
- Then hash the attestation for our transaction: `89cd658c0ce3ff62db4270a317c35f8a7dfe1242e2cc94232aa3947d77f82431`
|
286
|
-
- Then the attestation is signed with the private key belonging to the trusted authority (with address `1K4c6YXR1ixNLAqrL8nx5HUQAPKbACTwDo`);
|
287
|
-
|
288
|
-
```
|
289
|
-
1BAPSuaPnfGnSBM3GLV9yhxUdYe4vGbdMT
|
290
|
-
ATTEST
|
291
|
-
89cd658c0ce3ff62db4270a317c35f8a7dfe1242e2cc94232aa3947d77f82431
|
292
|
-
0
|
293
|
-
|
|
294
|
-
15PciHG22SNLQJXMoSUaWVi7WSqc7hCfva
|
295
|
-
BITCOIN_ECDSA
|
296
|
-
1K4c6YXR1ixNLAqrL8nx5HUQAPKbACTwDo
|
297
|
-
HB6Ye7ekxjKDkblJYL9lX3J2vhY75vl+WfVCq+wW3+y6S7XECkgYwUEVH3WEArRuDb/aVZ8ntLI/D0Yolb1dhD8=
|
298
|
-
```
|
299
|
-
|
300
|
-
Since the hash of our attestation is always the same, any authority attesting the identity attribute will broadcast a transaction where the 3rd item is the same. In this way it is possible to search (using for instance Planaria) through the blockchain for all attestations of the identity attribute and select the one most trusted.
|
301
|
-
|
302
|
-
## Verifying an identity attribute
|
303
|
-
|
304
|
-
For a user to prove their identity, that has been verified by a trusted authority, the user does the following.
|
305
|
-
|
306
|
-
He shares his identity key `3SyWUZXvhidNcEHbAC3HkBnKoD2Q`, the full urn `urn:bap:id:name:John Doe:e2c6fb4063cc04af58935737eaffc938011dff546d47b7fbb18ed346f8c4d4fa` and signs a challenge message from the party that request an identity verification.
|
307
|
-
|
308
|
-
The receiving party can now verify:
|
309
|
-
- That the user is the owner of the address `1JfMQDtBKYi6z65M9uF2gxgLv7E8pPR6MA` by verifying the signature
|
310
|
-
- That the identity `3SyWUZXvhidNcEHbAC3HkBnKoD2Q` is linked to the address via an `ID` record
|
311
|
-
- That the attestation urn has been signed by that latest valid address of Banco De Bitcoin.
|
312
|
-
- Thereby verifying that the user signing the message has been attested by the bank to have the name `John Doe`.
|
313
|
-
|
314
|
-
NOTE: No unneeded sensitive information has been shared and it is not possible to infer any other information from the information sent. The only thing the receiver now knows is that the person doing the signing is called John Doe.
|
315
|
-
|
316
|
-
## Delegating signing to another identity
|
317
|
-
|
318
|
-
With BAP, it is very easy to create an infinite number of identities for a user. This is even encouraged to preserve privacy.
|
319
|
-
|
320
|
-
When for instance a KYC check is done, this check is done for a certain identity. Replicating this KYC check for all identities for a user, to be able to use in all access applications, is impractical. To solve this we must be able to link, or delegate, from one identity to another.
|
321
|
-
|
322
|
-
`urn:bap:delegate:<from idKey>:<to IdKey>:<Nonce>`
|
323
|
-
|
324
|
-
Example:
|
325
|
-
```
|
326
|
-
var attestation = 'urn:bap:delegate:3SyWUZXvhidNcEHbAC3HkBnKoD2Q:341d782c56a588ccdd3ebb181d1dbb4699bdb5fb9956b7bd07e917d955acdb04:7f2fe5aac07e2d4c43bdb232029ed157acf0272eac94a2f75cc17566c01a5e89';
|
327
|
-
var attestationHash = sha256(attestation); // 2dbb381888f973a0db3bf311e551a6ac2f3ab792420262d8a6f65ef4feb8c1ef
|
328
|
-
```
|
329
|
-
|
330
|
-
This links, or delegates, from identity `3SyWUZXvhidNcEHbAC3HkBnKoD2Q` to identity `341d782c56a588ccdd3ebb181d1dbb4699bdb5fb9956b7bd07e917d955acdb04`;
|
331
|
-
|
332
|
-
The attestation can be published to the blockchain, signed by the identity `3SyWUZXvhidNcEHbAC3HkBnKoD2Q`;
|
333
|
-
|
334
|
-
```
|
335
|
-
1BAPSuaPnfGnSBM3GLV9yhxUdYe4vGbdMT
|
336
|
-
ATTEST
|
337
|
-
2dbb381888f973a0db3bf311e551a6ac2f3ab792420262d8a6f65ef4feb8c1ef
|
338
|
-
0
|
339
|
-
|
|
340
|
-
15PciHG22SNLQJXMoSUaWVi7WSqc7hCfva
|
341
|
-
BITCOIN_ECDSA
|
342
|
-
1JfMQDtBKYi6z65M9uF2gxgLv7E8pPR6MA
|
343
|
-
HB6Ye7ekxjKDkblJYL9lX3J2vhY75vl+WfVCq+wW3+y6S7XECkgYwUEVH3WEArRuDb/aVZ8ntLI/D0Yolb1dhD8=
|
344
|
-
```
|
345
|
-
|
346
|
-
Showing that it is possible to use the verified attributes from `3SyWUZXvhidNcEHbAC3HkBnKoD2Q` in identity `341d782c56a588ccdd3ebb181d1dbb4699bdb5fb9956b7bd07e917d955acdb04` can now be done by sharing the delegation. The delegation attestation will be available to check on-chain.
|
347
|
-
|
348
|
-
The challenge sent by the application requesting the attributes should be signed by **both (!)** identites, to proof access to the private keys of both identities.
|
349
|
-
|
350
|
-
NOTE: The grant published on-chain for the attributes shared must be signed by the delegating identity `3SyWUZXvhidNcEHbAC3HkBnKoD2Q`, and not `341d782c56a588ccdd3ebb181d1dbb4699bdb5fb9956b7bd07e917d955acdb04`;
|
351
|
-
|
352
|
-
NOTE: The receiving end should store both identity keys to be able to proof they have received access to the data of the user. The could be stored as a concatenation of the two identity strings: `341d782c56a588ccdd3ebb181d1dbb4699bdb5fb9956b7bd07e917d955acdb04<-3SyWUZXvhidNcEHbAC3HkBnKoD2Q`;
|
353
|
-
|
354
|
-
NOTE: The main identity, for which a KYC has been done, should never directly be used in any application. A new identity should be created for each and every application accessed.
|
355
|
-
|
356
|
-
## Publishing Identity information (ALIAS)
|
357
|
-
|
358
|
-
It is possible to publish information about an identity by using the BAP ALIAS keyword. This tells the world that an identity key should be seen as belonging to the entity published in the alias.
|
3
|
+
> Sovereign digital identity on the Bitcoin blockchain
|
359
4
|
|
360
|
-
|
5
|
+
[](https://badge.fury.io/js/bsv-bap)
|
6
|
+
[](LICENSE)
|
361
7
|
|
362
|
-
|
363
|
-
```
|
364
|
-
1BAPSuaPnfGnSBM3GLV9yhxUdYe4vGbdMT
|
365
|
-
ALIAS
|
366
|
-
3SyWUZXvhidNcEHbAC3HkBnKoD2Q
|
367
|
-
{"@type":"Organization","name":"Banco De Bitcoin","address":{"@type":"PostalAddress","addressLocality":"Mexico Beach","addressRegion":"FL","streetAddress":"3102 Highway 98"},"url":https://bancodebitcoin.com","logo":{"@type":"ImageObject","contentUrl":"data:image/png;base64,..."}
|
368
|
-
|
|
369
|
-
15PciHG22SNLQJXMoSUaWVi7WSqc7hCfva
|
370
|
-
BITCOIN_ECDSA
|
371
|
-
1K4c6YXR1ixNLAqrL8nx5HUQAPKbACTwDo
|
372
|
-
HB6Ye7ekxjKDkblJYL9lX3J2vhY75vl+WfVCq+wW3+y6S7XECkgYwUEVH3WEArRuDb/aVZ8ntLI/D0Yolb1dhD8=
|
373
|
-
```
|
374
|
-
|
375
|
-
Organizations are encouraged to use attributes defined at https://schema.org/Organization when using the ALIAS keyword.
|
376
|
-
|
377
|
-
## BAP uniKey
|
378
|
-
|
379
|
-
The BAP uniKey is a unique hash of identity attributes of a person to create a uniquely identifiable hash to use across services. The uniKey can also be used in a custodial identity service where the only thing shared with a service is the uniKey and the uniKey expiration. The real identity can be looked up at the custodial service.
|
380
|
-
|
381
|
-
The BAP uniKey is defined as follows:
|
382
|
-
```
|
383
|
-
privateUniKey := sha256(
|
384
|
-
fullName
|
385
|
-
nationality
|
386
|
-
birthDate
|
387
|
-
socialSecurityNr
|
388
|
-
passportNr
|
389
|
-
passportExpirationDate
|
390
|
-
base64(passport image)
|
391
|
-
)
|
392
|
-
uniKey := sha256(privateUniKey)
|
393
|
-
```
|
394
|
-
The privateUniKey should only be defined based on a digital (NFC) passport that supports all the attributes mentioned. Adding the base64 data of the image on the passport is especially important to create enough entropy for the hashing function to safe guard against dictionary attacks. The uniKey is a hash of the privateUniKey.
|
395
|
-
|
396
|
-
The privateUniKey should __never__ be shared. The uniKey should only be shared in situations where the user would normally share all his personal info (KYC check).
|
397
|
-
|
398
|
-
The `uniKeyExpirationDate` is equal to the `passportExpirationDate`.
|
399
|
-
|
400
|
-
Example:
|
401
|
-
```
|
402
|
-
privateUniKey = "27dacfd5d0eefd927263a502bd2dea7b9b6193ba7f8bf98c2f4855b45e7d0008";
|
403
|
-
uniKey = "dce3ba1199b74d74a5fb941f92ed7e6adb97acc4dffdb055cf6867162dc8fa74";
|
404
|
-
|
405
|
-
urn:bap:id:uniKey:dce3ba1199b74d74a5fb941f92ed7e6adb97acc4dffdb055cf6867162dc8fa74:c490de4c40fecd9fa7c3979b9134d0a419fa77388d1535b48a24cdb69425b5d5
|
406
|
-
|
407
|
-
hash = "bc47cdfc44cc89519dca5f12bc10c53492c57090a012d2540257bf02772f82a5";
|
408
|
-
```
|
409
|
-
`c490de4c40...` is just a random nonce to increase entropy.
|
410
|
-
```
|
411
|
-
uniKeyExpirationDate = "2025-04-20";
|
412
|
-
|
413
|
-
urn:bap:id:uniKeyExpirationDate:2025-04-20:dce3ba1199b74d74a5fb941f92ed7e6adb97acc4dffdb055cf6867162dc8fa74
|
414
|
-
|
415
|
-
hash = "a67e363c4163b49f81529b8b5118670ffbf6d76e2b47a03a01e6e21805388f7f";
|
416
|
-
```
|
417
|
-
The urn of the uniKeyExpirationDate should use the uniKey as the nonce. This links them together and makes it verifiable for third parties.
|
418
|
-
|
419
|
-
# Publishing data
|
420
|
-
|
421
|
-
The BAP protocol defines a way to publish data on-chain, optionally in a way that only the sender and receiver can read the data.
|
422
|
-
|
423
|
-
The data can be encrypted using the ECIES encryption scheme (specifically electrum-ecies, https://www.npmjs.com/package/electrum-ecies).
|
424
|
-
|
425
|
-
```
|
426
|
-
1BAPSuaPnfGnSBM3GLV9yhxUdYe4vGbdMT
|
427
|
-
DATA
|
428
|
-
[Attestation hash]
|
429
|
-
[[Optionally ECIES encrypted] data]
|
430
|
-
|
|
431
|
-
15PciHG22SNLQJXMoSUaWVi7WSqc7hCfva
|
432
|
-
[Signature algorithm]
|
433
|
-
[Address of signer]
|
434
|
-
[Signature]
|
435
|
-
```
|
436
|
-
|
437
|
-
Example:
|
438
|
-
```
|
439
|
-
1BAPSuaPnfGnSBM3GLV9yhxUdYe4vGbdMT
|
440
|
-
DATA
|
441
|
-
2dbb381888f973a0db3bf311e551a6ac2f3ab792420262d8a6f65ef4feb8c1ef
|
442
|
-
QklFMQMFmPdvjFe8Wfo+JWmTpo+33LXc+4G8ThfaucU72kieb6lWEv4layTb0x5tzpi6lA2it8rO/ELrXomJqC53uBOd+DZSzDhCSpK6SwR+Itt+Pw==
|
443
|
-
|
|
444
|
-
15PciHG22SNLQJXMoSUaWVi7WSqc7hCfva
|
445
|
-
BITCOIN_ECDSA
|
446
|
-
1WffojxvgpQBmUTigoss7VUdfN45JiiRK
|
447
|
-
HB6Ye7ekxjKDkblJYL9lX3J2vhY75vl+WfVCq+wW3+y6S7XECkgYwUEVH3WEArRuDb/aVZ8ntLI/D0Yolb1dhD8=
|
448
|
-
```
|
449
|
-
When adding data like this to an attestation, the identity of the signing party should match the identity of the attestation, otherwise the data should be ignored.
|
450
|
-
|
451
|
-
Or as a part of an attestation transaction:
|
452
|
-
```
|
453
|
-
1BAPSuaPnfGnSBM3GLV9yhxUdYe4vGbdMT
|
454
|
-
ATTEST
|
455
|
-
5e991865273588e8be0b834b013b7b3b7e4ff2c7517c9fcdf77da84502cebef1
|
456
|
-
0
|
457
|
-
|
|
458
|
-
1BAPSuaPnfGnSBM3GLV9yhxUdYe4vGbdMT
|
459
|
-
DATA
|
460
|
-
5e991865273588e8be0b834b013b7b3b7e4ff2c7517c9fcdf77da84502cebef1
|
461
|
-
QklFMQMFmPdvjFe8Wfo+JWmTpo+33LXc+4G8ThfaucU72kieb6lWEv4layTb0x5tzpi6lA2it8rO/ELrXomJqC53uBOd+DZSzDhCSpK6SwR+Itt+Pw==
|
462
|
-
|
|
463
|
-
15PciHG22SNLQJXMoSUaWVi7WSqc7hCfva
|
464
|
-
BITCOIN_ECDSA
|
465
|
-
1K4c6YXR1ixNLAqrL8nx5HUQAPKbACTwDo
|
466
|
-
HB6Ye7ekxjKDkblJYL9lX3J2vhY75vl+WfVCq+wW3+y6S7XECkgYwUEVH3WEArRuDb/aVZ8ntLI/D0Yolb1dhD8=
|
467
|
-
```
|
468
|
-
|
469
|
-
This can be used to append data to an attestation, for instance to add context to the attestation for a UI of an application.
|
470
|
-
|
471
|
-
For maximum compatibility with ECIES, the data should be encrypted using the private key of the attester and the public key of the owner of the identity for which the attestation is being done (Traditional 2 keys ECIES, https://www.npmjs.com/package/electrum-ecies#traditional-2-keys-ecies).
|
472
|
-
|
473
|
-
# Using as a Power of Attorney
|
474
|
-
|
475
|
-
All users that have an identity and an address registered, should be able to, for instance, give another user temporary rights to sign on their behalf. A Power of Attorney could be defined with the BAP protocol in the following way.
|
476
|
-
All users that have an identity and an address registered, should be able to, for instance, give another user temporary rights to sign on their behalf. A Power of Attorney could be defined with the BAP protocol in the following way.
|
477
|
-
|
478
|
-
(A power of attorney of this kind is only valid in the real world, but does not allow anyone else to sign anything on-chain)
|
479
|
-
|
480
|
-
The Power of Attorney would have the following characteristics:
|
481
|
-
|
482
|
-
```
|
483
|
-
urn:bap:poa:[PoA Attribute]:[Address]:[Nonce]
|
484
|
-
```
|
485
|
-
Attribute | Description
|
486
|
-
--------- | ----------
|
487
|
-
PoA Attribute | Power of Attorney attribute being handed over to the person with the identity associates with Address
|
488
|
-
Address | The bitcoin address of the person (or organisation) being handed the PoA
|
489
|
-
Nonce | A unique random string to make sure the entropy of hashing the urn will not cause collision and not allow for dictionary attacks
|
490
|
-
|
491
|
-
PoA attributes:
|
492
|
-
|
493
|
-
Attribute | Description
|
494
|
-
--------- | ----------
|
495
|
-
real-estate | To buy, sell, rent, or otherwise manage residential, commercial, and personal real estate
|
496
|
-
business | To invest, trade, and manage any and all business transactions and decisions, as well as handle any claim or litigation matters
|
497
|
-
finance | To control banking, tax, and government and retirement transactions, as well as living trust and estate decisions
|
498
|
-
family | To purchase gifts, employ professionals, and to buy, sell or trade any of your personal property
|
499
|
-
general | This grants the authority to make any decisions that you would be able to if you were personally present
|
500
|
-
|
501
|
-
Example, give the bank the Power of Attorney over finances:
|
502
|
-
|
503
|
-
For the Identity 1 (`3SyWUZXvhidNcEHbAC3HkBnKoD2Q`) given PoA to the bank `ezY2h8B5sj7SHGw8i1KhHtRvgM5`:
|
504
|
-
|
505
|
-
- We take the hash of `urn:bap:poa:finance:3SyWUZXvhidNcEHbAC3HkBnKoD2Q:ef4ef3b8847cf9533cc044dc032269f80ecf6fcbefbd4d6ac81dddc0124f50e7`
|
506
|
-
- Then hash the poa for the transaction: `77cdec21e1025f85a5cb3744d5515c54783c739b8fa7c72c9e24d83900261d7f`
|
507
|
-
- Then the poa is signed with the private key belonging to the identity handing over the PoA (with address `1JfMQDtBKYi6z65M9uF2gxgLv7E8pPR6MA`);
|
508
|
-
|
509
|
-
```
|
510
|
-
1BAPSuaPnfGnSBM3GLV9yhxUdYe4vGbdMT
|
511
|
-
ATTEST
|
512
|
-
77cdec21e1025f85a5cb3744d5515c54783c739b8fa7c72c9e24d83900261d7f
|
513
|
-
0
|
514
|
-
|
|
515
|
-
15PciHG22SNLQJXMoSUaWVi7WSqc7hCfva
|
516
|
-
BITCOIN_ECDSA
|
517
|
-
1JfMQDtBKYi6z65M9uF2gxgLv7E8pPR6MA
|
518
|
-
HB6Ye7ekxjKDkblJYL9lX3J2vhY75vl+WfVCq+wW3+y6S7XECkgYwUEVH3WEArRuDb/aVZ8ntLI/D0Yolb1dhD8=
|
519
|
-
```
|
520
|
-
|
521
|
-
The bank will save the urn and can prove that the PoA is still valid on the blockchain.
|
522
|
-
|
523
|
-
The user can always revoke the PoA with a REVOKE transaction.
|
524
|
-
|
525
|
-
# Blacklisting
|
526
|
-
|
527
|
-
With more and more data being posted to the bitcoin blockchain it becomes ever more important to be able to block data from being viewed on sites offering that service. Especially illegal data needs to be filtered from viewing to prevent liability claims.
|
528
|
-
|
529
|
-
A proposed format for blacklisting any type of data could have the following format:
|
530
|
-
```
|
531
|
-
urn:bap:blacklist:[type]:[attribute]:[key]
|
532
|
-
```
|
533
|
-
|
534
|
-
## Blacklisting transactions / addresses
|
535
|
-
|
536
|
-
Using the blacklisting format, a transaction ID blacklist would be of the following format for a transaction ID:
|
537
|
-
```
|
538
|
-
urn:bap:blacklist:bitcoin:tx-id:[Transaction ID]
|
539
|
-
```
|
540
|
-
|
541
|
-
Example, blacklisting transaction ID `9e4b52ca8abe317d246ae2e742898df0956eaf1cc8df7c02154d20c1f55f3f9b`:
|
542
|
-
```
|
543
|
-
urn:bap:blacklist:bitcoin:tx-id:9e4b52ca8abe317d246ae2e742898df0956eaf1cc8df7c02154d20c1f55f3f9b
|
544
|
-
```
|
8
|
+
## Abstract
|
545
9
|
|
546
|
-
The
|
10
|
+
The Bitcoin Attestation Protocol (BAP) establishes a cryptographic system for creating, managing, and verifying digital identities directly on the Bitcoin blockchain. By treating Bitcoin keypairs as the fundamental identity primitive, BAP eliminates traditional authentication intermediaries while providing mathematical guarantees of identity ownership, attestation validity, and data sovereignty.
|
547
11
|
|
548
|
-
|
549
|
-
```
|
550
|
-
1BAPSuaPnfGnSBM3GLV9yhxUdYe4vGbdMT
|
551
|
-
ATTEST
|
552
|
-
8a6bc20369171516fb9155a10f11caff8a51dbd8ae90c5bf3443fc4c83bdc8e8
|
553
|
-
0
|
554
|
-
|
|
555
|
-
15PciHG22SNLQJXMoSUaWVi7WSqc7hCfva
|
556
|
-
BITCOIN_ECDSA
|
557
|
-
1JfMQDtBKYi6z65M9uF2gxgLv7E8pPR6MA
|
558
|
-
HB6Ye7ekxjKDkblJYL9lX3J2vhY75vl+WfVCq+wW3+y6S7XECkgYwUEVH3WEArRuDb/aVZ8ntLI/D0Yolb1dhD8=
|
559
|
-
```
|
12
|
+
## Motivation
|
560
13
|
|
561
|
-
|
14
|
+
Current digital identity systems suffer from three critical failures:
|
562
15
|
|
563
|
-
|
16
|
+
1. **Centralized Control**: Identity providers act as gatekeepers, capable of suspending, deleting, or modifying user identities at will. Users possess accounts, not identities.
|
564
17
|
|
565
|
-
|
566
|
-
```
|
567
|
-
urn:bap:blacklist:bitcoin:address:[Address]
|
568
|
-
```
|
569
|
-
Example:
|
570
|
-
```
|
571
|
-
urn:bap:blacklist:bitcoin:address:1JfMQDtBKYi6z65M9uF2gxgLv7E8pPR6MA
|
572
|
-
```
|
18
|
+
2. **Platform Fragmentation**: Each service maintains isolated identity silos, forcing users to recreate their digital presence repeatedly across platforms. Reputation, relationships, and verified attributes cannot move between systems.
|
573
19
|
|
574
|
-
|
20
|
+
3. **Trust Without Verification**: Traditional systems require blind trust in institutions to maintain identity records accurately and permanently. No mathematical proof exists that your identity data remains unaltered or accessible.
|
575
21
|
|
576
|
-
|
22
|
+
BAP resolves these failures by recognizing a simple axiom: **a cryptographic keypair IS an identity**. This principle, combined with Bitcoin's immutable ledger, creates a system where:
|
577
23
|
|
578
|
-
|
24
|
+
- Identity ownership is cryptographically provable
|
25
|
+
- Attestations form an auditable chain of trust
|
26
|
+
- Data persistence requires no institutional faith
|
27
|
+
- Interoperability emerges from shared protocols, not corporate agreements
|
579
28
|
|
580
|
-
|
581
|
-
```
|
582
|
-
urn:bap:blacklist:ip-address:[IP Address]:[ID key]
|
583
|
-
```
|
29
|
+
## Core Principles
|
584
30
|
|
585
|
-
|
31
|
+
### Identity as Mathematics
|
586
32
|
|
587
|
-
|
588
|
-
```
|
589
|
-
urn:bap:blacklist:ip-address:1.1.1.1:3SyWUZXvhidNcEHbAC3HkBnKoD2Q
|
590
|
-
```
|
33
|
+
In BAP, identity is not assigned but derived. Your identity emerges from the mathematical relationship between private and public keys:
|
591
34
|
|
592
|
-
The hash of this blacklisting is: `73df789478993f8f4e100be416811860d6fc2ae208fdfaf256788cd522f21219`
|
593
|
-
|
594
|
-
The attestation looks like:
|
595
35
|
```
|
596
|
-
|
597
|
-
ATTEST
|
598
|
-
73df789478993f8f4e100be416811860d6fc2ae208fdfaf256788cd522f21219
|
599
|
-
0
|
600
|
-
|
|
601
|
-
15PciHG22SNLQJXMoSUaWVi7WSqc7hCfva
|
602
|
-
BITCOIN_ECDSA
|
603
|
-
1JfMQDtBKYi6z65M9uF2gxgLv7E8pPR6MA
|
604
|
-
HB6Ye7ekxjKDkblJYL9lX3J2vhY75vl+WfVCq+wW3+y6S7XECkgYwUEVH3WEArRuDb/aVZ8ntLI/D0Yolb1dhD8=
|
36
|
+
IdentityKey = base58(ripemd160(sha256(rootAddress)))
|
605
37
|
```
|
606
38
|
|
607
|
-
|
608
|
-
|
609
|
-
## Final note on blacklisting
|
610
|
-
|
611
|
-
Using attestations for blacklists is a good way of creating one-way blacklists. It's easy to lookup whether some service has blacklisted something (transaction, address, IP address), but it is very hard to create a list of all things a service has blacklisted.
|
39
|
+
This deterministic derivation means identity recovery requires only the original key material - no database lookups, no account recovery flows, no customer service.
|
612
40
|
|
613
|
-
|
41
|
+
### Attestations as Proofs
|
614
42
|
|
615
|
-
|
43
|
+
Trust in BAP is not declared but proven. When an entity attests to an identity attribute, they create a cryptographic proof:
|
616
44
|
|
617
|
-
BAP can also be used for simple assertions of any type of data or action.
|
618
|
-
|
619
|
-
Example:
|
620
|
-
```
|
621
|
-
urn:bap:assert:[Some assertion you want to make]:[nonce]
|
622
|
-
```
|
623
|
-
|
624
|
-
Example, asserting ownership of a file:
|
625
45
|
```
|
626
|
-
|
46
|
+
Attestation = Sign(SHA256(attribute + identityKey), attestorKey)
|
627
47
|
```
|
628
|
-
This has a hash of `e4d1c8868d143cb8eaf240c0191c19e513a4f58a8eb8243af00b5626fe2eb764`.
|
629
48
|
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
e4d1c8868d143cb8eaf240c0191c19e513a4f58a8eb8243af00b5626fe2eb764
|
635
|
-
0
|
636
|
-
|
|
637
|
-
15PciHG22SNLQJXMoSUaWVi7WSqc7hCfva
|
638
|
-
BITCOIN_ECDSA
|
639
|
-
1K4c6YXR1ixNLAqrL8nx5HUQAPKbACTwDo
|
640
|
-
HB6Ye7ekxjKDkblJYL9lX3J2vhY75vl+WfVCq+wW3+y6S7XECkgYwUEVH3WEArRuDb/aVZ8ntLI/D0Yolb1dhD8=
|
641
|
-
```
|
49
|
+
These proofs are:
|
50
|
+
- **Independently verifiable**: Any party can validate without contacting the attestor
|
51
|
+
- **Temporally fixed**: The blockchain timestamp prevents backdating
|
52
|
+
- **Publicly auditable**: Anyone can examine an entity's attestation history
|
642
53
|
|
643
|
-
|
54
|
+
### Sovereignty Through Cryptography
|
644
55
|
|
645
|
-
|
646
|
-
|
647
|
-
A possible way to do this, using BAP:
|
648
|
-
```
|
649
|
-
urn:bap:grant:[Attribute names]:[Identity key]
|
650
|
-
```
|
651
|
-
|
652
|
-
Example, for a service with identity key `ezY2h8B5sj7SHGw8i1KhHtRvgM5`:
|
653
|
-
```
|
654
|
-
urn:bap:grant:name,email,alternateName:ezY2h8B5sj7SHGw8i1KhHtRvgM5
|
655
|
-
```
|
656
|
-
This has a hash of `b88bd23005be7e0737f02e67de8b392df834ba27caed1e7774aec77c9dcb85d0`.
|
657
|
-
|
658
|
-
The user then needs to attest to this on-chain:
|
659
|
-
```
|
660
|
-
1BAPSuaPnfGnSBM3GLV9yhxUdYe4vGbdMT
|
661
|
-
ATTEST
|
662
|
-
b88bd23005be7e0737f02e67de8b392df834ba27caed1e7774aec77c9dcb85d0
|
663
|
-
0
|
664
|
-
|
|
665
|
-
15PciHG22SNLQJXMoSUaWVi7WSqc7hCfva
|
666
|
-
BITCOIN_ECDSA
|
667
|
-
1K4c6YXR1ixNLAqrL8nx5HUQAPKbACTwDo
|
668
|
-
HB6Ye7ekxjKDkblJYL9lX3J2vhY75vl+WfVCq+wW3+y6S7XECkgYwUEVH3WEArRuDb/aVZ8ntLI/D0Yolb1dhD8=
|
669
|
-
```
|
56
|
+
BAP implements true data sovereignty through:
|
670
57
|
|
671
|
-
|
58
|
+
1. **Key Rotation**: Identity owners can update signing keys while maintaining identity continuity
|
59
|
+
2. **Selective Disclosure**: Share only specific attributes with cryptographic proof of the whole
|
60
|
+
3. **Encrypted Storage**: Sensitive data remains encrypted, with decryption controlled by identity owner
|
672
61
|
|
673
|
-
|
62
|
+
## Technical Architecture
|
674
63
|
|
675
|
-
|
64
|
+
### Protocol Structure
|
676
65
|
|
677
|
-
|
66
|
+
BAP transactions follow a deterministic format:
|
678
67
|
|
679
68
|
```
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
|
685
|
-
|
686
|
-
BITCOIN_ECDSA
|
687
|
-
1JfMQDtBKYi6z65M9uF2gxgLv7E8pPR6MA
|
688
|
-
HB6Ye7ekxjKDkblJYL9lX3J2vhY75vl+WfVCq+wW3+y6S7XECkgYwUEVH3WEArRuDb/aVZ8ntLI/D0Yolb1dhD8=
|
69
|
+
OP_RETURN
|
70
|
+
1BAPSuaPnfGnSBM3GLV9yhxUdYe4vGbdMT # Protocol prefix
|
71
|
+
[ACTION] # ID | ATTEST | ALIAS | DATA | REVOKE
|
72
|
+
[DATA] # Action-specific payload
|
73
|
+
| # Separator
|
74
|
+
[AIP_SIGNATURE] # Author Identity Protocol signature
|
689
75
|
```
|
690
76
|
|
691
|
-
|
77
|
+
### Identity Lifecycle
|
692
78
|
|
693
|
-
|
79
|
+
1. **Genesis**: Create identity by deriving key from root address
|
80
|
+
2. **Attestation**: Build trust through cryptographic attestations
|
81
|
+
3. **Rotation**: Update signing keys while preserving identity chain
|
82
|
+
4. **Revocation**: Cryptographically invalidate compromised keys
|
694
83
|
|
695
|
-
|
84
|
+
### Cryptographic Operations
|
696
85
|
|
697
|
-
|
86
|
+
Each identity possesses distinct keys for different operations:
|
698
87
|
|
699
|
-
|
88
|
+
- **Signing Key**: Transaction authorization and message signing
|
89
|
+
- **Encryption Key**: ECIES encryption for private data exchange
|
90
|
+
- **Derivation Path**: Hierarchical key generation for sub-identities
|
700
91
|
|
701
|
-
##
|
92
|
+
## Implementation
|
702
93
|
|
703
|
-
|
94
|
+
### Installation
|
704
95
|
|
96
|
+
```bash
|
97
|
+
npm install bsv-bap
|
705
98
|
```
|
706
|
-
1BAPSuaPnfGnSBM3GLV9yhxUdYe4vGbdMT
|
707
|
-
ID
|
708
|
-
3SyWUZXvhidNcEHbAC3HkBnKoD2Q
|
709
|
-
1KJ8vx8adZeznoDfoGf632rNkzxK2ZwzSG
|
710
|
-
|
|
711
|
-
15PciHG22SNLQJXMoSUaWVi7WSqc7hCfva
|
712
|
-
BITCOIN_ECDSA
|
713
|
-
1WffojxvgpQBmUTigoss7VUdfN45JiiRK
|
714
|
-
HB6Ye7ekxjKDkblJYL9lX3J2vhY75vl+WfVCq+wW3+y6S7XECkgYwUEVH3WEArRuDb/aVZ8ntLI/D0Yolb1dhD8=
|
715
|
-
```
|
716
|
-
|
717
|
-
Would then look more like this:
|
718
99
|
|
719
|
-
|
720
|
-
Input:
|
721
|
-
<𝑆𝑖𝑔 𝑃𝑝𝑎𝑟𝑒𝑛𝑡> <𝑃𝑝𝑎𝑟𝑒𝑛𝑡>
|
100
|
+
### Basic Usage
|
722
101
|
|
723
|
-
|
724
|
-
|
725
|
-
|
102
|
+
```javascript
|
103
|
+
import { BAP } from 'bsv-bap';
|
104
|
+
import { PrivateKey } from '@bsv/sdk';
|
726
105
|
|
727
|
-
|
106
|
+
// Initialize with Type 42 derivation (recommended)
|
107
|
+
const rootKey = PrivateKey.fromRandom();
|
108
|
+
const bap = new BAP({
|
109
|
+
rootPk: rootKey.toWif()
|
110
|
+
});
|
728
111
|
|
729
|
-
|
112
|
+
// Create identity with meaningful name
|
113
|
+
const identity = bap.newId('Professional Identity');
|
114
|
+
identity.setAttribute('name', 'Satoshi Nakamoto');
|
730
115
|
|
731
|
-
|
732
|
-
|
733
|
-
<𝑆𝑖𝑔 𝑃𝑝𝑎𝑟𝑒𝑛𝑡> <𝑃𝑝𝑎𝑟𝑒𝑛𝑡>
|
116
|
+
// Generate ID transaction for blockchain
|
117
|
+
const idTransaction = identity.getInitialIdTransaction();
|
734
118
|
|
735
|
-
|
736
|
-
|
119
|
+
// Create attestation hash for verification
|
120
|
+
const attestationHash = identity.getAttestationHash('name');
|
737
121
|
```
|
738
122
|
|
739
|
-
|
123
|
+
### Identity Discovery
|
740
124
|
|
741
|
-
|
125
|
+
Type 42 identities use sequential counters (`bap:0`, `bap:1`, etc.) for deterministic recovery. This enables identity discovery when restoring from partial backups:
|
742
126
|
|
743
|
-
```
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
127
|
+
```javascript
|
128
|
+
// Discover identities by checking sequential counters
|
129
|
+
async function discoverIdentities(bap, checkExistsOnChain) {
|
130
|
+
const found = [];
|
131
|
+
|
132
|
+
for (let i = 0; i < 100; i++) { // Check first 100 slots
|
133
|
+
const identity = bap.newIdWithCounter(i, `Discovered Identity ${i}`);
|
134
|
+
|
135
|
+
if (await checkExistsOnChain(identity.getIdentityKey())) {
|
136
|
+
found.push(identity);
|
137
|
+
}
|
138
|
+
}
|
139
|
+
|
140
|
+
return found;
|
141
|
+
}
|
749
142
|
```
|
750
143
|
|
751
|
-
|
144
|
+
### Deprecation Notice
|
752
145
|
|
753
|
-
|
146
|
+
The BIP32 initialization format using extended private keys (xprv) is deprecated. For new implementations, use Type 42 initialization with `{ rootPk: wifKey }`. The legacy BIP32 format remains supported for backward compatibility but should not be used in new projects.
|
754
147
|
|
755
|
-
|
148
|
+
### Advanced Operations
|
756
149
|
|
757
|
-
|
758
|
-
{
|
759
|
-
"@context": ["https://w3id.org/did/v0.11", "https://w3id.org/bap/v1"],
|
760
|
-
"id": "did:bap:id:<Identity Key>",
|
761
|
-
"publicKey": [
|
762
|
-
{
|
763
|
-
"id": "did:bap:id:<Identity Key>#<key identifier>",
|
764
|
-
"controller": "did:bap:id:<Identity Key>",
|
765
|
-
"type": "EcdsaSecp256k1VerificationKey2019",
|
766
|
-
"bitcoinAddress": "<Base58 bitcoin address>"
|
767
|
-
}
|
768
|
-
],
|
769
|
-
"authentication": ["#key1"],
|
770
|
-
"assertionMethod": ["#key1"]
|
771
|
-
}
|
772
|
-
```
|
773
|
-
Example:
|
774
|
-
```
|
775
|
-
{
|
776
|
-
"@context": ["https://w3id.org/did/v0.11", "https://w3id.org/bap/v1"],
|
777
|
-
"id": "did:bap:id:3SyWUZXvhidNcEHbAC3HkBnKoD2Q",
|
778
|
-
"publicKey": [
|
779
|
-
{
|
780
|
-
"id": "did:bap:id:3SyWUZXvhidNcEHbAC3HkBnKoD2Q#root",
|
781
|
-
"controller": "did:bap:id:3SyWUZXvhidNcEHbAC3HkBnKoD2Q",
|
782
|
-
"type": "EcdsaSecp256k1VerificationKey2019",
|
783
|
-
"bitcoinAddress": "1WffojxvgpQBmUTigoss7VUdfN45JiiRK"
|
784
|
-
},
|
785
|
-
{
|
786
|
-
"id": "did:bap:id:3SyWUZXvhidNcEHbAC3HkBnKoD2Q#key1",
|
787
|
-
"controller": "did:bap:id:3SyWUZXvhidNcEHbAC3HkBnKoD2Q",
|
788
|
-
"type": "EcdsaSecp256k1VerificationKey2019",
|
789
|
-
"bitcoinAddress": "1K4c6YXR1ixNLAqrL8nx5HUQAPKbACTwDo"
|
790
|
-
}
|
791
|
-
],
|
792
|
-
"authentication": ["#key1"],
|
793
|
-
"assertionMethod": ["#key1"]
|
794
|
-
}
|
795
|
-
```
|
150
|
+
For detailed API documentation, see the [Library Documentation](src/README.md).
|
796
151
|
|
797
|
-
|
798
|
-
```
|
799
|
-
{
|
800
|
-
"@context": ["https://w3id.org/did/v0.11", "https://w3id.org/bap/v1"],
|
801
|
-
"id": "did:bap:id:3SyWUZXvhidNcEHbAC3HkBnKoD2Q",
|
802
|
-
"publicKey": [
|
803
|
-
{
|
804
|
-
"id": "did:bap:id:3SyWUZXvhidNcEHbAC3HkBnKoD2Q#root",
|
805
|
-
"controller": "did:bap:id:3SyWUZXvhidNcEHbAC3HkBnKoD2Q",
|
806
|
-
"type": "EcdsaSecp256k1VerificationKey2019",
|
807
|
-
"bitcoinAddress": "1WffojxvgpQBmUTigoss7VUdfN45JiiRK"
|
808
|
-
},
|
809
|
-
{
|
810
|
-
"id": "did:bap:id:3SyWUZXvhidNcEHbAC3HkBnKoD2Q#key1",
|
811
|
-
"controller": "did:bap:id:3SyWUZXvhidNcEHbAC3HkBnKoD2Q",
|
812
|
-
"type": "EcdsaSecp256k1VerificationKey2019",
|
813
|
-
"bitcoinAddress": "1K4c6YXR1ixNLAqrL8nx5HUQAPKbACTwDo"
|
814
|
-
},
|
815
|
-
{
|
816
|
-
"id": "did:bap:id:3SyWUZXvhidNcEHbAC3HkBnKoD2Q#key2",
|
817
|
-
"controller": "did:bap:id:3SyWUZXvhidNcEHbAC3HkBnKoD2Q",
|
818
|
-
"type": "EcdsaSecp256k1VerificationKey2019",
|
819
|
-
"bitcoinAddress": "1JfMQDtBKYi6z65M9uF2gxgLv7E8pPR6MA"
|
820
|
-
}
|
821
|
-
],
|
822
|
-
"authentication": ["#key2"],
|
823
|
-
"assertionMethod": ["#key2"]
|
824
|
-
}
|
825
|
-
```
|
152
|
+
## Applications
|
826
153
|
|
827
|
-
|
154
|
+
### Primary Use Cases
|
828
155
|
|
829
|
-
|
156
|
+
- **Decentralized Authentication**: Replace passwords with cryptographic proofs
|
157
|
+
- **Portable Reputation**: Carry verified history across platforms
|
158
|
+
- **Regulatory Compliance**: Reusable KYC with selective disclosure
|
159
|
+
- **Digital Signatures**: Legally binding with blockchain timestamps
|
830
160
|
|
831
|
-
|
161
|
+
### Integration with UI Components
|
832
162
|
|
833
|
-
|
163
|
+
For React applications, [BigBlocks](https://bigblocks.dev) provides production-ready components for BAP integration:
|
834
164
|
|
835
|
-
```
|
836
|
-
|
837
|
-
|
838
|
-
// Export for backup with optional parameters
|
839
|
-
const masterBackup = bap.exportForBackup(
|
840
|
-
'My Identity', // optional label
|
841
|
-
undefined, // optional xprv override
|
842
|
-
'word list...' // optional mnemonic
|
843
|
-
);
|
844
|
-
|
845
|
-
console.log(masterBackup);
|
846
|
-
// {
|
847
|
-
// ids: '...encrypted string...',
|
848
|
-
// xprv: 'xprv...',
|
849
|
-
// mnemonic: 'word list...',
|
850
|
-
// label: 'My Identity',
|
851
|
-
// createdAt: '2024-01-20T10:30:00.000Z'
|
852
|
-
// }
|
165
|
+
```bash
|
166
|
+
npm install bigblocks
|
853
167
|
```
|
854
168
|
|
855
|
-
|
856
|
-
|
857
|
-
- `xprv`: The HD private key (extended private key)
|
858
|
-
- `mnemonic`: BIP39 mnemonic phrase (if provided)
|
859
|
-
- `label`: Optional descriptive label
|
860
|
-
- `createdAt`: ISO timestamp of when the export was created
|
861
|
-
|
862
|
-
## Exporting Member Identity for Backup
|
863
|
-
|
864
|
-
To export a member identity in bitcoin-backup compatible format:
|
169
|
+
```jsx
|
170
|
+
import { BitcoinAuth } from 'bigblocks';
|
865
171
|
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
console.log(memberBackup);
|
873
|
-
// {
|
874
|
-
// wif: 'L1...',
|
875
|
-
// id: '...encrypted data...',
|
876
|
-
// label: 'alice@example.com',
|
877
|
-
// createdAt: '2024-01-20T10:30:00.000Z'
|
878
|
-
// }
|
879
|
-
|
880
|
-
// Or export directly from MemberID instance
|
881
|
-
const memberID = new MemberID('L1...');
|
882
|
-
const memberBackup = memberID.exportForBackup('Member Label');
|
172
|
+
<BitcoinAuth
|
173
|
+
onAuthenticated={(identity) => {
|
174
|
+
console.log('Authenticated:', identity);
|
175
|
+
}}
|
176
|
+
/>
|
883
177
|
```
|
884
178
|
|
885
|
-
|
886
|
-
- `wif`: Wallet Import Format private key
|
887
|
-
- `id`: Encrypted member identity data
|
888
|
-
- `label`: Optional descriptive label
|
889
|
-
- `createdAt`: ISO timestamp of when the export was created
|
179
|
+
## Protocol Specification
|
890
180
|
|
891
|
-
|
181
|
+
For complete technical specification including transaction formats, URN structures, and validation rules, see [PROTOCOL.md](PROTOCOL.md).
|
892
182
|
|
893
|
-
|
183
|
+
## Related Work
|
894
184
|
|
895
|
-
|
896
|
-
|
897
|
-
|
898
|
-
|
899
|
-
// Initialize services
|
900
|
-
const bap = new BAP('xprv...');
|
901
|
-
const backupService = new BackupService();
|
902
|
-
|
903
|
-
// Export and encrypt master backup
|
904
|
-
const masterBackup = bap.exportForBackup('Primary Identity');
|
905
|
-
const encryptedMaster = await backupService.encryptBapMaster(
|
906
|
-
masterBackup,
|
907
|
-
'password123'
|
908
|
-
);
|
909
|
-
|
910
|
-
// Export and encrypt member backup
|
911
|
-
const memberBackup = bap.exportMemberForBackup('Work Identity');
|
912
|
-
const encryptedMember = await backupService.encryptBapMember(
|
913
|
-
memberBackup,
|
914
|
-
'password123'
|
915
|
-
);
|
916
|
-
|
917
|
-
// Store encrypted backups securely
|
918
|
-
await storage.save('master-backup.json', encryptedMaster);
|
919
|
-
await storage.save('member-backup.json', encryptedMember);
|
920
|
-
```
|
185
|
+
- [Type 42 Key Derivation](docs/TYPE42_MIGRATION.md) - Modern derivation method for enhanced privacy
|
186
|
+
- [Author Identity Protocol](https://github.com/b-open-io/aip) - Foundational signing protocol
|
187
|
+
- [Bitcoin Backup](https://github.com/rohenaz/bitcoin-backup) - Compatible backup format specification
|
921
188
|
|
922
|
-
##
|
189
|
+
## Contributing
|
923
190
|
|
924
|
-
|
925
|
-
|
926
|
-
```javascript
|
927
|
-
import { BAP, MemberID } from 'bsv-bap';
|
928
|
-
import { BackupService } from 'bitcoin-backup';
|
929
|
-
|
930
|
-
const backupService = new BackupService();
|
931
|
-
|
932
|
-
// Restore master identity
|
933
|
-
const encryptedMaster = await storage.load('master-backup.json');
|
934
|
-
const masterData = await backupService.decryptBapMaster(
|
935
|
-
encryptedMaster,
|
936
|
-
'password123'
|
937
|
-
);
|
938
|
-
const bap = BAP.import(masterData.xprv, masterData.ids);
|
939
|
-
|
940
|
-
// Restore member identity
|
941
|
-
const encryptedMember = await storage.load('member-backup.json');
|
942
|
-
const memberData = await backupService.decryptBapMember(
|
943
|
-
encryptedMember,
|
944
|
-
'password123'
|
945
|
-
);
|
946
|
-
const memberID = new MemberID(memberData.wif);
|
947
|
-
```
|
191
|
+
We welcome contributions. See [Contributing Guidelines](CONTRIBUTING.md).
|
948
192
|
|
949
|
-
##
|
193
|
+
## License
|
950
194
|
|
951
|
-
|
952
|
-
- Use strong passwords for encryption
|
953
|
-
- Store encrypted backups in secure locations
|
954
|
-
- Never share unencrypted private keys or mnemonics
|
955
|
-
- Consider using hardware security modules for production systems
|
195
|
+
Open BSV License. See [LICENSE](LICENSE) for details.
|
956
196
|
|
957
|
-
|
197
|
+
## Acknowledgments
|
958
198
|
|
959
|
-
|
199
|
+
Created by Siggi with contributions from Attila Aros and Satchmo.
|