@bsv/sdk 1.1.27 → 1.1.29

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bsv/sdk",
3
- "version": "1.1.27",
3
+ "version": "1.1.29",
4
4
  "type": "module",
5
5
  "description": "BSV Blockchain Software Development Kit",
6
6
  "main": "dist/cjs/mod.js",
@@ -133,6 +133,9 @@
133
133
  "import": "./dist/esm/src/totp/*.js",
134
134
  "require": "./dist/cjs/src/totp/*.js",
135
135
  "types": "./dist/types/src/totp/*.d.ts"
136
+ },
137
+ "./umd": {
138
+ "import": "./dist/umd/bundle.js"
136
139
  }
137
140
  },
138
141
  "scripts": {
@@ -140,7 +143,9 @@
140
143
  "test:watch": "npm run build && jest --watch",
141
144
  "test:coverage": "npm run build && jest --coverage",
142
145
  "lint": "ts-standard --fix src/**/*.ts",
143
- "build": "tsc -b && tsconfig-to-dual-package tsconfig.cjs.json",
146
+ "build": "npm run build:ts && npm run build:umd",
147
+ "build:ts": "tsc -b && tsconfig-to-dual-package tsconfig.cjs.json",
148
+ "build:umd": "webpack --config webpack.config.js",
144
149
  "dev": "tsc -b -w",
145
150
  "prepublish": "npm run build",
146
151
  "doc": "ts2md --inputFilename=src/script/index.ts --outputFilename=docs/script.md --filenameSubString=script --firstHeadingLevel=1 && ts2md --inputFilename=src/primitives/index.ts --outputFilename=docs/primitives.md --filenameSubString=primitives --firstHeadingLevel=1 && ts2md --inputFilename=src/transaction/index.ts --outputFilename=docs/transaction.md --filenameSubString=transaction --firstHeadingLevel=1 && ts2md --inputFilename=src/messages/index.ts --outputFilename=docs/messages.md --filenameSubString=messages --firstHeadingLevel=1 && ts2md --inputFilename=src/compat/index.ts --outputFilename=docs/compat.md --filenameSubString=compat --firstHeadingLevel=1"
@@ -166,9 +171,12 @@
166
171
  "@types/jest": "^29.5.5",
167
172
  "jest": "^29.7.0",
168
173
  "ts-jest": "^29.1.1",
174
+ "ts-loader": "^9.5.1",
169
175
  "ts-standard": "^12.0.2",
170
176
  "ts2md": "^0.2.0",
171
177
  "tsconfig-to-dual-package": "^1.2.0",
172
- "typescript": "^5.2.2"
178
+ "typescript": "^5.2.2",
179
+ "webpack": "^5.95.0",
180
+ "webpack-cli": "^5.1.4"
173
181
  }
174
182
  }
@@ -46,9 +46,9 @@ function AES (key) {
46
46
  decKey[j] = tmp
47
47
  } else {
48
48
  decKey[j] = decTable[0][sbox[tmp >>> 24]] ^
49
- decTable[1][sbox[tmp >> 16 & 255]] ^
50
- decTable[2][sbox[tmp >> 8 & 255]] ^
51
- decTable[3][sbox[tmp & 255]]
49
+ decTable[1][sbox[tmp >> 16 & 255]] ^
50
+ decTable[2][sbox[tmp >> 8 & 255]] ^
51
+ decTable[3][sbox[tmp & 255]]
52
52
  }
53
53
  }
54
54
  }
@@ -162,11 +162,11 @@ AES.prototype = {
162
162
  // Last round.
163
163
  for (i = 0; i < 4; i++) {
164
164
  out[dir ? 3 & -i : i] =
165
- sbox[a >>> 24] << 24 ^
166
- sbox[b >> 16 & 255] << 16 ^
167
- sbox[c >> 8 & 255] << 8 ^
168
- sbox[d & 255] ^
169
- key[kIndex++]
165
+ sbox[a >>> 24] << 24 ^
166
+ sbox[b >> 16 & 255] << 16 ^
167
+ sbox[c >> 8 & 255] << 8 ^
168
+ sbox[d & 255] ^
169
+ key[kIndex++]
170
170
  a2 = a; a = b; b = c; c = d; d = a2
171
171
  }
172
172
 
@@ -200,10 +200,10 @@ class AESWrapper {
200
200
  const words = []
201
201
  for (let i = 0; i < buf.length / 4; i++) {
202
202
  const val =
203
- (buf[i * 4] * 0x1000000) + // Shift the first byte by 24 bits
204
- ((buf[i * 4 + 1] << 16) | // Shift the second byte by 16 bits
205
- (buf[i * 4 + 2] << 8) | // Shift the third byte by 8 bits
206
- buf[i * 4 + 3]) // The fourth byte
203
+ (buf[i * 4] * 0x1000000) + // Shift the first byte by 24 bits
204
+ ((buf[i * 4 + 1] << 16) | // Shift the second byte by 16 bits
205
+ (buf[i * 4 + 2] << 8) | // Shift the third byte by 8 bits
206
+ buf[i * 4 + 3]) // The fourth byte
207
207
  words.push(val)
208
208
  }
209
209
  return words
@@ -477,12 +477,32 @@ export default class ECIES {
477
477
  throw new Error('Invalid Magic')
478
478
  }
479
479
  let offset = 4
480
- if (!fromPublicKey) {
481
- // BIE1 use compressed public key, length is always 33.
482
- const pub = encBuf.slice(4, 37)
483
- fromPublicKey = PublicKey.fromString(toHex(pub))
484
- offset = 37
480
+
481
+ // Determine if the sender's public key is included in encBuf
482
+ let Rbuf: number[] | null = null
483
+ if (encBuf.length - offset - tagLength >= 33) {
484
+ const firstByte = encBuf[offset]
485
+ if (firstByte === 0x02 || firstByte === 0x03) {
486
+ // Compressed public key
487
+ Rbuf = encBuf.slice(offset, offset + 33)
488
+ offset += 33
489
+ } else if (firstByte === 0x04) {
490
+ // Uncompressed public key
491
+ Rbuf = encBuf.slice(offset, offset + 65)
492
+ offset += 65
493
+ }
494
+ }
495
+
496
+ if (Rbuf) {
497
+ if (!fromPublicKey) {
498
+ fromPublicKey = PublicKey.fromString(toHex(Rbuf))
499
+ }
500
+ } else {
501
+ if (!fromPublicKey) {
502
+ throw new Error('Sender public key is required')
503
+ }
485
504
  }
505
+
486
506
  const { iv, kE, kM } = ECIES.ivkEkM(toPrivateKey, fromPublicKey)
487
507
  const ciphertext = encBuf.slice(offset, encBuf.length - tagLength)
488
508
  const hmac = encBuf.slice(encBuf.length - tagLength, encBuf.length)
@@ -492,6 +512,7 @@ export default class ECIES {
492
512
  if (toHex(hmac) !== toHex(hmac2)) {
493
513
  throw new Error('Invalid checksum')
494
514
  }
515
+
495
516
  return AESCBC.decrypt(ciphertext, kE, iv)
496
517
  }
497
518
 
@@ -1,7 +1,7 @@
1
1
  import ECIES from '../../../dist/cjs/src/compat/ECIES'
2
2
  import * as Hash from '../../../dist/cjs/src/primitives/Hash'
3
3
  import PrivateKey from '../../../dist/cjs/src/primitives/PrivateKey'
4
- import { toArray, toHex, encode, toBase64 } from '../../../dist/cjs/src/primitives/utils'
4
+ import { toArray, toHex, encode, toBase64, toUTF8 } from '../../../dist/cjs/src/primitives/utils'
5
5
 
6
6
  describe('#ECIES', () => {
7
7
  it('should make a new ECIES object', () => {
@@ -93,5 +93,27 @@ describe('#ECIES', () => {
93
93
  expect(ECIES.electrumDecrypt(encryptedMessage, bobPrivateKey))
94
94
  .toEqual(message)
95
95
  })
96
+
97
+ it('should encrypt and decrypt message with counterparty public key', () => {
98
+ const wif = 'L211enC224G1kV8pyyq7bjVd9SxZebnRYEzzM3i7ZHCc1c5E7dQu'
99
+ const senderPrivateKey = PrivateKey.fromWif(wif)
100
+ const senderPublicKey = senderPrivateKey.toPublicKey()
101
+ const msgStr = 'hello world'
102
+ const messageBuf = toArray(msgStr, 'utf8')
103
+
104
+ // Create a random counterparty (recipient) public/private key pair
105
+ const recipientPrivateKey = PrivateKey.fromRandom()
106
+ const recipientPublicKey = recipientPrivateKey.toPublicKey()
107
+
108
+ // Encrypt the message using electrumEncrypt
109
+ const encryptedMessage = ECIES.electrumEncrypt(messageBuf, recipientPublicKey, senderPrivateKey)
110
+
111
+ // Decrypt the message using electrumDecrypt
112
+ const decryptedMessageBuf = ECIES.electrumDecrypt(encryptedMessage, recipientPrivateKey, senderPublicKey)
113
+
114
+ const decryptedMsgStr = toUTF8(decryptedMessageBuf)
115
+
116
+ expect(decryptedMsgStr).toEqual(msgStr)
117
+ })
96
118
  })
97
119
  })