Example #1
0
static ERL_NIF_TERM
context_fini(ErlNifEnv* env, Context* ctx, size_t dsize, ChunkHandler handler)
{
    ERL_NIF_TERM result;
    ctx->bitlen += ctx->count*8;
    pad(0, 0, ctx);
    handler(ctx, ctx->bytes);
    if (ctx->count > ctx->size) {
        handler(ctx, ctx->bytes + ctx->size);
    }
#ifndef WORDS_BIGENDIAN
    {
        int i;
        if (ctx->size == PADDED_SIZE_2XX_BYTES) {
            uint32_t* hash = (uint32_t*)ctx->digest.data;
            for (i = 0; i < ctx->digest.size/sizeof(*hash); ++i) {
                hash[i] = BYTESWAP32(hash[i]);
            }
        } else {
            uint64_t* hash = (uint64_t*)ctx->digest.data;
            for (i = 0; i < ctx->digest.size/sizeof(*hash); ++i) {
                hash[i] = BYTESWAP64(hash[i]);
            }
        }
    }
#endif
    if (ctx->digest.size != dsize) {
        enif_realloc_binary(&ctx->digest, dsize);
    }
    result = enif_make_binary(env, &ctx->digest);
    ctx->digest.size = 0;
    return result;
}
Example #2
0
static void
pad(unsigned char* bin, uint64_t binsize, Context* ctx)
{
    unsigned char* p;
    uint64_t congruence = ctx->size == PADDED_SIZE_2XX_BYTES ?
        CONGRUENCE_2XX : CONGRUENCE_5XX;
    uint64_t lenbits = ctx->bitlen;
    uint64_t pad;

    while (lenbits + 1 > congruence) {
        congruence += ctx->size*8;
    }
    pad = (congruence - (lenbits + 1)) / 8;
    if (ctx->size == PADDED_SIZE_5XX_BYTES) {
        pad += 8;
    }
    if (bin != NULL && binsize > 0) {
        memcpy(ctx->bytes + ctx->count, bin, binsize);
        ctx->count += binsize;
    }
    p = ctx->bytes + ctx->count;
    *p++ = 0x80;
    memset(p, 0, pad);
#ifndef WORDS_BIGENDIAN
    *(uint64_t*)(p + pad) = BYTESWAP64(lenbits);
#else
    *(uint64_t*)(p + pad) = lenbits;
#endif
    ctx->count += 1 + pad + sizeof lenbits;
}
Example #3
0
void reverse(char *bytes, int numChunks) {
  uint64_t *arr = (uint64_t *)bytes;
  uint64_t buf[BUF_SIZE];
  for (int j = 0; j < numChunks; ++j) {
    memcpy(buf, arr + BUF_SIZE * j, BUF_SIZE * sizeof(uint64_t));
    for (int i = 0; i < BUF_SIZE; ++i)
      buf[i] = BYTESWAP64(buf[i]);
    for (int i = 0; i < BUF_SIZE / 2; ++i) {
      uint64_t tmp = buf[i];
      buf[i] = buf[BUF_SIZE - i - 1];
      buf[BUF_SIZE - i - 1] = tmp;
    }
    memcpy(arr + BUF_SIZE * j, buf, BUF_SIZE * sizeof(uint64_t));
  }
}
Example #4
0
static void
sha5xx_chunk(Context* ctx, unsigned char* chunk)
{
    uint64_t* hash = (uint64_t*)ctx->digest.data;
    uint64_t a, b, c, d, e, f, g, h;
    uint64_t words[80];
    int i;
#ifndef WORDS_BIGENDIAN
    {
        uint64_t* from = (uint64_t*)chunk;
        for (i = 0; i < 16; ++i) {
            words[i] = BYTESWAP64(from[i]);
        }
    }
#else
    memcpy(words, chunk, 16*sizeof(*words));
#endif
    for (i = 16; i < sizeof(words)/sizeof(*words); ++i) {
        uint64_t w15 = words[i-15], w2 = words[i-2];
        uint64_t s0 = SM_SIGMA512_0(w15), s1 = SM_SIGMA512_1(w2);
        uint64_t w7 = words[i-7], w16 = words[i-16];
        words[i] = s1 + w7 + s0 + w16;
    }
    a = hash[0]; b = hash[1]; c = hash[2]; d = hash[3];
    e = hash[4]; f = hash[5]; g = hash[6]; h = hash[7];
    for (i = 0; i < sizeof(words)/sizeof(*words); ++i) {
        uint64_t t1, t2;
        t1 = h + BIG_SIGMA512_1(e) + CH(e,f,g) + K512[i] + words[i];
        t2 = BIG_SIGMA512_0(a) + MAJ(a,b,c);
        h = g;
        g = f;
        f = e;
        e = d + t1;
        d = c;
        c = b;
        b = a;
        a = t1 + t2;
    }
    hash[0] += a; hash[1] += b; hash[2] += c; hash[3] += d;
    hash[4] += e; hash[5] += f; hash[6] += g; hash[7] += h;
}