Ejemplo n.º 1
0
inline
void Hash( hash_context &c, double d )
{
	union
	{
		double doublePart;
		unsigned long long intPart;
	} value;
	
	value.doublePart = d;
	const unsigned long long i = value.intPart;
	
	unsigned char syncBuffer[8] = {
		i & 0xFF,
		(i >> 8) & 0xFF,
		(i >> 16) & 0xFF,
		(i >> 24) & 0xFF,
		(i >> 32) & 0xFF,
		(i >> 40) & 0xFF,
		(i >> 48) & 0xFF,
		(i >> 56) & 0xFF,
	};
	
	hash_process( &c, (unsigned char *)syncBuffer, 8 );
}
Ejemplo n.º 2
0
void HashData( char *_data, char *_result )
{
    hash_context c;
    hash_initial(&c);

    hash_process(&c, (unsigned char *) _data, strlen(_data));

    uint32 hash[5];
    hash_final(&c, hash);

    sprintf(_result, "hsh%04x%04x%04x%04x%04x", hash[0], hash[1], hash[2], hash[3], hash[4]);
}
Ejemplo n.º 3
0
inline
void Hash( hash_context &c, unsigned i )
{
       unsigned char syncBuffer[4] = {
               i & 0xFF,
               (i >> 8) & 0xFF,
               (i >> 16) & 0xFF,
               (i >> 24) & 0xFF
       };

       hash_process( &c, (unsigned char *)syncBuffer, 4 );
}
Ejemplo n.º 4
0
void HashData( char *_data, int _hashToken, char *_result )
{
	hash_context c;
	hash_initial(&c);

	char fullString[512];
	sprintf( fullString, "%s-%d", _data, _hashToken );

	hash_process(&c, (unsigned char *) fullString, strlen(fullString));

    uint32 hash[5];
	hash_final(&c, hash);
	
    sprintf(_result, "hsh%04x%04x%04x%04x%04x", hash[0], hash[1], hash[2], hash[3], hash[4]);
}
Ejemplo n.º 5
0
void cryptonight_hash_ctx_aes_ni(void* output, const void* input, size_t len, struct cryptonight_ctx* ctx) {
	hash_process(&ctx->state.hs, (const uint8_t*) input, len);
	ctx->aes_ctx = (oaes_ctx*) oaes_alloc();
	size_t i, j;
	memcpy(ctx->text, ctx->state.init, INIT_SIZE_BYTE);

	oaes_key_import_data(ctx->aes_ctx, ctx->state.hs.b, AES_KEY_SIZE);
	for (i = 0; likely(i < MEMORY); i += INIT_SIZE_BYTE) {
		fast_aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 0], ctx->aes_ctx->key->exp_data);
		fast_aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 1], ctx->aes_ctx->key->exp_data);
		fast_aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 2], ctx->aes_ctx->key->exp_data);
		fast_aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 3], ctx->aes_ctx->key->exp_data);
		fast_aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 4], ctx->aes_ctx->key->exp_data);
		fast_aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 5], ctx->aes_ctx->key->exp_data);
		fast_aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 6], ctx->aes_ctx->key->exp_data);
		fast_aesb_pseudo_round_mut(&ctx->text[AES_BLOCK_SIZE * 7], ctx->aes_ctx->key->exp_data);
		memcpy(&ctx->long_state[i], ctx->text, INIT_SIZE_BYTE);
	}

	xor_blocks_dst(&ctx->state.k[0], &ctx->state.k[32], ctx->a);
	xor_blocks_dst(&ctx->state.k[16], &ctx->state.k[48], ctx->b);

	for (i = 0; likely(i < ITER / 4); ++i) {
		/* Dependency chain: address -> read value ------+
		 * written value <-+ hard function (AES or MUL) <+
		 * next address  <-+
		 */
		/* Iteration 1 */
		j = e2i(ctx->a);
		fast_aesb_single_round(&ctx->long_state[j], ctx->c, ctx->a);
		xor_blocks_dst(ctx->c, ctx->b, &ctx->long_state[j]);
		/* Iteration 2 */
		mul_sum_xor_dst(ctx->c, ctx->a, &ctx->long_state[e2i(ctx->c)]);
		/* Iteration 3 */
		j = e2i(ctx->a);
		fast_aesb_single_round(&ctx->long_state[j], ctx->b, ctx->a);
		xor_blocks_dst(ctx->b, ctx->c, &ctx->long_state[j]);
		/* Iteration 4 */
		mul_sum_xor_dst(ctx->b, ctx->a, &ctx->long_state[e2i(ctx->b)]);
	}

	memcpy(ctx->text, ctx->state.init, INIT_SIZE_BYTE);
	oaes_key_import_data(ctx->aes_ctx, &ctx->state.hs.b[32], AES_KEY_SIZE);
	for (i = 0; likely(i < MEMORY); i += INIT_SIZE_BYTE) {
		xor_blocks(&ctx->text[0 * AES_BLOCK_SIZE], &ctx->long_state[i + 0 * AES_BLOCK_SIZE]);
		fast_aesb_pseudo_round_mut(&ctx->text[0 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data);
		xor_blocks(&ctx->text[1 * AES_BLOCK_SIZE], &ctx->long_state[i + 1 * AES_BLOCK_SIZE]);
		fast_aesb_pseudo_round_mut(&ctx->text[1 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data);
		xor_blocks(&ctx->text[2 * AES_BLOCK_SIZE], &ctx->long_state[i + 2 * AES_BLOCK_SIZE]);
		fast_aesb_pseudo_round_mut(&ctx->text[2 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data);
		xor_blocks(&ctx->text[3 * AES_BLOCK_SIZE], &ctx->long_state[i + 3 * AES_BLOCK_SIZE]);
		fast_aesb_pseudo_round_mut(&ctx->text[3 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data);
		xor_blocks(&ctx->text[4 * AES_BLOCK_SIZE], &ctx->long_state[i + 4 * AES_BLOCK_SIZE]);
		fast_aesb_pseudo_round_mut(&ctx->text[4 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data);
		xor_blocks(&ctx->text[5 * AES_BLOCK_SIZE], &ctx->long_state[i + 5 * AES_BLOCK_SIZE]);
		fast_aesb_pseudo_round_mut(&ctx->text[5 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data);
		xor_blocks(&ctx->text[6 * AES_BLOCK_SIZE], &ctx->long_state[i + 6 * AES_BLOCK_SIZE]);
		fast_aesb_pseudo_round_mut(&ctx->text[6 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data);
		xor_blocks(&ctx->text[7 * AES_BLOCK_SIZE], &ctx->long_state[i + 7 * AES_BLOCK_SIZE]);
		fast_aesb_pseudo_round_mut(&ctx->text[7 * AES_BLOCK_SIZE], ctx->aes_ctx->key->exp_data);
	}
	memcpy(ctx->state.init, ctx->text, INIT_SIZE_BYTE);
	hash_permutation(&ctx->state.hs);
	/*memcpy(hash, &state, 32);*/
	extra_hashes[ctx->state.hs.b[0] & 3](&ctx->state, 200, output);
	oaes_free((OAES_CTX **) &ctx->aes_ctx);
}
Ejemplo n.º 6
0
void cryptonight_hash(const char* input, char* output, uint32_t len) {
    uint8_t long_state[MEMORY];
    union cn_slow_hash_state state;
    uint8_t text[INIT_SIZE_BYTE];
    uint8_t a[AES_BLOCK_SIZE];
    uint8_t b[AES_BLOCK_SIZE];
    uint8_t c[AES_BLOCK_SIZE];
    uint8_t d[AES_BLOCK_SIZE];
    size_t i, j;
    uint8_t aes_key[AES_KEY_SIZE];
    OAES_CTX* aes_ctx;

    hash_process(&state.hs, (const uint8_t*) input, len);
    memcpy(text, state.init, INIT_SIZE_BYTE);
    memcpy(aes_key, state.hs.b, AES_KEY_SIZE);
    aes_ctx = oaes_alloc();

    oaes_key_import_data(aes_ctx, aes_key, AES_KEY_SIZE);
    for (i = 0; i < MEMORY / INIT_SIZE_BYTE; i++) {
        for (j = 0; j < INIT_SIZE_BLK; j++) {
            oaes_pseudo_encrypt_ecb(aes_ctx, &text[AES_BLOCK_SIZE * j]);
        }
        memcpy(&long_state[i * INIT_SIZE_BYTE], text, INIT_SIZE_BYTE);
    }

    for (i = 0; i < 16; i++) {
        a[i] = state.k[i] ^ state.k[32 + i];
        b[i] = state.k[16 + i] ^ state.k[48 + i];
    }

    for (i = 0; i < ITER / 2; i++) {
        /* Dependency chain: address -> read value ------+
         * written value <-+ hard function (AES or MUL) <+
         * next address  <-+
         */
        /* Iteration 1 */
        j = e2i(a, MEMORY / AES_BLOCK_SIZE);
        copy_block(c, &long_state[j * AES_BLOCK_SIZE]);
        oaes_encryption_round(a, c);
        xor_blocks(b, c);
        swap_blocks(b, c);
        copy_block(&long_state[j * AES_BLOCK_SIZE], c);
        assert(j == e2i(a, MEMORY / AES_BLOCK_SIZE));
        swap_blocks(a, b);
        /* Iteration 2 */
        j = e2i(a, MEMORY / AES_BLOCK_SIZE);
        copy_block(c, &long_state[j * AES_BLOCK_SIZE]);
        mul(a, c, d);
        sum_half_blocks(b, d);
        swap_blocks(b, c);
        xor_blocks(b, c);
        copy_block(&long_state[j * AES_BLOCK_SIZE], c);
        swap_blocks(a, b);
    }

    memcpy(text, state.init, INIT_SIZE_BYTE);
    oaes_key_import_data(aes_ctx, &state.hs.b[32], AES_KEY_SIZE);
    for (i = 0; i < MEMORY / INIT_SIZE_BYTE; i++) {
        for (j = 0; j < INIT_SIZE_BLK; j++) {
            xor_blocks(&text[j * AES_BLOCK_SIZE],
                       &long_state[i * INIT_SIZE_BYTE + j * AES_BLOCK_SIZE]);
            oaes_pseudo_encrypt_ecb(aes_ctx, &text[j * AES_BLOCK_SIZE]);
        }
    }
    memcpy(state.init, text, INIT_SIZE_BYTE);
    hash_permutation(&state.hs);
    /*memcpy(hash, &state, 32);*/
    extra_hashes[state.hs.b[0] & 3](&state, 200, output);
    oaes_free(&aes_ctx);
}
Ejemplo n.º 7
0
void cn_fast_hash(const void *data, size_t length, char *hash) {
  union hash_state state;
  hash_process(&state, data, length);
  memcpy(hash, &state, HASH_SIZE);
}
Ejemplo n.º 8
0
void CryptData::SetCryptKeys(char *Password,unsigned char *Salt,bool Encrypt,bool OldOnly)
{
  if (*Password==0)
    return;
  if (OldOnly)
  {
#ifndef SFX_MODULE
    if (CRCTab[1]==0)
      InitCRC();
    unsigned char Psw[MAXPASSWORD];
    SetOldKeys(Password);
    Key[0]=0xD3A3B879L;
    Key[1]=0x3F6D12F7L;
    Key[2]=0x7515A235L;
    Key[3]=0xA4E7F123L;
    memset(Psw,0,sizeof(Psw));
#if defined(_WIN_32) && !defined(GUI)
    CharToOemBuff(Password,(char*)Psw,strlen(Password));
#else
    strncpy((char *)Psw,Password,MAXPASSWORD-1);
#endif
    int PswLength=strlen(Password);
    memcpy(SubstTable,InitSubstTable,sizeof(SubstTable));
    for (int J=0;J<256;J++)
      for (int I=0;I<PswLength;I+=2)
      {
        unsigned int N1=(unsigned char)CRCTab[(Psw[I]-J)&0xff];
        unsigned int N2=(unsigned char)CRCTab[(Psw[I+1]+J)&0xff];
        for (int K=1;N1!=N2;N1=(N1+1)&0xff,K++)
          Swap(&SubstTable[N1],&SubstTable[(N1+I+K)&0xff]);
      }
    for (int I=0;I<PswLength;I+=16)
      EncryptBlock20(&Psw[I]);
#endif
    return;
  }

  bool Cached=false;
  for (int I=0;I<sizeof(Cache)/sizeof(Cache[0]);I++)
    if (strcmp(Cache[I].Password,Password)==0 &&
        (Salt==NULL && !Cache[I].SaltPresent || Salt!=NULL &&
        Cache[I].SaltPresent && memcmp(Cache[I].Salt,Salt,SALT_SIZE)==0))
    {
      memcpy(AESKey,Cache[I].AESKey,sizeof(AESKey));
      memcpy(AESInit,Cache[I].AESInit,sizeof(AESInit));
      Cached=true;
      break;
    }

  if (!Cached)
  {
    wchar PswW[MAXPASSWORD];
    CharToWide(Password,PswW,MAXPASSWORD-1);
    PswW[MAXPASSWORD-1]=0;
    unsigned char RawPsw[2*MAXPASSWORD+SALT_SIZE];
    WideToRaw(PswW,RawPsw);
    int RawLength=2*strlenw(PswW);
    if (Salt!=NULL)
    {
      memcpy(RawPsw+RawLength,Salt,SALT_SIZE);
      RawLength+=SALT_SIZE;
    }
    hash_context c;
    hash_initial(&c);

    const int HashRounds=0x40000;
    for (int I=0;I<HashRounds;I++)
    {
      hash_process( &c, RawPsw, RawLength);
      unsigned char PswNum[3];
      PswNum[0]=(unsigned char)I;
      PswNum[1]=(unsigned char)(I>>8);
      PswNum[2]=(unsigned char)(I>>16);
      hash_process( &c, PswNum, 3);
      if (I%(HashRounds/16)==0)
      {
        hash_context tempc=c;
        uint32 digest[5];
        hash_final( &tempc, digest);
        AESInit[I/(HashRounds/16)]=(unsigned char)digest[4];
      }
    }
    uint32 digest[5];
    hash_final( &c, digest);
    for (int I=0;I<4;I++)
      for (int J=0;J<4;J++)
        AESKey[I*4+J]=(unsigned char)(digest[I]>>(J*8));

    strcpy(Cache[CachePos].Password,Password);
    if ((Cache[CachePos].SaltPresent=(Salt!=NULL))==true)
      memcpy(Cache[CachePos].Salt,Salt,SALT_SIZE);
    memcpy(Cache[CachePos].AESKey,AESKey,sizeof(AESKey));
    memcpy(Cache[CachePos].AESInit,AESInit,sizeof(AESInit));
    CachePos=(CachePos+1)%(sizeof(Cache)/sizeof(Cache[0]));
  }
Ejemplo n.º 9
0
void CryptData::SetKey30(bool Encrypt,SecPassword *Password,const wchar *PwdW,const byte *Salt)
{
  byte AESKey[16],AESInit[16];

  bool Cached=false;
  for (uint I=0;I<ASIZE(Cache);I++)
    if (Cache[I].Password==*Password &&
        ((Salt==NULL && !Cache[I].SaltPresent) || (Salt!=NULL &&
        Cache[I].SaltPresent && memcmp(Cache[I].Salt,Salt,SIZE_SALT30)==0)))
    {
      memcpy(AESKey,Cache[I].AESKey,sizeof(AESKey));
      memcpy(AESInit,Cache[I].AESInit,sizeof(AESInit));
      Cached=true;
      break;
    }

  if (!Cached)
  {
    byte RawPsw[2*MAXPASSWORD+SIZE_SALT30];
    WideToRaw(PwdW,RawPsw,ASIZE(RawPsw));
    size_t RawLength=2*unrar_wcslen(PwdW);
    if (Salt!=NULL)
    {
      memcpy(RawPsw+RawLength,Salt,SIZE_SALT30);
      RawLength+=SIZE_SALT30;
    }
    hash_context c;
    hash_initial(&c);

    const int HashRounds=0x40000;
    for (int I=0;I<HashRounds;I++)
    {
      hash_process( &c, RawPsw, RawLength, false);
      byte PswNum[3];
      PswNum[0]=(byte)I;
      PswNum[1]=(byte)(I>>8);
      PswNum[2]=(byte)(I>>16);
      hash_process( &c, PswNum, 3, false);
      if (I%(HashRounds/16)==0)
      {
        hash_context tempc=c;
        uint32 digest[5];
        hash_final( &tempc, digest, false);
        AESInit[I/(HashRounds/16)]=(byte)digest[4];
      }
    }
    uint32 digest[5];
    hash_final( &c, digest, false);
    for (int I=0;I<4;I++)
      for (int J=0;J<4;J++)
        AESKey[I*4+J]=(byte)(digest[I]>>(J*8));

    Cache[CachePos].Password=*Password;
    if ((Cache[CachePos].SaltPresent=(Salt!=NULL))==true)
      memcpy(Cache[CachePos].Salt,Salt,SIZE_SALT30);
    memcpy(Cache[CachePos].AESKey,AESKey,sizeof(AESKey));
    memcpy(Cache[CachePos].AESInit,AESInit,sizeof(AESInit));
    CachePos=(CachePos+1)%ASIZE(Cache);

    cleandata(RawPsw,sizeof(RawPsw));
  }
Ejemplo n.º 10
0
Archivo: crypt.cpp Proyecto: Bootz/nzbm
void CryptData::SetCryptKeys(const wchar *Password,const byte *Salt,bool Encrypt,bool OldOnly,bool HandsOffHash)
{
  if (*Password==0)
    return;
  if (OldOnly)
  {
#ifndef SFX_MODULE
    if (CRCTab[1]==0)
      InitCRC();
    char Psw[MAXPASSWORD];
    memset(Psw,0,sizeof(Psw));

    // We need to use ASCII password for older encryption algorithms.
    WideToChar(Password,Psw,ASIZE(Psw));
    Psw[ASIZE(Psw)-1]=0;

    size_t PswLength=strlen(Psw);

    SetOldKeys(Psw);
    Key[0]=0xD3A3B879L;
    Key[1]=0x3F6D12F7L;
    Key[2]=0x7515A235L;
    Key[3]=0xA4E7F123L;

    memcpy(SubstTable,InitSubstTable,sizeof(SubstTable));
    for (int J=0;J<256;J++)
      for (size_t I=0;I<PswLength;I+=2)
      {
        uint N1=(byte)CRCTab [ (byte(Psw[I])   - J) &0xff];
        uint N2=(byte)CRCTab [ (byte(Psw[I+1]) + J) &0xff];
        for (int K=1;N1!=N2;N1=(N1+1)&0xff,K++)
          Swap(&SubstTable[N1],&SubstTable[(N1+I+K)&0xff]);
      }
    for (size_t I=0;I<PswLength;I+=16)
      EncryptBlock20((byte *)&Psw[I]);
#endif
    return;
  }

  bool Cached=false;
  for (uint I=0;I<ASIZE(Cache);I++)
    if (wcscmp(Cache[I].Password,Password)==0 &&
        (Salt==NULL && !Cache[I].SaltPresent || Salt!=NULL &&
        Cache[I].SaltPresent && memcmp(Cache[I].Salt,Salt,SALT_SIZE)==0) &&
        Cache[I].HandsOffHash==HandsOffHash)
    {
      memcpy(AESKey,Cache[I].AESKey,sizeof(AESKey));
      memcpy(AESInit,Cache[I].AESInit,sizeof(AESInit));
      Cached=true;
      break;
    }

  if (!Cached)
  {
    byte RawPsw[2*MAXPASSWORD+SALT_SIZE];
    WideToRaw(Password,RawPsw);
    size_t RawLength=2*wcslen(Password);
    if (Salt!=NULL)
    {
      memcpy(RawPsw+RawLength,Salt,SALT_SIZE);
      RawLength+=SALT_SIZE;
    }
    hash_context c;
    hash_initial(&c);

    const int HashRounds=0x40000;
    for (int I=0;I<HashRounds;I++)
    {
      hash_process( &c, RawPsw, RawLength, HandsOffHash);
      byte PswNum[3];
      PswNum[0]=(byte)I;
      PswNum[1]=(byte)(I>>8);
      PswNum[2]=(byte)(I>>16);
      hash_process( &c, PswNum, 3, HandsOffHash);
      if (I%(HashRounds/16)==0)
      {
        hash_context tempc=c;
        uint32 digest[5];
        hash_final( &tempc, digest, HandsOffHash);
        AESInit[I/(HashRounds/16)]=(byte)digest[4];
      }
    }
    uint32 digest[5];
    hash_final( &c, digest, HandsOffHash);
    for (int I=0;I<4;I++)
      for (int J=0;J<4;J++)
        AESKey[I*4+J]=(byte)(digest[I]>>(J*8));

    wcscpy(Cache[CachePos].Password,Password);
    if ((Cache[CachePos].SaltPresent=(Salt!=NULL))==true)
      memcpy(Cache[CachePos].Salt,Salt,SALT_SIZE);
    Cache[CachePos].HandsOffHash=HandsOffHash;
    memcpy(Cache[CachePos].AESKey,AESKey,sizeof(AESKey));
    memcpy(Cache[CachePos].AESInit,AESInit,sizeof(AESInit));
    CachePos=(CachePos+1)%(sizeof(Cache)/sizeof(Cache[0]));
  }
Ejemplo n.º 11
0
void cryptonight_fast_hash(const char* input, char* output, uint32_t len) {
    union hash_state state;
    hash_process(&state, (const uint8_t*) input, len);
    memcpy(output, &state, HASH_SIZE);
}
Ejemplo n.º 12
0
void cryptonight_hash(const char* input, char* output, uint32_t len, int variant, uint64_t height) {
    struct cryptonight_ctx *ctx = alloca(sizeof(struct cryptonight_ctx));
    hash_process(&ctx->state.hs, (const uint8_t*) input, len);
    memcpy(ctx->text, ctx->state.init, INIT_SIZE_BYTE);
    memcpy(ctx->aes_key, ctx->state.hs.b, AES_KEY_SIZE);
    ctx->aes_ctx = (oaes_ctx*) oaes_alloc();
    size_t i, j;

    VARIANT1_INIT();
    VARIANT2_INIT(ctx->b, ctx->state);
    VARIANT4_RANDOM_MATH_INIT(ctx->state);

    oaes_key_import_data(ctx->aes_ctx, ctx->aes_key, AES_KEY_SIZE);
    for (i = 0; i < MEMORY / INIT_SIZE_BYTE; i++) {
        for (j = 0; j < INIT_SIZE_BLK; j++) {
            aesb_pseudo_round(&ctx->text[AES_BLOCK_SIZE * j],
                    &ctx->text[AES_BLOCK_SIZE * j],
                    ctx->aes_ctx->key->exp_data);
        }
        memcpy(&ctx->long_state[i * INIT_SIZE_BYTE], ctx->text, INIT_SIZE_BYTE);
    }

    for (i = 0; i < 16; i++) {
        ctx->a[i] = ctx->state.k[i] ^ ctx->state.k[32 + i];
        ctx->b[i] = ctx->state.k[16 + i] ^ ctx->state.k[48 + i];
    }

    for (i = 0; i < ITER / 2; i++) {
        /* Dependency chain: address -> read value ------+
         * written value <-+ hard function (AES or MUL) <+
         * next address  <-+
         */
        /* Iteration 1 */
        j = e2i(ctx->a);
        aesb_single_round(&ctx->long_state[j * AES_BLOCK_SIZE], ctx->c, ctx->a);
        VARIANT2_SHUFFLE_ADD(ctx->long_state, j * AES_BLOCK_SIZE, ctx->a, ctx->b, ctx->c);
        xor_blocks_dst(ctx->c, ctx->b, &ctx->long_state[j * AES_BLOCK_SIZE]);
        VARIANT1_1((uint8_t*)&ctx->long_state[j * AES_BLOCK_SIZE]);
        /* Iteration 2 */
        j = e2i(ctx->c);

        uint64_t* dst = (uint64_t*)&ctx->long_state[j * AES_BLOCK_SIZE];

        uint64_t t[2];
        t[0] = dst[0];
        t[1] = dst[1];

        VARIANT2_INTEGER_MATH(t, ctx->c);
        copy_block(ctx->a1, ctx->a);
        VARIANT4_RANDOM_MATH(ctx->a, t, r, ctx->b, ctx->b + AES_BLOCK_SIZE);

        uint64_t hi;
        uint64_t lo = mul128(((uint64_t*)ctx->c)[0], t[0], &hi);

        VARIANT2_2();
        VARIANT2_SHUFFLE_ADD(ctx->long_state, j * AES_BLOCK_SIZE, ctx->a1, ctx->b, ctx->c);

        ((uint64_t*)ctx->a)[0] += hi;
        ((uint64_t*)ctx->a)[1] += lo;

        dst[0] = ((uint64_t*)ctx->a)[0];
        dst[1] = ((uint64_t*)ctx->a)[1];

        ((uint64_t*)ctx->a)[0] ^= t[0];
        ((uint64_t*)ctx->a)[1] ^= t[1];

        VARIANT1_2((uint8_t*)&ctx->long_state[j * AES_BLOCK_SIZE]);
        copy_block(ctx->b + AES_BLOCK_SIZE, ctx->b);
        copy_block(ctx->b, ctx->c);
    }

    memcpy(ctx->text, ctx->state.init, INIT_SIZE_BYTE);
    oaes_key_import_data(ctx->aes_ctx, &ctx->state.hs.b[32], AES_KEY_SIZE);
    for (i = 0; i < MEMORY / INIT_SIZE_BYTE; i++) {
        for (j = 0; j < INIT_SIZE_BLK; j++) {
            xor_blocks(&ctx->text[j * AES_BLOCK_SIZE],
                    &ctx->long_state[i * INIT_SIZE_BYTE + j * AES_BLOCK_SIZE]);
            aesb_pseudo_round(&ctx->text[j * AES_BLOCK_SIZE],
                    &ctx->text[j * AES_BLOCK_SIZE],
                    ctx->aes_ctx->key->exp_data);
        }
    }
    memcpy(ctx->state.init, ctx->text, INIT_SIZE_BYTE);
    hash_permutation(&ctx->state.hs);
    /*memcpy(hash, &state, 32);*/
    extra_hashes[ctx->state.hs.b[0] & 3](&ctx->state, 200, output);
    oaes_free((OAES_CTX **) &ctx->aes_ctx);
}
Ejemplo n.º 13
0
void cn_slow_hash(const void *data, size_t length, char *hash) {
  uint8_t long_state[MEMORY];
  union cn_slow_hash_state state;
  uint8_t text[INIT_SIZE_BYTE];
  uint8_t a[AES_BLOCK_SIZE];
  uint8_t b[AES_BLOCK_SIZE];
  uint8_t c[AES_BLOCK_SIZE];
  uint8_t d[AES_BLOCK_SIZE];
  size_t i, j;
  uint8_t aes_key[AES_KEY_SIZE];
  oaes_ctx *aes_ctx;

  hash_process(&state.hs, data, length);
  memcpy(text, state.init, INIT_SIZE_BYTE);
  memcpy(aes_key, state.hs.b, AES_KEY_SIZE);
  aes_ctx = (oaes_ctx *) oaes_alloc();

  oaes_key_import_data(aes_ctx, aes_key, AES_KEY_SIZE);
  for (i = 0; i < MEMORY / INIT_SIZE_BYTE; i++) {
    for (j = 0; j < INIT_SIZE_BLK; j++) {
      aesb_pseudo_round(&text[AES_BLOCK_SIZE * j], &text[AES_BLOCK_SIZE * j], aes_ctx->key->exp_data);
	}
    memcpy(&long_state[i * INIT_SIZE_BYTE], text, INIT_SIZE_BYTE);
  }

  for (i = 0; i < 16; i++) {
    a[i] = state.k[     i] ^ state.k[32 + i];
    b[i] = state.k[16 + i] ^ state.k[48 + i];
  }

  for (i = 0; i < ITER / 2; i++) {
    /* Dependency chain: address -> read value ------+
     * written value <-+ hard function (AES or MUL) <+
     * next address  <-+
     */
    /* Iteration 1 */
    j = e2i(a, MEMORY / AES_BLOCK_SIZE);
    copy_block(c, &long_state[j * AES_BLOCK_SIZE]);
    aesb_single_round(c, c, a);
    xor_blocks(b, c);
    swap_blocks(b, c);
    copy_block(&long_state[j * AES_BLOCK_SIZE], c);
    //assert(j == e2i(a, MEMORY / AES_BLOCK_SIZE));
    swap_blocks(a, b);
    /* Iteration 2 */
    j = e2i(a, MEMORY / AES_BLOCK_SIZE);
    copy_block(c, &long_state[j * AES_BLOCK_SIZE]);
    mul(a, c, d);
    sum_half_blocks(b, d);
    swap_blocks(b, c);
    xor_blocks(b, c);
    copy_block(&long_state[j * AES_BLOCK_SIZE], c);
    //assert(j == e2i(a, MEMORY / AES_BLOCK_SIZE));
    swap_blocks(a, b);
  }

  memcpy(text, state.init, INIT_SIZE_BYTE);
  oaes_key_import_data(aes_ctx, &state.hs.b[32], AES_KEY_SIZE);
  for (i = 0; i < MEMORY / INIT_SIZE_BYTE; i++) {
    for (j = 0; j < INIT_SIZE_BLK; j++) {
      xor_blocks(&text[j * AES_BLOCK_SIZE], &long_state[i * INIT_SIZE_BYTE + j * AES_BLOCK_SIZE]);
      aesb_pseudo_round(&text[AES_BLOCK_SIZE * j], &text[AES_BLOCK_SIZE * j], aes_ctx->key->exp_data);
    }
  }
  memcpy(state.init, text, INIT_SIZE_BYTE);
  hash_permutation(&state.hs);
  extra_hashes[state.hs.b[0] & 3](&state, 200, hash);
  oaes_free((OAES_CTX **) &aes_ctx);
}