2014-12-20 19:30:34 +00:00
|
|
|
//
|
|
|
|
// mpw-bench.c
|
|
|
|
// MasterPassword
|
|
|
|
//
|
|
|
|
// Created by Maarten Billemont on 2014-12-20.
|
|
|
|
// Copyright (c) 2014 Lyndir. All rights reserved.
|
|
|
|
//
|
|
|
|
|
2014-10-15 20:26:09 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
2017-01-05 15:58:02 +00:00
|
|
|
#include <math.h>
|
2014-10-15 20:26:09 +00:00
|
|
|
#include <string.h>
|
|
|
|
#include <errno.h>
|
2014-12-20 19:30:34 +00:00
|
|
|
#include <sys/time.h>
|
2014-10-15 20:26:09 +00:00
|
|
|
|
2017-08-29 05:01:38 +00:00
|
|
|
#include "bcrypt.h"
|
2014-12-20 19:30:34 +00:00
|
|
|
|
|
|
|
#include "mpw-algorithm.h"
|
2016-01-04 19:52:05 +00:00
|
|
|
#include "mpw-util.h"
|
2014-10-15 20:26:09 +00:00
|
|
|
|
|
|
|
#define MP_N 32768
|
|
|
|
#define MP_r 8
|
|
|
|
#define MP_p 2
|
|
|
|
|
2014-12-20 19:30:34 +00:00
|
|
|
static void mpw_getTime(struct timeval *time) {
|
2014-10-15 20:26:09 +00:00
|
|
|
|
2014-12-20 19:30:34 +00:00
|
|
|
if (gettimeofday( time, NULL ) != 0)
|
2017-08-01 21:35:13 +00:00
|
|
|
ftl( "Could not get time: %s\n", strerror( errno ) );
|
2014-12-20 19:30:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static const double mpw_showSpeed(struct timeval startTime, const unsigned int iterations, const char *operation) {
|
|
|
|
|
|
|
|
struct timeval endTime;
|
|
|
|
mpw_getTime( &endTime );
|
|
|
|
|
|
|
|
const time_t dsec = (endTime.tv_sec - startTime.tv_sec);
|
|
|
|
const suseconds_t dusec = (endTime.tv_usec - startTime.tv_usec);
|
|
|
|
const double elapsed = dsec + dusec / 1000000.;
|
|
|
|
const double speed = iterations / elapsed;
|
|
|
|
|
|
|
|
fprintf( stderr, " done. " );
|
2017-08-27 14:47:39 +00:00
|
|
|
fprintf( stdout, "%d %s iterations in %lus %uµs -> %.2f/s\n", iterations, operation, dsec, dusec, speed );
|
2014-12-20 19:30:34 +00:00
|
|
|
|
|
|
|
return speed;
|
|
|
|
}
|
2014-10-15 20:26:09 +00:00
|
|
|
|
2014-12-20 19:30:34 +00:00
|
|
|
int main(int argc, char *const argv[]) {
|
2014-10-15 20:26:09 +00:00
|
|
|
|
2014-12-20 19:30:34 +00:00
|
|
|
const char *fullName = "Robert Lee Mitchel";
|
|
|
|
const char *masterPassword = "banana colored duckling";
|
|
|
|
const char *siteName = "masterpasswordapp.com";
|
2017-08-08 00:27:08 +00:00
|
|
|
const MPCounterValue siteCounter = MPCounterValueDefault;
|
2017-08-10 16:30:42 +00:00
|
|
|
const MPResultType resultType = MPResultTypeDefault;
|
2017-08-01 17:45:54 +00:00
|
|
|
const MPKeyPurpose keyPurpose = MPKeyPurposeAuthentication;
|
|
|
|
const char *keyContext = NULL;
|
2014-10-15 20:26:09 +00:00
|
|
|
struct timeval startTime;
|
2017-01-05 15:58:02 +00:00
|
|
|
unsigned int iterations;
|
|
|
|
float percent;
|
2017-07-23 03:45:54 +00:00
|
|
|
MPMasterKey masterKey;
|
2014-10-15 20:26:09 +00:00
|
|
|
|
2016-08-24 04:07:58 +00:00
|
|
|
// Start HMAC-SHA-256
|
2017-01-05 15:58:02 +00:00
|
|
|
// Similar to phase-two of mpw
|
2016-08-24 04:07:58 +00:00
|
|
|
uint8_t *sitePasswordInfo = malloc( 128 );
|
2017-08-27 14:47:39 +00:00
|
|
|
iterations = 4200000; /* tuned to ~10s on dev machine */
|
2017-08-01 12:31:39 +00:00
|
|
|
masterKey = mpw_masterKey( fullName, masterPassword, MPAlgorithmVersionCurrent );
|
2017-08-01 20:50:50 +00:00
|
|
|
if (!masterKey) {
|
2017-08-01 21:35:13 +00:00
|
|
|
ftl( "Could not allocate master key: %s\n", strerror( errno ) );
|
2017-08-01 20:50:50 +00:00
|
|
|
abort();
|
|
|
|
}
|
2014-12-20 19:30:34 +00:00
|
|
|
mpw_getTime( &startTime );
|
2017-01-05 15:58:02 +00:00
|
|
|
for (int i = 1; i <= iterations; ++i) {
|
2017-08-10 16:30:42 +00:00
|
|
|
free( (void *)mpw_hash_hmac_sha256( masterKey, MPMasterKeySize, sitePasswordInfo, 128 ) );
|
2014-10-17 21:10:43 +00:00
|
|
|
|
2017-01-05 15:58:02 +00:00
|
|
|
if (modff(100.f * i / iterations, &percent) == 0)
|
|
|
|
fprintf( stderr, "\rhmac-sha-256: iteration %d / %d (%.0f%%)..", i, iterations, percent );
|
2014-10-17 12:52:15 +00:00
|
|
|
}
|
2016-08-24 04:07:58 +00:00
|
|
|
const double hmacSha256Speed = mpw_showSpeed( startTime, iterations, "hmac-sha-256" );
|
2017-01-05 15:58:02 +00:00
|
|
|
free( (void *)masterKey );
|
2014-10-15 20:26:09 +00:00
|
|
|
|
|
|
|
// Start BCrypt
|
2017-01-05 15:58:02 +00:00
|
|
|
// Similar to phase-one of mpw
|
2017-08-27 14:47:39 +00:00
|
|
|
uint8_t bcrypt_rounds = 9;
|
|
|
|
iterations = 170; /* tuned to ~10s on dev machine */
|
2014-12-20 19:30:34 +00:00
|
|
|
mpw_getTime( &startTime );
|
2017-01-05 15:58:02 +00:00
|
|
|
for (int i = 1; i <= iterations; ++i) {
|
2017-08-27 14:47:39 +00:00
|
|
|
bcrypt( masterPassword, bcrypt_gensalt( bcrypt_rounds ) );
|
2014-10-17 21:10:43 +00:00
|
|
|
|
2017-01-05 15:58:02 +00:00
|
|
|
if (modff(100.f * i / iterations, &percent) == 0)
|
2017-08-27 14:47:39 +00:00
|
|
|
fprintf( stderr, "\rbcrypt (rounds 10^%d): iteration %d / %d (%.0f%%)..", bcrypt_rounds, i, iterations, percent );
|
2014-10-17 12:52:15 +00:00
|
|
|
}
|
2017-08-27 14:47:39 +00:00
|
|
|
const double bcrypt9Speed = mpw_showSpeed( startTime, iterations, "bcrypt" );
|
2014-10-17 21:10:43 +00:00
|
|
|
|
2017-01-05 15:58:02 +00:00
|
|
|
// Start SCrypt
|
|
|
|
// Phase one of mpw
|
2017-08-27 14:47:39 +00:00
|
|
|
iterations = 50; /* tuned to ~10s on dev machine */
|
2017-01-05 15:58:02 +00:00
|
|
|
mpw_getTime( &startTime );
|
|
|
|
for (int i = 1; i <= iterations; ++i) {
|
2017-08-01 12:31:39 +00:00
|
|
|
free( (void *)mpw_masterKey( fullName, masterPassword, MPAlgorithmVersionCurrent ) );
|
2017-01-05 15:58:02 +00:00
|
|
|
|
|
|
|
if (modff(100.f * i / iterations, &percent) == 0)
|
|
|
|
fprintf( stderr, "\rscrypt_mpw: iteration %d / %d (%.0f%%)..", i, iterations, percent );
|
|
|
|
}
|
|
|
|
const double scryptSpeed = mpw_showSpeed( startTime, iterations, "scrypt_mpw" );
|
|
|
|
|
|
|
|
// Start MPW
|
|
|
|
// Both phases of mpw
|
2017-08-27 14:47:39 +00:00
|
|
|
iterations = 50; /* tuned to ~10s on dev machine */
|
2017-01-05 15:58:02 +00:00
|
|
|
mpw_getTime( &startTime );
|
|
|
|
for (int i = 1; i <= iterations; ++i) {
|
2017-08-01 12:31:39 +00:00
|
|
|
masterKey = mpw_masterKey( fullName, masterPassword, MPAlgorithmVersionCurrent );
|
2017-08-01 20:50:50 +00:00
|
|
|
if (!masterKey) {
|
2017-08-01 21:35:13 +00:00
|
|
|
ftl( "Could not allocate master key: %s\n", strerror( errno ) );
|
2017-08-01 20:50:50 +00:00
|
|
|
break;
|
|
|
|
}
|
2017-01-05 15:58:02 +00:00
|
|
|
|
2017-08-10 16:30:42 +00:00
|
|
|
free( (void *)mpw_siteResult(
|
|
|
|
masterKey, siteName, siteCounter, keyPurpose, keyContext, resultType, NULL, MPAlgorithmVersionCurrent ) );
|
2017-01-05 15:58:02 +00:00
|
|
|
free( (void *)masterKey );
|
|
|
|
|
|
|
|
if (modff(100.f * i / iterations, &percent) == 0)
|
|
|
|
fprintf( stderr, "\rmpw: iteration %d / %d (%.0f%%)..", i, iterations, percent );
|
|
|
|
}
|
|
|
|
const double mpwSpeed = mpw_showSpeed( startTime, iterations, "mpw" );
|
|
|
|
|
2014-10-17 21:10:43 +00:00
|
|
|
// Summarize.
|
|
|
|
fprintf( stdout, "\n== SUMMARY ==\nOn this machine,\n" );
|
2017-08-27 14:47:39 +00:00
|
|
|
fprintf( stdout, " - mpw is %f times slower than hmac-sha-256.\n", hmacSha256Speed / mpwSpeed );
|
|
|
|
fprintf( stdout, " - mpw is %f times slower than bcrypt (rounds 10^%d).\n", bcrypt9Speed / mpwSpeed, bcrypt_rounds );
|
|
|
|
fprintf( stdout, " - scrypt is %f times slower than bcrypt (rounds 10^%d).\n", bcrypt9Speed / scryptSpeed, bcrypt_rounds );
|
2014-10-15 20:26:09 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|