Skip to content

Commit

Permalink
mont_new_from_bytes() can take numbers larger than the modulus
Browse files Browse the repository at this point in the history
  • Loading branch information
Legrandin committed Sep 7, 2024
1 parent 392a162 commit 767ac2e
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 13 deletions.
2 changes: 1 addition & 1 deletion src/bignum.c
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ STATIC void add_mod(uint64_t* out, const uint64_t* a, const uint64_t* b, const u
/*
* Subtract two multi-word numbers with modulo arithmetic.
*
* @param out The locaton where the multi-word result (nw words) is stored
* @param out The location where the multi-word result (nw words) is stored
* @param a The number it will be subtracted from (nw words)
* @param b The number to subtract (nw wordS)
* @param modulus The modulus (nw words)
Expand Down
21 changes: 11 additions & 10 deletions src/mont.c
Original file line number Diff line number Diff line change
Expand Up @@ -794,7 +794,7 @@ int mont_new_random_number(uint64_t **out, unsigned count, uint64_t seed, const
* The memory will contain the number encoded in Montgomery form.
* The caller is responsible for deallocating the memory.
* @param ctx Montgomery context, as created by mont_context_init().
* @param number The big endian-encoded number to transform, strictly smaller than the modulus.
* @param number The big endian-encoded number to transform.
* @param len The length of the big-endian number in bytes (this may be
* smaller than the output of mont_bytes(ctx)).
* @return 0 in case of success, the relevant error code otherwise.
Expand Down Expand Up @@ -835,23 +835,24 @@ int mont_new_from_bytes(uint64_t **out, const uint8_t *number, size_t len, const
}
bytes_to_words(tmp1, ctx->words, number, len);

/** Make sure number<modulus **/
if (ge(tmp1, ctx->modulus, ctx->words)) {
res = ERR_VALUE;
goto cleanup;
}

/** Scratchpad **/
scratchpad = (uint64_t*)calloc(SCRATCHPAD_NR, ctx->words*sizeof(uint64_t));
if (NULL == scratchpad) {
res = ERR_MEMORY;
goto cleanup;
}

if (ctx->modulus_type != ModulusP521)
if (ctx->modulus_type != ModulusP521) {
mont_mult_generic(encoded, tmp1, ctx->r2_mod_n, ctx->modulus, ctx->m0, scratchpad, ctx->words);
else
mont_copy(encoded, tmp1, ctx);
} else {
while (ge(tmp1, ctx->modulus, ctx->words)) {
res = sub(tmp1, tmp1, ctx->modulus, ctx->words);
if (res) goto cleanup;
}
res = mont_copy(encoded, tmp1, ctx);
if (res) goto cleanup;
}

res = 0;

cleanup:
Expand Down
21 changes: 19 additions & 2 deletions src/test/test_mont.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,9 @@ void test_mont_new_from_bytes(void)
{
int res;
MontContext *ctx;
uint8_t modulus[16] = { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
uint8_t number[] = { 2, 2 };
uint8_t modulus[16] = { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; // 0x01000001000000000000000000000001
uint8_t number[] = { 2, 2 }; // 0x0202
uint8_t number2[16] = { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3 }; // 0x01000001000000000000000000000001 + 0x0202
uint64_t *output;

res = mont_context_init(&ctx, modulus, 16);
Expand All @@ -113,6 +114,22 @@ void test_mont_new_from_bytes(void)
assert(output[1] == 71492449356218367L);
free(output);

res = mont_new_from_bytes(&output, number, sizeof(number), ctx);
assert(res == 0);
assert(output != NULL);
assert(output[0] == 18446744073709420033UL);
assert(output[1] == 71492449356218367L);
free(output);

/** Same as above, but larger than modulus **/
res = mont_new_from_bytes(&output, number2, sizeof(number2), ctx);
assert(res == 0);
assert(output != NULL);
assert(output[0] == 18446744073709420033UL);
assert(output[1] == 71492449356218367L);
free(output);

/** 0 is still 0 in Montgomery form **/
number[0] = 0;
number[1] = 0;
res = mont_new_from_bytes(&output, number, 2, ctx);
Expand Down

0 comments on commit 767ac2e

Please sign in to comment.