// File: simap[P]ecctools/verifier.cpp
// Function: main
int main(int argc, char ** argv) {
  const struct uECC_Curve_t * curve = uECC_secp256k1();

  if (argc != 3) {
    fprintf(stderr, "Need a public key and archive\n");
    return -1;
  }

  // uint8_t private1[32];
  uint8_t public1[64];
  char tmp[100];
  FILE *fp, *fpin;


  sprintf(tmp, "%s.pub", argv[1]);
  fp = fopen(tmp, "rb");
  int nread = fread(public1, 1, sizeof(public1), fp);
  fclose(fp);
  if (nread != sizeof(public1)) {
    fprintf(stderr, "can't read key %s\n", tmp);
    return -1;
  }

  fpin = fopen(argv[2], "rb");
  FUHeader header = {0};
  nread = fread(&header, 1, sizeof(FUHeader), fpin);
  if (nread != sizeof(FUHeader) || strncmp("STFU", header.magic, 4) != 0) {
    fprintf(stderr, "can't read magic and header\n");
    return -1;
  }

  for (int fileNum = 0; fileNum < header.numFiles; fileNum++) {
    FUFileHeader header = {0};
    nread = fread(&header, 1, sizeof(header), fpin);
    if (nread != sizeof(header)) {
      fprintf(stderr, "unable to read header\n");
      return -1;
    }

    printf("Scanning type:%d size:%d name:%s\n", header.type, header.size, header.name);

    int bytesRemaining = header.size;

    //hash it
    uint8_t buf[512];
    SHA256 sha;
    sha.update(&header, sizeof(header));
    while (bytesRemaining > 0) {
      int nread = fread(buf, 1, bytesRemaining < 512 ? bytesRemaining : 512, fpin);
      if (nread > 0) {
        bytesRemaining -= nread;
        sha.update(buf, nread);
      } else {
        break;
      }
    }
    if (bytesRemaining) {
      fprintf(stderr, "had trouble reading file for hash, %d bytes more wanted\n", bytesRemaining);
      return -1;
    }

    FUFileFooter footer = {0};
    nread = fread(&footer, 1, sizeof(footer), fpin);
    if (nread != sizeof(footer)) {
      fprintf(stderr, "unable to read footer\n");
      return -1;
    }

    uint8_t hash[32];
    sha.finalize(hash, 32);
    if (memcmp(hash, footer.hash, 32) != 0) {
      fprintf(stderr, "hash mismatch!\n");
      return -1; 
    }

    int signatureOK = uECC_verify(public1, hash, 32, footer.signature, curve);
    if (!signatureOK) {
      fprintf(stderr, "signature invalid!\n");
      return -1;
    }
  }
  fclose(fpin);
  printf("signed transfer file update verification complete!\n");
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x4b0, %rsp            # imm = 0x4B0
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
callq 0x1850
movq %rax, -0x18(%rbp)
cmpl $0x3, -0x8(%rbp)
je 0x128c
movq 0x9d71(%rip), %rax      # 0xafe0
movq (%rax), %rdi
leaq 0x6d8b(%rip), %rsi      # 0x8004
movb $0x0, %al
callq 0x10f0
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x1779
leaq -0xd0(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdx
leaq 0x6d81(%rip), %rsi      # 0x8023
movb $0x0, %al
callq 0x1040
leaq -0xd0(%rbp), %rdi
leaq 0x6d73(%rip), %rsi      # 0x802a
callq 0x10e0
movq %rax, -0xd8(%rbp)
leaq -0x60(%rbp), %rdi
movq -0xd8(%rbp), %rcx
movl $0x1, %esi
movl $0x40, %edx
callq 0x1110
movl %eax, -0xe4(%rbp)
movq -0xd8(%rbp), %rdi
callq 0x10c0
movslq -0xe4(%rbp), %rax
cmpq $0x40, %rax
je 0x1327
movq 0x9cdd(%rip), %rax      # 0xafe0
movq (%rax), %rdi
leaq -0xd0(%rbp), %rdx
leaq 0x6d19(%rip), %rsi      # 0x802d
movb $0x0, %al
callq 0x10f0
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x1779
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
leaq 0x6cf4(%rip), %rsi      # 0x802a
callq 0x10e0
movq %rax, -0xe0(%rbp)
leaq -0xec(%rbp), %rdi
xorl %esi, %esi
movl $0x8, %edx
callq 0x1090
movq -0xe0(%rbp), %rcx
leaq -0xec(%rbp), %rdi
movl $0x1, %esi
movl $0x8, %edx
callq 0x1110
movl %eax, -0xe4(%rbp)
movslq -0xe4(%rbp), %rax
cmpq $0x8, %rax
jne 0x13a2
leaq -0xec(%rbp), %rsi
leaq 0x6cad(%rip), %rdi      # 0x8040
movl $0x4, %edx
callq 0x1080
cmpl $0x0, %eax
je 0x13c6
movq 0x9c37(%rip), %rax      # 0xafe0
movq (%rax), %rdi
leaq 0x6c92(%rip), %rsi      # 0x8045
movb $0x0, %al
callq 0x10f0
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x1779
movl $0x0, -0xf0(%rbp)
movl -0xf0(%rbp), %eax
cmpl -0xe8(%rbp), %eax
jae 0x175f
leaq -0x154(%rbp), %rdi
xorl %esi, %esi
movl $0x64, %edx
callq 0x1090
movq -0xe0(%rbp), %rcx
leaq -0x154(%rbp), %rdi
movl $0x1, %esi
movl $0x64, %edx
callq 0x1110
movl %eax, -0xe4(%rbp)
movslq -0xe4(%rbp), %rax
cmpq $0x64, %rax
je 0x1449
movq 0x9bb4(%rip), %rax      # 0xafe0
movq (%rax), %rdi
leaq 0x6c2c(%rip), %rsi      # 0x8062
movb $0x0, %al
callq 0x10f0
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x1779
movl -0x154(%rbp), %esi
movl -0x150(%rbp), %edx
leaq -0x14c(%rbp), %rcx
leaq 0x6c16(%rip), %rdi      # 0x8079
xorl %eax, %eax
callq 0x1030
movl -0x150(%rbp), %eax
movl %eax, -0x158(%rbp)
leaq -0x3d8(%rbp), %rdi
movq %rdi, -0x480(%rbp)
callq 0x6630
movq -0x480(%rbp), %rdi
leaq -0x154(%rbp), %rsi
movl $0x64, %edx
callq 0x6750
jmp 0x14a3
jmp 0x14a5
cmpl $0x0, -0x158(%rbp)
jle 0x1583
leaq -0x360(%rbp), %rax
movq %rax, -0x488(%rbp)
cmpl $0x200, -0x158(%rbp)    # imm = 0x200
jge 0x14da
movl -0x158(%rbp), %eax
movl %eax, -0x48c(%rbp)
jmp 0x14e7
movl $0x200, %eax            # imm = 0x200
movl %eax, -0x48c(%rbp)
jmp 0x14e7
movq -0x488(%rbp), %rdi
movl -0x48c(%rbp), %eax
movslq %eax, %rdx
movq -0xe0(%rbp), %rcx
movl $0x1, %esi
callq 0x1110
movq %rax, -0x498(%rbp)
jmp 0x1511
movq -0x498(%rbp), %rax
movl %eax, -0x3e8(%rbp)
cmpl $0x0, -0x3e8(%rbp)
jle 0x157c
movl -0x3e8(%rbp), %ecx
movl -0x158(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x158(%rbp)
movslq -0x3e8(%rbp), %rdx
leaq -0x3d8(%rbp), %rdi
leaq -0x360(%rbp), %rsi
callq 0x6750
jmp 0x1557
jmp 0x157e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x3e0(%rbp)
movl %eax, -0x3e4(%rbp)
leaq -0x3d8(%rbp), %rdi
callq 0x66c0
jmp 0x1785
jmp 0x1583
jmp 0x14a5
cmpl $0x0, -0x158(%rbp)
je 0x15c0
movq 0x9a4d(%rip), %rax      # 0xafe0
movq (%rax), %rdi
movl -0x158(%rbp), %edx
leaq 0x6af8(%rip), %rsi      # 0x809b
movb $0x0, %al
callq 0x10f0
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
movl $0x1, -0x3ec(%rbp)
jmp 0x172f
xorps %xmm0, %xmm0
movaps %xmm0, -0x400(%rbp)
movaps %xmm0, -0x410(%rbp)
movaps %xmm0, -0x420(%rbp)
movaps %xmm0, -0x430(%rbp)
movaps %xmm0, -0x440(%rbp)
movaps %xmm0, -0x450(%rbp)
movq -0xe0(%rbp), %rcx
leaq -0x450(%rbp), %rdi
movl $0x1, %esi
movl $0x60, %edx
callq 0x1110
movq %rax, -0x4a0(%rbp)
jmp 0x1613
movq -0x4a0(%rbp), %rax
movl %eax, -0xe4(%rbp)
movslq -0xe4(%rbp), %rax
cmpq $0x60, %rax
je 0x165b
movq 0x99ac(%rip), %rax      # 0xafe0
movq (%rax), %rdi
leaq 0x6a96(%rip), %rsi      # 0x80d4
movb $0x0, %al
callq 0x10f0
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
movl $0x1, -0x3ec(%rbp)
jmp 0x172f
leaq -0x3d8(%rbp), %rdi
leaq -0x470(%rbp), %rsi
movl $0x20, %edx
callq 0x6d60
jmp 0x1675
leaq -0x470(%rbp), %rdi
leaq -0x450(%rbp), %rsi
movl $0x20, %edx
callq 0x1070
cmpl $0x0, %eax
je 0x16bd
movq 0x9947(%rip), %rax      # 0xafe0
movq (%rax), %rdi
leaq 0x6a48(%rip), %rsi      # 0x80eb
movb $0x0, %al
callq 0x10f0
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
movl $0x1, -0x3ec(%rbp)
jmp 0x172f
leaq -0x430(%rbp), %rcx
movq -0x18(%rbp), %r8
leaq -0x60(%rbp), %rdi
leaq -0x470(%rbp), %rsi
movl $0x20, %edx
callq 0x3290
movl %eax, -0x4a4(%rbp)
jmp 0x16e5
movl -0x4a4(%rbp), %eax
movl %eax, -0x474(%rbp)
cmpl $0x0, -0x474(%rbp)
jne 0x1725
movq 0x98df(%rip), %rax      # 0xafe0
movq (%rax), %rdi
leaq 0x69f0(%rip), %rsi      # 0x80fb
movb $0x0, %al
callq 0x10f0
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
movl $0x1, -0x3ec(%rbp)
jmp 0x172f
movl $0x0, -0x3ec(%rbp)
leaq -0x3d8(%rbp), %rdi
callq 0x66c0
movl -0x3ec(%rbp), %eax
testl %eax, %eax
je 0x1749
jmp 0x1747
jmp 0x1779
jmp 0x174b
movl -0xf0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xf0(%rbp)
jmp 0x13d0
movq -0xe0(%rbp), %rdi
callq 0x10c0
leaq 0x699d(%rip), %rdi      # 0x810f
movb $0x0, %al
callq 0x1030
movl -0x4(%rbp), %eax
addq $0x4b0, %rsp            # imm = 0x4B0
popq %rbp
retq
movq -0x3e0(%rbp), %rdi
callq 0x1120
nopw %cs:(%rax,%rax)
nopl (%rax,%rax)