static int verify_tth_final(void) { if G_UNLIKELY(NULL == verify_tth.context) return -1; tt_digest(verify_tth.context, &verify_tth.digest); return 0; }
char* tth(const char* filename, char **tthl, size_t *tthl_len) { char *tth = NULL; size_t numbytes; unsigned char root[24]; unsigned char *cur; TT_CONTEXT tt; unsigned char buf[1 + 256 * BLOCKSIZE]; struct stat sb; unsigned level; size_t leaf_blocksize; int fd = open(filename, O_RDONLY); if ((fd == -1) || ( fstat(fd, &sb) == -1)) { return NULL; } level = calc_block_level(sb.st_size, max_block_count); leaf_blocksize = 1 << (level+10); *tthl_len = 0; *tthl = NULL; tt_init(&tt, *tthl, level); tt.leaf = buf; buf[0] = '\0'; while ( (numbytes = read(fd, &buf[1], sizeof(buf) - 1) ) > 0) { tt.index = BLOCKSIZE; for (cur = &buf[1]; cur + BLOCKSIZE <= &buf[numbytes + 1]; cur += BLOCKSIZE) { tt.leaf = cur - 1; tt.leaf[0] = '\0'; tt_block(&tt); } tt.index = numbytes - (cur - &buf[1]); tt.leaf = cur - 1; tt.leaf[0] = '\0'; } close(fd); tt_digest(&tt, root); tth = base32_encode(root, sizeof(root)); return tth; }
static G_GNUC_COLD void tt_check_digest(const char * const expected, const void *data, size_t size) { char digest[TTH_BASE32_SIZE + 1]; struct tth hash; TTH_CONTEXT ctx; tt_init(&ctx, size); tt_update(&ctx, data, size); tt_digest(&ctx, &hash); ZERO(&digest); base32_encode(digest, sizeof digest, hash.data, sizeof hash.data); digest[G_N_ELEMENTS(digest) - 1] = '\0'; if (0 != strcmp(expected, digest)) { g_warning("tt_check_digest:\nExpected: \"%s\"\nGot: \"%s\"", expected, digest); g_error("Tigertree implementation is defective."); } }
static int verify_tth_final(void) { tt_digest(verify_tth.context, &verify_tth.digest); return 0; }