0

Given the example code below that generates 32 bytes and masks the first bytes with zeroes.

 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, 0, 27);
    //r.i8[23] = 0xE;
    return r;
}

I would like to get the bytes sequentially(as in sequence like \x09,\x0A ... 99) with the difference of +1, like if the last byte is "\x09" on first call then on second call it would be "\x0A".

Note: the numbers i am working on are very large and my program accept type "uint256_t" which is declared like this:

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;

Lets say uint256_t r = rand256(seed); produce this on first execution of my program:

E8411A8777E440FD1FA6CBF5F5149D14B45844B32F7B720CE653686229F9B758

then after memset in rand256_and_mask() the value of r returned will be:

0000000000000000000000000000000000000000000000000000000029F9B758

Here i need to keep the value of r which i will then increment by 1 on the next call (skip rand256() call if necessary), so the value of r will be:

0000000000000000000000000000000000000000000000000000000029F9B759

Technically i need the program to keep track of r as it represents a position in range. I am not fluent in C, so I hope I clarified something.

C developers please help.

  • If I get you right, you are basically trying to keep a `uint256_t` counter that you can return on each function call and that you need to increment by 1. correct? – Gerhardh Jun 06 '23 at 06:10
  • @Gerhardh Thats correct – terry franklin Jun 06 '23 at 06:23
  • Is that your own type to hold 256 bits or are you using a library providing that type? Does it also provide functions to to arithmetic operations on it? If not, you may add 1 like you would add it with pen and paper for normal numbers. Sum up each digit, check if you need to carry over to next digit, repeat... – Gerhardh Jun 06 '23 at 07:22
  • 2
    It is still unclear to me what you are trying to achieve. You have the `uint256_t` type, but as the very first thing mask off 28 bytes so you are essentially left with an `uint32_t`. What keeps you from working with a `uint32_t` from that point on? i.e. `static uint32_t rand256_and_mask(struct seed *seed) { return rand256(seed).i32[7]; }`. – nielsen Jun 06 '23 at 07:39
  • @nielsen the masking is just zfill because the program will expects 1 to 256 bit in 256 bit form – terry franklin Jun 06 '23 at 09:45
  • `uint256_t` is a [reserved identifier](https://port70.net/~nsz/c/c11/n1570.html#7.20.1.1p2). Which means using it [invokes undefined behavior](https://port70.net/~nsz/c/c11/n1570.html#7.1.3p2). Not likely to cause problems? [128-bit numbers have already been around for over 10 years....](https://stackoverflow.com/questions/16088282/is-there-a-128-bit-integer-in-gcc) – Andrew Henle Jun 06 '23 at 11:47

2 Answers2

0

You can use memset to set all its bytes to 0. To sequentially generate bytes in C, you can modify the provided code as follows:

static int currentNumber = 9; // store current

static uint256_t getNextNumber()
{
    currentNumber++;
    if (currentNumber > 99)
        currentNumber = 10;

    uint256_t result;
    memset(&result, 0, sizeof(uint256_t));

    for (int i = 31; i >= 0; i--)
    {
        result.i8[i] = currentNumber & 0xFF;
        currentNumber >>= 8;
    }

    return result;
}

Each time you call the getNextNumber function, it will generate the next sequential byte pattern based on the currentNumber.

Roomey Rahman
  • 244
  • 2
  • 6
  • 1
    The use of `memset` is rather pointless if you immediately fill all the bytes afterwards. And an `int` variable will barely provide enough bits to fill a `uint256_t` – Gerhardh Jun 06 '23 at 06:10
  • This seems like an odd answer to an admittedly very weird question. Given that `currentNumber` is always `<= 99`, why the loop? Looks like something CharGPT would come up with. – pmacfarlane Jun 06 '23 at 06:10
  • you may have misunderstood me, 10 to 99 is a sample range in which numbers are extracted sequentially, as from 10 to 99 but that is just a gist of what i am trying to achieve because i need to do that with the earlier code, with bytes not integers, let me update the question to claarify – terry franklin Jun 06 '23 at 06:39
0

You could use this function to increment an array of uint8_t in big-endian byte order:

#include <stdint.h>
#include <stddef.h>
void incu8v(uint8_t *v, size_t len)
{
    while (len-- > 0)
    {
        if (++v[len] != 0)
        {
            /* No carry. */
            break;
        }
    }
}

This function will increment one of your uint256_t in-place (pass a pointer to the uint256_t):

void inc256p(uint256_t *v)
{
    incu8v(v->i8, sizeof(v->i8));
}

This function will increment a uint256_t by value and return the incremented value:

uint256_t inc256(uint256_t v)
{
    inc256p(&v);
    return v;
}

The way the i16, i32 and i64 member values are changed will depend on the native byte order of your machine.

inc256() and inc256p() do not mask the result, but incu8v() can be used to increment a subsequence of the bytes in place, e.g.

incu8v(r.i8 + 27, 5);

Note that identifiers that begin with int or uint and end with _t are reserved by the C standard, so the type name uint256_t should be renamed to something that is not reserved.

Ian Abbott
  • 15,083
  • 19
  • 33