os

An operating system
git clone https://erai.gay/code/os/
Log | Files | Refs | README | LICENSE

sha256.om (10433B)


      1 // https://www.rfc-editor.org/rfc/rfc4634
      2 
      3 struct sha256_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: _sha256_block;
     14 }
     15 
     16 struct _sha256_block {
     17 	w0: int;
     18 	w1: int;
     19 	w2: int;
     20 	w3: int;
     21 	w4: int;
     22 	w5: int;
     23 	w6: int;
     24 	w7: int;
     25 	w8: int;
     26 	w9: int;
     27 	w10: int;
     28 	w11: int;
     29 	w12: int;
     30 	w13: int;
     31 	w14: int;
     32 	w15: int;
     33 }
     34 
     35 struct _sha256_digest {
     36 	d0: int;
     37 	d1: int;
     38 	d2: int;
     39 	d3: int;
     40 	d4: int;
     41 }
     42 
     43 func sha256_init(r: *sha256_ctx) {
     44 	r.a = 0x6a09e667;
     45 	r.b = 0xbb67ae85;
     46 	r.c = 0x3c6ef372;
     47 	r.d = 0xa54ff53a;
     48 	r.e = 0x510e527f;
     49 	r.f = 0x9b05688c;
     50 	r.g = 0x1f83d9ab;
     51 	r.h = 0x5be0cd19;
     52 	r.len = 0;
     53 }
     54 
     55 func ror32(x: int, n: int): int {
     56 	return ((x >> n) | (x << (32 - n))) & (-1 >> 32);
     57 }
     58 
     59 func sha256_round(ctx: *sha256_ctx, w: *int, k: int) {
     60 	var t1: int;
     61 	var t2: int;
     62 	var s0: int;
     63 	var s1: int;
     64 	var ch: int;
     65 	var maj: int;
     66 	var w16: int;
     67 
     68 	s1 = ror32(ctx.e, 6); s1 = s1 ^ ror32(ctx.e, 11); s1 = s1 ^ ror32(ctx.e, 25);
     69 	ch = (ctx.e & ctx.f) ^ ((~ctx.e) & ctx.g);
     70 	t1 = (ctx.h + s1 + ch + k + w[0]) & (-1 >> 32);
     71 	s0 = ror32(ctx.a, 2); s0 = s0 ^ ror32(ctx.a, 13); s0 = s0 ^ ror32(ctx.a, 22);
     72 	maj = (ctx.a & ctx.b) ^ (ctx.a & ctx.c) ^ (ctx.b & ctx.c);
     73 	t2 = (s0 + maj) & (-1 >> 32);
     74 
     75 	s0 = ror32(w[16 - 15], 7); s0 = s0 ^ ror32(w[16 - 15], 18); s0 = s0 ^ (w[16 - 15] >> 3);
     76 	s1 = ror32(w[16 - 2], 17); s1 = s1 ^ ror32(w[16 - 2], 19); s1 = s1 ^ (w[16 - 2] >> 10);
     77 	w16 = (w[16 - 16] + s0 + w[16 - 7] + s1) & (-1 >> 32);
     78 
     79 	w[0] = w[1];
     80 	w[1] = w[2];
     81 	w[2] = w[3];
     82 	w[3] = w[4];
     83 	w[4] = w[5];
     84 	w[5] = w[6];
     85 	w[6] = w[7];
     86 	w[7] = w[8];
     87 	w[8] = w[9];
     88 	w[9] = w[10];
     89 	w[10] = w[11];
     90 	w[11] = w[12];
     91 	w[12] = w[13];
     92 	w[13] = w[14];
     93 	w[14] = w[15];
     94 	w[15] = w16;
     95 
     96 	ctx.h = ctx.g;
     97 	ctx.g = ctx.f;
     98 	ctx.f = ctx.e;
     99 	ctx.e = (ctx.d + t1) & (-1 >> 32);
    100 	ctx.d = ctx.c;
    101 	ctx.c = ctx.b;
    102 	ctx.b = ctx.a;
    103 	ctx.a = (t1 + t2) & (-1 >> 32);
    104 }
    105 
    106 func sha256_rounds(ctx: *sha256_ctx, block: *byte) {
    107 	var _w: _sha256_block;
    108 	var w: *int;
    109 	var r: sha256_ctx;
    110 	w = &_w.w0;
    111 
    112 	r.a = ctx.a;
    113 	r.b = ctx.b;
    114 	r.c = ctx.c;
    115 	r.d = ctx.d;
    116 	r.e = ctx.e;
    117 	r.f = ctx.f;
    118 	r.g = ctx.g;
    119 	r.h = ctx.h;
    120 
    121 	w[0] = (block[0] as int << 24)
    122 		| (block[1] as int << 16)
    123 		| (block[2] as int << 8)
    124 		| block[3] as int;
    125 	w[1] = (block[4] as int << 24)
    126 		| (block[5] as int << 16)
    127 		| (block[6] as int << 8)
    128 		| block[7] as int;
    129 	w[2] = (block[8] as int << 24)
    130 		| (block[9] as int << 16)
    131 		| (block[10] as int << 8)
    132 		| block[11] as int;
    133 	w[3] = (block[12] as int << 24)
    134 		| (block[13] as int << 16)
    135 		| (block[14] as int << 8)
    136 		| block[15] as int;
    137 	w[4] = (block[16] as int << 24)
    138 		| (block[17] as int << 16)
    139 		| (block[18] as int << 8)
    140 		| block[19] as int;
    141 	w[5] = (block[20] as int << 24)
    142 		| (block[21] as int << 16)
    143 		| (block[22] as int << 8)
    144 		| block[23] as int;
    145 	w[6] = (block[24] as int << 24)
    146 		| (block[25] as int << 16)
    147 		| (block[26] as int << 8)
    148 		| block[27] as int;
    149 	w[7] = (block[28] as int << 24)
    150 		| (block[29] as int << 16)
    151 		| (block[30] as int << 8)
    152 		| block[31] as int;
    153 	w[8] = (block[32] as int << 24)
    154 		| (block[33] as int << 16)
    155 		| (block[34] as int << 8)
    156 		| block[35] as int;
    157 	w[9] = (block[36] as int << 24)
    158 		| (block[37] as int << 16)
    159 		| (block[38] as int << 8)
    160 		| block[39] as int;
    161 	w[10] = (block[40] as int << 24)
    162 		| (block[41] as int << 16)
    163 		| (block[42] as int << 8)
    164 		| block[43] as int;
    165 	w[11] = (block[44] as int << 24)
    166 		| (block[45] as int << 16)
    167 		| (block[46] as int << 8)
    168 		| block[47] as int;
    169 	w[12] = (block[48] as int << 24)
    170 		| (block[49] as int << 16)
    171 		| (block[50] as int << 8)
    172 		| block[51] as int;
    173 	w[13] = (block[52] as int << 24)
    174 		| (block[53] as int << 16)
    175 		| (block[54] as int << 8)
    176 		| block[55] as int;
    177 	w[14] = (block[56] as int << 24)
    178 		| (block[57] as int << 16)
    179 		| (block[58] as int << 8)
    180 		| block[59] as int;
    181 	w[15] = (block[60] as int << 24)
    182 		| (block[61] as int << 16)
    183 		| (block[62] as int << 8)
    184 		| block[63] as int;
    185 
    186 	sha256_round(&r, w, 0x428a2f98);
    187 	sha256_round(&r, w, 0x71374491);
    188 	sha256_round(&r, w, 0xb5c0fbcf);
    189 	sha256_round(&r, w, 0xe9b5dba5);
    190 	sha256_round(&r, w, 0x3956c25b);
    191 	sha256_round(&r, w, 0x59f111f1);
    192 	sha256_round(&r, w, 0x923f82a4);
    193 	sha256_round(&r, w, 0xab1c5ed5);
    194 	sha256_round(&r, w, 0xd807aa98);
    195 	sha256_round(&r, w, 0x12835b01);
    196 	sha256_round(&r, w, 0x243185be);
    197 	sha256_round(&r, w, 0x550c7dc3);
    198 	sha256_round(&r, w, 0x72be5d74);
    199 	sha256_round(&r, w, 0x80deb1fe);
    200 	sha256_round(&r, w, 0x9bdc06a7);
    201 	sha256_round(&r, w, 0xc19bf174);
    202 	sha256_round(&r, w, 0xe49b69c1);
    203 	sha256_round(&r, w, 0xefbe4786);
    204 	sha256_round(&r, w, 0x0fc19dc6);
    205 	sha256_round(&r, w, 0x240ca1cc);
    206 	sha256_round(&r, w, 0x2de92c6f);
    207 	sha256_round(&r, w, 0x4a7484aa);
    208 	sha256_round(&r, w, 0x5cb0a9dc);
    209 	sha256_round(&r, w, 0x76f988da);
    210 	sha256_round(&r, w, 0x983e5152);
    211 	sha256_round(&r, w, 0xa831c66d);
    212 	sha256_round(&r, w, 0xb00327c8);
    213 	sha256_round(&r, w, 0xbf597fc7);
    214 	sha256_round(&r, w, 0xc6e00bf3);
    215 	sha256_round(&r, w, 0xd5a79147);
    216 	sha256_round(&r, w, 0x06ca6351);
    217 	sha256_round(&r, w, 0x14292967);
    218 	sha256_round(&r, w, 0x27b70a85);
    219 	sha256_round(&r, w, 0x2e1b2138);
    220 	sha256_round(&r, w, 0x4d2c6dfc);
    221 	sha256_round(&r, w, 0x53380d13);
    222 	sha256_round(&r, w, 0x650a7354);
    223 	sha256_round(&r, w, 0x766a0abb);
    224 	sha256_round(&r, w, 0x81c2c92e);
    225 	sha256_round(&r, w, 0x92722c85);
    226 	sha256_round(&r, w, 0xa2bfe8a1);
    227 	sha256_round(&r, w, 0xa81a664b);
    228 	sha256_round(&r, w, 0xc24b8b70);
    229 	sha256_round(&r, w, 0xc76c51a3);
    230 	sha256_round(&r, w, 0xd192e819);
    231 	sha256_round(&r, w, 0xd6990624);
    232 	sha256_round(&r, w, 0xf40e3585);
    233 	sha256_round(&r, w, 0x106aa070);
    234 	sha256_round(&r, w, 0x19a4c116);
    235 	sha256_round(&r, w, 0x1e376c08);
    236 	sha256_round(&r, w, 0x2748774c);
    237 	sha256_round(&r, w, 0x34b0bcb5);
    238 	sha256_round(&r, w, 0x391c0cb3);
    239 	sha256_round(&r, w, 0x4ed8aa4a);
    240 	sha256_round(&r, w, 0x5b9cca4f);
    241 	sha256_round(&r, w, 0x682e6ff3);
    242 	sha256_round(&r, w, 0x748f82ee);
    243 	sha256_round(&r, w, 0x78a5636f);
    244 	sha256_round(&r, w, 0x84c87814);
    245 	sha256_round(&r, w, 0x8cc70208);
    246 	sha256_round(&r, w, 0x90befffa);
    247 	sha256_round(&r, w, 0xa4506ceb);
    248 	sha256_round(&r, w, 0xbef9a3f7);
    249 	sha256_round(&r, w, 0xc67178f2);
    250 
    251 	ctx.a = (ctx.a + r.a) & (-1 >> 32);
    252 	ctx.b = (ctx.b + r.b) & (-1 >> 32);
    253 	ctx.c = (ctx.c + r.c) & (-1 >> 32);
    254 	ctx.d = (ctx.d + r.d) & (-1 >> 32);
    255 	ctx.e = (ctx.e + r.e) & (-1 >> 32);
    256 	ctx.f = (ctx.f + r.f) & (-1 >> 32);
    257 	ctx.g = (ctx.g + r.g) & (-1 >> 32);
    258 	ctx.h = (ctx.h + r.h) & (-1 >> 32);
    259 }
    260 
    261 func sha256_finish(ctx: *sha256_ctx, nblocks: int, data: *byte, len: int) {
    262 	var _final: sha256_ctx;
    263 	var final: *byte;
    264 	var pad: int;
    265 	var i: int;
    266 
    267 	final = (&_final) as *byte;
    268 
    269 	pad = nblocks * 512;
    270 
    271 	loop {
    272 		if len < 64 {
    273 			break;
    274 		}
    275 
    276 		sha256_rounds(ctx, data);
    277 
    278 		data = &data[64];
    279 		len = len - 64;
    280 		pad = pad + 512;
    281 	}
    282 
    283 	pad = pad + len * 8;
    284 
    285 	i = 0;
    286 	loop {
    287 		if i == len {
    288 			break;
    289 		}
    290 
    291 		final[i] = data[i];
    292 
    293 		i = i + 1;
    294 	}
    295 
    296 	final[i] = 0x80 as byte;
    297 	i = i + 1;
    298 
    299 	loop {
    300 		if i == 64 {
    301 			break;
    302 		}
    303 
    304 		final[i] = 0 as byte;
    305 
    306 		i = i + 1;
    307 	}
    308 
    309 	if len + 9 > 64 {
    310 		sha256_rounds(ctx, final);
    311 
    312 		i = 0;
    313 		loop {
    314 			if i == 64 {
    315 				break;
    316 			}
    317 
    318 			final[i] = 0 as byte;
    319 
    320 			i = i + 1;
    321 		}
    322 	}
    323 
    324 	final[56] = (pad >> 56) as byte;
    325 	final[57] = (pad >> 48) as byte;
    326 	final[58] = (pad >> 40) as byte;
    327 	final[59] = (pad >> 32) as byte;
    328 	final[60] = (pad >> 24) as byte;
    329 	final[61] = (pad >> 16) as byte;
    330 	final[62] = (pad >> 8) as byte;
    331 	final[63] = pad as byte;
    332 
    333 	sha256_rounds(ctx, final);
    334 }
    335 
    336 func sha256_digest(digest: *byte, ctx: *sha256_ctx) {
    337 	digest[0] = (ctx.a >> 24) as byte;
    338 	digest[1] = (ctx.a >> 16) as byte;
    339 	digest[2] = (ctx.a >> 8) as byte;
    340 	digest[3] = ctx.a as byte;
    341 	digest[4] = (ctx.b >> 24) as byte;
    342 	digest[5] = (ctx.b >> 16) as byte;
    343 	digest[6] = (ctx.b >> 8) as byte;
    344 	digest[7] = ctx.b as byte;
    345 	digest[8] = (ctx.c >> 24) as byte;
    346 	digest[9] = (ctx.c >> 16) as byte;
    347 	digest[10] = (ctx.c >> 8) as byte;
    348 	digest[11] = ctx.c as byte;
    349 	digest[12] = (ctx.d >> 24) as byte;
    350 	digest[13] = (ctx.d >> 16) as byte;
    351 	digest[14] = (ctx.d >> 8) as byte;
    352 	digest[15] = ctx.d as byte;
    353 	digest[16] = (ctx.e >> 24) as byte;
    354 	digest[17] = (ctx.e >> 16) as byte;
    355 	digest[18] = (ctx.e >> 8) as byte;
    356 	digest[19] = ctx.e as byte;
    357 	digest[20] = (ctx.f >> 24) as byte;
    358 	digest[21] = (ctx.f >> 16) as byte;
    359 	digest[22] = (ctx.f >> 8) as byte;
    360 	digest[23] = ctx.f as byte;
    361 	digest[24] = (ctx.g >> 24) as byte;
    362 	digest[25] = (ctx.g >> 16) as byte;
    363 	digest[26] = (ctx.g >> 8) as byte;
    364 	digest[27] = ctx.g as byte;
    365 	digest[28] = (ctx.h >> 24) as byte;
    366 	digest[29] = (ctx.h >> 16) as byte;
    367 	digest[30] = (ctx.h >> 8) as byte;
    368 	digest[31] = ctx.h as byte;
    369 }
    370 
    371 func sha256(digest: *byte, data: *byte, dlen: int) {
    372 	var ctx: sha256_ctx;
    373 	sha256_init(&ctx);
    374 	sha256_finish(&ctx, 0, data, dlen);
    375 	sha256_digest(digest, &ctx);
    376 }
    377 
    378 func sha256_hmac(mac: *byte, key: *byte, klen: int, data: *byte, dlen: int) {
    379 	var _digest: _sha256_block;
    380 	var digest: *byte;
    381 	var _ipad: _sha256_block;
    382 	var ipad: *byte;
    383 	var _opad: _sha256_block;
    384 	var opad: *byte;
    385 	var ctx: sha256_ctx;
    386 	var i: int;
    387 
    388 	digest = (&_digest) as *byte;
    389 	ipad = (&_ipad) as *byte;
    390 	opad = (&_opad) as *byte;
    391 
    392 	i = 0;
    393 	loop {
    394 		if i == 64 {
    395 			break;
    396 		}
    397 
    398 		digest[i] = 0 as byte;
    399 
    400 		i = i + 1;
    401 	}
    402 
    403 	if (klen <= 64) {
    404 		i = 0;
    405 		loop {
    406 			if i == klen {
    407 				break;
    408 			}
    409 
    410 			digest[i] = key[i];
    411 
    412 			i = i + 1;
    413 		}
    414 	} else {
    415 		sha256(digest, key, klen);
    416 	}
    417 
    418 	i = 0;
    419 	loop {
    420 		if i == 64 {
    421 			break;
    422 		}
    423 
    424 		ipad[i] = digest[i] ^ (0x36 as byte);
    425 		opad[i] = digest[i] ^ (0x5c as byte);
    426 
    427 		i = i + 1;
    428 	}
    429 
    430 	sha256_init(&ctx);
    431 	sha256_rounds(&ctx, ipad);
    432 	sha256_finish(&ctx, 1, data, dlen);
    433 	sha256_digest(digest, &ctx);
    434 
    435 	sha256_init(&ctx);
    436 	sha256_rounds(&ctx, opad);
    437 	sha256_finish(&ctx, 1, digest, 32);
    438 	sha256_digest(mac, &ctx);
    439 }
    440 
    441 func sha256_update(ctx: *sha256_ctx, msg: *byte, len: int) {
    442 	var o: int;
    443 	var r: int;
    444 
    445 	o = ctx.len & 63;
    446 	if o != 0 {
    447 		r = 64 - o;
    448 		if len < r {
    449 			memcpy(&(&ctx.block) as *byte[o], msg, len);
    450 			ctx.len = ctx.len + len;
    451 			return;
    452 		} else {
    453 			memcpy(&(&ctx.block) as *byte[o], msg, r);
    454 			sha256_rounds(ctx, (&ctx.block) as *byte);
    455 			ctx.len = ctx.len + r;
    456 			len = len - r;
    457 			msg = &msg[r];
    458 		}
    459 	}
    460 
    461 	loop {
    462 		if len < 64 {
    463 			memcpy((&ctx.block) as *byte, msg, len);
    464 			ctx.len = ctx.len + len;
    465 			return;
    466 		}
    467 
    468 		sha256_rounds(ctx, msg);
    469 
    470 		ctx.len = ctx.len + 64;
    471 		len = len - 64;
    472 		msg = &msg[64];
    473 	}
    474 }
    475 
    476 func sha256_final(digest: *byte, ctx: *sha256_ctx) {
    477 	sha256_finish(ctx, ctx.len >> 6, (&ctx.block) as *byte, ctx.len & 63);
    478 	sha256_digest(digest, ctx);
    479 }