1
mirror of https://github.com/jedisct1/libsodium.git synced 2024-12-23 20:15:19 -07:00

Add crypto_scalarmult_curve25519_{noclamp, base_noclamp}

Fixes #1216
This commit is contained in:
Frank Denis 2022-10-10 12:06:41 +02:00
parent 3a99e1ec8a
commit 8b2cbb0d02
17 changed files with 359 additions and 99 deletions

1
.gitignore vendored
View File

@ -144,6 +144,7 @@ test/default/scalarmult6
test/default/scalarmult7
test/default/scalarmult8
test/default/scalarmult_ed25519
test/default/scalarmult_noclamp
test/default/scalarmult_ristretto255
test/default/secretbox
test/default/secretbox2

View File

@ -419,10 +419,14 @@ _crypto_pwhash_str_verify 1 1
_crypto_pwhash_strbytes 1 1
_crypto_pwhash_strprefix 1 1
_crypto_scalarmult 1 1
_crypto_scalarmult_noclamp 0 1
_crypto_scalarmult_base 1 1
_crypto_scalarmult_base_noclamp 0 1
_crypto_scalarmult_bytes 1 1
_crypto_scalarmult_curve25519 0 1
_crypto_scalarmult_curve25519_noclamp 0 1
_crypto_scalarmult_curve25519_base 0 1
_crypto_scalarmult_curve25519_base_noclamp 0 1
_crypto_scalarmult_curve25519_bytes 0 1
_crypto_scalarmult_curve25519_scalarbytes 0 1
_crypto_scalarmult_ed25519 0 1

File diff suppressed because one or more lines are too long

View File

@ -17,7 +17,7 @@ symbols() {
fi
done <emscripten-symbols.def
/usr/bin/nm /usr/local/lib/libsodium.27.dylib |
/usr/bin/nm ../src/libsodium/.libs/libsodium.dylib |
fgrep ' T _' |
cut -d' ' -f3 | {
while read symbol; do

View File

@ -20,6 +20,19 @@ crypto_scalarmult(unsigned char *q, const unsigned char *n,
return crypto_scalarmult_curve25519(q, n, p);
}
int
crypto_scalarmult_base_noclamp(unsigned char *q, const unsigned char *n)
{
return crypto_scalarmult_curve25519_base_noclamp(q, n);
}
int
crypto_scalarmult_noclamp(unsigned char *q, const unsigned char *n,
const unsigned char *p)
{
return crypto_scalarmult_curve25519_noclamp(q, n, p);
}
size_t
crypto_scalarmult_bytes(void)
{

View File

@ -8,71 +8,11 @@
#include "utils.h"
#include "x25519_ref10.h"
/*
* Reject small order points early to mitigate the implications of
* unexpected optimizations that would affect the ref10 code.
* See https://eprint.iacr.org/2017/806.pdf for reference.
*/
static int
has_small_order(const unsigned char s[32])
{
CRYPTO_ALIGN(16)
static const unsigned char blocklist[][32] = {
/* 0 (order 4) */
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
/* 1 (order 1) */
{ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
/* 325606250916557431795983626356110631294008115727848805560023387167927233504
(order 8) */
{ 0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae, 0x16, 0x56, 0xe3,
0xfa, 0xf1, 0x9f, 0xc4, 0x6a, 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32,
0xb1, 0xfd, 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, 0x00 },
/* 39382357235489614581723060781553021112529911719440698176882885853963445705823
(order 8) */
{ 0x5f, 0x9c, 0x95, 0xbc, 0xa3, 0x50, 0x8c, 0x24, 0xb1, 0xd0, 0xb1,
0x55, 0x9c, 0x83, 0xef, 0x5b, 0x04, 0x44, 0x5c, 0xc4, 0x58, 0x1c,
0x8e, 0x86, 0xd8, 0x22, 0x4e, 0xdd, 0xd0, 0x9f, 0x11, 0x57 },
/* p-1 (order 2) */
{ 0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f },
/* p (=0, order 4) */
{ 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f },
/* p+1 (=1, order 1) */
{ 0xee, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f }
};
unsigned char c[7] = { 0 };
unsigned int k;
size_t i, j;
COMPILER_ASSERT(7 == sizeof blocklist / sizeof blocklist[0]);
for (j = 0; j < 31; j++) {
for (i = 0; i < sizeof blocklist / sizeof blocklist[0]; i++) {
c[i] |= s[j] ^ blocklist[i][j];
}
}
for (i = 0; i < sizeof blocklist / sizeof blocklist[0]; i++) {
c[i] |= (s[j] & 0x7f) ^ blocklist[i][j];
}
k = 0;
for (i = 0; i < sizeof blocklist / sizeof blocklist[0]; i++) {
k |= (c[i] - 1);
}
return (int) ((k >> 8) & 1);
}
static int
crypto_scalarmult_curve25519_ref10(unsigned char *q,
const unsigned char *n,
const unsigned char *p)
const unsigned char *p,
const int bits)
{
unsigned char *t = q;
unsigned int i;
@ -82,15 +22,6 @@ crypto_scalarmult_curve25519_ref10(unsigned char *q,
unsigned int swap;
unsigned int bit;
if (has_small_order(p)) {
return -1;
}
for (i = 0; i < 32; i++) {
t[i] = n[i];
}
t[0] &= 248;
t[31] &= 127;
t[31] |= 64;
fe25519_frombytes(x1, p);
fe25519_1(x2);
fe25519_0(z2);
@ -98,8 +29,8 @@ crypto_scalarmult_curve25519_ref10(unsigned char *q,
fe25519_1(z3);
swap = 0;
for (pos = 254; pos >= 0; --pos) {
bit = t[pos / 8] >> (pos & 7);
for (pos = bits - 1; pos >= 0; --pos) {
bit = n[pos / 8] >> (pos & 7);
bit &= 1;
swap ^= bit;
fe25519_cswap(x2, x3, swap);
@ -150,18 +81,11 @@ static int
crypto_scalarmult_curve25519_ref10_base(unsigned char *q,
const unsigned char *n)
{
unsigned char *t = q;
ge25519_p3 A;
fe25519 pk;
unsigned int i;
for (i = 0; i < 32; i++) {
t[i] = n[i];
}
t[0] &= 248;
t[31] &= 127;
t[31] |= 64;
ge25519_scalarmult_base(&A, t);
ge25519_scalarmult_base(&A, n);
edwards_to_montgomery(pk, A.Y, A.Z);
fe25519_tobytes(q, pk);

View File

@ -22,24 +22,16 @@
static int
crypto_scalarmult_curve25519_sandy2x(unsigned char *q, const unsigned char *n,
const unsigned char *p)
const unsigned char *p, const int bits)
{
unsigned char *t = q;
fe var[3];
fe51 x_51;
fe51 z_51;
unsigned int i;
for (i = 0; i < 32; i++) {
t[i] = n[i];
}
t[0] &= 248;
t[31] &= 127;
t[31] |= 64;
fe_frombytes(x1, p);
ladder(var, t);
ladder(var, n, bits);
z_51.v[0] = (z2[1] << 26) + z2[0];
z_51.v[1] = (z2[3] << 26) + z2[2];

View File

@ -19,12 +19,13 @@ _ladder:
mov %rsp,%r11
and $31,%r11
add $1856,%r11
add $1864,%r11
sub %r11,%rsp
movq %r11,1824(%rsp)
movq %r12,1832(%rsp)
movq %r13,1840(%rsp)
movq %r14,1848(%rsp)
movq %rdx,1856(%rsp)
vmovdqa v0_0(%rip),%xmm0
vmovdqa v1_0(%rip),%xmm1
vmovdqu 0(%rdi),%xmm2
@ -136,7 +137,7 @@ movl %r13d,768(%rsi)
add $4,%rsi
sub $1,%rax
jne ._ladder_small_loop
mov $255,%rdx
movq 1856(%rsp),%rdx
add $760,%rsi
.p2align 4

View File

@ -8,7 +8,7 @@ extern "C" {
#include "fe.h"
#include "ladder_namespace.h"
extern void ladder(fe *, const unsigned char *);
extern void ladder(fe *, const unsigned char *, const int);
#ifdef __cplusplus
}

View File

@ -1,8 +1,11 @@
#include "crypto_scalarmult_curve25519.h"
#include "private/common.h"
#include "private/ed25519_ref10.h"
#include "private/implementations.h"
#include "scalarmult_curve25519.h"
#include "runtime.h"
#include "utils.h"
#ifdef HAVE_AVX_ASM
# include "sandy2x/curve25519_sandy2x.h"
@ -11,27 +14,150 @@
static const crypto_scalarmult_curve25519_implementation *implementation =
&crypto_scalarmult_curve25519_ref10_implementation;
static void
clamp(unsigned char *cn, const unsigned char *n)
{
size_t i;
for (i = 0; i < 32; i++) {
cn[i] = n[i];
}
cn[0] &= 248;
cn[31] &= 127;
cn[31] |= 64;
}
/*
* Reject small order points early to mitigate the implications of
* unexpected optimizations that would affect the ref10 code.
* See https://eprint.iacr.org/2017/806.pdf for reference.
*/
static int
has_small_order(const unsigned char s[32])
{
CRYPTO_ALIGN(16)
static const unsigned char blocklist[][32] = {
/* 0 (order 4) */
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
/* 1 (order 1) */
{ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
/* 325606250916557431795983626356110631294008115727848805560023387167927233504
(order 8) */
{ 0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae, 0x16, 0x56, 0xe3,
0xfa, 0xf1, 0x9f, 0xc4, 0x6a, 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32,
0xb1, 0xfd, 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, 0x00 },
/* 39382357235489614581723060781553021112529911719440698176882885853963445705823
(order 8) */
{ 0x5f, 0x9c, 0x95, 0xbc, 0xa3, 0x50, 0x8c, 0x24, 0xb1, 0xd0, 0xb1,
0x55, 0x9c, 0x83, 0xef, 0x5b, 0x04, 0x44, 0x5c, 0xc4, 0x58, 0x1c,
0x8e, 0x86, 0xd8, 0x22, 0x4e, 0xdd, 0xd0, 0x9f, 0x11, 0x57 },
/* p-1 (order 2) */
{ 0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f },
/* p (=0, order 4) */
{ 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f },
/* p+1 (=1, order 1) */
{ 0xee, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f }
};
unsigned char c[7] = { 0 };
unsigned int k;
size_t i, j;
COMPILER_ASSERT(7 == sizeof blocklist / sizeof blocklist[0]);
for (j = 0; j < 31; j++) {
for (i = 0; i < sizeof blocklist / sizeof blocklist[0]; i++) {
c[i] |= s[j] ^ blocklist[i][j];
}
}
for (i = 0; i < sizeof blocklist / sizeof blocklist[0]; i++) {
c[i] |= (s[j] & 0x7f) ^ blocklist[i][j];
}
k = 0;
for (i = 0; i < sizeof blocklist / sizeof blocklist[0]; i++) {
k |= (c[i] - 1);
}
return (int) ((k >> 8) & 1);
}
int
crypto_scalarmult_curve25519_noclamp(unsigned char *q, const unsigned char *n,
const unsigned char *p)
{
if (has_small_order(p)) {
return -1;
}
if (implementation->mult(q, n, p, 256) != 0) {
return -1; /* LCOV_EXCL_LINE */
}
if (has_small_order(q)) {
return -1;
}
return 0;
}
int
crypto_scalarmult_curve25519(unsigned char *q, const unsigned char *n,
const unsigned char *p)
{
unsigned char t[crypto_scalarmult_curve25519_SCALARBYTES];
size_t i;
volatile unsigned char d = 0;
if (implementation->mult(q, n, p) != 0) {
if (has_small_order(p)) {
return -1;
}
COMPILER_ASSERT(crypto_scalarmult_curve25519_SCALARBYTES ==
crypto_scalarmult_curve25519_BYTES);
clamp(t, n);
if (implementation->mult(q, t, p, 255) != 0) {
return -1; /* LCOV_EXCL_LINE */
}
sodium_memzero(t, sizeof t);
for (i = 0; i < crypto_scalarmult_curve25519_BYTES; i++) {
d |= q[i];
}
return -(1 & ((d - 1) >> 8));
}
int
crypto_scalarmult_curve25519_base_noclamp(unsigned char *q, const unsigned char *n)
{
unsigned char t[64];
int ret;
COMPILER_ASSERT(crypto_scalarmult_curve25519_SCALARBYTES <= 64);
COMPILER_ASSERT(crypto_scalarmult_curve25519_SCALARBYTES ==
crypto_scalarmult_curve25519_BYTES);
memcpy(t, n, crypto_scalarmult_curve25519_SCALARBYTES);
memset(t + crypto_scalarmult_curve25519_SCALARBYTES, 0,
64 - crypto_scalarmult_curve25519_SCALARBYTES);
sc25519_reduce(t);
ret = crypto_scalarmult_curve25519_ref10_implementation
.mult_base(q, t);
sodium_memzero(t, sizeof t);
return ret;
}
int
crypto_scalarmult_curve25519_base(unsigned char *q, const unsigned char *n)
{
COMPILER_ASSERT(crypto_scalarmult_curve25519_SCALARBYTES ==
crypto_scalarmult_curve25519_BYTES);
clamp(q, n);
return crypto_scalarmult_curve25519_ref10_implementation
.mult_base(q, n);
.mult_base(q, q);
}
size_t

View File

@ -4,7 +4,7 @@
typedef struct crypto_scalarmult_curve25519_implementation {
int (*mult)(unsigned char *q, const unsigned char *n,
const unsigned char *p);
const unsigned char *p, const int bits);
int (*mult_base)(unsigned char *q, const unsigned char *n);
} crypto_scalarmult_curve25519_implementation;

View File

@ -39,6 +39,15 @@ int crypto_scalarmult(unsigned char *q, const unsigned char *n,
const unsigned char *p)
__attribute__ ((warn_unused_result)) __attribute__ ((nonnull));
SODIUM_EXPORT
int crypto_scalarmult_base_noclamp(unsigned char *q, const unsigned char *n)
__attribute__ ((nonnull));
SODIUM_EXPORT
int crypto_scalarmult_noclamp(unsigned char *q, const unsigned char *n,
const unsigned char *p)
__attribute__ ((warn_unused_result)) __attribute__ ((nonnull));
#ifdef __cplusplus
}
#endif

View File

@ -35,6 +35,17 @@ int crypto_scalarmult_curve25519_base(unsigned char *q,
const unsigned char *n)
__attribute__ ((nonnull));
SODIUM_EXPORT
int crypto_scalarmult_curve25519_noclamp(unsigned char *q,
const unsigned char *n,
const unsigned char *p)
__attribute__ ((warn_unused_result)) __attribute__ ((nonnull));
SODIUM_EXPORT
int crypto_scalarmult_curve25519_base_noclamp(unsigned char *q,
const unsigned char *n)
__attribute__ ((nonnull));
#ifdef __cplusplus
}
#endif

View File

@ -58,6 +58,7 @@ EXTRA_DIST = \
randombytes.exp \
scalarmult.exp \
scalarmult_ed25519.exp \
scalarmult_noclamp.exp \
scalarmult_ristretto255.exp \
scalarmult2.exp \
scalarmult5.exp \
@ -142,6 +143,7 @@ DISTCLEANFILES = \
randombytes.res \
scalarmult.res \
scalarmult_ed25519.res \
scalarmult_noclamp.res \
scalarmult_ristretto255.res \
scalarmult2.res \
scalarmult5.res \
@ -228,6 +230,7 @@ TESTS_TARGETS = \
pwhash_argon2id \
randombytes \
scalarmult \
scalarmult_noclamp \
scalarmult2 \
scalarmult5 \
scalarmult6 \
@ -426,6 +429,9 @@ scalarmult_LDADD = $(TESTS_LDADD)
scalarmult_ed25519_SOURCE = cmptest.h scalarmult_ed25519.c
scalarmult_ed25519_LDADD = $(TESTS_LDADD)
scalarmult_noclamp_SOURCE = cmptest.h scalarmult_noclamp.c
scalarmult_noclamp_LDADD = $(TESTS_LDADD)
scalarmult_ristretto255_SOURCE = cmptest.h scalarmult_ristretto255.c
scalarmult_ristretto255_LDADD = $(TESTS_LDADD)

View File

@ -0,0 +1,166 @@
#define TEST_NAME "scalarmult_noclamp"
#include "cmptest.h"
static const unsigned char B[32] = {
0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
/* order 8 */
static const unsigned char low_order[32] = {
0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae, 0x16, 0x56, 0xe3,
0xfa, 0xf1, 0x9f, 0xc4, 0x6a, 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32,
0xb1, 0xfd, 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, 0x00
};
int
main(void)
{
unsigned char *n, *n2, *n3, *p, *q, *q2;
n = (unsigned char *) sodium_malloc(crypto_scalarmult_curve25519_SCALARBYTES);
n2 = (unsigned char *) sodium_malloc(crypto_scalarmult_curve25519_SCALARBYTES);
n3 = (unsigned char *) sodium_malloc(crypto_scalarmult_curve25519_SCALARBYTES);
p = (unsigned char *) sodium_malloc(crypto_scalarmult_curve25519_BYTES);
q = (unsigned char *) sodium_malloc(crypto_scalarmult_curve25519_BYTES);
q2 = (unsigned char *) sodium_malloc(crypto_scalarmult_curve25519_BYTES);
memset(n, 0, crypto_scalarmult_curve25519_SCALARBYTES);
memcpy(p, B, crypto_scalarmult_ed25519_BYTES);
if (crypto_scalarmult_curve25519_base(q, n) != -1) {
printf("crypto_scalarmult_curve25519_base(0) passed\n");
}
if (crypto_scalarmult_curve25519(q2, n, p) != -1) {
printf("crypto_scalarmult_curve25519(0) passed\n");
}
if (crypto_scalarmult_curve25519_noclamp(q2, n, p) != -1) {
printf("crypto_scalarmult_curve25519_noclamp(0) passed\n");
}
n[0] = 1;
if (crypto_scalarmult_curve25519_base(q, n) != 0) {
printf("crypto_scalarmult_curve25519_base() failed\n");
}
if (crypto_scalarmult_curve25519(q2, n, p) != 0) {
printf("crypto_scalarmult_curve25519() failed\n");
}
if (crypto_scalarmult_curve25519_noclamp(q2, n, p) != 0) {
printf("crypto_scalarmult_curve25519_noclamp() failed\n");
}
n[0] = 9;
if (crypto_scalarmult_curve25519(q, n, p) != 0) {
printf("crypto_scalarmult_curve25519() failed\n");
}
if (crypto_scalarmult_curve25519_noclamp(q2, n, p) != 0) {
printf("crypto_scalarmult_curve25519_noclamp() failed\n");
}
if (memcmp(q, q2, crypto_scalarmult_curve25519_BYTES) == 0) {
printf("clamping not applied\n");
}
n[0] = 9;
if (crypto_scalarmult_curve25519_base(q, n) != 0) {
printf("crypto_scalarmult_curve25519_base() failed\n");
}
if (crypto_scalarmult_curve25519_base_noclamp(q2, n) != 0) {
printf("crypto_scalarmult_curve25519_base_noclamp() failed\n");
}
if (memcmp(q, q2, crypto_scalarmult_curve25519_BYTES) == 0) {
printf("clamping not applied\n");
}
n[0] = 8;
n[31] = 64;
if (crypto_scalarmult_curve25519_noclamp(q2, n, p) != 0) {
printf("crypto_scalarmult_curve25519_base_noclamp() failed\n");
}
if (memcmp(q, q2, crypto_scalarmult_curve25519_BYTES) != 0) {
printf("inconsistent clamping\n");
}
memset(p, 0, crypto_scalarmult_curve25519_BYTES);
if (crypto_scalarmult_curve25519(q, n, p) != -1) {
printf("crypto_scalarmult_curve25519() didn't fail\n");
}
if (crypto_scalarmult_curve25519_noclamp(q, n, p) != -1) {
printf("crypto_scalarmult_curve25519_noclamp() didn't fail\n");
}
n[0] = 8;
if (crypto_scalarmult_curve25519(q, n, p) != -1) {
printf("crypto_scalarmult_curve25519() didn't fail\n");
}
if (crypto_scalarmult_curve25519_noclamp(q, n, p) != -1) {
printf("crypto_scalarmult_curve25519_noclamp() didn't fail\n");
}
crypto_core_ed25519_scalar_random(n);
crypto_core_ed25519_scalar_random(n2);
crypto_core_ed25519_scalar_mul(n3, n, n2);
if (crypto_scalarmult_curve25519_base_noclamp(q, n) != 0) {
printf("crypto_scalarmult_curve25519_noclamp(n) failed\n");
}
if (crypto_scalarmult_curve25519_noclamp(q, n2, q) != 0) {
printf("crypto_scalarmult_curve25519_noclamp(n2) failed\n");
}
if (crypto_scalarmult_curve25519_base_noclamp(q2, n3) != 0) {
printf("crypto_scalarmult_curve25519_noclamp(n3) failed\n");
}
if (memcmp(q, q2, crypto_scalarmult_curve25519_BYTES) != 0) {
printf("unclamped scalarmult broken\n");
}
randombytes_buf(n, crypto_scalarmult_curve25519_SCALARBYTES);
n[31] |= 128;
if (crypto_scalarmult_curve25519_base_noclamp(q, n) != 0) {
printf("crypto_scalarmult_curve25519_base_noclamp(n) failed\n");
}
n[31] &= 127;
if (crypto_scalarmult_curve25519_base_noclamp(q2, n) != 0) {
printf("crypto_scalarmult_curve25519_base_noclamp(n) failed\n");
}
if (memcmp(q, q2, crypto_scalarmult_curve25519_BYTES) == 0) {
printf("unclamped scalarmult_base ignores the top bit\n");
}
memcpy(p, B, crypto_scalarmult_curve25519_BYTES);
randombytes_buf(n, crypto_scalarmult_curve25519_SCALARBYTES);
n[31] |= 128;
if (crypto_scalarmult_curve25519_noclamp(q, n, p) != 0) {
printf("crypto_scalarmult_curve25519_noclamp(n) failed\n");
}
n[31] &= 127;
if (crypto_scalarmult_curve25519_noclamp(q2, n, p) != 0) {
printf("crypto_scalarmult_curve25519_noclamp(n) failed\n");
}
if (memcmp(q, q2, crypto_scalarmult_curve25519_BYTES) == 0) {
printf("unclamped scalarmult ignores the top bit\n");
}
if (crypto_scalarmult_curve25519_noclamp(q, n, low_order) != -1 ||
crypto_scalarmult_curve25519_noclamp(q, n2, low_order) != -1 ||
crypto_scalarmult_curve25519_noclamp(q, n3, low_order) != -1) {
printf("crypto_scalarmult_curve25519_noclamp() didn't fail with a low-order point\n");
}
sodium_free(q2);
sodium_free(q);
sodium_free(p);
sodium_free(n3);
sodium_free(n2);
sodium_free(n);
assert(crypto_scalarmult_curve25519_BYTES == crypto_scalarmult_curve25519_bytes());
assert(crypto_scalarmult_curve25519_SCALARBYTES == crypto_scalarmult_curve25519_scalarbytes());
assert(crypto_scalarmult_curve25519_BYTES == crypto_scalarmult_bytes());
assert(crypto_scalarmult_curve25519_SCALARBYTES == crypto_scalarmult_scalarbytes());
printf("OK\n");
return 0;
}

View File

@ -0,0 +1,3 @@
crypto_scalarmult_curve25519_base(0) passed
crypto_scalarmult_curve25519(0) passed
OK

View File

@ -455,10 +455,13 @@ crypto_pwhash_strbytes
crypto_pwhash_strprefix
crypto_scalarmult
crypto_scalarmult_base
crypto_scalarmult_base_noclamp
crypto_scalarmult_bytes
crypto_scalarmult_curve25519
crypto_scalarmult_curve25519_base
crypto_scalarmult_curve25519_base_noclamp
crypto_scalarmult_curve25519_bytes
crypto_scalarmult_curve25519_noclamp
crypto_scalarmult_curve25519_scalarbytes
crypto_scalarmult_ed25519
crypto_scalarmult_ed25519_base
@ -466,6 +469,7 @@ crypto_scalarmult_ed25519_base_noclamp
crypto_scalarmult_ed25519_bytes
crypto_scalarmult_ed25519_noclamp
crypto_scalarmult_ed25519_scalarbytes
crypto_scalarmult_noclamp
crypto_scalarmult_primitive
crypto_scalarmult_ristretto255
crypto_scalarmult_ristretto255_base