1

I need to patch first 23 bytes of 32 bytes randomly generated by the rand256 function but it seems memset isn't correctly patching.

0000000000000000000000C90F4094919B9FAE4616149C0FDC61E7C1F318E234

as you can see, memset added only 23 zeroes whereas I am expecting 46 zeroes. Now I am wondering if there is something like zfill that can correctly fill 23 bytes with zeros.

union uint256_s
{
    uint8_t i8[32];
    uint16_t i16[16];
    uint32_t i32[8];
    uint64_t i64[4];
};
typedef union uint256_s uint256_t;
static uint256_t rand256(struct seed *seed)
{
    seed->counter++;
    return sha256(seed, sizeof(struct seed));
}

static uint256_t rand256_and_mask(struct seed *seed)
{
    uint256_t r = rand256(seed);
    memset(&r, 0x000, 23);
    return r;
}

struct seed {
    uint256_t seed;
    uint128_t counter;
};

static inline uint256_t sha256(const void *data, size_t len)
{
    secp256k1_sha256_t cxt;
    secp256k1_sha256_initialize(&cxt);
    secp256k1_sha256_write(&cxt, (uint8_t *)data, (int)len);
    uint256_t res;
    secp256k1_sha256_finalize(&cxt, (uint8_t *)&res);
    return res;
}
static void *init_worker(void *arg)
{
    struct seed *seed = make_seed();
    size_t i = (size_t)arg;

    for (size_t j = 0; j < OFFSET_MAX_ROW; j++)
    {
        int overflow = 0;
        do
        {
            uint256_t x = rand256_and_mask(seed);
            secp256k1_scalar_set_b32(&priv_offsets[j][i], x.i8 + 12, &overflow);
        }
        while (overflow);
        secp256k1_gej_t tmp;
        secp256k1_ecmult_gen(&cxt->ecmult_gen_ctx, &tmp, &priv_offsets[j][i]);
        secp256k1_ge_set_gej(&offsets[j][i], &tmp);
    }
    free(seed);
    putchar('.');
    fflush(stdout);

    return NULL;
}

how can I correctly patch first 23 bytes?

BsMthethwa
  • 11
  • 3
  • 5
    `as you can see, memset added only 23 zeroes` How are you checking that, exactly? – KamilCuk Feb 18 '23 at 19:10
  • 1
    The 64-character hex value, which represents the 32 bytes of a 256-bit value, has its most significant bits clear. From that, your system must be big-endian? Is that the case? – Weather Vane Feb 18 '23 at 19:19
  • 1
    The function `rand256_and_mask()` which calls `memset()` isn't itself used in the code shown. – Weather Vane Feb 18 '23 at 19:41
  • 3
    nor is the code that prints the 'bad' value. Complete testable code please – pm100 Feb 18 '23 at 19:51
  • `memset(&r, 0x000, 23);` Have you tried to pass the second parameter with 0 (zero)? Its just an unsigned char conversion of the value anyway. And the third parameter is set to 23 as you stated in the first sentence. Why do you expect 46 zeros? – ptr2n0 Feb 18 '23 at 20:00
  • 1
    @ptr2n0 perhaps because 23 bytes should show as 46 characters in hexadecimal text. The whole thing is unclear, though. – Weather Vane Feb 18 '23 at 20:25
  • @WeatherVane Maybe I'm misinterpreting this, but if a char array is given you just patch the wanted bytes with the char you choose. In that case it is plain 0. If you need to do 23 Bytes you write `memset(&r, '0', 23);` and if you need 46 Bytes aka 46 zeros you write to the third parameter 46. See: [link](https://onlinegdb.com/vkzgrWWTv) – ptr2n0 Feb 18 '23 at 21:08
  • 1
    @ptr2n0: no, `r` is a `uint256_t`, which is a 256 bit integer occupying 32 bytes. Yet the OP does not provide the code that outputs the textual representation, which might be incorrect. – chqrlie Feb 19 '23 at 00:25
  • What exactly is `uint256_t` type? – dimich Feb 19 '23 at 05:13
  • @BsMthethwa:" as you can see, memset added only 23 zeroes" --> "0000000000000000000000C90F4094919B9FAE4616149C0FDC61E7C1F318E234" has 22 leading zeros in its 64 digit length. Where is the 23 coming from? a mis-count? – chux - Reinstate Monica Feb 19 '23 at 05:47
  • @BsMthethwa, `rand256_and_mask()` is never called. No evidence that `memset(&r, 0x000, 23);` ever called. Post a [mcve]. – chux - Reinstate Monica Feb 19 '23 at 05:50
  • the program outputs uint256 in hexadecimal, so i think since i replaced the first 23 bytes with 0s the value of r is no longer 32bytes, its just a theory – BsMthethwa Feb 20 '23 at 02:39
  • @dimich its union – BsMthethwa Feb 20 '23 at 02:41
  • @BsMthethwa Thanks, i see the post is updated. How do you monitor `x` value? Try `for (int i=0; i<32; ++i) printf(" %02X", x.i8[i]); printf("\n");` right after `uint256_t x = rand256_and_mask(seed);` – dimich Feb 20 '23 at 18:21
  • @dimich you are right, x is correctly patched, after putting the above code i get `00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 48 02 3B 57 B5 92 94 21 80` – BsMthethwa Feb 20 '23 at 19:38

0 Answers0