/** Terminate the hash to get the digest @param md The hash state @param out [out] The destination of the hash (20 bytes) @return CRYPT_OK if successful */ int rmd160_done(hash_state * md, unsigned char *out) { int i; LTC_ARGCHK(md != NULL); LTC_ARGCHK(out != NULL); if (md->rmd160.curlen >= sizeof(md->rmd160.buf)) { return CRYPT_INVALID_ARG; } /* increase the length of the message */ md->rmd160.length += md->rmd160.curlen * 8; /* append the '1' bit */ md->rmd160.buf[md->rmd160.curlen++] = (unsigned char)0x80; /* if the length is currently above 56 bytes we append zeros * then compress. Then we can fall back to padding zeros and length * encoding like normal. */ if (md->rmd160.curlen > 56) { while (md->rmd160.curlen < 64) { md->rmd160.buf[md->rmd160.curlen++] = (unsigned char)0; } rmd160_compress(md, md->rmd160.buf); md->rmd160.curlen = 0; } /* pad upto 56 bytes of zeroes */ while (md->rmd160.curlen < 56) { md->rmd160.buf[md->rmd160.curlen++] = (unsigned char)0; } /* store length */ STORE64L(md->rmd160.length, md->rmd160.buf+56); rmd160_compress(md, md->rmd160.buf); /* copy output */ for (i = 0; i < 5; i++) { STORE32L(md->rmd160.state[i], out+(4*i)); } #ifdef LTC_CLEAN_STACK zeromem(md, sizeof(hash_state)); #endif return CRYPT_OK; }
void digestif_rmd160_finalize(struct rmd160_ctx *ctx, uint8_t *out) { int i = ctx->n; ctx->buf[i++] = 0x80; if (i > 56) { memset(ctx->buf + i, 0, 64 - i); rmd160_compress(ctx, (uint32_t *) ctx->buf); i = 0; } memset(ctx->buf + i, 0, 56 - i); cpu_to_le32_array((uint32_t *) (ctx->buf + 56), ctx->sz, 2); rmd160_compress(ctx, (uint32_t *) ctx->buf); cpu_to_le32_array((uint32_t *) out, ctx->h, 5); }
void digestif_rmd160_update(struct rmd160_ctx *ctx, uint8_t *data, uint32_t len) { uint32_t t; /* update length */ t = ctx->sz[0]; if ((ctx->sz[0] = t + (len << 3)) < t) ctx->sz[1]++; /* carry from low 32 bits to high 32 bits. */ ctx->sz[1] += (len >> 29); /* if data was left in buffer, pad it with fresh data and munge/eat block. */ if (ctx->n != 0) { t = 64 - ctx->n; if (len < t) /* not enough to munge. */ { memcpy(ctx->buf + ctx->n, data, len); ctx->n += len; return; } memcpy(ctx->buf + ctx->n, data, t); rmd160_compress(ctx, (uint32_t *) ctx->buf); data += t; len -= t; } /* munge/eat data in 64 bytes chunks. */ while (len >= 64) { /* memcpy(ctx->buf, data, 64); XXX(dinosaure): from X.L. but avoid to be fast. */ rmd160_compress(ctx, (uint32_t *) data); data += 64; len -= 64; } /* save remaining data. */ memcpy(ctx->buf, data, len); ctx->n = len; }