@bsv/sdk 1.9.17 → 1.9.18

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.9.17",
3
+ "version": "1.9.18",
4
4
  "type": "module",
5
5
  "description": "BSV Blockchain Software Development Kit",
6
6
  "main": "dist/cjs/mod.js",
@@ -168,48 +168,42 @@ abstract class BaseHash {
168
168
  * @returns Returns an array denoting the padding.
169
169
  */
170
170
  private _pad (): number[] {
171
- //
172
- let len = this.pendingTotal
171
+ const len = this.pendingTotal
173
172
  const bytes = this._delta8
174
173
  const k = bytes - ((len + this.padLength) % bytes)
175
174
  const res = new Array(k + this.padLength)
176
175
  res[0] = 0x80
177
- let i
176
+ let i: number
178
177
  for (i = 1; i < k; i++) {
179
178
  res[i] = 0
180
179
  }
181
180
 
182
181
  // Append length
183
- len <<= 3
184
- let t
182
+ const lengthBytes = this.padLength
183
+ const maxBits = 1n << BigInt(lengthBytes * 8)
184
+ let totalBits = BigInt(len) * 8n
185
+
186
+ if (totalBits >= maxBits) {
187
+ throw new Error('Message too long for this hash function')
188
+ }
189
+
185
190
  if (this.endian === 'big') {
186
- for (t = 8; t < this.padLength; t++) {
187
- res[i++] = 0
191
+ const lenArray = new Array<number>(lengthBytes)
192
+
193
+ for (let b = lengthBytes - 1; b >= 0; b--) {
194
+ lenArray[b] = Number(totalBits & 0xffn)
195
+ totalBits >>= 8n
188
196
  }
189
197
 
190
- res[i++] = 0
191
- res[i++] = 0
192
- res[i++] = 0
193
- res[i++] = 0
194
- res[i++] = (len >>> 24) & 0xff
195
- res[i++] = (len >>> 16) & 0xff
196
- res[i++] = (len >>> 8) & 0xff
197
- res[i++] = len & 0xff
198
+ for (let b = 0; b < lengthBytes; b++) {
199
+ res[i++] = lenArray[b]
200
+ }
198
201
  } else {
199
- res[i++] = len & 0xff
200
- res[i++] = (len >>> 8) & 0xff
201
- res[i++] = (len >>> 16) & 0xff
202
- res[i++] = (len >>> 24) & 0xff
203
- res[i++] = 0
204
- res[i++] = 0
205
- res[i++] = 0
206
- res[i++] = 0
207
-
208
- for (t = 8; t < this.padLength; t++) {
209
- res[i++] = 0
202
+ for (let b = 0; b < lengthBytes; b++) {
203
+ res[i++] = Number(totalBits & 0xffn)
204
+ totalBits >>= 8n
210
205
  }
211
206
  }
212
-
213
207
  return res
214
208
  }
215
209
  }
@@ -101,6 +101,54 @@ describe('Hash', function () {
101
101
  )
102
102
  })
103
103
 
104
+ describe('BaseHash padding and endianness', () => {
105
+ it('encodes length in big-endian for SHA1', () => {
106
+ const sha1 = new (hash as any).SHA1()
107
+ ;(sha1 as any).pendingTotal = 12345
108
+ const pad = (sha1 as any)._pad() as number[]
109
+ const padLength = (sha1 as any).padLength as number
110
+ const lengthBytes = pad.slice(-padLength)
111
+
112
+ const totalBits = BigInt(12345) * 8n
113
+ const expected = new Array<number>(padLength)
114
+ let tmp = totalBits
115
+ for (let i = padLength - 1; i >= 0; i--) {
116
+ expected[i] = Number(tmp & 0xffn)
117
+ tmp >>= 8n
118
+ }
119
+
120
+ expect(lengthBytes).toEqual(expected)
121
+ })
122
+
123
+ it('encodes length in little-endian for RIPEMD160', () => {
124
+ const ripemd = new (hash as any).RIPEMD160()
125
+ ;(ripemd as any).pendingTotal = 12345
126
+ const pad = (ripemd as any)._pad() as number[]
127
+ const padLength = (ripemd as any).padLength as number
128
+ const lengthBytes = pad.slice(-padLength)
129
+
130
+ const totalBits = BigInt(12345) * 8n
131
+ const expected = new Array<number>(padLength)
132
+ let tmp = totalBits
133
+ for (let i = 0; i < padLength; i++) {
134
+ expected[i] = Number(tmp & 0xffn)
135
+ tmp >>= 8n
136
+ }
137
+
138
+ expect(lengthBytes).toEqual(expected)
139
+ })
140
+
141
+ it('throws when message length exceeds maximum encodable bits', () => {
142
+ const sha1 = new (hash as any).SHA1()
143
+ ;(sha1 as any).padLength = 1
144
+ ;(sha1 as any).pendingTotal = 40
145
+
146
+ expect(() => {
147
+ ;(sha1 as any)._pad()
148
+ }).toThrow(new Error('Message too long for this hash function'))
149
+ })
150
+ })
151
+
104
152
  describe('PBKDF2 vectors', () => {
105
153
  for (let i = 0; i < PBKDF2Vectors.length; i++) {
106
154
  const v = PBKDF2Vectors[i]