problem in implementing google authenticator app in c++ - multi-factor-authentication

i am trying to implement google Authenticator mechanism in c++.
i always get different OTP than that of google authenticator.
i wonder why ?
1 - i searched and found that google uses HMAC-SHA1 algorithm. but i am suspecious because :
almost all articles i have read are old. seems irrelevent.
i found that google authenticator code is now private before it was
open source. so am afraid google might changed the algorithim used
i found that SHA1 is no longer secure. some people managed to make
SHA1-collision. i would be surprized if google still uses it instead of
other more secure algorithms like SHA256,SHA512.
if you have any information regarding that, please inform me.
2 - i am sure my code is correct.
because i compared the output Hash value to automatically generated one
in this website, and they always match.
the website : https://www.liavaag.org/English/SHA-Generator/HMAC/
because code is pretty simple!
here's the code :
/*****************************************************************************************/
#include <iostream>
#include <cmath>
#include <ctime>
#include <stdio.h>
#include <string>
#include "SHA1.h"
#include "HMAC_SHA1.h"
using namespace std;
void IntegerToString(time_t epochTime, BYTE timeAsString[] , int length);
int TimeLength(time_t epochTime);
int main(void)
{
CHMAC_SHA1 sha1;
int one,two,three,four;
time_t result = time(nullptr);
result = (long long)floor(result/30);
cout << result <<endl;
int offset;
int truncatedHash;
int finalOTP;
BYTE key[33] = "atoqb4y572clkhj2sls5h72a76cnyzpe";
int key_len = 33; /*32 + null terminator*/
int text_len = TimeLength(result);
//cout << text_len << endl;
BYTE text[text_len+1];
IntegerToString(result , text , text_len);
text[text_len] = '\0';
//printf("%s",text);
/*the digest is always 20 bytes long*/
BYTE digest[20] = {0};
sha1.HMAC_SHA1(text,text_len,key,key_len-1,digest);
printf("0x");
for(int i = 0 ; i < 20 ; i++)
{
printf("%x",(int)digest[i]);
}
offset = digest[19] & 0xf;
one = (digest[offset+0] & 0x7f) << 24;
two = (digest[offset+1] & 0xff) << 16;
three = (digest[offset+2] & 0xff) << 8;
four = (digest[offset+3] & 0xff);
truncatedHash = one | two | three | four;
finalOTP = (truncatedHash % (1000000));
cout << "\nyour OTP : " << finalOTP << endl;
return 0;
}
void IntegerToString(time_t epochTime, BYTE timeAsString[] , int length)
{
time_t reverse = 1; /*to hold zeros*/
int i = 0;
while(epochTime >= 1) /*reverse : 1000 -> 10001*/
{
reverse = reverse*10+epochTime%10;
epochTime = epochTime / 10;
//cout << epochTime << "*" << reverse <<endl;
}
while(reverse != 1)
{
timeAsString[i] = (reverse%10 +'0');
reverse = reverse / 10;
//cout << i << timeAsString[i] << "#" << reverse << endl;
i++;
}
}
int TimeLength(time_t epochTime)
{
int counter = 0;
while(epochTime)
{
epochTime = epochTime / 10;
counter++;
}
return counter;
}
please help.

The key you use atoqb4y572clkhj2sls5h72a76cnyzpe does not seem to be in hex format.
You should be using hex (hex of your string is 04dd00f31dfe84b51d3a92e5d3ff40ff84dc65e4 If you need to use base32, you need to convert it to hex first

This repo works out perfectly: https://github.com/RavuAlHemio/cpptotp
Just tested.
steps on ubuntu:
git clone https://github.com/RavuAlHemio/cpptotp.git
cd cpptotp/
mkdir build
cd build/
cmake ..
make
./gauche
Input your key

Related

Segmentation Fault 11 with Maps and vector c++

I am trying to get a frequency table from a given text.
But the output is showing segmentation fault 11. I don't know why.
I am a newbie. Your help with the code will be very well appreciated.
You can edit my code to make me learn a better method of writing code as well. Thanks a lot.
#include<iostream>
#include<map>
#include<string>
#include<vector>
void make_table(vector<pair<char, int> > &table , string path){
string text = "Hello thusnvkj.ernbuilvgqboipghq3pojavnaj.,fbvlkarebihfg094why091[3tugjvlksbdfv ajklvrpt-30qjhrgiaoehk.BL;H]IH;LGBJSFDNOWI;HBPWRHGB;ORTWIHGOQHRWI0TUGJRLKEWHUGIH49P0-IT302-UR9GM,NXM,BNX,MNMB/E/RGP'KGP34OR[2=O-O-=0-3-1I0-439890375892R0U;L.GNLS.N.SVMS/FS/FKWEP[IF0W))_*(&*(^^&$%#^%$&%*(^*&)(*)_*_(()())))]]'";
map<char, int> m;
for(int i=0; text[i]!='\0'; i++){
m[text[i]]++;
}
map<char,int>::iterator it;
int j=0;
for(it=m.begin();it!=m.end(); it++){
table[j].first=it->first;
table[j].second=it->second;
j++;
//cout << it->first << " " << it->second << endl;
}
return;
}
int main(){
vector<pair<char , int> > table;
string path;
//cin >> path;
path= "Hi";
make_table(table, path);
// make_table function will give us the sorted table(vector of pair) in the decreasing order of frequency of a character.
/*for(int i =0; i<table.size(); i++){
cout << table[i].first << " " << table[i].second << endl;
}
*/
return 0;
}
You get an error because you try to access elements in an empty vector
table[j].first=it->first;
table[j].second=it->second;
Here you can add one line outside the for loop
table.resize(text.size());

How to use OpenMP to deal with two for loops with

I am new to OpenMP... Please help me with this dumb question. Thank you :)
Basically, I want to use OpenMP to speed up two for loops. But I do not know why it keeps saying: invalid controlling predicate for the for loop.
By the way, my GCC version is gcc (Ubuntu 6.2.0-5ubuntu12) 6.2.0 20161005, and OS I am using is Ubuntu 16.10.
Basically, I generate a toy data that has a typical Key-Value style, like this:
Data = {
"0": ["100","99","98","97",..."1"];
"1": ["100","99","98","97",..."1"];
...
"999":["100","99","98","97",..."1"];
}
Then, for each key, I want to compare its value with the rest of the keys. Here, I sum them up through "user1_list.size()+user2_list.size();". As for each key, the sum-up process is totally independent of other keys, which means this works for parallelism.
Here is my toy example code.
#include <map>
#include <vector>
#include <string>
#include <iostream>
#include "omp.h"
using namespace std;
int main(){
// Create Data
map<string, vector<string>> data;
for(int i=0; i != 1000; i++){
vector<string> list;
for (int j=100; j!=0; j--){
list.push_back(to_string(j));
}
data[to_string(i)]=list;
}
cout << "Data Total size: " << data.size() << endl;
int count = 1;
#pragma omp parallel for private(count)
for (auto it=data.begin(); it!=data.end(); it++){
//cout << "Evoke Thread: " << omp_get_thread_num();
cout << " count: " << count << " / " << data.size() << endl;
count ++;
string user1 = it->first;
vector<string> user1_list = it->second;
for (auto it2=data.begin(); it2!=data.end(); it2++){
string user2 = it2->first;
vector<string> user2_list = it2->second;
cout << "u1:" << user1 << " u2:" << user2;
int total_size = user1_list.size()+user2_list.size();
cout << " total size: " << total_size << endl;
}
}
return 0;
}

wrong result boost gmp float

I need to compute 5^64 with boost multiprecision library which should yield 542101086242752217003726400434970855712890625 but boost::multiprecision::pow() takes mpfloat and gives 542101086242752217003726392492611895881105408.
However If I loop and repeatedly multiply using mpint I get correct result.
Is it a bug ? or I am using boost::multiprecision::pow() in a wrong way ? or I there is an alternative of using boost::multiprecision::pow() ?
#include <iostream>
#include <string>
#include <boost/multiprecision/gmp.hpp>
typedef boost::multiprecision::mpz_int mpint;
typedef boost::multiprecision::number<boost::multiprecision::gmp_float<4> > mpfloat;
int main(){
mpfloat p = boost::multiprecision::pow(mpfloat(5), mpfloat(64));
std::cout << p.template convert_to<mpint>() << std::endl;
mpint res(1);
for(int i = 0; i < 64; ++i){
res = res * 5;
}
std::cout << res << std::endl;
}

C++ MurmurHash3 returning same value for different key

I am confused with how should i call MurmurHash3_x86_128() when i have lot of key value. The murmurhash3 code can be found https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp. Method definition is given below.
void MurmurHash3_x86_128 ( const void * key, const int len,
uint32_t seed, void * out )
I am passing different key value using a for loop as shown below but still the hash value return is same. If i am removing for loop and passing individual key value then the value is different. What am i doing wrong ?
int main()
{
uint64_t seed = 100;
vector <string> ex;
ex.push_back("TAA");
ex.push_back("ATT");
for(int i=0; i < ex.size(); i++)
{
uint64_t hash_otpt[2]= {};
cout<< hash_otpt << "\t" << endl;
const char *key = ex[i].c_str();
cout << key << endl;
MurmurHash3_x64_128(key, strlen(key), seed, hash_otpt); // 0xb6d99cf8
cout << hash_otpt << endl;
}
return 0;
The line
cout << hash_otpt << endl;
is emitting the address of hash_otpt, not its contents.
It should be
cout << hash_otpt[0] << hash_otpt[1] << endl;
Basically the 128-bit hash is split and stored in two 64-bit unsigned integers (the MSBs in one and the LSBs in another). On combining them, you get the complete hash.

OpenCV perspectiveTransform broken function

Im trying to use perspectiveTransform but I keep getting error. I tried to follow the solution from this thread http://answers.opencv.org/question/18252/opencv-assertion-failed-for-perspective-transform/
_players[i].getCoordinates() is of type Point
_homography_matrix is a 3 x 3 Mat
Mat temp_Mat = Mat::zeros(2, 1, CV_32FC2);
for (int i = 0; i < _players.size(); i++)
{
cout << Mat(_players[i].get_Coordinates()) << endl;
perspectiveTransform(Mat(_players[i].get_Coordinates()), temp_Mat, _homography_matrix);
}
Also, how do I convert temp_Mat into type Point ?
OpenCV Error: Assertion failed (scn + 1 == m.cols) in cv::perspectiveTransform
Basically you just need to correct from
Mat(_players[i].get_Coordinates()) ...
to
Mat2f(_players[i].get_Coordinates()) ...
In the first case you are creating a 2x1, 1 channel float matrix, in the second case (correct) you create a 1x1, 2 channel float matrix.
You also don't need to initialize temp_Mat.
You can also use template Mat_ to better control the types of your Mats. E.g. creating a Mat of type CV_32FC2 is equivalent to create a Mat2f.
This sample code will show you also how to convert back and forth between Mat and Point:
#include <opencv2\opencv.hpp>
#include <vector>
using namespace std;
using namespace cv;
int main()
{
// Some random points
vector<Point2f> pts = {Point2f(1,2), Point2f(5,10)};
// Some random transform matrix
Mat1f m(3,3, float(0.1));
for (int i = 0; i < pts.size(); ++i)
{
cout << "Point: " << pts[i] << endl;
Mat2f dst;
perspectiveTransform(Mat2f(pts[i]), dst, m);
cout << "Dst mat: " << dst << endl;
Point2f p(dst(0));
cout << "Dst point: " << p << endl;
}
return 0;
}

Resources