Team Ai
Modelpublic

Felipe97/llama-cpp-compiled

sourceHugging Faceupdated 21d agoView on Hugging Face
0likes1.2kdownloads
gguf-hash.cpp701 linesDownload Raw Back to gguf-hash
1#include "ggml.h"2#include "gguf.h"3 4#include <algorithm>5#include <clocale>6#include <cstddef>7#include <cstdio>8#include <cstdlib>   /* abort() */9#include <cstring>10#include <stdexcept>11#include <string>12 13#include <sstream>14#include <fstream>15 16#ifdef __cplusplus17extern "C" {18#endif19 20#include "hash/xxhash/xxhash.h"21#include "hash/sha256/sha256.h"22 23#ifdef __cplusplus24}25#endif26 27// sha1 is compiled as C++ and lives in a namespace, see scripts/sync_vendor.py28#include "hash/sha1/sha1.h"29using namespace vendor_hash;30 31 32// uuid.uuid5(uuid.NAMESPACE_URL, 'en.wikipedia.org/wiki/Llama.cpp')33#define UUID_NAMESPACE_LLAMA_CPP "ef001206-dadc-5f6d-a15f-3359e577d4e5"34#define UUID_NAMESPACE_LLAMA_CPP_HEX 0xef, 0x00, 0x12, 0x06, 0xda, 0xdc, 0x5f, 0x6d, 0xa1, 0x5f, 0x33, 0x59, 0xe5, 0x77, 0xd4, 0xe535 36 37#define HASH_TYPE_SHA256_STR "sha256"38#define HASH_TYPE_SHA1_STR   "sha1"39#define HASH_TYPE_XXH64_STR  "xxh64"40#define HASH_TYPE_UUID_STR   "uuid"41 42 43typedef enum {44    HASH_EXIT_SUCCESS = 0, // All hash has been generated or validated45    HASH_EXIT_FAILURE = 1, // Generic Failure46    HASH_EXIT_MISMATCH = 2, // Hash mismatched during validation47    HASH_EXIT_MANIFEST_MISSING_ENTRY = 3, // Hash attempted validation but missing entry in manifest48    HASH_EXIT_MANIFEST_UNKNOWN_HASH = 4, // Manifest is present, but we do not know any hash format within it49    HASH_EXIT_MANIFEST_FILE_ERROR = 5 // Manifest is either missing or not a known format50} hash_exit_code_t;51 52 53typedef enum {54    HASH_MANIFEST_NOT_FOUND,55    HASH_MANIFEST_MISMATCH,56    HASH_MANIFEST_OK,57} hash_manifest_result_t;58 59 60struct hash_params {61    std::string input;62    bool xxh64 = false;63    bool sha1 = false;64    bool sha256 = false;65    bool uuid = false;66 67    bool no_layer = false;68 69    bool manifest_is_usable = false;70    std::string manifest_file;71};72 73struct manifest_check_params {74    bool xxh64 = false;75    bool sha1 = false;76    bool sha256 = false;77    bool uuid = false;78};79 80static char const * hash_manifest_result_to_str(hash_manifest_result_t value) {81    switch (value) {82        case HASH_MANIFEST_NOT_FOUND: return "Not Found";83        case HASH_MANIFEST_MISMATCH: return "Mismatch";84        case HASH_MANIFEST_OK: return "Ok";85    }86    return "?";87}88 89static char const * hash_exit_code_to_str(hash_exit_code_t value) {90    switch (value) {91        case HASH_EXIT_SUCCESS: return "Success";92        case HASH_EXIT_FAILURE: return "Failure";93        case HASH_EXIT_MISMATCH: return "Mismatch";94        case HASH_EXIT_MANIFEST_MISSING_ENTRY: return "Manifest Missing Entry";95        case HASH_EXIT_MANIFEST_UNKNOWN_HASH: return "Manifest Unknown Hash";96        case HASH_EXIT_MANIFEST_FILE_ERROR: return "Manifest File Error";97    }98    return "?";99}100 101static void hash_print_usage(const char * executable) {102    const hash_params default_params;103    printf("\n");104    printf("usage: %s [options] GGUF_IN\n", executable);105    printf("\n");106    printf("Hash a GGUF file");107    printf("\n");108    printf("options:\n");109    printf("  -h, --help              show this help message and exit\n");110    printf("      --xxh64             use xxh64 hash\n");111    printf("      --sha1              use sha1 hash\n");112    printf("      --sha256            use sha256 hash\n");113    printf("      --all               use all hash\n");114    printf("      --no-layer          exclude per layer hash\n");115    printf("      --uuid              generate UUIDv5 ID\n");116    printf("  -c, --check <manifest>  verify against a manifest\n");117    printf("\n");118}119 120static void hash_params_parse_ex(int argc, const char ** argv, hash_params & params) {121    std::string arg;122    bool invalid_param = false;123    const std::string arg_prefix = "--";124 125    int arg_idx = 1;126    for (; arg_idx < argc && strncmp(argv[arg_idx], "--", 2) == 0; arg_idx++) {127        arg = argv[arg_idx];128        if (arg.compare(0, arg_prefix.size(), arg_prefix) == 0) {129            std::replace(arg.begin(), arg.end(), '_', '-');130        }131 132        bool arg_found = false;133        if (arg == "-h" || arg == "--help") {134            hash_print_usage(argv[0]);135            exit(0);136        }137 138        if (arg == "--xxh64") {139            arg_found = true;140            params.xxh64 = true;141        }142 143        if (arg == "--sha1") {144            arg_found = true;145            params.sha1 = true;146        }147 148        if (arg == "--uuid") {149            arg_found = true;150            params.uuid = true;151        }152 153        if (arg == "--sha256") {154            arg_found = true;155            params.sha256 = true;156        }157 158        if (arg == "--all") {159            arg_found = true;160            params.sha256 = true;161            params.sha1 = true;162            params.xxh64 = true;163        }164 165        if (arg == "--no-layer") {166            arg_found = true;167            params.no_layer = true;168        }169 170        if (arg == "-c" || arg == "--check") {171            if (++arg_idx >= argc) {172                invalid_param = true;173                break;174            }175            arg_found = true;176            params.manifest_file = argv[arg_idx];177        }178 179        if (!arg_found) {180            throw std::invalid_argument("error: unknown argument: " + arg);181        }182    }183 184    if (invalid_param) {185        throw std::invalid_argument("error: invalid parameter for argument:" + arg);186    }187 188    if (argc - arg_idx < 1) {189        throw std::invalid_argument("error: bad arguments");190    }191 192    params.input = argv[arg_idx++];193}194 195static bool hash_params_parse(int argc, const char ** argv, hash_params & params) {196    bool result = true;197    try {198        hash_params_parse_ex(argc, argv, params);199    }200    catch (const std::invalid_argument & ex) {201        fprintf(stderr, "%s\n", ex.what());202        hash_print_usage(argv[0]);203        exit(EXIT_FAILURE);204    }205    return result;206}207 208static bool manifest_type(const std::string & manifest_file, manifest_check_params & manifest_check) {209    if (manifest_file.empty()) {210        return false;211    }212 213    std::ifstream file(manifest_file);214    if (!file.is_open()) {215        return false;216    }217 218    std::string manifest_entry_line;219    while (getline(file, manifest_entry_line)) {220        // hash_type_str hash_str tensor_name221        // e.g. 'xxh64     f66e9cd66a4396a0  test.gguf:tensor_0'222        std::istringstream line_stream(manifest_entry_line);223        std::string file_hash_type;224        if (line_stream >> file_hash_type) {225            if (file_hash_type == HASH_TYPE_SHA256_STR) {226                manifest_check.sha256 = true;227            } else if (file_hash_type == HASH_TYPE_SHA1_STR) {228                manifest_check.sha1 = true;229            } else if (file_hash_type == HASH_TYPE_XXH64_STR) {230                manifest_check.xxh64 = true;231            } else if (file_hash_type == HASH_TYPE_UUID_STR) {232                manifest_check.uuid = true;233            }234        }235    }236 237    return true;238}239 240static hash_manifest_result_t manifest_verify(const std::string& manifest_file, const std::string& hash_type_str, const std::string& hash_str, const std::string& tensor_name) {241    if (manifest_file.empty()) {242        return HASH_MANIFEST_NOT_FOUND;243    }244 245    std::ifstream file(manifest_file);246    if (!file.is_open()) {247        return HASH_MANIFEST_NOT_FOUND;248    }249 250    std::string manifest_entry_line;251    while (getline(file, manifest_entry_line)) {252        std::istringstream line_stream(manifest_entry_line);253        std::string file_hash_type;254        std::string file_hash;255        std::string file_tensor_name;256        if (line_stream >> file_hash_type >> file_hash >> file_tensor_name) {257            // Line parsed. Check hash validity258 259            if (file_hash_type != hash_type_str) {260                continue;261            }262 263            if (file_tensor_name != tensor_name) {264                continue;265            }266 267            return (file_hash == hash_str) ? HASH_MANIFEST_OK : HASH_MANIFEST_MISMATCH;268        }269    }270 271    return HASH_MANIFEST_NOT_FOUND;272}273 274static void generate_uuidv5(const unsigned char sha1_digest[20], unsigned char uuid[16]) {275    // Ref: https://www.rfc-editor.org/rfc/rfc9562.html#section-5.5276    // Assumes that digest was processed correctly with the expected namespace277    for (int i = 0; i < 16; i++) {278        uuid[i] = sha1_digest[i];279    }280 281    // Set bits corresponding to UUID ver 5282    uuid[ 6] &= ~(0xF << 4);283    uuid[ 6] |= (5 << 4);284 285    // Set bits corresponding to UUID variant 0b10XX286    uuid[ 8] &= ~(0xc << 4);287    uuid[ 8] |= (0x8 << 4);288}289 290static hash_exit_code_t gguf_hash(const hash_params & hash_params) {291    const std::string & fname = hash_params.input;292    struct ggml_context * ctx_data = NULL;293 294    struct gguf_init_params params = {295        /*.no_alloc = */ false,296        /*.ctx      = */ &ctx_data,297    };298 299    // xxh64 init300    XXH64_state_t* xxh64_model_hash_state = NULL;301    if (hash_params.xxh64) {302        xxh64_model_hash_state = XXH64_createState();303        if (xxh64_model_hash_state==NULL) {304            abort();305        }306 307        XXH64_hash_t const seed = 0;308        if (XXH64_reset(xxh64_model_hash_state, seed) == XXH_ERROR) {309            abort();310        }311    }312 313    // sha1 init314    SHA1_CTX sha1_model_hash_ctx;315    if (hash_params.sha1) {316        SHA1Init(&sha1_model_hash_ctx);317    }318 319    // sha256 init320    sha256_t sha256_model_hash_ctx;321    if (hash_params.sha256) {322        sha256_init(&sha256_model_hash_ctx);323    }324 325    // sha1 for uuid init326    SHA1_CTX sha1_for_uuid_ctx;327    if (hash_params.uuid) {328        unsigned char const uuidv5_namespace[] = {UUID_NAMESPACE_LLAMA_CPP_HEX};329        SHA1Init(&sha1_for_uuid_ctx);330        SHA1Update( &sha1_for_uuid_ctx, (unsigned char const *)uuidv5_namespace, sizeof(uuidv5_namespace));331    }332 333    struct gguf_context * ctx = gguf_init_from_file(fname.c_str(), params);334    const int n_tensors = gguf_get_n_tensors(ctx);335    bool tensor_layer_in_manifest = false;336    bool model_in_manifest = false;337    bool tensor_layer_has_mismatch = false;338    bool model_has_mismatch = false;339    for (int i = 0; i < n_tensors; ++i) {340        const char * name = gguf_get_tensor_name(ctx, i);341        struct ggml_tensor * cur = ggml_get_tensor(ctx_data, name);342        auto n_bytes = ggml_nbytes(cur);343        auto *raw_data = cur->data;344        const std::string tensor_layer_name = fname + ":" + name;345 346        if (hash_params.xxh64) {347 348            if (!hash_params.no_layer) {349                // Per Layer Hash350                XXH64_hash_t hash = XXH64(raw_data, n_bytes, 0);351 352                char hex_result[17];353                for (int  offset = 0; offset < 8; offset++) {354                    unsigned int shift_bits_by = (8 * (8 - offset - 1));355                    snprintf( ( hex_result + (2*offset)), sizeof(hex_result) - (2*offset), "%02x", (unsigned char) (hash >> shift_bits_by)&0xff);356                }357 358                if (hash_params.manifest_is_usable) {359                    hash_manifest_result_t verify_result = manifest_verify(hash_params.manifest_file, HASH_TYPE_XXH64_STR, hex_result, tensor_layer_name);360 361                    switch (verify_result) {362                        case HASH_MANIFEST_NOT_FOUND:363                            break;364                        case HASH_MANIFEST_MISMATCH:365                            tensor_layer_in_manifest = true;366                            tensor_layer_has_mismatch = true;367                            break;368                        case HASH_MANIFEST_OK:369                            tensor_layer_in_manifest = true;370                            break;371                    }372 373                    printf("%-8s  %-s  %s  -  %s\n", HASH_TYPE_XXH64_STR, hex_result, tensor_layer_name.c_str(), hash_manifest_result_to_str(verify_result));374                } else {375                    printf("%-8s  %-s  %s\n", HASH_TYPE_XXH64_STR, hex_result, tensor_layer_name.c_str());376                }377            }378 379            // Overall Model Hash380            if (XXH64_update(xxh64_model_hash_state, raw_data, n_bytes) == XXH_ERROR) abort();381        }382 383        if (hash_params.sha1) {384 385            if (!hash_params.no_layer) {386                // Per Layer Hash387                char result[21]; // sha1 outputs 20 bytes388                SHA1( result, (const char *)raw_data, n_bytes);389 390                char hex_result[41] = {0};391                for (int  offset = 0; offset < 20; offset++) {392                    snprintf( ( hex_result + (2*offset)), sizeof(hex_result) - (2*offset), "%02x", result[offset]&0xff);393                }394 395                if (hash_params.manifest_is_usable) {396                    hash_manifest_result_t verify_result = manifest_verify(hash_params.manifest_file, HASH_TYPE_SHA1_STR, hex_result, tensor_layer_name);397 398                    switch (verify_result) {399                        case HASH_MANIFEST_NOT_FOUND:400                            break;401                        case HASH_MANIFEST_MISMATCH:402                            tensor_layer_in_manifest = true;403                            tensor_layer_has_mismatch = true;404                            break;405                        case HASH_MANIFEST_OK:406                            tensor_layer_in_manifest = true;407                            break;408                    }409 410                    printf("%-8s  %-s  %s  -  %s\n", HASH_TYPE_SHA1_STR, hex_result, tensor_layer_name.c_str(), hash_manifest_result_to_str(verify_result));411                } else {412                    printf("%-8s  %-s  %s\n", HASH_TYPE_SHA1_STR, hex_result, tensor_layer_name.c_str());413                }414            }415 416            // Overall Model Hash417            SHA1Update( &sha1_model_hash_ctx, (unsigned char const *)raw_data, n_bytes);418        }419 420        if (hash_params.sha256) {421 422            if (!hash_params.no_layer) {423                // Per Layer Hash424                unsigned char result[SHA256_DIGEST_SIZE]; // sha256 outputs 32 bytes425                sha256_hash((unsigned char*) result, (const unsigned char *)raw_data, n_bytes);426 427                char hex_result[SHA256_DIGEST_SIZE * 2 + 1] = {0};428                for (int  offset = 0; offset < SHA256_DIGEST_SIZE; offset++) {429                    snprintf( ( hex_result + (2*offset)), sizeof(hex_result) - (2*offset), "%02x", result[offset]&0xff);430                }431 432                if (hash_params.manifest_is_usable) {433                    hash_manifest_result_t verify_result = manifest_verify(hash_params.manifest_file, HASH_TYPE_SHA256_STR, hex_result, tensor_layer_name);434 435                    switch (verify_result) {436                        case HASH_MANIFEST_NOT_FOUND:437                            break;438                        case HASH_MANIFEST_MISMATCH:439                            tensor_layer_in_manifest = true;440                            tensor_layer_has_mismatch = true;441                            break;442                        case HASH_MANIFEST_OK:443                            tensor_layer_in_manifest = true;444                            break;445                    }446 447                    printf("%-8s  %-s  %s  -  %s\n", HASH_TYPE_SHA256_STR, hex_result, tensor_layer_name.c_str(), hash_manifest_result_to_str(verify_result));448                } else {449                    printf("%-8s  %-s  %s\n", HASH_TYPE_SHA256_STR, hex_result, tensor_layer_name.c_str());450                }451            }452 453            // Overall Model Hash454            sha256_update( &sha256_model_hash_ctx, (unsigned char const *)raw_data, n_bytes);455        }456 457        if (hash_params.uuid) {458            SHA1Update( &sha1_for_uuid_ctx, (unsigned char const *)raw_data, n_bytes);459        }460    }461 462    if (hash_params.xxh64) {463        XXH64_hash_t const hash = XXH64_digest(xxh64_model_hash_state);464 465        char hex_result[17];466        for (int  offset = 0; offset < 8; offset++) {467            unsigned int shift_bits_by = (8 * (8 - offset - 1));468            snprintf( ( hex_result + (2*offset)), sizeof(hex_result) - (2*offset), "%02x", (unsigned char) (hash >> shift_bits_by)&0xff);469        }470 471        if (hash_params.manifest_is_usable) {472            hash_manifest_result_t verify_result = manifest_verify(hash_params.manifest_file, HASH_TYPE_XXH64_STR, hex_result, fname);473 474            switch (verify_result) {475                case HASH_MANIFEST_NOT_FOUND:476                    break;477                case HASH_MANIFEST_MISMATCH:478                    model_in_manifest = true;479                    model_has_mismatch = true;480                    break;481                case HASH_MANIFEST_OK:482                    model_in_manifest = true;483                    break;484            }485 486            printf("%-8s  %-s  %s  -  %s\n", HASH_TYPE_XXH64_STR, hex_result, fname.c_str(), hash_manifest_result_to_str(verify_result));487        } else {488            printf("%-8s  %-s  %s\n", HASH_TYPE_XXH64_STR, hex_result, fname.c_str());489        }490    }491 492    if (hash_params.sha1) {493        unsigned char result[21];494        SHA1Final(result, &sha1_model_hash_ctx);495 496        char hex_result[41];497        for (int  offset = 0; offset < 20; offset++) {498            snprintf( ( hex_result + (2*offset)), sizeof(hex_result) - (2*offset), "%02x", result[offset]&0xff);499        }500 501        if (hash_params.manifest_is_usable) {502            hash_manifest_result_t verify_result = manifest_verify(hash_params.manifest_file, HASH_TYPE_SHA1_STR, hex_result, fname);503 504            switch (verify_result) {505                case HASH_MANIFEST_NOT_FOUND:506                    break;507                case HASH_MANIFEST_MISMATCH:508                    model_in_manifest = true;509                    model_has_mismatch = true;510                    break;511                case HASH_MANIFEST_OK:512                    model_in_manifest = true;513                    break;514            }515 516            printf("%-8s  %-s  %s  -  %s\n", HASH_TYPE_SHA1_STR, hex_result, fname.c_str(), hash_manifest_result_to_str(verify_result));517        } else {518            printf("%-8s  %-s  %s\n", HASH_TYPE_SHA1_STR, hex_result, fname.c_str());519        }520    }521 522    if (hash_params.sha256) {523        unsigned char result[SHA256_DIGEST_SIZE]; // sha256 outputs 32 bytes524        sha256_final( &sha256_model_hash_ctx,  result);525 526        char hex_result[SHA256_DIGEST_SIZE * 2 + 1] = {0};527        for (int  offset = 0; offset < SHA256_DIGEST_SIZE; offset++) {528            snprintf( ( hex_result + (2*offset)), sizeof(hex_result) - (2*offset), "%02x", result[offset]&0xff);529        }530 531        if (hash_params.manifest_is_usable) {532            hash_manifest_result_t verify_result = manifest_verify(hash_params.manifest_file, HASH_TYPE_SHA256_STR, hex_result, fname);533 534            switch (verify_result) {535                case HASH_MANIFEST_NOT_FOUND:536                    break;537                case HASH_MANIFEST_MISMATCH:538                    model_in_manifest = true;539                    model_has_mismatch = true;540                    break;541                case HASH_MANIFEST_OK:542                    model_in_manifest = true;543                    break;544            }545 546            printf("%-8s  %-s  %s  -  %s\n", HASH_TYPE_SHA256_STR, hex_result, fname.c_str(), hash_manifest_result_to_str(verify_result));547        } else {548            printf("%-8s  %-s  %s\n", HASH_TYPE_SHA256_STR, hex_result, fname.c_str());549        }550    }551 552    if (hash_params.uuid) {553        unsigned char result[21];554        SHA1Final(result, &sha1_for_uuid_ctx);555 556        unsigned char uuid[16];557        generate_uuidv5(result, uuid);558 559        char string_buffer[37] = {0};560        snprintf(string_buffer, sizeof(string_buffer), "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",561            uuid[0], uuid[1], uuid[2], uuid[3],562            uuid[4], uuid[5], uuid[6], uuid[7],563            uuid[8], uuid[9], uuid[10], uuid[11],564            uuid[12], uuid[13], uuid[14], uuid[15]);565 566        if (hash_params.manifest_is_usable) {567            hash_manifest_result_t verify_result = manifest_verify(hash_params.manifest_file, HASH_TYPE_SHA256_STR, string_buffer, fname);568 569            switch (verify_result) {570                case HASH_MANIFEST_NOT_FOUND:571                    break;572                case HASH_MANIFEST_MISMATCH:573                    model_in_manifest = true;574                    model_has_mismatch = true;575                    break;576                case HASH_MANIFEST_OK:577                    model_in_manifest = true;578                    break;579            }580 581            printf("%-8s  %-s  %s  -  %s\n", HASH_TYPE_UUID_STR, string_buffer, fname.c_str(), hash_manifest_result_to_str(verify_result));582        } else {583            printf("%-8s  %-s  %s\n", HASH_TYPE_UUID_STR, string_buffer, fname.c_str());584        }585    }586 587 588    ggml_free(ctx_data);589    gguf_free(ctx);590 591 592    if (hash_params.manifest_is_usable) {593        // In hash verification mode594 595        if (!model_in_manifest) {596            // model missing in manifest?597 598            // Check tensor layer...599            if (!tensor_layer_in_manifest) {600                // Still missing? Maybe we are reading the wrong manifest.601                return HASH_EXIT_MANIFEST_MISSING_ENTRY;602            }603 604            if (tensor_layer_has_mismatch) {605                // Per tensor check found error606                return HASH_EXIT_FAILURE;607            }608 609            // All per tensor layer checks passed? Sounds good enough.610            return HASH_EXIT_SUCCESS;611        }612 613        // Overall model check passed, but let's check per layer just in case614        // If missing, we don't care too much as the overall model checked615        if (tensor_layer_in_manifest && tensor_layer_has_mismatch) {616            return HASH_EXIT_FAILURE;617        }618 619        if (model_has_mismatch) {620            // model has failed hash somewhere in the model621            return HASH_EXIT_FAILURE;622        }623 624        // All checks appears to be fine625        return HASH_EXIT_SUCCESS;626    }627 628    // In hash generation mode629    return HASH_EXIT_SUCCESS;630}631 632int main(int argc, const char ** argv) {633    std::setlocale(LC_NUMERIC, "C");634 635    hash_params params;636    manifest_check_params manifest_check;637    hash_params_parse(argc, argv, params);638 639    if (!params.manifest_file.empty()) {640        if (!manifest_type(params.manifest_file, manifest_check)) {641            printf("ERROR cannot open manifest %s", params.manifest_file.c_str());642            return HASH_EXIT_MANIFEST_FILE_ERROR;643        }644 645        if (!manifest_check.sha256 && !manifest_check.sha1 && !manifest_check.xxh64 && !manifest_check.uuid) {646            printf("ERROR manifest does not have any known hash format in %s", params.manifest_file.c_str());647            return HASH_EXIT_MANIFEST_UNKNOWN_HASH;648        }649 650        printf("manifest  %s", params.manifest_file.c_str());651 652        if (manifest_check.sha256) {653            printf("  sha256");654        }655 656        if (manifest_check.sha1) {657            printf("  sha1");658        }659 660        if (manifest_check.xxh64) {661            printf("  xxh64");662        }663 664        if (manifest_check.uuid) {665            printf("  uuid");666        }667 668        printf("\n");669 670        // Autoselect the highest security hash if manifest is provided but671        // the user has not specifically defined the hash they care about672        if (!params.xxh64 && !params.sha1 && !params.uuid && !params.sha256) {673            // User has not selected a specific value, pick most secure hash674            if (manifest_check.sha256) {675                params.sha256 = true;676            } else if (manifest_check.sha1) {677                params.sha1 = true;678            } else if (manifest_check.xxh64) {679                params.xxh64 = true;680            } else if (manifest_check.uuid) {681                params.uuid = true;682            }683        }684 685        params.manifest_is_usable = true;686    }687 688    // By default if no swich argument provided, assume xxh64689    if (!params.xxh64 && !params.sha1 && !params.uuid && !params.sha256) {690        params.xxh64 = true;691    }692 693    hash_exit_code_t exit_code = gguf_hash(params);694 695    if (params.manifest_is_usable) {696        printf("\nVerification results for %s - %s\n", params.manifest_file.c_str(), hash_exit_code_to_str(exit_code));697    }698 699    return exit_code;700}701