OPTION STRICT
OPTION DEFINT

DIM W[64]
DIM K[64]'CONST
COPY K,@K
@K
DATA &H428A2F98,&H71374491,&HB5C0FBCF,&HE9B5DBA5,&H3956C25B,&H59F111F1,&H923F82A4,&HAB1C5ED5,&HD807AA98,&H12835B01,&H243185BE,&H550C7DC3,&H72BE5D74,&H80DEB1FE,&H9BDC06A7,&HC19BF174,&HE49B69C1,&HEFBE4786,&H0FC19DC6,&H240CA1CC,&H2DE92C6F,&H4A7484AA,&H5CB0A9DC,&H76F988DA,&H983E5152,&HA831C66D,&HB00327C8,&HBF597FC7,&HC6E00BF3,&HD5A79147,&H06CA6351,&H14292967,&H27B70A85,&H2E1B2138,&H4D2C6DFC,&H53380D13,&H650A7354,&H766A0ABB,&H81C2C92E,&H92722C85,&HA2BFE8A1,&HA81A664B,&HC24B8B70,&HC76C51A3,&HD192E819,&HD6990624,&HF40E3585,&H106AA070,&H19A4C116,&H1E376C08,&H2748774C,&H34B0BCB5,&H391C0CB3,&H4ED8AA4A,&H5B9CCA4F,&H682E6FF3,&H748F82EE,&H78A5636F,&H84C87814,&H8CC70208,&H90BEFFFA,&HA4506CEB,&HBEF9A3F7,&HC67178F2

VAR IN[0],BITS
STR8 "12Me21" OUT IN,BITS
DIM HASH[0]

VAR I,M=MILLISEC+1000
WHILE MILLISEC<M
 HASH=SHA256(IN,BITS)
 INC I
WEND
?"Hashes per second: ";I
?HEX256$(A)

'Generate SHA256 hash
'inputs:
'IN2: integer array (bit order: big endian)
'BITS: number of bits
'output:
'integer array, length=8
DEF SHA256(IN2,BITS)
 DIM RET[8]
 VAR H0=&H6A09E667,H1=&HBB67AE85,H2=&H3C6EF372,H3=&HA54FF53A,H4=&H510E527F,H5=&H9B05688C,H6=&H1F83D9AB,H7=&H5BE0CD19
 VAR I,J
 VAR BLOCKS=BITS+(1+64+511)>>9
 VAR ILEN=BLOCKS<<9-5
 DIM IN[ILEN]
 COPY IN,IN2
 INC IN[BITS>>5],1<<(31-BITS AND 31)
 IN[ILEN-1]=BITS
 FOR J=0 TO BLOCKS-1
  COPY W,IN,J<<4,512 DIV 32
  FOR I=16 TO 64-1
   VAR FIF=W[I-15]
   VAR TWO=W[I-2]
   W[I]=W[I-16]+(                                (FIF>> 7 AND (1<<32- 7)-1 OR FIF<<32- 7) XOR  (FIF>>18 AND (1<<32-18)-1 OR FIF<<32-18) XOR  (FIF>> 3 AND (1<<32- 3)-1))+ W[I-7]+ (        (TWO>>17 AND (1<<32-17)-1 OR TWO<<32-17) XOR  (TWO>>19 AND (1<<32-19)-1 OR TWO<<32-19) XOR  (TWO>>10 AND (1<<32-10)-1))
  NEXT
  VAR A=H0,B=H1,C=H2,D=H3,E=H4,F=H5,G=H6,H=H7
  
  FOR I=0 TO 64-1
   VAR TEMP1=H+(                                 (E>> 6 AND (1<<32- 6)-1 OR E<<32- 6) XOR      (E>>11 AND (1<<32-11)-1 OR E<<32-11) XOR      (E>>25 AND (1<<32-25)-1 OR E<<32-25))+        ((E AND F) XOR (NOT(E) AND G))+K[I]+W[I]
   VAR TEMP2=(                                   (A>> 2 AND (1<<32- 2)-1 OR A<<32- 2) XOR      (A>>13 AND (1<<32-13)-1 OR A<<32-13) XOR      (A>>22 AND (1<<32-22)-1 OR A<<32-22))+        ((A AND B) XOR (A AND C) XOR (B AND C))
   H=G:G=F:F=E:E=D+TEMP1:D=C:C=B:B=A
   A=TEMP1+TEMP2
  NEXT
  
  INC H0,A:INC H1,B:INC H2,C:INC H3,D
  INC H4,E:INC H5,F:INC H6,G:INC H7,H
 NEXT
 
 RET[0]=H0:RET[1]=H1:RET[2]=H2:RET[3]=H3
 RET[4]=H4:RET[5]=H5:RET[6]=H6:RET[7]=H7
 RETURN RET
END

'Convert string to integer array+length
'inputs:
'S$: string (characters treated as 8 bits each)
'outputs:
'IN2: integer array
'L: number of bits (length of string * 8)
DEF STR8 S$ OUT IN2,L
 L=LEN(S$)*8
 VAR I
 DIM IN[CEIL(L DIV 32)*32]
 FOR I=0 TO L DIV 8-1
  IN[I DIV 4]=IN[I DIV 4] OR ASC(S$[I])<<(3-(I MOD 4))*8
 NEXT
 IN2=IN
END

'Generate 256 bit hex number
'inputs:
'A: integer array, length=8
'output:
'256 bit hexadecimal number
DEF HEX256$(A)
 VAR RET$
 FOR I=0 TO 7
  INC RET$,HEX$(A[I],8)
 NEXT
 RETURN RET$
END