@smartledger/bsv 1.5.6-fix1

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.
Files changed (76) hide show
  1. package/LICENSE +36 -0
  2. package/README.md +305 -0
  3. package/SECURITY.md +75 -0
  4. package/bsv-ecies.min.js +12 -0
  5. package/bsv-message.min.js +10 -0
  6. package/bsv-mnemonic.min.js +12 -0
  7. package/bsv.d.ts +440 -0
  8. package/bsv.min.js +37 -0
  9. package/ecies/index.js +1 -0
  10. package/index.js +101 -0
  11. package/lib/address.js +526 -0
  12. package/lib/block/block.js +277 -0
  13. package/lib/block/blockheader.js +294 -0
  14. package/lib/block/index.js +4 -0
  15. package/lib/block/merkleblock.js +316 -0
  16. package/lib/crypto/bn.js +278 -0
  17. package/lib/crypto/ecdsa.js +330 -0
  18. package/lib/crypto/elliptic-fixed.js +74 -0
  19. package/lib/crypto/hash.browser.js +171 -0
  20. package/lib/crypto/hash.js +2 -0
  21. package/lib/crypto/hash.node.js +171 -0
  22. package/lib/crypto/point.js +217 -0
  23. package/lib/crypto/random.js +37 -0
  24. package/lib/crypto/signature.js +410 -0
  25. package/lib/crypto/smartledger_verify.js +109 -0
  26. package/lib/ecies/bitcore-ecies.js +163 -0
  27. package/lib/ecies/electrum-ecies.js +175 -0
  28. package/lib/ecies/errors.js +16 -0
  29. package/lib/ecies/index.js +1 -0
  30. package/lib/encoding/base58.js +108 -0
  31. package/lib/encoding/base58check.js +112 -0
  32. package/lib/encoding/bufferreader.js +200 -0
  33. package/lib/encoding/bufferwriter.js +150 -0
  34. package/lib/encoding/varint.js +71 -0
  35. package/lib/errors/index.js +57 -0
  36. package/lib/errors/spec.js +184 -0
  37. package/lib/hdprivatekey.js +655 -0
  38. package/lib/hdpublickey.js +509 -0
  39. package/lib/message/index.js +4 -0
  40. package/lib/message/message.js +181 -0
  41. package/lib/mnemonic/errors.js +18 -0
  42. package/lib/mnemonic/index.js +4 -0
  43. package/lib/mnemonic/mnemonic.js +304 -0
  44. package/lib/mnemonic/pbkdf2.js +68 -0
  45. package/lib/mnemonic/words/chinese.js +5 -0
  46. package/lib/mnemonic/words/english.js +5 -0
  47. package/lib/mnemonic/words/french.js +5 -0
  48. package/lib/mnemonic/words/index.js +8 -0
  49. package/lib/mnemonic/words/italian.js +5 -0
  50. package/lib/mnemonic/words/japanese.js +5 -0
  51. package/lib/mnemonic/words/spanish.js +5 -0
  52. package/lib/networks.js +392 -0
  53. package/lib/opcode.js +248 -0
  54. package/lib/privatekey.js +373 -0
  55. package/lib/publickey.js +387 -0
  56. package/lib/script/index.js +3 -0
  57. package/lib/script/interpreter.js +1807 -0
  58. package/lib/script/script.js +1153 -0
  59. package/lib/transaction/index.js +7 -0
  60. package/lib/transaction/input/index.js +6 -0
  61. package/lib/transaction/input/input.js +202 -0
  62. package/lib/transaction/input/multisig.js +220 -0
  63. package/lib/transaction/input/multisigscripthash.js +189 -0
  64. package/lib/transaction/input/publickey.js +96 -0
  65. package/lib/transaction/input/publickeyhash.js +103 -0
  66. package/lib/transaction/output.js +192 -0
  67. package/lib/transaction/sighash.js +288 -0
  68. package/lib/transaction/signature.js +88 -0
  69. package/lib/transaction/transaction.js +1208 -0
  70. package/lib/transaction/unspentoutput.js +97 -0
  71. package/lib/util/_.js +44 -0
  72. package/lib/util/js.js +91 -0
  73. package/lib/util/preconditions.js +34 -0
  74. package/message/index.js +1 -0
  75. package/mnemonic/index.js +1 -0
  76. package/package.json +89 -0
@@ -0,0 +1,330 @@
1
+ 'use strict'
2
+
3
+ var BN = require('./bn')
4
+ var Point = require('./point')
5
+ var Signature = require('./signature')
6
+ var PublicKey = require('../publickey')
7
+ var Random = require('./random')
8
+ var Hash = require('./hash')
9
+ var _ = require('../util/_')
10
+ var $ = require('../util/preconditions')
11
+
12
+ var ECDSA = function ECDSA (obj) {
13
+ if (!(this instanceof ECDSA)) {
14
+ return new ECDSA(obj)
15
+ }
16
+ if (obj) {
17
+ this.set(obj)
18
+ }
19
+ }
20
+
21
+ ECDSA.prototype.set = function (obj) {
22
+ this.hashbuf = obj.hashbuf || this.hashbuf
23
+ this.endian = obj.endian || this.endian // the endianness of hashbuf
24
+ this.privkey = obj.privkey || this.privkey
25
+ this.pubkey = obj.pubkey || (this.privkey ? this.privkey.publicKey : this.pubkey)
26
+ this.sig = obj.sig || this.sig
27
+ this.k = obj.k || this.k
28
+ this.verified = obj.verified || this.verified
29
+ return this
30
+ }
31
+
32
+ ECDSA.prototype.privkey2pubkey = function () {
33
+ this.pubkey = this.privkey.toPublicKey()
34
+ }
35
+
36
+ ECDSA.prototype.calci = function () {
37
+ for (var i = 0; i < 4; i++) {
38
+ this.sig.i = i
39
+ var Qprime
40
+ try {
41
+ Qprime = this.toPublicKey()
42
+ } catch (e) {
43
+ console.error(e)
44
+ continue
45
+ }
46
+
47
+ if (Qprime.point.eq(this.pubkey.point)) {
48
+ this.sig.compressed = this.pubkey.compressed
49
+ return this
50
+ }
51
+ }
52
+
53
+ this.sig.i = undefined
54
+ throw new Error('Unable to find valid recovery factor')
55
+ }
56
+
57
+ ECDSA.fromString = function (str) {
58
+ var obj = JSON.parse(str)
59
+ return new ECDSA(obj)
60
+ }
61
+
62
+ ECDSA.prototype.randomK = function () {
63
+ var N = Point.getN()
64
+ var k
65
+ do {
66
+ k = BN.fromBuffer(Random.getRandomBuffer(32))
67
+ } while (!(k.lt(N) && k.gt(BN.Zero)))
68
+ this.k = k
69
+ return this
70
+ }
71
+
72
+ // https://tools.ietf.org/html/rfc6979#section-3.2
73
+ ECDSA.prototype.deterministicK = function (badrs) {
74
+ // if r or s were invalid when this function was used in signing,
75
+ // we do not want to actually compute r, s here for efficiency, so,
76
+ // we can increment badrs. explained at end of RFC 6979 section 3.2
77
+ if (_.isUndefined(badrs)) {
78
+ badrs = 0
79
+ }
80
+ var v = Buffer.alloc(32)
81
+ v.fill(0x01)
82
+ var k = Buffer.alloc(32)
83
+ k.fill(0x00)
84
+ var x = this.privkey.bn.toBuffer({
85
+ size: 32
86
+ })
87
+ var hashbuf = this.endian === 'little' ? Buffer.from(this.hashbuf).reverse() : this.hashbuf
88
+ k = Hash.sha256hmac(Buffer.concat([v, Buffer.from([0x00]), x, hashbuf]), k)
89
+ v = Hash.sha256hmac(v, k)
90
+ k = Hash.sha256hmac(Buffer.concat([v, Buffer.from([0x01]), x, hashbuf]), k)
91
+ v = Hash.sha256hmac(v, k)
92
+ v = Hash.sha256hmac(v, k)
93
+ var T = BN.fromBuffer(v)
94
+ var N = Point.getN()
95
+
96
+ // also explained in 3.2, we must ensure T is in the proper range (0, N)
97
+ for (var i = 0; i < badrs || !(T.lt(N) && T.gt(BN.Zero)); i++) {
98
+ k = Hash.sha256hmac(Buffer.concat([v, Buffer.from([0x00])]), k)
99
+ v = Hash.sha256hmac(v, k)
100
+ v = Hash.sha256hmac(v, k)
101
+ T = BN.fromBuffer(v)
102
+ }
103
+
104
+ this.k = T
105
+ return this
106
+ }
107
+
108
+ // Information about public key recovery:
109
+ // https://bitcointalk.org/index.php?topic=6430.0
110
+ // http://stackoverflow.com/questions/19665491/how-do-i-get-an-ecdsa-public-key-from-just-a-bitcoin-signature-sec1-4-1-6-k
111
+ ECDSA.prototype.toPublicKey = function () {
112
+ var i = this.sig.i
113
+ $.checkArgument(i === 0 || i === 1 || i === 2 || i === 3, new Error('i must be equal to 0, 1, 2, or 3'))
114
+
115
+ var e = BN.fromBuffer(this.hashbuf)
116
+ var r = this.sig.r
117
+ var s = this.sig.s
118
+
119
+ // A set LSB signifies that the y-coordinate is odd
120
+ var isYOdd = i & 1
121
+
122
+ // The more significant bit specifies whether we should use the
123
+ // first or second candidate key.
124
+ var isSecondKey = i >> 1
125
+
126
+ var n = Point.getN()
127
+ var G = Point.getG()
128
+
129
+ // 1.1 Let x = r + jn
130
+ var x = isSecondKey ? r.add(n) : r
131
+ var R = Point.fromX(isYOdd, x)
132
+
133
+ // 1.4 Check that nR is at infinity
134
+ var nR = R.mul(n)
135
+
136
+ if (!nR.isInfinity()) {
137
+ throw new Error('nR is not a valid curve point')
138
+ }
139
+
140
+ // Compute -e from e
141
+ var eNeg = e.neg().umod(n)
142
+
143
+ // 1.6.1 Compute Q = r^-1 (sR - eG)
144
+ // Q = r^-1 (sR + -eG)
145
+ var rInv = r.invm(n)
146
+
147
+ // var Q = R.multiplyTwo(s, G, eNeg).mul(rInv);
148
+ var Q = R.mul(s).add(G.mul(eNeg)).mul(rInv)
149
+
150
+ var pubkey = PublicKey.fromPoint(Q, this.sig.compressed)
151
+
152
+ return pubkey
153
+ }
154
+
155
+ ECDSA.prototype.sigError = function () {
156
+ if (!Buffer.isBuffer(this.hashbuf) || this.hashbuf.length !== 32) {
157
+ return 'hashbuf must be a 32 byte buffer'
158
+ }
159
+
160
+ // === SmartLedger Security Patches ===
161
+ // Apply security validation during cryptographic verification
162
+ try {
163
+ // Create a copy to avoid mutating original signature
164
+ var secureSig = {
165
+ r: this.sig.r,
166
+ s: this.sig.s
167
+ }
168
+
169
+ // Apply security patches to the copy
170
+ var n = Point.getN()
171
+
172
+ // Fix 1 & 2: Enhanced range validation (maintains original message for compatibility)
173
+ if (secureSig.r.isZero() || secureSig.s.isZero() ||
174
+ secureSig.r.gte(n) || secureSig.s.gte(n)) {
175
+ return 'r and s not in range'
176
+ }
177
+
178
+ // Fix 3: Canonicalize s for verification (non-mutating)
179
+ var nh = n.shrn(1) // n/2
180
+ if (secureSig.s.gt(nh)) {
181
+ secureSig.s = n.sub(secureSig.s)
182
+ }
183
+
184
+ // Use secure signature for verification
185
+ var r = secureSig.r
186
+ var canonicalS = secureSig.s
187
+ } catch (error) {
188
+ return 'Signature security validation failed: ' + error.message
189
+ }
190
+
191
+ var e = BN.fromBuffer(this.hashbuf, this.endian ? {
192
+ endian: this.endian
193
+ } : undefined)
194
+ // Use canonical s for verification
195
+ var sinv = canonicalS.invm(n)
196
+ var u1 = sinv.mul(e).umod(n)
197
+ var u2 = sinv.mul(r).umod(n)
198
+
199
+ var p = Point.getG().mulAdd(u1, this.pubkey.point, u2)
200
+ if (p.isInfinity()) {
201
+ return 'p is infinity'
202
+ }
203
+
204
+ if (p.getX().umod(n).cmp(r) !== 0) {
205
+ return 'Invalid signature'
206
+ } else {
207
+ return false
208
+ }
209
+ }
210
+
211
+ ECDSA.toLowS = function (s) {
212
+ // enforce low s
213
+ // see BIP 62, "low S values in signatures"
214
+ if (s.gt(BN.fromBuffer(Buffer.from('7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0', 'hex')))) {
215
+ s = Point.getN().sub(s)
216
+ }
217
+ return s
218
+ }
219
+
220
+ ECDSA.prototype._findSignature = function (d, e) {
221
+ var N = Point.getN()
222
+ var G = Point.getG()
223
+ // try different values of k until r, s are valid
224
+ var badrs = 0
225
+ var k, Q, r, s
226
+ do {
227
+ if (!this.k || badrs > 0) {
228
+ this.deterministicK(badrs)
229
+ }
230
+ badrs++
231
+ k = this.k
232
+ Q = G.mul(k)
233
+ r = Q.x.umod(N)
234
+ s = k.invm(N).mul(e.add(d.mul(r))).umod(N)
235
+ } while (r.cmp(BN.Zero) <= 0 || s.cmp(BN.Zero) <= 0)
236
+
237
+ s = ECDSA.toLowS(s)
238
+ return {
239
+ s: s,
240
+ r: r
241
+ }
242
+ }
243
+
244
+ ECDSA.prototype.sign = function () {
245
+ var hashbuf = this.hashbuf
246
+ var privkey = this.privkey
247
+ var d = privkey.bn
248
+
249
+ $.checkState(hashbuf && privkey && d, new Error('invalid parameters'))
250
+ $.checkState(Buffer.isBuffer(hashbuf) && hashbuf.length === 32, new Error('hashbuf must be a 32 byte buffer'))
251
+
252
+ var e = BN.fromBuffer(hashbuf, this.endian ? {
253
+ endian: this.endian
254
+ } : undefined)
255
+
256
+ var obj = this._findSignature(d, e)
257
+ obj.compressed = this.pubkey.compressed
258
+
259
+ this.sig = new Signature(obj)
260
+ return this
261
+ }
262
+
263
+ ECDSA.prototype.signRandomK = function () {
264
+ this.randomK()
265
+ return this.sign()
266
+ }
267
+
268
+ ECDSA.prototype.toString = function () {
269
+ var obj = {}
270
+ if (this.hashbuf) {
271
+ obj.hashbuf = this.hashbuf.toString('hex')
272
+ }
273
+ if (this.privkey) {
274
+ obj.privkey = this.privkey.toString()
275
+ }
276
+ if (this.pubkey) {
277
+ obj.pubkey = this.pubkey.toString()
278
+ }
279
+ if (this.sig) {
280
+ obj.sig = this.sig.toString()
281
+ }
282
+ if (this.k) {
283
+ obj.k = this.k.toString()
284
+ }
285
+ return JSON.stringify(obj)
286
+ }
287
+
288
+ ECDSA.prototype.verify = function () {
289
+ if (!this.sigError()) {
290
+ this.verified = true
291
+ } else {
292
+ this.verified = false
293
+ }
294
+ return this
295
+ }
296
+
297
+ ECDSA.sign = function (hashbuf, privkey, endian) {
298
+ return ECDSA().set({
299
+ hashbuf: hashbuf,
300
+ endian: endian,
301
+ privkey: privkey
302
+ }).sign().sig
303
+ }
304
+
305
+ ECDSA.signWithCalcI = function (hashbuf, privkey, endian) {
306
+ return ECDSA().set({
307
+ hashbuf: hashbuf,
308
+ endian: endian,
309
+ privkey: privkey
310
+ }).sign().calci().sig
311
+ }
312
+
313
+ ECDSA.signRandomK = function (hashbuf, privkey, endian) {
314
+ return ECDSA().set({
315
+ hashbuf: hashbuf,
316
+ endian: endian,
317
+ privkey: privkey
318
+ }).signRandomK().sig
319
+ }
320
+
321
+ ECDSA.verify = function (hashbuf, sig, pubkey, endian) {
322
+ return ECDSA().set({
323
+ hashbuf: hashbuf,
324
+ endian: endian,
325
+ sig: sig,
326
+ pubkey: pubkey
327
+ }).verify().verified
328
+ }
329
+
330
+ module.exports = ECDSA
@@ -0,0 +1,74 @@
1
+ 'use strict'
2
+
3
+ /**
4
+ * SmartLedger Elliptic Security Wrapper
5
+ * Patches elliptic library to prevent signature verification vulnerabilities
6
+ */
7
+
8
+ const { ec: EC } = require('elliptic')
9
+ const ec = new EC('secp256k1')
10
+
11
+ // Store original verify method
12
+ const origVerify = ec.verify.bind(ec)
13
+
14
+ /**
15
+ * Hardened elliptic verify method
16
+ * Rejects invalid signature parameters before calling original verify
17
+ */
18
+ ec.verify = function (msg, sig, key, enc, opts) {
19
+ // Validate signature components exist
20
+ if (!sig || typeof sig !== 'object') {
21
+ return false
22
+ }
23
+
24
+ // Check for r and s components
25
+ if (!sig.r || !sig.s) {
26
+ return false
27
+ }
28
+
29
+ // Convert to BN if needed for comparison
30
+ const r = typeof sig.r.cmp === 'function' ? sig.r : this.curve.n.red ? this.curve.n.fromRed(sig.r) : sig.r
31
+ const s = typeof sig.s.cmp === 'function' ? sig.s : this.curve.n.red ? this.curve.n.fromRed(sig.s) : sig.s
32
+
33
+ // Reject if r or s >= curve order n
34
+ if (r && r.cmp && r.cmp(this.curve.n) >= 0) {
35
+ return false
36
+ }
37
+ if (s && s.cmp && s.cmp(this.curve.n) >= 0) {
38
+ return false
39
+ }
40
+
41
+ // Reject zero values
42
+ if (r && r.isZero && r.isZero()) {
43
+ return false
44
+ }
45
+ if (s && s.isZero && s.isZero()) {
46
+ return false
47
+ }
48
+
49
+ // Call original verify with validated parameters
50
+ return origVerify(msg, sig, key, enc, opts)
51
+ }
52
+
53
+ // Store original sign method for potential future hardening
54
+ const origSign = ec.sign.bind(ec)
55
+
56
+ /**
57
+ * Hardened elliptic sign method
58
+ * Ensures canonical signatures (s <= n/2)
59
+ */
60
+ ec.sign = function (msg, key, enc, options) {
61
+ const signature = origSign(msg, key, enc, options)
62
+
63
+ // Canonicalize s value to lower half
64
+ if (signature.s && signature.s.cmp) {
65
+ const halfOrder = this.curve.n.shrn(1)
66
+ if (signature.s.cmp(halfOrder) > 0) {
67
+ signature.s = this.curve.n.sub(signature.s)
68
+ }
69
+ }
70
+
71
+ return signature
72
+ }
73
+
74
+ module.exports = ec
@@ -0,0 +1,171 @@
1
+ 'use strict'
2
+
3
+ var hash = require('hash.js')
4
+ var $ = require('../util/preconditions')
5
+
6
+ var Hash = module.exports
7
+
8
+ /**
9
+ * A SHA or SHA1 hash, which is always 160 bits or 20 bytes long.
10
+ *
11
+ * See:
12
+ * https://en.wikipedia.org/wiki/SHA-1
13
+ *
14
+ * @param {Buffer} buf Data, a.k.a. pre-image, which can be any size.
15
+ * @returns {Buffer} The hash in the form of a buffer.
16
+ */
17
+ Hash.sha1 = function (buf) {
18
+ $.checkArgument(Buffer.isBuffer(buf))
19
+ return Buffer.from(hash.sha1().update(buf).digest('hex'), 'hex')
20
+ }
21
+
22
+ Hash.sha1.blocksize = 512
23
+
24
+ /**
25
+ * A SHA256 hash, which is always 256 bits or 32 bytes long.
26
+ *
27
+ * See:
28
+ * https://www.movable-type.co.uk/scripts/sha256.html
29
+ *
30
+ * @param {Buffer} buf Data, a.k.a. pre-image, which can be any size.
31
+ * @returns {Buffer} The hash in the form of a buffer.
32
+ */
33
+ Hash.sha256 = function (buf) {
34
+ $.checkArgument(Buffer.isBuffer(buf))
35
+ return Buffer.from(hash.sha256().update(buf).digest('hex'), 'hex')
36
+ }
37
+
38
+ Hash.sha256.blocksize = 512
39
+
40
+ /**
41
+ * A double SHA256 hash, which is always 256 bits or 32 bytes bytes long. This
42
+ * hash function is commonly used inside Bitcoin, particularly for the hash of a
43
+ * block and the hash of a transaction.
44
+ *
45
+ * See:
46
+ * https://www.movable-type.co.uk/scripts/sha256.html
47
+ *
48
+ * @param {Buffer} buf Data, a.k.a. pre-image, which can be any size.
49
+ * @returns {Buffer} The hash in the form of a buffer.
50
+ */
51
+ Hash.sha256sha256 = function (buf) {
52
+ $.checkArgument(Buffer.isBuffer(buf))
53
+ return Hash.sha256(Hash.sha256(buf))
54
+ }
55
+
56
+ /**
57
+ * A RIPEMD160 hash, which is always 160 bits or 20 bytes long.
58
+ *
59
+ * See:
60
+ * https://en.wikipedia.org/wiki/RIPEMD
61
+ *
62
+ * @param {Buffer} buf Data, a.k.a. pre-image, which can be any size.
63
+ * @returns {Buffer} The hash in the form of a buffer.
64
+ */
65
+ Hash.ripemd160 = function (buf) {
66
+ $.checkArgument(Buffer.isBuffer(buf))
67
+ return Buffer.from(hash.ripemd160().update(buf).digest('hex'), 'hex')
68
+ }
69
+ /**
70
+ * A RIPEMD160 hash of a SHA256 hash, which is always 160 bits or 20 bytes long.
71
+ * This value is commonly used inside Bitcoin, particularly for Bitcoin
72
+ * addresses.
73
+ *
74
+ * See:
75
+ * https://en.wikipedia.org/wiki/RIPEMD
76
+ *
77
+ * @param {Buffer} buf Data, a.k.a. pre-image, which can be any size.
78
+ * @returns {Buffer} The hash in the form of a buffer.
79
+ */
80
+ Hash.sha256ripemd160 = function (buf) {
81
+ $.checkArgument(Buffer.isBuffer(buf))
82
+ return Hash.ripemd160(Hash.sha256(buf))
83
+ }
84
+
85
+ /**
86
+ * A SHA512 hash, which is always 512 bits or 64 bytes long.
87
+ *
88
+ * See:
89
+ * https://en.wikipedia.org/wiki/SHA-2
90
+ *
91
+ * @param {Buffer} buf Data, a.k.a. pre-image, which can be any size.
92
+ * @returns {Buffer} The hash in the form of a buffer.
93
+ */
94
+ Hash.sha512 = function (buf) {
95
+ $.checkArgument(Buffer.isBuffer(buf))
96
+ return Buffer.from(hash.sha512().update(buf).digest('hex'), 'hex')
97
+ }
98
+
99
+ Hash.sha512.blocksize = 1024
100
+
101
+ /**
102
+ * A way to do HMAC using any underlying hash function. If you ever find that
103
+ * you want to hash two pieces of data together, you should use HMAC instead of
104
+ * just using a hash function. Rather than doing hash(data1 + data2) you should
105
+ * do HMAC(data1, data2). Actually, rather than use HMAC directly, we recommend
106
+ * you use either sha256hmac or sha515hmac provided below.
107
+ *
108
+ * See:
109
+ * https://en.wikipedia.org/wiki/Length_extension_attack
110
+ * https://blog.skullsecurity.org/2012/everything-you-need-to-know-about-hash-length-extension-attacks
111
+ *
112
+ * @param {function} hashf Which hash function to use.
113
+ * @param {Buffer} data Data, which can be any size.
114
+ * @param {Buffer} key Key, which can be any size.
115
+ * @returns {Buffer} The HMAC in the form of a buffer.
116
+ */
117
+ Hash.hmac = function (hashf, data, key) {
118
+ // http://en.wikipedia.org/wiki/Hash-based_message_authentication_code
119
+ // http://tools.ietf.org/html/rfc4868#section-2
120
+ $.checkArgument(Buffer.isBuffer(data))
121
+ $.checkArgument(Buffer.isBuffer(key))
122
+ $.checkArgument(hashf.blocksize)
123
+
124
+ var blocksize = hashf.blocksize / 8
125
+
126
+ if (key.length > blocksize) {
127
+ key = hashf(key)
128
+ } else if (key < blocksize) {
129
+ var fill = Buffer.alloc(blocksize)
130
+ fill.fill(0)
131
+ key.copy(fill)
132
+ key = fill
133
+ }
134
+
135
+ var oKey = Buffer.alloc(blocksize)
136
+ oKey.fill(0x5c)
137
+
138
+ var iKey = Buffer.alloc(blocksize)
139
+ iKey.fill(0x36)
140
+
141
+ var oKeyPad = Buffer.alloc(blocksize)
142
+ var iKeyPad = Buffer.alloc(blocksize)
143
+ for (var i = 0; i < blocksize; i++) {
144
+ oKeyPad[i] = oKey[i] ^ key[i]
145
+ iKeyPad[i] = iKey[i] ^ key[i]
146
+ }
147
+
148
+ return hashf(Buffer.concat([oKeyPad, hashf(Buffer.concat([iKeyPad, data]))]))
149
+ }
150
+
151
+ /**
152
+ * A SHA256 HMAC.
153
+ *
154
+ * @param {Buffer} data Data, which can be any size.
155
+ * @param {Buffer} key Key, which can be any size.
156
+ * @returns {Buffer} The HMAC in the form of a buffer.
157
+ */
158
+ Hash.sha256hmac = function (data, key) {
159
+ return Hash.hmac(Hash.sha256, data, key)
160
+ }
161
+
162
+ /**
163
+ * A SHA512 HMAC.
164
+ *
165
+ * @param {Buffer} data Data, which can be any size.
166
+ * @param {Buffer} key Key, which can be any size.
167
+ * @returns {Buffer} The HMAC in the form of a buffer.
168
+ */
169
+ Hash.sha512hmac = function (data, key) {
170
+ return Hash.hmac(Hash.sha512, data, key)
171
+ }
@@ -0,0 +1,2 @@
1
+ if (process.browser) module.exports = require('./hash.browser')
2
+ else module.exports = require('./hash.node')