UNPKG

5.64 kBPlain TextView Raw
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 */
17export 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 */
28function 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 */
39function 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 */
51export 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 */
63export 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 */
75export 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 */
85export 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 */
98export 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 */
116export 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 */
135export 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 */
148export 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 */
158export 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 */
168export function sigma1_32(x: number): number {
169 return rotr_32(x, 6) ^ rotr_32(x, 11) ^ rotr_32(x, 25);
170}