sha512.om (10031B)
1 // https://www.rfc-editor.org/rfc/rfc4634 2 3 struct sha512_ctx { 4 a: int; 5 b: int; 6 c: int; 7 d: int; 8 e: int; 9 f: int; 10 g: int; 11 h: int; 12 len: int; 13 block: _sha512_block; 14 } 15 16 struct _sha512_block { 17 c0: int; 18 c1: int; 19 c2: int; 20 c3: int; 21 c4: int; 22 c5: int; 23 c6: int; 24 c7: int; 25 c8: int; 26 c9: int; 27 c10: int; 28 c11: int; 29 c12: int; 30 c13: int; 31 c14: int; 32 c15: int; 33 } 34 35 struct _sha512_digest { 36 c: sha512_ctx; 37 } 38 39 func sha512_init(ctx: *sha512_ctx) { 40 ctx.a = (0x6a09e667 << 32) | 0xf3bcc908; 41 ctx.b = (0xbb67ae85 << 32) | 0x84caa73b; 42 ctx.c = (0x3c6ef372 << 32) | 0xfe94f82b; 43 ctx.d = (0xa54ff53a << 32) | 0x5f1d36f1; 44 ctx.e = (0x510e527f << 32) | 0xade682d1; 45 ctx.f = (0x9b05688c << 32) | 0x2b3e6c1f; 46 ctx.g = (0x1f83d9ab << 32) | 0xfb41bd6b; 47 ctx.h = (0x5be0cd19 << 32) | 0x137e2179; 48 ctx.len = 0; 49 } 50 51 func ror64(x: int, n: int): int { 52 return (x >> n) | (x << (64 - n)); 53 } 54 55 func sha512_round(r: *sha512_ctx, w: *int, k: int) { 56 var s0: int; 57 var s1: int; 58 var t1: int; 59 var t2: int; 60 var ch: int; 61 var maj: int; 62 var w16: int; 63 var i: int; 64 65 s1 = ror64(r.e, 14); s1 = s1 ^ ror64(r.e, 18); s1 = s1 ^ ror64(r.e, 41); 66 ch = (r.e & r.f) ^ ((~r.e) & r.g); 67 t1 = r.h + s1 + ch + k + w[0]; 68 s0 = ror64(r.a, 28); s0 = s0 ^ ror64(r.a, 34); s0 = s0 ^ ror64(r.a, 39); 69 maj = (r.a & r.b) ^ (r.a & r.c) ^ (r.b & r.c); 70 71 t2 = s0 + maj; 72 r.h = r.g; 73 r.g = r.f; 74 r.f = r.e; 75 r.e = r.d + t1; 76 r.d = r.c; 77 r.c = r.b; 78 r.b = r.a; 79 r.a = t1 + t2; 80 81 s0 = ror64(w[1], 1); s0 = s0 ^ ror64(w[1], 8); s0 = s0 ^ (w[1] >> 7); 82 s1 = ror64(w[14], 19); s1 = s1 ^ ror64(w[14], 61); s1 = s1 ^ (w[14] >> 6); 83 w16 = w[0] + s0 + w[9] + s1; 84 85 i = 0; 86 loop { 87 if i == 15 { 88 break; 89 } 90 91 w[i] = w[i + 1]; 92 93 i = i + 1; 94 } 95 96 w[15] = w16; 97 } 98 99 func sha512_rounds(ctx: *sha512_ctx, block: *byte) { 100 var r: sha512_ctx; 101 var _w: _sha512_block; 102 var w: *int; 103 var i: int; 104 w = (&_w) as *int; 105 106 r.a = ctx.a; 107 r.b = ctx.b; 108 r.c = ctx.c; 109 r.d = ctx.d; 110 r.e = ctx.e; 111 r.f = ctx.f; 112 r.g = ctx.g; 113 r.h = ctx.h; 114 115 i = 0; 116 loop { 117 if i == 16 { 118 break; 119 } 120 121 w[i] = (block[0] as int << 56) 122 | (block[1] as int << 48) 123 | (block[2] as int << 40) 124 | (block[3] as int << 32) 125 | (block[4] as int << 24) 126 | (block[5] as int << 16) 127 | (block[6] as int << 8) 128 | block[7] as int; 129 130 block = &block[8]; 131 i = i + 1; 132 } 133 134 sha512_round(&r, w, (0x428a2f98 << 32) | 0xd728ae22); 135 sha512_round(&r, w, (0x71374491 << 32) | 0x23ef65cd); 136 sha512_round(&r, w, (0xb5c0fbcf << 32) | 0xec4d3b2f); 137 sha512_round(&r, w, (0xe9b5dba5 << 32) | 0x8189dbbc); 138 sha512_round(&r, w, (0x3956c25b << 32) | 0xf348b538); 139 sha512_round(&r, w, (0x59f111f1 << 32) | 0xb605d019); 140 sha512_round(&r, w, (0x923f82a4 << 32) | 0xaf194f9b); 141 sha512_round(&r, w, (0xab1c5ed5 << 32) | 0xda6d8118); 142 sha512_round(&r, w, (0xd807aa98 << 32) | 0xa3030242); 143 sha512_round(&r, w, (0x12835b01 << 32) | 0x45706fbe); 144 sha512_round(&r, w, (0x243185be << 32) | 0x4ee4b28c); 145 sha512_round(&r, w, (0x550c7dc3 << 32) | 0xd5ffb4e2); 146 sha512_round(&r, w, (0x72be5d74 << 32) | 0xf27b896f); 147 sha512_round(&r, w, (0x80deb1fe << 32) | 0x3b1696b1); 148 sha512_round(&r, w, (0x9bdc06a7 << 32) | 0x25c71235); 149 sha512_round(&r, w, (0xc19bf174 << 32) | 0xcf692694); 150 sha512_round(&r, w, (0xe49b69c1 << 32) | 0x9ef14ad2); 151 sha512_round(&r, w, (0xefbe4786 << 32) | 0x384f25e3); 152 sha512_round(&r, w, (0x0fc19dc6 << 32) | 0x8b8cd5b5); 153 sha512_round(&r, w, (0x240ca1cc << 32) | 0x77ac9c65); 154 sha512_round(&r, w, (0x2de92c6f << 32) | 0x592b0275); 155 sha512_round(&r, w, (0x4a7484aa << 32) | 0x6ea6e483); 156 sha512_round(&r, w, (0x5cb0a9dc << 32) | 0xbd41fbd4); 157 sha512_round(&r, w, (0x76f988da << 32) | 0x831153b5); 158 sha512_round(&r, w, (0x983e5152 << 32) | 0xee66dfab); 159 sha512_round(&r, w, (0xa831c66d << 32) | 0x2db43210); 160 sha512_round(&r, w, (0xb00327c8 << 32) | 0x98fb213f); 161 sha512_round(&r, w, (0xbf597fc7 << 32) | 0xbeef0ee4); 162 sha512_round(&r, w, (0xc6e00bf3 << 32) | 0x3da88fc2); 163 sha512_round(&r, w, (0xd5a79147 << 32) | 0x930aa725); 164 sha512_round(&r, w, (0x06ca6351 << 32) | 0xe003826f); 165 sha512_round(&r, w, (0x14292967 << 32) | 0x0a0e6e70); 166 sha512_round(&r, w, (0x27b70a85 << 32) | 0x46d22ffc); 167 sha512_round(&r, w, (0x2e1b2138 << 32) | 0x5c26c926); 168 sha512_round(&r, w, (0x4d2c6dfc << 32) | 0x5ac42aed); 169 sha512_round(&r, w, (0x53380d13 << 32) | 0x9d95b3df); 170 sha512_round(&r, w, (0x650a7354 << 32) | 0x8baf63de); 171 sha512_round(&r, w, (0x766a0abb << 32) | 0x3c77b2a8); 172 sha512_round(&r, w, (0x81c2c92e << 32) | 0x47edaee6); 173 sha512_round(&r, w, (0x92722c85 << 32) | 0x1482353b); 174 sha512_round(&r, w, (0xa2bfe8a1 << 32) | 0x4cf10364); 175 sha512_round(&r, w, (0xa81a664b << 32) | 0xbc423001); 176 sha512_round(&r, w, (0xc24b8b70 << 32) | 0xd0f89791); 177 sha512_round(&r, w, (0xc76c51a3 << 32) | 0x0654be30); 178 sha512_round(&r, w, (0xd192e819 << 32) | 0xd6ef5218); 179 sha512_round(&r, w, (0xd6990624 << 32) | 0x5565a910); 180 sha512_round(&r, w, (0xf40e3585 << 32) | 0x5771202a); 181 sha512_round(&r, w, (0x106aa070 << 32) | 0x32bbd1b8); 182 sha512_round(&r, w, (0x19a4c116 << 32) | 0xb8d2d0c8); 183 sha512_round(&r, w, (0x1e376c08 << 32) | 0x5141ab53); 184 sha512_round(&r, w, (0x2748774c << 32) | 0xdf8eeb99); 185 sha512_round(&r, w, (0x34b0bcb5 << 32) | 0xe19b48a8); 186 sha512_round(&r, w, (0x391c0cb3 << 32) | 0xc5c95a63); 187 sha512_round(&r, w, (0x4ed8aa4a << 32) | 0xe3418acb); 188 sha512_round(&r, w, (0x5b9cca4f << 32) | 0x7763e373); 189 sha512_round(&r, w, (0x682e6ff3 << 32) | 0xd6b2b8a3); 190 sha512_round(&r, w, (0x748f82ee << 32) | 0x5defb2fc); 191 sha512_round(&r, w, (0x78a5636f << 32) | 0x43172f60); 192 sha512_round(&r, w, (0x84c87814 << 32) | 0xa1f0ab72); 193 sha512_round(&r, w, (0x8cc70208 << 32) | 0x1a6439ec); 194 sha512_round(&r, w, (0x90befffa << 32) | 0x23631e28); 195 sha512_round(&r, w, (0xa4506ceb << 32) | 0xde82bde9); 196 sha512_round(&r, w, (0xbef9a3f7 << 32) | 0xb2c67915); 197 sha512_round(&r, w, (0xc67178f2 << 32) | 0xe372532b); 198 sha512_round(&r, w, (0xca273ece << 32) | 0xea26619c); 199 sha512_round(&r, w, (0xd186b8c7 << 32) | 0x21c0c207); 200 sha512_round(&r, w, (0xeada7dd6 << 32) | 0xcde0eb1e); 201 sha512_round(&r, w, (0xf57d4f7f << 32) | 0xee6ed178); 202 sha512_round(&r, w, (0x06f067aa << 32) | 0x72176fba); 203 sha512_round(&r, w, (0x0a637dc5 << 32) | 0xa2c898a6); 204 sha512_round(&r, w, (0x113f9804 << 32) | 0xbef90dae); 205 sha512_round(&r, w, (0x1b710b35 << 32) | 0x131c471b); 206 sha512_round(&r, w, (0x28db77f5 << 32) | 0x23047d84); 207 sha512_round(&r, w, (0x32caab7b << 32) | 0x40c72493); 208 sha512_round(&r, w, (0x3c9ebe0a << 32) | 0x15c9bebc); 209 sha512_round(&r, w, (0x431d67c4 << 32) | 0x9c100d4c); 210 sha512_round(&r, w, (0x4cc5d4be << 32) | 0xcb3e42b6); 211 sha512_round(&r, w, (0x597f299c << 32) | 0xfc657e2a); 212 sha512_round(&r, w, (0x5fcb6fab << 32) | 0x3ad6faec); 213 sha512_round(&r, w, (0x6c44198c << 32) | 0x4a475817); 214 215 ctx.a = ctx.a + r.a; 216 ctx.b = ctx.b + r.b; 217 ctx.c = ctx.c + r.c; 218 ctx.d = ctx.d + r.d; 219 ctx.e = ctx.e + r.e; 220 ctx.f = ctx.f + r.f; 221 ctx.g = ctx.g + r.g; 222 ctx.h = ctx.h + r.h; 223 } 224 225 func sha512_finish(ctx: *sha512_ctx, nblocks: int, data: *byte, len: int) { 226 var _final: _sha512_block; 227 var final: *byte; 228 var pad: int; 229 final = (&_final) as *byte; 230 231 pad = nblocks * 1024; 232 loop { 233 if len < 128 { 234 break; 235 } 236 237 sha512_rounds(ctx, data); 238 239 data = &data[128]; 240 len = len - 128; 241 pad = pad + 1024; 242 } 243 pad = pad + len * 8; 244 245 bzero(final, 128); 246 memcpy(final, data, len); 247 final[len] = 0x80 as byte; 248 249 if len + 17 > 128 { 250 sha512_rounds(ctx, final); 251 bzero(final, 128); 252 } 253 254 final[120] = (pad >> 56) as byte; 255 final[121] = (pad >> 48) as byte; 256 final[122] = (pad >> 40) as byte; 257 final[123] = (pad >> 32) as byte; 258 final[124] = (pad >> 24) as byte; 259 final[125] = (pad >> 16) as byte; 260 final[126] = (pad >> 8) as byte; 261 final[127] = pad as byte; 262 263 sha512_rounds(ctx, final); 264 } 265 266 func sha512_digest(digest: *byte, ctx: *sha512_ctx) { 267 var r: *int; 268 var i: int; 269 r = &ctx.a; 270 i = 0; 271 loop { 272 if i == 8 { 273 break; 274 } 275 digest[0] = (r[i] >> 56) as byte; digest = &digest[1]; 276 digest[0] = (r[i] >> 48) as byte; digest = &digest[1]; 277 digest[0] = (r[i] >> 40) as byte; digest = &digest[1]; 278 digest[0] = (r[i] >> 32) as byte; digest = &digest[1]; 279 digest[0] = (r[i] >> 24) as byte; digest = &digest[1]; 280 digest[0] = (r[i] >> 16) as byte; digest = &digest[1]; 281 digest[0] = (r[i] >> 8) as byte; digest = &digest[1]; 282 digest[0] = r[i] as byte; digest = &digest[1]; 283 i = i + 1; 284 } 285 } 286 287 func sha512(digest: *byte, data: *byte, dlen: int) { 288 var ctx: sha512_ctx; 289 sha512_init(&ctx); 290 sha512_finish(&ctx, 0, data, dlen); 291 sha512_digest(digest, &ctx); 292 } 293 294 func sha512_hmac(mac: *byte, key: *byte, klen: int, data: *byte, dlen: int) { 295 var _digest: _sha512_block; 296 var digest: *byte; 297 var _ipad: _sha512_block; 298 var ipad: *byte; 299 var _opad: _sha512_block; 300 var opad: *byte; 301 var ctx: sha512_ctx; 302 var i: int; 303 304 digest = (&_digest) as *byte; 305 ipad = (&_ipad) as *byte; 306 opad = (&_opad) as *byte; 307 308 if (klen <= 128) { 309 bzero(digest, 128); 310 memcpy(digest, key, klen); 311 } else { 312 sha512(digest, key, klen); 313 } 314 315 i = 0; 316 loop { 317 if i == 128 { 318 break; 319 } 320 321 ipad[i] = digest[i] ^ (0x36 as byte); 322 opad[i] = digest[i] ^ (0x5c as byte); 323 324 i = i + 1; 325 } 326 327 sha512_init(&ctx); 328 sha512_rounds(&ctx, ipad); 329 sha512_finish(&ctx, 1, data, dlen); 330 sha512_digest(digest, &ctx); 331 332 sha512_init(&ctx); 333 sha512_rounds(&ctx, opad); 334 sha512_finish(&ctx, 1, digest, 64); 335 sha512_digest(mac, &ctx); 336 } 337 338 func sha512_update(ctx: *sha512_ctx, msg: *byte, len: int) { 339 var o: int; 340 var r: int; 341 342 o = ctx.len & 127; 343 if o != 0 { 344 r = 128 - o; 345 if len < r { 346 memcpy(&(&ctx.block) as *byte[o], msg, len); 347 ctx.len = ctx.len + len; 348 return; 349 } else { 350 memcpy(&(&ctx.block) as *byte[o], msg, r); 351 sha512_rounds(ctx, (&ctx.block) as *byte); 352 ctx.len = ctx.len + r; 353 len = len - r; 354 msg = &msg[r]; 355 } 356 } 357 358 loop { 359 if len < 128 { 360 memcpy((&ctx.block) as *byte, msg, len); 361 ctx.len = ctx.len + len; 362 return; 363 } 364 365 sha512_rounds(ctx, msg); 366 367 ctx.len = ctx.len + 128; 368 len = len - 128; 369 msg = &msg[128]; 370 } 371 } 372 373 func sha512_final(digest: *byte, ctx: *sha512_ctx) { 374 sha512_finish(ctx, ctx.len >> 7, (&ctx.block) as *byte, ctx.len & 127); 375 sha512_digest(digest, ctx); 376 }