Add crypto_core_ed25519_scalar_complement(), _negate(), _add(), _sub()
This commit is contained in:
parent
cff3d7f6c7
commit
1542d473da
@ -15,7 +15,9 @@ not to be detected.
|
||||
- Test vectors from Project Wycheproof have been added.
|
||||
- New low-level APIs for arithmetic mod the order of the prime order group:
|
||||
`crypto_core_ed25519_scalar_random()`, `crypto_core_ed25519_scalar_reduce()`,
|
||||
and `crypto_core_ed25519_scalar_invert()`.
|
||||
`crypto_core_ed25519_scalar_invert()`, `crypto_core_ed25519_scalar_negate()`,
|
||||
`crypto_core_ed25519_scalar_complement()`, `crypto_core_ed25519_scalar_add()`
|
||||
and `crypto_core_ed25519_scalar_sub()`.
|
||||
- New low-level APIs for scalar multiplication without clamping:
|
||||
`crypto_scalarmult_ed25519_base_noclamp()`,
|
||||
and `crypto_scalarmult_ed25519_noclamp()`. These new APIs are
|
||||
|
@ -1,4 +1,6 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "crypto_core_ed25519.h"
|
||||
#include "private/common.h"
|
||||
#include "private/ed25519_ref10.h"
|
||||
@ -86,6 +88,88 @@ crypto_core_ed25519_scalar_invert(unsigned char *recip, const unsigned char *s)
|
||||
return - sodium_is_zero(s, crypto_core_ed25519_SCALARBYTES);
|
||||
}
|
||||
|
||||
void
|
||||
crypto_core_ed25519_scalar_negate(unsigned char *neg, const unsigned char *s)
|
||||
{
|
||||
/* 2^252+27742317777372353535851937790883648493 */
|
||||
static const unsigned char L[32] = {
|
||||
0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7,
|
||||
0xa2, 0xde, 0xf9, 0xde, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10
|
||||
};
|
||||
uint_fast16_t c = 0U;
|
||||
unsigned char r = 0U;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < crypto_core_ed25519_SCALARBYTES; i++) {
|
||||
r |= s[i];
|
||||
c = (uint_fast16_t) L[i] - (uint_fast16_t) s[i] - c;
|
||||
neg[i] = (unsigned char) c;
|
||||
c = (c >> 8) & 1U;
|
||||
}
|
||||
r = ~(r - 1U) >> 8;
|
||||
for (i = 0; i < crypto_core_ed25519_SCALARBYTES; i++) {
|
||||
neg[i] &= r;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
crypto_core_ed25519_scalar_complement(unsigned char *comp, const unsigned char *s)
|
||||
{
|
||||
/* 2^252+27742317777372353535851937790883648493 + 1 */
|
||||
static const unsigned char L1[32] = {
|
||||
0xee, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7,
|
||||
0xa2, 0xde, 0xf9, 0xde, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10
|
||||
};
|
||||
uint_fast16_t c = 0U;
|
||||
unsigned char q = 0U;
|
||||
unsigned char r = 0U;
|
||||
size_t i;
|
||||
|
||||
q |= s[0] ^ 1U;
|
||||
r |= s[0];
|
||||
c = (uint_fast16_t) L1[0] - (uint_fast16_t) s[0] - c;
|
||||
comp[0] = (unsigned char) c;
|
||||
c = (c >> 8) & 1U;
|
||||
for (i = 1U; i < crypto_core_ed25519_SCALARBYTES; i++) {
|
||||
q |= s[i];
|
||||
r |= s[i];
|
||||
c = (uint_fast16_t) L1[i] - (uint_fast16_t) s[i] - c;
|
||||
comp[i] = (unsigned char) c;
|
||||
c = (c >> 8) & 1U;
|
||||
}
|
||||
q = ~(q - 1U) >> 8;
|
||||
r = ~(r - 1U) >> 8;
|
||||
for (i = 0; i < crypto_core_ed25519_SCALARBYTES; i++) {
|
||||
comp[i] &= q & r;
|
||||
}
|
||||
comp[0] |= (~r) & 1U;
|
||||
}
|
||||
|
||||
void
|
||||
crypto_core_ed25519_scalar_add(unsigned char *z, const unsigned char *x,
|
||||
const unsigned char *y)
|
||||
{
|
||||
unsigned char x_[crypto_core_ed25519_NONREDUCEDSCALARBYTES] = { 0U };
|
||||
unsigned char y_[crypto_core_ed25519_NONREDUCEDSCALARBYTES] = { 0U };
|
||||
|
||||
memcpy(x_, x, crypto_core_ed25519_SCALARBYTES);
|
||||
memcpy(y_, y, crypto_core_ed25519_SCALARBYTES);
|
||||
sodium_add(x_, y_, crypto_core_ed25519_SCALARBYTES);
|
||||
crypto_core_ed25519_scalar_reduce(z, x_);
|
||||
}
|
||||
|
||||
void
|
||||
crypto_core_ed25519_scalar_sub(unsigned char *z, const unsigned char *x,
|
||||
const unsigned char *y)
|
||||
{
|
||||
unsigned char yn[crypto_core_ed25519_SCALARBYTES];
|
||||
|
||||
crypto_core_ed25519_scalar_negate(yn, y);
|
||||
crypto_core_ed25519_scalar_add(z, x, yn);
|
||||
}
|
||||
|
||||
void
|
||||
crypto_core_ed25519_scalar_reduce(unsigned char *r,
|
||||
const unsigned char *s)
|
||||
|
@ -50,6 +50,24 @@ SODIUM_EXPORT
|
||||
int crypto_core_ed25519_scalar_invert(unsigned char *recip, const unsigned char *s)
|
||||
__attribute__ ((nonnull));
|
||||
|
||||
SODIUM_EXPORT
|
||||
void crypto_core_ed25519_scalar_negate(unsigned char *neg, const unsigned char *s)
|
||||
__attribute__ ((nonnull));
|
||||
|
||||
SODIUM_EXPORT
|
||||
void crypto_core_ed25519_scalar_complement(unsigned char *comp, const unsigned char *s)
|
||||
__attribute__ ((nonnull));
|
||||
|
||||
SODIUM_EXPORT
|
||||
void crypto_core_ed25519_scalar_add(unsigned char *z, const unsigned char *x,
|
||||
const unsigned char *y)
|
||||
__attribute__ ((nonnull));
|
||||
|
||||
SODIUM_EXPORT
|
||||
void crypto_core_ed25519_scalar_sub(unsigned char *z, const unsigned char *x,
|
||||
const unsigned char *y)
|
||||
__attribute__ ((nonnull));
|
||||
|
||||
/*
|
||||
* The interval `s` is sampled from should be at least 317 bits to ensure almost
|
||||
* uniformity of `r` over `L`.
|
||||
|
@ -174,6 +174,43 @@ main(void)
|
||||
printf("crypto_core_ed25519_scalar_reduce() failed\n");
|
||||
}
|
||||
|
||||
randombytes_buf(h, crypto_core_ed25519_UNIFORMBYTES);
|
||||
crypto_core_ed25519_from_uniform(p, h);
|
||||
memcpy(p2, p, crypto_core_ed25519_BYTES);
|
||||
crypto_core_ed25519_scalar_random(sc);
|
||||
if (crypto_scalarmult_ed25519_noclamp(p, sc, p) != 0) {
|
||||
printf("crypto_scalarmult_ed25519_noclamp() failed (1)\n");
|
||||
}
|
||||
crypto_core_ed25519_scalar_complement(sc, sc);
|
||||
if (crypto_scalarmult_ed25519_noclamp(p2, sc, p2) != 0) {
|
||||
printf("crypto_scalarmult_ed25519_noclamp() failed (2)\n");
|
||||
}
|
||||
crypto_core_ed25519_add(p3, p, p2);
|
||||
crypto_core_ed25519_from_uniform(p, h);
|
||||
crypto_core_ed25519_sub(p, p, p3);
|
||||
assert(p[0] == 0x01);
|
||||
for (i = 1; i < crypto_core_ed25519_BYTES; i++) {
|
||||
assert(p[i] == 0);
|
||||
}
|
||||
|
||||
randombytes_buf(h, crypto_core_ed25519_UNIFORMBYTES);
|
||||
crypto_core_ed25519_from_uniform(p, h);
|
||||
memcpy(p2, p, crypto_core_ed25519_BYTES);
|
||||
crypto_core_ed25519_scalar_random(sc);
|
||||
if (crypto_scalarmult_ed25519_noclamp(p, sc, p) != 0) {
|
||||
printf("crypto_scalarmult_ed25519_noclamp() failed (3)\n");
|
||||
}
|
||||
crypto_core_ed25519_scalar_negate(sc, sc);
|
||||
if (crypto_scalarmult_ed25519_noclamp(p2, sc, p2) != 0) {
|
||||
printf("crypto_scalarmult_ed25519_noclamp() failed (4)\n");
|
||||
}
|
||||
crypto_core_ed25519_add(p, p, p2);
|
||||
assert(p[0] == 0x01);
|
||||
for (i = 1; i < crypto_core_ed25519_BYTES; i++) {
|
||||
assert(p[i] == 0);
|
||||
}
|
||||
|
||||
sodium_free(sc64);
|
||||
sodium_free(sc);
|
||||
sodium_free(p3);
|
||||
sodium_free(p2);
|
||||
|
Loading…
Reference in New Issue
Block a user