Sitelet https://github.com/erigontech/silkpre/commit/11987adf63bdf0057cdcd34eb13901658e9c1e0c
Skip to content

Commit 11987ad

Browse files
committed
ECDSA silkpre_recover_address
1 parent ba6370d commit 11987ad

5 files changed

Lines changed: 133 additions & 4 deletions

File tree

‎CMakeLists.txt‎

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ if(NOT SILKPRE_HAS_PARENT)
2626
endif()
2727

2828
if(SILKPRE_TESTING)
29-
set(HUNTER_PACKAGES Catch intx)
29+
set(HUNTER_PACKAGES Catch ethash intx)
3030
else()
31-
set(HUNTER_PACKAGES intx)
31+
set(HUNTER_PACKAGES ethash intx)
3232
endif()
3333

3434
include(FetchContent)
@@ -40,6 +40,21 @@ project(silkpre)
4040

4141
# TODO: disable exceptions
4242

43+
# secp256k1
44+
add_library(secp256k1 third_party/secp256k1/src/secp256k1.c)
45+
if(MSVC)
46+
target_link_libraries(secp256k1 PRIVATE gmp)
47+
target_compile_definitions(secp256k1 PUBLIC USE_NUM_GMP USE_FIELD_INV_NUM USE_SCALAR_INV_NUM)
48+
target_compile_definitions(secp256k1 PUBLIC USE_FIELD_10X26 USE_SCALAR_8X32)
49+
target_compile_options(secp256k1 PRIVATE /w) # Not much we can do about warnings
50+
else()
51+
target_compile_definitions(secp256k1 PUBLIC USE_NUM_NONE USE_FIELD_INV_BUILTIN USE_SCALAR_INV_BUILTIN)
52+
target_compile_definitions(secp256k1 PUBLIC USE_FIELD_5X52 USE_SCALAR_4X64 HAVE___INT128)
53+
endif()
54+
target_compile_definitions(secp256k1 PUBLIC ECMULT_WINDOW_SIZE=15 ECMULT_GEN_PREC_BITS=4 USE_ENDOMORPHISM)
55+
target_compile_definitions(secp256k1 PUBLIC ENABLE_MODULE_RECOVERY)
56+
target_include_directories(secp256k1 PRIVATE secp256k1 INTERFACE third_party/secp256k1/include)
57+
4358
# libff
4459
set(CURVE "ALT_BN128" CACHE STRING "" FORCE)
4560
option(WITH_PROCPS "" OFF)

‎lib/CMakeLists.txt‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,14 @@
1414
limitations under the License.
1515
]]
1616

17+
find_package(ethash CONFIG REQUIRED)
1718
find_package(intx CONFIG REQUIRED)
1819

1920
add_library(silkpre
2021
silkpre/blake2b.c
2122
silkpre/blake2b.h
23+
silkpre/ecdsa.c
24+
silkpre/ecdsa.h
2225
silkpre/rmd160.c
2326
silkpre/rmd160.h
2427
silkpre/sha256.c
@@ -30,4 +33,4 @@ add_library(silkpre
3033
)
3134
target_include_directories(silkpre PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
3235
# TODO: make ff private
33-
target_link_libraries(silkpre PUBLIC intx::intx ff)
36+
target_link_libraries(silkpre PUBLIC intx::intx ff secp256k1 PRIVATE ethash::keccak)

‎lib/silkpre/ecdsa.c‎

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
Copyright 2022 The Silkpre Authors
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#include "ecdsa.h"
18+
19+
#include <string.h>
20+
21+
#include <ethash/keccak.h>
22+
#include <secp256k1_recovery.h>
23+
24+
//! \brief Tries recover public key used for message signing.
25+
//! \return An optional Bytes. Should it has no value the recovery has failed
26+
//! This is different from recover_address as the whole 64 bytes are returned.
27+
static bool recover(uint8_t* out, const uint8_t message[32], const uint8_t signature[64], bool odd_y_parity,
28+
secp256k1_context* context) {
29+
secp256k1_ecdsa_recoverable_signature sig;
30+
if (!secp256k1_ecdsa_recoverable_signature_parse_compact(context, &sig, signature, odd_y_parity)) {
31+
return false;
32+
}
33+
34+
secp256k1_pubkey pub_key;
35+
if (!secp256k1_ecdsa_recover(context, &pub_key, &sig, &message[0])) {
36+
return false;
37+
}
38+
39+
size_t out_len = 65;
40+
secp256k1_ec_pubkey_serialize(context, out, &out_len, &pub_key, SECP256K1_EC_UNCOMPRESSED);
41+
return true;
42+
}
43+
44+
//! Tries extract address from recovered public key
45+
//! \param [in] public_key: The recovered public key
46+
//! \return Whether the recovery has succeeded.
47+
static bool public_key_to_address(uint8_t* out, const uint8_t public_key[65]) {
48+
if (public_key[0] != 4u) {
49+
return false;
50+
}
51+
// Ignore first byte of public key
52+
const union ethash_hash256 key_hash = ethash_keccak256(public_key + 1, 64);
53+
memcpy(out, &key_hash.bytes[12], 20);
54+
return true;
55+
}
56+
57+
bool recover_address(uint8_t* out, const uint8_t message[32], const uint8_t signature[64], bool odd_y_parity,
58+
secp256k1_context* context) {
59+
uint8_t public_key[65];
60+
bool converted = false;
61+
if (recover(public_key, message, signature, odd_y_parity, context)) {
62+
converted = public_key_to_address(out, public_key);
63+
}
64+
return converted;
65+
}

‎lib/silkpre/ecdsa.h‎

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
Copyright 2022 The Silkpre Authors
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#ifndef SILKPRE_ECDSA_H_
18+
#define SILKPRE_ECDSA_H_
19+
20+
// See Yellow Paper, Appendix F "Signing Transactions"
21+
22+
#include <secp256k1.h>
23+
#include <stdbool.h>
24+
#include <stddef.h>
25+
#include <stdint.h>
26+
27+
#define SILKPRE_SECP256K1_CONTEXT_FLAGS (SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY)
28+
29+
#if defined(__cplusplus)
30+
extern "C" {
31+
#endif
32+
33+
//! \brief Tries recover the address used for message signing
34+
//! \param [in] message : the signed message
35+
//! \param [in] signature : the signature
36+
//! \param [in] odd_y_parity : whether y parity is odd
37+
//! \param [in] context: a pointer to an existing secp256k1 context
38+
//! \return Whether the recovery has succeeded
39+
bool silkpre_recover_address(uint8_t* out, const uint8_t message[32], const uint8_t signature[64], bool odd_y_parity,
40+
secp256k1_context* context);
41+
42+
#if defined(__cplusplus)
43+
}
44+
#endif
45+
46+
#endif // SILKPRE_ECDSA_H_

‎third_party/secp256k1‎

Submodule secp256k1 updated 89 files

0 commit comments

Comments
 (0)