Fixes#6277
Description:
Make each of the five EdDSA instances defined in RFC 8032 -- Ed25519,
Ed25519ctx, Ed25519ph, Ed448, Ed448ph -- available via the EVP APIs.
The desired EdDSA instance is specified via an OSSL_PARAM.
All instances, except for Ed25519, allow context strings as input.
Context strings are passed via an OSSL_PARAM. For Ed25519ctx, the
context string must be nonempty.
Ed25519, Ed25519ctx, Ed448 are PureEdDSA instances, which means that
the full message (not a digest) must be passed to sign and verify
operations.
Ed25519ph, Ed448ph are HashEdDSA instances, which means that the input
message is hashed before sign and verify.
Testing:
All 21 test vectors from RFC 8032 have been added to evppkey_ecx.txt
(thanks to Shane Lontis for showing how to do that). Those 21 test
vectors are exercised by evp_test.c and cover all five instances.
Reviewed-by: Hugo Landau <hlandau@openssl.org>
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/19705)
Description:
Mark Wooden and Franck Rondepierre noted that the square-root-mod-p
operations used in the EdDSA RFC (RFC 8032) can be simplified. For
Ed25519, instead of computing u*v^3 * (u * v^7)^((p-5)/8), we can
compute u * (u*v)^((p-5)/8). This saves 3 multiplications and 2
squarings. For more details (including a proof), see the following
message from the CFRG mailing list:
https://mailarchive.ietf.org/arch/msg/cfrg/qlKpMBqxXZYmDpXXIx6LO3Oznv4/
Note that the Ed448 implementation (see
ossl_curve448_point_decode_like_eddsa_and_mul_by_ratio() in
./crypto/ec/curve448/curve448.c) appears to already use this simpler
method (i.e. it does not follow the method suggested in RFC 8032).
Testing:
Build and then run the test suite:
./Configure -Werror --strict-warnings
make update
make
make test
Numerical testing of the square-root computation can be done using the
following sage script:
def legendre(x,p):
return kronecker(x,p)
# Ed25519
p = 2**255-19
# -1 is a square
if legendre(-1,p)==1:
print("-1 is a square")
# suppose u/v is a square.
# to compute one of its square roots, find x such that
# x**4 == (u/v)**2 .
# this implies
# x**2 == u/v, or
# x**2 == -(u/v) ,
# which implies either x or i*x is a square-root of u/v (where i is a square root of -1).
# we can take x equal to u * (u*v)**((p-5)/8).
# 2 is a generator
# this can be checked by factoring p-1
# and then showing 2**((p-1)/q) != 1 (mod p)
# for all primes q dividing p-1.
g = 2
s = p>>2 # s = (p-1)/4
i = power_mod(g, s, p)
t = p>>3 # t = (p-5)/8
COUNT = 1<<18
while COUNT > 0:
COUNT -= 1
r = randint(0,p-1) # r = u/v
v = randint(1,p-1)
u = mod(r*v,p)
# compute x = u * (u*v)**((p-5)/8)
w = mod(u*v,p)
x = mod(u*power_mod(w, t, p), p)
# check that x**2 == r, or (i*x)**2 == r, or r is not a square
rr = power_mod(x, 2, p)
if rr==r:
continue
rr = power_mod(mod(i*x,p), 2, p)
if rr==r:
continue
if legendre(r,p) != 1:
continue
print("failure!")
exit()
print("passed!")
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/17544)
Signed-off-by: Amitay Isaacs <amitay@ozlabs.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14784)
Many of the new types introduced by OpenSSL 3.0 have an OSSL_ prefix,
e.g., OSSL_CALLBACK, OSSL_PARAM, OSSL_ALGORITHM, OSSL_SERIALIZER.
The OPENSSL_CTX type stands out a little by using a different prefix.
For consistency reasons, this type is renamed to OSSL_LIB_CTX.
Reviewed-by: Paul Dale <paul.dale@oracle.com>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/12621)
Ed25519 needs to fetch a digest and so needs to use the correct libctx.
Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org>
(Merged from https://github.com/openssl/openssl/pull/11496)
Add ref counting and control how we allocate storage for the private key.
We will need this type in following commits where we move the ecx code
to be provider aware.
Reviewed-by: Patrick Steuer <patrick.steuer@de.ibm.com>
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/10964)
Use of the low level ECDSA and EC_KEY_METHOD functions has been informally discouraged for a
long time. We now formally deprecate them.
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/10960)
Apart from public and internal header files, there is a third type called
local header files, which are located next to source files in the source
directory. Currently, they have different suffixes like
'*_lcl.h', '*_local.h', or '*_int.h'
This commit changes the different suffixes to '*_local.h' uniformly.
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/9333)
Check that s is less than the order before attempting to verify the
signature as per RFC8032 5.1.7
Fixes#7693
Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/7697)
Move base 2^64 code to own #if section. It was nested in base 2^51 section,
which arguably might have been tricky to follow.
Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/6699)
Unlike "upstream", Android NDK's arm64 gcc [but not clang] performs
64x64=128-bit multiplications with library calls, which appears to
have devastating impact on performance. [The condition is reduced to
__ANDROID__ [&& !__clang__], because x86_64 has corresponding
assembly module.]
Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/5589)
As it turns out gcc -pedantic doesn't seem to consider __uint128_t
as non-standard, unlike __int128 that is.
Fix even MSVC warnings in curve25519.c.
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Rich Salz <rsalz@openssl.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/5449)
Currently it's limited to 64-bit platforms only as minimum radix
expected in assembly is 2^51.
Reviewed-by: Rich Salz <rsalz@openssl.org>
Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/5408)
3 least significant bits of the input scalar are explicitly cleared,
hence swap variable has fixed value [of zero] upon exit from the loop.
Reviewed-by: Rich Salz <rsalz@openssl.org>
Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/5408)
SPARC ISA doesn't have provisions to back up 128-bit multiplications
and additions. And so multiplications are done with library calls
and carries with comparisons and conditional moves. As result base
2^51 code is >40% slower...
Reviewed-by: Tim Hudson <tjh@openssl.org>
"Double" is in quotes because improvement coefficient varies
significantly depending on platform and compiler. You're likely
to measure ~2x improvement on popular desktop and server processors,
but not so much on mobile ones, even minor regression on ARM
Cortex series. Latter is because they have rather "weak" umulh
instruction. On low-end x86_64 problem is that contemporary gcc
and clang tend to opt for double-precision shift for >>51, which
can be devastatingly slow on some processors.
Just in case for reference, trick is to use 2^51 radix [currently
only for DH].
Reviewed-by: Rich Salz <rsalz@openssl.org>
It's argued that /WX allows to keep better focus on new code, which
motivates its comeback...
Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/4721)
Fix undefined behaviour in curve25519.c. Prior to this running with
ubsan produces errors like this:
crypto/ec/curve25519.c:3871:18: runtime error: left shift of negative
value -22867
[extended tests]
Reviewed-by: Andy Polyakov <appro@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/3600)
Rename and change ED25519_keypair_from_seed to ED25519_public_from_private
to be consistent with X25519 API.
Modidy ED25519_sign to take separate public key argument instead of
requiring it to follow the private key.
Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/3503)
Reinstate Ed25519 algorithm to curv25519.c this is largely just a copy of
the code from BoringSSL with some adjustments so it compiles under OpenSSL.
Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/3503)
This demystifies two for-loops that do nothing. They were used to write
the ladder in a unified way. Now that the ladder is otherwise commented,
remove the dead loops.
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Rich Salz <rsalz@openssl.org>
Appease the sanitizer: avoid left shifts of negative values.
This could've been done entirely with casts to uint and back,
but using masks seemed slightly more readable.
There are also implementation-defined signed right shifts in this
code. Those remain.
Reviewed-by: Rich Salz <rsalz@openssl.org>
- Remove OPENSSL_X25519_X86_64 which never worked, because we don't have
the assembly.
- Also remove OPENSSL_SMALL (which should have been
OPENSSL_SMALL_FOOTPRINT) which isn't a priority at the moment.
Reviewed-by: Rich Salz <rsalz@openssl.org>