functionalscript 0.0.299 → 0.0.303

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": "functionalscript",
3
- "version": "0.0.299",
3
+ "version": "0.0.303",
4
4
  "description": "FunctionalScript is a functional subset of JavaScript",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/sha2/index.js ADDED
@@ -0,0 +1,178 @@
1
+ /**
2
+ * @typedef {{
3
+ * readonly f: (i: number) => number
4
+ * readonly length: number
5
+ * }} HashInput
6
+ */
7
+
8
+ /** @typedef {Int32Array} Hash8 */
9
+
10
+ /** @typedef {Int32Array} Array16 */
11
+
12
+ /** @type {(input: number) => (pos: number) => number} */
13
+ const appendOne = input => pos => input | (1 << 31 - pos)
14
+
15
+ /** @type {(input: number) => (pos: number) => number} */
16
+ const mod = a => b => (a % b + b) % b
17
+
18
+ /** @type {(input: readonly number[]) => (bits: number) => HashInput} */
19
+ const padding = input => bitsCount => {
20
+ const appendBlockIndex = (bitsCount / 32) | 0
21
+ const length = (bitsCount + mod(447 - bitsCount)(512) + 65) / 32
22
+ /** @type {(i: number) => number} */
23
+ const f = i =>
24
+ i < appendBlockIndex ?
25
+ input[i] :
26
+ i === appendBlockIndex ?
27
+ (appendBlockIndex >= input.length ? 0x8000_0000 : appendOne(input[appendBlockIndex])(bitsCount % 32)) :
28
+ i === length - 2 ?
29
+ (bitsCount / 0x1_0000_0000) | 0 :
30
+ i === length - 1 ?
31
+ bitsCount % 0x1_0000_0000 : 0
32
+ return ({ f, length })
33
+ }
34
+
35
+ /** @type {(d: number) => (n: number) => number} */
36
+ const rotr = d => {
37
+ const r = 32 - d
38
+ return n => n >>> d | n << r
39
+ }
40
+
41
+ /** @type {(x: number) => (y: number) => (z: number) => number} */
42
+ const ch = x => y => z => x & y ^ ~x & z
43
+
44
+ /** @type {(x: number) => (y: number) => (z: number) => number} */
45
+ const maj = x => y => z => x & y ^ x & z ^ y & z
46
+
47
+ /** @type {(d: number) => (n: number) => number} */
48
+ const shr = d => n => n >>> d
49
+
50
+ /** @type {(a: number) => (b: number) => (c: number) => (x: number) => number} */
51
+ const bigSigma = a => b => c => {
52
+ const ra = rotr(a)
53
+ const rb = rotr(b)
54
+ const rc = rotr(c)
55
+ return x => ra(x) ^ rb(x) ^ rc(x)
56
+ }
57
+
58
+ const bigSigma0 = bigSigma(2)(13)(22)
59
+
60
+ const bigSigma1 = bigSigma(6)(11)(25)
61
+
62
+ /** @type {(a: number) => (b: number) => (c: number) => (x: number) => number} */
63
+ const smallSigma = a => b => c => {
64
+ const ra = rotr(a)
65
+ const rb = rotr(b)
66
+ const sc = shr(c)
67
+ return x => ra(x) ^ rb(x) ^ sc(x)
68
+ }
69
+
70
+ const smallSigma0 = smallSigma(7)(18)(3)
71
+
72
+ const smallSigma1 = smallSigma(17)(19)(10)
73
+
74
+ /** @type {Hash8} */
75
+ const init256 = new Int32Array([0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19])
76
+
77
+ /** @type {(input: readonly number[]) => (bitsCount: number) => Hash8} */
78
+ const computeSha256 = input => bitsCount => compute(input)(bitsCount)(init256)
79
+
80
+ /** @type {Hash8} */
81
+ const init224 = new Int32Array([0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4])
82
+
83
+ const k = [
84
+ new Int32Array([
85
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
86
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174]),
87
+ new Int32Array([
88
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
89
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967]),
90
+ new Int32Array([
91
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
92
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070]),
93
+ new Int32Array([
94
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
95
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2]),
96
+ ];
97
+
98
+ /** @type {(input: readonly number[]) => (bitsCount: number) => Hash8} */
99
+ const computeSha224 = input => bitsCount => compute(input)(bitsCount)(init224)
100
+
101
+ /** @type {(input: Array16) => Array16} */
102
+ const nextW = w => {
103
+ for (let t = 0; t < 16; t++) {
104
+ w[t] = smallSigma1(w[(t + 14) & 0xF]) + w[(t + 9) & 0xF] + smallSigma0(w[(t + 1) & 0xF]) + w[t]
105
+ }
106
+ return w
107
+ }
108
+
109
+ /** @type {(init: Hash8) => (data: Array16) => Hash8} */
110
+ const compress = init => data => {
111
+ let w = new Int32Array(16)
112
+ for (let t = 0; t < 16; t++) {
113
+ w[t] = data[t]
114
+ }
115
+
116
+ let a = init[0]
117
+ let b = init[1]
118
+ let c = init[2]
119
+ let d = init[3]
120
+ let e = init[4]
121
+ let f = init[5]
122
+ let g = init[6]
123
+ let h = init[7]
124
+
125
+ for (let i = 0; i < 4; ++i) {
126
+ const ki = k[i]
127
+ for (let j = 0; j < 16; ++j) {
128
+ const t1 = h + bigSigma1(e) + ch(e)(f)(g) + ki[j] + w[j]
129
+ const t2 = bigSigma0(a) + maj(a)(b)(c)
130
+ h = g
131
+ g = f
132
+ f = e
133
+ e = (d + t1) | 0
134
+ d = c
135
+ c = b
136
+ b = a
137
+ a = (t1 + t2) | 0
138
+ }
139
+ w = nextW(w)
140
+ }
141
+
142
+ return new Int32Array([
143
+ init[0] + a,
144
+ init[1] + b,
145
+ init[2] + c,
146
+ init[3] + d,
147
+ init[4] + e,
148
+ init[5] + f,
149
+ init[6] + g,
150
+ init[7] + h,
151
+ ])
152
+ }
153
+
154
+ /** @type {(input: readonly number[]) => (bitsCount: number) => (init: Hash8) => Hash8} */
155
+ const compute = input => bitsCount => init => {
156
+ const { f, length } = padding(input)(bitsCount)
157
+
158
+ let result = init
159
+
160
+ const chunkCount = length / 16
161
+ for (let i = 0; i < chunkCount; i++) {
162
+ const s = i * 16
163
+ result = compress(result)(new Int32Array([
164
+ f(s + 0), f(s + 1), f(s + 2), f(s + 3), f(s + 4), f(s + 5), f(s + 6), f(s + 7),
165
+ f(s + 8), f(s + 9), f(s + 10), f(s + 11), f(s + 12), f(s + 13), f(s + 14), f(s + 15)]))
166
+ }
167
+
168
+ return result
169
+ }
170
+
171
+ module.exports = {
172
+ /** @readonly */
173
+ padding,
174
+ /** @readonly */
175
+ computeSha256,
176
+ /** @readonly */
177
+ computeSha224
178
+ }
@@ -1,12 +1,13 @@
1
1
  const _ = require('.')
2
- const json = require('../../json')
3
- const { sort } = require('../object')
2
+ const json = require('../json')
3
+ const { sort } = require('../types/object')
4
+ const list = require('../types/list')
5
+
6
+ /** @type {(a: number) => number} */
7
+ const toU32 = x => (x + 0x1_0000_0000) % 0x1_0000_0000
4
8
 
5
9
  /** @type {(a: number) => string} */
6
- const toHexString = x =>
7
- {
8
- return x >= 0 ? x.toString(16).padStart(8, '0') : (x + 0x100000000).toString(16).padStart(8, '0')
9
- }
10
+ const toHexString = x => toU32(x).toString(16).padStart(8, '0')
10
11
 
11
12
  /** @type {(a: readonly json.Unknown[]) => string} */
12
13
  const stringify = a => json.stringify(sort)(a)
@@ -33,27 +34,33 @@ const stringify = a => json.stringify(sort)(a)
33
34
 
34
35
  {
35
36
  const hash = _.computeSha256([])(0)
36
- const result = stringify(hash.map(toHexString))
37
+ const result = stringify(Array.from(hash).map(toHexString))
37
38
  if (result !== '["e3b0c442","98fc1c14","9afbf4c8","996fb924","27ae41e4","649b934c","a495991b","7852b855"]') { throw result }
38
39
  }
39
40
 
41
+ {
42
+ const hash = _.computeSha224([])(0)
43
+ const result = stringify(Array.from(hash).map(toHexString))
44
+ if (result !== '["d14a028c","2a3a2bc9","476102bb","288234c4","15a2b01f","828ea62a","c5b3e42f","bdd387cb"]') { throw result }
45
+ }
46
+
40
47
  {
41
48
  //[0x68656C6C, 0x6F20776F, 0x726C6400] represents phrase 'hello world'
42
49
  const hash = _.computeSha256([0x68656C6C, 0x6F20776F, 0x726C6400])(88)
43
- const result = stringify(hash.map(toHexString))
50
+ const result = stringify(Array.from(hash).map(toHexString))
44
51
  if (result !== '["b94d27b9","934d3e08","a52e52d7","da7dabfa","c484efe3","7a5380ee","9088f7ac","e2efcde9"]') { throw result }
45
52
  }
46
53
 
47
54
  {
48
55
  const input = Array(8).fill(0x31313131)
49
56
  const result = _.computeSha256(input)(256)
50
- if (result[0] !== 0x8a83665f) { throw result[0] }
57
+ if (toU32(result[0]) !== 0x8a83665f) { throw result[0] }
51
58
  }
52
59
 
53
60
  {
54
61
  const input = Array(16).fill(0x31313131)
55
62
  const hash = _.computeSha256(input)(512)
56
- const result = stringify(hash.map(toHexString))
63
+ const result = stringify(Array.from(hash).map(toHexString))
57
64
  if (result !== '["3138bb9b","c78df27c","473ecfd1","410f7bd4","5ebac1f5","9cf3ff9c","fe4db77a","ab7aedd3"]') { throw result }
58
65
  }
59
66
 
package/test.js CHANGED
@@ -3,7 +3,7 @@ const i = require('./')
3
3
  require('./types/list/test')
4
4
  require('./types/array/test')
5
5
  require('./types/btree/test')
6
- require('./types/crypto/test')
6
+ require('./sha2/test')
7
7
  require('./json/test')
8
8
  require('./types/object/test')
9
9
  require('./io/commonjs/test')
@@ -47,6 +47,16 @@ const seq = require('../list')
47
47
  * @typedef {readonly[T, T, T, T, T]} Array5
48
48
  */
49
49
 
50
+ /**
51
+ * @template T
52
+ * @typedef {readonly[T, T, T, T, T, T, T, T]} Array8
53
+ */
54
+
55
+ /**
56
+ * @template T
57
+ * @typedef {readonly[T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T]} Array16
58
+ */
59
+
50
60
  /**
51
61
  * @template T
52
62
  * @typedef {Array1<T>| Array2<T> | Array3<T> | Array4<T> | Array5<T>} Array1_5
@@ -1,192 +0,0 @@
1
- /**
2
- * @typedef {{
3
- * readonly input: number[]
4
- * readonly length: number
5
- * }} HashInput
6
- */
7
-
8
- /**
9
- * @typedef {readonly[number, number, number, number, number, number, number, number]} HashOutput8
10
- */
11
-
12
- /** @type {(input: number) => (pos: number) => number} */
13
- const appendOne = input => pos =>
14
- {
15
- return input | (1 << 31 - pos)
16
- }
17
-
18
- /** @type {(input: number) => (pos: number) => number} */
19
- const unsignedMod = a => b =>
20
- {
21
- return (a % b + b) % b
22
- }
23
-
24
- /** @type {(input: number[]) => (length: number) => readonly number[]} */
25
- const padding = input => length =>
26
- {
27
- const appendBlockIndex = Math.floor(length / 32)
28
- //console.log(appendBlockIndex)
29
- const k = unsignedMod(447 - length)(512)
30
- //console.log(k)
31
- const outputLength = length + k + 65
32
- //console.log(outputLength)
33
- let o = new Array(outputLength / 32)
34
- //console.log(o.length)
35
- /** @type {(i: number) => number} */
36
- const f = i =>
37
- i < appendBlockIndex ?
38
- input[i] :
39
- i === appendBlockIndex ?
40
- (appendBlockIndex >= input.length ? 0x80000000 : appendOne(input[appendBlockIndex])(length % 32)) :
41
- i === o.length - 2 ? (length / 4294967296) | 0 :
42
- i === o.length - 1 ? length % 4294967296 : 0
43
- for(let i = 0; i < o.length; i++)
44
- {
45
- o[i] = f(i)
46
- }
47
- return o;
48
- }
49
-
50
- /** @type {(x: number) => (y: number) => (z: number) => number} */
51
- const ch = x => y => z =>
52
- {
53
- return x & y ^ ~x & z
54
- }
55
-
56
- /** @type {(x: number) => (y: number) => (z: number) => number} */
57
- const maj = x => y => z =>
58
- {
59
- return x & y ^ x & z ^ y & z
60
- }
61
-
62
- /** @type {(n: number) => (d: number) => number} */
63
- const rotr = n => d =>
64
- {
65
- return n >>> d | n << (32-d)
66
- }
67
-
68
- /** @type {(n: number) => (d: number) => number} */
69
- const shr = n => d =>
70
- {
71
- return n >>> d
72
- }
73
-
74
- /** @type {(x: number) => number} */
75
- const bsig0 = x =>
76
- {
77
- return rotr(x)(2) ^ rotr(x)(13) ^ rotr(x)(22)
78
- }
79
-
80
- /** @type {(x: number) => number} */
81
- const bsig1 = x =>
82
- {
83
- return rotr(x)(6) ^ rotr(x)(11) ^ rotr(x)(25)
84
- }
85
-
86
- /** @type {(x: number) => number} */
87
- const ssig0 = x =>
88
- {
89
- return rotr(x)(7) ^ rotr(x)(18) ^ shr(x)(3)
90
- }
91
-
92
- /** @type {(x: number) => number} */
93
- const ssig1 = x =>
94
- {
95
- return rotr(x)(17) ^ rotr(x)(19) ^ shr(x)(10)
96
- }
97
-
98
- /** @type {(x: number) => number} */
99
- const mod2pow32 = x =>
100
- {
101
- return x % 4294967296
102
- }
103
-
104
- /** @type {(input: number[]) => (length: number) => HashOutput8} */
105
- const computeSha256 = input => length =>
106
- {
107
- const padded = padding(input)(length)
108
-
109
- let h0 = 0x6a09e667
110
- let h1 = 0xbb67ae85
111
- let h2 = 0x3c6ef372
112
- let h3 = 0xa54ff53a
113
- let h4 = 0x510e527f
114
- let h5 = 0x9b05688c
115
- let h6 = 0x1f83d9ab
116
- let h7 = 0x5be0cd19
117
-
118
- const k = [
119
- 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
120
- 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
121
- 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
122
- 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
123
- 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
124
- 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
125
- 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
126
- 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
127
- ];
128
-
129
- // /** @type {(a: number) => string} */
130
- // const toHexString = x =>
131
- // {
132
- // return x >= 0 ? x.toString(16).padStart(8, '0') : (x + 0x100000000).toString(16).padStart(8, '0')
133
- // }
134
-
135
- let w = new Array(64)
136
- const chunkCount = padded.length / 16
137
- for(let i = 0; i < chunkCount; i++)
138
- {
139
- for(let t = 0; t < 16; t++)
140
- {
141
- w[t] = padded[t + i * 16]
142
- }
143
-
144
- for(let t = 16; t < 64; t++)
145
- {
146
- w[t] = mod2pow32(ssig1(w[t - 2]) + w[t - 7] + ssig0(w[t-15]) + w[t - 16])
147
- }
148
-
149
- //console.log(w.map(toHexString))
150
-
151
- let a = h0
152
- let b = h1
153
- let c = h2
154
- let d = h3
155
- let e = h4
156
- let f = h5
157
- let g = h6
158
- let h = h7
159
-
160
- for(let t = 0; t < 64; t++)
161
- {
162
- let t1 = mod2pow32(h + bsig1(e) + ch(e)(f)(g) + k[t] + w[t])
163
- let t2 = mod2pow32(bsig0(a) + maj(a)(b)(c))
164
- h = g
165
- g = f
166
- f = e
167
- e = mod2pow32(d + t1)
168
- d = c
169
- c = b
170
- b = a
171
- a = mod2pow32(t1 + t2)
172
- }
173
-
174
- h0 = mod2pow32(h0 + a)
175
- h1 = mod2pow32(h1 + b)
176
- h2 = mod2pow32(h2+ c)
177
- h3 = mod2pow32(h3 + d)
178
- h4 = mod2pow32(h4 + e)
179
- h5 = mod2pow32(h5 + f)
180
- h6 = mod2pow32(h6 + g)
181
- h7 = mod2pow32(h7 + h)
182
- }
183
-
184
- return [h0, h1, h2, h3, h4, h5, h6, h7]
185
- }
186
-
187
- module.exports = {
188
- /** @readonly */
189
- padding,
190
- /** @readonly */
191
- computeSha256,
192
- }