Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

question: Build library without standard IO functions #262

Closed
ssantos21 opened this issue Aug 1, 2023 · 4 comments
Closed

question: Build library without standard IO functions #262

ssantos21 opened this issue Aug 1, 2023 · 4 comments

Comments

@ssantos21
Copy link

I'm using secp256k1-zkp as a library in an Intel SGX Enclave project.
When any secp256k1-zkp function is called in the untrusted environment, the project builds successfully.
But I got the error below when secp256k1-zkp functions are called in Enclave trusted environment.

The reason, I think, is taht the secp256k1-zkp library seems to have references to fprintf and stderr, which are standard C library functions and global variables.
In the context of Intel SGX enclaves, the standard C library is not directly accessible in the same manner as regular applications.

So the linker (/usr/local/bin/ld) is unable to find references for stderr and __fprintf_chk, causing the "undefined reference" error.

Is there a way to compile the secp256k1-zkp library in a way that doesn't reference any functionality that isn't supported inside an enclave, like standard IO functions?

/usr/local/bin/ld: secp256k1-zkp/.libs/libsecp256k1.a(libsecp256k1_la-secp256k1.o): warning: relocation against `stderr' in read-only section `.text'
/usr/local/bin/ld: secp256k1-zkp/.libs/libsecp256k1.a(libsecp256k1_la-secp256k1.o): in function `fprintf':
/usr/include/x86_64-linux-gnu/bits/stdio2.h:105: undefined reference to `stderr'
/usr/local/bin/ld: /usr/include/x86_64-linux-gnu/bits/stdio2.h:105: undefined reference to `__fprintf_chk'
/usr/local/bin/ld: /usr/include/x86_64-linux-gnu/bits/stdio2.h:105: undefined reference to `stderr'
/usr/local/bin/ld: /usr/include/x86_64-linux-gnu/bits/stdio2.h:105: undefined reference to `__fprintf_chk'
/usr/local/bin/ld: warning: creating DT_TEXTREL in a PIE

I am building the secp256k1-zkp lib with --enable-module-schnorrsig --enable-experimental --enable-module-musig flags and including ./secp256k1-zkp/.libs/libsecp256k1.a in the main project build.

@real-or-random
Copy link
Collaborator

This is related to the callbacks, see the docs for secp256k1_set_illegal_callback and secp256k1_set_error_callback. The default callbacks print error messages, and so they need fprintf and stderr.

You need to configure with --enable-external-default-callbacks and then provide default callbacks:

* When this function has not been called (or called with fn==NULL), then the
* default handler will be used. The library provides a default handler which
* writes the message to stderr and calls abort. This default handler can be
* replaced at link time if the preprocessor macro
* USE_EXTERNAL_DEFAULT_CALLBACKS is defined, which is the case if the build
* has been configured with --enable-external-default-callbacks. Then the
* following two symbols must be provided to link against:
* - void secp256k1_default_illegal_callback_fn(const char* message, void* data);
* - void secp256k1_default_error_callback_fn(const char* message, void* data);

These should abort your program (but without printing an error message).

@ssantos21
Copy link
Author

@real-or-random Thanks for the quick answer.

I am now compiling with ./configure --enable-module-schnorrsig --enable-experimental --enable-module-musig --enable-external-default-callbacks --enable-benchmark=no --enable-tests=no --enable-exhaustive-tests=no.

The libsecp256k1 compiled successfully, but I got the error below when calling its functions.

/usr/local/bin/ld: secp256k1-zkp/.libs/libsecp256k1.a(libsecp256k1_la-secp256k1.o): in function `secp256k1_callback_call':
/home/user/intel-sgx-enclave-server/secp256k1-zkp/src/util.h:25: undefined reference to `secp256k1_default_illegal_callback_fn'
/usr/local/bin/ld: secp256k1-zkp/.libs/libsecp256k1.a(libsecp256k1_la-secp256k1.o): in function `secp256k1_context_preallocated_create':
/home/user/intel-sgx-enclave-server/secp256k1-zkp/src/secp256k1.c:117: undefined reference to `secp256k1_default_illegal_callback_fn'
/usr/local/bin/ld: /home/user/intel-sgx-enclave-server/secp256k1-zkp/src/secp256k1.c:118: undefined reference to `secp256k1_default_error_callback_fn'
/usr/local/bin/ld: secp256k1-zkp/.libs/libsecp256k1.a(libsecp256k1_la-secp256k1.o): in function `secp256k1_callback_call':
/home/user/intel-sgx-enclave-server/secp256k1-zkp/src/util.h:25: undefined reference to `secp256k1_default_error_callback_fn'
/usr/local/bin/ld: /home/user/intel-sgx-enclave-server/secp256k1-zkp/src/util.h:25: undefined reference to `secp256k1_default_illegal_callback_fn'
/usr/local/bin/ld: /home/user/intel-sgx-enclave-server/secp256k1-zkp/src/util.h:25: undefined reference to `secp256k1_default_illegal_callback_fn'
/usr/local/bin/ld: /home/user/intel-sgx-enclave-server/secp256k1-zkp/src/util.h:25: undefined reference to `secp256k1_default_error_callback_fn'
/usr/local/bin/ld: secp256k1-zkp/.libs/libsecp256k1.a(libsecp256k1_la-secp256k1.o): in function `secp256k1_context_set_illegal_callback':
/home/user/intel-sgx-enclave-server/secp256k1-zkp/src/secp256k1.c:177: undefined reference to `secp256k1_default_illegal_callback_fn'
/usr/local/bin/ld: secp256k1-zkp/.libs/libsecp256k1.a(libsecp256k1_la-secp256k1.o): in function `secp256k1_context_set_error_callback':
/home/user/intel-sgx-enclave-server/secp256k1-zkp/src/secp256k1.c:186: undefined reference to `secp256k1_default_error_callback_fn'
/usr/local/bin/ld: secp256k1-zkp/.libs/libsecp256k1.a(libsecp256k1_la-secp256k1.o):(.data.rel.ro+0xa8): undefined reference to `secp256k1_default_illegal_callback_fn'
/usr/local/bin/ld: secp256k1-zkp/.libs/libsecp256k1.a(libsecp256k1_la-secp256k1.o):(.data.rel.ro+0xb8): undefined reference to `secp256k1_default_error_callback_fn'
collect2: error: ld returned 1 exit status

The code is:

void counting_illegal_callback_fn(const char* str, void* data) {
    /* Dummy callback function that just counts. */
    int32_t *p;
    (void)str;
    p = (int32_t *) data;
    (*p)++;
}

int test_secp256k1_zkp() {
    unsigned char seckey[32];

    secp256k1_context* ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);

    int32_t ecount = 0;
    int32_t ecount2 = 10;
    secp256k1_context_set_illegal_callback(ctx, counting_illegal_callback_fn, &ecount);
    secp256k1_context_set_illegal_callback(ctx, counting_illegal_callback_fn, &ecount2);
    
    // ...

   secp256k1_context_destroy(ctx);
    return 1;
}

@real-or-random
Copy link
Collaborator

As I quoted above, you have to define functions

  *   - void secp256k1_default_illegal_callback_fn(const char* message, void* data); 
  *   - void secp256k1_default_error_callback_fn(const char* message, void* data); 

I don't see them in your code.

@ssantos21
Copy link
Author

Thanks for the detailed explanation @real-or-random
I had misunderstood the solution.

I managed to solve it with the following code:

extern "C" {
    #include "../secp256k1-zkp/include/secp256k1.h"
    #include "../secp256k1-zkp/include/secp256k1_schnorrsig.h"
    #include "../secp256k1-zkp/include/secp256k1_musig.h"

    void secp256k1_default_illegal_callback_fn(const char* str, void* data) {
        (void)str;
        (void)data;
        abort();
    }

    void secp256k1_default_error_callback_fn(const char* str, void* data) {
        (void)str;
        (void)data;
        abort();
    }
}

jonasnick pushed a commit that referenced this issue Aug 1, 2023
…th x specified as n/d

0f86420 Add exhaustive tests for ecmult_const_xonly (Pieter Wuille)
4485926 Add x-only ecmult_const version for x=n/d (Pieter Wuille)

Pull request description:

  This implements a generalization of Peter Dettman's sqrt-less x-only random-base multiplication algorithm from #262, using the Jacobi symbol algorithm from #979. The generalization is to permit the X coordinate of the base point to be specified as a fraction $n/d$:

  To compute $x(q \cdot P)$, where $x(P) = n/d$:
  * Compute $g=n^3 + 7d^3$.
  * Let $P' = (ng, g^2, 1)$ (the Jacobian coordinates of $P$ mapped to the isomorphic curve $y^2 = x^3 + 7(dg)^3$).
  * Compute the Jacobian coordinates $(X',Y',Z') = q \cdot P'$ on the isomorphic curve.
  * Return $X'/(dgZ'^2)$, which is the affine x coordinate on the isomorphic curve $X/Z'^2$ mapped back to secp256k1.

  This ability to specify the X coordinate as a fraction is useful in the context of x-only [Elligator Swift](https://eprint.iacr.org/2022/759), which can decode to X coordinates on the curve without inversions this way.

ACKs for top commit:
  jonasnick:
    ACK 0f86420
  real-or-random:
    ACK 0f86420

Tree-SHA512: eeedb3045bfabcb4bcaf3a1738067c83a5ea9a79b150b8fd1c00dc3f68505d34c19654885a90e2292ae40ddf40a58dfb27197d98eebcf5d6d9e25897e07ae595
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants