tinyhmacmd5 0.0.6 → 0.1.0

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 CHANGED
@@ -1,8 +1,8 @@
1
1
  # Tiny HMAC MD5
2
2
 
3
- A tiny JavaScript HMAC-MD5 implementation.
3
+ A tiny, reliable JavaScript HMAC-MD5 implementation.
4
4
 
5
- The minified browser bundle ([`browser.min.js`](browser.min.js)) is only 965 bytes.
5
+ The minified browser bundle ([`browser.min.js`](browser.min.js)) is only 1057 bytes.
6
6
 
7
7
  Preview: https://bddjr.github.io/tinyhmacmd5/
8
8
 
package/browser.min.js CHANGED
@@ -1,2 +1,2 @@
1
1
  /** @license https://bddjr.github.io/tinyhmacmd5/lic */
2
- {let r=1732584193,e=271733878,t=~r,n=~e,o=[],f=(f,a,h=0,i,l,u,d,c,g=[r,n,t,e],s=[...g],y=r=>g[3&++c])=>{for(f[a+64>>>9<<4|14]=0|a,f[a>>>5]|=128<<a%32;h<f.length;h+=16){for(c=i=0;i<64;c-=6)g[3&c]=0|((l=0|(l=y(),u=y(),d=y(),((a=i>>4<<2)?a>4?a>8?u^(l|~d):l^u^d:l&d|u&~d:l&u|~l&d)+(0|f[h+(i*(29521>>a)+(1296>>a)&15)])+(u="',16%).4$+07&*/5".charCodeAt(a+i%4)-32,o[63-i++]??=0|2**32*Math.abs(Math.sin(i)))+y()))<<u|l>>>32-u)+y();for(c=4;c;)s[--c]=g[c]=0|s[c]+g[c]}return g},a=(r,e,t=("string"==typeof r?r=(new TextEncoder).encode(r):r).length,n=[],o=8*t)=>{for(;t;)n[e+(--t>>>2)]|=r[t]<<t%4*8;return[n,o]};var md5=(r,e,t)=>{var n=16,o=null!=e,[h,i]=a(r,o*n),l=new Uint8Array(n);if(o){let[r,t]=a(e,0),o=e=>{for(;n;)h[--n]=16843009*e^r[n];n=16};t>512&&(r=f(r,t)),o(54),(h=f(h,512+i)).unshift(...Array(16)),o(92),i=640}for(h=f(h,i);n;)l[--n]=h[n>>2]>>>n%4*8;return t?l:l.reduce((r,e)=>r+(e>>4&&"")+e.toString(16),"")}}
2
+ {let r=1732584193,e=271733878,n=~r,t=~e,o=2**32,f=Math,a=f.floor,l=r=>16*a((r+8)/64)+16,i=[],u=(u,d,h=0,c=l(d),g,s,w,y,A=[r,t,n,e],v=[...A])=>{for(u[c-1]=0|8*d/o,u[c-2]=0|8*d,u[a(d/4)]|=128<<d%4*8;h<u.length;h+=16){for(y=c=0;c<64;)A[3&y]=0|((g=0|(g=A[3&++y],s=A[3&++y],w=A[3&++y],((d=c>>4<<2)?d>4?d>8?s^(g|~w):g^s^w:g&w|s&~w:g&s|~g&w)+(0|u[h+(c*(29521>>d)+(1296>>d)&15)])+(s=31&"',16%).4$+07&*/5".charCodeAt(d+c%4),i[63-c++]??=0|o*f.abs(f.sin(c)))+A[y+1&3]))<<s|g>>>32-s)+A[y+2&3];for(y=4;y;)v[--y]=A[y]=0|v[y]+A[y]}return A},d=(r,e,n=("string"==typeof r?r=(new TextEncoder).encode(r):r).length,t=new Int32Array(l(4*e+n)),o=0)=>{for(;o<n;)t[e++]=r[o++]|r[o++]<<8|r[o++]<<16|r[o++]<<24;return[t,n]};var md5=(r,e,n)=>{var t=16,o=null!=e,[f,a]=d(r,o*t),l=new Uint8Array(t);if(o){let[r,n]=d(e,0),o=[];for(n>64&&(r=u(r,n));t;)f[--t]=909522486^r[t],o[t]=1549556828^r[t];t=16,(f=u(f,64+a)).unshift(...o),a=80}for(f=u(f,a);t;)l[--t]=f[t>>2]>>>t%4*8;return n?l:l.reduce((r,e)=>r+(e>>4&&"")+e.toString(16),"")}}
package/main.d.ts CHANGED
@@ -9,8 +9,8 @@
9
9
  * @param {boolean} [raw] If true, the hash is returned as raw bytes (Uint8Array); otherwise, as a hex string.
10
10
  * @returns {string | Uint8Array<ArrayBuffer>} The MD5 (or HMAC‑MD5) digest, either as a hex string or a Uint8Array.
11
11
  */
12
- var md5: {
12
+ declare var md5: {
13
13
  (data: string | Uint8Array, key?: string | Uint8Array | null, raw?: false): string;
14
- (data: string | Uint8Array, key?: string | Uint8Array | null, raw: true): Uint8Array<ArrayBuffer>;
14
+ (data: string | Uint8Array, key: string | Uint8Array | null | undefined, raw: true): Uint8Array<ArrayBuffer>;
15
15
  };
16
16
  export default md5;
package/main.js CHANGED
@@ -7,14 +7,23 @@ let A = 1732584193
7
7
  , C = ~A
8
8
  , B = ~D
9
9
 
10
+ let $2_32 = 2 ** 32
11
+
12
+ let $Math = Math
13
+
14
+ let floor = $Math.floor
15
+
16
+ /** @param {number} byteLen */
17
+ let toBinlLen = (byteLen) => floor((byteLen + 8) / 64) * 16 + 16
18
+
10
19
  /** @type {number[]} MD5 constants cached in memory */
11
20
  let K = []
12
21
 
13
22
  /**
14
23
  * Calculate the MD5 of an array of little-endian words, and a bit length.
15
24
  *
16
- * @param {number[]} x Array of little-endian words
17
- * @param {number} l Bit length
25
+ * @param {Int32Array | number[]} x Array of little-endian words
26
+ * @param {number} l Byte length
18
27
  *
19
28
  * @param {number} [j]
20
29
  * @param {number} [t0]
@@ -29,28 +38,29 @@ let binlMD5 = (
29
38
  l,
30
39
  // var:
31
40
  i = 0,
32
- j,
41
+ j = toBinlLen(l),
33
42
  t0,
34
43
  t1,
35
44
  t2,
36
45
  oi,
37
46
  output = [A, B, C, D],
38
47
  oldOutput = [...output],
39
- o = (/**@type {*}*/ _) => output[++oi & 3],
40
48
  ) => {
49
+ // console.time("binlMD5")
41
50
 
42
51
  // append padding
43
- x[l + 64 >>> 9 << 4 | 14] = 0 | l;
44
- x[l >>> 5] |= 0x80 << l % 32;
52
+ x[j - 1] = 0 | l * 8 / $2_32;
53
+ x[j - 2] = 0 | l * 8;
54
+ x[floor(l / 4)] |= 0x80 << l % 4 * 8;
45
55
 
46
56
  for (; i < x.length; i += 16) {
47
- for (oi = j = 0; j < 64; oi -= 6) {
57
+ for (oi = j = 0; j < 64;) {
48
58
  output[oi & 3] = (
49
59
  t0 = 0 | (
50
60
  (
51
- t0 = o(),
52
- t1 = o(),
53
- t2 = o(),
61
+ t0 = output[++oi & 3],
62
+ t1 = output[++oi & 3],
63
+ t2 = output[++oi & 3],
54
64
  (l = j >> 4 << 2)
55
65
  ? l > 4
56
66
  ? l > 8
@@ -63,47 +73,54 @@ let binlMD5 = (
63
73
  0 | x[i + (j * (0x7351 >> l) + (0x0510 >> l) & 15)]
64
74
  ) +
65
75
  (
66
- t1 = "',16%).4$+07&*/5".charCodeAt(l + j % 4) - 32,
67
- K[63 - j++] ??= 0 | 2 ** 32 * Math.abs(Math.sin(j))
76
+ t1 = "',16%).4$+07&*/5".charCodeAt(l + j % 4) & 31,
77
+ K[63 - j++] ??= 0 | $2_32 * $Math.abs($Math.sin(j))
68
78
  ) +
69
- o()
79
+ output[oi + 1 & 3]
70
80
  ),
71
- 0 | (t0 << t1 | t0 >>> 32 - t1) + o()
81
+ 0 | (t0 << t1 | t0 >>> 32 - t1) + output[oi + 2 & 3]
72
82
  )
73
83
  }
74
84
  for (oi = 4; oi;) {
75
85
  oldOutput[--oi] = output[oi] = 0 | oldOutput[oi] + output[oi]
76
86
  }
77
87
  }
88
+ // console.timeEnd("binlMD5")
78
89
  return output
79
90
  }
80
91
 
81
92
  /**
82
93
  * Convert bytes to an array of little-endian words
83
94
  *
84
- * @param {string | Uint8Array} input
85
- * @param {number} padLen
86
- *
87
- * @param {number[]} [output]
95
+ * @param {*} input
96
+ * @param {number} j pad int32 length
88
97
  *
89
- * @returns {[number[], number]}
98
+ * @returns {[Int32Array<ArrayBuffer> | number[], number]}
90
99
  */
91
100
  let inputToBinl = (
92
101
  input,
93
- padLen,
102
+ j,
94
103
  // var:
95
- i = (
104
+ byteLen = (
96
105
  typeof input == 'string'
97
106
  ? input = new TextEncoder().encode(input)
98
107
  : input
99
108
  ).length,
100
- output = [],
101
- bitLen = 8 * i,
109
+ // Using Array would fail to handle large files, so Int32Array must be used.
110
+ output = new Int32Array(toBinlLen(j * 4 + byteLen)),
111
+ i = 0,
102
112
  ) => {
103
- for (; i;) {
104
- output[padLen + (--i >>> 2)] |= /**@type {Uint8Array}*/(input)[i] << i % 4 * 8
113
+ // console.time("inputToBinl")
114
+ for (; i < byteLen;) {
115
+ output[j++] = (
116
+ input[i++] |
117
+ input[i++] << 8 |
118
+ input[i++] << 16 |
119
+ input[i++] << 24
120
+ )
105
121
  }
106
- return [output, bitLen]
122
+ // console.timeEnd("inputToBinl")
123
+ return [output, byteLen]
107
124
  }
108
125
 
109
126
  /**
@@ -116,7 +133,7 @@ let inputToBinl = (
116
133
  /**
117
134
  * @overload
118
135
  * @param {string | Uint8Array} data
119
- * @param {string | Uint8Array | null} [key]
136
+ * @param {string | Uint8Array | null | undefined} key
120
137
  * @param {true} raw
121
138
  * @returns {Uint8Array<ArrayBuffer>}
122
139
  */
@@ -134,29 +151,27 @@ let inputToBinl = (
134
151
  var md5 = (data, key, raw) => {
135
152
  var i = 16
136
153
  , hasKey = key != null
137
- , [bdata, bitLen] = inputToBinl(data, /**@type {*}*/(hasKey) * i)
154
+ , [bdata, dataByteLen] = inputToBinl(data, /**@type {*}*/(hasKey) * i)
138
155
  , out = new Uint8Array(i)
139
156
 
140
157
  if (hasKey) {
141
158
  // HMAC
142
- let [bkey, keyBitlen] = inputToBinl(key, 0)
143
- , pad = (/**@type {number}*/ x) => {
144
- for (; i;) {
145
- bdata[--i] = 0x01010101 * x ^ bkey[i]
146
- }
147
- i = 16
148
- }
149
- if (keyBitlen > 512) {
150
- bkey = binlMD5(bkey, keyBitlen)
159
+ let [bkey, keyByteLen] = inputToBinl(key, 0)
160
+ let pad5cArr = []
161
+ if (keyByteLen > 64) {
162
+ bkey = binlMD5(bkey, keyByteLen)
163
+ }
164
+ for (; i;) {
165
+ bdata[--i] = 0x36363636 ^ bkey[i]
166
+ pad5cArr[i] = 0x5c5c5c5c ^ bkey[i]
151
167
  }
152
- pad(0x36)
153
- bdata = binlMD5(bdata, 512 + bitLen)
154
- bdata.unshift(...Array(16))
155
- pad(0x5c)
156
- bitLen = 640
168
+ i = 16
169
+ bdata = binlMD5(bdata, 64 + dataByteLen)
170
+ bdata.unshift(...pad5cArr)
171
+ dataByteLen = 80
157
172
  }
158
173
 
159
- bdata = binlMD5(bdata, bitLen)
174
+ bdata = binlMD5(bdata, dataByteLen)
160
175
 
161
176
  // binl to bytes
162
177
  for (; i;) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "tinyhmacmd5",
3
- "version": "0.0.6",
4
- "description": "A tiny JavaScript HMAC-MD5 implementation. The minified browser bundle is only 965 bytes.",
3
+ "version": "0.1.0",
4
+ "description": "A tiny, reliable JavaScript HMAC-MD5 implementation. The minified browser bundle is only 1057 bytes.",
5
5
  "author": "bddjr",
6
6
  "license": "MIT",
7
7
  "type": "module",
@@ -32,10 +32,11 @@
32
32
  "devDependencies": {
33
33
  "es-check": "^9.6.4",
34
34
  "terser": "^5.49.0",
35
- "tinyhmacmd5": "link:"
35
+ "tinyhmacmd5": "link:",
36
+ "typescript": "^7.0.2"
36
37
  },
37
38
  "scripts": {
38
- "build": "node scripts/build.mjs && es-check es2021 --module --checkFeatures main.js browser.min.js",
39
+ "build": "tsc && node scripts/build.mjs && es-check es2021 --module --checkFeatures main.js browser.min.js",
39
40
  "test": "pnpm build && node scripts/test.mjs"
40
41
  }
41
42
  }