change: add base32 decode, initial deconstruction of hashed

laumann
Aug 25, 2022, 3:36 PM
VKLGQREYOZDV46F672RFE5XJO3OEOP4EHTCWZYOJY24HVPQX3L6QC

Dependencies

  • [2] X36ICMJN Initial import for blake3
  • [3] OBKF6SII change: decompress the hashed section too
  • [4] RIWSVVAS change: decompress the 'contents' with zstd_seekable
  • [5] Q7TKZCJP Add initial support for reading the offsets from a (fixed) change
  • [*] QEFCNNVC change: display offsets for given change file
  • [*] PEUS54XQ
  • [*] B3XLVPNC Add ani.c and initial Makefile

Change contents

  • edit in change.h at line 35
    [4.810]
    [4.810]
    struct change_header {
    char *message; /* the "commit" message */
    char *description; /* the other undescribed part of a change */
    char *timestamp; /* yes, as a string */
    void *authors; /* something... */
    };
  • edit in change.h at line 43
    [4.814]
    [4.814]
    * The parts of a given change that is blake3-hashed.
    *
    * The actual hashing happens on the serialized (w/bincode) version of this
    * struct. Decoding the 'changes' field will take quite a bit of doing, it's a
    * fairly convoluted field.
    */
    struct hashed {
    uint64_t version; /* same as in offsets? here to be hashed! */
    struct change_header header;
    void *dependencies; /* array of hashes */
    void *extra_known; /* another array of hashes */
    };
    /**
  • edit in change.c at line 11
    [4.66]
    [4.1192]
    #include "blake3.h"
  • edit in change.c at line 13
    [4.1212]
    [3.0]
    #include "base32.h"
  • replacement in change.c at line 25
    [3.130][3.130:167]()
    printf("%s = [%02x", name, buf[0]);
    [3.130]
    [3.167]
    printf("%s = [%u", name, buf[0]);
  • replacement in change.c at line 27
    [3.194][3.194:222]()
    printf(", %02x", buf[i]);
    [3.194]
    [3.222]
    printf(", %u", buf[i]);
  • replacement in change.c at line 144
    [3.1083][3.1083:1155]()
    change_decode_hashed(int fd, size_t comp_hashed_len, size_t hashed_len)
    [3.1083]
    [3.1155]
    change_decode_hashed(int fd, size_t comp_hashed_len, size_t hashed_len, uint8_t *expected_hash)
  • edit in change.c at line 147
    [3.1172]
    [4.2591]
    struct hashed hashed;
    blake3_hasher b3sum;
    uint8_t output[BLAKE3_OUT_LEN];
    size_t i;
  • edit in change.c at line 158
    [3.1373]
    [3.1373]
    /* TODO Decode into 'struct hashed' */
    /* Step 1. Compute the hash of the result buf! */
    blake3_hasher_init(&b3sum);
    blake3_hasher_update(&b3sum, buf, hashed_len);
    blake3_hasher_finalize(&b3sum, output, BLAKE3_OUT_LEN);
    for (i = 0; i < BLAKE3_OUT_LEN; i++)
    printf("%02x", output[i]);
    printf("\n");
    if (expected_hash != NULL) {
    for (i = 0; i < BLAKE3_OUT_LEN; i++)
    printf("%02x", expected_hash[i]);
    printf("\n");
    }
  • edit in change.c at line 207
    [4.2620]
    [7.122]
    uint8_t contents_hash[32];
  • edit in change.c at line 227
    [4.2474]
    [4.2474]
    base32_decode_hash(contents_hash, hash);
  • replacement in change.c at line 235
    [3.1874][3.1874:1956]()
    err = change_decode_hashed(fd, off.unhashed_off - OFFSETS_SIZE, off.hashed_len);
    [3.1874]
    [3.1956]
    err = change_decode_hashed(fd, off.unhashed_off - OFFSETS_SIZE, off.hashed_len, contents_hash);
  • file addition: base32.h (----------)
    [8.1]
    #ifndef BASE32_H
    #define BASE32_H
    /**
    * Takes care of decoding a base32-encoded blake3 hash sum.
    *
    * The input is assumed to be an array of 53 base32 characters, dst is assumed
    * to be able to hold at least 32 bytes.
    */
    void base32_decode_hash(uint8_t *dst, char const *in);
    #endif
  • file addition: base32.c (----------)
    [8.1]
    #include <stdint.h>
    /**
    * Inspired by the base32 implementation here:
    *
    * https://sourceforge.net/p/cyoencode/code/HEAD/tree/trunk/src/CyoDecode.c
    *
    * Basically, the idea is to allocate a much too large array, fill it with 0xff
    * and plug in the values from the alphabet in their corresponding holes.
    */
    static uint8_t BASE32[0x80] = {
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
    0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
    0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
    0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
    };
    void
    base32_decode_hash(uint8_t *dst, char const *in)
    {
    int i, r, off;
    uint8_t v[8];
    for (r = 0; r < 6; r++) {
    off = 8 * r;
    for (i = 0; i < 8; i++)
    v[i] = BASE32[(int)in[off + i]];
    off = 5 * r;
    dst[off] = v[0] << 3 | v[1] >> 2;
    dst[off+1] = v[1] << 6 | v[2] << 1 | v[3] >> 4;
    dst[off+2] = v[3] << 4 | v[4] >> 1;
    dst[off+3] = v[4] << 7 | v[5] << 2 | v[6] >> 3;
    dst[off+4] = v[6] << 5 | v[7];
    }
    /* decode the remaining two bytes */
    off = 48; /* 6×8 */
    for (i = 0; i < 5; i++)
    v[i] = BASE32[(int)in[off+i]];
    off = 30; /* 6×5 */
    dst[off] = v[0] << 3 | v[1] >> 2;
    dst[off+1] = v[1] << 6 | v[2] << 1 | v[3] >> 4;
    }
  • edit in Makefile at line 23
    [2.53469]
    [2.53469]
    OBJS += base32.o