]> git.codecow.com Git - Monocypher.git/commitdiff
Remove EdDSA incremental & custom hash API
authorLoup Vaillant <loup@loup-vaillant.fr>
Thu, 1 Dec 2022 15:27:08 +0000 (16:27 +0100)
committerLoup Vaillant <loup@loup-vaillant.fr>
Thu, 1 Dec 2022 15:51:39 +0000 (16:51 +0100)
The incremental and custom hash API was too complex and too niche to
justify itself.  I'm removing them in favour of a more flexible
approach: giving the basic building blocks necessary to implement EdDSA
manually.

Those building blocks comprise 5 specialised functions:

- crypto_eddsa_trim_scalar: turn 32 random bytes into a proper scalar.
- crypto_eddsa_reduce     : reduces a 64 bytes number modulo L.
- crypto_eddsa_mul_add    : like MUL_ADD, except modulo L.
- crypto_eddsa_scalarbase : multiplies a scalar by the base point.
- crypto_eddsa_r_check    : generates R independently for verification.

These make it fairly easy to implement EdDSA (including Ed25519) in
various ways, including the streaming and custom hash functions I just
removed, replacing the deterministic nonce by a random one, or adding a
random prefix to mitigate the energy side channel in some settings.

I believe only minimal tweaks are required to implement the Edwards25519
half of RFC 8032 entirely (including the context and pre-hash variants),
as well as XEdDSA (which should only require a single Montgomery to
Edwards conversion function).

This is a prototype, and the extensibility promises remain to be tested.
Ideally that means implementing all the fancy extensions in a separate
project, and _maybe_ include some of them in the optional files.

Related to #227

23 files changed:
doc/man/man3/advanced/crypto_check_final.3monocypher [deleted symlink]
doc/man/man3/advanced/crypto_check_init.3monocypher [deleted symlink]
doc/man/man3/advanced/crypto_check_init_custom_hash.3monocypher [deleted symlink]
doc/man/man3/advanced/crypto_check_update.3monocypher [deleted symlink]
doc/man/man3/advanced/crypto_sign_final.3monocypher [deleted symlink]
doc/man/man3/advanced/crypto_sign_init_first_pass.3monocypher [deleted file]
doc/man/man3/advanced/crypto_sign_init_first_pass_custom_hash.3monocypher [deleted file]
doc/man/man3/advanced/crypto_sign_init_second_pass.3monocypher [deleted symlink]
doc/man/man3/advanced/crypto_sign_public_key_custom_hash.3monocypher [deleted symlink]
doc/man/man3/advanced/crypto_sign_update.3monocypher [deleted symlink]
doc/man/man3/intro.3monocypher
doc/man/man3/optional/crypto_ed25519_check_final.3monocypher [deleted symlink]
doc/man/man3/optional/crypto_ed25519_check_init.3monocypher [deleted symlink]
doc/man/man3/optional/crypto_ed25519_check_update.3monocypher [deleted symlink]
doc/man/man3/optional/crypto_ed25519_sign_final.3monocypher [deleted symlink]
doc/man/man3/optional/crypto_ed25519_sign_init_first_pass.3monocypher [deleted file]
doc/man/man3/optional/crypto_ed25519_sign_init_second_pass.3monocypher [deleted symlink]
doc/man/man3/optional/crypto_ed25519_sign_update.3monocypher [deleted symlink]
src/monocypher.c
src/monocypher.h
src/optional/monocypher-ed25519.c
src/optional/monocypher-ed25519.h
tests/test.c

diff --git a/doc/man/man3/advanced/crypto_check_final.3monocypher b/doc/man/man3/advanced/crypto_check_final.3monocypher
deleted file mode 120000 (symlink)
index 08c255b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-crypto_sign_init_first_pass.3monocypher
\ No newline at end of file
diff --git a/doc/man/man3/advanced/crypto_check_init.3monocypher b/doc/man/man3/advanced/crypto_check_init.3monocypher
deleted file mode 120000 (symlink)
index 08c255b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-crypto_sign_init_first_pass.3monocypher
\ No newline at end of file
diff --git a/doc/man/man3/advanced/crypto_check_init_custom_hash.3monocypher b/doc/man/man3/advanced/crypto_check_init_custom_hash.3monocypher
deleted file mode 120000 (symlink)
index a4b73ad..0000000
+++ /dev/null
@@ -1 +0,0 @@
-crypto_sign_init_first_pass_custom_hash.3monocypher
\ No newline at end of file
diff --git a/doc/man/man3/advanced/crypto_check_update.3monocypher b/doc/man/man3/advanced/crypto_check_update.3monocypher
deleted file mode 120000 (symlink)
index 08c255b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-crypto_sign_init_first_pass.3monocypher
\ No newline at end of file
diff --git a/doc/man/man3/advanced/crypto_sign_final.3monocypher b/doc/man/man3/advanced/crypto_sign_final.3monocypher
deleted file mode 120000 (symlink)
index 08c255b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-crypto_sign_init_first_pass.3monocypher
\ No newline at end of file
diff --git a/doc/man/man3/advanced/crypto_sign_init_first_pass.3monocypher b/doc/man/man3/advanced/crypto_sign_init_first_pass.3monocypher
deleted file mode 100644 (file)
index cbaaf05..0000000
+++ /dev/null
@@ -1,318 +0,0 @@
-.\" This file is dual-licensed.  Choose whichever you want.
-.\"
-.\" The first licence is a regular 2-clause BSD licence.  The second licence
-.\" is the CC-0 from Creative Commons. It is intended to release Monocypher
-.\" to the public domain.  The BSD licence serves as a fallback option.
-.\"
-.\" SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
-.\"
-.\" ----------------------------------------------------------------------------
-.\"
-.\" Copyright (c) 2017-2021 Loup Vaillant
-.\" Copyright (c) 2017-2018 Michael Savage
-.\" Copyright (c) 2017, 2019-2022 Fabio Scotoni
-.\" All rights reserved.
-.\"
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions are
-.\" met:
-.\"
-.\" 1. Redistributions of source code must retain the above copyright
-.\"    notice, this list of conditions and the following disclaimer.
-.\"
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\"    notice, this list of conditions and the following disclaimer in the
-.\"    documentation and/or other materials provided with the
-.\"    distribution.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-.\" "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-.\" A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-.\" HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-.\" OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-.\"
-.\" ----------------------------------------------------------------------------
-.\"
-.\" Written in 2017-2022 by Loup Vaillant, Michael Savage and Fabio Scotoni
-.\"
-.\" To the extent possible under law, the author(s) have dedicated all copyright
-.\" and related neighboring rights to this software to the public domain
-.\" worldwide.  This software is distributed without any warranty.
-.\"
-.\" You should have received a copy of the CC0 Public Domain Dedication along
-.\" with this software.  If not, see
-.\" <https://creativecommons.org/publicdomain/zero/1.0/>
-.\"
-.Dd February 13, 2022
-.Dt CRYPTO_SIGN_INIT_FIRST_PASS 3MONOCYPHER
-.Os
-.Sh NAME
-.Nm crypto_sign_init_first_pass ,
-.Nm crypto_sign_update ,
-.Nm crypto_sign_final ,
-.Nm crypto_sign_init_second_pass ,
-.Nm crypto_check_init ,
-.Nm crypto_check_update ,
-.Nm crypto_check_final
-.Nd incremental public key signatures
-.Sh SYNOPSIS
-.In monocypher.h
-.Ft void
-.Fo crypto_sign_init_first_pass
-.Fa "crypto_sign_ctx *ctx"
-.Fa "const uint8_t secret_key[32]"
-.Fa "const uint8_t public_key[32]"
-.Fc
-.Ft void
-.Fo crypto_sign_update
-.Fa "crypto_sign_ctx *ctx"
-.Fa "const uint8_t *message"
-.Fa "size_t message_size"
-.Fc
-.Ft void
-.Fo crypto_sign_final
-.Fa "crypto_sign_ctx *ctx"
-.Fa "uint8_t signature[64]"
-.Fc
-.Ft void
-.Fo crypto_sign_init_second_pass
-.Fa "crypto_sign_ctx *ctx"
-.Fc
-.Ft void
-.Fo crypto_check_init
-.Fa "crypto_check_ctx *ctx"
-.Fa "const uint8_t signature[64]"
-.Fa "const uint8_t public_key[32]"
-.Fc
-.Ft void
-.Fo crypto_check_update
-.Fa "crypto_check_ctx *ctx"
-.Fa "const uint8_t *message"
-.Fa "size_t message_size"
-.Fc
-.Ft int
-.Fo crypto_check_final
-.Fa "crypto_check_ctx *ctx"
-.Fc
-.Sh DESCRIPTION
-These functions are variants of
-.Xr crypto_sign 3monocypher
-and
-.Xr crypto_check 3monocypher .
-Prefer those simpler functions if possible.
-.Pp
-The arguments are the same as those described in
-.Xr crypto_sign 3monocypher .
-.Pp
-This incremental interface can be used to sign or verify messages too
-large to fit in a single buffer.
-The arguments are the same as the direct interface described in
-.Xr crypto_sign 3monocypher .
-.Pp
-The direct and incremental interface produce and accept the same
-signatures.
-.Pp
-Signing is done in two passes.
-This requires five steps:
-.Bl -bullet
-.It
-Initialisation of the first pass with
-.Fn crypto_sign_init_first_pass .
-The public key is optional and will be recomputed if not provided.
-This recomputation doubles the execution time for short messages.
-.It
-The first pass proper, with
-.Fn crypto_sign_update .
-.Sy Under no circumstances must you forget the first pass .
-Forgetting to call
-.Fn crypto_sign_update
-will appear to work in that it produces valid signatures
-but also
-loses all security because attackers may now recover the secret key.
-.It
-Initialisation of the second pass with
-.Fn crypto_sign_init_second_pass .
-.It
-The second pass proper, with
-.Fn crypto_sign_update .
-The same update function is used for both passes.
-.It
-Signature generation with
-.Fn crypto_sign_final .
-This also wipes the context.
-.El
-.Pp
-Verification requires three steps:
-.Bl -bullet
-.It
-Initialisation with
-.Fn crypto_check_init .
-.It
-Update with
-.Fn crypto_check_update .
-.It
-Signature verification with
-.Fn crypto_check_final .
-.El
-.Sh RETURN VALUES
-.Fn crypto_sign_init_first_pass ,
-.Fn crypto_sign_init_second_pass ,
-.Fn crypto_sign_update ,
-.Fn crypto_sign_final ,
-.Fn crypto_check_init ,
-and
-.Fn crypto_check_update
-return nothing.
-.Pp
-.Fn crypto_check_final
-returns 0 for legitimate messages and -1 for forgeries.
-.Sh EXAMPLES
-Sign a message:
-.Bd -literal -offset indent
-uint8_t       sk       [ 32]; /* Secret key            */
-const uint8_t pk       [ 32]; /* Public key (optional) */
-const uint8_t message  [500]; /* Message to sign       */
-uint8_t       signature[ 64]; /* Output signature      */
-crypto_sign_ctx ctx;
-arc4random_buf(sk, 32);
-crypto_sign_public_key(pk, sk);
-crypto_sign_init_first_pass((crypto_sign_ctx_abstract*)&ctx, sk, pk);
-/* Wipe the secret key if no longer needed */
-crypto_wipe(sk, 32);
-for (size_t i = 0; i < 500; i += 100) {
-    crypto_sign_update((crypto_sign_ctx_abstract*)&ctx, message + i, 100);
-}
-crypto_sign_init_second_pass((crypto_sign_ctx_abstract*)&ctx);
-for (size_t i = 0; i < 500; i += 100) {
-    crypto_sign_update((crypto_sign_ctx_abstract*)&ctx, message + i, 100);
-}
-crypto_sign_final((crypto_sign_ctx_abstract*)&ctx, signature);
-.Ed
-.Pp
-Check the above:
-.Bd -literal -offset indent
-const uint8_t pk       [ 32]; /* Public key         */
-const uint8_t message  [500]; /* Message to sign    */
-const uint8_t signature[ 64]; /* Signature to check */
-crypto_check_ctx ctx;
-crypto_check_init((crypto_sign_ctx_abstract*)&ctx, signature, pk);
-for (size_t i = 0; i < 500; i += 100) {
-    crypto_check_update((crypto_sign_ctx_abstract*)&ctx, message + i, 100);
-}
-if (crypto_check_final((crypto_sign_ctx_abstract*)&ctx)) {
-    /* Message is corrupted, abort processing */
-} else {
-    /* Message is genuine */
-}
-.Ed
-.Pp
-This interface can be used to mitigate attacks that leverage power
-analysis and fault injection (glitching) \(en both of which require
-physical access and appropriate equipment.
-We inject additional randomness (at least 32 bytes) and
-enough all-zero padding to fill the hash function's block size
-(128 bytes for both BLAKE2b and SHA-512).
-Note that
-.Fn crypto_sign_init_first_pass
-already fills 32 bytes,
-so randomness and padding must fill 32 bytes
-.Em less
-than the block
-size (96 bytes for BLAKE2b and SHA-512).
-Access to a cryptographically secure pseudo-random generator is a
-requirement for effective side-channel mitigation.
-Signing a message with increased power-related side-channel mitigations:
-.Bd -literal -offset indent
-const uint8_t message  [   500]; /* Message to sign         */
-uint8_t       sk       [    32]; /* Secret key              */
-const uint8_t pk       [    32]; /* Public key (optional)   */
-uint8_t       signature[    64]; /* Output signature        */
-uint8_t       buf      [128-32] = {0}; /* Mitigation buffer */
-crypto_sign_ctx ctx;
-crypto_sign_ctx_abstract *actx = (crypto_sign_ctx_abstract *)&ctx;
-
-arc4random_buf(sk, 32);
-crypto_sign_public_key(pk, sk);
-
-arc4random_buf(buf, 32);
-/* The rest of buf MUST be zeroes. */
-
-crypto_sign_init_first_pass(actx, sk, pk);
-crypto_sign_update         (actx, buf, sizeof(buf));
-crypto_sign_update         (actx, message, 500);
-
-crypto_sign_init_second_pass(actx);
-crypto_sign_update          (actx, message, 500);
-crypto_sign_final           (actx, signature);
-
-crypto_wipe(buf, 32);
-/* Wipe the secret key if no longer needed */
-crypto_wipe(sk,  32);
-.Ed
-.Sh SEE ALSO
-.Xr crypto_blake2b 3monocypher ,
-.Xr crypto_x25519 3monocypher ,
-.Xr crypto_lock 3monocypher ,
-.Xr crypto_sign 3monocypher ,
-.Xr crypto_wipe 3monocypher ,
-.Xr intro 3monocypher
-.Sh STANDARDS
-These functions implement PureEdDSA with Curve25519 and BLAKE2b, as
-described in RFC 8032.
-This is the same as Ed25519, with BLAKE2b instead of SHA-512.
-.Pp
-The example for side-channel mitigation follows the methodology outlined
-in I-D.draft-mattsson-cfrg-det-sigs-with-noise-02.
-.Sh HISTORY
-The
-.Fn crypto_sign_init_first_pass ,
-.Fn crypto_sign_update ,
-.Fn crypto_sign_final ,
-.Fn crypto_sign_init_second_pass ,
-.Fn crypto_check_init ,
-.Fn crypto_check_update ,
-and
-.Fn crypto_check_final
-functions first appeared in Monocypher 1.1.0.
-.Pp
-Starting with Monocypher 2.0.5, modified signatures abusing the inherent
-signature malleability property of EdDSA now cause a non-zero return
-value of
-.Fn crypto_check_final ;
-in prior versions, such signatures would be accepted.
-.Pp
-.Sy A critical security vulnerability
-that caused all-zero signatures to be accepted was introduced in
-Monocypher 0.3;
-it was fixed in Monocypher 1.1.1 and 2.0.4.
-.Sh SECURITY CONSIDERATIONS
-Messages are not verified until the call to
-.Fn crypto_check_final .
-Messages may be stored before they are verified, but they cannot be
-.Em trusted .
-Processing untrusted messages increases the attack surface of the
-system.
-Doing so securely is hard.
-Do not process messages before calling
-.Fn crypto_check_final .
-.Pp
-When signing messages, the security considerations documented in
-.Xr crypto_sign 3monocypher
-also apply.
-If power-related side-channels are part of your threat model,
-note that there may still be other power-related side-channels (such as
-if the CPU leaks information when an operation overflows a register)
-that must be considered.
-.Sh IMPLEMENTATION DETAILS
-EdDSA signatures require two passes that cannot be performed in
-parallel.
-There are ways around this limitation, but they all lower security in
-some way.
-For this reason, Monocypher does not support them.
diff --git a/doc/man/man3/advanced/crypto_sign_init_first_pass_custom_hash.3monocypher b/doc/man/man3/advanced/crypto_sign_init_first_pass_custom_hash.3monocypher
deleted file mode 100644 (file)
index f1f7920..0000000
+++ /dev/null
@@ -1,296 +0,0 @@
-.\" This file is dual-licensed.  Choose whichever you want.
-.\"
-.\" The first licence is a regular 2-clause BSD licence.  The second licence
-.\" is the CC-0 from Creative Commons. It is intended to release Monocypher
-.\" to the public domain.  The BSD licence serves as a fallback option.
-.\"
-.\" SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
-.\"
-.\" ----------------------------------------------------------------------------
-.\"
-.\" Copyright (c) 2019-2020 Fabio Scotoni
-.\" All rights reserved.
-.\"
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions are
-.\" met:
-.\"
-.\" 1. Redistributions of source code must retain the above copyright
-.\"    notice, this list of conditions and the following disclaimer.
-.\"
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\"    notice, this list of conditions and the following disclaimer in the
-.\"    documentation and/or other materials provided with the
-.\"    distribution.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-.\" "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-.\" A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-.\" HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-.\" OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-.\"
-.\" ----------------------------------------------------------------------------
-.\"
-.\" Written in 2019-2020 by Fabio Scotoni
-.\"
-.\" To the extent possible under law, the author(s) have dedicated all copyright
-.\" and related neighboring rights to this software to the public domain
-.\" worldwide.  This software is distributed without any warranty.
-.\"
-.\" You should have received a copy of the CC0 Public Domain Dedication along
-.\" with this software.  If not, see
-.\" <https://creativecommons.org/publicdomain/zero/1.0/>
-.\"
-.Dd December 28, 2019
-.Dt CRYPTO_SIGN_INIT_FIRST_PASS_CUSTOM_HASH 3MONOCYPHER
-.Os
-.Sh NAME
-.Nm crypto_sign_init_first_pass_custom_hash ,
-.Nm crypto_sign_public_key_custom_hash ,
-.Nm crypto_check_init_custom_hash
-.Nd public key signatures with custom hash functions
-.Sh SYNOPSIS
-.In monocypher.h
-.Ft void
-.Fo crypto_sign_init_first_pass_custom_hash
-.Fa "crypto_sign_ctx_abstract *ctx"
-.Fa "const uint8_t secret_key[32]"
-.Fa "const uint8_t public_key[32]"
-.Fa "const crypto_sign_vtable *hash"
-.Fc
-.Ft void
-.Fo crypto_sign_public_key_custom_hash
-.Fa "uint8_t public_key[32]"
-.Fa "const uint8_t secret_key[32]"
-.Fa "const crypto_sign_vtable *hash"
-.Fc
-.Ft void
-.Fo crypto_check_init_custom_hash
-.Fa "crypto_sign_ctx_abstract *ctx"
-.Fa "const uint8_t signature[64]"
-.Fa "const uint8_t public_key[32]"
-.Fa "const crypto_sign_vtable *hash"
-.Fc
-.Sh DESCRIPTION
-These functions are variants of the
-.Xr crypto_sign_init_first_pass 3monocypher
-family of functions.
-They provide the ability to replace the EdDSA hash function with any
-user-provided hash function.
-.Pp
-.Sy This is a highly advanced feature .
-Interoperability of public key signatures
-with other cryptographic libraries can normally be achieved by using
-.Xr crypto_ed25519_sign 3monocypher
-or
-.Xr crypto_ed25519_sign_init_first_pass 3monocypher
-already.
-This interface is exposed only for completeness and to handle special
-situations
-(e.g. to use the hash function of the future winner of the NIST
-lightweight crypto competition on a device with highly constrained
-resources or taking advantage of hardware support for cryptographic
-hash functions).
-Whenever possible, these functions should be avoided.
-.Pp
-To make a custom hash algorithm available for use with these functions,
-a
-.Vt crypto_sign_vtable
-structure must be provided.
-It is defined as:
-.Bd -literal
-typedef struct {
-    void (*hash)(uint8_t hash[64], const uint8_t *message,
-                 size_t message_size);
-    void (*init  )(void *ctx);
-    void (*update)(void *ctx, const uint8_t *message,
-                   size_t message_size);
-    void (*final )(void *ctx, uint8_t hash[64]);
-    size_t ctx_size;
-} crypto_sign_vtable;
-.Ed
-.Pp
-The context argument to the functions shall be referred to as
-.Dq outer signing context .
-The outer signing context must contain a
-.Vt crypto_sign_ctx_abstract
-as
-.Em its first member .
-Other than that, the outer signing context may be defined freely.
-Logically, it is required to contain some kind of hash context as well;
-otherwise it cannot work as a custom hash function.
-.Pp
-Because the calling code cannot know the real type of the outer signing
-context,
-it is cast to
-.Vt void *
-when calling the hash functions in the vtable,
-but the
-.Fa ctx
-argument to the functions in the vtable is always guaranteed to be the
-outer signing context.
-.Pp
-The hash functions must not fail.
-If they somehow can fail,
-they have no way to propagate its error status,
-and thus the only ways to handle errors
-are to either assume an error never occurs (if reasonable)
-or to induce a crash in the code when an error occurs.
-.Pp
-The fields of
-.Vt crypto_sign_vtable
-are:
-.Bl -tag -width Ds
-.It Fa hash
-Function that computes a 64-byte hash for a given message
-and writes the computed hash to
-.Fa hash .
-The output length
-.Em must
-be exactly 64 bytes.
-This will normally be constructed using the functions that provide the
-.Fa init ,
-.Fa update ,
-and
-.Fa final
-members.
-.It Fa init
-Function that initialises the hash context of an outer signing context.
-.It Fa update
-Function that updates the hash context of an outer signing context.
-It must be able to handle message sizes of at least 32 bytes.
-.It Fa final
-Function that finalises the hash context of an outer signing context
-and writes the computed hash to
-.Fa hash .
-The output length
-.Em must
-be exactly 64 bytes.
-This function should wipe the hash context with
-.Xr crypto_wipe 3monocypher
-if it contains pointers to objects outside the outer signing context.
-Monocypher takes care of wiping the outer signing context.
-.It Fa ctx_size
-The size of the outer signing context as determined by
-.Fn sizeof .
-.El
-.Pp
-The functions indicated in the
-.Vt crypto_sign_vtable
-must be thread-safe if any of Monocypher's signing functions are
-accessed from multiple threads.
-.Pp
-After calling
-.Fn crypto_sign_init_first_pass_custom_hash
-or
-.Fn crypto_check_init_custom_hash ,
-the
-.Xr crypto_sign_update 3monocypher ,
-.Xr crypto_sign_final 3monocypher ,
-.Xr crypto_sign_init_second_pass 3monocypher ,
-.Xr crypto_check_update 3monocypher ,
-and
-.Xr crypto_check_final 3monocypher
-functions can be used as usual.
-They will call into the hash vtable as required.
-The same security considerations and semantics apply.
-.Sh RETURN VALUES
-These functions return nothing.
-.Sh EXAMPLES
-Defining and using a custom implementation of SHA-512 and crudely
-checking its results against
-.Xr crypto_ed25519_sign 3monocypher :
-.Bd -literal -offset indent
-struct outer_ctx {
-    crypto_sign_ctx_abstract sctx;
-    SHA2_CTX hash_ctx;
-};
-
-static void
-my_hash(uint8_t hash[64], const uint8_t *msg, size_t len)
-{
-    SHA2_CTX ctx;
-    SHA512Init(&ctx);
-    SHA512Update(&ctx, msg, len);
-    SHA512Final(hash, &ctx);
-}
-
-static void
-my_init(void *ctx)
-{
-    struct outer_ctx *octx = (struct outer_ctx *)ctx;
-    SHA512Init(&octx->hash_ctx);
-}
-
-static void
-my_update(void *ctx, const uint8_t *msg, size_t len)
-{
-    struct outer_ctx *octx = (struct outer_ctx *)ctx;
-    SHA512Update(&octx->hash_ctx, msg, len);
-}
-
-static void
-my_final(void *ctx, uint8_t *hash)
-{
-    struct outer_ctx *octx = (struct outer_ctx *)ctx;
-    SHA512Final(hash, &octx->hash_ctx);
-}
-
-static const crypto_sign_vtable my_vtable = {
-    my_hash,
-    my_init,
-    my_update,
-    my_final,
-    sizeof(struct outer_ctx)
-};
-
-int
-main(void)
-{
-    uint8_t theirs[64], mine[64];
-    uint8_t sk[32] = {0x01, 0x02, 0x03, 0x04};
-    const uint8_t msg[] = {
-        0x00, 0x01, 0x02, 0x04
-    };
-
-    crypto_ed25519_sign(theirs, sk, NULL, msg, sizeof(msg));
-
-    struct outer_ctx ctx;
-    crypto_sign_ctx_abstract *actx = (crypto_sign_ctx_abstract*)&ctx;
-    crypto_sign_init_first_pass_custom_hash(actx,
-                                            sk, NULL, &my_vtable);
-    crypto_wipe(sk, sizeof(sk));
-    crypto_sign_update(          actx, msg, sizeof(msg));
-    crypto_sign_init_second_pass(actx);
-    crypto_sign_update(          actx, msg, sizeof(msg));
-    crypto_sign_final(           actx, mine);
-
-    if (crypto_verify64(theirs, mine) != 0) {
-        fprintf(stderr, "theirs != mine\en");
-        return 1;
-    }
-    puts("ok");
-    return 0;
-}
-.Ed
-.Sh SEE ALSO
-.Xr crypto_blake2b 3monocypher ,
-.Xr crypto_sha512 3monocypher ,
-.Xr crypto_sign 3monocypher ,
-.Xr crypto_sign_init_first_pass 3monocypher ,
-.Xr crypto_wipe 3monocypher ,
-.Xr intro 3monocypher
-.Sh HISTORY
-The
-.Fn crypto_sign_init_first_pass_custom_hash ,
-.Fn crypto_sign_public_key_custom_hash ,
-and
-.Fn crypto_check_init_first_pass_custom_hash
-functions first appeared in Monocypher 3.0.0.
diff --git a/doc/man/man3/advanced/crypto_sign_init_second_pass.3monocypher b/doc/man/man3/advanced/crypto_sign_init_second_pass.3monocypher
deleted file mode 120000 (symlink)
index 08c255b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-crypto_sign_init_first_pass.3monocypher
\ No newline at end of file
diff --git a/doc/man/man3/advanced/crypto_sign_public_key_custom_hash.3monocypher b/doc/man/man3/advanced/crypto_sign_public_key_custom_hash.3monocypher
deleted file mode 120000 (symlink)
index a4b73ad..0000000
+++ /dev/null
@@ -1 +0,0 @@
-crypto_sign_init_first_pass_custom_hash.3monocypher
\ No newline at end of file
diff --git a/doc/man/man3/advanced/crypto_sign_update.3monocypher b/doc/man/man3/advanced/crypto_sign_update.3monocypher
deleted file mode 120000 (symlink)
index 08c255b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-crypto_sign_init_first_pass.3monocypher
\ No newline at end of file
index e6d4d1984f278313917ea216c31b5c0a16e8559c..6e8c219a0f993b5e8b4a4658543e7b5f86a33d55 100644 (file)
@@ -114,11 +114,6 @@ and
 implement EdDSA, with Curve25519 and BLAKE2b.
 This is the same as the more famous Ed25519, with SHA-512 replaced by
 the faster and more secure BLAKE2b.
-.Pp
-For highly specialised needs,
-it is possible to use a custom hash function with EdDSA;
-see
-.Xr crypto_sign_init_first_pass_custom_hash 3monocypher .
 .Ss Constant time comparison
 .Xr crypto_verify16 3monocypher ,
 .Xr crypto_verify32 3monocypher ,
@@ -153,10 +148,6 @@ and
 .Xr crypto_chacha20 3monocypher ,
 .Xr crypto_chacha20_ctr 3monocypher ,
 .Xr crypto_check 3monocypher ,
-.Xr crypto_check_final 3monocypher ,
-.Xr crypto_check_init 3monocypher ,
-.Xr crypto_check_init_custom_hash 3monocypher ,
-.Xr crypto_check_update 3monocypher ,
 .Xr crypto_curve_to_hidden 3monocypher ,
 .Xr crypto_from_eddsa_private 3monocypher ,
 .Xr crypto_from_eddsa_public 3monocypher ,
@@ -172,13 +163,7 @@ and
 .Xr crypto_poly1305_init 3monocypher ,
 .Xr crypto_poly1305_update 3monocypher ,
 .Xr crypto_sign 3monocypher ,
-.Xr crypto_sign_final 3monocypher ,
-.Xr crypto_sign_init_first_pass 3monocypher ,
-.Xr crypto_sign_init_first_pass_custom_hash 3monocypher ,
-.Xr crypto_sign_init_second_pass 3monocypher ,
 .Xr crypto_sign_public_key 3monocypher ,
-.Xr crypto_sign_public_key_custom_hash 3monocypher ,
-.Xr crypto_sign_update 3monocypher ,
 .Xr crypto_unlock 3monocypher ,
 .Xr crypto_unlock_aead 3monocypher ,
 .Xr crypto_verify16 3monocypher ,
@@ -196,14 +181,8 @@ and
 .Xr crypto_from_ed25519_private 3monocypher ,
 .Xr crypto_from_ed25519_public 3monocypher ,
 .Xr crypto_ed25519_check 3monocypher ,
-.Xr crypto_ed25519_check_init 3monocypher ,
-.Xr crypto_ed25519_check_update 3monocypher ,
-.Xr crypto_ed25519_check_final 3monocypher ,
 .Xr crypto_ed25519_public_key 3monocypher ,
 .Xr crypto_ed25519_sign 3monocypher ,
-.Xr crypto_ed25519_sign_init_first_pass 3monocypher ,
-.Xr crypto_ed25519_sign_init_second_pass 3monocypher ,
-.Xr crypto_ed25519_sign_final 3monocypher ,
 .Xr crypto_hmac_sha512 3monocypher ,
 .Xr crypto_hmac_sha512_init 3monocypher ,
 .Xr crypto_hmac_sha512_update 3monocypher ,
diff --git a/doc/man/man3/optional/crypto_ed25519_check_final.3monocypher b/doc/man/man3/optional/crypto_ed25519_check_final.3monocypher
deleted file mode 120000 (symlink)
index a2ccd03..0000000
+++ /dev/null
@@ -1 +0,0 @@
-crypto_ed25519_sign_init_first_pass.3monocypher
\ No newline at end of file
diff --git a/doc/man/man3/optional/crypto_ed25519_check_init.3monocypher b/doc/man/man3/optional/crypto_ed25519_check_init.3monocypher
deleted file mode 120000 (symlink)
index a2ccd03..0000000
+++ /dev/null
@@ -1 +0,0 @@
-crypto_ed25519_sign_init_first_pass.3monocypher
\ No newline at end of file
diff --git a/doc/man/man3/optional/crypto_ed25519_check_update.3monocypher b/doc/man/man3/optional/crypto_ed25519_check_update.3monocypher
deleted file mode 120000 (symlink)
index a2ccd03..0000000
+++ /dev/null
@@ -1 +0,0 @@
-crypto_ed25519_sign_init_first_pass.3monocypher
\ No newline at end of file
diff --git a/doc/man/man3/optional/crypto_ed25519_sign_final.3monocypher b/doc/man/man3/optional/crypto_ed25519_sign_final.3monocypher
deleted file mode 120000 (symlink)
index a2ccd03..0000000
+++ /dev/null
@@ -1 +0,0 @@
-crypto_ed25519_sign_init_first_pass.3monocypher
\ No newline at end of file
diff --git a/doc/man/man3/optional/crypto_ed25519_sign_init_first_pass.3monocypher b/doc/man/man3/optional/crypto_ed25519_sign_init_first_pass.3monocypher
deleted file mode 100644 (file)
index 61fd649..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-.\" This file is dual-licensed.  Choose whichever you want.
-.\"
-.\" The first licence is a regular 2-clause BSD licence.  The second licence
-.\" is the CC-0 from Creative Commons. It is intended to release Monocypher
-.\" to the public domain.  The BSD licence serves as a fallback option.
-.\"
-.\" SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
-.\"
-.\" ----------------------------------------------------------------------------
-.\"
-.\" Copyright (c) 2019-2020, 2022 Fabio Scotoni
-.\" All rights reserved.
-.\"
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions are
-.\" met:
-.\"
-.\" 1. Redistributions of source code must retain the above copyright
-.\"    notice, this list of conditions and the following disclaimer.
-.\"
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\"    notice, this list of conditions and the following disclaimer in the
-.\"    documentation and/or other materials provided with the
-.\"    distribution.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-.\" "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-.\" A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-.\" HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-.\" OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-.\"
-.\" ----------------------------------------------------------------------------
-.\"
-.\" Written in 2019-2020 and 2022 by Fabio Scotoni
-.\"
-.\" To the extent possible under law, the author(s) have dedicated all copyright
-.\" and related neighboring rights to this software to the public domain
-.\" worldwide.  This software is distributed without any warranty.
-.\"
-.\" You should have received a copy of the CC0 Public Domain Dedication along
-.\" with this software.  If not, see
-.\" <https://creativecommons.org/publicdomain/zero/1.0/>
-.\"
-.Dd February 13, 2022
-.Dt CRYPTO_ED25519_SIGN_INIT_FIRST_PASS 3MONOCYPHER
-.Os
-.Sh NAME
-.Nm crypto_ed25519_sign_init_first_pass ,
-.Nm crypto_ed25519_sign_update ,
-.Nm crypto_ed25519_sign_final ,
-.Nm crypto_ed25519_sign_init_second_pass ,
-.Nm crypto_ed25519_check_init ,
-.Nm crypto_ed25519_check_update ,
-.Nm crypto_ed25519_check_final
-.Nd incremental public key signatures
-.Sh SYNOPSIS
-.In monocypher-ed25519.h
-.Ft void
-.Fo crypto_ed25519_sign_init_first_pass
-.Fa "crypto_ed25519_sign_ctx *ctx"
-.Fa "const uint8_t secret_key[32]"
-.Fa "const uint8_t public_key[32]"
-.Fc
-.Ft void
-.Fo crypto_ed25519_sign_update
-.Fa "crypto_ed25519_sign_ctx *ctx"
-.Fa "const uint8_t *message"
-.Fa "size_t message_size"
-.Fc
-.Ft void
-.Fo crypto_ed25519_sign_final
-.Fa "crypto_ed25519_sign_ctx *ctx"
-.Fa "uint8_t signature[64]"
-.Fc
-.Ft void
-.Fo crypto_ed25519_sign_init_second_pass
-.Fa "crypto_ed25519_sign_ctx *ctx"
-.Fc
-.Ft void
-.Fo crypto_ed25519_check_init
-.Fa "crypto_ed25519_check_ctx *ctx"
-.Fa "const uint8_t signature[64]"
-.Fa "const uint8_t public_key[32]"
-.Fc
-.Ft void
-.Fo crypto_ed25519_check_update
-.Fa "crypto_ed25519_check_ctx *ctx"
-.Fa "const uint8_t *message"
-.Fa "size_t message_size"
-.Fc
-.Ft int
-.Fo crypto_ed25519_check_final
-.Fa "crypto_ed25519_check_ctx *ctx"
-.Fc
-.Sh DESCRIPTION
-These functions are variants of
-.Xr crypto_ed25519_sign 3monocypher
-and
-.Xr crypto_ed25519_check 3monocypher .
-Prefer those simpler functions if possible.
-.Pp
-These functions provide Ed25519 public key signatures and verification
-with SHA-512 as the underlying hash function.
-They are interoperable with other Ed25519 implementations.
-If you have no interoperability requirements, prefer
-.Xr crypto_sign 3monocypher .
-.Pp
-The arguments, security considerations, and semantics are the same as
-those described in
-.Xr crypto_sign_init_first_pass 3monocypher
-and
-.Xr crypto_sign 3monocypher .
-.Sh RETURN VALUES
-.Fn crypto_ed25519_sign_init_first_pass ,
-.Fn crypto_ed25519_sign_init_second_pass ,
-.Fn crypto_ed25519_sign_update ,
-.Fn crypto_ed25519_sign_final ,
-.Fn crypto_ed25519_check_init ,
-and
-.Fn crypto_ed25519_check_update
-return nothing.
-.Pp
-.Fn crypto_ed25519_check_final
-returns 0 for legitimate messages and -1 for forgeries.
-.Sh SEE ALSO
-.Xr crypto_blake2b 3monocypher ,
-.Xr crypto_x25519 3monocypher ,
-.Xr crypto_lock 3monocypher ,
-.Xr crypto_ed25519_sign 3monocypher ,
-.Xr crypto_sign 3monocypher ,
-.Xr crypto_sign_init_first_pass 3monocypher ,
-.Xr crypto_sha512 3monocypher ,
-.Xr crypto_wipe 3monocypher ,
-.Xr intro 3monocypher
-.Sh STANDARDS
-These functions implement Ed25519 as described in RFC 8032.
-.Sh HISTORY
-The
-.Fn crypto_ed25519_sign_init_first_pass ,
-.Fn crypto_ed25519_sign_update ,
-.Fn crypto_ed25519_sign_final ,
-.Fn crypto_ed25519_sign_init_second_pass ,
-.Fn crypto_ed25519_check_init ,
-.Fn crypto_ed25519_check_update ,
-and
-.Fn crypto_ed25519_check_final
-functions first appeared in Monocypher 3.0.0.
-They replace recompilation of Monocypher with the
-.Dv ED25519_SHA512
-preprocessor definition.
diff --git a/doc/man/man3/optional/crypto_ed25519_sign_init_second_pass.3monocypher b/doc/man/man3/optional/crypto_ed25519_sign_init_second_pass.3monocypher
deleted file mode 120000 (symlink)
index a2ccd03..0000000
+++ /dev/null
@@ -1 +0,0 @@
-crypto_ed25519_sign_init_first_pass.3monocypher
\ No newline at end of file
diff --git a/doc/man/man3/optional/crypto_ed25519_sign_update.3monocypher b/doc/man/man3/optional/crypto_ed25519_sign_update.3monocypher
deleted file mode 120000 (symlink)
index a2ccd03..0000000
+++ /dev/null
@@ -1 +0,0 @@
-crypto_ed25519_sign_init_first_pass.3monocypher
\ No newline at end of file
index 1b7d82734c194acb3f512a057ac156121806abd1..2869c38f44a68112e24653361eca09412aa06ee8 100644 (file)
@@ -637,23 +637,6 @@ void crypto_blake2b(u8 hash[64], const u8 *message, size_t message_size)
        crypto_blake2b_general(hash, 64, 0, 0, message, message_size);
 }
 
-static void blake2b_vtable_init(void *ctx) {
-       crypto_blake2b_init(&((crypto_sign_ctx*)ctx)->hash);
-}
-static void blake2b_vtable_update(void *ctx, const u8 *m, size_t s) {
-       crypto_blake2b_update(&((crypto_sign_ctx*)ctx)->hash, m, s);
-}
-static void blake2b_vtable_final(void *ctx, u8 *h) {
-       crypto_blake2b_final(&((crypto_sign_ctx*)ctx)->hash, h);
-}
-const crypto_sign_vtable crypto_blake2b_vtable = {
-       crypto_blake2b,
-       blake2b_vtable_init,
-       blake2b_vtable_update,
-       blake2b_vtable_final,
-       sizeof(crypto_sign_ctx),
-};
-
 ////////////////
 /// Argon2 i ///
 ////////////////
@@ -1517,11 +1500,12 @@ static void fe_invert(fe out, const fe x)
 }
 
 // trim a scalar for scalar multiplication
-static void trim_scalar(u8 scalar[32])
+void crypto_eddsa_trim_scalar(u8 out[32], const u8 in[32])
 {
-       scalar[ 0] &= 248;
-       scalar[31] &= 127;
-       scalar[31] |= 64;
+       COPY(out, in, 32);
+       out[ 0] &= 248;
+       out[31] &= 127;
+       out[31] |= 64;
 }
 
 // get bit from scalar at position i
@@ -1599,8 +1583,7 @@ void crypto_x25519(u8       raw_shared_secret[32],
 {
        // restrict the possible scalar values
        u8 e[32];
-       COPY(e, your_secret_key, 32);
-       trim_scalar(e);
+       crypto_eddsa_trim_scalar(e, your_secret_key);
        scalarmult(raw_shared_secret, e, their_public_key, 255);
        WIPE_BUFFER(e);
 }
@@ -1706,16 +1689,17 @@ static void mod_l(u8 reduced[32], const u32 x[16])
        WIPE_BUFFER(xr);
 }
 
-static void reduce(u8 r[64])
+void crypto_eddsa_reduce(u8 reduced[32], const u8 expanded[64])
 {
        u32 x[16];
-       load32_le_buf(x, r, 16);
-       mod_l(r, x);
+       load32_le_buf(x, expanded, 16);
+       mod_l(reduced, x);
        WIPE_BUFFER(x);
 }
 
 // r = (a * b) + c
-static void mul_add(u8 r[32], const u8 a[32], const u8 b[32], const u8 c[32])
+void crypto_eddsa_mul_add(u8 r[32],
+                          const u8 a[32], const u8 b[32], const u8 c[32])
 {
        u32 A[8];  load32_le_buf(A, a, 8);
        u32 B[8];  load32_le_buf(B, b, 8);
@@ -2195,7 +2179,7 @@ static void ge_scalarmult_base(ge *p, const u8 scalar[32])
 
        // All bits set form: 1 means 1, 0 means -1
        u8 s_scalar[32];
-       mul_add(s_scalar, scalar, half_mod_L, half_ones);
+       crypto_eddsa_mul_add(s_scalar, scalar, half_mod_L, half_ones);
 
        // Double and add ladder
        fe tmp_a, tmp_b;  // temporaries for addition
@@ -2226,41 +2210,66 @@ static void ge_scalarmult_base(ge *p, const u8 scalar[32])
        WIPE_BUFFER(s_scalar);
 }
 
-void crypto_sign_public_key_custom_hash(u8       public_key[32],
-                                        const u8 secret_key[32],
-                                        const crypto_sign_vtable *hash)
+void crypto_eddsa_scalarbase(u8 point[32], const u8 scalar[32])
+{
+       ge P;
+       ge_scalarmult_base(&P, scalar);
+       ge_tobytes(point, &P);
+       WIPE_CTX(&P);
+}
+
+int crypto_eddsa_r_check(u8 r_check[32], const u8 public_key[32],
+                         const u8 h_ram[32], const u8 s[32])
 {
-       u8 a[64];
-       hash->hash(a, secret_key, 32);
-       trim_scalar(a);
        ge A;
-       ge_scalarmult_base(&A, a);
-       ge_tobytes(public_key, &A);
-       WIPE_BUFFER(a);
-       WIPE_CTX(&A);
+       u32 s32[8];                                      // s (different encoding)
+       load32_le_buf(s32, s, 8);
+
+       if (ge_frombytes_neg_vartime(&A, public_key) ||  // A = -pk
+           is_above_l(s32)) {                           // prevent s malleability
+               return -1;
+       }
+       ge_double_scalarmult_vartime(&A, h_ram, s);      // A = [s]B - [h_ram]pk
+       ge_tobytes(r_check, &A);                         // r_check = A
+       return 0;
 }
 
 void crypto_sign_public_key(u8 public_key[32], const u8 secret_key[32])
 {
-       crypto_sign_public_key_custom_hash(public_key, secret_key,
-                                          &crypto_blake2b_vtable);
+       u8 a[64];
+       crypto_blake2b(a, secret_key, 32);
+       crypto_eddsa_trim_scalar(a, a);
+       crypto_eddsa_scalarbase(public_key, a);
 }
 
-void crypto_sign_init_first_pass_custom_hash(crypto_sign_ctx_abstract *ctx,
-                                             const u8 secret_key[32],
-                                             const u8 public_key[32],
-                                             const crypto_sign_vtable *hash)
+static void hash_reduce(u8 h[32],
+                        const u8 *a, size_t a_size,
+                        const u8 *b, size_t b_size,
+                        const u8 *c, size_t c_size)
 {
-       ctx->hash  = hash; // set vtable
-       u8 *a      = ctx->buf;
-       u8 *prefix = ctx->buf + 32;
-       ctx->hash->hash(a, secret_key, 32);
-       trim_scalar(a);
+       u8 hash[64];
+       crypto_blake2b_ctx ctx;
+       crypto_blake2b_init  (&ctx);
+       crypto_blake2b_update(&ctx, a, a_size);
+       crypto_blake2b_update(&ctx, b, b_size);
+       crypto_blake2b_update(&ctx, c, c_size);
+       crypto_blake2b_final (&ctx, hash);
+       crypto_eddsa_reduce(h, hash);
+}
 
+void crypto_sign(u8        signature[64],
+                 const u8  secret_key[32],
+                 const u8  public_key[32],
+                 const u8 *message, size_t message_size)
+{
+       u8 a[64];
+       crypto_blake2b(a, secret_key, 32);
+       crypto_eddsa_trim_scalar(a, a);
+       u8 pk[32];  // not secret, not wiped
        if (public_key == 0) {
-               crypto_sign_public_key_custom_hash(ctx->pk, secret_key, ctx->hash);
+               crypto_eddsa_scalarbase(pk, a);
        } else {
-               COPY(ctx->pk, public_key, 32);
+               COPY(pk, public_key, 32);
        }
 
        // Deterministic part of EdDSA: Construct a nonce by hashing the message
@@ -2268,125 +2277,34 @@ void crypto_sign_init_first_pass_custom_hash(crypto_sign_ctx_abstract *ctx,
        // An actual random number would work just fine, and would save us
        // the trouble of hashing the message twice.  If we did that
        // however, the user could fuck it up and reuse the nonce.
-       ctx->hash->init  (ctx);
-       ctx->hash->update(ctx, prefix , 32);
-}
+       u8 r[32];
+       hash_reduce(r, a + 32, 32, message, message_size, 0, 0);
 
-void crypto_sign_init_first_pass(crypto_sign_ctx_abstract *ctx,
-                                 const u8 secret_key[32],
-                                 const u8 public_key[32])
-{
-       crypto_sign_init_first_pass_custom_hash(ctx, secret_key, public_key,
-                                               &crypto_blake2b_vtable);
-}
+       // First half of the signature R = [r]B
+       u8 R[32];  // Not secret, not wiped
+       crypto_eddsa_scalarbase(R, r);
 
-void crypto_sign_update(crypto_sign_ctx_abstract *ctx,
-                        const u8 *msg, size_t msg_size)
-{
-       ctx->hash->update(ctx, msg, msg_size);
-}
+       // Second half of the signature
+       u8 h_ram[32];
+       hash_reduce(h_ram, R, 32, pk, 32, message, message_size);
+       COPY(signature, R, 32);
+       crypto_eddsa_mul_add(signature + 32, h_ram, a, r); // s = h_ram * a + r
 
-void crypto_sign_init_second_pass(crypto_sign_ctx_abstract *ctx)
-{
-       u8 *r        = ctx->buf + 32;
-       u8 *half_sig = ctx->buf + 64;
-       ctx->hash->final(ctx, r);
-       reduce(r);
-
-       // first half of the signature = "random" nonce times the base point
-       ge R;
-       ge_scalarmult_base(&R, r);
-       ge_tobytes(half_sig, &R);
-       WIPE_CTX(&R);
-
-       // Hash R, the public key, and the message together.
-       // It cannot be done in parallel with the first hash.
-       ctx->hash->init  (ctx);
-       ctx->hash->update(ctx, half_sig, 32);
-       ctx->hash->update(ctx, ctx->pk , 32);
-}
-
-void crypto_sign_final(crypto_sign_ctx_abstract *ctx, u8 signature[64])
-{
-       u8 *a        = ctx->buf;
-       u8 *r        = ctx->buf + 32;
-       u8 *half_sig = ctx->buf + 64;
-       u8  h_ram[64];
-       ctx->hash->final(ctx, h_ram);
-       reduce(h_ram);
-       COPY(signature, half_sig, 32);
-       mul_add(signature + 32, h_ram, a, r); // s = h_ram * a + r
+       WIPE_BUFFER(a);
+       WIPE_BUFFER(r);
        WIPE_BUFFER(h_ram);
-       crypto_wipe(ctx, ctx->hash->ctx_size);
 }
 
-void crypto_sign(u8        signature[64],
-                 const u8  secret_key[32],
-                 const u8  public_key[32],
+int crypto_check(const u8  signature[64], const u8 public_key[32],
                  const u8 *message, size_t message_size)
 {
-       crypto_sign_ctx ctx;
-       crypto_sign_ctx_abstract *actx = (crypto_sign_ctx_abstract*)&ctx;
-       crypto_sign_init_first_pass (actx, secret_key, public_key);
-       crypto_sign_update          (actx, message, message_size);
-       crypto_sign_init_second_pass(actx);
-       crypto_sign_update          (actx, message, message_size);
-       crypto_sign_final           (actx, signature);
-}
-
-void crypto_check_init_custom_hash(crypto_check_ctx_abstract *ctx,
-                                   const u8 signature[64],
-                                   const u8 public_key[32],
-                                   const crypto_sign_vtable *hash)
-{
-       ctx->hash = hash; // set vtable
-       COPY(ctx->buf, signature , 64);
-       COPY(ctx->pk , public_key, 32);
-       ctx->hash->init  (ctx);
-       ctx->hash->update(ctx, signature , 32);
-       ctx->hash->update(ctx, public_key, 32);
-}
-
-void crypto_check_init(crypto_check_ctx_abstract *ctx, const u8 signature[64],
-                       const u8 public_key[32])
-{
-       crypto_check_init_custom_hash(ctx, signature, public_key,
-                                     &crypto_blake2b_vtable);
-}
-
-void crypto_check_update(crypto_check_ctx_abstract *ctx,
-                         const u8 *msg, size_t msg_size)
-{
-       ctx->hash->update(ctx, msg, msg_size);
-}
-
-int crypto_check_final(crypto_check_ctx_abstract *ctx)
-{
-       u8 *s = ctx->buf + 32; // s
-       u8  h_ram[64];
-       u32 s32[8];            // s (different encoding)
-       ge  A;
-
-       ctx->hash->final(ctx, h_ram);
-       reduce(h_ram);
-       load32_le_buf(s32, s, 8);
-       if (ge_frombytes_neg_vartime(&A, ctx->pk) ||  // A = -pk
-           is_above_l(s32)) {                        // prevent s malleability
+       u8 h_ram  [32];
+       u8 r_check[32];
+       hash_reduce(h_ram, signature, 32, public_key, 32, message, message_size);
+       if (crypto_eddsa_r_check(r_check, public_key, h_ram, signature + 32)) {
                return -1;
        }
-       ge_double_scalarmult_vartime(&A, h_ram, s);   // A = [s]B - [h_ram]pk
-       ge_tobytes(ctx->pk, &A);                      // R_check = A
-       return crypto_verify32(ctx->buf, ctx->pk);    // R == R_check ? OK : fail
-}
-
-int crypto_check(const u8  signature[64], const u8 public_key[32],
-                 const u8 *message, size_t message_size)
-{
-       crypto_check_ctx ctx;
-       crypto_check_ctx_abstract *actx = (crypto_check_ctx_abstract*)&ctx;
-       crypto_check_init  (actx, signature, public_key);
-       crypto_check_update(actx, message, message_size);
-       return crypto_check_final(actx);
+       return crypto_verify32(r_check, signature);  // R == R_check ? OK : fail
 }
 
 ///////////////////////
@@ -2501,8 +2419,7 @@ void crypto_x25519_dirty_small(u8 public_key[32], const u8 secret_key[32])
        };
        // separate the main factor & the cofactor of the scalar
        u8 scalar[32];
-       COPY(scalar, secret_key, 32);
-       trim_scalar(scalar);
+       crypto_eddsa_trim_scalar(scalar, secret_key);
 
        // Separate the main factor and the cofactor
        //
@@ -2572,8 +2489,7 @@ void crypto_x25519_dirty_fast(u8 public_key[32], const u8 secret_key[32])
        // Compute clean scalar multiplication
        u8 scalar[32];
        ge pk;
-       COPY(scalar, secret_key, 32);
-       trim_scalar(scalar);
+       crypto_eddsa_trim_scalar(scalar, secret_key);
        ge_scalarmult_base(&pk, scalar);
 
        // Compute low order point
@@ -2856,8 +2772,7 @@ void crypto_x25519_inverse(u8 blind_salt [32], const u8 private_key[32],
                0xfffffffe, 0xffffffff, 0xffffffff, 0x0fffffff,};
 
        u8 scalar[32];
-       COPY(scalar, private_key, 32);
-       trim_scalar(scalar);
+       crypto_eddsa_trim_scalar(scalar, private_key);
 
        // Convert the scalar in Montgomery form
        // m_scl = scalar * 2^256 (modulo L)
index f8fd07051c61e3f343988d94de525c4fffd589f7..1fa9bce19ff0c3123e984a1af7a74280b956bd5e 100644 (file)
@@ -67,17 +67,6 @@ extern "C" {
 /// Type definitions ///
 ////////////////////////
 
-// Vtable for EdDSA with a custom hash.
-// Instantiate it to define a custom hash.
-// Its size, contents, and layout, are part of the public API.
-typedef struct {
-       void (*hash)(uint8_t hash[64], const uint8_t *message, size_t message_size);
-       void (*init  )(void *ctx);
-       void (*update)(void *ctx, const uint8_t *message, size_t message_size);
-       void (*final )(void *ctx, uint8_t hash[64]);
-       size_t ctx_size;
-} crypto_sign_vtable;
-
 // Do not rely on the size or contents of any of the types below,
 // they may change without notice.
 
@@ -99,20 +88,6 @@ typedef struct {
        size_t   hash_size;
 } crypto_blake2b_ctx;
 
-// Signatures (EdDSA)
-typedef struct {
-       const crypto_sign_vtable *hash;
-       uint8_t buf[96];
-       uint8_t pk [32];
-} crypto_sign_ctx_abstract;
-typedef crypto_sign_ctx_abstract crypto_check_ctx_abstract;
-
-typedef struct {
-       crypto_sign_ctx_abstract ctx;
-       crypto_blake2b_ctx       hash;
-} crypto_sign_ctx;
-typedef crypto_sign_ctx crypto_check_ctx;
-
 ////////////////////////////
 /// High level interface ///
 ////////////////////////////
@@ -180,9 +155,6 @@ void crypto_blake2b_final (crypto_blake2b_ctx *ctx, uint8_t *hash);
 void crypto_blake2b_general_init(crypto_blake2b_ctx *ctx, size_t hash_size,
                                  const uint8_t      *key, size_t key_size);
 
-// vtable for signatures
-extern const crypto_sign_vtable crypto_blake2b_vtable;
-
 
 // Password key derivation (Argon2 i)
 // ----------------------------------
@@ -319,6 +291,19 @@ void crypto_x25519_inverse(uint8_t       blind_salt [32],
                            const uint8_t private_key[32],
                            const uint8_t curve_point[32]);
 
+// EdDSA
+// -----
+void crypto_eddsa_trim_scalar(uint8_t out[32], const uint8_t in[32]);
+void crypto_eddsa_reduce(uint8_t reduced[32], const uint8_t expanded[64]);
+void crypto_eddsa_mul_add(uint8_t r[32],
+                          const uint8_t a[32],
+                                                 const uint8_t b[32],
+                                                 const uint8_t c[32]);
+void crypto_eddsa_scalarbase(uint8_t point[32], const uint8_t scalar[32]);
+int crypto_eddsa_r_check(uint8_t r_check[32],
+                                                const uint8_t public_key[32],
+                         const uint8_t h_ram[32],
+                                                const uint8_t s[32]);
 
 // EdDSA to X25519
 // ---------------
@@ -326,44 +311,6 @@ void crypto_from_eddsa_private(uint8_t x25519[32], const uint8_t eddsa[32]);
 void crypto_from_eddsa_public (uint8_t x25519[32], const uint8_t eddsa[32]);
 
 
-// EdDSA -- Incremental interface
-// ------------------------------
-
-// Signing (2 passes)
-// Make sure the two passes hash the same message,
-// else you might reveal the private key.
-void crypto_sign_init_first_pass(crypto_sign_ctx_abstract *ctx,
-                                 const uint8_t  secret_key[32],
-                                 const uint8_t  public_key[32]);
-void crypto_sign_update(crypto_sign_ctx_abstract *ctx,
-                        const uint8_t *message, size_t message_size);
-void crypto_sign_init_second_pass(crypto_sign_ctx_abstract *ctx);
-// use crypto_sign_update() again.
-void crypto_sign_final(crypto_sign_ctx_abstract *ctx, uint8_t signature[64]);
-
-// Verification (1 pass)
-// Make sure you don't use (parts of) the message
-// before you're done checking it.
-void crypto_check_init  (crypto_check_ctx_abstract *ctx,
-                         const uint8_t signature[64],
-                         const uint8_t public_key[32]);
-void crypto_check_update(crypto_check_ctx_abstract *ctx,
-                         const uint8_t *message, size_t message_size);
-int crypto_check_final  (crypto_check_ctx_abstract *ctx);
-
-// Custom hash interface
-void crypto_sign_public_key_custom_hash(uint8_t       public_key[32],
-                                        const uint8_t secret_key[32],
-                                        const crypto_sign_vtable *hash);
-void crypto_sign_init_first_pass_custom_hash(crypto_sign_ctx_abstract *ctx,
-                                             const uint8_t secret_key[32],
-                                             const uint8_t public_key[32],
-                                             const crypto_sign_vtable *hash);
-void crypto_check_init_custom_hash(crypto_check_ctx_abstract *ctx,
-                                   const uint8_t signature[64],
-                                   const uint8_t public_key[32],
-                                   const crypto_sign_vtable *hash);
-
 // Elligator 2
 // -----------
 
index 446553babc930873227daf832d6e82f85a53306b..7230e47835221e354a57b26fd167dcb190419942 100644 (file)
@@ -283,23 +283,6 @@ void crypto_sha512(u8 hash[64], const u8 *message, size_t message_size)
        crypto_sha512_final (&ctx, hash);
 }
 
-static void sha512_vtable_init(void *ctx) {
-       crypto_sha512_init(&((crypto_sign_ed25519_ctx*)ctx)->hash);
-}
-static void sha512_vtable_update(void *ctx, const u8 *m, size_t s) {
-       crypto_sha512_update(&((crypto_sign_ed25519_ctx*)ctx)->hash, m, s);
-}
-static void sha512_vtable_final(void *ctx, u8 *h) {
-       crypto_sha512_final(&((crypto_sign_ed25519_ctx*)ctx)->hash, h);
-}
-const crypto_sign_vtable crypto_sha512_vtable = {
-       crypto_sha512,
-       sha512_vtable_init,
-       sha512_vtable_update,
-       sha512_vtable_final,
-       sizeof(crypto_sign_ed25519_ctx),
-};
-
 ////////////////////
 /// HMAC SHA 512 ///
 ////////////////////
@@ -355,28 +338,27 @@ void crypto_hmac_sha512(u8 hmac[64], const u8 *key, size_t key_size,
 ///////////////
 /// Ed25519 ///
 ///////////////
-
-void crypto_ed25519_public_key(u8       public_key[32],
-                               const u8 secret_key[32])
+void crypto_ed25519_public_key(u8 public_key[32], const u8 secret_key[32])
 {
-       crypto_sign_public_key_custom_hash(public_key, secret_key,
-                                          &crypto_sha512_vtable);
-}
-
-void crypto_ed25519_sign_init_first_pass(crypto_sign_ctx_abstract *ctx,
-                                         const u8 secret_key[32],
-                                         const u8 public_key[32])
-{
-       crypto_sign_init_first_pass_custom_hash(ctx, secret_key, public_key,
-                                               &crypto_sha512_vtable);
+       u8 a[64];
+       crypto_sha512(a, secret_key, 32);
+       crypto_eddsa_trim_scalar(a, a);
+       crypto_eddsa_scalarbase(public_key, a);
 }
 
-void crypto_ed25519_check_init(crypto_check_ctx_abstract *ctx,
-                               const u8 signature[64],
-                               const u8 public_key[32])
+static void hash_reduce(u8 h[32],
+                        const u8 *a, size_t a_size,
+                        const u8 *b, size_t b_size,
+                        const u8 *c, size_t c_size)
 {
-       crypto_check_init_custom_hash(ctx, signature, public_key,
-                                     &crypto_sha512_vtable);
+       u8 hash[64];
+       crypto_sha512_ctx ctx;
+       crypto_sha512_init  (&ctx);
+       crypto_sha512_update(&ctx, a, a_size);
+       crypto_sha512_update(&ctx, b, b_size);
+       crypto_sha512_update(&ctx, c, c_size);
+       crypto_sha512_final (&ctx, hash);
+       crypto_eddsa_reduce(h, hash);
 }
 
 void crypto_ed25519_sign(u8        signature [64],
@@ -384,24 +366,50 @@ void crypto_ed25519_sign(u8        signature [64],
                          const u8  public_key[32],
                          const u8 *message, size_t message_size)
 {
-       crypto_sign_ed25519_ctx ctx;
-       crypto_sign_ctx_abstract *actx = (crypto_sign_ctx_abstract*)&ctx;
-       crypto_ed25519_sign_init_first_pass (actx, secret_key, public_key);
-       crypto_ed25519_sign_update          (actx, message, message_size);
-       crypto_ed25519_sign_init_second_pass(actx);
-       crypto_ed25519_sign_update          (actx, message, message_size);
-       crypto_ed25519_sign_final           (actx, signature);
+       u8 a[64];
+       crypto_sha512(a, secret_key, 32);
+       crypto_eddsa_trim_scalar(a, a);
+       u8 pk[32];  // not secret, not wiped
+       if (public_key == 0) {
+               crypto_eddsa_scalarbase(pk, a);
+       } else {
+               COPY(pk, public_key, 32);
+       }
+
+       // Deterministic part of EdDSA: Construct a nonce by hashing the message
+       // instead of generating a random number.
+       // An actual random number would work just fine, and would save us
+       // the trouble of hashing the message twice.  If we did that
+       // however, the user could fuck it up and reuse the nonce.
+       u8 r[32];
+       hash_reduce(r, a + 32, 32, message, message_size, 0, 0);
+
+       // First half of the signature R = [r]B
+       u8 R[32];  // Not secret, not wiped
+       crypto_eddsa_scalarbase(R, r);
+
+       // Second half of the signature
+       u8 h_ram[32];
+       hash_reduce(h_ram, R, 32, pk, 32, message, message_size);
+       COPY(signature, R, 32);
+       crypto_eddsa_mul_add(signature + 32, h_ram, a, r); // s = h_ram * a + r
+
+       WIPE_BUFFER(a);
+       WIPE_BUFFER(r);
+       WIPE_BUFFER(h_ram);
 }
 
 int crypto_ed25519_check(const u8  signature [64],
                          const u8  public_key[32],
                          const u8 *message, size_t message_size)
 {
-       crypto_check_ed25519_ctx ctx;
-       crypto_check_ctx_abstract *actx = (crypto_check_ctx_abstract*)&ctx;
-       crypto_ed25519_check_init  (actx, signature, public_key);
-       crypto_ed25519_check_update(actx, message, message_size);
-       return crypto_ed25519_check_final(actx);
+       u8 h_ram  [32];
+       u8 r_check[32];
+       hash_reduce(h_ram, signature, 32, public_key, 32, message, message_size);
+       if (crypto_eddsa_r_check(r_check, public_key, h_ram, signature + 32)) {
+               return -1;
+       }
+       return crypto_verify32(r_check, signature);  // R == R_check ? OK : fail
 }
 
 void crypto_from_ed25519_private(u8 x25519[32], const u8 eddsa[32])
index 07ef9be8693425589edecdd98736ccf99f9410af..8ee14e179801f5004c1ad2497cce47d936e22798 100644 (file)
@@ -80,11 +80,6 @@ typedef struct {
        crypto_sha512_ctx ctx;
 } crypto_hmac_sha512_ctx;
 
-typedef struct {
-       crypto_sign_ctx_abstract ctx;
-       crypto_sha512_ctx        hash;
-} crypto_sign_ed25519_ctx;
-typedef crypto_sign_ed25519_ctx crypto_check_ed25519_ctx;
 
 // SHA 512
 // -------
@@ -95,9 +90,6 @@ void crypto_sha512_final (crypto_sha512_ctx *ctx, uint8_t hash[64]);
 void crypto_sha512(uint8_t hash[64],
                    const uint8_t *message, size_t message_size);
 
-// vtable for signatures
-extern const crypto_sign_vtable crypto_sha512_vtable;
-
 
 // HMAC SHA 512
 // ------------
@@ -114,11 +106,9 @@ void crypto_hmac_sha512(uint8_t hmac[64],
 // Ed25519
 // -------
 
-// Generate public key
 void crypto_ed25519_public_key(uint8_t       public_key[32],
                                const uint8_t secret_key[32]);
 
-// Direct interface
 void crypto_ed25519_sign(uint8_t        signature [64],
                          const uint8_t  secret_key[32],
                          const uint8_t  public_key[32], // optional, may be 0
@@ -127,21 +117,6 @@ int crypto_ed25519_check(const uint8_t  signature [64],
                          const uint8_t  public_key[32],
                          const uint8_t *message, size_t message_size);
 
-// Incremental interface
-void crypto_ed25519_sign_init_first_pass(crypto_sign_ctx_abstract *ctx,
-                                         const uint8_t secret_key[32],
-                                         const uint8_t public_key[32]);
-#define crypto_ed25519_sign_update crypto_sign_update
-#define crypto_ed25519_sign_init_second_pass crypto_sign_init_second_pass
-// use crypto_ed25519_sign_update() again.
-#define crypto_ed25519_sign_final crypto_sign_final
-
-void crypto_ed25519_check_init(crypto_check_ctx_abstract *ctx,
-                               const uint8_t signature[64],
-                               const uint8_t public_key[32]);
-#define crypto_ed25519_check_update crypto_check_update
-#define crypto_ed25519_check_final crypto_check_final
-
 void crypto_from_ed25519_private(uint8_t x25519[32], const uint8_t eddsa[32]);
 #define crypto_from_ed25519_public crypto_from_eddsa_public
 
index 3d4d7a16420850b32812841b952485454f0082fd..4606c886a18412c316bc1b327cb97a4e66ce2f77 100644 (file)
@@ -635,7 +635,7 @@ static int p_hmac_sha512()
        return status;
 }
 
-// Tests that the input and output buffers of crypto_sha_512 can overlap.
+// Tests that the input and output buffers of HMAC can overlap.
 static int p_hmac_sha512_overlap()
 {
 #undef INPUT_SIZE
@@ -812,41 +812,6 @@ static int p_eddsa_overlap()
        return status;
 }
 
-static int p_eddsa_incremental()
-{
-       int status = 0;
-       FOR (i, 0, MESSAGE_SIZE) {
-               RANDOM_INPUT(msg, MESSAGE_SIZE);
-               RANDOM_INPUT(sk, 32);
-               u8 pk      [32];  crypto_sign_public_key(pk, sk);
-               u8 sig_mono[64];  crypto_sign(sig_mono, sk, pk, msg, MESSAGE_SIZE);
-               u8 sig_incr[64];
-               {
-                       crypto_sign_ctx ctx;
-                       crypto_sign_ctx_abstract *actx = (crypto_sign_ctx_abstract*)&ctx;
-                       crypto_sign_init_first_pass (actx, sk, pk);
-                       crypto_sign_update          (actx, msg  , i);
-                       crypto_sign_update          (actx, msg+i, MESSAGE_SIZE-i);
-                       crypto_sign_init_second_pass(actx);
-                       crypto_sign_update          (actx, msg  , i);
-                       crypto_sign_update          (actx, msg+i, MESSAGE_SIZE-i);
-                       crypto_sign_final           (actx, sig_incr);
-               }
-               status |= memcmp(sig_mono, sig_incr, 64);
-               status |= crypto_check(sig_mono, pk, msg, MESSAGE_SIZE);
-               {
-                       crypto_check_ctx ctx;
-                       crypto_check_ctx_abstract *actx = (crypto_check_ctx_abstract*)&ctx;
-                       crypto_check_init  (actx, sig_incr, pk);
-                       crypto_check_update(actx, msg  , i);
-                       crypto_check_update(actx, msg+i, MESSAGE_SIZE-i);
-                       status |= crypto_check_final(actx);
-               }
-       }
-       printf("%s: EdDSA (incremental)\n", status != 0 ? "FAILED" : "OK");
-       return status;
-}
-
 static int p_aead()
 {
        int status = 0;
@@ -1182,7 +1147,6 @@ int main(int argc, char *argv[])
        status |= p_eddsa_roundtrip();
        status |= p_eddsa_random();
        status |= p_eddsa_overlap();
-       status |= p_eddsa_incremental();
        status |= p_aead();
        status |= p_elligator_direct_msb();
        status |= p_elligator_direct_overlap();