Need help with /bitcoin-core/secp256k1

I want to create a public key for private key 7
There is such code

struct secp256k1_pubkey
    data::NTuple{64, Cuchar}
end

pubkey =  Ref{secp256k1_pubkey}()
private_key = 7
pub = ccall((:secp256k1_ec_pubkey_create, "/usr/local/lib/libsecp256k1.so"), Int, (Pair{Int64, Int64}, Ref{secp256k1_pubkey}, Int32), secp256k1_ctx, pubkey, private_key)

in return, I get
[libsecp256k1] illegal argument: pubkey != NULL

Do you have source for that library? Can you give a link to it?

ScottPJones, hello!
Oh sure
https://github.com/bitcoin-core/secp256k1

It looks like you don’t have the calling sequence correct:
The function wants 3 pointers:

int secp256k1_ec_pubkey_create(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const unsigned char *seckey) {

I don’t know why you are trying to pass a Julia type for the first argument, and seckey needs to be a pointer to a Vector{UInt8}, you are passing an Int, which is likely to cause a core-dump.

Also, it returns a Cint, not an Int (Cint will be 32-bits, Int will be 32 or 64 on Julia, 64 for 64-bit platforms)

Can you demonstrate the code?
If I change the type, I get a type conversion error.

int secp256k1_ec_pubkey_create(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const unsigned char *seckey) {
    secp256k1_gej pj;
    secp256k1_ge p;
    secp256k1_scalar sec;
    int overflow;
    int ret = 0;
    VERIFY_CHECK(ctx != NULL);
    ARG_CHECK(pubkey != NULL);
    memset(pubkey, 0, sizeof(*pubkey));
    ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx));
    ARG_CHECK(seckey != NULL);

    secp256k1_scalar_set_b32(&sec, seckey, &overflow);
    ret = (!overflow) & (!secp256k1_scalar_is_zero(&sec));
    if (ret) {
        secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &pj, &sec);
        secp256k1_ge_set_gej(&p, &pj);
        secp256k1_pubkey_save(pubkey, &p);
    }
    secp256k1_scalar_clear(&sec);
    return ret;
}

on the first argument the function does not swear
VERIFY_CHECK (ctx! = NULL); here we pass
and here
ARG_CHECK (pubkey! = NULL); we get an error

Tell me, do not you exist the standard library of Julia for the ecdsa?

ARG_CHECK (pubkey! = NULL); we get an error

This means that you have passed NULL for pubkey. Let’s see what is pubkey in your code:

pubkey = Ref{secp256k1_pubkey}()

Well, Ref without arguments is that same as Ref(0), so your pubkey is indeed NULL, while secp256k1_ec_pubkey_create clearly needs it to be a pointer to a pre-allocated array of 64 bytes. Try something like this:

pubkey =  Vector{Cuchar}(64)     # pre-allocate buffer
private_key = 7
pub = ccall((:secp256k1_ec_pubkey_create, "/usr/local/lib/libsecp256k1.so"), Cint, (Pair{Int64, Int64}, Ptr{Cuchar}, Int32), secp256k1_ctx, pubkey, private_key)

Note that I also replaced Ref{secp256k1_pubkey} with Ptr{Cuchar}. When you invoke ccall, Julia should(*) take a pointer to array data and pass it to the function, so when it’s finished this array will contain the populated data.

(* - “should” because I always forget all the conversions between Julia and C types, but a quick test will confirm it).

dfdx, thanks, but the mistake is same
[libsecp256k1] illegal argument: pubkey != NULL

pubkey =  Vector{Cuchar}(64) 
println(pubkey)

UInt8[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]

struct secp256k1_pubkey
    data::NTuple{64, Cuchar}
end

pubkey =  Ref{secp256k1_pubkey}()
println(pubkey)
Base.RefValue{secp256k1_pubkey}(secp256k1_pubkey((0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)))
UInt8[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]