⍝ SHA - Provide a pleasant interface to the US Secure Hash Algorithm 1 and 2 family functions. ⍝ Copyright 2020 Prince Trippy programmer@verisimilitudes.net. ⍝ This program is free software: you can redistribute it and/or modify it under the terms of the ⍝ GNU Affero General Public License version 3 as published by the Free Software Foundation. ⍝ This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without ⍝ even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ⍝ See the GNU Affero General Public License for more details. ⍝ You should have received a copy of the GNU Affero General Public License along with this program. ⍝ If not, see . ⍝ This is a nicer and smaller form of SHA-1 K, as with the others: k←⍉(20 20 20 20/1518500249 1859775393 2400959708 3395469782)⊤⍨32⍴2 ⍝ I don't calculate this sixty-four vector kk due to my concerns of numerical representation: kk← 1116352408 1899447441 3049323471 3921009573 0961987163 1508970993 2453635748 2870763221 kk←kk,3624381080 0310598401 0607225278 1426881987 1925078388 2162078206 2614888103 3248222580 kk←kk,3835390401 4022224774 0264347078 0604807628 0770255983 1249150122 1555081692 1996064986 kk←kk,2554220882 2821834349 2952996808 3210313671 3336571891 3584528711 0113926993 0338241895 kk←kk,0666307205 0773529912 1294757372 1396182291 1695183700 1986661051 2177026350 2456956037 kk←kk,2730485921 2820302411 3259730800 3345764771 3516065817 3600352804 4094571909 0275423344 kk←kk,0430227734 0506948616 0659060556 0883997877 0958139571 1322822218 1537002063 1747873779 kk←kk,1955562222 2024104815 2227730452 2361852424 2428436474 2756734187 3204031479 3329325298 ⍝ I don't calculate this eighty vector kkk, due to my concerns of numerical representation: kkk← 04794697086780616226 08158064640168781261 13096744586834688815 16840607885511220156 kkk←kkk,04131703408338449720 06480981068601479193 10538285296894168987 12329834152419229976 kkk←kkk,15566598209576043074 01334009975649890238 02608012711638119052 06128411473006802146 kkk←kkk,08268148722764581231 09286055187155687089 11230858885718282805 13951009754708518548 kkk←kkk,16472876342353939154 17275323862435702243 01135362057144423861 02597628984639134821 kkk←kkk,03308224258029322869 05365058923640841347 06679025012923562964 08573033837759648693 kkk←kkk,10970295158949994411 12119686244451234320 12683024718118986047 13788192230050041572 kkk←kkk,14330467153632333762 15395433587784984357 00489312712824947311 01452737877330783856 kkk←kkk,02861767655752347644 03322285676063803686 05560940570517711597 05996557281743188959 kkk←kkk,07280758554555802590 08532644243296465576 09350256976987008742 10552545826968843579 kkk←kkk,11727347734174303076 12113106623233404929 14000437183269869457 14369950271660146224 kkk←kkk,15101387698204529176 15463397548674623760 17586052441742319658 01182934255886127544 kkk←kkk,01847814050463011016 02177327727835720531 02830643537854262169 03796741975233480872 kkk←kkk,04115178125766777443 05681478168544905931 06601373596472566643 07507060721942968483 kkk←kkk,08399075790359081724 08693463985226723168 09568029438360202098 10144078919501101548 kkk←kkk,10430055236837252648 11840083180663258601 13761210420658862357 14299343276471374635 kkk←kkk,14566680578165727644 15097957966210449927 16922976911328602910 17689382322260857208 kkk←kkk,00500013540394364858 00748580250866718886 01242879168328830382 01977374033974150939 kkk←kkk,02944078676154940804 03659926193048069267 04368137639120453308 04836135668995329356 kkk←kkk,05532061633213252278 06448918945643986474 06902733635092675308 07801388544844847127 ⍝ I'm dissatisfied by my constant names; statusNNN isn't much better, and these are shorter: S1← ⍉1732584193 4023233417 2562383102 0271733878 3285377520⊤⍨32⍴2 S224←3238371032 0914150663 0812702999 4144912697 4290775857 1750603025 1694076839 3204075428 S256←1779033703 3144134277 1013904242 2773480762 1359893119 2600822924 0528734635 1541459225 S224←⍉S224⊤⍨32⍴2◊S256←⍉S256⊤⍨32⍴2 S512← 07640891576956012808 13503953896175478587 04354685564936845355 11912009170470909681 S512←S512,05840696475078001361 11170449401992604703 02270897969802886507 06620516959819538809 S384← 14680500436340154072 07105036623409894663 10473403895298186519 01526699215303891257 S384←S384,07436329637833083697 10282925794625328401 15784041429090275239 05167115440072839076 S384←⍉S384⊤⍨64⍴2◊S512←⍉S512⊤⍨64⍴2 ⍝ I want to name these pad512 and pad1024; it would confuse. ⍝ Both of them require y be below the respective block size. ∇ z←x pad256 y ⍝ The x is the bit-length and y what remains. z←((2↓⍨447≥⍴y),512)⍴y,1,(0⍴⍨(↑512 0↓⍨447≥⍴y)+447-⍴y),x⊤⍨64⍴2 ∇ ∇ z←x pad512 y ⍝ The x is that bit-length and y that remaining. z←((2↓⍨895≥⍴y),1024)⍴y,1,(0⍴⍨(↑1024 0↓⍨895≥⍴y)+895-⍴y),x⊤⍨128⍴2 ∇ ⍝ Similarly to the k, this is a much nicer and more pleasant form of F. f←20 20 20 20/'(b∧c)∨d∧~b' '⊃≠/b c d' '⊃(∨/(b∧c)(b∧d)(c∧d))' '⊃≠/b c d' ∇ z←x SHA1 y;⎕IO;a;b;c;d;e;t;u;v;w ⎕IO←v←0◊u←16◊a←x[0;]◊b←x[1;]◊c←x[2;]◊d←x[3;]◊e←x[4;]◊w←y,2048⍴0 w[(32×u)+⍳32]←1⌽≠⌿w[(32×u-3 8 14 16)∘.+⍳32]◊→(80≠u←u+1)/2 t←(32⍴2)⊤+/2⊥⍉⊃w[(32×v)+⍳32]e(5⌽a)k[v;](⍎⊃f[v])◊e←d◊d←c◊c←30⌽b◊b←a◊a←t◊→(80≠v←v+1)/3 z←⍉(32⍴2)⊤(2⊥⍉⊃a b c d e)+2⊥⍉x ∇ ⍝ All of Ch, Maj, and the sigma functions are inlined in these functions. ∇ z←x SHA256 y;⎕IO;a;b;c;d;e;f;g;h;s;t;u;v;w ⎕IO←v←0◊u←16◊w←y,2048⍴0 t←w[(32×u-2 7 15 16)∘.+⍳32]◊s←((0 0 0,¯3↓t[2;])≠≠⌿¯7 ¯18⌽2 32⍴t[2;]),[0]t[1 3;] w[(⍳32)+32×u]←(32⍴2)⊤+/2⊥⍉(((10⍴0),¯10↓t[0;])≠≠⌿¯17 ¯19⌽2 32⍴t[0;]),[0]s◊→(64≠u←u+1)/2 a←x[0;]◊b←x[1;]◊c←x[2;]◊d←x[3;]◊e←x[4;]◊f←x[5;]◊g←x[6;]◊h←x[7;] s←+/kk[v],2⊥⍉⊃(≠⌿¯6 ¯11 ¯25⌽3 32⍴e)w[(⍳32)+32×v]h((e∧f)≠g∧~e) t←+/ 2⊥⍉⊃(≠⌿¯2 ¯13 ¯22⌽3 32⍴a) ((a∧b)≠(a∧c)≠b∧c) h←g◊g←f◊f←e◊e←(32⍴2)⊤s+2⊥d◊d←c◊c←b◊b←a◊a←(32⍴2)⊤s+t◊→(64≠v←v+1)/5 z←⍉(32⍴2)⊤(2⊥⍉⊃a b c d e f g h)+2⊥⍉x ∇ ⍝ This is an alternative form of the rotation and shifting with XOR: ⍝ ≠⌿¯7 0 ¯18⌽3 32⍴y,0 0 0,¯3↓y ⍝ It's by far easiest to simply copy and update in place for both of these. ∇ z←x SHA512 y;⎕IO;a;b;c;d;e;f;g;h;s;t;u;v;w ⎕IO←v←0◊u←16◊w←y,4096⍴0 t←w[(64×u-2 7 15 16)∘.+⍳64]◊s←(((7⍴0),¯7↓t[2;])≠≠⌿¯1 ¯8⌽2 64⍴t[2;]),[0]t[1 3;] w[(⍳64)+64×u]←(64⍴2)⊤+/2⊥⍉(((6⍴0),¯6↓t[0;])≠≠⌿¯19 ¯61⌽2 64⍴t[0;]),[0]s◊→(64≠u←u+1)/2 a←x[0;]◊b←x[1;]◊c←x[2;]◊d←x[3;]◊e←x[4;]◊f←x[5;]◊g←x[6;]◊h←x[7;] s←+/kkk[v],2⊥⍉⊃(≠⌿¯14 ¯18 ¯41⌽3 64⍴e)w[(⍳64)+64×v]h((e∧f)≠g∧~e) t←+/ 2⊥⍉⊃(≠⌿¯28 ¯34 ¯39⌽3 64⍴a) ((a∧b)≠(a∧c)≠b∧c) h←g◊g←f◊f←e◊e←(64⍴2)⊤s+2⊥d◊d←c◊c←b◊b←a◊a←(64⍴2)⊤s+t◊→(64≠v←v+1)/5 z←⍉(64⍴2)⊤(2⊥⍉⊃a b c d e f g h)+2⊥⍉x ∇ ⍝ '0123456789ABCDEF'[,⍉(8⍴16)⊤2⊥⍉S256 SHA256 0 pad256 0⍴0] ⍝ ⎕IO is zero here. .