Add support for monero generate_key_derivation and subaddress/output step

cmake-rewrite
Lee Clagett 4 years ago committed by Lee Clagett
parent d11e401c4e
commit 07beaba033

@ -0,0 +1,36 @@
# Copyright (c) 2020, The Monero Project
#
# 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.
#
# 3. Neither the name of the copyright holder nor the names of its contributors may be
# used to endorse or promote products derived from this software without specific
# prior written permission.
#
# 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.
project(monero-crypto)
include(intree.cmake)
add_library(monero-crypto $<TARGET_OBJECTS:monero-crypto-intree>)
INSTALL(FILES "${CMAKE_CURRENT_SOURCE_DIR}/include/monero/crypto/${MONERO_CRYPTO_LIBRARY}.h" DESTINATION "include/monero/crypto")
INSTALL(FILES "${CMAKE_BINARY_DIR}/include/monero/crypto.h" DESTINATION "include/monero")
INSTALL(TARGETS monero-crypto LIBRARY)

@ -1 +1,125 @@
# supercop
# Supercop
> This project could use a rename :/
The objective of this project is to provide fast cryptographic operations for
Monero wallets. Unfortunately, there isn't necessarily a single fastest library
for all platforms - donna64 for instance likely performs poorly when
cross-compiled to asm.js or 32-bit arm. This project mitigates this issue by
copying the cryptographic libraries with as little changes as possible (ideally
zero), and then provides smaller and easier to audit "glue" functions that use
the cryptographic library to perform typical Monero wallet tasks. These "glue"
functions are often not obvious to the typical developer (otherwise they would
be using the cryptographic libraries already), however auditing these functions
should be straightforward to anyone familar with how the cryptography works.
The project is also designed to be used in-tree in other projects or installable
on a system. The default Monero wallets use the in-tree implementation which
serve as a more complex example of its usage. The project directory structure:
- **crypto_sign** - whose name is taken from supercop. The code in here is
from upstream cryptographic libraries with minimal changes (position
independent ASM).
- **include** - The only files that should be included by external projects,
with the exception of the auto-generated header.
- **src** - Contains all of the glue functions and build code.
- **functions.cmake** - The raw components for building the library. Used by
the default Monero wallet.
- **intree.cmake** - Creates a cmake library target `monero-crypto-intree`
and generates a header at `<BUILD_LOCATION>/include/monero/crypto.h`.
- **CMakeLists.txt** - Declares a new project for creating/installing a
shared or static `monero-crypto` library.
> Downstream projects cannot currently use this project _without_ also using
> the `monero-project/monero/src/crypto/crypto.h` functions - specifically
> `crypto::derivation_to_scalar`. So currently this project provides
> performance enhancements but not standalone usage.
## Usage
Every cryptographic library implements the same function signatures but with
unique namespaces to avoid collisions in the C symbol table. Downstream
projects can either use a specific library and header file OR dynamically
select a library and use a cmake generated header that uses macro replacement
to reference the selected library. Since each library has unique symbol names,
multiple can be used simulatenously (benchmarking, etc).
## C Wallet Functions
Every cryptographic library implements:
- **`monero_crypto_<namespace>_scalarmult(char* out, const char* pub, const char* sec)`** -
where `out` is the shared secret, `pub` is an ed25519 public key, and `sec`
is a user secret key. This operation is a standard ECDH operation on the
ed25519 curve.
- **`monero_crypto_<namespace>_generate_key_derivation(char* out, const char* tx_pub, const char* view_sec)`** -
where `out` is the shared secret, `tx_pub` is the public key from the
transaction and `view_sec` is the users view-key secret.
- **`monero_crypto_<namespace>_generate_subaddress_public_key(char* out, const char* output_pub, const char* special_sec)`** -
where `out` is the computed spend-public (primary or subaddress),
`output_pub` is the public key from the transaction output, and
`special_sec` is the output from `crypto::derivation_to_scalar` (which is
given the shared secret from `generate_key_derivation`).
All `char` pointers must be exactly 32-bytes. The auto-generated header has an
empty namespace for these functions and uses macro replacement to forward to the
selected library. If using dynamically selected libraries, include the
auto-generated header and use `monero_crypto_generate_key_derivation`, etc.
## CMake Usage
### Explicit Library Usage
A library can be selected explicitly in-tree:
```
include(supercop/functions.cmake)
monero_crypto_get_target("amd64-64-24k" CRYPTO_TARGET)
add_library(all $<OBJECT_TARGETS:${CRYPTO_TARGET}> all.cpp)
add_library(referenced referenced.cpp)
target_link_libraries(referenced ${CRYPTO_TARGET})
```
The `all` library will have all C functions in the `amd64-64-24k` library
whereas the `referenced` library will only have C functions referenced in
`referenced.cpp`.
## Basic In-Tree Dynamic Usage
A library can be selected at build time in-tree:
```
include(supercop/intree.cmake)
add_library(all $<OBJECT_TARGETS:monero-crypto-intree> all.cpp)
add_library(referenced referenced.cpp)
target_link_libraries(referenced monero-crypto-intree)
```
The best available library for the target platform is selected which can be
overriden with `-DMONERO_CRYPTO_LIBRARY=amd64-51-30k` or by setting the
variable with the same name.
A header file is written to `<BUILD_LOCATION>/include/monero/crypto.h` which
contains empty namespace macros that expand to the
[wallet functions](#c-wallet-functions) for the selected library. Including
this header file and using the empty namespace macros will allow for the
crypto library to be selected dynamically.
See the [explicit usage section](#explicit-library-usage) for the difference
between the `all` and `referenced` libraries.
## Advanced In-Tree Dynamic Usage
See `intree.cmake` on how to use the individual cmake functions in your project
for more control. Each of the cmake functions is documented.
## Standalone Usage
Is not-yet fully functional since the `crypto::derivation_to_scalar` from the
Monero source tree is still needed. However this is a proof-of-concept that
will be useful for testing if your project does not use cmake.
Running `cmake <source_path> . && make && sudo make install` will autodetect
the best crypto library, build it in the current directory, and then install to
the default location for your system. An error is generated if your target
platform does not have a supported crypto library. The auto-selected library
can be overriden with `-DMONERO_CRYPTO_LIBRARY=amd64-51-30k` at the first
cmake step. Using `-DMONERO_CRYPTO_LIBRARY=invalid` will generate an error
that displays all available crypto libraries.

@ -0,0 +1,91 @@
# Copyright (c) 2020, The Monero Project
#
# 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.
#
# 3. Neither the name of the copyright holder nor the names of its contributors may be
# used to endorse or promote products derived from this software without specific
# prior written permission.
#
# 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.
set(MONERO_CRYPTO_DIR ${CMAKE_CURRENT_LIST_DIR})
add_subdirectory("${MONERO_CRYPTO_DIR}/src" ${CMAKE_CURRENT_BINARY_DIR}/monero_crypto_src)
# Set `OUT` to a list of all valid library names.
function(monero_crypto_libraries OUT)
set(${OUT} "amd64-64-24k" "amd64-51-30k" PARENT_SCOPE)
endfunction (monero_crypto_libraries)
# `OUT` is set to 1 iff `CRYPTO_LIBRARY` is a valid library name.
function(monero_crypto_valid CRYPTO_LIBRARY OUT)
monero_crypto_libraries(ALL_LIBRARIES)
list(FIND ALL_LIBRARIES ${CRYPTO_LIBRARY} FOUND)
if (FOUND LESS 0)
set(${OUT} 0 PARENT_SCOPE)
else ()
set(${OUT} 1 PARENT_SCOPE)
endif ()
endfunction (monero_crypto_valid)
# Set `OUT` to a valid C/C++ namespace name based on `CRYPTO_LIBRARY`.
function(monero_crypto_get_namespace CRYPTO_LIBRARY OUT)
string(REPLACE "-" "_" TEMP "${CRYPTO_LIBRARY}")
set(${OUT} ${TEMP} PARENT_SCOPE)
endfunction (monero_crypto_get_namespace)
# Set `OUT` to a valid target dependency name based on `CRYPTO_LIBRARY`.
function(monero_crypto_get_target CRYPTO_LIBRARY OUT)
set(${OUT} "monero-crypto-${CRYPTO_LIBRARY}" PARENT_SCOPE)
endfunction (monero_crypto_get_target)
# Sets `BEST` to the preferred crypto library for the target platform, and
# sets `AVAILABLE` to all valid crypto libraries for the target platform.
function(monero_crypto_autodetect AVAILABLE BEST)
if (UNIX AND CMAKE_SYSTEM_PROCESSOR MATCHES "amd64.*|AMD64.*|x86_64.*")
message("Monero crypto autodetect selected \"amd64-64-24k\" for target platform")
set(${AVAILABLE} "amd64-64-24k" "amd64-51-30k" PARENT_SCOPE)
set(${BEST} "amd64-64-24k" PARENT_SCOPE)
else ()
message("Monero crypto autodetect failed to find library for target platform")
unset(${AVAILABLE} PARENT_SCOPE)
unset(${BEST} PARENT_SCOPE)
endif ()
endfunction (monero_crypto_autodetect)
# Writes a C header to `HEADER_FILE` that contains these C functions:
# - `monero_crypto_generate_key_derivation`
# - `monero_crypto_derive_subaddress_public_key`
# that map to the selected `CRYPTO_LIBRARY` implementation using macro
# replacement. See README.md for function explanation.
#
# A fatal error is generated if `CRYPTO_LIBRARY` is not valid - linking will
# always fails in this situation.
function(monero_crypto_generate_header MONERO_CRYPTO_LIBRARY HEADER_FILE)
monero_crypto_valid(${MONERO_CRYPTO_LIBRARY} VALID)
if (NOT VALID)
monero_crypto_libraries(ALL_LIBRARIES)
string(REPLACE ";" " " ALL_LIBRARIES "${ALL_LIBRARIES}")
message(FATAL_ERROR "Library ${MONERO_CRYPTO_LIBRARY} is not valid. Must be one of: ${ALL_LIBRARIES}")
endif ()
monero_crypto_get_namespace(${MONERO_CRYPTO_LIBRARY} MONERO_CRYPTO_NAMESPACE)
configure_file("${MONERO_CRYPTO_DIR}/src/crypto.h.in" ${HEADER_FILE})
endfunction (monero_crypto_generate_header)

@ -0,0 +1,45 @@
// Copyright (c) 2020, The Monero Project
//
// 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.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
// 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.
#ifndef MONERO_CRYPTO_AMD64_51_30K_H
#define MONERO_CRYPTO_AMD64_51_30K_H
#ifdef __cplusplus
extern "C"
{
#endif
int monero_crypto_amd64_51_30k_ge25519_scalarmult(char* out, char const* pub, char const* sec);
int monero_crypto_amd64_51_30k_generate_key_derivation(char* out, char const* tx_pub, char const* view_sec);
int monero_crypto_amd64_51_30k_generate_subaddress_public_key(char* out, char const* output_pub, char const* special_sec);
#ifdef __cplusplus
}
#endif
#endif // MONERO_CRYPTO_AMD64_51_30K_H

@ -0,0 +1,45 @@
// Copyright (c) 2020, The Monero Project
//
// 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.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
// 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.
#ifndef MONERO_CRYPTO_AMD64_64_24K_H
#define MONERO_CRYPTO_AMD64_64_24K_H
#ifdef __cplusplus
extern "C"
{
#endif
int monero_crypto_amd64_64_24k_ge25519_scalarmult(char* out, char const* pub, char const* sec);
int monero_crypto_amd64_64_24k_generate_key_derivation(char* out, char const* tx_pub, char const* view_sec);
int monero_crypto_amd64_64_24k_generate_subaddress_public_key(char* out, char const* output_pub, char const* special_sec);
#ifdef __cplusplus
}
#endif
#endif // MONERO_CRYPTO_AMD64_64_24K_H

@ -0,0 +1,46 @@
# Copyright (c) 2020, The Monero Project
#
# 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.
#
# 3. Neither the name of the copyright holder nor the names of its contributors may be
# used to endorse or promote products derived from this software without specific
# prior written permission.
#
# 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.
include(functions.cmake)
set(MONERO_CRYPTO_LIBRARY "auto" CACHE STRING "Select a crypto library backend")
if (${MONERO_CRYPTO_LIBRARY} STREQUAL "auto")
monero_crypto_autodetect(AVAILABLE BEST)
if (NOT DEFINED BEST)
message(FATAL_ERROR "No crypto library available for target platform")
endif ()
set(MONERO_CRYPTO_LIBRARY ${BEST})
endif ()
# next line fatal errors if invalid library selected
monero_crypto_generate_header(${MONERO_CRYPTO_LIBRARY} "${CMAKE_BINARY_DIR}/include/monero/crypto.h")
monero_crypto_get_target(${MONERO_CRYPTO_LIBRARY} CRYPTO_TARGET)
add_library(monero-crypto-intree ALIAS ${CRYPTO_TARGET})

@ -0,0 +1,30 @@
# Copyright (c) 2020, The Monero Project
#
# 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.
#
# 3. Neither the name of the copyright holder nor the names of its contributors may be
# used to endorse or promote products derived from this software without specific
# prior written permission.
#
# 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.
# Only build libraries when targeted
add_subdirectory(amd64 EXCLUDE_FROM_ALL)

@ -0,0 +1,82 @@
# Copyright (c) 2020, The Monero Project
#
# 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.
#
# 3. Neither the name of the copyright holder nor the names of its contributors may be
# used to endorse or promote products derived from this software without specific
# prior written permission.
#
# 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.
enable_language(ASM-ATT)
function(add_amd64_library LIBNAME LIBFOLDER)
set(MULTIVARS SOURCES)
cmake_parse_arguments(AMD64_PERF "" "" "${MULTIVARS}" ${ARGN})
add_library("monero-crypto-${LIBNAME}" OBJECT
"${LIBNAME}.c" "${LIBNAME}-choose_tp.s"
"${LIBFOLDER}/choose_t.s"
"${LIBFOLDER}/consts.s"
"${LIBFOLDER}/fe25519_getparity.c"
"${LIBFOLDER}/fe25519_freeze.s"
"${LIBFOLDER}/fe25519_invert.c"
"${LIBFOLDER}/fe25519_iseq.c"
"${LIBFOLDER}/fe25519_mul.s"
"${LIBFOLDER}/fe25519_neg.c"
"${LIBFOLDER}/fe25519_pack.c"
"${LIBFOLDER}/fe25519_pow2523.c"
"${LIBFOLDER}/fe25519_setint.c"
"${LIBFOLDER}/fe25519_square.s"
"${LIBFOLDER}/fe25519_unpack.c"
"${LIBFOLDER}/ge25519_add.c"
"${LIBFOLDER}/ge25519_add_p1p1.s"
"${LIBFOLDER}/ge25519_dbl_p1p1.s"
"${LIBFOLDER}/ge25519_double.c"
"${LIBFOLDER}/ge25519_nielsadd_p1p1.s"
"${LIBFOLDER}/ge25519_nielsadd2.s"
"${LIBFOLDER}/ge25519_pack.c"
"${LIBFOLDER}/ge25519_p1p1_to_p2.s"
"${LIBFOLDER}/ge25519_p1p1_to_p3.s"
"${LIBFOLDER}/ge25519_pnielsadd_p1p1.s"
"${LIBFOLDER}/ge25519_scalarmult_base.c"
"${LIBFOLDER}/ge25519_unpackneg.c"
"${LIBFOLDER}/sc25519_from32bytes.c"
"${LIBFOLDER}/sc25519_window4.c"
${AMD64_PERF_SOURCES})
target_include_directories("monero-crypto-${LIBNAME}" PRIVATE ${LIBFOLDER})
endfunction (add_amd64_library)
add_amd64_library(
"amd64-64-24k"
"${CMAKE_CURRENT_SOURCE_DIR}/../../crypto_sign/ed25519/amd64-64-24k"
SOURCES
"${CMAKE_CURRENT_SOURCE_DIR}/../../crypto_sign/ed25519/amd64-64-24k/fe25519_add.s"
"${CMAKE_CURRENT_SOURCE_DIR}/../../crypto_sign/ed25519/amd64-64-24k/fe25519_sub.s")
add_amd64_library(
"amd64-51-30k"
"${CMAKE_CURRENT_SOURCE_DIR}/../../crypto_sign/ed25519/amd64-51-30k"
SOURCES
"${CMAKE_CURRENT_SOURCE_DIR}/../../crypto_sign/ed25519/amd64-51-30k/fe25519_add.c"
"${CMAKE_CURRENT_SOURCE_DIR}/../../crypto_sign/ed25519/amd64-51-30k/fe25519_nsquare.s"
"${CMAKE_CURRENT_SOURCE_DIR}/../../crypto_sign/ed25519/amd64-51-30k/fe25519_sub.c"
"${CMAKE_CURRENT_SOURCE_DIR}/../../crypto_sign/ed25519/amd64-51-30k/ge25519_p1p1_to_pniels.s")

File diff suppressed because it is too large Load Diff

@ -0,0 +1,65 @@
// Copyright (c) 2020, The Monero Project
//
// 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.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
// 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.
//
// Parts of this file from bench.cr.yp.to/supercop.html (2017-07-25):
// Daniel J. Bernstein
// Niels Duif
// Tanja Lange
// lead: Peter Schwabe
// Bo-Yin Yang
#include <stddef.h>
#include "fe25519.h"
/* constants below can be found in various fles in ed25519/amd64-51-30k */
/* d */
static const fe25519 ecd = {{929955233495203, 466365720129213, 1662059464998953, 2033849074728123, 1442794654840575}};
/* 2*d */
static const fe25519 ec2d = {{1859910466990425, 932731440258426, 1072319116312658, 1815898335770999, 633789495995903}};
/* sqrt(-1) */
static const fe25519 sqrtm1 = {{1718705420411056, 234908883556509, 2233514472574048, 2117202627021982, 765476049583133}};
#define choose_tp crypto_sign_ed25519_amd64_51_30k_batch_choose_tp
#include "amd64.c.inc"
int monero_crypto_amd64_51_30k_ge25519_scalarmult(char* out, char const* pub, char const* sec)
{
return scalarmult(out, pub, sec);
}
int monero_crypto_amd64_51_30k_generate_key_derivation(char* out, char const* tx_pub, char const* view_sec)
{
return generate_key_derivation(out, tx_pub, view_sec);
}
int monero_crypto_amd64_51_30k_generate_subaddress_public_key(char* out, char const* output_pub, char const* special_sec)
{
return generate_subaddress_public_key(out, output_pub, special_sec);
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,76 @@
// Copyright (c) 2020, The Monero Project
//
// 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.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
// 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.
//
// Parts of this file from bench.cr.yp.to/supercop.html (2017-07-25):
// Daniel J. Bernstein
// Niels Duif
// Tanja Lange
// lead: Peter Schwabe
// Bo-Yin Yang
#include <stddef.h>
#include "fe25519.h"
#include "ge25519.h"
/* constants below can be found in various fles in ed25519/amd64-64-24k */
/* d */
static const fe25519 ecd = {{0x75EB4DCA135978A3, 0x00700A4D4141D8AB, 0x8CC740797779E898, 0x52036CEE2B6FFE73}};
/* 2*d */
static const fe25519 ec2d = {{0xEBD69B9426B2F146, 0x00E0149A8283B156, 0x198E80F2EEF3D130, 0xA406D9DC56DFFCE7}};
/* sqrt(-1) */
static const fe25519 sqrtm1 = {{0xC4EE1B274A0EA0B0, 0x2F431806AD2FE478, 0x2B4D00993DFBD7A7, 0x2B8324804FC1DF0B}};
/* taken from loop in ed25519/amd64-64-24k/ge25519_double_scalarmult.c */
static void ge25519_p1p1_to_pniels(ge25519_pniels* out, ge25519_p1p1 const* in)
{
ge25519_p1p1_to_p3((ge25519_p3*)out, in);
const fe25519 d = out->ysubx;
fe25519_sub(&(out->ysubx), &(out->xaddy), &(out->ysubx));
fe25519_add(&(out->xaddy), &(out->xaddy), &d);
fe25519_mul(&(out->t2d), &(out->t2d), &ec2d);
}
#define choose_tp crypto_sign_ed25519_amd64_64_choose_tp
#include "amd64.c.inc"
int monero_crypto_amd64_64_24k_ge25519_scalarmult(char* out, char const* pub, char const* sec)
{
return scalarmult(out, pub, sec);
}
int monero_crypto_amd64_64_24k_generate_key_derivation(char* out, char const* tx_pub, char const* view_sec)
{
return generate_key_derivation(out, tx_pub, view_sec);
}
int monero_crypto_amd64_64_24k_generate_subaddress_public_key(char* out, char const* output_pub, char const* special_sec)
{
return generate_subaddress_public_key(out, output_pub, special_sec);
}

@ -0,0 +1,221 @@
// Copyright (c) 2020, The Monero Project
//
// 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.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
// 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.
//
// Parts of this file from biench.cr.yp.to/supercop.html (2017-02-25):
// Daniel J. Bernstein
// Niels Duif
// Tanja Lange
// lead: Peter Schwabe
// Bo-Yin Yang
#include <string.h>
#include "ge25519.h"
extern void choose_tp(ge25519_pniels *t, unsigned long long pos, signed long long b, const ge25519_pniels *base_multiples);
/* return 0 on success, -1 otherwise. Taken from
ed25519/amd64-51-30k/ge25519_unpackneg.c - the negation is removed. */
static int unpack_vartime(ge25519_p3 *r, const unsigned char p[32])
{
fe25519 t, chk, num, den, den2, den4, den6;
unsigned char par = p[31] >> 7;
fe25519_setint(&r->z,1);
fe25519_unpack(&r->y, p);
fe25519_square(&num, &r->y); /* x = y^2 */
fe25519_mul(&den, &num, &ecd); /* den = dy^2 */
fe25519_sub(&num, &num, &r->z); /* x = y^2-1 */
fe25519_add(&den, &r->z, &den); /* den = dy^2+1 */
/* Computation of sqrt(num/den)
1.: computation of num^((p-5)/8)*den^((7p-35)/8) = (num*den^7)^((p-5)/8)
*/
fe25519_square(&den2, &den);
fe25519_square(&den4, &den2);
fe25519_mul(&den6, &den4, &den2);
fe25519_mul(&t, &den6, &num);
fe25519_mul(&t, &t, &den);
fe25519_pow2523(&t, &t);
/* 2. computation of r->x = t * num * den^3
*/
fe25519_mul(&t, &t, &num);
fe25519_mul(&t, &t, &den);
fe25519_mul(&t, &t, &den);
fe25519_mul(&r->x, &t, &den);
/* 3. Check whether sqrt computation gave correct result, multiply by sqrt(-1) if not:
*/
fe25519_square(&chk, &r->x);
fe25519_mul(&chk, &chk, &den);
if (!fe25519_iseq_vartime(&chk, &num))
fe25519_mul(&r->x, &r->x, &sqrtm1);
/* 4. Now we have one of the two square roots, except if input was not a square
*/
fe25519_square(&chk, &r->x);
fe25519_mul(&chk, &chk, &den);
if (!fe25519_iseq_vartime(&chk, &num))
return -1;
/* 5. Choose the desired square root according to parity:
*/
if(fe25519_getparity(&r->x) == (1-par)) // only change from original function was `!=` -> `==`
fe25519_neg(&r->x, &r->x);
fe25519_mul(&r->t, &r->x, &r->y);
return 0;
}
static void p3_to_pniels(ge25519_pniels* out, ge25519_p3 const* src)
{
fe25519_sub(&out->ysubx, &src->y, &src->x);
fe25519_add(&out->xaddy, &src->x, &src->y);
fe25519_mul(&out->t2d, &src->t, &ec2d);
out->z = src->z;
}
static void negate(ge25519* out)
{
fe25519_neg(&out->x, &out->x);
fe25519_neg(&out->t, &out->t);
}
// similar to loops in existing implementation, but uses dynamic table instead of fixed `G`.
static void scalarmult_p1p1(ge25519_p1p1* r, ge25519_pniels const* base, char const* sec)
{
signed char b[64];
ge25519_pniels t;
ge25519_p3 tp3;
sc25519 s;
memcpy(s.v, sec, sizeof(s));
sc25519_window4(b, &s);
// set neutral
fe25519_setint(&tp3.x, 0);
fe25519_setint(&tp3.y, 1);
fe25519_setint(&tp3.t, 0);
fe25519_setint(&tp3.z, 1);
// end set neutral
for (int i = 63; /* break below*/ ; --i)
{
choose_tp(&t, (unsigned long long) 0, (signed long long) b[i], base);
ge25519_pnielsadd_p1p1(r, &tp3, &t);
if (i == 0) break;
ge25519_p1p1_to_p2((ge25519_p2*)&tp3, r);
ge25519_dbl_p1p1(r,(ge25519_p2 *)&tp3);
ge25519_p1p1_to_p2((ge25519_p2 *)&tp3, r);
ge25519_dbl_p1p1(r,(ge25519_p2 *)&tp3);
ge25519_p1p1_to_p2((ge25519_p2 *)&tp3, r);
ge25519_dbl_p1p1(r,(ge25519_p2 *)&tp3);
ge25519_p1p1_to_p2((ge25519_p2 *)&tp3, r);
ge25519_dbl_p1p1(r,(ge25519_p2 *)&tp3);
ge25519_p1p1_to_p3(&tp3, r);
}
}
// _similar_ to ge_scalarmult in src/crypto/crypto-ops.c
static void base_precomp(ge25519_pniels* base, ge25519_p3 const* r)
{
ge25519_p1p1 tp1p1;
p3_to_pniels(&base[0], r);
for (int i = 0; i < 7; ++i)
{
ge25519_pnielsadd_p1p1(&tp1p1, r, &base[i]);
ge25519_p1p1_to_pniels(&base[i + 1], &tp1p1);
}
}
static int scalarmult(char* out, char const* pub, char const* sec)
{
ge25519 unpacked;
ge25519_pniels base[8];
ge25519_p1p1 tp1p1;
if (unpack_vartime(&unpacked, (unsigned char const*)pub) != 0)
return -1;
base_precomp(base, &unpacked);
scalarmult_p1p1(&tp1p1, base, sec);
ge25519_p1p1_to_p3(&unpacked, &tp1p1);
ge25519_pack((unsigned char*)out, &unpacked);
return 0;
}
static int generate_key_derivation(char* out, char const* tx_pub, char const* view_sec)
{
ge25519 unpacked;
ge25519_pniels base[8];
ge25519_p1p1 tp1p1;
if (unpack_vartime(&unpacked, (unsigned char const*)tx_pub) != 0)
return -1;
base_precomp(base, &unpacked);
scalarmult_p1p1(&tp1p1, base, view_sec);
// non-standard, monero specific - guarantees point is in ed25519 group
ge25519_p1p1_to_p2((ge25519_p2*)&unpacked, &tp1p1);
ge25519_dbl_p1p1(&tp1p1,(ge25519_p2 *)&unpacked);
ge25519_p1p1_to_p2((ge25519_p2 *)&unpacked, &tp1p1);
ge25519_dbl_p1p1(&tp1p1,(ge25519_p2 *)&unpacked);
ge25519_p1p1_to_p2((ge25519_p2 *)&unpacked, &tp1p1);
ge25519_dbl_p1p1(&tp1p1,(ge25519_p2 *)&unpacked);
ge25519_p1p1_to_p3(&unpacked, &tp1p1);
ge25519_pack((unsigned char*)out, &unpacked);
return 0;
}
static void generate_subaddress_public_key_base(char* out, ge25519 const* output_pub, char const* special_sec)
{
ge25519 p1;
sc25519 p2;
memcpy(p2.v, special_sec, sizeof(p2.v));
ge25519_scalarmult_base(&p1, &p2);
negate(&p1); // ge25519_sub is not provided by these libraries
ge25519_add(&p1, output_pub, &p1);
ge25519_pack((unsigned char*)out, &p1);
}
static int generate_subaddress_public_key(char* out, char const* output_pub, char const* special_sec)
{
ge25519 p;
if (unpack_vartime(&p, (unsigned char const*)output_pub) != 0)
return -1;
generate_subaddress_public_key_base(out, &p, special_sec);
return 0;
}

@ -0,0 +1,38 @@
// Copyright (c) 2020, The Monero Project
//
// 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.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
// 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.
#ifndef MONERO_CRYPTO_H
#define MONERO_CRYPTO_H
#include "monero/crypto/@MONERO_CRYPTO_LIBRARY@.h"
#define monero_crypto_ge25519_scalarmult monero_crypto_@MONERO_CRYPTO_NAMESPACE@_ge25519_scalarmult
#define monero_crypto_generate_key_derivation monero_crypto_@MONERO_CRYPTO_NAMESPACE@_generate_key_derivation
#define monero_crypto_generate_subaddress_public_key monero_crypto_@MONERO_CRYPTO_NAMESPACE@_generate_subaddress_public_key
#endif // MONERO_CRYPTO_H
Loading…
Cancel
Save