Wednesday, July 23, 2014

Transpose matrix with SSE2

Output:
Matrix:
| 1  2  3  4 |
| 5  6  7  8 |
| 8  7  6  5 |
| 4  3  2  1 |

Matrix, transposed:
| 1  5  8  4 |
| 2  6  7  3 |
| 3  7  6  2 |
| 4  8  5  1 |


Code:
/*Please refactor identifiers, as you like*/

#define eCG/*G++*/
/*#define eCV*//*VC++*/

#ifdef eCG
#define okN(p)__attribute__((aligned(p)))
#elif defined eCV
#define okN(p)__declspec(align(p))
#endif

#include<emmintrin.h>
#include<iostream>

struct okN(0x10) tR4x4{
float m[0x10];/*Column-major, not row-major -- OpenGL FTW*/

#define o_(a,b)\
float N##a##b()const noexcept{return m[((b-1)<<2)+(a-1)];}\
float&N##a##b()noexcept{return m[((b-1)<<2)+(a-1)];}
o_(1,1)o_(1,2)o_(1,3)o_(1,4)
o_(2,1)o_(2,2)o_(2,3)o_(2,4)
o_(3,1)o_(3,2)o_(3,3)o_(3,4)
o_(4,1)o_(4,2)o_(4,3)o_(4,4)
#undef o_

tR4x4(
float p11,float p12,float p13,float p14,
float p21,float p22,float p23,float p24,
float p31,float p32,float p33,float p34,
float p41,float p42,float p43,float p44
)noexcept{
#define o_(a,b)N##a##b()=p##a##b;
o_(1,1)o_(1,2)o_(1,3)o_(1,4)
o_(2,1)o_(2,2)o_(2,3)o_(2,4)
o_(3,1)o_(3,2)o_(3,3)o_(3,4)
o_(4,1)o_(4,2)o_(4,3)o_(4,4)
#undef o_
}

tR4x4(__m128i const&a,__m128i const&b,__m128i const&c,__m128i const&d)noexcept{
((__m128i*)this)[0]=a,((__m128i*)this)[1]=b,
((__m128i*)this)[2]=c,((__m128i*)this)[3]=d;}

#if 0/*Without SIMD SSE2*/
tR4x4 kTp()const noexcept{return tR4x4(
N11(),N21(),N31(),N41(),
N12(),N22(),N32(),N42(),
N13(),N23(),N33(),N43(),
N14(),N24(),N34(),N44());}
#endif

tR4x4 kTp()const noexcept{__m128i const
l1=_mm_unpacklo_epi32(((__m128i*)this)[0],((__m128i*)this)[2]),
l2=_mm_unpacklo_epi32(((__m128i*)this)[1],((__m128i*)this)[3]),
l3=_mm_unpackhi_epi32(((__m128i*)this)[0],((__m128i*)this)[2]),
l4=_mm_unpackhi_epi32(((__m128i*)this)[1],((__m128i*)this)[3]);
return tR4x4(_mm_unpacklo_epi32(l1,l2),_mm_unpackhi_epi32(l1,l2),_mm_unpacklo_epi32(l3,l4),_mm_unpackhi_epi32(l3,l4));}

friend std::ostream&operator<<(std::ostream&,tR4x4 const&)noexcept;};

std::ostream&operator<<(std::ostream&q,tR4x4 const&p)noexcept{q
<<"| "<<p.N11()<<"  "<<p.N12()<<"  "<<p.N13()<<"  "<<p.N14()<<" |\n"
<<"| "<<p.N21()<<"  "<<p.N22()<<"  "<<p.N23()<<"  "<<p.N24()<<" |\n"
<<"| "<<p.N31()<<"  "<<p.N32()<<"  "<<p.N33()<<"  "<<p.N34()<<" |\n"
<<"| "<<p.N41()<<"  "<<p.N42()<<"  "<<p.N43()<<"  "<<p.N44()<<" |\n";return q;}

void f()noexcept{
tR4x4 l(
1.F,2.F,3.F,4.F,
5.F,6.F,7.F,8.F,
8.F,7.F,6.F,5.F,
4.F,3.F,2.F,1.F);

std::cout<<"Matrix:\n"<<l<<std::endl;
std::cout<<"Matrix, transposed:\n"<<l.kTp()<<std::endl;}

int main(){f();return 0;}

Monday, July 21, 2014

Securely compare two memory blocks

This function would be necessary to prevent timing attack, when you compare two passwords or two passphrases.

#include<stdint.h>
typedef uint8_t t1u;
typedef int8_t t1s;
typedef uint16_t t2u;
typedef int16_t t2s;
typedef uint32_t t4u;
typedef int32_t t4s;typedef float t4f;
typedef uint64_t t8u;
typedef int64_t t8s;typedef double t8f;
typedef void v;


/*Compare two memory blocks, both of equal size 'O'
1, if same
0, if not the same*/
bool xbEqScr(v const*p,v const*q,t4u O)noexcept{t1u const*A,*B;t8u F=0;t4u l=O>>3;O&=7;
if(l){t8u const*C=(t8u const*)p,*D=(t8u const*)q;
A=O+(t1u const*)(C+l);
B=O+(t1u const*)(D+l);
while(l--){F|=*C++^*D++;}}
else{A=O+(t1u const*)p,B=O+(t1u const*)q;}
switch(O){
case 7:F|=*--A^*--B;
case 6:F|=*--A^*--B;
case 5:F|=*--A^*--B;
case 4:F|=*--A^*--B;
case 3:F|=*--A^*--B;
case 2:F|=*--A^*--B;
case 1:F|=*--A^*--B;}return!F;}

Test endianness

#include<stdint.h>
typedef uint16_t t2u;

/*1, if little; 0, if big*/
bool constexpr bEL()noexcept{return(t2u&)"AB"==(t2u)0x4241;}

C++ fixed-point type

Simple implementation ...
Preferably, please copy the code into your source editor. (UPDATE: My apology, because there was an error ... -- It's been fixed .. > <)

Output:
Addition
[PASS]    5.0+3.0=8.0F Out: (float) (fixed)  8  8.0000
[PASS]    5.0+=3.0=>8.0F Out: (float) (fixed)  8  8.0000
[PASS]    7.0+-3.0=4.0F Out: (float) (fixed)  4  4.0000
[PASS]    7.0+=-3.0=>4.0F Out: (float) (fixed)  4  4.0000
[PASS]    2.0+-8.0=-6.0F Out: (float) (fixed)  -6  -6.0000
[PASS]    2.0+=-8.0=>-6.0F Out: (float) (fixed)  -6  -6.0000
[PASS]    -6.0+-3.0=-9.0F Out: (float) (fixed)  -9  -9.0000
[PASS]    -6.0+=-3.0=>-9.0F Out: (float) (fixed)  -9  -9.0000

Subtraction
[PASS]    8.0-6.0=2.0F Out: (float) (fixed)  2  2.0000
[PASS]    8.0-=6.0=>2.0F Out: (float) (fixed)  2  2.0000
[PASS]    1.0--3.0=4.0F Out: (float) (fixed)  4  4.0000
[PASS]    1.0-=-3.0=>4.0F Out: (float) (fixed)  4  4.0000
[PASS]    -3.0--9.0=6.0F Out: (float) (fixed)  6  6.0000
[PASS]    -3.0-=-9.0=>6.0F Out: (float) (fixed)  6  6.0000
[PASS]    -2.0-5.0=-7.0F Out: (float) (fixed)  -7  -7.0000
[PASS]    -2.0-=5.0=>-7.0F Out: (float) (fixed)  -7  -7.0000

Multiplication
[PASS]    2.0*3.0=6.0F Out: (float) (fixed)  6  6.0000
[PASS]    2.0*=3.0=>6.0F Out: (float) (fixed)  6  6.0000
[PASS]    3.0*-4.0=-12.0F Out: (float) (fixed)  -12  -12.0000
[PASS]    3.0*=-4.0=>-12.0F Out: (float) (fixed)  -12  -12.0000
[PASS]    2.0*-5.0=-10.0F Out: (float) (fixed)  -10  -10.0000
[PASS]    2.0*=-5.0=>-10.0F Out: (float) (fixed)  -10  -10.0000
[PASS]    -6.0*-7.0=42.0F Out: (float) (fixed)  42  42.0000
[PASS]    -6.0*=-7.0=>42.0F Out: (float) (fixed)  42  42.0000

Division
[PASS]    14.0/3.5=4.0F Out: (float) (fixed)  4  4.0000
[PASS]    14.0/=3.5=>4.0F Out: (float) (fixed)  4  4.0000
[PASS]    15.0/-3.0=-5.0F Out: (float) (fixed)  -5  -5.0000
[PASS]    15.0/=-3.0=>-5.0F Out: (float) (fixed)  -5  -5.0000
[PASS]    -36.0/8.0=-4.5F Out: (float) (fixed)  -4.5  -4.5000
[PASS]    -36.0/=8.0=>-4.5F Out: (float) (fixed)  -4.5  -4.5000
[PASS]    -48.0/-8.0=6.0F Out: (float) (fixed)  6  6.0000
[PASS]    -48.0/=-8.0=>6.0F Out: (float) (fixed)  6  6.0000

Modulo
[PASS]    3.0%5.0=3.0F Out: (float) (fixed)  3  3.0000
[PASS]    2.0%4.5=2.0F Out: (float) (fixed)  2  2.0000
[PASS]    6.5%5.0=1.5F Out: (float) (fixed)  1.5  1.5000
[PASS]    8.0%4.5=3.5F Out: (float) (fixed)  3.5  3.5000


Code:
/*
Other header #1
*/
/*Bloody C99 keywords, I deny!*/
#include<stdint.h>
typedef uint8_t t1u;
typedef int8_t t1s;
typedef uint16_t t2u;
typedef int16_t t2s;
typedef uint32_t t4u;
typedef int32_t t4s;typedef float t4f;
typedef uint64_t t8u;
typedef int64_t t8s;typedef double t8f;

/*Haters gonna hate ... */
typedef void v;
#define ig else if
#define ih else
#define rK noexcept
#define rU const noexcept

/*
Other header #2
*/
typedef t4s tII4;
/*struct tII4{};*/  /*Or something similar*/
/*
Other header #3
*/
typedef t4u tWU4;
/*struct tWU4{};*/  /*Or something similar*/

/*
The header
*/
#include<iostream>
struct tRX4{
public:
typedef t4s tCn;
typedef t4u tFc;
static tFc const cFc=8;
static tCn const cFM=(1<<cFc)-1;
static tRX4 const c0;
static tRX4 const c1;
protected:
tCn m;
public:
inline tCn g()rU{return m;}

v operator+=(tRX4 const&p)rK{m+=p.m;}tRX4 operator+(tRX4 const&p)rU{tRX4 l;l.m=m+p.m;return l;}
v operator-=(tRX4 const&p)rK{m-=p.m;}tRX4 operator-(tRX4 const&p)rU{tRX4 l;l.m=m-p.m;return l;}tRX4 operator-()rU{tRX4 l;l.m=-m;return l;}
inline v operator*=(tRX4 const&p)rK{m=(((t8s)m)*p.m)>>cFc;}inline tRX4 operator*(tRX4 const&p)rU{tRX4 l;l.m=(tCn)((((t8s)m)*p.m)>>cFc);return l;}
inline v operator/=(tRX4 const&p)rK{m=(((t8s)m)<<cFc)/p.m;}inline tRX4 operator/(tRX4 const&p)rU{tRX4 l;l.m=(tCn)((((t8s)m)<<cFc)/p.m);return l;}
inline tRX4 operator%(tRX4 const&p)rU{tRX4 l;l.m=m%p.m;return l;}
inline v operator=(tII4 p)rK{m=(tCn)((t4s)p<<cFc);}
inline v operator*=(tII4 p)rK{m*=(t4s)p;}inline tRX4 operator*(tII4 p)rU{tRX4 l;l.m=m*(t4s)p;return l;}
inline v operator/=(tII4 p)rK{m/=(t4s)p;}inline tRX4 operator/(tII4 p)rU{tRX4 l;l.m=m/(t4s)p;return l;}
inline v operator%=(tII4 p)rK{m%=(t4s)p<<cFc;}inline tRX4 operator%(tII4 p)rU{tRX4 l;l.m=m%((t4s)p<<cFc);return l;}
inline v operator^=(tRX4 const&p)rK{m^=p.m;}inline tRX4 operator^(tRX4 const&p)rU{tRX4 l;l.m=m^p.m;return l;}
inline v operator&=(tRX4 const&p)rK{m&=p.m;}inline tRX4 operator&(tRX4 const&p)rU{tRX4 l;l.m=m&p.m;return l;}
inline v operator|=(tRX4 const&p)rK{m|=p.m;}inline tRX4 operator|(tRX4 const&p)rU{tRX4 l;l.m=m|p.m;return l;}
inline tRX4 operator~()rU{tRX4 l;l.m=~m;return l;}
bool operator==(tRX4 const&p)rU{return m==p.m;}bool operator<=(tRX4 const&p)rU{return m<=p.m;}bool operator<(tRX4 const&p)rU{return m<p.m;}
bool operator!=(tRX4 const&p)rU{return m!=p.m;}bool operator>=(tRX4 const&p)rU{return m>=p.m;}bool operator>(tRX4 const&p)rU{return m>p.m;}
bool operator==(t4f p)rU{return (*this)==tRX4(p);}bool operator<=(t4f p)rU{return (*this)<=tRX4(p);}bool operator<(t4f p)rU{return (*this)<tRX4(p);}
bool operator!=(t4f p)rU{return (*this)!=tRX4(p);}bool operator>=(t4f p)rU{return (*this)>=tRX4(p);}bool operator>(t4f p)rU{return (*this)>tRX4(p);}
friend bool operator==(t4f p,tRX4 const&q)rK{return tRX4(p)==q;}friend bool operator<=(t4f p,tRX4 const&q)rK{return tRX4(p)<=q;}friend bool operator<(t4f p,tRX4 const&q)rK{return tRX4(p)<q;}
friend bool operator!=(t4f p,tRX4 const&q)rK{return tRX4(p)!=q;}friend bool operator>=(t4f p,tRX4 const&q)rK{return tRX4(p)>=q;}friend bool operator>(t4f p,tRX4 const&q)rK{return tRX4(p)>q;}
bool operator==(t8f p)rU{return (*this)==tRX4(p);}bool operator<=(t8f p)rU{return (*this)<=tRX4(p);}bool operator<(t8f p)rU{return (*this)<tRX4(p);}
bool operator!=(t8f p)rU{return (*this)!=tRX4(p);}bool operator>=(t8f p)rU{return (*this)>=tRX4(p);}bool operator>(t8f p)rU{return (*this)>tRX4(p);}
friend bool operator==(t8f p,tRX4 const&q)rK{return tRX4(p)==q;}friend bool operator<=(t8f p,tRX4 const&q)rK{return tRX4(p)<=q;}friend bool operator<(t8f p,tRX4 const&q)rK{return tRX4(p)<q;}
friend bool operator!=(t8f p,tRX4 const&q)rK{return tRX4(p)!=q;}friend bool operator>=(t8f p,tRX4 const&q)rK{return tRX4(p)>=q;}friend bool operator>(t8f p,tRX4 const&q)rK{return tRX4(p)>q;}

friend std::ostream&operator<<(std::ostream&,tRX4 const&)rK;

public:
inline v operator=(t4f p)rK{m=(tCn)(p*c1.m);}
inline v operator=(t8f p)rK{m=(tCn)(p*c1.m);}
inline tRX4(t4f p)rK{m=(tCn)(p*c1.m);}
inline tRX4(t8f p)rK{m=(tCn)(p*c1.m);}
public:
inline explicit tRX4(t2s p,t2u q)rK:m((((tCn)p)<<cFc)|(q>>(16-cFc))){}
inline explicit tRX4(tII4 const&p)rK{m=(tCn)((t4s)p<<cFc);}
inline explicit tRX4(tWU4 const&p)rK{m=(tCn)((t4u)p<<cFc);}
public:
tRX4&operator=(tRX4 const&)rK=default;
tRX4&operator=(tRX4&&)rK=default;
tRX4(tRX4 const&)rK=default;
tRX4(tRX4&&)rK=default;
tRX4()rK=default;};

/*
The source
*/
tRX4 const tRX4::c0(tII4(0));
tRX4 const tRX4::c1(tII4(1));

std::ostream&operator<<(std::ostream&q,tRX4 const&p)rK{tRX4::tCn l;if(p<tRX4::c0){l=~p.g()+1;if(l>0){q<<"-";}}ih{l=p.g();}
static tRX4::tCn const l10=1000;
tRX4::tCn const lDm=((l&(tRX4::c1.g()-1))*l10*10)/tRX4::c1.g();
tRX4::tCn lDv=l10;
q<<(l>>tRX4::cFc);q<<".";
while(lDv&&!(lDm/lDv)){q<<"0";lDv/=10;}if(lDm){q<<lDm;}return q;}

/*
The tester
*/
#include<cmath>

v f()rK{
#define o_f1(a,b,p1,p2,p)\
lA1=a,lA2=b;lA0=lA1 p1 lA2;\
lB1=a,lB2=b;lB0=lB1 p1 lB2;\
std::cout<<(lB0==p?"[PASS]":"[FAIL]")<<"    "<<#a<<#p1<<#b<<"="<<#p<<" Out: (float) (fixed)  "<<lA0<<"  "<<lB0<<std::endl;\
lA0=a,lA1=b;lA0 p2 lA1;\
lB0=a,lB1=b;lB0 p2 lB1;\
std::cout<<(lB0==p?"[PASS]":"[FAIL]")<<"    "<<#a<<#p2<<#b<<"=>"<<#p<<" Out: (float) (fixed)  "<<lA0<<"  "<<lB0<<std::endl;
t4f lA0,lA1,lA2;
tRX4 lB0,lB1,lB2,lB3;
printf("Addition\n");
o_f1(5.0,3.0,+,+=,8.0F)
o_f1(7.0,-3.0,+,+=,4.0F)
o_f1(2.0,-8.0,+,+=,-6.0F)
o_f1(-6.0,-3.0,+,+=,-9.0F)printf("\n");
printf("Subtraction\n");
o_f1(8.0,6.0,-,-=,2.0F)
o_f1(1.0,-3.0,-,-=,4.0F)
o_f1(-3.0,-9.0,-,-=,6.0F)
o_f1(-2.0,5.0,-,-=,-7.0F)printf("\n");
printf("Multiplication\n");
o_f1(2.0,3.0,*,*=,6.0F)
o_f1(3.0,-4.0,*,*=,-12.0F)
o_f1(2.0,-5.0,*,*=,-10.0F)
o_f1(-6.0,-7.0,*,*=,42.0F)printf("\n");
printf("Division\n");
o_f1(14.0,3.5,/,/=,4.0F)
o_f1(15.0,-3.0,/,/=,-5.0F)
o_f1(-36.0,8.0,/,/=,-4.5F)
o_f1(-48.0,-8.0,/,/=,6.0F)printf("\n");
#define o_f2(a,b,p1,p)\
lA1=a,lA2=b;lA0=std::fmod(lA1,lA2);\
lB1=a,lB2=b;lB0=lB1 p1 lB2;\
std::cout<<(lB0==p?"[PASS]":"[FAIL]")<<"    "<<#a<<#p1<<#b<<"="<<#p<<" Out: (float) (fixed)  "<<lA0<<"  "<<lB0<<std::endl;
printf("Modulo\n");
o_f2(3.0,5.0,%,3.0F)
o_f2(2.0,4.5,%,2.0F)
o_f2(6.5,5.0,%,1.5F)
o_f2(8.0,4.5,%,3.5F)printf("\n");
#undef o_f2
#undef o_f1
}

int main(){f();getchar();return 0;}

Sunday, July 20, 2014

Decrypt WhatsApp crypt5 file

Decrypt WhatsApp crypt5 file, with Python and M2Crypto.

(In Ubuntu, for example ... )
1. Install Python, install M2Crypto (Also install SQLite database browser)
2. Copy the script at the bottom of this page, save it in your local directory as <name>.py
(example: WaDecr.py)
3. Open terminal and run:
python ./WaDecr.py ./msgstore.db.crypt5
(Replace the token "msgstore.db.crypt5" with your own file name)
In Windows: (Please notice that you have to use the "current-folder" specifier in Linux)
 python WaDecr.py msgstore.db.crypt5

4. Voila!


Once you get your decrypted file, use a SQLite database browser to view your chats.

Au revoir!


#!/usr/bin/python

import sys
import hashlib
import StringIO
import os.path
from M2Crypto import EVP

ngKy=bytearray([
0x8D,0x4B,0x15,0x5C,0xC9,0xFF,0x81,0xE5,
0xCB,0xF6,0xFA,0x78,0x19,0x36,0x6A,0x3E,
0xC6,0x21,0xA6,0x56,0x41,0x6C,0xD7,0x93])
ngIv=bytearray([
0x1E,0x39,0xF3,0x69,0xE9,0x0D,0xB3,0x3A,
0xA7,0x3B,0x44,0x2B,0xBB,0xB6,0xB0,0xB9])

def fFil(p):
    return p+".decr.db"

def fBCryp(pDB,pAc):
    lDB=fFil(pDB)
    lb_=True
    for i in xrange(10):
        if os.path.isfile(lDB):
            lDB=fFil(pDB+"."+str(i))
        else:
            lb_=False
            break
    if lb_:
        print "ERROR: Cannot find a directory for your decrypted file, to safely write ... :("
        return
    try:
        lFH=file(pDB,'rb')
    except:
        print "ERROR: Cannot open your encrypted file ... Check directory again ... !   -.-"
        return  
    lED=lFH.read()
    lFH.close()
    l_M=hashlib.md5()
    l_M.update(pAc)
    lM5=bytearray(l_M.digest())
    for i in xrange(24):ngKy[i]^=lM5[i&0xF]
    try:
        lCi=EVP.Cipher('aes_192_cbc',key=ngKy,iv=ngIv,op=0)
        lFI=file(lDB,'wb')
        lFI.write(lCi.update(lED))
        lFI.write(lCi.final())
        lFI.close()
    except:
        print "ERROR: Cannot decrypt ...\nDid you put the correct account name,\nhave you checked if it is the \"crypt5\" file and not the \"crypt\" file,\nor are you sure that the file is not corrupted  ... ?  o.O"
        return
    print "SUCCESS! =D"

if __name__ == '__main__':
    if len(sys.argv) == 3:
        fBCryp(sys.argv[1],sys.argv[2])
    else:
        print 'Parameter:   %s <crypt5-file> <name-of-account>' %sys.argv[0]