-1

Consider the following:

uint8_t message[15] = {
     0x32, 0xdc, 0x21, 0x55, 0x3f, 0x87, 0xc8, 0x1e,
     0x85, 0x10, 0x43, 0xf9, 0x93, 0x34, 0x1a
};
uint64_t num = 0xa1b2c33412;

I want to multiply the above variable num to the array message[]. The pseudo-code for what I have need, is following:

uint8_t message[15] = {
     0x32, 0xdc, 0x21, 0x55, 0x3f, 0x87, 0xc8, 0x1e,
     0x85, 0x10, 0x43, 0xf9, 0x93, 0x34, 0x1a
};
uint64_t num = 0xa1b2c33412;
uint64_t p = 0x31ba62ca3037;
uint64_t result = 0x00;
result = moduloMultiplication(message, num, p); // (message * num) (mod p)

I am expecting the following results:

num * msg = num*msg mod p
num * msg = 0x2bf2d18cdf92   (Final result)

Is there any way to multiply the array with value of typeuint64_t?

Any help regarding this will be appreciated...

abbasi_ahsan
  • 340
  • 1
  • 11
  • Provide some example of which result you expect to get? I suggest adding such an example with values which are easy to calculate manually. I mean, what should happen if you calculate e.g. `27 * 27 mod 1000` and get 729 - what would you want to appear in your result? – anatolyg May 05 '19 at 12:42
  • i edit the question to explain what i expect... – abbasi_ahsan May 05 '19 at 13:15
  • In your example, it looks like your 15-byte message, when multiplied by your `num = 0xa1b2c33412`, should be equal to that long number with many trailing zeros. Why? When I multiply them in Python, I get a similar number, but not exactly that number. Maybe explain it with a simple example, with a 1-byte message, or with a 2-byte message, and a smaller multiplier? – anatolyg May 05 '19 at 13:31

1 Answers1

2

Assuming the number stored in the 15-byte array is in big-endian order, here is a simple solution:

#include <stdio.h>
#include <stdint.h>

uint64_t moduloMultiplication(const uint8_t message[15], size_t n,
                              uint64_t num, uint64_t p)
{
    uint64_t res = 0;
    for (size_t i = 0; i < n; i++) {
        // assuming `p < 1ULL << 56`
        res = (res * 256 + message[i] * num) % p;
    }
    return res;
}

int main() {
    uint8_t message[15] = {
        0x32, 0xdc, 0x21, 0x55, 0x3f, 0x87, 0xc8, 0x1e,
        0x85, 0x10, 0x43, 0xf9, 0x93, 0x34, 0x1a
    };
    uint64_t num = 0xa1b2c33412;
    uint64_t p = 0x31ba62ca3037;
    // result = (message * num) (mod p)
    uint64_t result = moduloMultiplication(message, sizeof message, num, p);

    printf("%#"PRIx64"\n", result);
    return 0;
}

Output: 0x2bf2d18cdf92

The result differs from that in the question because either the message is incorrect, or your intermediary result is approximate: 201FF4CDCFE8C0000000000000000000000000000 seems incorrect.

chqrlie
  • 131,814
  • 10
  • 121
  • 189