Skip to content

Instantly share code, notes, and snippets.

@jbetz34
Created August 6, 2021 13:42
Show Gist options
  • Save jbetz34/597772d7214ff15aae98702742b9f214 to your computer and use it in GitHub Desktop.
Save jbetz34/597772d7214ff15aae98702742b9f214 to your computer and use it in GitHub Desktop.
SHA-256 built in q
\d .sha
// frequently used config functions
cfg.zeroPadding:{*[x;ceiling abs count[y]%x]#$[0>x;,[x#0;];,[;x#0]] y}
cfg.hex2bin:{cfg.zeroPadding[-8]{$[x<2;:reverse y,x;y,:x mod 2];.z.s[;y] div[x;2]}[;()] `long$x};
cfg.bin2dec:{sum prd each x,'#\:[;2] reverse til count x};
cfg.bin2hex:{`byte$cfg.bin2dec each 8 cut x};
cfg.binary:{raze cfg.hex2bin each `byte$x};
cfg.rightrotate:{rotate[neg[y];x]};
cfg.rightshift:{while[y;x:0^prev x;y-:1];x};
cfg.xor:{`long$(<>/) x};
cfg.binAdd:{s:sum x;while[any b:1<s;s:@[s;where b;-[;2]];s:@[s;except[;-1]where[b]-1;1+]];s};
// constants used for compression
const.init:{[]
const.hash:`h0`h1`h2`h3`h4`h5`h6`h7!(0x6a09e667;0xbb67ae85;0x3c6ef372;0xa54ff53a;0x510e527f;0x9b05688c;0x1f83d9ab;0x5be0cd19);
const.k:( 0x428a2f98; 0x71374491; 0xb5c0fbcf; 0xe9b5dba5; 0x3956c25b; 0x59f111f1; 0x923f82a4; 0xab1c5ed5;
0xd807aa98; 0x12835b01; 0x243185be; 0x550c7dc3; 0x72be5d74; 0x80deb1fe; 0x9bdc06a7; 0xc19bf174;
0xe49b69c1; 0xefbe4786; 0x0fc19dc6; 0x240ca1cc; 0x2de92c6f; 0x4a7484aa; 0x5cb0a9dc; 0x76f988da;
0x983e5152; 0xa831c66d; 0xb00327c8; 0xbf597fc7; 0xc6e00bf3; 0xd5a79147; 0x06ca6351; 0x14292967;
0x27b70a85; 0x2e1b2138; 0x4d2c6dfc; 0x53380d13; 0x650a7354; 0x766a0abb; 0x81c2c92e; 0x92722c85;
0xa2bfe8a1; 0xa81a664b; 0xc24b8b70; 0xc76c51a3; 0xd192e819; 0xd6990624; 0xf40e3585; 0x106aa070;
0x19a4c116; 0x1e376c08; 0x2748774c; 0x34b0bcb5; 0x391c0cb3; 0x4ed8aa4a; 0x5b9cca4f; 0x682e6ff3;
0x748f82ee; 0x78a5636f; 0x84c87814; 0x8cc70208; 0x90befffa; 0xa4506ceb; 0xbef9a3f7; 0xc67178f2);
};
// message schedule functions
sched.s0:{[x] cfg.xor (cfg.rightrotate[x;7];cfg.rightrotate[x;18];cfg.rightshift[x;3]) };
sched.s1:{[x] cfg.xor (cfg.rightrotate[x;17];cfg.rightrotate[x;19];cfg.rightshift[x;10])};
sched.w:{[x;i] cfg.binAdd enlist x[i-16] + sched.s0[x i-15] + x[i-7] + sched.s1[x i-2]};
// compression functions
comp.S0:{[a] cfg.xor cfg.rightrotate[a] each 2 13 22 }; // expects 'a' 32bit binary value
comp.S1:{[e] cfg.xor cfg.rightrotate[e] each 6 11 25 }; // expects 'e' 32bit binary value
comp.ch:{[e;f;g] cfg.xor (&[e;f] ; &[not e;g])}; // expects 'e','f'&'g' 32-bit binary values
comp.tmp1:{[i;w;e;f;g;h] cfg.binAdd (h ;comp.S1[e] ;comp.ch[e;f;g] ;raze cfg.hex2bin each const.k[i] ;w) } // where i is the iteration (0-63)&&w is msgSched[i]
comp.tmp2:{[a;b;c] cfg.binAdd (comp.S0[a]; comp.maj[a;b;c]) };
comp.maj:{[a;b;c] cfg.xor (a&b;a&c;b&c)};
comp.iterate:{[dict;msg;i]
tmp1:comp.tmp1[i;msg[i]] . dict[`e`f`g`h];
tmp2:comp.tmp2 . dict[`a`b`c];
dict[`h]:dict[`g];
dict[`g]:dict[`f];
dict[`f]:dict[`e];
dict[`e]:cfg.binAdd (dict[`d];tmp1);
dict[`d]:dict[`c];
dict[`c]:dict[`b];
dict[`b]:dict[`a];
dict[`a]:cfg.binAdd (tmp1;tmp2);
dict
}
// main functions
preprocess:{[x] len:count msg:.sha.cfg.binary x;:,[;cfg.zeroPadding[-64;cfg.binary len]] -64_cfg.zeroPadding[512]raze msg,1};
createMessageSchedule:{[x] msg:32 cut cfg.zeroPadding[64*32] x;r:16;while[r<64;msg[r]:sched.w[msg] r;r+:1];msg};
compress:{[x] orig:dict:`a`b`c`d`e`f`g`h!cfg.binary each value const.hash;
i:0;while[i<64;dict:comp.iterate[dict;x;i];i+:1];
.sha.const.hash:key[const.hash]!{cfg.bin2hex cfg.binAdd x} each flip (value[dict];value[orig])
};
// final
.sha.run:{ const.init[]; {compress createMessageSchedule x} each 512 cut preprocess x; raze value const.hash};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment