functionalscript 0.0.296 → 0.0.300

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/LANGUAGE.md CHANGED
@@ -167,7 +167,7 @@ const f = x => {
167
167
 
168
168
  ## 9. Statements
169
169
 
170
- `{ A_LIST_OF_STATEMENTS }` is one or many statements seperated by the newline control character. One of these statements mentioned earlier was [definition](#25-Definitions), also known as a [const](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const) statement. The other statements are described below.
170
+ `{ A_LIST_OF_STATEMENTS }` is one or many statements seperated by the newline control character. One of these statements mentioned earlier was [definition](#5-Definitions), also known as a [const](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const) statement. The other statements are described below.
171
171
 
172
172
  ### 9.1. Let
173
173
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "functionalscript",
3
- "version": "0.0.296",
3
+ "version": "0.0.300",
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,155 @@
1
+ /**
2
+ * @typedef {{
3
+ * readonly f: (i: number) => number
4
+ * readonly length: number
5
+ * }} HashInput
6
+ */
7
+
8
+ /**
9
+ * @typedef {readonly[number, number, number, number, number, number, number, number]} Hash8
10
+ */
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 unsignedMod = a => b => (a % b + b) % b
17
+
18
+ /** @type {(input: readonly number[]) => (bits: number) => HashInput} */
19
+ const padding = input => bitsCount =>
20
+ {
21
+ const appendBlockIndex = (bitsCount / 32) | 0
22
+ const length = (bitsCount + unsignedMod(447 - bitsCount)(512) + 65) / 32
23
+ /** @type {(i: number) => number} */
24
+ const f = i =>
25
+ i < appendBlockIndex ?
26
+ input[i] :
27
+ i === appendBlockIndex ?
28
+ (appendBlockIndex >= input.length ? 0x80000000 : appendOne(input[appendBlockIndex])(bitsCount % 32)) :
29
+ i === length - 2 ? (bitsCount / 0x100000000) | 0 :
30
+ i === length - 1 ? bitsCount % 0x100000000 : 0
31
+ return ({f, length})
32
+ }
33
+
34
+ /** @type {(x: number) => (y: number) => (z: number) => number} */
35
+ const ch = x => y => z => x & y ^ ~x & z
36
+
37
+ /** @type {(x: number) => (y: number) => (z: number) => number} */
38
+ const maj = x => y => z => x & y ^ x & z ^ y & z
39
+
40
+ /** @type {(n: number) => (d: number) => number} */
41
+ const rotr = n => d => n >>> d | n << (32-d)
42
+
43
+ /** @type {(n: number) => (d: number) => number} */
44
+ const shr = n => d => n >>> d
45
+
46
+ /** @type {(x: number) => number} */
47
+ const bsig0 = x => rotr(x)(2) ^ rotr(x)(13) ^ rotr(x)(22)
48
+
49
+ /** @type {(x: number) => number} */
50
+ const bsig1 = x => rotr(x)(6) ^ rotr(x)(11) ^ rotr(x)(25)
51
+
52
+ /** @type {(x: number) => number} */
53
+ const ssig0 = x => rotr(x)(7) ^ rotr(x)(18) ^ shr(x)(3)
54
+
55
+ /** @type {(x: number) => number} */
56
+ const ssig1 = x => rotr(x)(17) ^ rotr(x)(19) ^ shr(x)(10)
57
+
58
+ /** @type {(x: number) => number} */
59
+ const mod2pow32 = x => x % 0x100000000
60
+
61
+ /** @type {Hash8} */
62
+ const init256 = [0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19]
63
+
64
+ /** @type {(input: readonly number[]) => (bitsCount: number) => Hash8} */
65
+ const computeSha256 = input => bitsCount => compute(input)(bitsCount)(init256)
66
+
67
+ /** @type {Hash8} */
68
+ const init224 = [0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4]
69
+
70
+ /** @type {(input: readonly number[]) => (bitsCount: number) => Hash8} */
71
+ const computeSha224 = input => bitsCount => compute(input)(bitsCount)(init224)
72
+
73
+ /** @type {(input: readonly number[]) => (bitsCount: number) => (init: Hash8) => Hash8} */
74
+ const compute = input => bitsCount => init =>
75
+ {
76
+ const padded = padding(input)(bitsCount)
77
+
78
+ let h0 = init[0]
79
+ let h1 = init[1]
80
+ let h2 = init[2]
81
+ let h3 = init[3]
82
+ let h4 = init[4]
83
+ let h5 = init[5]
84
+ let h6 = init[6]
85
+ let h7 = init[7]
86
+
87
+ const k = [
88
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
89
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
90
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
91
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
92
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
93
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
94
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
95
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
96
+ ];
97
+
98
+ let w = new Array(64)
99
+ const chunkCount = padded.length / 16
100
+ for(let i = 0; i < chunkCount; i++)
101
+ {
102
+ for(let t = 0; t < 16; t++)
103
+ {
104
+ w[t] = padded.f(t + i * 16)
105
+ }
106
+
107
+ for(let t = 16; t < 64; t++)
108
+ {
109
+ w[t] = mod2pow32(ssig1(w[t - 2]) + w[t - 7] + ssig0(w[t-15]) + w[t - 16])
110
+ }
111
+
112
+ let a = h0
113
+ let b = h1
114
+ let c = h2
115
+ let d = h3
116
+ let e = h4
117
+ let f = h5
118
+ let g = h6
119
+ let h = h7
120
+
121
+ for(let t = 0; t < 64; t++)
122
+ {
123
+ let t1 = mod2pow32(h + bsig1(e) + ch(e)(f)(g) + k[t] + w[t])
124
+ let t2 = mod2pow32(bsig0(a) + maj(a)(b)(c))
125
+ h = g
126
+ g = f
127
+ f = e
128
+ e = mod2pow32(d + t1)
129
+ d = c
130
+ c = b
131
+ b = a
132
+ a = mod2pow32(t1 + t2)
133
+ }
134
+
135
+ h0 = mod2pow32(h0 + a)
136
+ h1 = mod2pow32(h1 + b)
137
+ h2 = mod2pow32(h2+ c)
138
+ h3 = mod2pow32(h3 + d)
139
+ h4 = mod2pow32(h4 + e)
140
+ h5 = mod2pow32(h5 + f)
141
+ h6 = mod2pow32(h6 + g)
142
+ h7 = mod2pow32(h7 + h)
143
+ }
144
+
145
+ return [h0, h1, h2, h3, h4, h5, h6, h7]
146
+ }
147
+
148
+ module.exports = {
149
+ /** @readonly */
150
+ padding,
151
+ /** @readonly */
152
+ computeSha256,
153
+ /** @readonly */
154
+ computeSha224
155
+ }
package/sha2/test.js ADDED
@@ -0,0 +1,65 @@
1
+ const _ = require('.')
2
+ const json = require('../json')
3
+ const { sort } = require('../types/object')
4
+
5
+ /** @type {(a: number) => string} */
6
+ const toHexString = x => x >= 0 ? x.toString(16).padStart(8, '0') : (x + 0x100000000).toString(16).padStart(8, '0')
7
+
8
+ /** @type {(a: readonly json.Unknown[]) => string} */
9
+ const stringify = a => json.stringify(sort)(a)
10
+
11
+ // {
12
+ // const result = _.padding([])(0)
13
+ // console.log(result.map(toHexString))
14
+ // }
15
+
16
+ // {
17
+ // const result = _.padding([0x61626364, 0x65000000])(40)
18
+ // console.log(result.map(toHexString))
19
+ // }
20
+
21
+ // {
22
+ // const result = _.padding([0x11111110])(31)
23
+ // console.log(result.map(toHexString))
24
+ // }
25
+
26
+ // {
27
+ // const result = _.padding([0x11111110])(32)
28
+ // console.log(result.map(toHexString))
29
+ // }
30
+
31
+ {
32
+ const hash = _.computeSha256([])(0)
33
+ const result = stringify(hash.map(toHexString))
34
+ if (result !== '["e3b0c442","98fc1c14","9afbf4c8","996fb924","27ae41e4","649b934c","a495991b","7852b855"]') { throw result }
35
+ }
36
+
37
+ {
38
+ const hash = _.computeSha224([])(0)
39
+ const result = stringify(hash.map(toHexString))
40
+ if (result !== '["d14a028c","2a3a2bc9","476102bb","288234c4","15a2b01f","828ea62a","c5b3e42f","bdd387cb"]') { throw result }
41
+ }
42
+
43
+ {
44
+ //[0x68656C6C, 0x6F20776F, 0x726C6400] represents phrase 'hello world'
45
+ const hash = _.computeSha256([0x68656C6C, 0x6F20776F, 0x726C6400])(88)
46
+ const result = stringify(hash.map(toHexString))
47
+ if (result !== '["b94d27b9","934d3e08","a52e52d7","da7dabfa","c484efe3","7a5380ee","9088f7ac","e2efcde9"]') { throw result }
48
+ }
49
+
50
+ {
51
+ const input = Array(8).fill(0x31313131)
52
+ const result = _.computeSha256(input)(256)
53
+ if (result[0] !== 0x8a83665f) { throw result[0] }
54
+ }
55
+
56
+ {
57
+ const input = Array(16).fill(0x31313131)
58
+ const hash = _.computeSha256(input)(512)
59
+ const result = stringify(hash.map(toHexString))
60
+ if (result !== '["3138bb9b","c78df27c","473ecfd1","410f7bd4","5ebac1f5","9cf3ff9c","fe4db77a","ab7aedd3"]') { throw result }
61
+ }
62
+
63
+ module.exports = {
64
+
65
+ }
package/test.js CHANGED
@@ -3,6 +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('./sha2/test')
6
7
  require('./json/test')
7
8
  require('./types/object/test')
8
9
  require('./io/commonjs/test')