-1

I am trying to include the libsodium into my Go project. For that, I've copied the repo inside my project

// #cgo CFLAGS: -I/mypath/libsodium/src/libsodium/include/sodium
// #include <stdlib.h>
// #include "crypto_sign_ed25519.h"
import "C"

When trying to build the project I get the following error:

/tmp/go-build/cgo-gcc-prolog:53: undefined reference to `crypto_sign_ed25519_pk_to_curve25519'
collect2: error: ld returned 1 exit status

The file can be found but the error is there. I've also tried to reference the '.c' file as well as to copy the crypto_sign_ed25519.h into the src folder but it does not work. My question is do I have to add LDFLAGS and therefore generate a .so file from the library or that is not needed and there is another possible way of doing it?

UPDATE: I've achieved to make it running by installing the library on my local ubuntu:

$ ./configure
$ make && make check
$ sudo make install

and adding // #cgo LDFLAGS: -L/usr/local/lib -lsodium But how can I do it without adding the local path?

manolodewiner
  • 504
  • 3
  • 26

2 Answers2

1

You indeed need to link the library, the headers themselves are only the interface to the library and don't link the actual libsodium code to your binary.

Assuming libsodium ships a pkg-config file (it seems to be the case), you can use something like

// #cgo pkg-config: libsodium
// #include "crypto_sign_ed25519.h"

See https://golang.org/cmd/cgo/ for more information about pkg-config support.

To see what cflags/libs you'd be getting (so what cgo will use), run:

pkg-config --cflags --libs libsodium
Adrien
  • 36
  • 3
-1

After manually installing a library on Linux, you have to type ldconfig so that the linker becomes aware of it.

Also, in order to get libsodium prototypes, you should simply include <sodium.h> not <sodium/crypto_sign_ed25519.h> (not meant to be included directly), and call sodium_init() before any other function so that internal data structures are properly initialized.

See how this is done in existing bindings for Go: https://github.com/jamesruan/sodium/blob/master/core.go

You may want to use these bindings instead of reinventing your own. If they are missing some of the functions you need, their maintainers will probably be happy to accept your pull requests.

The two main Go bindings for libsodium that I am aware of are sodium and libsodium-go.

Frank Denis
  • 1,475
  • 9
  • 12
  • I am using cgo! – manolodewiner Aug 21 '19 at 09:15
  • This is a shared library, so it totally applies to cgo as well. I just added this to the documentation. And calling sodium_init() is also mandatory for Go applications. – Frank Denis Aug 22 '19 at 00:02
  • NOO, there is no necessity of calling sodium_init() – manolodewiner Aug 22 '19 at 09:14
  • sodium_init() must be called, or internal data structures may not be initialized. (I'm libsodium's author). – Frank Denis Aug 22 '19 at 09:37
  • You can see how they use cgo, initialize the library and include and not individual headers: https://github.com/jamesruan/sodium/blob/master/core.go - The ldconfig step is also required on Linux, no matter what language you use, since this is a library loaded by the dynamic linker. This is now explicitly mentioned [here](https://download.libsodium.org/doc/installation#compilation-on-unix-like-systems). – Frank Denis Aug 22 '19 at 09:49
  • It is not needed. I am using it without it. Check an example https://github.com/GoKillers/libsodium-go – manolodewiner Aug 23 '19 at 14:08
  • If you don't do it, some functions will make the whole app crash (e.g. anything that requires randomness or memory allocation), and other functions will currently fall back to their slowest implementations since CPU features haven't been probed. Using the library without initialization should be considered undefined behavior, and what happens can change at any time. libsodium-go, that you are referring to, has the same code as James Ruan's Sodium bindings: https://github.com/GoKillers/libsodium-go/blob/master/sodium/core.go – Frank Denis Aug 23 '19 at 14:22
  • Even in the current version, signatures will cause the application to crash if the library has been compiled with non-deterministic signatures, and hasn't been initialized. And headers such as `crypto_sign_ed25519.h` may also be renamed or removed at any time, so I'd recommend simply including `` as documented. – Frank Denis Aug 23 '19 at 14:29