/
md2.mjs
138 lines (127 loc) · 4.46 KB
/
md2.mjs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
'use strict';
import Hasher8 from "./hasher8.mjs";
/**
* Constants from Pi
* @link https://github.com/e-sushi/MD2-S-box-creator
* @type {number[]}
*/
const SBOX = [
0x29, 0x2e, 0x43, 0xc9, 0xa2, 0xd8, 0x7c, 0x01, 0x3d, 0x36, 0x54, 0xa1,
0xec, 0xf0, 0x06, 0x13, 0x62, 0xa7, 0x05, 0xf3, 0xc0, 0xc7, 0x73, 0x8c,
0x98, 0x93, 0x2b, 0xd9, 0xbc, 0x4c, 0x82, 0xca, 0x1e, 0x9b, 0x57, 0x3c,
0xfd, 0xd4, 0xe0, 0x16, 0x67, 0x42, 0x6f, 0x18, 0x8a, 0x17, 0xe5, 0x12,
0xbe, 0x4e, 0xc4, 0xd6, 0xda, 0x9e, 0xde, 0x49, 0xa0, 0xfb, 0xf5, 0x8e,
0xbb, 0x2f, 0xee, 0x7a, 0xa9, 0x68, 0x79, 0x91, 0x15, 0xb2, 0x07, 0x3f,
0x94, 0xc2, 0x10, 0x89, 0x0b, 0x22, 0x5f, 0x21, 0x80, 0x7f, 0x5d, 0x9a,
0x5a, 0x90, 0x32, 0x27, 0x35, 0x3e, 0xcc, 0xe7, 0xbf, 0xf7, 0x97, 0x03,
0xff, 0x19, 0x30, 0xb3, 0x48, 0xa5, 0xb5, 0xd1, 0xd7, 0x5e, 0x92, 0x2a,
0xac, 0x56, 0xaa, 0xc6, 0x4f, 0xb8, 0x38, 0xd2, 0x96, 0xa4, 0x7d, 0xb6,
0x76, 0xfc, 0x6b, 0xe2, 0x9c, 0x74, 0x04, 0xf1, 0x45, 0x9d, 0x70, 0x59,
0x64, 0x71, 0x87, 0x20, 0x86, 0x5b, 0xcf, 0x65, 0xe6, 0x2d, 0xa8, 0x02,
0x1b, 0x60, 0x25, 0xad, 0xae, 0xb0, 0xb9, 0xf6, 0x1c, 0x46, 0x61, 0x69,
0x34, 0x40, 0x7e, 0x0f, 0x55, 0x47, 0xa3, 0x23, 0xdd, 0x51, 0xaf, 0x3a,
0xc3, 0x5c, 0xf9, 0xce, 0xba, 0xc5, 0xea, 0x26, 0x2c, 0x53, 0x0d, 0x6e,
0x85, 0x28, 0x84, 0x09, 0xd3, 0xdf, 0xcd, 0xf4, 0x41, 0x81, 0x4d, 0x52,
0x6a, 0xdc, 0x37, 0xc8, 0x6c, 0xc1, 0xab, 0xfa, 0x24, 0xe1, 0x7b, 0x08,
0x0c, 0xbd, 0xb1, 0x4a, 0x78, 0x88, 0x95, 0x8b, 0xe3, 0x63, 0xe8, 0x6d,
0xe9, 0xcb, 0xd5, 0xfe, 0x3b, 0x00, 0x1d, 0x39, 0xf2, 0xef, 0xb7, 0x0e,
0x66, 0x58, 0xd0, 0xe4, 0xa6, 0x77, 0x72, 0xf8, 0xeb, 0x75, 0x4b, 0x0a,
0x31, 0x44, 0x50, 0xb4, 0x8f, 0xed, 0x1f, 0x1a, 0xdb, 0x99, 0x8d, 0x33,
0x9f, 0x11, 0x83, 0x14
];
/**
* Calculates [MD2](https://tools.ietf.org/html/rfc1319) hash
*
* @example <caption>Calculates MD2 hash from string "message" - ES6 style</caption>
* import Md2 from "crypto-api/src/hasher/md2";
* import {toHex} from "crypto-api/src/encoder/hex";
*
* let hasher = new Md2();
* hasher.update('message');
* console.log(toHex(hasher.finalize()));
*
* @example <caption>Calculates MD2 hash from UTF string "message" - ES6 style</caption>
* import Md2 from "crypto-api/src/hasher/md2";
* import {toHex} from "crypto-api/src/encoder/hex";
* import {fromUtf} from "crypto-api/src/encoder/utf";
*
* let hasher = new Md2();
* hasher.update(fromUtf('message'));
* console.log(toHex(hasher.finalize()));
*
* @example <caption>Calculates MD2 hash from string "message" - ES5 style</caption>
* <script src="https://nf404.github.io/crypto-api/crypto-api.min.js"></script>
* <script>
* var hasher = CryptoApi.getHasher('md2');
* hasher.update('message');
* console.log(CryptoApi.encoder.toHex(hasher.finalize()));
* </script>
*
* @example <caption>Calculates MD2 hash from UTF string "message" - ES5 style</caption>
* <script src="https://nf404.github.io/crypto-api/crypto-api.min.js"></script>
* <script>
* console.log(CryptoApi.hash('md2', 'message'));
* </script>
*/
class Md2 extends Hasher8 {
/**
* @param {Object} [options]
* @param {number} [options.rounds=18] - Number of rounds (Must be greater than 0)
*/
constructor(options) {
super(options);
this.options.rounds = this.options.rounds || 18;
}
/**
* Reset hasher to initial state
*/
reset() {
super.reset();
this.state.hash = new Array(48);
this.state.checksum = new Array(16);
}
/**
* Process ready blocks
*
* @protected
* @ignore
* @param {number[]} block - Block
*/
processBlock(block) {
// Append hash
for (let i = 0; i < 16; i++) {
this.state.hash[16 + i] = block[i] | 0;
this.state.hash[32 + i] = block[i] ^ this.state.hash[i];
}
// Rounds
let t = 0;
for (let i = 0; i < this.options.rounds; i++) {
for (let j = 0; j < 48; j++) {
t = this.state.hash[j] ^= SBOX[t];
}
t = (t + i) & 0xff;
}
// Append checksum
t = this.state.checksum[15] & 0xff;
for (let i = 0; i < 16; i++) {
t = this.state.checksum[i] ^= SBOX[block[i] ^ t];
}
}
/**
* Finalize hash and return result
*
* @returns {string}
*/
finalize() {
this.addPaddingPKCS7(16 - (this.state.message.length & 0xf) | 0);
this.process();
// Process checksum
for (let i = 0; i < 16; i++) {
this.state.message += String.fromCharCode(this.state.checksum[i]);
}
this.process();
// Return hash
return this.getStateHash(16);
}
}
export default Md2;