Skip to content

Instantly share code, notes, and snippets.

@Steve132
Last active August 17, 2016 14:56
Show Gist options
  • Save Steve132/797325e876c6e1e63d93a5fd813391f0 to your computer and use it in GitHub Desktop.
Save Steve132/797325e876c6e1e63d93a5fd813391f0 to your computer and use it in GitHub Desktop.
Simple Quantum Sha1
//THis is an implementation for a quantum simulator showing that sha1 iterations are computable and reversible with no global ancillary bits and one *local*
//ancillary register that is uncomputed per iteration. This iteration is only 5 bits, of course, for space.
#include<qcpp/QRegister.h>
#include<qcpp/QMachine.h>
uint32_t msha1_computeF(int i,QRegister& B,QRegister& C,QRegister& D,QRegister& F)
{
static const uint32_t k[4]=[0x5A827999,0x6ED9EBA1,0x8F1BBCDC,0xCA62C1D6]
switch(i/20)
{
case 0:
{
//F=(B and C) xor ((not B) and D)
F^=B & C; //Toffoli gates
B=~B; //invert B
F^=B & D;
B=~B; //invert B back.
break;
}
case 1:
{
F^=B;
F^=C;
F^=D;
break;
}
case 2:
{
//F=(b And C) xor (B and D) xor (C and D);
F^=B & C; //Toffoli gates
F^=B & D;
F^=C & D;
break;
}
case 3:
{
F^=B;
F^=C;
F^=D;
break;
}
};
return k[i/20];
}
void msha1_uncomputeF(int i,QRegister& B,QRegister& C,QRegister& D,QRegister& F)
{
static const uint32_t k[4]=[0x5A827999,0x6ED9EBA1,0x8F1BBCDC,0xCA62C1D6]
switch(i/20)
{
case 0:
{
//F=(B and C) xor ((not B) and D)
B=~B; //invert B back.
F^=B & D;
B=~B; //invert B
F^=B & C; //Toffoli gates
break;
}
case 1:
{
F^=D;
F^=C;
F^=B;
break;
}
case 2:
{
//F=(b And C) xor (B and D) xor (C and D);
F^=C & D;
F^=B & D;
F^=B & C; //Toffoli gates
break;
}
case 3:
{
F^=D;
F^=C;
F^=B;
break;
}
};
return k[i/20];
}
void msha1_iterate_forwards(int i,unsigned char w_i,
QRegister& A,QRegister& B,
QRegister& C,QRegister& D,
QRegister& E,QRegister& F)
{
uint32_t k=msha1_computeF(i,B,C,D,F);
//Compute TEMP variable
A <<= 5;
F+=A;
F+=E;
F+=k;
F+=w_i;
A >>=5;
QMachine& m=A.machine;
QRegister all(m,{0:30});
//Rotate globally (reversible)
/*
F=E
E=D
D=C
C=B
B=A
A=F */
all <<=5;
F-=A; //F=oldE-(B left 5)-computedf-k-w[i]-oldE
B <<=5;
F+=B;
B >>=5; //F=computedf-k-w[i]
F+=k;
F+=w[i]; //F=computedf
msha1_uncomputeF(i,C,D,E,F);
//F=0; rest of state is correct for one iteration.
}
QRegister minisha1(QMachine& m,unsigned char w[80])
{
QRegister A(m,{0,1,2,3,4}),
B(m,{5,6,7,8,9}),
C(m,{10,11,12,13,14}),
D(m,{16,17,18,19,20}),
E(m,{21,22,23,24,25})
F(m,{26,27,28,29,30});
QRegister outhash(m,
{0,1,2,3,4,5,6,7,8,9,10
,11,12,13,14,15,16,17,18,19,20,
21,22,23,24,25,26,27,28,29,30});
A ^= 0x67452301 & 0x1F;
B ^= 0xEFCDAB89 & 0x1F;
C ^= 0x98BADCFE & 0x1F;
D ^= 0x10325476 & 0x1F;
E ^= 0xC3D2E1F0 & 0x1F;
F ^= 0;
for(int i=0;i<80;i++)
{
iterate_forwards(i,w[i],A,B,C,D,E,F);
}
//output is Hash value is A|B|C|D|E
//Set A
return outhash;
}
int main()
{
QMachine m(30);
cout << measure(minisha1(m));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment