#ifndef SHA_256
#define SHA_256 1
#include "globals.h"

/*
void SHA256_fresh(uint8 *digest, uint8 *block0, uint8 *block1){

uint B00 = (*block0).s0;
uint B01 = (*block0).s1;
uint B02 = (*block0).s2;
uint B03 = (*block0).s3;
uint B04 = (*block0).s4;
uint B05 = (*block0).s5;
uint B06 = (*block0).s6;
uint B07 = (*block0).s7;

uint B08 = (*block1).s0;
uint B09 = (*block1).s1;
uint B10 = (*block1).s2;
uint B11 = (*block1).s3;
uint B12 = (*block1).s4;
uint B13 = (*block1).s5;
uint B14 = (*block1).s6;
uint B15 = (*block1).s7;

uint fk03 = 0x510e527fU;
uint fk04 = 0x9b05688cU;
uint fk10 = 0x6a09e667U;
uint fk13 = 0xBB67AE85U;
uint fk14 = 0x3C6EF372U;
uint fk15 = 0xA54FF53AU;
uint fk16 = 0x1F83D9ABU;
uint fk17 = 0x5BE0CD19U;

uint A = 0xa4ce148bU;
uint B = 0x0c2e12e0U;
uint C = 0xcd2a11aeU;
uint D = 0x98c7e2a2U;
uint E = 0x95F61999U;
uint F = 0x4498517BU;
uint G = 0xC3910C8EU;
uint H = 0xfc08884dU;

D += B00;
H += B00;
C += B01 + Tr1(D) + Ch(D, fk03, fk04);
G += C + Tr2(H) + Ch(H, 0xfb6feee7U, 0x2a01a605U);
B += B02 + Tr1(C) + Ch(C,D, fk03);
F += B + Tr2(G) + Maj(G,H, fk10);
A += B03 + Tr1(B) + Ch(B,C,D);
E += A + Tr2(F) + Maj(F,G,H);


RND(E,F,G,H,A,B,C,D, B04+Ka[4]);
RND(D,E,F,G,H,A,B,C, B05+Ka[5]);
RND(C,D,E,F,G,H,A,B, B06+Ka[6]);
RND(B,C,D,E,F,G,H,A, B07+Ka[7]);
RND(A,B,C,D,E,F,G,H, B08+Ka[8]);
RND(H,A,B,C,D,E,F,G, B09+Ka[9]);
RND(G,H,A,B,C,D,E,F, B10+Ka[10]);
RND(F,G,H,A,B,C,D,E, B11+Ka[11]);
RND(E,F,G,H,A,B,C,D, B12+Ka[12]);
RND(D,E,F,G,H,A,B,C, B13+Ka[13]);
RND(C,D,E,F,G,H,A,B, B14+Ka[14]);
RND(B,C,D,E,F,G,H,A, B15+Ka[15]);


for(uint i=0; i<3; i++){

B00 += Wr1(B14) + B09 + Wr2(B01);
B01 += Wr1(B15) + B10 + Wr2(B02);
B02 += Wr1(B00) + B11 + Wr2(B03);
B03 += Wr1(B01) + B12 + Wr2(B04);
B04 += Wr1(B02) + B13 + Wr2(B05);
B05 += Wr1(B03) + B14 + Wr2(B06);
B06 += Wr1(B04) + B15 + Wr2(B07);
B07 += Wr1(B05) + B00 + Wr2(B08);
B08 += Wr1(B06) + B01 + Wr2(B09);
B09 += Wr1(B07) + B02 + Wr2(B10);
B10 += Wr1(B08) + B03 + Wr2(B11);
B11 += Wr1(B09) + B04 + Wr2(B12);
B12 += Wr1(B10) + B05 + Wr2(B13);
B13 += Wr1(B11) + B06 + Wr2(B14);
B14 += Wr1(B12) + B07 + Wr2(B15);
B15 += Wr1(B13) + B08 + Wr2(B00);

RND(A,B,C,D,E,F,G,H, B00+Kc[i].s0);
RND(H,A,B,C,D,E,F,G, B01+Kc[i].s1);
RND(G,H,A,B,C,D,E,F, B02+Kc[i].s2);
RND(F,G,H,A,B,C,D,E, B03+Kc[i].s3);
RND(E,F,G,H,A,B,C,D, B04+Kc[i].s4);
RND(D,E,F,G,H,A,B,C, B05+Kc[i].s5);
RND(C,D,E,F,G,H,A,B, B06+Kc[i].s6);
RND(B,C,D,E,F,G,H,A, B07+Kc[i].s7);
RND(A,B,C,D,E,F,G,H, B08+Kc[i].s8);
RND(H,A,B,C,D,E,F,G, B09+Kc[i].s9);
RND(G,H,A,B,C,D,E,F, B10+Kc[i].sa);
RND(F,G,H,A,B,C,D,E, B11+Kc[i].sb);
RND(E,F,G,H,A,B,C,D, B12+Kc[i].sc);
RND(D,E,F,G,H,A,B,C, B13+Kc[i].sd);
RND(C,D,E,F,G,H,A,B, B14+Kc[i].se);
RND(B,C,D,E,F,G,H,A, B15+Kc[i].sf);

}

	(*digest).s0 = A + fk10;
	(*digest).s1 = B + fk13;
	(*digest).s2 = C + fk14;
	(*digest).s3 = D + fk15;
	(*digest).s4 = E + fk03;
	(*digest).s5 = F + fk04;
	(*digest).s6 = G + fk16;
	(*digest).s7 = H + fk17;
}

*/


void SHA256(uint8 *digest, uint8 *block0, uint8 *block1){

uint A = (*digest).s0;
uint B = (*digest).s1;
uint C = (*digest).s2;
uint D = (*digest).s3;
uint E = (*digest).s4;
uint F = (*digest).s5;
uint G = (*digest).s6;
uint H = (*digest).s7;

uint B00 = (*block0).s0;
uint B01 = (*block0).s1;
uint B02 = (*block0).s2;
uint B03 = (*block0).s3;
uint B04 = (*block0).s4;
uint B05 = (*block0).s5;
uint B06 = (*block0).s6;
uint B07 = (*block0).s7;

uint B08 = (*block1).s0;
uint B09 = (*block1).s1;
uint B10 = (*block1).s2;
uint B11 = (*block1).s3;
uint B12 = (*block1).s4;
uint B13 = (*block1).s5;
uint B14 = (*block1).s6;
uint B15 = (*block1).s7;



for(uint i=0; i<4; i++){

RND(A,B,C,D,E,F,G,H, B00+Kc[i].s0);
RND(H,A,B,C,D,E,F,G, B01+Kc[i].s1);
RND(G,H,A,B,C,D,E,F, B02+Kc[i].s2);
RND(F,G,H,A,B,C,D,E, B03+Kc[i].s3);
RND(E,F,G,H,A,B,C,D, B04+Kc[i].s4);
RND(D,E,F,G,H,A,B,C, B05+Kc[i].s5);
RND(C,D,E,F,G,H,A,B, B06+Kc[i].s6);
RND(B,C,D,E,F,G,H,A, B07+Kc[i].s7);
RND(A,B,C,D,E,F,G,H, B08+Kc[i].s8);
RND(H,A,B,C,D,E,F,G, B09+Kc[i].s9);
RND(G,H,A,B,C,D,E,F, B10+Kc[i].sa);
RND(F,G,H,A,B,C,D,E, B11+Kc[i].sb);
RND(E,F,G,H,A,B,C,D, B12+Kc[i].sc);
RND(D,E,F,G,H,A,B,C, B13+Kc[i].sd);
RND(C,D,E,F,G,H,A,B, B14+Kc[i].se);
RND(B,C,D,E,F,G,H,A, B15+Kc[i].sf);


if(i==3)
    break;

B00 += Wr1(B14) + B09 + Wr2(B01);
B01 += Wr1(B15) + B10 + Wr2(B02);
B02 += Wr1(B00) + B11 + Wr2(B03);
B03 += Wr1(B01) + B12 + Wr2(B04);
B04 += Wr1(B02) + B13 + Wr2(B05);
B05 += Wr1(B03) + B14 + Wr2(B06);
B06 += Wr1(B04) + B15 + Wr2(B07);
B07 += Wr1(B05) + B00 + Wr2(B08);
B08 += Wr1(B06) + B01 + Wr2(B09);
B09 += Wr1(B07) + B02 + Wr2(B10);
B10 += Wr1(B08) + B03 + Wr2(B11);
B11 += Wr1(B09) + B04 + Wr2(B12);
B12 += Wr1(B10) + B05 + Wr2(B13);
B13 += Wr1(B11) + B06 + Wr2(B14);
B14 += Wr1(B12) + B07 + Wr2(B15);
B15 += Wr1(B13) + B08 + Wr2(B00);


}


	(*digest).s0 += A;
	(*digest).s1 += B;
	(*digest).s2 += C;
	(*digest).s3 += D;
	(*digest).s4 += E;
	(*digest).s5 += F;
	(*digest).s6 += G;
	(*digest).s7 += H;
}

/*

void SHA256_fixed(uint8 *digest){


uint A = (*digest).s0;
uint B = (*digest).s1;
uint C = (*digest).s2;
uint D = (*digest).s3;
uint E = (*digest).s4;
uint F = (*digest).s5;
uint G = (*digest).s6;
uint H = (*digest).s7;


//0x00000001, 0x80000000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00000620

uint B00 = 0x00000001U;
uint B01 = 0x80000000U;
uint B02 = zero;
uint B03 = zero;
uint B04 = zero;
uint B05 = zero;
uint B06 = zero;
uint B07 = zero;
uint B08 = zero;
uint B09 = zero;
uint B10 = zero;
uint B11 = zero;
uint B12 = zero;
uint B13 = zero;
uint B14 = zero;
uint B15 = 0x00000620U;



    for(uint i=0; i<4; i++){


FXRD(A,B,C,D,E,F,G,H, B00 + Kc[i].s0);
FXRD(H,A,B,C,D,E,F,G, B01 + Kc[i].s1);
FXRD(G,H,A,B,C,D,E,F, B02 + Kc[i].s2);
FXRD(F,G,H,A,B,C,D,E, B03 + Kc[i].s3);
FXRD(E,F,G,H,A,B,C,D, B04 + Kc[i].s4);
FXRD(D,E,F,G,H,A,B,C, B05 + Kc[i].s5);
FXRD(C,D,E,F,G,H,A,B, B06 + Kc[i].s6);
FXRD(B,C,D,E,F,G,H,A, B07 + Kc[i].s7);
FXRD(A,B,C,D,E,F,G,H, B08 + Kc[i].s8);
FXRD(H,A,B,C,D,E,F,G, B09 + Kc[i].s9);
FXRD(G,H,A,B,C,D,E,F, B10 + Kc[i].sa);
FXRD(F,G,H,A,B,C,D,E, B11 + Kc[i].sb);
FXRD(E,F,G,H,A,B,C,D, B12 + Kc[i].sc);
FXRD(D,E,F,G,H,A,B,C, B13 + Kc[i].sd);
FXRD(C,D,E,F,G,H,A,B, B14 + Kc[i].se);
FXRD(B,C,D,E,F,G,H,A, B15 + Kc[i].sf);

if(i==3)
	break;

B00 += Wr1(B14) + B09 + Wr2(B01);
B01 += Wr1(B15) + B10 + Wr2(B02);
B02 += Wr1(B00) + B11 + Wr2(B03);
B03 += Wr1(B01) + B12 + Wr2(B04);
B04 += Wr1(B02) + B13 + Wr2(B05);
B05 += Wr1(B03) + B14 + Wr2(B06);
B06 += Wr1(B04) + B15 + Wr2(B07);
B07 += Wr1(B05) + B00 + Wr2(B08);
B08 += Wr1(B06) + B01 + Wr2(B09);
B09 += Wr1(B07) + B02 + Wr2(B10);
B10 += Wr1(B08) + B03 + Wr2(B11);
B11 += Wr1(B09) + B04 + Wr2(B12);
B12 += Wr1(B10) + B05 + Wr2(B13);
B13 += Wr1(B11) + B06 + Wr2(B14);
B14 += Wr1(B12) + B07 + Wr2(B15);
B15 += Wr1(B13) + B08 + Wr2(B00);


    }

    (*digest).s0 += A;
    (*digest).s1 += B;
    (*digest).s2 += C;
    (*digest).s3 += D;
    (*digest).s4 += E;
    (*digest).s5 += F;
    (*digest).s6 += G;
    (*digest).s7 += H;


}
*/
#endif