1 | /*
|
2 | * Note 1: All the functions in this file guarantee only that the bottom 32-bits of the return value are correct.
|
3 | * JavaScript is flakey when it comes to bit operations and a '1' in the highest order bit of a 32-bit number causes
|
4 | * it to be interpreted as a negative number per two's complement.
|
5 | *
|
6 | * Note 2: Per the ECMAScript spec, all JavaScript operations mask the shift amount by 0x1F. This results in weird
|
7 | * cases like 1 << 32 == 1 and 1 << 33 === 1 << 1 === 2
|
8 | */
|
9 |
|
10 | /**
|
11 | * The 32-bit implementation of circular rotate left.
|
12 | *
|
13 | * @param x The 32-bit integer argument.
|
14 | * @param n The number of bits to shift.
|
15 | * @returns `x` shifted left circularly by `n` bits
|
16 | */
|
17 | export function rotl_32(x: number, n: number): number {
|
18 | return (x << n) | (x >>> (32 - n));
|
19 | }
|
20 |
|
21 | /**
|
22 | * The 32-bit implementation of circular rotate right.
|
23 | *
|
24 | * @param x The 32-bit integer argument.
|
25 | * @param n The number of bits to shift.
|
26 | * @returns `x` shifted right circularly by `n` bits
|
27 | */
|
28 | function rotr_32(x: number, n: number): number {
|
29 | return (x >>> n) | (x << (32 - n));
|
30 | }
|
31 |
|
32 | /**
|
33 | * The 32-bit implementation of shift right.
|
34 | *
|
35 | * @param x The 32-bit integer argument.
|
36 | * @param n The number of bits to shift.
|
37 | * @returns `x` shifted by `n` bits.
|
38 | */
|
39 | function shr_32(x: number, n: number): number {
|
40 | return x >>> n;
|
41 | }
|
42 |
|
43 | /**
|
44 | * The 32-bit implementation of the NIST specified Parity function.
|
45 | *
|
46 | * @param x The first 32-bit integer argument.
|
47 | * @param y The second 32-bit integer argument.
|
48 | * @param z The third 32-bit integer argument.
|
49 | * @returns The NIST specified output of the function.
|
50 | */
|
51 | export function parity_32(x: number, y: number, z: number): number {
|
52 | return x ^ y ^ z;
|
53 | }
|
54 |
|
55 | /**
|
56 | * The 32-bit implementation of the NIST specified Ch function.
|
57 | *
|
58 | * @param x The first 32-bit integer argument.
|
59 | * @param y The second 32-bit integer argument.
|
60 | * @param z The third 32-bit integer argument.
|
61 | * @returns The NIST specified output of the function.
|
62 | */
|
63 | export function ch_32(x: number, y: number, z: number): number {
|
64 | return (x & y) ^ (~x & z);
|
65 | }
|
66 |
|
67 | /**
|
68 | * The 32-bit implementation of the NIST specified Maj function.
|
69 | *
|
70 | * @param x The first 32-bit integer argument.
|
71 | * @param y The second 32-bit integer argument.
|
72 | * @param z The third 32-bit integer argument.
|
73 | * @returns The NIST specified output of the function.
|
74 | */
|
75 | export function maj_32(x: number, y: number, z: number): number {
|
76 | return (x & y) ^ (x & z) ^ (y & z);
|
77 | }
|
78 |
|
79 | /**
|
80 | * The 32-bit implementation of the NIST specified Sigma0 function.
|
81 | *
|
82 | * @param x The 32-bit integer argument.
|
83 | * @returns The NIST specified output of the function.
|
84 | */
|
85 | export function sigma0_32(x: number): number {
|
86 | return rotr_32(x, 2) ^ rotr_32(x, 13) ^ rotr_32(x, 22);
|
87 | }
|
88 |
|
89 | /**
|
90 | * Add two 32-bit integers.
|
91 | *
|
92 | * This uses 16-bit operations internally to work around sign problems due to JavaScript's lack of uint32 support.
|
93 | *
|
94 | * @param a The first 32-bit integer argument to be added.
|
95 | * @param b The second 32-bit integer argument to be added.
|
96 | * @returns The sum of `a` + `b`.
|
97 | */
|
98 | export function safeAdd_32_2(a: number, b: number): number {
|
99 | const lsw = (a & 0xffff) + (b & 0xffff),
|
100 | msw = (a >>> 16) + (b >>> 16) + (lsw >>> 16);
|
101 |
|
102 | return ((msw & 0xffff) << 16) | (lsw & 0xffff);
|
103 | }
|
104 |
|
105 | /**
|
106 | * Add four 32-bit integers.
|
107 | *
|
108 | * This uses 16-bit operations internally to work around sign problems due to JavaScript's lack of uint32 support.
|
109 | *
|
110 | * @param a The first 32-bit integer argument to be added.
|
111 | * @param b The second 32-bit integer argument to be added.
|
112 | * @param c The third 32-bit integer argument to be added.
|
113 | * @param d The fourth 32-bit integer argument to be added.
|
114 | * @returns The sum of `a` + `b` + `c` + `d`.
|
115 | */
|
116 | export function safeAdd_32_4(a: number, b: number, c: number, d: number): number {
|
117 | const lsw = (a & 0xffff) + (b & 0xffff) + (c & 0xffff) + (d & 0xffff),
|
118 | msw = (a >>> 16) + (b >>> 16) + (c >>> 16) + (d >>> 16) + (lsw >>> 16);
|
119 |
|
120 | return ((msw & 0xffff) << 16) | (lsw & 0xffff);
|
121 | }
|
122 |
|
123 | /**
|
124 | * Add five 32-bit integers.
|
125 | *
|
126 | * This uses 16-bit operations internally to work around sign problems due to JavaScript's lack of uint32 support.
|
127 | *
|
128 | * @param a The first 32-bit integer argument to be added.
|
129 | * @param b The second 32-bit integer argument to be added.
|
130 | * @param c The third 32-bit integer argument to be added.
|
131 | * @param d The fourth 32-bit integer argument to be added.
|
132 | * @param e The fifth 32-bit integer argument to be added.
|
133 | * @returns The sum of `a` + `b` + `c` + `d` + `e`.
|
134 | */
|
135 | export function safeAdd_32_5(a: number, b: number, c: number, d: number, e: number): number {
|
136 | const lsw = (a & 0xffff) + (b & 0xffff) + (c & 0xffff) + (d & 0xffff) + (e & 0xffff),
|
137 | msw = (a >>> 16) + (b >>> 16) + (c >>> 16) + (d >>> 16) + (e >>> 16) + (lsw >>> 16);
|
138 |
|
139 | return ((msw & 0xffff) << 16) | (lsw & 0xffff);
|
140 | }
|
141 |
|
142 | /**
|
143 | * The 32-bit implementation of the NIST specified Gamma1 function.
|
144 | *
|
145 | * @param x The 32-bit integer argument.
|
146 | * @returns The NIST specified output of the function.
|
147 | */
|
148 | export function gamma1_32(x: number): number {
|
149 | return rotr_32(x, 17) ^ rotr_32(x, 19) ^ shr_32(x, 10);
|
150 | }
|
151 |
|
152 | /**
|
153 | * The 32-bit implementation of the NIST specified Gamma0 function.
|
154 | *
|
155 | * @param x The 32-bit integer argument.
|
156 | * @returns The NIST specified output of the function.
|
157 | */
|
158 | export function gamma0_32(x: number): number {
|
159 | return rotr_32(x, 7) ^ rotr_32(x, 18) ^ shr_32(x, 3);
|
160 | }
|
161 |
|
162 | /**
|
163 | * The 32-bit implementation of the NIST specified Sigma1 function.
|
164 | *
|
165 | * @param x The 32-bit integer argument.
|
166 | * @returns The NIST specified output of the function.
|
167 | */
|
168 | export function sigma1_32(x: number): number {
|
169 | return rotr_32(x, 6) ^ rotr_32(x, 11) ^ rotr_32(x, 25);
|
170 | }
|