@bsv/sdk 1.9.10 → 1.9.12

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.10",
3
+ "version": "1.9.12",
4
4
  "type": "module",
5
5
  "description": "BSV Blockchain Software Development Kit",
6
6
  "main": "dist/cjs/mod.js",
@@ -7,7 +7,6 @@
7
7
  * - Modern browsers via globalThis.crypto, self.crypto, or window.crypto
8
8
  * - Web Workers and Service Workers via self.crypto
9
9
  * - Deno and Bun via globalThis.crypto
10
- * - React Native (requires react-native-get-random-values polyfill)
11
10
  *
12
11
  * @throws {Error} If no secure random number generator is available
13
12
  */
@@ -72,34 +71,6 @@ class Rand {
72
71
  return
73
72
  }
74
73
 
75
- // React Native support - try to load polyfill
76
- if (typeof navigator !== 'undefined' && (navigator as any).product === 'ReactNative') {
77
- try {
78
- // Try to require the polyfill - this will populate globalThis.crypto
79
- // eslint-disable-next-line @typescript-eslint/no-var-requires
80
- require('react-native-get-random-values')
81
-
82
- if (typeof (globalThis as any).crypto?.getRandomValues === 'function') {
83
- this._rand = (n) => {
84
- /* eslint-disable-next-line */
85
- return this.getRandomValues(globalThis as any, n)
86
- }
87
- return
88
- }
89
- } catch (e) {
90
- // Polyfill not available - provide helpful error
91
- this._rand = (): never => {
92
- throw new Error(
93
- 'React Native detected but crypto is not available. ' +
94
- 'Please install and import "react-native-get-random-values" at the top of your entry file:\n' +
95
- 'npm install react-native-get-random-values\n' +
96
- 'Then add: import "react-native-get-random-values" to your index.js/App.js'
97
- )
98
- }
99
- return
100
- }
101
- }
102
-
103
74
  // No crypto available
104
75
  this._rand = noRand
105
76
  }
@@ -44,12 +44,7 @@ export default class SymmetricKey extends BigNumber {
44
44
  const iv = Random(32)
45
45
  msg = toArray(msg, enc)
46
46
  const keyBytes = this.toArray('be', 32)
47
- const { result, authenticationTag } = AESGCM(
48
- msg,
49
- [],
50
- iv,
51
- keyBytes
52
- )
47
+ const { result, authenticationTag } = AESGCM(msg, [], iv, keyBytes)
53
48
  const totalLength = iv.length + result.length + authenticationTag.length
54
49
  const combined = new Array(totalLength)
55
50
  let offset = 0
@@ -79,10 +74,23 @@ export default class SymmetricKey extends BigNumber {
79
74
  */
80
75
  decrypt (msg: number[] | string, enc?: 'hex' | 'utf8'): string | number[] {
81
76
  msg = toArray(msg, enc)
82
- const iv = msg.slice(0, 32)
83
- const tagStart = msg.length - 16
84
- const ciphertext = msg.slice(32, tagStart)
77
+
78
+ const ivLength = 32
79
+ const tagLength = 16
80
+
81
+ if (msg.length < ivLength + tagLength) {
82
+ throw new Error('Ciphertext too short')
83
+ }
84
+
85
+ const iv = msg.slice(0, ivLength)
86
+ const tagStart = msg.length - tagLength
87
+ const ciphertext = msg.slice(ivLength, tagStart)
85
88
  const messageTag = msg.slice(tagStart)
89
+
90
+ if (tagStart < ivLength) {
91
+ throw new Error('Malformed ciphertext')
92
+ }
93
+
86
94
  const result = AESGCMDecrypt(
87
95
  ciphertext,
88
96
  [],
@@ -102,5 +102,27 @@ describe('SymmetricKey', () => {
102
102
 
103
103
  expect(decrypted).toBe(plaintext)
104
104
  })
105
+
106
+ it('throws "Ciphertext too short" for inputs shorter than IV + tag', () => {
107
+ const shortCipherArray = new Array(47).fill(0)
108
+ expect(() => {
109
+ KEYS[0].decrypt(shortCipherArray)
110
+ }).toThrow(new Error('Ciphertext too short'))
111
+ })
112
+
113
+ it('throws "Ciphertext too short" for hex-encoded inputs shorter than IV + tag', () => {
114
+ const shortBuffer = Buffer.alloc(47, 0)
115
+ const shortHex = shortBuffer.toString('hex')
116
+
117
+ expect(() => {
118
+ KEYS[0].decrypt(shortHex, 'hex')
119
+ }).toThrow(new Error('Ciphertext too short'))
120
+ })
121
+
122
+ it('still throws "Decryption failed!" for structurally valid but wrong ciphertext', () => {
123
+ expect(() => {
124
+ KEYS[2].decrypt(CIPHERTEXT_1, 'hex')
125
+ }).toThrow(new Error('Decryption failed!'))
126
+ })
105
127
  })
106
128
  })