aboutsummaryrefslogtreecommitdiff
path: root/src/hash.c
blob: 2cb0851d1d0d76527713870ae27126e705b03f75 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include "hash.h"

#include <blake2.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int pow_check_blake2b_hash(char *path, char *target_hash) {
  FILE *fp = fopen(path, "rb");

  if (!fp) {
    printf("failed to open file to check hash\n");

    return 1;
  }

  fseek(fp, 0, SEEK_END);
  long fsize = ftell(fp);
  fseek(fp, 0, SEEK_SET);

  if (fsize < 0) {
    printf("error: ftell\n");

    fclose(fp);

    return 1;
  }

  char *buf = NULL;

  if (fsize > 0) {
    buf = malloc((size_t)fsize);

    if (!buf) {
      fprintf(stderr, "out of memory\n");
      fclose(fp);
      return 1;
    }

    if (fread(buf, 1, (size_t)fsize, fp) != (size_t)fsize) {
      fprintf(stderr, "read error\n");
      free(buf);
      fclose(fp);
      return 1;
    }
  }

  fclose(fp);

  uint8_t digest[BLAKE2B_OUTBYTES];
  if (blake2b(digest, buf, NULL, BLAKE2B_OUTBYTES, (size_t)fsize, 0) != 0) {
    fprintf(stderr, "blake2b failed\n");
    free(buf);
    return 1;
  }

  free(buf);

  char hex[BLAKE2B_OUTBYTES * 2 + 1];
  for (size_t i = 0; i < BLAKE2B_OUTBYTES; i++) {
    snprintf(&hex[i * 2], 3, "%02x", digest[i]);
  }
  hex[BLAKE2B_OUTBYTES * 2] = '\0';

  if (!target_hash || strcmp(hex, target_hash) != 0) {
    return 1;
  }

  return 0;
}